@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
|
@@ -2,7 +2,7 @@ import { InternalCompilerError } from "../errors.js";
|
|
|
2
2
|
import { mockCallRecordType, mockContextType } from "./mock-shapes.js";
|
|
3
3
|
import * as ts from "./ts7/adapter.js";
|
|
4
4
|
import { bodyReadsArguments } from "./arguments-usage.js";
|
|
5
|
-
import { BYTES_ELEMENT_NAME, arrayOf, BOOL, bytesOf, canConvertToDyn, CHILD_T, CRYPTOHASH_T, CRYPTOHMAC_T, DATE_T, DYN, F64, funcOf, isSupportedArrayElem, isSupportedIndexValue, isSupportedMapKey, isSupportedMapValue, isSupportedSetElem, isUnitType, mapOf, NULL_T, PROCSTREAM_T, RUNTIME_EMITTER_CLASS, RUNTIME_ERROR_CLASSES, RUNTIME_STREAM_CLASSES, ZLIB_STREAM_MODES, setOf, STRING, SYMBOL_T, typeEquals, typeKey, unionContainerArmsOk, UNDEFINED_T, VOID, } from "../ir/ir.js";
|
|
5
|
+
import { BYTES_ELEMENT_NAME, arrayOf, isDynTypedRefType, BOOL, bytesOf, canConvertToDyn, canDynCheckTo, CHILD_T, CRYPTOHASH_T, CRYPTOHMAC_T, DATE_T, DYN, F64, funcOf, isSupportedArrayElem, isSupportedIndexValue, isSupportedMapKey, isSupportedMapValue, isSupportedSetElem, isUnitType, mapOf, NULL_T, PROCSTREAM_T, RUNTIME_EMITTER_CLASS, RUNTIME_ERROR_CLASSES, RUNTIME_STREAM_CLASSES, ZLIB_STREAM_MODES, setOf, STRING, SYMBOL_T, typeEquals, typeKey, maybePromiseUnionArmsOk, unionContainerArmsOk, UNDEFINED_T, VOID, } from "../ir/ir.js";
|
|
6
6
|
import { BIGINT_T } from "../ir/ir.js";
|
|
7
7
|
import { literalValues } from "./literal-values.js";
|
|
8
8
|
import { remapUnionDiscriminant } from "./union-discriminants.js";
|
|
@@ -21,7 +21,7 @@ function runtimeParameterCount(parameters) {
|
|
|
21
21
|
/** Empty JS object inference describes no fixed layout. Keep these values
|
|
22
22
|
* in checked storage across fields, parameters and function signatures. */
|
|
23
23
|
export function jsOpenObjectType(decl, type, shapes, unions) {
|
|
24
|
-
if (!decl || !isJsSourceFile(
|
|
24
|
+
if (!decl || !isJsSourceFile(ts.getSourceFileOfNode(decl)))
|
|
25
25
|
return type;
|
|
26
26
|
const arms = type.kind === "union" ? unions.get(type.unionId)?.arms : [type];
|
|
27
27
|
const present = arms?.filter((arm) => arm.kind !== "undefinedT");
|
|
@@ -67,6 +67,25 @@ export function jsOpenObjectType(decl, type, shapes, unions) {
|
|
|
67
67
|
? DYN
|
|
68
68
|
: type;
|
|
69
69
|
}
|
|
70
|
+
/** The modules whose RequestOptions interface maps to the checked dynamic. */
|
|
71
|
+
const HTTP_REQUEST_OPTION_MODULES = new Set([
|
|
72
|
+
"http",
|
|
73
|
+
"node:http",
|
|
74
|
+
"https",
|
|
75
|
+
"node:https",
|
|
76
|
+
]);
|
|
77
|
+
/** The WebCrypto interfaces whose values are checked-dynamic: the crypto
|
|
78
|
+
* global, SubtleCrypto, CryptoKey handles and the algorithm dictionaries
|
|
79
|
+
* (scr_webcrypto.c). */
|
|
80
|
+
export const WEBCRYPTO_DYN_TYPES = new Set([
|
|
81
|
+
"Crypto",
|
|
82
|
+
"SubtleCrypto",
|
|
83
|
+
"CryptoKey",
|
|
84
|
+
"Algorithm",
|
|
85
|
+
"KeyAlgorithm",
|
|
86
|
+
"HmacImportParams",
|
|
87
|
+
"HmacKeyAlgorithm",
|
|
88
|
+
]);
|
|
70
89
|
export const FETCH_AMBIENT_TYPES = [
|
|
71
90
|
"Response",
|
|
72
91
|
"Request",
|
|
@@ -74,6 +93,7 @@ export const FETCH_AMBIENT_TYPES = [
|
|
|
74
93
|
"RequestInit",
|
|
75
94
|
"Event",
|
|
76
95
|
"CustomEvent",
|
|
96
|
+
"MessageEvent",
|
|
77
97
|
"EventTarget",
|
|
78
98
|
"AddEventListenerOptions",
|
|
79
99
|
"EventListenerOptions",
|
|
@@ -232,7 +252,7 @@ export class ShapeRegistry {
|
|
|
232
252
|
comparePriority(previous, this.currentDeclaredOrderPriority) <= 0) {
|
|
233
253
|
return;
|
|
234
254
|
}
|
|
235
|
-
shape.declaredOrder = declaredOrder;
|
|
255
|
+
shape.declaredOrder = this.withExtendedNames(shape.id, declaredOrder);
|
|
236
256
|
this.declaredOrderPriority.set(shape.id, this.currentDeclaredOrderPriority);
|
|
237
257
|
}
|
|
238
258
|
/** Mutable generic-instance ranks settle only after reachability closes.
|
|
@@ -250,7 +270,7 @@ export class ShapeRegistry {
|
|
|
250
270
|
const shape = this.byId.get(shapeId);
|
|
251
271
|
if (!shape)
|
|
252
272
|
continue;
|
|
253
|
-
shape.declaredOrder = best.order;
|
|
273
|
+
shape.declaredOrder = this.withExtendedNames(shapeId, best.order);
|
|
254
274
|
this.declaredOrderPriority.set(shapeId, best.priority);
|
|
255
275
|
}
|
|
256
276
|
for (const finalize of this.derivedDeclaredOrderFinalizers)
|
|
@@ -274,7 +294,7 @@ export class ShapeRegistry {
|
|
|
274
294
|
return;
|
|
275
295
|
const next = order();
|
|
276
296
|
if (next !== undefined)
|
|
277
|
-
shape.declaredOrder = next;
|
|
297
|
+
shape.declaredOrder = this.withExtendedNames(shape.id, next);
|
|
278
298
|
};
|
|
279
299
|
}
|
|
280
300
|
/** The shape id a back-reference to an in-progress type resolves to:
|
|
@@ -367,6 +387,52 @@ export class ShapeRegistry {
|
|
|
367
387
|
get(shapeId) {
|
|
368
388
|
return this.byId.get(shapeId);
|
|
369
389
|
}
|
|
390
|
+
/** Names extendShape added to a shape, which every key-order table the
|
|
391
|
+
* shape adopts lists after its declared names. */
|
|
392
|
+
extendedNames = new Map();
|
|
393
|
+
/** The members extendShape attached to a shape (empty for most). */
|
|
394
|
+
attachedNames(shapeId) {
|
|
395
|
+
return this.extendedNames.get(shapeId) ?? [];
|
|
396
|
+
}
|
|
397
|
+
withExtendedNames(shapeId, order) {
|
|
398
|
+
const extra = this.extendedNames.get(shapeId);
|
|
399
|
+
if (!extra)
|
|
400
|
+
return order;
|
|
401
|
+
const missing = extra.filter((name) => !order.includes(name));
|
|
402
|
+
return missing.length === 0 ? order : [...order, ...missing];
|
|
403
|
+
}
|
|
404
|
+
/** Adds optional fields to an interned shape in place: members a type
|
|
405
|
+
* assertion attaches to the shape's values (`r as R & { tag: string }`
|
|
406
|
+
* followed by `view.tag = ...`; see assertion-members.ts). Every value
|
|
407
|
+
* of the shape holds them absent until a write through such a view, so
|
|
408
|
+
* the shape keeps its id, both structural keys resolve to it, and its
|
|
409
|
+
* key-order table lists the new names after the declared ones. Runs
|
|
410
|
+
* before any body lowers; existing layouts change, so the revision
|
|
411
|
+
* advances like a closing recursive placeholder. */
|
|
412
|
+
extendShape(shapeId, extra) {
|
|
413
|
+
const shape = this.byId.get(shapeId);
|
|
414
|
+
if (!shape || shape.tuple || extra.length === 0)
|
|
415
|
+
return;
|
|
416
|
+
const fresh = extra.filter((f) => !shape.fields.some((x) => x.name === f.name));
|
|
417
|
+
if (fresh.length === 0)
|
|
418
|
+
return;
|
|
419
|
+
shape.fields = [...shape.fields, ...fresh].sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0);
|
|
420
|
+
this.extendedNames.set(shapeId, [
|
|
421
|
+
...(this.extendedNames.get(shapeId) ?? []),
|
|
422
|
+
...fresh.map((f) => f.name),
|
|
423
|
+
]);
|
|
424
|
+
if (shape.declaredOrder)
|
|
425
|
+
shape.declaredOrder = this.withExtendedNames(shapeId, shape.declaredOrder);
|
|
426
|
+
const candidates = this.declaredOrderCandidates.get(shapeId);
|
|
427
|
+
if (candidates) {
|
|
428
|
+
for (const c of candidates)
|
|
429
|
+
c.order = this.withExtendedNames(shapeId, c.order);
|
|
430
|
+
}
|
|
431
|
+
this.revision++;
|
|
432
|
+
const key = this.keyOf(shape.fields, false, shape.indexValue);
|
|
433
|
+
if (!this.byKey.has(key))
|
|
434
|
+
this.byKey.set(key, shapeId);
|
|
435
|
+
}
|
|
370
436
|
}
|
|
371
437
|
/** The frontend's union interner — mirrors ShapeRegistry. A union's
|
|
372
438
|
* canonical identity includes its typeKey-sorted arms and literal
|
|
@@ -527,6 +593,7 @@ export function formatIrType(t, shapes, unions, seen = new Set()) {
|
|
|
527
593
|
case "bool":
|
|
528
594
|
return append("boolean");
|
|
529
595
|
case "dyn":
|
|
596
|
+
case "jsval":
|
|
530
597
|
return append("unknown");
|
|
531
598
|
case "caught":
|
|
532
599
|
// What tsc calls the binding; the fence messages carry the real story.
|
|
@@ -793,7 +860,7 @@ function isDeclaredInAmbientModule(d, name) {
|
|
|
793
860
|
/** True when the declaration's nearest enclosing namespace is `name`
|
|
794
861
|
* (`declare global { namespace NodeJS { ... } }` — the NodeJS-global
|
|
795
862
|
* interfaces @types/node declares outside any ambient module). */
|
|
796
|
-
function isDeclaredInAmbientNamespace(d, name) {
|
|
863
|
+
export function isDeclaredInAmbientNamespace(d, name) {
|
|
797
864
|
let node = d.parent;
|
|
798
865
|
while (node) {
|
|
799
866
|
if (ts.isModuleDeclaration(node) && ts.isIdentifier(node.name)) {
|
|
@@ -803,6 +870,39 @@ function isDeclaredInAmbientNamespace(d, name) {
|
|
|
803
870
|
}
|
|
804
871
|
return false;
|
|
805
872
|
}
|
|
873
|
+
/** Whether `type` is one of the stream spellings the general stream
|
|
874
|
+
* representation (TypeMapperCtx.generalNodeStreams) maps differently:
|
|
875
|
+
* NodeJS.ReadableStream / NodeJS.WritableStream, @types/node's
|
|
876
|
+
* stream.Readable / stream.Writable, or the fallback declarations'
|
|
877
|
+
* ChildStdin. */
|
|
878
|
+
export function isGeneralNodeStreamInterface(type, ctx) {
|
|
879
|
+
const psym = type.getSymbol() ?? type.getAliasSymbol();
|
|
880
|
+
if (psym === undefined)
|
|
881
|
+
return false;
|
|
882
|
+
return psym.declarations.some((d) => {
|
|
883
|
+
if (!(ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)))
|
|
884
|
+
return false;
|
|
885
|
+
if (!ctx.isStdlibFile(ts.getSourceFileOfNode(d)))
|
|
886
|
+
return false;
|
|
887
|
+
if (ts.symbolName(psym) === "ReadableStream" || ts.symbolName(psym) === "WritableStream")
|
|
888
|
+
return ts.isInterfaceDeclaration(d) && isDeclaredInAmbientNamespace(d, "NodeJS");
|
|
889
|
+
if (ts.symbolName(psym) === "ChildStdin")
|
|
890
|
+
return isDeclaredInAmbientModule(d, "child_process");
|
|
891
|
+
return ((ts.symbolName(psym) === "Readable" || ts.symbolName(psym) === "Writable") &&
|
|
892
|
+
isNodeTypesPath(ts.getSourceFileOfNode(d).fileName) &&
|
|
893
|
+
isDeclaredInAmbientModule(d, "stream"));
|
|
894
|
+
});
|
|
895
|
+
}
|
|
896
|
+
/** A type declared in the shipped WebAssembly namespace (scriptc.d.ts):
|
|
897
|
+
* its modules, instances, memories, tables, globals, error classes and the
|
|
898
|
+
* Exports/Imports records. */
|
|
899
|
+
export function isWebAssemblyType(type, ctx) {
|
|
900
|
+
const symbol = type.getAliasSymbol() ?? type.getSymbol();
|
|
901
|
+
if (!symbol)
|
|
902
|
+
return false;
|
|
903
|
+
return symbol.declarations.some((d) => ctx.isStdlibFile(ts.getSourceFileOfNode(d)) &&
|
|
904
|
+
isDeclaredInAmbientNamespace(d, "WebAssembly"));
|
|
905
|
+
}
|
|
806
906
|
/** True when a type contains a record anywhere (the trigger for the
|
|
807
907
|
* shape-mismatch diagnostic SC2002 — non-record mismatches are tsc's or
|
|
808
908
|
* the validator's business). */
|
|
@@ -928,8 +1028,8 @@ export function isLegacyUrlType(type, ctx) {
|
|
|
928
1028
|
export function isLegacyUrlSymbol(symbol, ctx) {
|
|
929
1029
|
if (!symbol)
|
|
930
1030
|
return false;
|
|
931
|
-
for (const d of
|
|
932
|
-
if (!ctx.isStdlibFile(
|
|
1031
|
+
for (const d of symbol.declarations) {
|
|
1032
|
+
if (!ctx.isStdlibFile(ts.getSourceFileOfNode(d)))
|
|
933
1033
|
continue;
|
|
934
1034
|
let family = false;
|
|
935
1035
|
for (let n = d; n; n = n.parent) {
|
|
@@ -958,10 +1058,11 @@ export function isOsConstantsType(type, ctx) {
|
|
|
958
1058
|
export function isOsConstantsSymbol(symbol, ctx, types = false) {
|
|
959
1059
|
if (!symbol)
|
|
960
1060
|
return false;
|
|
961
|
-
for (const d of
|
|
1061
|
+
for (const d of symbol.declarations) {
|
|
962
1062
|
const alias = types && ts.isTypeAliasDeclaration(d) && d.name.text === "SignalConstants";
|
|
963
1063
|
const signals = !types && ts.isVariableDeclaration(d) && ts.isIdentifier(d.name) && d.name.text === "signals";
|
|
964
|
-
if (!(alias || signals || ts.isModuleDeclaration(d)) ||
|
|
1064
|
+
if (!(alias || signals || ts.isModuleDeclaration(d)) ||
|
|
1065
|
+
!ctx.isStdlibFile(ts.getSourceFileOfNode(d)))
|
|
965
1066
|
continue;
|
|
966
1067
|
let inConstants = ts.isModuleDeclaration(d) && d.name.text === "constants";
|
|
967
1068
|
for (let n = d.parent; n; n = n.parent) {
|
|
@@ -981,26 +1082,147 @@ export function isOsConstantsSymbol(symbol, ctx, types = false) {
|
|
|
981
1082
|
/** worker_threads' Worker and MessagePort: owned runtime handles that keep
|
|
982
1083
|
* their live object representation (DYN) wherever they are stored. */
|
|
983
1084
|
function isWorkerHandleSymbol(symbol, ctx) {
|
|
984
|
-
return ((symbol
|
|
985
|
-
symbol
|
|
986
|
-
symbol
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
.
|
|
990
|
-
ctx.isStdlibFile(d.getSourceFile()) &&
|
|
1085
|
+
return (((symbol !== undefined && ts.symbolName(symbol) === "Worker") ||
|
|
1086
|
+
(symbol !== undefined && ts.symbolName(symbol) === "MessagePort") ||
|
|
1087
|
+
(symbol !== undefined && ts.symbolName(symbol) === "MessageChannel") ||
|
|
1088
|
+
(symbol !== undefined && ts.symbolName(symbol) === "BroadcastChannel")) &&
|
|
1089
|
+
symbol.declarations.some((d) => (ts.isClassDeclaration(d) || ts.isInterfaceDeclaration(d)) &&
|
|
1090
|
+
ctx.isStdlibFile(ts.getSourceFileOfNode(d)) &&
|
|
991
1091
|
isDeclaredInAmbientModule(d, "worker_threads")));
|
|
992
1092
|
}
|
|
993
1093
|
/** The `{ message: any }` object type (or its union with undefined) that
|
|
994
1094
|
* worker_threads declares as receiveMessageOnPort's result. */
|
|
1095
|
+
/** A union of dns lookup option bags with numbers and nullish values that
|
|
1096
|
+
* includes LookupAllOptions (whose `all: true` arm has no record form). */
|
|
1097
|
+
function isLookupOptionsUnion(type, ctx) {
|
|
1098
|
+
if (!type.isUnionType())
|
|
1099
|
+
return false;
|
|
1100
|
+
let all = false;
|
|
1101
|
+
for (const member of ts.constituentTypes(type)) {
|
|
1102
|
+
if (member.flags & (ts.TypeFlags.NumberLike | ts.TypeFlags.Null | ts.TypeFlags.Undefined))
|
|
1103
|
+
continue;
|
|
1104
|
+
const symbol = member.getSymbol();
|
|
1105
|
+
if (symbol === undefined ||
|
|
1106
|
+
!/^Lookup(One|All)?Options$/.test(ts.symbolName(symbol)) ||
|
|
1107
|
+
!symbol.declarations.some((d) => ctx.isStdlibFile(ts.getSourceFileOfNode(d))))
|
|
1108
|
+
return false;
|
|
1109
|
+
if (ts.symbolName(symbol) === "LookupAllOptions")
|
|
1110
|
+
all = true;
|
|
1111
|
+
}
|
|
1112
|
+
return all;
|
|
1113
|
+
}
|
|
1114
|
+
/** The binary and stream members of fetch's BodyInit (undici-types):
|
|
1115
|
+
* NodeJS.ArrayBufferView expands to the typed arrays and DataView. */
|
|
1116
|
+
const FETCH_BODY_MEMBERS = new Set([
|
|
1117
|
+
"ArrayBuffer",
|
|
1118
|
+
"SharedArrayBuffer",
|
|
1119
|
+
"AsyncIterable",
|
|
1120
|
+
"Iterable",
|
|
1121
|
+
"Blob",
|
|
1122
|
+
"FormData",
|
|
1123
|
+
"URLSearchParams",
|
|
1124
|
+
"ReadableStream",
|
|
1125
|
+
"DataView",
|
|
1126
|
+
"Buffer",
|
|
1127
|
+
"Int8Array",
|
|
1128
|
+
"Uint8Array",
|
|
1129
|
+
"Uint8ClampedArray",
|
|
1130
|
+
"Int16Array",
|
|
1131
|
+
"Uint16Array",
|
|
1132
|
+
"Int32Array",
|
|
1133
|
+
"Uint32Array",
|
|
1134
|
+
"Float16Array",
|
|
1135
|
+
"Float32Array",
|
|
1136
|
+
"Float64Array",
|
|
1137
|
+
"BigInt64Array",
|
|
1138
|
+
"BigUint64Array",
|
|
1139
|
+
]);
|
|
1140
|
+
/** fetch's request body type, BodyInit, however TypeScript spells it
|
|
1141
|
+
* (`RequestInit["body"]`, `NonNullable<...>`, an optional member): a
|
|
1142
|
+
* union of strings, the stdlib binary and stream types and nullish
|
|
1143
|
+
* values that includes both FormData and URLSearchParams. Native fetch
|
|
1144
|
+
* reads such a body at run time, so it rides checked-dynamic storage. */
|
|
1145
|
+
function isFetchBodyUnion(type, ctx) {
|
|
1146
|
+
if (!type.isUnionType())
|
|
1147
|
+
return false;
|
|
1148
|
+
let formData = false;
|
|
1149
|
+
let searchParams = false;
|
|
1150
|
+
for (const member of ts.constituentTypes(type)) {
|
|
1151
|
+
if (member.flags & (ts.TypeFlags.StringLike | ts.TypeFlags.Null | ts.TypeFlags.Undefined))
|
|
1152
|
+
continue;
|
|
1153
|
+
const symbol = member.getSymbol();
|
|
1154
|
+
if (symbol === undefined ||
|
|
1155
|
+
!FETCH_BODY_MEMBERS.has(ts.symbolName(symbol)) ||
|
|
1156
|
+
!symbol.declarations.some((d) => ctx.isStdlibFile(ts.getSourceFileOfNode(d))))
|
|
1157
|
+
return false;
|
|
1158
|
+
if (ts.symbolName(symbol) === "FormData")
|
|
1159
|
+
formData = true;
|
|
1160
|
+
if (ts.symbolName(symbol) === "URLSearchParams")
|
|
1161
|
+
searchParams = true;
|
|
1162
|
+
}
|
|
1163
|
+
return formData && searchParams;
|
|
1164
|
+
}
|
|
1165
|
+
/** A mapped object type (Omit, Pick, Partial) whose members all come from
|
|
1166
|
+
* one stdlib interface that maps to the checked dynamic. */
|
|
1167
|
+
function isDynInterfaceSubset(type, ctx) {
|
|
1168
|
+
if (!(type.flags & ts.TypeFlags.Object) || type.isClassOrInterface())
|
|
1169
|
+
return false;
|
|
1170
|
+
const alias = type.getAliasSymbol();
|
|
1171
|
+
if (alias === undefined)
|
|
1172
|
+
return false;
|
|
1173
|
+
const props = ctx.checker.getPropertiesOfType(type);
|
|
1174
|
+
if (props.length === 0)
|
|
1175
|
+
return false;
|
|
1176
|
+
let owner;
|
|
1177
|
+
for (const prop of props) {
|
|
1178
|
+
const decl = prop.declarations[0];
|
|
1179
|
+
const parent = decl?.parent;
|
|
1180
|
+
if (parent === undefined ||
|
|
1181
|
+
!ts.isInterfaceDeclaration(parent) ||
|
|
1182
|
+
!ctx.isStdlibFile(ts.getSourceFileOfNode(parent)) ||
|
|
1183
|
+
(owner !== undefined && owner !== parent))
|
|
1184
|
+
return false;
|
|
1185
|
+
owner = parent;
|
|
1186
|
+
}
|
|
1187
|
+
return (owner !== undefined && mapType(ctx.checker.getTypeAtLocation(owner.name), ctx)?.kind === "dyn");
|
|
1188
|
+
}
|
|
1189
|
+
/** fetch's HeadersInit (undici-types): a union of the stdlib Headers
|
|
1190
|
+
* class with header-pair arrays and/or a header record, plus nullish
|
|
1191
|
+
* values. Native fetch reads it at run time like the init around it. */
|
|
1192
|
+
function isFetchHeadersUnion(type, ctx) {
|
|
1193
|
+
if (!type.isUnionType())
|
|
1194
|
+
return false;
|
|
1195
|
+
let headers = false;
|
|
1196
|
+
let other = false;
|
|
1197
|
+
for (const member of ts.constituentTypes(type)) {
|
|
1198
|
+
if (member.flags & (ts.TypeFlags.Null | ts.TypeFlags.Undefined))
|
|
1199
|
+
continue;
|
|
1200
|
+
const symbol = member.getSymbol();
|
|
1201
|
+
if (symbol !== undefined &&
|
|
1202
|
+
ts.symbolName(symbol) === "Headers" &&
|
|
1203
|
+
symbol.declarations.some((d) => ctx.isStdlibFile(ts.getSourceFileOfNode(d)))) {
|
|
1204
|
+
headers = true;
|
|
1205
|
+
continue;
|
|
1206
|
+
}
|
|
1207
|
+
const alias = ts.symbolNameOf(member.getAliasSymbol());
|
|
1208
|
+
if ((symbol !== undefined && ts.symbolName(symbol) === "Array") ||
|
|
1209
|
+
(symbol !== undefined && ts.symbolName(symbol) === "ReadonlyArray") ||
|
|
1210
|
+
alias === "Record" ||
|
|
1211
|
+
alias === "HeaderRecord") {
|
|
1212
|
+
other = true;
|
|
1213
|
+
continue;
|
|
1214
|
+
}
|
|
1215
|
+
return false;
|
|
1216
|
+
}
|
|
1217
|
+
return headers && other;
|
|
1218
|
+
}
|
|
995
1219
|
function isReceiveMessageResult(type, ctx) {
|
|
996
1220
|
const members = type.isUnionType() ? ts.constituentTypes(type) : [type];
|
|
997
1221
|
let found = false;
|
|
998
1222
|
for (const member of members) {
|
|
999
1223
|
if (member.flags & ts.TypeFlags.Undefined)
|
|
1000
1224
|
continue;
|
|
1001
|
-
const decl = member.getSymbol()
|
|
1002
|
-
? ctx.checker.declarationsOf(member.getSymbol())[0]
|
|
1003
|
-
: undefined;
|
|
1225
|
+
const decl = member.getSymbol() ? member.getSymbol().declarations[0] : undefined;
|
|
1004
1226
|
let fn = decl?.parent;
|
|
1005
1227
|
while (fn && ts.isUnionTypeNode(fn))
|
|
1006
1228
|
fn = fn.parent;
|
|
@@ -1009,7 +1231,7 @@ function isReceiveMessageResult(type, ctx) {
|
|
|
1009
1231
|
!fn ||
|
|
1010
1232
|
!ts.isFunctionDeclaration(fn) ||
|
|
1011
1233
|
fn.name?.text !== "receiveMessageOnPort" ||
|
|
1012
|
-
!ctx.isStdlibFile(
|
|
1234
|
+
!ctx.isStdlibFile(ts.getSourceFileOfNode(decl)) ||
|
|
1013
1235
|
!isDeclaredInAmbientModule(fn, "worker_threads")) {
|
|
1014
1236
|
return false;
|
|
1015
1237
|
}
|
|
@@ -1037,6 +1259,57 @@ export function isWorkerHandleType(type, ctx) {
|
|
|
1037
1259
|
}
|
|
1038
1260
|
return handle;
|
|
1039
1261
|
}
|
|
1262
|
+
/** The return annotation of an `async *` declaration spelled with the
|
|
1263
|
+
* protocol interfaces the generator object implements —
|
|
1264
|
+
* `AsyncIterator<T>`, `AsyncIterableIterator<T>` or `AsyncIterable<T>` (pi's
|
|
1265
|
+
* `async *[Symbol.asyncIterator](): AsyncIterator<T>`): the body always
|
|
1266
|
+
* produces an async generator, so the declaration maps exactly like an
|
|
1267
|
+
* `AsyncGenerator<T, TReturn, TNext>` annotation. Values of these types
|
|
1268
|
+
* elsewhere stay unmapped (they can hold any object implementing the
|
|
1269
|
+
* protocol). Null when the annotation is not one of them. */
|
|
1270
|
+
export function mapAsyncGeneratorAnnotation(type, ctx) {
|
|
1271
|
+
const { checker } = ctx;
|
|
1272
|
+
const symbol = type.getSymbol();
|
|
1273
|
+
if (!symbol ||
|
|
1274
|
+
!["AsyncIterator", "AsyncIterableIterator", "AsyncIterable"].includes(ts.symbolName(symbol)) ||
|
|
1275
|
+
!symbol.declarations.some((d) => ts.isInterfaceDeclaration(d) && ctx.isStdlibFile(ts.getSourceFileOfNode(d))))
|
|
1276
|
+
return null;
|
|
1277
|
+
const args = checker.getTypeArguments(type);
|
|
1278
|
+
const channels = genChannels(args[0], args[1], args[2], ctx);
|
|
1279
|
+
if (!channels)
|
|
1280
|
+
return null;
|
|
1281
|
+
if (!genResultRecord(channels.yieldT, channels.retT, ctx.shapes, ctx.unions))
|
|
1282
|
+
return null;
|
|
1283
|
+
return { kind: "generator", async: true, ...channels };
|
|
1284
|
+
}
|
|
1285
|
+
/** The native fetch handles (Headers, Request, Response), optionally in
|
|
1286
|
+
* arrays or with null/undefined: checked-dynamic handles wherever they are
|
|
1287
|
+
* stored, like the worker handles above. */
|
|
1288
|
+
export function isFetchHandleType(type, ctx) {
|
|
1289
|
+
const members = type.isUnionType() ? ts.constituentTypes(type) : [type];
|
|
1290
|
+
let handle = false;
|
|
1291
|
+
for (const member of members) {
|
|
1292
|
+
if (member.flags & (ts.TypeFlags.Null | ts.TypeFlags.Undefined))
|
|
1293
|
+
continue;
|
|
1294
|
+
if (ctx.checker.isArrayType(member)) {
|
|
1295
|
+
const element = ctx.checker.getTypeArguments(member)[0];
|
|
1296
|
+
if (element === undefined || !isFetchHandleType(element, ctx))
|
|
1297
|
+
return false;
|
|
1298
|
+
}
|
|
1299
|
+
else {
|
|
1300
|
+
const symbol = member.getSymbol();
|
|
1301
|
+
if (!symbol ||
|
|
1302
|
+
(ts.symbolName(symbol) !== "Headers" &&
|
|
1303
|
+
ts.symbolName(symbol) !== "Request" &&
|
|
1304
|
+
ts.symbolName(symbol) !== "Response") ||
|
|
1305
|
+
!symbol.declarations.some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
|
|
1306
|
+
ctx.isStdlibFile(ts.getSourceFileOfNode(d))))
|
|
1307
|
+
return false;
|
|
1308
|
+
}
|
|
1309
|
+
handle = true;
|
|
1310
|
+
}
|
|
1311
|
+
return handle;
|
|
1312
|
+
}
|
|
1040
1313
|
export function mapType(type, ctx) {
|
|
1041
1314
|
if (mapTypeDepth >= MAP_TYPE_MAX_DEPTH)
|
|
1042
1315
|
return null;
|
|
@@ -1064,7 +1337,18 @@ export function mapType(type, ctx) {
|
|
|
1064
1337
|
const sensitivityAtEntry = contextResolutions;
|
|
1065
1338
|
mapTypeDepth++;
|
|
1066
1339
|
try {
|
|
1067
|
-
|
|
1340
|
+
let mapped;
|
|
1341
|
+
try {
|
|
1342
|
+
mapped = mapTypeInner(type, ctx);
|
|
1343
|
+
}
|
|
1344
|
+
catch (e) {
|
|
1345
|
+
// typescript-go's API can panic serializing a union's members (an
|
|
1346
|
+
// empty tuple cloned as an array literal, `s.match(re) || []`): a
|
|
1347
|
+
// union the checker cannot describe has no representation.
|
|
1348
|
+
if (!topLevel || !ts.isUnreadableConstituentsPanic(e))
|
|
1349
|
+
throw e;
|
|
1350
|
+
mapped = null;
|
|
1351
|
+
}
|
|
1068
1352
|
if (mapped !== null &&
|
|
1069
1353
|
memoKey !== null &&
|
|
1070
1354
|
topLevel &&
|
|
@@ -1087,38 +1371,135 @@ function classExprNeedsContext(decl) {
|
|
|
1087
1371
|
}
|
|
1088
1372
|
return false;
|
|
1089
1373
|
}
|
|
1374
|
+
/** True for the type of a TypeScript object literal with no contextual
|
|
1375
|
+
* type (`const options = { ...location, path }`) that spreads a value
|
|
1376
|
+
* mapping to the checked dynamic (a stdlib options type such as
|
|
1377
|
+
* http.RequestOptions). A literal with a contextual type is built in that
|
|
1378
|
+
* type's representation instead, and JavaScript literals keep their own
|
|
1379
|
+
* rules. */
|
|
1380
|
+
function spreadsCheckedDynamic(symbol, ctx) {
|
|
1381
|
+
if (symbol === undefined || (symbol.flags & ts.SymbolFlags.ObjectLiteral) === 0)
|
|
1382
|
+
return false;
|
|
1383
|
+
const decl = symbol.declarations[0];
|
|
1384
|
+
if (decl === undefined || !ts.isObjectLiteralExpression(decl))
|
|
1385
|
+
return false;
|
|
1386
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(decl)))
|
|
1387
|
+
return false;
|
|
1388
|
+
if (ctx.checker.getContextualType(decl))
|
|
1389
|
+
return false;
|
|
1390
|
+
return decl.properties.nodes.some((prop) => ts.isSpreadAssignment(prop) &&
|
|
1391
|
+
mapType(ctx.checker.getTypeAtLocation(prop.expression), ctx)?.kind === "dyn");
|
|
1392
|
+
}
|
|
1090
1393
|
function mapTypeInner(type, ctx) {
|
|
1091
1394
|
const { checker, unions, classNamer, resolveTypeParam } = ctx;
|
|
1092
1395
|
// TypeScript's intrinsic globalThis symbol has no declaration. A stored
|
|
1093
1396
|
// reference needs native object identity, including var's undefined state.
|
|
1094
1397
|
const intrinsic = type.getSymbol();
|
|
1095
|
-
if (intrinsic
|
|
1398
|
+
if (intrinsic !== undefined &&
|
|
1399
|
+
ts.symbolName(intrinsic) === "globalThis" &&
|
|
1400
|
+
intrinsic.declarations.length === 0)
|
|
1096
1401
|
return DYN;
|
|
1402
|
+
if (ctx.jsDynamicDeclaration !== undefined && intrinsic !== undefined) {
|
|
1403
|
+
const objectLiteral = (intrinsic.flags & ts.SymbolFlags.ObjectLiteral) !== 0;
|
|
1404
|
+
const classInstance = (intrinsic.flags & ts.SymbolFlags.Class) !== 0 && type.isClassOrInterface();
|
|
1405
|
+
if ((objectLiteral || classInstance) &&
|
|
1406
|
+
intrinsic.declarations.some((decl) => ctx.jsDynamicDeclaration(decl)))
|
|
1407
|
+
return DYN;
|
|
1408
|
+
}
|
|
1097
1409
|
{
|
|
1098
1410
|
const moduleId = ctx.moduleNamespaceId?.(type) ?? null;
|
|
1099
1411
|
if (moduleId !== null)
|
|
1100
1412
|
return { kind: "moduleNs", moduleId };
|
|
1101
1413
|
}
|
|
1414
|
+
// A TypeScript object literal that spreads a checked-dynamic value
|
|
1415
|
+
// (`{ ...requestOptions, path, timeout }`): its keys are the source's
|
|
1416
|
+
// runtime keys, which no record shape holds, so the literal rides
|
|
1417
|
+
// checked-dynamic storage like its source.
|
|
1418
|
+
if (spreadsCheckedDynamic(intrinsic, ctx))
|
|
1419
|
+
return DYN;
|
|
1102
1420
|
// worker_threads.receiveMessageOnPort's `{ message: any } | undefined`:
|
|
1103
1421
|
// the runtime's { message } object, a checked-dynamic value.
|
|
1104
1422
|
if (isReceiveMessageResult(type, ctx))
|
|
1105
1423
|
return DYN;
|
|
1424
|
+
if (isFetchBodyUnion(type, ctx) || isFetchHeadersUnion(type, ctx))
|
|
1425
|
+
return DYN;
|
|
1426
|
+
// Omit/Pick/Partial of a stdlib interface that rides checked-dynamic
|
|
1427
|
+
// storage (`Omit<RequestInit, "body" | "headers">`): every member comes
|
|
1428
|
+
// from that interface, so the value is a subset of the same runtime-read
|
|
1429
|
+
// options object and rides the same storage.
|
|
1430
|
+
if (isDynInterfaceSubset(type, ctx))
|
|
1431
|
+
return DYN;
|
|
1432
|
+
// The lookup-function option union (`LookupOneOptions | LookupAllOptions
|
|
1433
|
+
// | number | undefined`): with a LookupAllOptions arm it is an option bag
|
|
1434
|
+
// dns.lookup reads at run time, so it rides checked-dynamic storage.
|
|
1435
|
+
if (isLookupOptionsUnion(type, ctx))
|
|
1436
|
+
return DYN;
|
|
1106
1437
|
// @types/node spells child_process.ExecFileException as an intersection
|
|
1107
1438
|
// type alias over two Error-derived metadata interfaces. The value is
|
|
1108
1439
|
// still one ordinary Error; recognize the owned alias before generic
|
|
1109
1440
|
// intersection mapping decomposes it into unsupported utility types.
|
|
1110
1441
|
const directAlias = type.getAliasSymbol();
|
|
1111
|
-
if (directAlias
|
|
1112
|
-
|
|
1442
|
+
if (directAlias !== undefined &&
|
|
1443
|
+
ts.symbolName(directAlias) === "ExecFileException" &&
|
|
1444
|
+
directAlias.declarations.some((decl) => ctx.isStdlibFile(ts.getSourceFileOfNode(decl)))) {
|
|
1445
|
+
return { kind: "object", className: "%Error" };
|
|
1446
|
+
}
|
|
1447
|
+
// child_process.ExecException, exec's callback error, is an interface
|
|
1448
|
+
// extending Error with optional metadata members; the value is one
|
|
1449
|
+
// ordinary Error as well.
|
|
1450
|
+
const execException = type.getSymbol();
|
|
1451
|
+
if (execException !== undefined &&
|
|
1452
|
+
ts.symbolName(execException) === "ExecException" &&
|
|
1453
|
+
execException.declarations.some((decl) => ts.isInterfaceDeclaration(decl) &&
|
|
1454
|
+
ctx.isStdlibFile(ts.getSourceFileOfNode(decl)) &&
|
|
1455
|
+
isDeclaredInAmbientModule(decl, "child_process"))) {
|
|
1113
1456
|
return { kind: "object", className: "%Error" };
|
|
1114
1457
|
}
|
|
1115
1458
|
if (isOsConstantsType(type, ctx) || isLegacyUrlType(type, ctx))
|
|
1116
1459
|
return DYN;
|
|
1460
|
+
// The WebAssembly API's values have the checked-dynamic representation, so
|
|
1461
|
+
// declarations that merely mention them compile; each reached use of the
|
|
1462
|
+
// API itself is refused at its site (builtins/webassembly.ts).
|
|
1463
|
+
if (isWebAssemblyType(type, ctx))
|
|
1464
|
+
return DYN;
|
|
1465
|
+
// A union over one of them (quickjs-wasi's `BufferSource | WebAssembly.Module`
|
|
1466
|
+
// option) holds that dynamic value too, so the whole union is dynamic.
|
|
1467
|
+
if (type.isUnionType() && ts.constituentTypes(type).some((t) => isWebAssemblyType(t, ctx)))
|
|
1468
|
+
return DYN;
|
|
1469
|
+
// JavaScript inference merges WebAssembly.instantiate's overloads into
|
|
1470
|
+
// `Promise<WebAssemblyInstantiatedSource> & Promise<Instance>`: a promise
|
|
1471
|
+
// of a WebAssembly value either way.
|
|
1472
|
+
if (type.isIntersectionType() &&
|
|
1473
|
+
ts.constituentTypes(type).every((t) => {
|
|
1474
|
+
if (ts.symbolNameOf(t.getSymbol()) !== "Promise")
|
|
1475
|
+
return false;
|
|
1476
|
+
const arg = ctx.checker.getTypeArguments(t)[0];
|
|
1477
|
+
return arg !== undefined && isWebAssemblyType(arg, ctx);
|
|
1478
|
+
}))
|
|
1479
|
+
return { kind: "promise", inner: DYN };
|
|
1117
1480
|
// Immutable<T> (@scriptc/types) is a deep-readonly view: the value is
|
|
1118
1481
|
// still the T it maps.
|
|
1119
1482
|
const immutableSource = immutableSourceType(type, ctx);
|
|
1120
1483
|
if (immutableSource !== null)
|
|
1121
1484
|
return mapType(immutableSource, ctx);
|
|
1485
|
+
// Inside an erased generic signature or body, every type that mentions
|
|
1486
|
+
// an erased type parameter is `unknown` (`T[]`, `Map<string, T>`,
|
|
1487
|
+
// `[A, B]`, `T[K]`, callbacks over `T`): its values cross through the
|
|
1488
|
+
// checked-dynamic boundary, as JavaScript sees them. The erased
|
|
1489
|
+
// signature itself maps its parameters and result this way.
|
|
1490
|
+
if ((ctx.erasingSignature || ctx.isErasing?.()) &&
|
|
1491
|
+
!(type.flags & ts.TypeFlags.TypeParameter) &&
|
|
1492
|
+
!checker.getCallSignatures(type).some((sig) => sig === ctx.erasingSignature) &&
|
|
1493
|
+
!ERASURE_KEPT_CONTAINERS.has(ts.symbolNameOf(type.getSymbol()) ?? "") &&
|
|
1494
|
+
mentionsErasedTypeParam(type, ctx, 0)) {
|
|
1495
|
+
contextResolutions++;
|
|
1496
|
+
return DYN;
|
|
1497
|
+
}
|
|
1498
|
+
// Readonly<C> over a program class (Object.freeze's result type) is the
|
|
1499
|
+
// same instance.
|
|
1500
|
+
const readonlyClass = readonlyClassType(type, ctx);
|
|
1501
|
+
if (readonlyClass !== null)
|
|
1502
|
+
return readonlyClass;
|
|
1122
1503
|
if (resolveTypeParam && type.flags & ts.TypeFlags.TypeParameter) {
|
|
1123
1504
|
const bound = resolveTypeParam(type);
|
|
1124
1505
|
if (bound) {
|
|
@@ -1157,6 +1538,27 @@ function mapTypeInner(type, ctx) {
|
|
|
1157
1538
|
contextResolutions++;
|
|
1158
1539
|
return viaIndexed;
|
|
1159
1540
|
}
|
|
1541
|
+
// `Parameters<F>` / `ReturnType<F>` over a bound function-typed
|
|
1542
|
+
// parameter (variadic higher-order wrappers): the checker keeps both
|
|
1543
|
+
// conditionals symbolic inside the body, and their `infer` positions
|
|
1544
|
+
// match a call signature, which matchInferReference cannot decide.
|
|
1545
|
+
const viaSignature = mapBoundSignatureAlias(type, ctx) ?? mapBoundKeyofNeverConditional(type, ctx);
|
|
1546
|
+
if (viaSignature !== null) {
|
|
1547
|
+
contextResolutions++;
|
|
1548
|
+
return viaSignature;
|
|
1549
|
+
}
|
|
1550
|
+
// A conditional type over a bound parameter (`Infer<S["left"]>`, a
|
|
1551
|
+
// mapped type's member): evaluate it against the bindings.
|
|
1552
|
+
if (type.isConditionalType()) {
|
|
1553
|
+
const evaluated = evalMappedTemplate(type, new Map(), new Map(), ctx);
|
|
1554
|
+
if (evaluated && evaluated !== type) {
|
|
1555
|
+
const viaConditional = mapType(evaluated, ctx);
|
|
1556
|
+
if (viaConditional !== null) {
|
|
1557
|
+
contextResolutions++;
|
|
1558
|
+
return viaConditional;
|
|
1559
|
+
}
|
|
1560
|
+
}
|
|
1561
|
+
}
|
|
1160
1562
|
}
|
|
1161
1563
|
const widened = checker.getBaseTypeOfLiteralType(type);
|
|
1162
1564
|
const flags = widened.flags;
|
|
@@ -1171,8 +1573,9 @@ function mapTypeInner(type, ctx) {
|
|
|
1171
1573
|
// checked-dynamic object retains that distinction through forwarding
|
|
1172
1574
|
// constructors. Only the standard library's interface gets this ABI.
|
|
1173
1575
|
const errorOptionsSymbol = widened.getSymbol();
|
|
1174
|
-
if (errorOptionsSymbol
|
|
1175
|
-
|
|
1576
|
+
if (errorOptionsSymbol !== undefined &&
|
|
1577
|
+
ts.symbolName(errorOptionsSymbol) === "ErrorOptions" &&
|
|
1578
|
+
errorOptionsSymbol.declarations.some((d) => ctx.isStdlibFile(ts.getSourceFileOfNode(d)))) {
|
|
1176
1579
|
return DYN;
|
|
1177
1580
|
}
|
|
1178
1581
|
// node:util.parseArgs config/results are declaration-heavy conditional
|
|
@@ -1186,7 +1589,7 @@ function mapTypeInner(type, ctx) {
|
|
|
1186
1589
|
{
|
|
1187
1590
|
const parseArgsSym = widened.getAliasSymbol() ?? widened.getSymbol();
|
|
1188
1591
|
const belongs = (declaration) => {
|
|
1189
|
-
if (!ctx.isStdlibFile(
|
|
1592
|
+
if (!ctx.isStdlibFile(ts.getSourceFileOfNode(declaration)))
|
|
1190
1593
|
return false;
|
|
1191
1594
|
let family = false;
|
|
1192
1595
|
for (let node = declaration; node; node = node.parent) {
|
|
@@ -1200,15 +1603,14 @@ function mapTypeInner(type, ctx) {
|
|
|
1200
1603
|
return false;
|
|
1201
1604
|
};
|
|
1202
1605
|
if (parseArgsSym &&
|
|
1203
|
-
PARSE_ARGS_DYN_TYPES.has(parseArgsSym
|
|
1204
|
-
|
|
1606
|
+
PARSE_ARGS_DYN_TYPES.has(ts.symbolName(parseArgsSym)) &&
|
|
1607
|
+
parseArgsSym.declarations.some(belongs))
|
|
1205
1608
|
return DYN;
|
|
1206
1609
|
// ReturnType and instantiated conditional types can erase the alias.
|
|
1207
1610
|
// Require every member to retain the util declaration provenance so
|
|
1208
1611
|
// unrelated records with similar property names keep their own layout.
|
|
1209
1612
|
const members = checker.getPropertiesOfType(widened);
|
|
1210
|
-
if (members.length > 0 &&
|
|
1211
|
-
members.every((member) => checker.declarationsOf(member).some(belongs)))
|
|
1613
|
+
if (members.length > 0 && members.every((member) => member.declarations.some(belongs)))
|
|
1212
1614
|
return DYN;
|
|
1213
1615
|
}
|
|
1214
1616
|
// The lib's BOXED wrapper interfaces used as TYPES (`const n: Number =
|
|
@@ -1219,9 +1621,15 @@ function mapTypeInner(type, ctx) {
|
|
|
1219
1621
|
{
|
|
1220
1622
|
const boxSym = widened.getSymbol();
|
|
1221
1623
|
if (boxSym &&
|
|
1222
|
-
(boxSym
|
|
1223
|
-
|
|
1224
|
-
|
|
1624
|
+
(ts.symbolName(boxSym) === "Number" ||
|
|
1625
|
+
ts.symbolName(boxSym) === "String" ||
|
|
1626
|
+
ts.symbolName(boxSym) === "Boolean") &&
|
|
1627
|
+
boxSym.declarations.some((d) => ctx.isStdlibFile(ts.getSourceFileOfNode(d)))) {
|
|
1628
|
+
return ts.symbolName(boxSym) === "Number"
|
|
1629
|
+
? F64
|
|
1630
|
+
: ts.symbolName(boxSym) === "String"
|
|
1631
|
+
? STRING
|
|
1632
|
+
: BOOL;
|
|
1225
1633
|
}
|
|
1226
1634
|
}
|
|
1227
1635
|
// The lib's PRIMITIVE-CONSTRUCTOR interfaces as TYPES (`typeof String`,
|
|
@@ -1238,13 +1646,13 @@ function mapTypeInner(type, ctx) {
|
|
|
1238
1646
|
{
|
|
1239
1647
|
const ctorSym = widened.getSymbol();
|
|
1240
1648
|
if (ctorSym &&
|
|
1241
|
-
(ctorSym
|
|
1242
|
-
ctorSym
|
|
1243
|
-
ctorSym
|
|
1244
|
-
|
|
1245
|
-
return funcOf([STRING], ctorSym
|
|
1649
|
+
(ts.symbolName(ctorSym) === "StringConstructor" ||
|
|
1650
|
+
ts.symbolName(ctorSym) === "NumberConstructor" ||
|
|
1651
|
+
ts.symbolName(ctorSym) === "BooleanConstructor") &&
|
|
1652
|
+
ctorSym.declarations.some((d) => ctx.isStdlibFile(ts.getSourceFileOfNode(d)))) {
|
|
1653
|
+
return funcOf([STRING], ts.symbolName(ctorSym) === "StringConstructor"
|
|
1246
1654
|
? STRING
|
|
1247
|
-
: ctorSym
|
|
1655
|
+
: ts.symbolName(ctorSym) === "NumberConstructor"
|
|
1248
1656
|
? F64
|
|
1249
1657
|
: BOOL);
|
|
1250
1658
|
}
|
|
@@ -1348,16 +1756,21 @@ function mapTypeInner(type, ctx) {
|
|
|
1348
1756
|
return hasStr ? STRING : F64;
|
|
1349
1757
|
}
|
|
1350
1758
|
}
|
|
1351
|
-
// @scriptc/experimental's LifetimeRegion and
|
|
1352
|
-
// program classes, provenance-checked by the package's
|
|
1759
|
+
// @scriptc/experimental's LifetimeRegion, InternTable and ThreadSlots:
|
|
1760
|
+
// synthetic program classes, provenance-checked by the package's
|
|
1761
|
+
// declaration file.
|
|
1353
1762
|
{
|
|
1354
1763
|
const classSym = widened.getSymbol();
|
|
1355
|
-
const name = classSym
|
|
1356
|
-
if (name === "LifetimeRegion" || name === "InternTable") {
|
|
1357
|
-
for (const d of
|
|
1764
|
+
const name = ts.symbolNameOf(classSym);
|
|
1765
|
+
if (name === "LifetimeRegion" || name === "InternTable" || name === "ThreadSlots") {
|
|
1766
|
+
for (const d of classSym.declarations) {
|
|
1358
1767
|
if (!ts.isClassDeclaration(d))
|
|
1359
1768
|
continue;
|
|
1360
|
-
const synthetic = name === "LifetimeRegion"
|
|
1769
|
+
const synthetic = name === "LifetimeRegion"
|
|
1770
|
+
? ctx.lifetimeRegionClass?.(d)
|
|
1771
|
+
: name === "InternTable"
|
|
1772
|
+
? ctx.internTableClass?.(d)
|
|
1773
|
+
: ctx.threadSlotsClass?.(d);
|
|
1361
1774
|
if (synthetic)
|
|
1362
1775
|
return synthetic;
|
|
1363
1776
|
}
|
|
@@ -1366,15 +1779,35 @@ function mapTypeInner(type, ctx) {
|
|
|
1366
1779
|
// Declaration-only package types have no compiled implementation.
|
|
1367
1780
|
// Primitive and container types retain their structural mappings; types
|
|
1368
1781
|
// owned by the standard library or explicit host mappings are handled
|
|
1369
|
-
// by their dedicated native rules.
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1782
|
+
// by their dedicated native rules. Pure type shapes — interfaces, type
|
|
1783
|
+
// aliases, and object or mapped type literals with no value declaration
|
|
1784
|
+
// merged in — describe data, not an implementation: a program value of
|
|
1785
|
+
// such a type is one the program built itself (`import type` from a
|
|
1786
|
+
// types-only package), so it maps structurally like a local declaration.
|
|
1787
|
+
// Values the package itself would produce stay refused at their import.
|
|
1788
|
+
const packageOnly = (sym) => {
|
|
1789
|
+
const decls = sym ? sym.declarations : undefined;
|
|
1790
|
+
return decls &&
|
|
1791
|
+
decls.length > 0 &&
|
|
1792
|
+
decls.every((d) => {
|
|
1793
|
+
const sf = ts.getSourceFileOfNode(d);
|
|
1794
|
+
return sf.isDeclarationFile && !ctx.isStdlibFile(sf) && !ctx.isExternalTypeFile(sf);
|
|
1795
|
+
})
|
|
1796
|
+
? decls
|
|
1797
|
+
: null;
|
|
1798
|
+
};
|
|
1799
|
+
const pureTypeShape = (decls) => decls === null ||
|
|
1800
|
+
decls.every((d) => packageTypeFile(ts.getSourceFileOfNode(d), ctx) &&
|
|
1801
|
+
(ts.isInterfaceDeclaration(d) ||
|
|
1802
|
+
ts.isTypeAliasDeclaration(d) ||
|
|
1803
|
+
ts.isTypeLiteralNode(d) ||
|
|
1804
|
+
ts.isMappedTypeNode(d) ||
|
|
1805
|
+
isDeclaredDataClass(d) ||
|
|
1806
|
+
(decls.some(isDeclaredDataClass) && isTypeOnlyNamespace(d))));
|
|
1807
|
+
const aliasDecls = packageOnly(widened.getAliasSymbol());
|
|
1808
|
+
const ownDecls = packageOnly(widened.getSymbol());
|
|
1809
|
+
if ((aliasDecls !== null || (widened.getAliasSymbol() === undefined && ownDecls !== null)) &&
|
|
1810
|
+
!(pureTypeShape(aliasDecls) && pureTypeShape(ownDecls))) {
|
|
1378
1811
|
return null;
|
|
1379
1812
|
}
|
|
1380
1813
|
// Module namespaces were claimed above when they name compiled source
|
|
@@ -1567,19 +2000,24 @@ function mapTypeInner(type, ctx) {
|
|
|
1567
2000
|
// Class instances name a program class. The same symbol with construct
|
|
1568
2001
|
// signatures names its static side, mapped to classval below.
|
|
1569
2002
|
const widenedSym = widened.getSymbol();
|
|
1570
|
-
const classDecl = widenedSym ?
|
|
2003
|
+
const classDecl = widenedSym ? widenedSym.valueDeclaration : undefined;
|
|
1571
2004
|
if (classDecl &&
|
|
1572
2005
|
(ts.isClassDeclaration(classDecl) || ts.isClassExpression(classDecl)) &&
|
|
1573
2006
|
// Nameless class DECLARATIONS are legal only as `export default class
|
|
1574
2007
|
// {}` — classNamer spells them "%anon" (unique per file), the same
|
|
1575
2008
|
// name their collection registered.
|
|
1576
|
-
!
|
|
1577
|
-
checker.getConstructSignatures(widened).length === 0
|
|
1578
|
-
//
|
|
1579
|
-
//
|
|
1580
|
-
//
|
|
1581
|
-
//
|
|
1582
|
-
|
|
2009
|
+
!ts.getSourceFileOfNode(classDecl).isDeclarationFile &&
|
|
2010
|
+
checker.getConstructSignatures(widened).length === 0 &&
|
|
2011
|
+
// A TypeScript class declared OUTSIDE the lowered program (reached
|
|
2012
|
+
// through `import type` alone) never registers, and the program can
|
|
2013
|
+
// hold no instance of it: its instance type maps below as the
|
|
2014
|
+
// structural type it describes, like an interface.
|
|
2015
|
+
(ctx.isProgramFile(ts.getSourceFileOfNode(classDecl)) ||
|
|
2016
|
+
isJsSourceFile(ts.getSourceFileOfNode(classDecl)))) {
|
|
2017
|
+
// A JavaScript class outside the lowered program (jsdoc `typeof
|
|
2018
|
+
// import()` over a never-required module) stays unmappable: JSDoc
|
|
2019
|
+
// types are not checked, so its slots fall back to the dynamic value.
|
|
2020
|
+
if (!ctx.isProgramFile(ts.getSourceFileOfNode(classDecl)))
|
|
1583
2021
|
return null;
|
|
1584
2022
|
// The class inside a MIXIN function: per-call-site instantiations
|
|
1585
2023
|
// share this one node — the CURRENT instantiation (collecting or
|
|
@@ -1593,7 +2031,7 @@ function mapTypeInner(type, ctx) {
|
|
|
1593
2031
|
}
|
|
1594
2032
|
}
|
|
1595
2033
|
if (classExprNeedsContext(classDecl)) {
|
|
1596
|
-
const local = ctx.localClassInstance?.(classDecl);
|
|
2034
|
+
const local = ctx.localClassInstance?.(classDecl, widened);
|
|
1597
2035
|
if (local)
|
|
1598
2036
|
contextResolutions++;
|
|
1599
2037
|
return local ?? null;
|
|
@@ -1601,7 +2039,7 @@ function mapTypeInner(type, ctx) {
|
|
|
1601
2039
|
// A GENERIC class's instance type (`Box<number>`) maps to the concrete
|
|
1602
2040
|
// INSTANTIATION's class (`Box%0`), registered on demand — the Lowerer
|
|
1603
2041
|
// hook owns the instance table (monomorphization by flow).
|
|
1604
|
-
if (classDecl.typeParameters) {
|
|
2042
|
+
if (classDecl.typeParameters?.nodes) {
|
|
1605
2043
|
const instance = ctx.genericClassInstance?.(classDecl, widened, (argument) => mapType(argument, ctx)) ??
|
|
1606
2044
|
null;
|
|
1607
2045
|
// Before the generic declaration's collection turn, the hook can only
|
|
@@ -1613,14 +2051,21 @@ function mapTypeInner(type, ctx) {
|
|
|
1613
2051
|
}
|
|
1614
2052
|
return { kind: "object", className: classNamer(classDecl) };
|
|
1615
2053
|
}
|
|
2054
|
+
// A runtime-provided class's static side (`typeof EventEmitter`,
|
|
2055
|
+
// `typeof Readable`, `ErrorConstructor`): that class's value.
|
|
2056
|
+
{
|
|
2057
|
+
const runtimeClass = ctx.runtimeClassValue?.(widened);
|
|
2058
|
+
if (runtimeClass)
|
|
2059
|
+
return { kind: "classval", className: runtimeClass };
|
|
2060
|
+
}
|
|
1616
2061
|
// The class STATIC side (`typeof C` — the class name as a value): the
|
|
1617
2062
|
// same symbol WITH its construct signatures. Program classes only; lib
|
|
1618
2063
|
// and package statics keep their fences.
|
|
1619
2064
|
if (classDecl &&
|
|
1620
2065
|
(ts.isClassDeclaration(classDecl) || ts.isClassExpression(classDecl)) &&
|
|
1621
|
-
!
|
|
2066
|
+
!ts.getSourceFileOfNode(classDecl).isDeclarationFile &&
|
|
1622
2067
|
checker.getConstructSignatures(widened).length > 0) {
|
|
1623
|
-
if (!ctx.isProgramFile(
|
|
2068
|
+
if (!ctx.isProgramFile(ts.getSourceFileOfNode(classDecl)))
|
|
1624
2069
|
return null;
|
|
1625
2070
|
// The MIXIN class node's static side (`typeof C` inside the mixin):
|
|
1626
2071
|
// the current instantiation's classval, like the instance type above.
|
|
@@ -1632,7 +2077,8 @@ function mapTypeInner(type, ctx) {
|
|
|
1632
2077
|
}
|
|
1633
2078
|
}
|
|
1634
2079
|
if (classExprNeedsContext(classDecl)) {
|
|
1635
|
-
const
|
|
2080
|
+
const ctorSigs = checker.getConstructSignatures(widened);
|
|
2081
|
+
const local = ctx.localClassInstance?.(classDecl, ctorSigs.length === 1 ? checker.getReturnTypeOfSignature(ctorSigs[0]) : undefined);
|
|
1636
2082
|
if (local?.kind === "object") {
|
|
1637
2083
|
contextResolutions++;
|
|
1638
2084
|
return { kind: "classval", className: local.className };
|
|
@@ -1645,7 +2091,7 @@ function mapTypeInner(type, ctx) {
|
|
|
1645
2091
|
// the instantiation's classval. Uninstantiated `typeof Box` keeps the
|
|
1646
2092
|
// type parameter in the construct signature's return — unmapped (the
|
|
1647
2093
|
// family has no thunk and no single constructor ABI).
|
|
1648
|
-
if (classDecl.typeParameters) {
|
|
2094
|
+
if (classDecl.typeParameters?.nodes) {
|
|
1649
2095
|
const ctorSigs = checker.getConstructSignatures(widened);
|
|
1650
2096
|
if (ctorSigs.length !== 1)
|
|
1651
2097
|
return null;
|
|
@@ -1681,10 +2127,15 @@ function mapTypeInner(type, ctx) {
|
|
|
1681
2127
|
// outside stays unmapped — callers report the component fence (SC2009)
|
|
1682
2128
|
// naming the offending half, as does the `new Map` lowering per site.
|
|
1683
2129
|
const psym = widened.getSymbol();
|
|
1684
|
-
const isStdlibInterface = (name) => psym
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
2130
|
+
const isStdlibInterface = (name) => psym !== undefined &&
|
|
2131
|
+
ts.symbolName(psym) === name &&
|
|
2132
|
+
psym.declarations.some((d) => ts.isInterfaceDeclaration(d) && ctx.isStdlibFile(ts.getSourceFileOfNode(d)));
|
|
2133
|
+
// The timer handles: an interface in the fallback and in @types/node 22+,
|
|
2134
|
+
// a class (`class Timeout implements Timer`) in @types/node 20 and older.
|
|
2135
|
+
const isStdlibTimerHandle = (name) => psym !== undefined &&
|
|
2136
|
+
ts.symbolName(psym) === name &&
|
|
2137
|
+
psym.declarations.some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
|
|
2138
|
+
ctx.isStdlibFile(ts.getSourceFileOfNode(d)));
|
|
1688
2139
|
// The builtin Error classes: references to the lib's Error interfaces map to the runtime-provided class
|
|
1689
2140
|
// hierarchy (provenance, not the name — a user's own `class Error`
|
|
1690
2141
|
// resolved through the class-instance branch above, and a user
|
|
@@ -1697,10 +2148,9 @@ function mapTypeInner(type, ctx) {
|
|
|
1697
2148
|
}
|
|
1698
2149
|
// node:assert's AssertionError is declared as a class (in the shipped
|
|
1699
2150
|
// fallback and in @types/node), not as a lib interface.
|
|
1700
|
-
if (psym
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
.some((d) => ts.isClassDeclaration(d) && ctx.isStdlibFile(d.getSourceFile())))
|
|
2151
|
+
if (psym !== undefined &&
|
|
2152
|
+
ts.symbolName(psym) === "AssertionError" &&
|
|
2153
|
+
psym.declarations.some((d) => ts.isClassDeclaration(d) && ctx.isStdlibFile(ts.getSourceFileOfNode(d))))
|
|
1704
2154
|
return { kind: "object", className: "%AssertionError" };
|
|
1705
2155
|
// The lib's `Object` interface is a TOP type: tsc admits every
|
|
1706
2156
|
// non-nullish value into an `Object` slot (`const x: Object = "s"`), so
|
|
@@ -1716,12 +2166,11 @@ function mapTypeInner(type, ctx) {
|
|
|
1716
2166
|
// module lowering before generic number operations can observe the
|
|
1717
2167
|
// representation. The node:module class's merged instance interface is
|
|
1718
2168
|
// included, while unrelated user interfaces named Module stay structural.
|
|
1719
|
-
if ((psym
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
.
|
|
1723
|
-
|
|
1724
|
-
(psym.name === "ScriptcModule" ||
|
|
2169
|
+
if (((psym !== undefined && ts.symbolName(psym) === "ScriptcModule") ||
|
|
2170
|
+
(psym !== undefined && ts.symbolName(psym) === "Module")) &&
|
|
2171
|
+
psym.declarations.some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
|
|
2172
|
+
ctx.isStdlibFile(ts.getSourceFileOfNode(d)) &&
|
|
2173
|
+
(ts.symbolName(psym) === "ScriptcModule" ||
|
|
1725
2174
|
isDeclaredInAmbientNamespace(d, "NodeJS") ||
|
|
1726
2175
|
isDeclaredInAmbientModule(d, "module")))) {
|
|
1727
2176
|
return F64;
|
|
@@ -1733,11 +2182,10 @@ function mapTypeInner(type, ctx) {
|
|
|
1733
2182
|
// (generic) class plus a same-named interface — and @types/node's
|
|
1734
2183
|
// NodeJS.EventEmitter interface (the structural surface net.Socket
|
|
1735
2184
|
// et al. extend) is the same runtime value. Provenance-checked.
|
|
1736
|
-
if (psym
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
.
|
|
1740
|
-
ctx.isStdlibFile(d.getSourceFile()) &&
|
|
2185
|
+
if (psym !== undefined &&
|
|
2186
|
+
ts.symbolName(psym) === "EventEmitter" &&
|
|
2187
|
+
psym.declarations.some((d) => (ts.isClassDeclaration(d) || ts.isInterfaceDeclaration(d)) &&
|
|
2188
|
+
ctx.isStdlibFile(ts.getSourceFileOfNode(d)) &&
|
|
1741
2189
|
(isDeclaredInAmbientModule(d, "events") || isDeclaredInAmbientNamespace(d, "NodeJS")))) {
|
|
1742
2190
|
return { kind: "object", className: RUNTIME_EMITTER_CLASS };
|
|
1743
2191
|
}
|
|
@@ -1745,11 +2193,10 @@ function mapTypeInner(type, ctx) {
|
|
|
1745
2193
|
// value is an f64 handle into the runtime's registry (the Timeout-id
|
|
1746
2194
|
// precedent). The NAME is generic, so the provenance check adds the
|
|
1747
2195
|
// enclosing ambient module, like net.Server.
|
|
1748
|
-
if (psym
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
.
|
|
1752
|
-
ctx.isStdlibFile(d.getSourceFile()) &&
|
|
2196
|
+
if (psym !== undefined &&
|
|
2197
|
+
ts.symbolName(psym) === "Interface" &&
|
|
2198
|
+
psym.declarations.some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
|
|
2199
|
+
ctx.isStdlibFile(ts.getSourceFileOfNode(d)) &&
|
|
1753
2200
|
(isDeclaredInAmbientModule(d, "readline") ||
|
|
1754
2201
|
isDeclaredInAmbientModule(d, "readline/promises")))) {
|
|
1755
2202
|
return F64;
|
|
@@ -1757,21 +2204,19 @@ function mapTypeInner(type, ctx) {
|
|
|
1757
2204
|
// readline.Key: emitKeys' key object stays a checked-dynamic value, so
|
|
1758
2205
|
// it keeps Node's own shape (an undefined name, the escape sequences'
|
|
1759
2206
|
// code member).
|
|
1760
|
-
if (psym
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
.
|
|
1764
|
-
ctx.isStdlibFile(d.getSourceFile()) &&
|
|
2207
|
+
if (psym !== undefined &&
|
|
2208
|
+
ts.symbolName(psym) === "Key" &&
|
|
2209
|
+
psym.declarations.some((d) => ts.isInterfaceDeclaration(d) &&
|
|
2210
|
+
ctx.isStdlibFile(ts.getSourceFileOfNode(d)) &&
|
|
1765
2211
|
(isDeclaredInAmbientModule(d, "readline") ||
|
|
1766
2212
|
isDeclaredInAmbientModule(d, "readline/promises")))) {
|
|
1767
2213
|
return DYN;
|
|
1768
2214
|
}
|
|
1769
2215
|
// readline/promises.Readline: an f64 handle the same way.
|
|
1770
|
-
if (psym
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
.
|
|
1774
|
-
ctx.isStdlibFile(d.getSourceFile()) &&
|
|
2216
|
+
if (psym !== undefined &&
|
|
2217
|
+
ts.symbolName(psym) === "Readline" &&
|
|
2218
|
+
psym.declarations.some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
|
|
2219
|
+
ctx.isStdlibFile(ts.getSourceFileOfNode(d)) &&
|
|
1775
2220
|
isDeclaredInAmbientModule(d, "readline/promises"))) {
|
|
1776
2221
|
return F64;
|
|
1777
2222
|
}
|
|
@@ -1781,39 +2226,36 @@ function mapTypeInner(type, ctx) {
|
|
|
1781
2226
|
// Provenance: the name is specific enough that stdlib-file provenance
|
|
1782
2227
|
// plus the ambient module suffices for both the fallback declarations
|
|
1783
2228
|
// and @types/node's class Channel<StoreType, ContextType>.
|
|
1784
|
-
if (psym
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
.
|
|
1788
|
-
ctx.isStdlibFile(d.getSourceFile()) &&
|
|
2229
|
+
if (psym !== undefined &&
|
|
2230
|
+
ts.symbolName(psym) === "Channel" &&
|
|
2231
|
+
psym.declarations.some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
|
|
2232
|
+
ctx.isStdlibFile(ts.getSourceFileOfNode(d)) &&
|
|
1789
2233
|
isDeclaredInAmbientModule(d, "diagnostics_channel"))) {
|
|
1790
2234
|
return F64;
|
|
1791
2235
|
}
|
|
1792
2236
|
// async_hooks.AsyncLocalStorage: the store value is an f64 handle into
|
|
1793
2237
|
// the runtime's store id space (the Channel story — stores are
|
|
1794
2238
|
// process-lived; contexts ride the fiber machinery).
|
|
1795
|
-
if (psym
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
.
|
|
1799
|
-
ctx.isStdlibFile(d.getSourceFile()) &&
|
|
2239
|
+
if (psym !== undefined &&
|
|
2240
|
+
ts.symbolName(psym) === "AsyncLocalStorage" &&
|
|
2241
|
+
psym.declarations.some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
|
|
2242
|
+
ctx.isStdlibFile(ts.getSourceFileOfNode(d)) &&
|
|
1800
2243
|
isDeclaredInAmbientModule(d, "async_hooks"))) {
|
|
1801
2244
|
return F64;
|
|
1802
2245
|
}
|
|
1803
2246
|
// diagnostics_channel.TracingChannel: the same f64-handle story over the
|
|
1804
2247
|
// runtime's tracing registry (five event channels per entry).
|
|
1805
|
-
if (psym
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
.
|
|
1809
|
-
ctx.isStdlibFile(d.getSourceFile()) &&
|
|
2248
|
+
if (psym !== undefined &&
|
|
2249
|
+
ts.symbolName(psym) === "TracingChannel" &&
|
|
2250
|
+
psym.declarations.some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
|
|
2251
|
+
ctx.isStdlibFile(ts.getSourceFileOfNode(d)) &&
|
|
1810
2252
|
isDeclaredInAmbientModule(d, "diagnostics_channel"))) {
|
|
1811
2253
|
return F64;
|
|
1812
2254
|
}
|
|
1813
2255
|
// Node names this result; the ambient WHATWG declaration uses a type literal.
|
|
1814
2256
|
const encodeResult = psym &&
|
|
1815
|
-
|
|
1816
|
-
if (!ctx.isStdlibFile(
|
|
2257
|
+
psym.declarations.some((decl) => {
|
|
2258
|
+
if (!ctx.isStdlibFile(ts.getSourceFileOfNode(decl)))
|
|
1817
2259
|
return false;
|
|
1818
2260
|
if (ts.isInterfaceDeclaration(decl) && decl.name.text === "EncodeIntoResult")
|
|
1819
2261
|
return true;
|
|
@@ -1837,16 +2279,15 @@ function mapTypeInner(type, ctx) {
|
|
|
1837
2279
|
};
|
|
1838
2280
|
// WHATWG codec instances have ordinary reference identity and ownership.
|
|
1839
2281
|
// Their private encoding slot is omitted from enumeration and JSON.
|
|
1840
|
-
if ((psym
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
.
|
|
1844
|
-
ctx.isStdlibFile(d.getSourceFile()))) {
|
|
2282
|
+
if (((psym !== undefined && ts.symbolName(psym) === "TextEncoder") ||
|
|
2283
|
+
(psym !== undefined && ts.symbolName(psym) === "TextDecoder")) &&
|
|
2284
|
+
psym.declarations.some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
|
|
2285
|
+
ctx.isStdlibFile(ts.getSourceFileOfNode(d)))) {
|
|
1845
2286
|
return {
|
|
1846
2287
|
kind: "record",
|
|
1847
2288
|
shapeId: ctx.shapes.intern([
|
|
1848
|
-
{ name: `%${psym
|
|
1849
|
-
...(psym
|
|
2289
|
+
{ name: `%${ts.symbolName(psym)}`, type: F64 },
|
|
2290
|
+
...(ts.symbolName(psym) === "TextDecoder"
|
|
1850
2291
|
? [
|
|
1851
2292
|
{ name: "%fatal", type: BOOL },
|
|
1852
2293
|
{ name: "%ignoreBOM", type: BOOL },
|
|
@@ -1863,11 +2304,10 @@ function mapTypeInner(type, ctx) {
|
|
|
1863
2304
|
// checked like Stats; construction and the write/end methods are
|
|
1864
2305
|
// special-cased in lowerNew / lowerStringDecoderMethodCall, so the
|
|
1865
2306
|
// record shape never surfaces.
|
|
1866
|
-
if (psym
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
.
|
|
1870
|
-
ctx.isStdlibFile(d.getSourceFile()))) {
|
|
2307
|
+
if (psym !== undefined &&
|
|
2308
|
+
ts.symbolName(psym) === "StringDecoder" &&
|
|
2309
|
+
psym.declarations.some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
|
|
2310
|
+
ctx.isStdlibFile(ts.getSourceFileOfNode(d)))) {
|
|
1871
2311
|
return {
|
|
1872
2312
|
kind: "record",
|
|
1873
2313
|
shapeId: ctx.shapes.intern([
|
|
@@ -1886,14 +2326,14 @@ function mapTypeInner(type, ctx) {
|
|
|
1886
2326
|
// record-holding binding forms compile. User-declared literals with
|
|
1887
2327
|
// these member names keep the ordinary record path (their declarations
|
|
1888
2328
|
// are not in declaration files).
|
|
1889
|
-
const promiseDeclarations = psym ?
|
|
2329
|
+
const promiseDeclarations = psym ? psym.declarations : [];
|
|
1890
2330
|
if (flags & ts.TypeFlags.Object &&
|
|
1891
2331
|
promiseDeclarations.length > 0 &&
|
|
1892
|
-
promiseDeclarations.every((d) =>
|
|
2332
|
+
promiseDeclarations.every((d) => ts.getSourceFileOfNode(d).isDeclarationFile)) {
|
|
1893
2333
|
const props = checker.getPropertiesOfType(widened);
|
|
1894
2334
|
if (props.length === 3 &&
|
|
1895
|
-
["promise", "resolve", "reject"].every((n) => props.some((p) => p
|
|
1896
|
-
const promProp = props.find((p) => p
|
|
2335
|
+
["promise", "resolve", "reject"].every((n) => props.some((p) => ts.symbolName(p) === n))) {
|
|
2336
|
+
const promProp = props.find((p) => ts.symbolName(p) === "promise");
|
|
1897
2337
|
const promT = mapType(checker.getTypeOfSymbol(promProp), ctx);
|
|
1898
2338
|
if (promT?.kind === "promise") {
|
|
1899
2339
|
const inner = promT.inner;
|
|
@@ -1930,6 +2370,27 @@ function mapTypeInner(type, ctx) {
|
|
|
1930
2370
|
// stdio and env values. Keep it checked-dynamic for native normalization.
|
|
1931
2371
|
if (isStdlibInterface("SpawnOptions"))
|
|
1932
2372
|
return DYN;
|
|
2373
|
+
// dns.LookupAllOptions (`all: true`, the overload whose callback takes
|
|
2374
|
+
// an address list): a lookup option bag dns.lookup reads at run time.
|
|
2375
|
+
// It rides checked-dynamic storage, so the lookup function type that
|
|
2376
|
+
// takes `LookupOneOptions | LookupAllOptions | number` compiles.
|
|
2377
|
+
if (isStdlibInterface("LookupAllOptions"))
|
|
2378
|
+
return DYN;
|
|
2379
|
+
// http.RequestOptions / https.RequestOptions as a declared type: an
|
|
2380
|
+
// option record whose members include functions, agents and signals.
|
|
2381
|
+
// Values ride checked-dynamic storage, like SpawnOptions.
|
|
2382
|
+
if (psym !== undefined &&
|
|
2383
|
+
ts.symbolName(psym) === "RequestOptions" &&
|
|
2384
|
+
psym.declarations.some((d) => {
|
|
2385
|
+
if (!ts.isInterfaceDeclaration(d) || !ctx.isStdlibFile(ts.getSourceFileOfNode(d)))
|
|
2386
|
+
return false;
|
|
2387
|
+
for (let p = d.parent; p !== undefined; p = p.parent) {
|
|
2388
|
+
if (ts.isModuleDeclaration(p) && ts.isStringLiteral(p.name))
|
|
2389
|
+
return HTTP_REQUEST_OPTION_MODULES.has(p.name.text);
|
|
2390
|
+
}
|
|
2391
|
+
return false;
|
|
2392
|
+
}))
|
|
2393
|
+
return DYN;
|
|
1933
2394
|
// exactly like npm-declared types. Static fetch has one deliberately
|
|
1934
2395
|
// narrower native representation: Response is an opaque checked-
|
|
1935
2396
|
// dynamic capsule consumed only by the Response method lowerings, and
|
|
@@ -1942,10 +2403,9 @@ function mapTypeInner(type, ctx) {
|
|
|
1942
2403
|
// interfaces; @types/node's undici-types declares Response as a class).
|
|
1943
2404
|
{
|
|
1944
2405
|
const alias = widened.getAliasSymbol();
|
|
1945
|
-
if (alias
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
.some((d) => ts.isTypeAliasDeclaration(d) && ctx.isStdlibFile(d.getSourceFile()))) {
|
|
2406
|
+
if (alias !== undefined &&
|
|
2407
|
+
ts.symbolName(alias) === "ReadableStreamReadResult" &&
|
|
2408
|
+
alias.declarations.some((d) => ts.isTypeAliasDeclaration(d) && ctx.isStdlibFile(ts.getSourceFileOfNode(d)))) {
|
|
1949
2409
|
const elemTs = widened.getAliasTypeArguments()?.[0];
|
|
1950
2410
|
const elem = elemTs && elemTs.flags & ts.TypeFlags.Any ? DYN : elemTs ? mapType(elemTs, ctx) : null;
|
|
1951
2411
|
if (!elem)
|
|
@@ -1954,37 +2414,48 @@ function mapTypeInner(type, ctx) {
|
|
|
1954
2414
|
}
|
|
1955
2415
|
}
|
|
1956
2416
|
if (psym &&
|
|
1957
|
-
(psym
|
|
1958
|
-
psym
|
|
1959
|
-
|
|
1960
|
-
.declarationsOf(psym)
|
|
1961
|
-
.some((d) => ts.isInterfaceDeclaration(d) && ctx.isStdlibFile(d.getSourceFile()))) {
|
|
2417
|
+
(ts.symbolName(psym) === "ReadableStreamReadValueResult" ||
|
|
2418
|
+
ts.symbolName(psym) === "ReadableStreamReadDoneResult") &&
|
|
2419
|
+
psym.declarations.some((d) => ts.isInterfaceDeclaration(d) && ctx.isStdlibFile(ts.getSourceFileOfNode(d)))) {
|
|
1962
2420
|
const elemTs = checker.getTypeArguments(widened)[0];
|
|
1963
2421
|
const elem = elemTs && elemTs.flags & ts.TypeFlags.Any ? DYN : elemTs ? mapType(elemTs, ctx) : null;
|
|
1964
2422
|
if (!elem)
|
|
1965
2423
|
return null;
|
|
1966
2424
|
return genResultRecord(elem, VOID, ctx.shapes, ctx.unions);
|
|
1967
2425
|
}
|
|
2426
|
+
// node:net's SocketAddress and BlockList: native handles (scr_net.c)
|
|
2427
|
+
// whose getters and methods dispatch through the handle.
|
|
2428
|
+
if (((psym !== undefined && ts.symbolName(psym) === "SocketAddress") ||
|
|
2429
|
+
(psym !== undefined && ts.symbolName(psym) === "BlockList")) &&
|
|
2430
|
+
psym.declarations.some((d) => (ts.isClassDeclaration(d) || ts.isInterfaceDeclaration(d)) &&
|
|
2431
|
+
ctx.isStdlibFile(ts.getSourceFileOfNode(d)))) {
|
|
2432
|
+
return DYN;
|
|
2433
|
+
}
|
|
2434
|
+
// WebCrypto: the crypto global and its subtle object are dynamic
|
|
2435
|
+
// objects, CryptoKey values are native handles (scr_webcrypto.c), and
|
|
2436
|
+
// the algorithm dictionaries the methods take and keys report are plain
|
|
2437
|
+
// checked-dynamic objects.
|
|
2438
|
+
if (psym &&
|
|
2439
|
+
WEBCRYPTO_DYN_TYPES.has(ts.symbolName(psym)) &&
|
|
2440
|
+
psym.declarations.some((d) => (ts.isClassDeclaration(d) || ts.isInterfaceDeclaration(d)) &&
|
|
2441
|
+
ctx.isStdlibFile(ts.getSourceFileOfNode(d)))) {
|
|
2442
|
+
return DYN;
|
|
2443
|
+
}
|
|
1968
2444
|
// node:crypto's KeyObject: secret keys are native handles (scr_lib.c)
|
|
1969
2445
|
// whose getters and methods dispatch through the handle. The JsonWebKey
|
|
1970
2446
|
// that export() returns is a plain checked-dynamic object.
|
|
1971
|
-
if ((psym
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
.
|
|
1975
|
-
ctx.isStdlibFile(d.getSourceFile()))) {
|
|
2447
|
+
if (((psym !== undefined && ts.symbolName(psym) === "KeyObject") ||
|
|
2448
|
+
(psym !== undefined && ts.symbolName(psym) === "JsonWebKey")) &&
|
|
2449
|
+
psym.declarations.some((d) => (ts.isClassDeclaration(d) || ts.isInterfaceDeclaration(d)) &&
|
|
2450
|
+
ctx.isStdlibFile(ts.getSourceFileOfNode(d)))) {
|
|
1976
2451
|
return DYN;
|
|
1977
2452
|
}
|
|
1978
2453
|
if (psym &&
|
|
1979
|
-
FETCH_AMBIENT_TYPES.includes(psym
|
|
1980
|
-
!(psym
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
checker
|
|
1985
|
-
.declarationsOf(psym)
|
|
1986
|
-
.some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
|
|
1987
|
-
ctx.isStdlibFile(d.getSourceFile()))) {
|
|
2454
|
+
FETCH_AMBIENT_TYPES.includes(ts.symbolName(psym)) &&
|
|
2455
|
+
!(ts.symbolName(psym) === "ReadableStream" &&
|
|
2456
|
+
psym.declarations.some((d) => ts.isInterfaceDeclaration(d) && isDeclaredInAmbientNamespace(d, "NodeJS"))) &&
|
|
2457
|
+
psym.declarations.some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
|
|
2458
|
+
ctx.isStdlibFile(ts.getSourceFileOfNode(d)))) {
|
|
1988
2459
|
return DYN;
|
|
1989
2460
|
}
|
|
1990
2461
|
// The stdlib Console interface (the global console and node:console
|
|
@@ -1992,19 +2463,28 @@ function mapTypeInner(type, ctx) {
|
|
|
1992
2463
|
// representation and consumed by the console method lowerings. The
|
|
1993
2464
|
// stdlib Disposable (events.addAbortListener's result) and
|
|
1994
2465
|
// AsyncDisposable are checked objects carrying their Symbol.dispose or
|
|
1995
|
-
// Symbol.asyncDispose method.
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2466
|
+
// Symbol.asyncDispose method. A DisposableStack is a native handle whose
|
|
2467
|
+
// methods are function values of its checked-dynamic view.
|
|
2468
|
+
if (((psym !== undefined && ts.symbolName(psym) === "Console") ||
|
|
2469
|
+
(psym !== undefined && ts.symbolName(psym) === "Disposable") ||
|
|
2470
|
+
(psym !== undefined && ts.symbolName(psym) === "AsyncDisposable") ||
|
|
2471
|
+
(psym !== undefined && ts.symbolName(psym) === "DisposableStack")) &&
|
|
2472
|
+
psym.declarations.some((d) => ts.isInterfaceDeclaration(d) && ctx.isStdlibFile(ts.getSourceFileOfNode(d)))) {
|
|
2000
2473
|
return DYN;
|
|
2001
2474
|
}
|
|
2002
2475
|
// node:crypto Cipheriv/Decipheriv values (and @types/node's per-mode
|
|
2003
2476
|
// interfaces over them) are native handles carried by the checked-dynamic
|
|
2004
2477
|
// representation; lowerCipherMethodCall dispatches their methods.
|
|
2005
2478
|
if (psym !== undefined &&
|
|
2006
|
-
CIPHER_TYPE_NAMES.has(psym
|
|
2007
|
-
|
|
2479
|
+
CIPHER_TYPE_NAMES.has(ts.symbolName(psym)) &&
|
|
2480
|
+
psym.declarations.some((d) => ctx.isStdlibFile(ts.getSourceFileOfNode(d)))) {
|
|
2481
|
+
return DYN;
|
|
2482
|
+
}
|
|
2483
|
+
// node:crypto ECDH values are native handles carried by the
|
|
2484
|
+
// checked-dynamic representation; lowerEcdhCall dispatches their methods.
|
|
2485
|
+
if (psym !== undefined &&
|
|
2486
|
+
ts.symbolName(psym) === "ECDH" &&
|
|
2487
|
+
psym.declarations.some((d) => ts.isClassDeclaration(d) && ctx.isStdlibFile(ts.getSourceFileOfNode(d)))) {
|
|
2008
2488
|
return DYN;
|
|
2009
2489
|
}
|
|
2010
2490
|
// ReadonlyMap/ReadonlySet are the SAME runtime values as Map/Set — the
|
|
@@ -2092,12 +2572,12 @@ function mapTypeInner(type, ctx) {
|
|
|
2092
2572
|
// methods lower over that handle (loop-liveness bookkeeping); `Timeout |
|
|
2093
2573
|
// null` becomes `number | null`, and clearTimeout/clearInterval take the
|
|
2094
2574
|
// handle. Provenance-checked like the other named interfaces.
|
|
2095
|
-
if (
|
|
2575
|
+
if (isStdlibTimerHandle("Timeout"))
|
|
2096
2576
|
return F64;
|
|
2097
2577
|
// NodeJS.Immediate / the fallback `Immediate` (setImmediate's return):
|
|
2098
2578
|
// the same numeric-handle story over the check-phase queue — its own id
|
|
2099
2579
|
// space, so clearTimeout of an Immediate no-ops like Node.
|
|
2100
|
-
if (
|
|
2580
|
+
if (isStdlibTimerHandle("Immediate"))
|
|
2101
2581
|
return F64;
|
|
2102
2582
|
if (isStdlibInterface("ArrayBuffer") ||
|
|
2103
2583
|
isStdlibInterface("SharedArrayBuffer") ||
|
|
@@ -2124,6 +2604,8 @@ function mapTypeInner(type, ctx) {
|
|
|
2124
2604
|
// SharedArrayBuffer, and the i32 semantics hold for every other use.
|
|
2125
2605
|
if (isStdlibInterface("Int32Array"))
|
|
2126
2606
|
return bytesOf("i32");
|
|
2607
|
+
if (isStdlibInterface("Float16Array"))
|
|
2608
|
+
return bytesOf("f16");
|
|
2127
2609
|
if (isStdlibInterface("Float32Array"))
|
|
2128
2610
|
return bytesOf("f32");
|
|
2129
2611
|
if (isStdlibInterface("Float64Array"))
|
|
@@ -2139,11 +2621,10 @@ function mapTypeInner(type, ctx) {
|
|
|
2139
2621
|
// (the u8 bytes kind). Declared `interface Buffer` by the shipped
|
|
2140
2622
|
// fallback and by @types/node (whose NonSharedBuffer alias resolves to
|
|
2141
2623
|
// the same symbol); provenance-checked like URL.
|
|
2142
|
-
if (psym
|
|
2143
|
-
|
|
2144
|
-
|
|
2145
|
-
.
|
|
2146
|
-
ctx.isStdlibFile(d.getSourceFile()))) {
|
|
2624
|
+
if (psym !== undefined &&
|
|
2625
|
+
ts.symbolName(psym) === "Buffer" &&
|
|
2626
|
+
psym.declarations.some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
|
|
2627
|
+
ctx.isStdlibFile(ts.getSourceFileOfNode(d)))) {
|
|
2147
2628
|
return bytesOf("u8");
|
|
2148
2629
|
}
|
|
2149
2630
|
// URL: the WHATWG URL instance type — declared as a global `interface
|
|
@@ -2151,41 +2632,36 @@ function mapTypeInner(type, ctx) {
|
|
|
2151
2632
|
// URL` in @types/node's "url" module (`new URL(x)` types as the class's
|
|
2152
2633
|
// instance type). Provenance, not the name: a user's own URL maps as a
|
|
2153
2634
|
// record/class like any other.
|
|
2154
|
-
if (psym
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
.
|
|
2158
|
-
ctx.isStdlibFile(d.getSourceFile()))) {
|
|
2635
|
+
if (psym !== undefined &&
|
|
2636
|
+
ts.symbolName(psym) === "URL" &&
|
|
2637
|
+
psym.declarations.some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
|
|
2638
|
+
ctx.isStdlibFile(ts.getSourceFileOfNode(d)))) {
|
|
2159
2639
|
return { kind: "url" };
|
|
2160
2640
|
}
|
|
2161
2641
|
// URLSearchParams: the WHATWG live query view — declared as a global
|
|
2162
2642
|
// interface by the shipped fallback and by @types/node (plus `class
|
|
2163
2643
|
// URLSearchParams` in the "url" module). Provenance-checked like URL.
|
|
2164
|
-
if (psym
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
.
|
|
2168
|
-
ctx.isStdlibFile(d.getSourceFile()))) {
|
|
2644
|
+
if (psym !== undefined &&
|
|
2645
|
+
ts.symbolName(psym) === "URLSearchParams" &&
|
|
2646
|
+
psym.declarations.some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
|
|
2647
|
+
ctx.isStdlibFile(ts.getSourceFileOfNode(d)))) {
|
|
2169
2648
|
return { kind: "searchParams" };
|
|
2170
2649
|
}
|
|
2171
2650
|
// fs.Stats: @types/node's `class Stats` (module "fs") or the fallback
|
|
2172
2651
|
// declarations' interface. Provenance-checked like URL.
|
|
2173
|
-
if (psym
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
.
|
|
2177
|
-
ctx.isStdlibFile(d.getSourceFile()))) {
|
|
2652
|
+
if (psym !== undefined &&
|
|
2653
|
+
ts.symbolName(psym) === "Stats" &&
|
|
2654
|
+
psym.declarations.some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
|
|
2655
|
+
ctx.isStdlibFile(ts.getSourceFileOfNode(d)))) {
|
|
2178
2656
|
return { kind: "stats" };
|
|
2179
2657
|
}
|
|
2180
2658
|
// Capacity snapshots and options keep their live object representation
|
|
2181
2659
|
// across numeric/BigInt overloads, runtime options, and callbacks.
|
|
2182
|
-
if ((psym
|
|
2183
|
-
psym
|
|
2184
|
-
psym
|
|
2185
|
-
|
|
2186
|
-
.
|
|
2187
|
-
.some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
|
|
2188
|
-
ctx.isStdlibFile(d.getSourceFile()) &&
|
|
2660
|
+
if (((psym !== undefined && ts.symbolName(psym) === "StatsFs") ||
|
|
2661
|
+
(psym !== undefined && ts.symbolName(psym) === "BigIntStatsFs") ||
|
|
2662
|
+
(psym !== undefined && ts.symbolName(psym) === "StatFsOptions")) &&
|
|
2663
|
+
psym.declarations.some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
|
|
2664
|
+
ctx.isStdlibFile(ts.getSourceFileOfNode(d)) &&
|
|
2189
2665
|
isDeclaredInAmbientModule(d, "fs")))
|
|
2190
2666
|
return DYN;
|
|
2191
2667
|
if (isWorkerHandleSymbol(psym, ctx))
|
|
@@ -2193,21 +2669,19 @@ function mapTypeInner(type, ctx) {
|
|
|
2193
2669
|
// fs/promises.FileHandle: an owned descriptor object. Module provenance
|
|
2194
2670
|
// distinguishes it from user interfaces with the same name; both the
|
|
2195
2671
|
// fallback and @types/node declare it in "fs/promises".
|
|
2196
|
-
if (psym
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
.
|
|
2200
|
-
ctx.isStdlibFile(d.getSourceFile()) &&
|
|
2672
|
+
if (psym !== undefined &&
|
|
2673
|
+
ts.symbolName(psym) === "FileHandle" &&
|
|
2674
|
+
psym.declarations.some((d) => ts.isInterfaceDeclaration(d) &&
|
|
2675
|
+
ctx.isStdlibFile(ts.getSourceFileOfNode(d)) &&
|
|
2201
2676
|
isDeclaredInAmbientModule(d, "fs/promises"))) {
|
|
2202
2677
|
return { kind: "fileHandle" };
|
|
2203
2678
|
}
|
|
2204
2679
|
// fs.Dir: an open directory stream, declared in "fs" by both the
|
|
2205
2680
|
// fallback and @types/node.
|
|
2206
|
-
if (psym
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
.
|
|
2210
|
-
ctx.isStdlibFile(d.getSourceFile()) &&
|
|
2681
|
+
if (psym !== undefined &&
|
|
2682
|
+
ts.symbolName(psym) === "Dir" &&
|
|
2683
|
+
psym.declarations.some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
|
|
2684
|
+
ctx.isStdlibFile(ts.getSourceFileOfNode(d)) &&
|
|
2211
2685
|
isDeclaredInAmbientModule(d, "fs"))) {
|
|
2212
2686
|
return { kind: "dir" };
|
|
2213
2687
|
}
|
|
@@ -2215,24 +2689,21 @@ function mapTypeInner(type, ctx) {
|
|
|
2215
2689
|
// Buffer/string split is re-checked at the stdout/stderr READ — status
|
|
2216
2690
|
// reads work either way) or the fallback declarations' plain interface.
|
|
2217
2691
|
// Provenance-checked like Stats.
|
|
2218
|
-
if (psym
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
.
|
|
2222
|
-
ctx.isStdlibFile(d.getSourceFile()))) {
|
|
2692
|
+
if (psym !== undefined &&
|
|
2693
|
+
ts.symbolName(psym) === "SpawnSyncReturns" &&
|
|
2694
|
+
psym.declarations.some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
|
|
2695
|
+
ctx.isStdlibFile(ts.getSourceFileOfNode(d)))) {
|
|
2223
2696
|
return { kind: "spawnRes" };
|
|
2224
2697
|
}
|
|
2225
2698
|
// child_process.ChildProcess and @types/node's stdio-refined return
|
|
2226
2699
|
// interfaces: all carry the same runtime child handle; the generic
|
|
2227
2700
|
// refinements only tell the checker which stdio properties are null.
|
|
2228
2701
|
if (psym !== undefined &&
|
|
2229
|
-
(psym
|
|
2230
|
-
psym
|
|
2231
|
-
psym
|
|
2232
|
-
|
|
2233
|
-
.
|
|
2234
|
-
.some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
|
|
2235
|
-
ctx.isStdlibFile(d.getSourceFile()) &&
|
|
2702
|
+
(ts.symbolName(psym) === "ChildProcess" ||
|
|
2703
|
+
ts.symbolName(psym) === "ChildProcessWithoutNullStreams" ||
|
|
2704
|
+
ts.symbolName(psym) === "ChildProcessByStdio") &&
|
|
2705
|
+
psym.declarations.some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
|
|
2706
|
+
ctx.isStdlibFile(ts.getSourceFileOfNode(d)) &&
|
|
2236
2707
|
isDeclaredInAmbientModule(d, "child_process"))) {
|
|
2237
2708
|
return { kind: "child" };
|
|
2238
2709
|
}
|
|
@@ -2243,64 +2714,62 @@ function mapTypeInner(type, ctx) {
|
|
|
2243
2714
|
// declare these inside `declare module "net"` — a declaration outside
|
|
2244
2715
|
// that module (http's Server) stays unmapped and fences at its use
|
|
2245
2716
|
// site.
|
|
2246
|
-
if ((psym
|
|
2247
|
-
|
|
2248
|
-
|
|
2717
|
+
if (((psym !== undefined && ts.symbolName(psym) === "Server") ||
|
|
2718
|
+
(psym !== undefined && ts.symbolName(psym) === "Socket") ||
|
|
2719
|
+
(psym !== undefined && ts.symbolName(psym) === "TLSSocket")) &&
|
|
2720
|
+
psym.declarations.some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
|
|
2721
|
+
ctx.isStdlibFile(ts.getSourceFileOfNode(d)) &&
|
|
2249
2722
|
(isDeclaredInAmbientModule(d, "net") ||
|
|
2250
2723
|
// http.Server extends net.Server in @types/node — and tls.Server
|
|
2251
2724
|
// / https.Server extend it transitively: same lowered surface
|
|
2252
2725
|
// (listen/close/address/'error'), same handle kind. tls.TLSSocket
|
|
2253
2726
|
// extends net.Socket the same way: post-handshake it IS a net
|
|
2254
2727
|
// socket to every lowered member.
|
|
2255
|
-
(psym
|
|
2728
|
+
(ts.symbolName(psym) === "Server" &&
|
|
2256
2729
|
(isDeclaredInAmbientModule(d, "http") ||
|
|
2257
2730
|
isDeclaredInAmbientModule(d, "tls") ||
|
|
2258
2731
|
isDeclaredInAmbientModule(d, "https"))) ||
|
|
2259
|
-
(psym
|
|
2260
|
-
return psym
|
|
2732
|
+
(ts.symbolName(psym) === "TLSSocket" && isDeclaredInAmbientModule(d, "tls"))))) {
|
|
2733
|
+
return ts.symbolName(psym) === "Server" ? { kind: "netServer" } : { kind: "netSocket" };
|
|
2261
2734
|
}
|
|
2262
2735
|
// tls.SecureContext: the opaque parsed-cert/key handle SNI callbacks
|
|
2263
2736
|
// answer with (tls.createSecureContext({ cert, key }) mints it; the TLS
|
|
2264
2737
|
// server's handshake consumes it). Module-checked like net.Server —
|
|
2265
2738
|
// @types/node declares `interface SecureContext` inside `declare module
|
|
2266
2739
|
// "tls"`, and the shipped fallback mirrors it.
|
|
2267
|
-
if (psym
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
.
|
|
2271
|
-
ctx.isStdlibFile(d.getSourceFile()) &&
|
|
2740
|
+
if (psym !== undefined &&
|
|
2741
|
+
ts.symbolName(psym) === "SecureContext" &&
|
|
2742
|
+
psym.declarations.some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
|
|
2743
|
+
ctx.isStdlibFile(ts.getSourceFileOfNode(d)) &&
|
|
2272
2744
|
isDeclaredInAmbientModule(d, "tls"))) {
|
|
2273
2745
|
return { kind: "secureCtx" };
|
|
2274
2746
|
}
|
|
2275
2747
|
// Scrypt's runtime options retain property accessors and aliases. Use
|
|
2276
2748
|
// checked values so presence probes and repeated getter reads match Node.
|
|
2277
|
-
if (psym
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
.
|
|
2281
|
-
ctx.isStdlibFile(d.getSourceFile()) &&
|
|
2749
|
+
if (psym !== undefined &&
|
|
2750
|
+
ts.symbolName(psym) === "ScryptOptions" &&
|
|
2751
|
+
psym.declarations.some((d) => ts.isInterfaceDeclaration(d) &&
|
|
2752
|
+
ctx.isStdlibFile(ts.getSourceFileOfNode(d)) &&
|
|
2282
2753
|
isDeclaredInAmbientModule(d, "crypto")))
|
|
2283
2754
|
return DYN;
|
|
2284
2755
|
// crypto.Hash / crypto.Hmac: native incremental digest handles. Keep
|
|
2285
2756
|
// provenance module-qualified so user classes with these common names
|
|
2286
2757
|
// retain their ordinary structural/class representation.
|
|
2287
|
-
if ((psym
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
.
|
|
2291
|
-
ctx.isStdlibFile(d.getSourceFile()) &&
|
|
2758
|
+
if (((psym !== undefined && ts.symbolName(psym) === "Hash") ||
|
|
2759
|
+
(psym !== undefined && ts.symbolName(psym) === "Hmac")) &&
|
|
2760
|
+
psym.declarations.some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
|
|
2761
|
+
ctx.isStdlibFile(ts.getSourceFileOfNode(d)) &&
|
|
2292
2762
|
isDeclaredInAmbientModule(d, "crypto"))) {
|
|
2293
|
-
return psym
|
|
2763
|
+
return ts.symbolName(psym) === "Hash" ? CRYPTOHASH_T : CRYPTOHMAC_T;
|
|
2294
2764
|
}
|
|
2295
2765
|
// fs.FSWatcher: the fs.watch handle (scr_watch.c). Module-checked like
|
|
2296
2766
|
// net.Server — @types/node declares `interface FSWatcher extends
|
|
2297
2767
|
// EventEmitter` inside `declare module "fs"`, and the shipped fallback
|
|
2298
2768
|
// mirrors it.
|
|
2299
|
-
if (psym
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
.
|
|
2303
|
-
ctx.isStdlibFile(d.getSourceFile()) &&
|
|
2769
|
+
if (psym !== undefined &&
|
|
2770
|
+
ts.symbolName(psym) === "FSWatcher" &&
|
|
2771
|
+
psym.declarations.some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
|
|
2772
|
+
ctx.isStdlibFile(ts.getSourceFileOfNode(d)) &&
|
|
2304
2773
|
isDeclaredInAmbientModule(d, "fs"))) {
|
|
2305
2774
|
return { kind: "fsWatcher" };
|
|
2306
2775
|
}
|
|
@@ -2321,41 +2790,70 @@ function mapTypeInner(type, ctx) {
|
|
|
2321
2790
|
// global-namespace interface real code writes in its own signatures —
|
|
2322
2791
|
// prefixStream's `output` param). The representation is the raw fd
|
|
2323
2792
|
// scalar; the lowered surface is write(string).
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2793
|
+
// Under the program's general stream representation (generalNodeStreams)
|
|
2794
|
+
// NodeJS.WritableStream is the runtime Writable instead: the process
|
|
2795
|
+
// streams convert into it where they flow (process.stdioWritable).
|
|
2796
|
+
// Checked-dynamic stream slots: an intersection over a NodeJS stream
|
|
2797
|
+
// interface (`NodeJS.ReadableStream & { destroy?(): void }`) holds the
|
|
2798
|
+
// same values as the interface.
|
|
2799
|
+
if (ctx.dynNodeStreams === true &&
|
|
2800
|
+
(type.flags & ts.TypeFlags.Intersection) !== 0 &&
|
|
2801
|
+
ts.constituentTypes(type).some((part) => {
|
|
2802
|
+
const sym = part.getSymbol();
|
|
2803
|
+
return (((sym !== undefined && ts.symbolName(sym) === "ReadableStream") ||
|
|
2804
|
+
(sym !== undefined && ts.symbolName(sym) === "WritableStream")) &&
|
|
2805
|
+
sym.declarations.some((d) => ts.isInterfaceDeclaration(d) &&
|
|
2806
|
+
ctx.isStdlibFile(ts.getSourceFileOfNode(d)) &&
|
|
2807
|
+
isDeclaredInAmbientNamespace(d, "NodeJS")));
|
|
2808
|
+
})) {
|
|
2809
|
+
return DYN;
|
|
2810
|
+
}
|
|
2811
|
+
const nodeWritableInterface = psym !== undefined &&
|
|
2812
|
+
ts.symbolName(psym) === "WritableStream" &&
|
|
2813
|
+
psym.declarations.some((d) => ts.isInterfaceDeclaration(d) &&
|
|
2814
|
+
ctx.isStdlibFile(ts.getSourceFileOfNode(d)) &&
|
|
2815
|
+
isDeclaredInAmbientNamespace(d, "NodeJS"));
|
|
2816
|
+
if (nodeWritableInterface && ctx.generalNodeStreams === true) {
|
|
2817
|
+
return ctx.dynNodeStreams === true ? DYN : { kind: "object", className: "%Writable" };
|
|
2818
|
+
}
|
|
2819
|
+
if ((psym !== undefined &&
|
|
2820
|
+
ts.symbolName(psym) === "WriteStream" &&
|
|
2821
|
+
psym.declarations.some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
|
|
2822
|
+
ctx.isStdlibFile(ts.getSourceFileOfNode(d)) &&
|
|
2329
2823
|
(isDeclaredInAmbientModule(d, "tty") ||
|
|
2330
|
-
(isDeclaredInAmbientModule(d, "process") &&
|
|
2331
|
-
|
|
2332
|
-
(psym?.name === "WritableStream" &&
|
|
2333
|
-
checker
|
|
2334
|
-
.declarationsOf(psym)
|
|
2335
|
-
.some((d) => ts.isInterfaceDeclaration(d) &&
|
|
2336
|
-
ctx.isStdlibFile(d.getSourceFile()) &&
|
|
2337
|
-
isDeclaredInAmbientNamespace(d, "NodeJS")))) {
|
|
2824
|
+
(isDeclaredInAmbientModule(d, "process") && isDeclaredInAmbientNamespace(d, "NodeJS"))))) ||
|
|
2825
|
+
nodeWritableInterface) {
|
|
2338
2826
|
return PROCSTREAM_T;
|
|
2339
2827
|
}
|
|
2340
2828
|
// A piped child stdin writer. The fallback declarations give it the
|
|
2341
2829
|
// dedicated ChildStdin name; @types/node spells the same value as
|
|
2342
2830
|
// stream.Writable. As with stream.Readable below, unsupported producers
|
|
2343
2831
|
// of the broad @types class fence where they are constructed.
|
|
2344
|
-
if ((psym
|
|
2345
|
-
|
|
2346
|
-
|
|
2347
|
-
|
|
2348
|
-
ctx.isStdlibFile(
|
|
2832
|
+
if ((psym !== undefined &&
|
|
2833
|
+
ts.symbolName(psym) === "ChildStdin" &&
|
|
2834
|
+
ctx.generalNodeStreams !== true &&
|
|
2835
|
+
psym.declarations.some((d) => ts.isInterfaceDeclaration(d) &&
|
|
2836
|
+
ctx.isStdlibFile(ts.getSourceFileOfNode(d)) &&
|
|
2349
2837
|
isDeclaredInAmbientModule(d, "child_process"))) ||
|
|
2350
|
-
(psym
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
ctx.isStdlibFile(
|
|
2355
|
-
isNodeTypesPath(
|
|
2838
|
+
(psym !== undefined &&
|
|
2839
|
+
ts.symbolName(psym) === "Writable" &&
|
|
2840
|
+
ctx.generalNodeStreams !== true &&
|
|
2841
|
+
psym.declarations.some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
|
|
2842
|
+
ctx.isStdlibFile(ts.getSourceFileOfNode(d)) &&
|
|
2843
|
+
isNodeTypesPath(ts.getSourceFileOfNode(d).fileName) &&
|
|
2356
2844
|
isDeclaredInAmbientModule(d, "stream")))) {
|
|
2357
2845
|
return { kind: "childWriter" };
|
|
2358
2846
|
}
|
|
2847
|
+
// Under the general stream representation the fallback declarations'
|
|
2848
|
+
// ChildStdin is the runtime Writable too (child.stdioStream bridges it).
|
|
2849
|
+
if (ctx.generalNodeStreams === true &&
|
|
2850
|
+
psym !== undefined &&
|
|
2851
|
+
ts.symbolName(psym) === "ChildStdin" &&
|
|
2852
|
+
psym.declarations.some((d) => ts.isInterfaceDeclaration(d) &&
|
|
2853
|
+
ctx.isStdlibFile(ts.getSourceFileOfNode(d)) &&
|
|
2854
|
+
isDeclaredInAmbientModule(d, "child_process"))) {
|
|
2855
|
+
return { kind: "object", className: "%Writable" };
|
|
2856
|
+
}
|
|
2359
2857
|
// The static node:stream classes (the shipped fallback declarations —
|
|
2360
2858
|
// NOT @types/node, whose stream.Readable also types child stdio; under
|
|
2361
2859
|
// @types/node the childStream mapping below keeps priority and the
|
|
@@ -2363,93 +2861,102 @@ function mapTypeInner(type, ctx) {
|
|
|
2363
2861
|
// branch: the fallback's Readable must map to the runtime class, and
|
|
2364
2862
|
// under the fallback child.stdout is NodeJS.ReadableStream (its own
|
|
2365
2863
|
// branch below), so the two never collide.
|
|
2864
|
+
// @types/node's Duplex/Transform/PassThrough classes have no child-stdio
|
|
2865
|
+
// reading, so they map to the runtime classes too; its Readable and
|
|
2866
|
+
// Writable join them under the general representation.
|
|
2366
2867
|
for (const [irName, rec] of RUNTIME_STREAM_CLASSES) {
|
|
2367
|
-
if (psym
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
.
|
|
2371
|
-
|
|
2372
|
-
|
|
2868
|
+
if (psym !== undefined &&
|
|
2869
|
+
ts.symbolName(psym) === rec.lib &&
|
|
2870
|
+
psym.declarations.some((d) => ts.isClassDeclaration(d) &&
|
|
2871
|
+
ctx.isStdlibFile(ts.getSourceFileOfNode(d)) &&
|
|
2872
|
+
(!isNodeTypesPath(ts.getSourceFileOfNode(d).fileName) ||
|
|
2873
|
+
ctx.generalNodeStreams === true ||
|
|
2874
|
+
(rec.lib !== "Readable" && rec.lib !== "Writable")) &&
|
|
2373
2875
|
isDeclaredInAmbientModule(d, "stream"))) {
|
|
2374
2876
|
return { kind: "object", className: irName };
|
|
2375
2877
|
}
|
|
2376
2878
|
}
|
|
2377
|
-
// node:zlib's stream classes (the shipped fallback declarations
|
|
2378
|
-
// instances are runtime Transform streams.
|
|
2879
|
+
// node:zlib's stream classes (the shipped fallback declarations and
|
|
2880
|
+
// @types/node's): their instances are runtime Transform streams.
|
|
2379
2881
|
if (psym !== undefined &&
|
|
2380
|
-
ZLIB_STREAM_MODES.has(psym
|
|
2381
|
-
|
|
2382
|
-
.
|
|
2383
|
-
.
|
|
2384
|
-
ctx.isStdlibFile(d.getSourceFile()) &&
|
|
2385
|
-
!isNodeTypesPath(d.getSourceFile().fileName) &&
|
|
2882
|
+
ZLIB_STREAM_MODES.has(ts.symbolName(psym)) &&
|
|
2883
|
+
psym.declarations.some((d) => (ts.isClassDeclaration(d) ||
|
|
2884
|
+
(ts.isInterfaceDeclaration(d) && isNodeTypesPath(ts.getSourceFileOfNode(d).fileName))) &&
|
|
2885
|
+
ctx.isStdlibFile(ts.getSourceFileOfNode(d)) &&
|
|
2386
2886
|
isDeclaredInAmbientModule(d, "zlib"))) {
|
|
2387
2887
|
return { kind: "object", className: "%Transform" };
|
|
2388
2888
|
}
|
|
2389
|
-
// fs.ReadStream / fs.WriteStream (the shipped fallback declarations
|
|
2390
|
-
// their instances are runtime Readable / Writable
|
|
2391
|
-
// (scr_fs_stream.c).
|
|
2392
|
-
if ((psym
|
|
2393
|
-
|
|
2394
|
-
|
|
2395
|
-
.
|
|
2396
|
-
ctx.isStdlibFile(d.getSourceFile()) &&
|
|
2397
|
-
!isNodeTypesPath(d.getSourceFile().fileName) &&
|
|
2889
|
+
// fs.ReadStream / fs.WriteStream (the shipped fallback declarations and
|
|
2890
|
+
// @types/node's): their instances are runtime Readable / Writable
|
|
2891
|
+
// streams (scr_fs_stream.c).
|
|
2892
|
+
if (((psym !== undefined && ts.symbolName(psym) === "ReadStream") ||
|
|
2893
|
+
(psym !== undefined && ts.symbolName(psym) === "WriteStream")) &&
|
|
2894
|
+
psym.declarations.some((d) => ts.isClassDeclaration(d) &&
|
|
2895
|
+
ctx.isStdlibFile(ts.getSourceFileOfNode(d)) &&
|
|
2398
2896
|
isDeclaredInAmbientModule(d, "fs"))) {
|
|
2399
|
-
return {
|
|
2897
|
+
return {
|
|
2898
|
+
kind: "object",
|
|
2899
|
+
className: ts.symbolName(psym) === "ReadStream" ? "%Readable" : "%Writable",
|
|
2900
|
+
};
|
|
2400
2901
|
}
|
|
2401
|
-
if ((psym
|
|
2402
|
-
|
|
2403
|
-
|
|
2404
|
-
.
|
|
2405
|
-
ctx.isStdlibFile(d.getSourceFile()) &&
|
|
2902
|
+
if ((psym !== undefined &&
|
|
2903
|
+
ts.symbolName(psym) === "Readable" &&
|
|
2904
|
+
psym.declarations.some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
|
|
2905
|
+
ctx.isStdlibFile(ts.getSourceFileOfNode(d)) &&
|
|
2406
2906
|
isDeclaredInAmbientModule(d, "stream"))) ||
|
|
2407
|
-
(psym
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
|
-
.
|
|
2411
|
-
ctx.isStdlibFile(d.getSourceFile()) &&
|
|
2907
|
+
(psym !== undefined &&
|
|
2908
|
+
ts.symbolName(psym) === "ReadableStream" &&
|
|
2909
|
+
psym.declarations.some((d) => ts.isInterfaceDeclaration(d) &&
|
|
2910
|
+
ctx.isStdlibFile(ts.getSourceFileOfNode(d)) &&
|
|
2412
2911
|
isDeclaredInAmbientNamespace(d, "NodeJS")))) {
|
|
2912
|
+
// The general representation: the runtime Readable, which child
|
|
2913
|
+
// stdio reads produce through the child stream bridge. With
|
|
2914
|
+
// checked-dynamic stream slots, NodeJS.ReadableStream holds any
|
|
2915
|
+
// stream value (dyn-streams.ts); stream.Readable keeps the class.
|
|
2916
|
+
if (ctx.generalNodeStreams === true) {
|
|
2917
|
+
if (ctx.dynNodeStreams === true && ts.symbolName(psym) === "ReadableStream")
|
|
2918
|
+
return DYN;
|
|
2919
|
+
return { kind: "object", className: "%Readable" };
|
|
2920
|
+
}
|
|
2413
2921
|
return { kind: "childStream" };
|
|
2414
2922
|
}
|
|
2415
2923
|
// dgram.Socket: the same ambiguous "Socket" name disambiguated by its
|
|
2416
2924
|
// enclosing ambient module — @types/node's `class Socket extends
|
|
2417
2925
|
// EventEmitter` and the fallback declarations' interface both live
|
|
2418
2926
|
// inside `declare module "dgram"`.
|
|
2419
|
-
if (psym
|
|
2420
|
-
|
|
2421
|
-
|
|
2422
|
-
.
|
|
2423
|
-
ctx.isStdlibFile(d.getSourceFile()) &&
|
|
2927
|
+
if (psym !== undefined &&
|
|
2928
|
+
ts.symbolName(psym) === "Socket" &&
|
|
2929
|
+
psym.declarations.some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
|
|
2930
|
+
ctx.isStdlibFile(ts.getSourceFileOfNode(d)) &&
|
|
2424
2931
|
isDeclaredInAmbientModule(d, "dgram"))) {
|
|
2425
2932
|
return { kind: "dgramSocket" };
|
|
2426
2933
|
}
|
|
2427
2934
|
// node:test's TestContext — the test-body parameter (`test('x', (t) =>
|
|
2428
|
-
// ...)`)
|
|
2429
|
-
//
|
|
2430
|
-
//
|
|
2431
|
-
|
|
2432
|
-
|
|
2433
|
-
|
|
2434
|
-
|
|
2435
|
-
|
|
2935
|
+
// ...)`) — and SuiteContext, the describe-body and suite-hook parameter:
|
|
2936
|
+
// both are the runner's node for the test or suite. @types/node's
|
|
2937
|
+
// classes and the fallback declarations' interfaces all live inside
|
|
2938
|
+
// `declare module "node:test"` (isDeclaredInAmbientModule answers for
|
|
2939
|
+
// both spellings).
|
|
2940
|
+
if (((psym !== undefined && ts.symbolName(psym) === "TestContext") ||
|
|
2941
|
+
(psym !== undefined && ts.symbolName(psym) === "SuiteContext")) &&
|
|
2942
|
+
psym.declarations.some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
|
|
2943
|
+
ctx.isStdlibFile(ts.getSourceFileOfNode(d)) &&
|
|
2436
2944
|
isDeclaredInAmbientModule(d, "test"))) {
|
|
2437
2945
|
return { kind: "testCtx" };
|
|
2438
2946
|
}
|
|
2439
2947
|
// node:test's MockFunctionContext<F> and MockFunctionCall<F>: compiler
|
|
2440
2948
|
// records built from F (mock-shapes.ts). Mock<F> then maps as the hybrid
|
|
2441
2949
|
// { %call: F, mock } record through mapHybridCallableIntersection.
|
|
2442
|
-
if ((psym
|
|
2443
|
-
|
|
2444
|
-
|
|
2445
|
-
.
|
|
2446
|
-
ctx.isStdlibFile(d.getSourceFile()) &&
|
|
2950
|
+
if (((psym !== undefined && ts.symbolName(psym) === "MockFunctionContext") ||
|
|
2951
|
+
(psym !== undefined && ts.symbolName(psym) === "MockFunctionCall")) &&
|
|
2952
|
+
psym.declarations.some((d) => ts.isInterfaceDeclaration(d) &&
|
|
2953
|
+
ctx.isStdlibFile(ts.getSourceFileOfNode(d)) &&
|
|
2447
2954
|
isDeclaredInAmbientModule(d, "test"))) {
|
|
2448
2955
|
const fnTs = checker.getTypeArguments(widened)[0];
|
|
2449
2956
|
const fn = fnTs ? mapType(fnTs, ctx) : null;
|
|
2450
2957
|
if (!fn || fn.kind !== "func")
|
|
2451
2958
|
return null;
|
|
2452
|
-
return psym
|
|
2959
|
+
return ts.symbolName(psym) === "MockFunctionContext"
|
|
2453
2960
|
? mockContextType(fn, ctx)
|
|
2454
2961
|
: mockCallRecordType(fn, ctx);
|
|
2455
2962
|
}
|
|
@@ -2458,10 +2965,9 @@ function mapTypeInner(type, ctx) {
|
|
|
2458
2965
|
// it to the runtime %Error hierarchy like the lib Error interfaces
|
|
2459
2966
|
// above; optional metadata uses the same checked property view.
|
|
2460
2967
|
// Provenance-checked like the rest.
|
|
2461
|
-
if (psym
|
|
2462
|
-
|
|
2463
|
-
|
|
2464
|
-
.some((d) => ts.isInterfaceDeclaration(d) && ctx.isStdlibFile(d.getSourceFile()))) {
|
|
2968
|
+
if (psym !== undefined &&
|
|
2969
|
+
ts.symbolName(psym) === "ErrnoException" &&
|
|
2970
|
+
psym.declarations.some((d) => ts.isInterfaceDeclaration(d) && ctx.isStdlibFile(ts.getSourceFileOfNode(d)))) {
|
|
2465
2971
|
return { kind: "object", className: "%Error" };
|
|
2466
2972
|
}
|
|
2467
2973
|
// http.Agent / https.Agent — the Agent VALUE is a checked-dynamic
|
|
@@ -2470,24 +2976,22 @@ function mapTypeInner(type, ctx) {
|
|
|
2470
2976
|
// binding, parameter, or field carrying an Agent stays usable instead
|
|
2471
2977
|
// of fencing at the declaration. Module-checked like the rest (https'
|
|
2472
2978
|
// Agent extends http's; both live in their ambient modules).
|
|
2473
|
-
if (psym
|
|
2474
|
-
|
|
2475
|
-
|
|
2476
|
-
.
|
|
2477
|
-
ctx.isStdlibFile(d.getSourceFile()) &&
|
|
2979
|
+
if (psym !== undefined &&
|
|
2980
|
+
ts.symbolName(psym) === "Agent" &&
|
|
2981
|
+
psym.declarations.some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
|
|
2982
|
+
ctx.isStdlibFile(ts.getSourceFileOfNode(d)) &&
|
|
2478
2983
|
(isDeclaredInAmbientModule(d, "http") || isDeclaredInAmbientModule(d, "https")))) {
|
|
2479
2984
|
return { kind: "dyn" };
|
|
2480
2985
|
}
|
|
2481
2986
|
// http.IncomingMessage / http.ServerResponse — module-checked like
|
|
2482
2987
|
// net.Server (the names repeat nowhere today, but provenance stays the
|
|
2483
2988
|
// rule).
|
|
2484
|
-
if ((psym
|
|
2485
|
-
|
|
2486
|
-
|
|
2487
|
-
.
|
|
2488
|
-
ctx.isStdlibFile(d.getSourceFile()) &&
|
|
2989
|
+
if (((psym !== undefined && ts.symbolName(psym) === "IncomingMessage") ||
|
|
2990
|
+
(psym !== undefined && ts.symbolName(psym) === "ServerResponse")) &&
|
|
2991
|
+
psym.declarations.some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
|
|
2992
|
+
ctx.isStdlibFile(ts.getSourceFileOfNode(d)) &&
|
|
2489
2993
|
isDeclaredInAmbientModule(d, "http"))) {
|
|
2490
|
-
return psym
|
|
2994
|
+
return ts.symbolName(psym) === "IncomingMessage" ? { kind: "httpReq" } : { kind: "httpRes" };
|
|
2491
2995
|
}
|
|
2492
2996
|
// http2's compatibility surface (the allowHTTP1 lowering): the secure
|
|
2493
2997
|
// server IS a net server (listen/close/address/emit ride the same
|
|
@@ -2497,17 +3001,15 @@ function mapTypeInner(type, ctx) {
|
|
|
2497
3001
|
// ServerResponse surface. h2-only members (stream, session) fence per
|
|
2498
3002
|
// member at their use sites (lower-server.ts). Module-checked like the
|
|
2499
3003
|
// rest.
|
|
2500
|
-
if ((psym
|
|
2501
|
-
psym
|
|
2502
|
-
psym
|
|
2503
|
-
|
|
2504
|
-
.
|
|
2505
|
-
.some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
|
|
2506
|
-
ctx.isStdlibFile(d.getSourceFile()) &&
|
|
3004
|
+
if (((psym !== undefined && ts.symbolName(psym) === "Http2SecureServer") ||
|
|
3005
|
+
(psym !== undefined && ts.symbolName(psym) === "Http2ServerRequest") ||
|
|
3006
|
+
(psym !== undefined && ts.symbolName(psym) === "Http2ServerResponse")) &&
|
|
3007
|
+
psym.declarations.some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
|
|
3008
|
+
ctx.isStdlibFile(ts.getSourceFileOfNode(d)) &&
|
|
2507
3009
|
isDeclaredInAmbientModule(d, "http2"))) {
|
|
2508
|
-
return psym
|
|
3010
|
+
return ts.symbolName(psym) === "Http2SecureServer"
|
|
2509
3011
|
? { kind: "netServer" }
|
|
2510
|
-
: psym
|
|
3012
|
+
: ts.symbolName(psym) === "Http2ServerRequest"
|
|
2511
3013
|
? { kind: "httpReq" }
|
|
2512
3014
|
: { kind: "httpRes" };
|
|
2513
3015
|
}
|
|
@@ -2515,30 +3017,27 @@ function mapTypeInner(type, ctx) {
|
|
|
2515
3017
|
// like the secure one; sessions and streams are first-class handle
|
|
2516
3018
|
// kinds (client and server flavors share a kind — the runtime handle
|
|
2517
3019
|
// carries the role). Module-checked like the rest.
|
|
2518
|
-
if ((psym
|
|
2519
|
-
psym
|
|
2520
|
-
psym
|
|
2521
|
-
psym
|
|
2522
|
-
psym
|
|
2523
|
-
psym
|
|
2524
|
-
|
|
2525
|
-
.
|
|
2526
|
-
.some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
|
|
2527
|
-
ctx.isStdlibFile(d.getSourceFile()) &&
|
|
3020
|
+
if (((psym !== undefined && ts.symbolName(psym) === "Http2Server") ||
|
|
3021
|
+
(psym !== undefined && ts.symbolName(psym) === "Http2Session") ||
|
|
3022
|
+
(psym !== undefined && ts.symbolName(psym) === "ClientHttp2Session") ||
|
|
3023
|
+
(psym !== undefined && ts.symbolName(psym) === "ServerHttp2Session") ||
|
|
3024
|
+
(psym !== undefined && ts.symbolName(psym) === "ClientHttp2Stream") ||
|
|
3025
|
+
(psym !== undefined && ts.symbolName(psym) === "ServerHttp2Stream")) &&
|
|
3026
|
+
psym.declarations.some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
|
|
3027
|
+
ctx.isStdlibFile(ts.getSourceFileOfNode(d)) &&
|
|
2528
3028
|
isDeclaredInAmbientModule(d, "http2"))) {
|
|
2529
|
-
return psym
|
|
3029
|
+
return ts.symbolName(psym) === "Http2Server"
|
|
2530
3030
|
? { kind: "netServer" }
|
|
2531
|
-
: psym
|
|
3031
|
+
: ts.symbolName(psym) === "ClientHttp2Stream" || ts.symbolName(psym) === "ServerHttp2Stream"
|
|
2532
3032
|
? { kind: "http2Stream" }
|
|
2533
3033
|
: { kind: "http2Session" };
|
|
2534
3034
|
}
|
|
2535
3035
|
// http.ClientRequest (http.request/http.get results) — module-checked
|
|
2536
3036
|
// like IncomingMessage.
|
|
2537
|
-
if (psym
|
|
2538
|
-
|
|
2539
|
-
|
|
2540
|
-
.
|
|
2541
|
-
ctx.isStdlibFile(d.getSourceFile()) &&
|
|
3037
|
+
if (psym !== undefined &&
|
|
3038
|
+
ts.symbolName(psym) === "ClientRequest" &&
|
|
3039
|
+
psym.declarations.some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
|
|
3040
|
+
ctx.isStdlibFile(ts.getSourceFileOfNode(d)) &&
|
|
2542
3041
|
isDeclaredInAmbientModule(d, "http"))) {
|
|
2543
3042
|
return { kind: "httpClientReq" };
|
|
2544
3043
|
}
|
|
@@ -2550,10 +3049,9 @@ function mapTypeInner(type, ctx) {
|
|
|
2550
3049
|
// record) and ProcessEnv-typed parameters mappable. The fallback
|
|
2551
3050
|
// declarations' anonymous env type takes the pureIndexShape path below
|
|
2552
3051
|
// and interns the SAME shape.
|
|
2553
|
-
if (psym
|
|
2554
|
-
|
|
2555
|
-
|
|
2556
|
-
.some((d) => ts.isInterfaceDeclaration(d) && ctx.isStdlibFile(d.getSourceFile()))) {
|
|
3052
|
+
if (psym !== undefined &&
|
|
3053
|
+
ts.symbolName(psym) === "ProcessEnv" &&
|
|
3054
|
+
psym.declarations.some((d) => ts.isInterfaceDeclaration(d) && ctx.isStdlibFile(ts.getSourceFileOfNode(d)))) {
|
|
2557
3055
|
const value = withUndefinedArm(STRING, ctx.unions);
|
|
2558
3056
|
if (!value)
|
|
2559
3057
|
return null;
|
|
@@ -2587,8 +3085,9 @@ function mapTypeInner(type, ctx) {
|
|
|
2587
3085
|
if (isStdlibInterface("MapIterator") || isStdlibInterface("SetIterator"))
|
|
2588
3086
|
return DYN;
|
|
2589
3087
|
// Array iterators (`list.values()` and friends) are generators over the
|
|
2590
|
-
// live array: each step reads the current length and element.
|
|
2591
|
-
|
|
3088
|
+
// live array: each step reads the current length and element. String
|
|
3089
|
+
// iterators (`s[Symbol.iterator]()`) are generators over the code points.
|
|
3090
|
+
if (isStdlibInterface("ArrayIterator") || isStdlibInterface("StringIterator")) {
|
|
2592
3091
|
const arg = checker.getTypeArguments(widened)[0];
|
|
2593
3092
|
const yieldT = arg ? mapType(arg, ctx) : null;
|
|
2594
3093
|
if (!yieldT || yieldT.kind === "void" || isUnitType(yieldT))
|
|
@@ -2623,7 +3122,10 @@ function mapTypeInner(type, ctx) {
|
|
|
2623
3122
|
isStdlibInterface("IterableIterator") ||
|
|
2624
3123
|
// An Iterator<T> annotation holds a single-pass iterator object: a
|
|
2625
3124
|
// generator, or a native iterator adapted into one.
|
|
2626
|
-
isStdlibInterface("Iterator")
|
|
3125
|
+
isStdlibInterface("Iterator") ||
|
|
3126
|
+
// IteratorObject<T> is what the iterator helpers return: a helper
|
|
3127
|
+
// generator over its source (containers/iterator-helpers.ts).
|
|
3128
|
+
isStdlibInterface("IteratorObject")) {
|
|
2627
3129
|
const args = checker.getTypeArguments(widened);
|
|
2628
3130
|
const channels = genChannels(args[0], args[1], args[2], ctx);
|
|
2629
3131
|
if (!channels)
|
|
@@ -2644,10 +3146,9 @@ function mapTypeInner(type, ctx) {
|
|
|
2644
3146
|
// g.next()` binds without an annotation and reads flow.
|
|
2645
3147
|
{
|
|
2646
3148
|
const alias = widened.getAliasSymbol();
|
|
2647
|
-
if (alias
|
|
2648
|
-
|
|
2649
|
-
|
|
2650
|
-
.some((d) => ts.isTypeAliasDeclaration(d) && ctx.isStdlibFile(d.getSourceFile()))) {
|
|
3149
|
+
if (alias !== undefined &&
|
|
3150
|
+
ts.symbolName(alias) === "IteratorResult" &&
|
|
3151
|
+
alias.declarations.some((d) => ts.isTypeAliasDeclaration(d) && ctx.isStdlibFile(ts.getSourceFileOfNode(d)))) {
|
|
2651
3152
|
const targs = widened.getAliasTypeArguments() ?? [];
|
|
2652
3153
|
const channels = genChannels(targs[0], targs[1], undefined, ctx);
|
|
2653
3154
|
if (!channels)
|
|
@@ -2745,12 +3246,12 @@ function mapTypeInner(type, ctx) {
|
|
|
2745
3246
|
];
|
|
2746
3247
|
const fields = [];
|
|
2747
3248
|
for (const property of checker.getPropertiesOfType(widened)) {
|
|
2748
|
-
if (!known.includes(property
|
|
3249
|
+
if (!known.includes(ts.symbolName(property)))
|
|
2749
3250
|
return null;
|
|
2750
3251
|
const type = mapType(checker.getTypeOfSymbol(property), ctx);
|
|
2751
3252
|
if (!type)
|
|
2752
3253
|
return null;
|
|
2753
|
-
fields.push({ name: property
|
|
3254
|
+
fields.push({ name: ts.symbolName(property), type });
|
|
2754
3255
|
}
|
|
2755
3256
|
const order = fields.map((field) => field.name);
|
|
2756
3257
|
fields.sort((a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0));
|
|
@@ -2758,23 +3259,21 @@ function mapTypeInner(type, ctx) {
|
|
|
2758
3259
|
}
|
|
2759
3260
|
// Filesystem options are data records. Keep their declared optional fields
|
|
2760
3261
|
// instead of allowing arbitrary standard-library interfaces into records.
|
|
2761
|
-
if ((psym
|
|
2762
|
-
psym
|
|
2763
|
-
psym
|
|
2764
|
-
psym
|
|
2765
|
-
|
|
2766
|
-
.
|
|
2767
|
-
.some((d) => ts.isInterfaceDeclaration(d) &&
|
|
2768
|
-
ctx.isStdlibFile(d.getSourceFile()) &&
|
|
3262
|
+
if (((psym !== undefined && ts.symbolName(psym) === "FileReadOptions") ||
|
|
3263
|
+
(psym !== undefined && ts.symbolName(psym) === "ReadOptions") ||
|
|
3264
|
+
(psym !== undefined && ts.symbolName(psym) === "ReadOptionsWithBuffer") ||
|
|
3265
|
+
(psym !== undefined && ts.symbolName(psym) === "WriteOptions")) &&
|
|
3266
|
+
psym.declarations.some((d) => ts.isInterfaceDeclaration(d) &&
|
|
3267
|
+
ctx.isStdlibFile(ts.getSourceFileOfNode(d)) &&
|
|
2769
3268
|
(isDeclaredInAmbientModule(d, "fs/promises") || isDeclaredInAmbientModule(d, "fs")))) {
|
|
2770
3269
|
const fields = [];
|
|
2771
3270
|
for (const property of checker.getPropertiesOfType(widened)) {
|
|
2772
|
-
if (!["buffer", "offset", "length", "position"].includes(property
|
|
3271
|
+
if (!["buffer", "offset", "length", "position"].includes(ts.symbolName(property)))
|
|
2773
3272
|
return null;
|
|
2774
3273
|
const type = mapType(checker.getTypeOfSymbol(property), ctx);
|
|
2775
3274
|
if (!type)
|
|
2776
3275
|
return null;
|
|
2777
|
-
fields.push({ name: property
|
|
3276
|
+
fields.push({ name: ts.symbolName(property), type });
|
|
2778
3277
|
}
|
|
2779
3278
|
const order = fields.map((field) => field.name);
|
|
2780
3279
|
fields.sort((a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0));
|
|
@@ -2784,26 +3283,24 @@ function mapTypeInner(type, ctx) {
|
|
|
2784
3283
|
// null-prototype objects returned by FileHandle.read/write. The native
|
|
2785
3284
|
// record does not model the prototype (unobservable through the lowered
|
|
2786
3285
|
// surface); it preserves the caller buffer/string by reference.
|
|
2787
|
-
if ((psym
|
|
2788
|
-
psym
|
|
2789
|
-
psym
|
|
2790
|
-
psym
|
|
2791
|
-
psym
|
|
2792
|
-
psym
|
|
2793
|
-
|
|
2794
|
-
.
|
|
2795
|
-
.some((d) => ts.isInterfaceDeclaration(d) &&
|
|
2796
|
-
ctx.isStdlibFile(d.getSourceFile()) &&
|
|
3286
|
+
if (((psym !== undefined && ts.symbolName(psym) === "FileReadResult") ||
|
|
3287
|
+
(psym !== undefined && ts.symbolName(psym) === "FileWriteResult") ||
|
|
3288
|
+
(psym !== undefined && ts.symbolName(psym) === "FileReadvResult") ||
|
|
3289
|
+
(psym !== undefined && ts.symbolName(psym) === "FileWritevResult") ||
|
|
3290
|
+
(psym !== undefined && ts.symbolName(psym) === "ReadVResult") ||
|
|
3291
|
+
(psym !== undefined && ts.symbolName(psym) === "WriteVResult")) &&
|
|
3292
|
+
psym.declarations.some((d) => ts.isInterfaceDeclaration(d) &&
|
|
3293
|
+
ctx.isStdlibFile(ts.getSourceFileOfNode(d)) &&
|
|
2797
3294
|
(isDeclaredInAmbientModule(d, "fs/promises") ||
|
|
2798
|
-
((psym
|
|
3295
|
+
((ts.symbolName(psym) === "ReadVResult" || ts.symbolName(psym) === "WriteVResult") &&
|
|
2799
3296
|
isDeclaredInAmbientModule(d, "fs"))))) {
|
|
2800
3297
|
const args = checker.getTypeArguments(widened);
|
|
2801
3298
|
if (args.length !== 1)
|
|
2802
3299
|
return null;
|
|
2803
|
-
const vector = psym
|
|
2804
|
-
psym
|
|
2805
|
-
psym
|
|
2806
|
-
psym
|
|
3300
|
+
const vector = ts.symbolName(psym) === "FileReadvResult" ||
|
|
3301
|
+
ts.symbolName(psym) === "FileWritevResult" ||
|
|
3302
|
+
ts.symbolName(psym) === "ReadVResult" ||
|
|
3303
|
+
ts.symbolName(psym) === "WriteVResult";
|
|
2807
3304
|
const emptyVector = vector &&
|
|
2808
3305
|
checker.isArrayType(args[0]) &&
|
|
2809
3306
|
(checker.getTypeArguments(args[0])[0].flags & ts.TypeFlags.Never) !== 0;
|
|
@@ -2814,9 +3311,9 @@ function mapTypeInner(type, ctx) {
|
|
|
2814
3311
|
: !(payload.kind === "string" || (payload.kind === "bytes" && payload.elem === "u8")))) {
|
|
2815
3312
|
return null;
|
|
2816
3313
|
}
|
|
2817
|
-
const count = psym
|
|
2818
|
-
psym
|
|
2819
|
-
psym
|
|
3314
|
+
const count = ts.symbolName(psym) === "FileReadResult" ||
|
|
3315
|
+
ts.symbolName(psym) === "FileReadvResult" ||
|
|
3316
|
+
ts.symbolName(psym) === "ReadVResult"
|
|
2820
3317
|
? "bytesRead"
|
|
2821
3318
|
: "bytesWritten";
|
|
2822
3319
|
const payloadName = vector ? "buffers" : "buffer";
|
|
@@ -2842,11 +3339,10 @@ function mapTypeInner(type, ctx) {
|
|
|
2842
3339
|
// encoding:'buffer' readdir form has no lowering); the shipped fallback
|
|
2843
3340
|
// declares it concrete (an interface; @types/node uses a class — both
|
|
2844
3341
|
// provenance-checked, the Buffer/URL pattern).
|
|
2845
|
-
if (psym
|
|
2846
|
-
|
|
2847
|
-
|
|
2848
|
-
.
|
|
2849
|
-
ctx.isStdlibFile(d.getSourceFile()))) {
|
|
3342
|
+
if (psym !== undefined &&
|
|
3343
|
+
ts.symbolName(psym) === "Dirent" &&
|
|
3344
|
+
psym.declarations.some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
|
|
3345
|
+
ctx.isStdlibFile(ts.getSourceFileOfNode(d)))) {
|
|
2850
3346
|
const args = checker.getTypeArguments(widened);
|
|
2851
3347
|
if (args.length > 1)
|
|
2852
3348
|
return null;
|
|
@@ -2884,15 +3380,13 @@ function mapTypeInner(type, ctx) {
|
|
|
2884
3380
|
shapeId: ctx.shapes.intern(["idle", "irq", "nice", "sys", "user"].map((name) => ({ name, type: F64 })), false, undefined, ["user", "nice", "sys", "idle", "irq"]),
|
|
2885
3381
|
});
|
|
2886
3382
|
if (psym &&
|
|
2887
|
-
|
|
2888
|
-
.declarationsOf(psym)
|
|
2889
|
-
.some((d) => ts.isTypeLiteralNode(d) &&
|
|
3383
|
+
psym.declarations.some((d) => ts.isTypeLiteralNode(d) &&
|
|
2890
3384
|
ts.isPropertySignature(d.parent) &&
|
|
2891
3385
|
ts.isIdentifier(d.parent.name) &&
|
|
2892
3386
|
d.parent.name.text === "times" &&
|
|
2893
3387
|
ts.isInterfaceDeclaration(d.parent.parent) &&
|
|
2894
3388
|
d.parent.parent.name.text === "CpuInfo" &&
|
|
2895
|
-
ctx.isStdlibFile(
|
|
3389
|
+
ctx.isStdlibFile(ts.getSourceFileOfNode(d))))
|
|
2896
3390
|
return cpuTimes();
|
|
2897
3391
|
if (isStdlibInterface("CpuInfo")) {
|
|
2898
3392
|
const times = cpuTimes();
|
|
@@ -2906,7 +3400,7 @@ function mapTypeInner(type, ctx) {
|
|
|
2906
3400
|
};
|
|
2907
3401
|
}
|
|
2908
3402
|
if (isStdlibInterface("ParsedPath") || isStdlibInterface("FormatInputPathObject")) {
|
|
2909
|
-
const field = psym
|
|
3403
|
+
const field = ts.symbolName(psym) === "ParsedPath" ? STRING : withUndefinedArm(STRING, ctx.unions);
|
|
2910
3404
|
if (!field)
|
|
2911
3405
|
return null;
|
|
2912
3406
|
return {
|
|
@@ -2936,26 +3430,40 @@ function mapTypeInner(type, ctx) {
|
|
|
2936
3430
|
], false, undefined, ["uid", "gid", "username", "homedir", "shell"]),
|
|
2937
3431
|
};
|
|
2938
3432
|
}
|
|
2939
|
-
// The promisified exec/execFile result `{ stdout: string; stderr: string }
|
|
2940
|
-
//
|
|
2941
|
-
//
|
|
2942
|
-
//
|
|
2943
|
-
//
|
|
2944
|
-
//
|
|
3433
|
+
// The promisified exec/execFile result `{ stdout: string; stderr: string }`
|
|
3434
|
+
// and the promisified dns.lookupService result `{ hostname: string;
|
|
3435
|
+
// service: string }`: anonymous type literals (@types/node's
|
|
3436
|
+
// __promisify__ overloads in child_process and dns, the shipped
|
|
3437
|
+
// fallback's promisify overloads in util), so they map by provenance and
|
|
3438
|
+
// exact shape. The exec result is interned as the %execFileAsync/
|
|
3439
|
+
// %execAsync helpers build it; Node builds { stdout, stderr } and
|
|
3440
|
+
// { hostname, service }. The Buffer-typed literals do not match and stay
|
|
2945
3441
|
// unmapped.
|
|
2946
3442
|
if (psym &&
|
|
2947
|
-
|
|
2948
|
-
.
|
|
2949
|
-
|
|
2950
|
-
|
|
2951
|
-
|
|
3443
|
+
psym.declarations.some((d) => ts.isTypeLiteralNode(d) &&
|
|
3444
|
+
ctx.isStdlibFile(ts.getSourceFileOfNode(d)) &&
|
|
3445
|
+
(isDeclaredInAmbientModule(d, "child_process") ||
|
|
3446
|
+
isDeclaredInAmbientModule(d, "util") ||
|
|
3447
|
+
isDeclaredInAmbientModule(d, "dns")))) {
|
|
2952
3448
|
const props = checker.getPropertiesOfType(widened);
|
|
2953
|
-
|
|
2954
|
-
props.every((p) => (p.
|
|
2955
|
-
(p.flags & ts.
|
|
2956
|
-
|
|
2957
|
-
|
|
3449
|
+
const names = props.length === 2 &&
|
|
3450
|
+
props.every((p) => (p.flags & ts.SymbolFlags.Optional) === 0 &&
|
|
3451
|
+
(checker.getTypeOfSymbol(p).flags & ts.TypeFlags.String) !== 0)
|
|
3452
|
+
? props
|
|
3453
|
+
.map((p) => ts.symbolName(p))
|
|
3454
|
+
.sort()
|
|
3455
|
+
.join(",")
|
|
3456
|
+
: "";
|
|
3457
|
+
if (names === "stderr,stdout")
|
|
2958
3458
|
return { kind: "record", shapeId: execResultShape(ctx.shapes) };
|
|
3459
|
+
if (names === "hostname,service") {
|
|
3460
|
+
return {
|
|
3461
|
+
kind: "record",
|
|
3462
|
+
shapeId: ctx.shapes.intern([
|
|
3463
|
+
{ name: "hostname", type: STRING },
|
|
3464
|
+
{ name: "service", type: STRING },
|
|
3465
|
+
], false, undefined, ["hostname", "service"]),
|
|
3466
|
+
};
|
|
2959
3467
|
}
|
|
2960
3468
|
}
|
|
2961
3469
|
// crypto.X509Certificate — the Dirent-style data record: THREE visible
|
|
@@ -2965,11 +3473,10 @@ function mapTypeInner(type, ctx) {
|
|
|
2965
3473
|
// `declare module "crypto"`, the shipped fallback mirrors it.
|
|
2966
3474
|
// JSON.stringify of one shows the three fields where Node's
|
|
2967
3475
|
// internal-slot object shows {} — the Dirent %dtype edge's cousin.
|
|
2968
|
-
if (psym
|
|
2969
|
-
|
|
2970
|
-
|
|
2971
|
-
.
|
|
2972
|
-
ctx.isStdlibFile(d.getSourceFile()) &&
|
|
3476
|
+
if (psym !== undefined &&
|
|
3477
|
+
ts.symbolName(psym) === "X509Certificate" &&
|
|
3478
|
+
psym.declarations.some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
|
|
3479
|
+
ctx.isStdlibFile(ts.getSourceFileOfNode(d)) &&
|
|
2973
3480
|
isDeclaredInAmbientModule(d, "crypto"))) {
|
|
2974
3481
|
return {
|
|
2975
3482
|
kind: "record",
|
|
@@ -2988,16 +3495,31 @@ function mapTypeInner(type, ctx) {
|
|
|
2988
3495
|
// record (util.inspect names the class from entryType, like Node).
|
|
2989
3496
|
// @types/node declares the classes in perf_hooks and global interfaces
|
|
2990
3497
|
// over them; the shipped fallback declares the classes.
|
|
2991
|
-
if ((psym
|
|
2992
|
-
psym
|
|
2993
|
-
psym
|
|
2994
|
-
|
|
2995
|
-
.
|
|
2996
|
-
.some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
|
|
2997
|
-
ctx.isStdlibFile(d.getSourceFile()))) {
|
|
3498
|
+
if (((psym !== undefined && ts.symbolName(psym) === "PerformanceEntry") ||
|
|
3499
|
+
(psym !== undefined && ts.symbolName(psym) === "PerformanceMark") ||
|
|
3500
|
+
(psym !== undefined && ts.symbolName(psym) === "PerformanceMeasure")) &&
|
|
3501
|
+
psym.declarations.some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
|
|
3502
|
+
ctx.isStdlibFile(ts.getSourceFileOfNode(d)))) {
|
|
2998
3503
|
return { kind: "record", shapeId: perfEntryShape(ctx.shapes, ctx.unions) };
|
|
2999
3504
|
}
|
|
3000
3505
|
// readline's getCursorPos() record, in Node's key order ({ cols, rows }).
|
|
3506
|
+
// perf_hooks' EventLoopUtilization (performance.eventLoopUtilization's
|
|
3507
|
+
// result): a plain data record in Node's key order.
|
|
3508
|
+
if (isStdlibInterface("EventLoopUtilization")) {
|
|
3509
|
+
return {
|
|
3510
|
+
kind: "record",
|
|
3511
|
+
shapeId: ctx.shapes.intern([
|
|
3512
|
+
{ name: "active", type: F64 },
|
|
3513
|
+
{ name: "idle", type: F64 },
|
|
3514
|
+
{ name: "utilization", type: F64 },
|
|
3515
|
+
], false, undefined, ["idle", "active", "utilization"]),
|
|
3516
|
+
};
|
|
3517
|
+
}
|
|
3518
|
+
// monitorEventLoopDelay's IntervalHistogram: a numeric handle into the
|
|
3519
|
+
// runtime's histogram table, like a timer handle. Its members lower over
|
|
3520
|
+
// the handle (builtins/performance.ts).
|
|
3521
|
+
if (isStdlibInterface("IntervalHistogram"))
|
|
3522
|
+
return F64;
|
|
3001
3523
|
if (isStdlibInterface("CursorPos")) {
|
|
3002
3524
|
return {
|
|
3003
3525
|
kind: "record",
|
|
@@ -3015,6 +3537,29 @@ function mapTypeInner(type, ctx) {
|
|
|
3015
3537
|
shapeId: ctx.shapes.intern([...names].sort().map((name) => ({ name, type: F64 })), false, undefined, names),
|
|
3016
3538
|
};
|
|
3017
3539
|
}
|
|
3540
|
+
// v8.getHeapStatistics()'s record, in Node's key order (builtins/v8.ts).
|
|
3541
|
+
if (isStdlibInterface("HeapInfo")) {
|
|
3542
|
+
const names = [
|
|
3543
|
+
"total_heap_size",
|
|
3544
|
+
"total_heap_size_executable",
|
|
3545
|
+
"total_physical_size",
|
|
3546
|
+
"total_available_size",
|
|
3547
|
+
"used_heap_size",
|
|
3548
|
+
"heap_size_limit",
|
|
3549
|
+
"malloced_memory",
|
|
3550
|
+
"peak_malloced_memory",
|
|
3551
|
+
"does_zap_garbage",
|
|
3552
|
+
"number_of_native_contexts",
|
|
3553
|
+
"number_of_detached_contexts",
|
|
3554
|
+
"total_global_handles_size",
|
|
3555
|
+
"used_global_handles_size",
|
|
3556
|
+
"external_memory",
|
|
3557
|
+
];
|
|
3558
|
+
return {
|
|
3559
|
+
kind: "record",
|
|
3560
|
+
shapeId: ctx.shapes.intern([...names].sort().map((name) => ({ name, type: F64 })), false, undefined, names),
|
|
3561
|
+
};
|
|
3562
|
+
}
|
|
3018
3563
|
// process.cpuUsage()/threadCpuUsage()'s {user, system} microsecond
|
|
3019
3564
|
// record and resourceUsage()'s getrusage record — stdlib data
|
|
3020
3565
|
// interfaces interned explicitly (the RemoteInfo pattern; declared
|
|
@@ -3073,7 +3618,7 @@ function mapTypeInner(type, ctx) {
|
|
|
3073
3618
|
// over a row answers exactly Node.
|
|
3074
3619
|
if (isStdlibInterface("NetworkInterfaceInfoIPv4") ||
|
|
3075
3620
|
isStdlibInterface("NetworkInterfaceInfoIPv6")) {
|
|
3076
|
-
const v6 = psym
|
|
3621
|
+
const v6 = ts.symbolName(psym) === "NetworkInterfaceInfoIPv6";
|
|
3077
3622
|
const cidrArms = [NULL_T, STRING].sort((a, b) => (typeKey(a) < typeKey(b) ? -1 : 1));
|
|
3078
3623
|
const cidr = { kind: "union", unionId: ctx.unions.intern(cidrArms) };
|
|
3079
3624
|
const scopeid = v6 ? F64 : withUndefinedArm(F64, ctx.unions);
|
|
@@ -3173,146 +3718,8 @@ function mapTypeInner(type, ctx) {
|
|
|
3173
3718
|
return hybrid;
|
|
3174
3719
|
}
|
|
3175
3720
|
const callSigs = checker.getCallSignatures(widened);
|
|
3176
|
-
if (callSigs.length === 1)
|
|
3177
|
-
|
|
3178
|
-
if (sig.getTypeParameters().length)
|
|
3179
|
-
return null;
|
|
3180
|
-
// A SYNTHESIZED rest param (tsc's JS inference for a function body
|
|
3181
|
-
// reading `arguments` — `(...args: any[]) => any` whose args symbol
|
|
3182
|
-
// has no declaration): the dotDotDot check below can't see it, and a
|
|
3183
|
-
// fixed-arity func mapping would LIE about the value's calling
|
|
3184
|
-
// convention. Detected by the param-count mismatch against the
|
|
3185
|
-
// signature's own declaration, excluding an erased `this` parameter.
|
|
3186
|
-
{
|
|
3187
|
-
const sigDecl = checker.signatureDeclaration(sig);
|
|
3188
|
-
const declParams = sigDecl !== undefined && ts.isFunctionLike(sigDecl) ? sigDecl.parameters : undefined;
|
|
3189
|
-
if (declParams !== undefined &&
|
|
3190
|
-
runtimeParameterCount(declParams) !== sig.getParameters().length) {
|
|
3191
|
-
return null;
|
|
3192
|
-
}
|
|
3193
|
-
// tsgo never SYNTHESIZES that rest param into the inferred signature
|
|
3194
|
-
// (5.9.3 did — the count mismatch above was the whole detector
|
|
3195
|
-
// there), so the declaration's own body answers directly.
|
|
3196
|
-
if (sigDecl !== undefined && ts.isFunctionLike(sigDecl) && bodyReadsArguments(sigDecl)) {
|
|
3197
|
-
return null;
|
|
3198
|
-
}
|
|
3199
|
-
}
|
|
3200
|
-
const params = [];
|
|
3201
|
-
let typedRest = false;
|
|
3202
|
-
for (const p of sig.getParameters()) {
|
|
3203
|
-
const decl = checker.valueDeclarationOf(p);
|
|
3204
|
-
const rest = decl !== undefined && ts.isParameter(decl) && decl.dotDotDotToken !== undefined;
|
|
3205
|
-
// arity ABI selected by lambdaSignature. Treating an inferred any[]
|
|
3206
|
-
// declaration as a typed packed-array closure would bypass its boxed
|
|
3207
|
-
// spread/error semantics and change coverage classification.
|
|
3208
|
-
if (rest && decl !== undefined && isJsSourceFile(decl.getSourceFile()))
|
|
3209
|
-
return null;
|
|
3210
|
-
const optional = decl !== undefined &&
|
|
3211
|
-
ts.isParameter(decl) &&
|
|
3212
|
-
(decl.questionToken !== undefined || decl.initializer !== undefined);
|
|
3213
|
-
let pt = mapType(checker.getTypeOfSymbol(p), ctx);
|
|
3214
|
-
if (decl &&
|
|
3215
|
-
ts.isParameter(decl) &&
|
|
3216
|
-
ts.isSetAccessorDeclaration(decl.parent) &&
|
|
3217
|
-
isJsSourceFile(decl.getSourceFile()))
|
|
3218
|
-
pt = DYN;
|
|
3219
|
-
// An inferred JavaScript binding pattern consumes an iterable; it
|
|
3220
|
-
// does not require the caller's array to have exactly this length.
|
|
3221
|
-
const executor = decl && ts.isParameter(decl) ? decl.parent : null;
|
|
3222
|
-
const construction = executor?.parent;
|
|
3223
|
-
const constructorSymbol = construction && ts.isNewExpression(construction)
|
|
3224
|
-
? checker.getSymbolAtLocation(construction.expression)
|
|
3225
|
-
: undefined;
|
|
3226
|
-
const nativeExecutor = executor &&
|
|
3227
|
-
(ts.isArrowFunction(executor) || ts.isFunctionExpression(executor)) &&
|
|
3228
|
-
construction &&
|
|
3229
|
-
ts.isNewExpression(construction) &&
|
|
3230
|
-
construction.arguments?.[0] === executor &&
|
|
3231
|
-
ts.isIdentifier(construction.expression) &&
|
|
3232
|
-
construction.expression.text === "Promise" &&
|
|
3233
|
-
constructorSymbol &&
|
|
3234
|
-
checker
|
|
3235
|
-
.declarationsOf(constructorSymbol)
|
|
3236
|
-
.some((site) => ctx.isStdlibFile(site.getSourceFile()));
|
|
3237
|
-
if (!nativeExecutor &&
|
|
3238
|
-
decl &&
|
|
3239
|
-
ts.isParameter(decl) &&
|
|
3240
|
-
!decl.dotDotDotToken &&
|
|
3241
|
-
!ts.isSetAccessorDeclaration(decl.parent) &&
|
|
3242
|
-
isJsSourceFile(decl.getSourceFile()) &&
|
|
3243
|
-
!decl.type &&
|
|
3244
|
-
!/@(?:param|type)\b/.test(decl.getSourceFile().text.slice(decl.parent?.pos ?? decl.pos, decl.getStart())))
|
|
3245
|
-
pt = DYN;
|
|
3246
|
-
if (pt)
|
|
3247
|
-
pt = jsOpenObjectType(decl, pt, ctx.shapes, ctx.unions);
|
|
3248
|
-
// Belt and braces for non-strict type worlds: an optional param's
|
|
3249
|
-
// ABI slot is always the undefined-armed union (strictNullChecks
|
|
3250
|
-
// already spells it that way; arm it here if the world didn't).
|
|
3251
|
-
if (optional && pt && pt.kind !== "void" && pt.kind !== "dyn") {
|
|
3252
|
-
const armed = withUndefinedArm(pt, ctx.unions);
|
|
3253
|
-
if (!armed)
|
|
3254
|
-
return null;
|
|
3255
|
-
pt = armed;
|
|
3256
|
-
}
|
|
3257
|
-
if (!pt)
|
|
3258
|
-
return null;
|
|
3259
|
-
if (rest) {
|
|
3260
|
-
if (pt.kind !== "array")
|
|
3261
|
-
return null;
|
|
3262
|
-
typedRest = true;
|
|
3263
|
-
}
|
|
3264
|
-
// `(value: void) => void` (Promise<void>'s resolve) is callable with
|
|
3265
|
-
// no arguments — a void param is dropped, not a mapping failure.
|
|
3266
|
-
if (pt.kind === "void")
|
|
3267
|
-
continue;
|
|
3268
|
-
params.push(pt);
|
|
3269
|
-
}
|
|
3270
|
-
const retT = checker.getReturnTypeOfSignature(sig);
|
|
3271
|
-
// `() => never` (a throw-only lambda's inferred type) is assignable to
|
|
3272
|
-
// `() => void` and its calls never produce a value — map the return
|
|
3273
|
-
// like declaredReturnType does for declarations. JS null/undefined
|
|
3274
|
-
// returns can read mutable fields, so callable values use the same
|
|
3275
|
-
// checked-native return ABI as their implementations.
|
|
3276
|
-
const sigDecl = checker.signatureDeclaration(sig);
|
|
3277
|
-
const jsUnitReturn = sigDecl !== undefined &&
|
|
3278
|
-
isJsSourceFile(sigDecl.getSourceFile()) &&
|
|
3279
|
-
(retT.flags & (ts.TypeFlags.Null | ts.TypeFlags.Undefined)) !== 0;
|
|
3280
|
-
let ret = jsUnitReturn || (retT.flags & ts.TypeFlags.Any) !== 0
|
|
3281
|
-
? DYN
|
|
3282
|
-
: retT.flags & ts.TypeFlags.Never
|
|
3283
|
-
? VOID
|
|
3284
|
-
: mapType(retT, ctx);
|
|
3285
|
-
if (sigDecl && ts.isGetAccessorDeclaration(sigDecl) && isJsSourceFile(sigDecl.getSourceFile()))
|
|
3286
|
-
ret = DYN;
|
|
3287
|
-
if (sigDecl && isJsSourceFile(sigDecl.getSourceFile()) && ret?.kind === "array")
|
|
3288
|
-
ret = DYN;
|
|
3289
|
-
if (sigDecl &&
|
|
3290
|
-
ts.isFunctionLike(sigDecl) &&
|
|
3291
|
-
isJsSourceFile(sigDecl.getSourceFile()) &&
|
|
3292
|
-
!sigDecl.type &&
|
|
3293
|
-
!/@returns?\b/.test(sigDecl.getSourceFile().text.slice(sigDecl.pos, sigDecl.getStart())) &&
|
|
3294
|
-
ret?.kind === "record")
|
|
3295
|
-
ret = DYN;
|
|
3296
|
-
if (sigDecl &&
|
|
3297
|
-
ts.isFunctionLike(sigDecl) &&
|
|
3298
|
-
isJsSourceFile(sigDecl.getSourceFile()) &&
|
|
3299
|
-
!sigDecl.type &&
|
|
3300
|
-
!/@returns?\b/.test(sigDecl.getSourceFile().text.slice(sigDecl.pos, sigDecl.getStart())) &&
|
|
3301
|
-
(ret?.kind === "date" ||
|
|
3302
|
-
(ret?.kind === "union" &&
|
|
3303
|
-
ctx.unions.get(ret.unionId)?.arms.some((arm) => arm.kind === "func"))))
|
|
3304
|
-
ret = DYN;
|
|
3305
|
-
if (ret &&
|
|
3306
|
-
sigDecl &&
|
|
3307
|
-
isJsSourceFile(sigDecl.getSourceFile()) &&
|
|
3308
|
-
functionCanReturnUndefined(sigDecl))
|
|
3309
|
-
ret = withUndefinedArm(ret, ctx.unions) ?? ret;
|
|
3310
|
-
if (!ret)
|
|
3311
|
-
return null;
|
|
3312
|
-
return typedRest
|
|
3313
|
-
? { kind: "func", params, ret, rest: true, restAbi: "typed" }
|
|
3314
|
-
: funcOf(params, ret);
|
|
3315
|
-
}
|
|
3721
|
+
if (callSigs.length === 1)
|
|
3722
|
+
return mapCallSignature(callSigs[0], ctx);
|
|
3316
3723
|
// Records: object types whose members are all data properties (shorthand
|
|
3317
3724
|
// methods in type position count — they're func-typed fields) with
|
|
3318
3725
|
// mappable types; no call/construct signatures, no index signatures, not
|
|
@@ -3349,10 +3756,8 @@ function mapTypeInner(type, ctx) {
|
|
|
3349
3756
|
if (flags & ts.TypeFlags.Object &&
|
|
3350
3757
|
callSigs.length === 0 &&
|
|
3351
3758
|
psym !== undefined &&
|
|
3352
|
-
|
|
3353
|
-
|
|
3354
|
-
.declarationsOf(psym)
|
|
3355
|
-
.every((d) => ts.isInterfaceDeclaration(d) && !ctx.isStdlibFile(d.getSourceFile()))) {
|
|
3759
|
+
psym.declarations.length > 0 &&
|
|
3760
|
+
psym.declarations.every((d) => ts.isInterfaceDeclaration(d) && !ctx.isStdlibFile(ts.getSourceFileOfNode(d)))) {
|
|
3356
3761
|
const CHILD_SURFACE = new Set([
|
|
3357
3762
|
"pid",
|
|
3358
3763
|
"exitCode",
|
|
@@ -3385,37 +3790,49 @@ function mapTypeInner(type, ctx) {
|
|
|
3385
3790
|
const props = checker.getPropertiesOfType(widened);
|
|
3386
3791
|
let core = 0;
|
|
3387
3792
|
const childMemberType = (p) => {
|
|
3388
|
-
if (["kill", "on", "once", "off", "removeListener", "unref", "ref"].includes(p
|
|
3793
|
+
if (["kill", "on", "once", "off", "removeListener", "unref", "ref"].includes(ts.symbolName(p))) {
|
|
3389
3794
|
return checker.getCallSignatures(checker.getTypeOfSymbol(p)).length > 0;
|
|
3390
3795
|
}
|
|
3391
|
-
const expected = p
|
|
3796
|
+
const expected = ts.symbolName(p) === "stdout" || ts.symbolName(p) === "stderr"
|
|
3392
3797
|
? "childStream"
|
|
3393
|
-
: p
|
|
3798
|
+
: ts.symbolName(p) === "stdin"
|
|
3394
3799
|
? "childWriter"
|
|
3395
|
-
: p
|
|
3800
|
+
: ts.symbolName(p) === "killed"
|
|
3396
3801
|
? "bool"
|
|
3397
3802
|
: "f64";
|
|
3398
|
-
const unit = p
|
|
3803
|
+
const unit = ts.symbolName(p) === "pid"
|
|
3399
3804
|
? "undefinedT"
|
|
3400
|
-
: p
|
|
3401
|
-
p
|
|
3402
|
-
p
|
|
3403
|
-
p
|
|
3805
|
+
: ts.symbolName(p) === "exitCode" ||
|
|
3806
|
+
ts.symbolName(p) === "stdin" ||
|
|
3807
|
+
ts.symbolName(p) === "stdout" ||
|
|
3808
|
+
ts.symbolName(p) === "stderr"
|
|
3404
3809
|
? "nullT"
|
|
3405
3810
|
: null;
|
|
3406
3811
|
const mapped = mapType(checker.getTypeOfSymbol(p), ctx);
|
|
3407
3812
|
if (!mapped)
|
|
3408
3813
|
return false;
|
|
3409
3814
|
const arms = mapped.kind === "union" ? ctx.unions.get(mapped.unionId)?.arms : [mapped];
|
|
3815
|
+
// Under the general stream representation the stdio members are the
|
|
3816
|
+
// runtime stream classes.
|
|
3817
|
+
const isExpected = (arm) => arm.kind === expected ||
|
|
3818
|
+
(ctx.generalNodeStreams === true &&
|
|
3819
|
+
arm.kind === "object" &&
|
|
3820
|
+
((expected === "childStream" && arm.className === "%Readable") ||
|
|
3821
|
+
(expected === "childWriter" && arm.className === "%Writable"))) ||
|
|
3822
|
+
// Checked-dynamic stream slots: `NodeJS.ReadableStream | null`
|
|
3823
|
+
// collapses to dyn (the reads still produce the bridged stream).
|
|
3824
|
+
(ctx.dynNodeStreams === true &&
|
|
3825
|
+
arm.kind === "dyn" &&
|
|
3826
|
+
(expected === "childStream" || expected === "childWriter"));
|
|
3410
3827
|
return (arms !== undefined &&
|
|
3411
|
-
arms.some(
|
|
3412
|
-
arms.every((arm) => arm
|
|
3828
|
+
arms.some(isExpected) &&
|
|
3829
|
+
arms.every((arm) => isExpected(arm) || arm.kind === unit));
|
|
3413
3830
|
};
|
|
3414
3831
|
const childShaped = props.length > 0 &&
|
|
3415
3832
|
props.every((p) => {
|
|
3416
|
-
if (!CHILD_SURFACE.has(p
|
|
3833
|
+
if (!CHILD_SURFACE.has(ts.symbolName(p)) || !childMemberType(p))
|
|
3417
3834
|
return false;
|
|
3418
|
-
if (CHILD_CORE.has(p
|
|
3835
|
+
if (CHILD_CORE.has(ts.symbolName(p)))
|
|
3419
3836
|
core++;
|
|
3420
3837
|
return true;
|
|
3421
3838
|
});
|
|
@@ -3423,6 +3840,9 @@ function mapTypeInner(type, ctx) {
|
|
|
3423
3840
|
return CHILD_T;
|
|
3424
3841
|
}
|
|
3425
3842
|
if (flags & (ts.TypeFlags.Object | ts.TypeFlags.Intersection) && callSigs.length === 0) {
|
|
3843
|
+
const viaMapped = mapBoundMappedType(widened, ctx);
|
|
3844
|
+
if (viaMapped)
|
|
3845
|
+
return viaMapped;
|
|
3426
3846
|
const viaAlias = mapGenericUtilityAlias(widened, ctx);
|
|
3427
3847
|
if (viaAlias)
|
|
3428
3848
|
return viaAlias;
|
|
@@ -3466,7 +3886,16 @@ function mapTypeInner(type, ctx) {
|
|
|
3466
3886
|
const parts = ts.constituentTypes(widened);
|
|
3467
3887
|
const emptyTuple = (part) => checker.isTupleType(part) &&
|
|
3468
3888
|
checker.getTypeArguments(part).length === 0;
|
|
3469
|
-
|
|
3889
|
+
// The match-result fallback `s.match(re) || []` (and `?? []`) widens
|
|
3890
|
+
// to `RegExpMatchArray | []`: the empty tuple is one of the match
|
|
3891
|
+
// array's own values too.
|
|
3892
|
+
const matchArray = (part) => {
|
|
3893
|
+
// The names have no leading `__`, so the escaped name is the name.
|
|
3894
|
+
const name = part.getSymbol()?.escapedName;
|
|
3895
|
+
return ((name === "RegExpMatchArray" || name === "RegExpExecArray") &&
|
|
3896
|
+
(part.getSymbol()?.declarations.some((d) => ctx.isStdlibFile(d.getSourceFile())) ?? false));
|
|
3897
|
+
};
|
|
3898
|
+
const hasArrayPart = parts.some((part) => checker.isArrayType(part) || matchArray(part));
|
|
3470
3899
|
for (const part of parts) {
|
|
3471
3900
|
if (hasArrayPart && emptyTuple(part))
|
|
3472
3901
|
continue;
|
|
@@ -3543,7 +3972,9 @@ function mapTypeInner(type, ctx) {
|
|
|
3543
3972
|
// semantics would DEGRADE under the collapse — class instances,
|
|
3544
3973
|
// Maps/Sets, functions (closure identity, `x === String`
|
|
3545
3974
|
// narrowing), promises, regexes, generators, handles — keep their
|
|
3546
|
-
// existing union homes and fences below.
|
|
3975
|
+
// existing union homes and fences below. URL is the
|
|
3976
|
+
// exception: its handle boxes by reference and keeps every member,
|
|
3977
|
+
// so it collapses too (dynSubsumableUnionArm). A pending recursive
|
|
3547
3978
|
// placeholder cannot collapse (back-references already hold the
|
|
3548
3979
|
// union id); the degenerate recursive spelling keeps its fence.
|
|
3549
3980
|
if (arms.some((a) => a.kind === "dyn") &&
|
|
@@ -3556,7 +3987,7 @@ function mapTypeInner(type, ctx) {
|
|
|
3556
3987
|
a.kind === "date" ||
|
|
3557
3988
|
a.kind === "dyn" ||
|
|
3558
3989
|
a.kind === "generator") ||
|
|
3559
|
-
!
|
|
3990
|
+
!maybePromiseUnionOk(parts, arms, ctx)) {
|
|
3560
3991
|
return null;
|
|
3561
3992
|
}
|
|
3562
3993
|
arms.sort((a, b) => (typeKey(a) < typeKey(b) ? -1 : 1));
|
|
@@ -3582,11 +4013,226 @@ function mapTypeInner(type, ctx) {
|
|
|
3582
4013
|
}
|
|
3583
4014
|
return null;
|
|
3584
4015
|
}
|
|
3585
|
-
/**
|
|
3586
|
-
*
|
|
3587
|
-
*
|
|
3588
|
-
|
|
3589
|
-
|
|
4016
|
+
/** One non-overloaded call signature's func type (mapTypeInner's
|
|
4017
|
+
* single-signature rule; erasedOverloadMemberType maps each overload of a
|
|
4018
|
+
* member through it). */
|
|
4019
|
+
function mapCallSignature(sig, ctx) {
|
|
4020
|
+
const { checker } = ctx;
|
|
4021
|
+
if (sig.getTypeParameters().length && ctx.erasingSignature !== sig)
|
|
4022
|
+
return null;
|
|
4023
|
+
// A SYNTHESIZED rest param (tsc's JS inference for a function body
|
|
4024
|
+
// reading `arguments` — `(...args: any[]) => any` whose args symbol
|
|
4025
|
+
// has no declaration): the dotDotDot check below can't see it, and a
|
|
4026
|
+
// fixed-arity func mapping would LIE about the value's calling
|
|
4027
|
+
// convention. Detected by the param-count mismatch against the
|
|
4028
|
+
// signature's own declaration, excluding an erased `this` parameter.
|
|
4029
|
+
{
|
|
4030
|
+
const sigDecl = sig.declaration;
|
|
4031
|
+
const declParams = sigDecl !== undefined && ts.isFunctionLike(sigDecl) ? sigDecl.parameters.nodes : undefined;
|
|
4032
|
+
if (declParams !== undefined &&
|
|
4033
|
+
runtimeParameterCount(declParams) !== sig.getParameters().length) {
|
|
4034
|
+
return null;
|
|
4035
|
+
}
|
|
4036
|
+
// tsgo never SYNTHESIZES that rest param into the inferred signature
|
|
4037
|
+
// (5.9.3 did — the count mismatch above was the whole detector
|
|
4038
|
+
// there), so the declaration's own body answers directly.
|
|
4039
|
+
if (sigDecl !== undefined && ts.isFunctionLike(sigDecl) && bodyReadsArguments(sigDecl)) {
|
|
4040
|
+
return null;
|
|
4041
|
+
}
|
|
4042
|
+
}
|
|
4043
|
+
const params = [];
|
|
4044
|
+
let typedRest = false;
|
|
4045
|
+
let dynRest = false;
|
|
4046
|
+
for (const p of sig.getParameters()) {
|
|
4047
|
+
const decl = p.valueDeclaration;
|
|
4048
|
+
const rest = decl !== undefined && ts.isParameter(decl) && decl.dotDotDotToken !== undefined;
|
|
4049
|
+
// arity ABI selected by lambdaSignature. Treating an inferred any[]
|
|
4050
|
+
// declaration as a typed packed-array closure would bypass its boxed
|
|
4051
|
+
// spread/error semantics and change coverage classification.
|
|
4052
|
+
if (rest && decl !== undefined && isJsSourceFile(ts.getSourceFileOfNode(decl)))
|
|
4053
|
+
return null;
|
|
4054
|
+
// A fixed-tuple rest (`...args: [A, B]`, `...args: Parameters<F>` over
|
|
4055
|
+
// a bound F) flattens to its positional parameters. Pattern rests keep
|
|
4056
|
+
// their packed-record ABI and stay unmapped as values.
|
|
4057
|
+
if (rest && decl !== undefined && ts.isParameter(decl) && ts.isIdentifier(decl.name)) {
|
|
4058
|
+
const elems = restTupleParamTypes(checker.getTypeOfSymbol(p), ctx);
|
|
4059
|
+
if (elems) {
|
|
4060
|
+
params.push(...elems);
|
|
4061
|
+
continue;
|
|
4062
|
+
}
|
|
4063
|
+
}
|
|
4064
|
+
const optional = decl !== undefined &&
|
|
4065
|
+
ts.isParameter(decl) &&
|
|
4066
|
+
(decl.questionToken !== undefined || decl.initializer !== undefined);
|
|
4067
|
+
let pt = mapType(checker.getTypeOfSymbol(p), ctx);
|
|
4068
|
+
// A parameter a TypeScript program types `any` takes whatever the
|
|
4069
|
+
// caller passes: the checked-dynamic slot, as an `any`-typed binding
|
|
4070
|
+
// already is (dynFallbackType). Declaration files keep their paths.
|
|
4071
|
+
// Only function declarations, spelled function types and lambda
|
|
4072
|
+
// parameters whose default is the only source of their type (`(n =
|
|
4073
|
+
// lookup() ?? 5) => ...` with an `any` lookup): other lambdas and
|
|
4074
|
+
// methods in object literals keep their existing checked-dynamic story.
|
|
4075
|
+
if (!pt &&
|
|
4076
|
+
!rest &&
|
|
4077
|
+
decl !== undefined &&
|
|
4078
|
+
ts.isParameter(decl) &&
|
|
4079
|
+
decl.parent !== undefined &&
|
|
4080
|
+
(ts.isFunctionDeclaration(decl.parent) ||
|
|
4081
|
+
ts.isFunctionTypeNode(decl.parent) ||
|
|
4082
|
+
((ts.isArrowFunction(decl.parent) || ts.isFunctionExpression(decl.parent)) &&
|
|
4083
|
+
decl.initializer !== undefined &&
|
|
4084
|
+
decl.type === undefined &&
|
|
4085
|
+
!isJsSourceFile(ts.getSourceFileOfNode(decl)))) &&
|
|
4086
|
+
!ts.getSourceFileOfNode(decl).isDeclarationFile &&
|
|
4087
|
+
(checker.getTypeOfSymbol(p).flags & ts.TypeFlags.Any) !== 0)
|
|
4088
|
+
pt = DYN;
|
|
4089
|
+
if (decl &&
|
|
4090
|
+
ts.isParameter(decl) &&
|
|
4091
|
+
ts.isSetAccessorDeclaration(decl.parent) &&
|
|
4092
|
+
isJsSourceFile(ts.getSourceFileOfNode(decl)))
|
|
4093
|
+
pt = DYN;
|
|
4094
|
+
// An inferred JavaScript binding pattern consumes an iterable; it
|
|
4095
|
+
// does not require the caller's array to have exactly this length.
|
|
4096
|
+
const executor = decl && ts.isParameter(decl) ? decl.parent : null;
|
|
4097
|
+
const construction = executor?.parent;
|
|
4098
|
+
const constructorSymbol = construction && ts.isNewExpression(construction)
|
|
4099
|
+
? checker.getSymbolAtLocation(construction.expression)
|
|
4100
|
+
: undefined;
|
|
4101
|
+
const nativeExecutor = executor &&
|
|
4102
|
+
(ts.isArrowFunction(executor) || ts.isFunctionExpression(executor)) &&
|
|
4103
|
+
construction &&
|
|
4104
|
+
ts.isNewExpression(construction) &&
|
|
4105
|
+
construction.arguments?.nodes[0] === executor &&
|
|
4106
|
+
ts.isIdentifier(construction.expression) &&
|
|
4107
|
+
construction.expression.text === "Promise" &&
|
|
4108
|
+
constructorSymbol &&
|
|
4109
|
+
constructorSymbol.declarations.some((site) => ctx.isStdlibFile(ts.getSourceFileOfNode(site)));
|
|
4110
|
+
if (!nativeExecutor &&
|
|
4111
|
+
decl &&
|
|
4112
|
+
ts.isParameter(decl) &&
|
|
4113
|
+
!decl.dotDotDotToken &&
|
|
4114
|
+
!ts.isSetAccessorDeclaration(decl.parent) &&
|
|
4115
|
+
isJsSourceFile(ts.getSourceFileOfNode(decl)) &&
|
|
4116
|
+
!decl.type &&
|
|
4117
|
+
!/@(?:param|type)\b/.test(ts
|
|
4118
|
+
.getSourceFileOfNode(decl)
|
|
4119
|
+
.text.slice(decl.parent?.pos ?? decl.pos, ts.tokenStartOfNode(decl))))
|
|
4120
|
+
pt = DYN;
|
|
4121
|
+
// A DEFAULTED program-source parameter of a function, arrow or function
|
|
4122
|
+
// expression that the checker types `any` — a default under an
|
|
4123
|
+
// `(...args: any[]) => any` wrapper slot (`wrap((limit = 5) => ...)`),
|
|
4124
|
+
// where the contextual `any` wins over the default's type: its binding
|
|
4125
|
+
// is already the checked-dynamic kind inside the body
|
|
4126
|
+
// (dynFallbackType), so the callable's ABI slot is the same dyn value.
|
|
4127
|
+
// Other `any` parameters keep their existing paths (an object literal
|
|
4128
|
+
// holding such a callback stays a checked-dynamic object).
|
|
4129
|
+
if (pt === null &&
|
|
4130
|
+
!rest &&
|
|
4131
|
+
decl !== undefined &&
|
|
4132
|
+
ts.isParameter(decl) &&
|
|
4133
|
+
decl.initializer !== undefined &&
|
|
4134
|
+
(ts.isArrowFunction(decl.parent) ||
|
|
4135
|
+
ts.isFunctionExpression(decl.parent) ||
|
|
4136
|
+
ts.isFunctionDeclaration(decl.parent)) &&
|
|
4137
|
+
!ts.getSourceFileOfNode(decl).isDeclarationFile &&
|
|
4138
|
+
(checker.getTypeOfSymbol(p).flags & ts.TypeFlags.Any) !== 0)
|
|
4139
|
+
pt = DYN;
|
|
4140
|
+
if (pt)
|
|
4141
|
+
pt = jsOpenObjectType(decl, pt, ctx.shapes, ctx.unions);
|
|
4142
|
+
// Belt and braces for non-strict type worlds: an optional param's
|
|
4143
|
+
// ABI slot is always the undefined-armed union (strictNullChecks
|
|
4144
|
+
// already spells it that way; arm it here if the world didn't).
|
|
4145
|
+
if (optional && pt && pt.kind !== "void" && pt.kind !== "dyn") {
|
|
4146
|
+
const armed = withUndefinedArm(pt, ctx.unions);
|
|
4147
|
+
if (!armed)
|
|
4148
|
+
return null;
|
|
4149
|
+
pt = armed;
|
|
4150
|
+
}
|
|
4151
|
+
// `...args: unknown[]` / `...args: any[]` declared in program source:
|
|
4152
|
+
// the checked-dynamic variadic ABI (no typed slot; the callee's hidden
|
|
4153
|
+
// trailing dyn array receives every surplus argument, as for JS rest
|
|
4154
|
+
// params). Declaration files keep their existing paths: library
|
|
4155
|
+
// callback slots such as String#replace's `(substring, ...args: any[])`
|
|
4156
|
+
// have intrinsic lowerings that inspect the unmapped type.
|
|
4157
|
+
// node:test's default mock function type, `(...args: any[]) =>
|
|
4158
|
+
// undefined` (the type parameter default of mock.fn), takes the same
|
|
4159
|
+
// ABI: mock.fn() without an original records whatever its callers pass.
|
|
4160
|
+
if (rest &&
|
|
4161
|
+
decl !== undefined &&
|
|
4162
|
+
(!ts.getSourceFileOfNode(decl).isDeclarationFile ||
|
|
4163
|
+
isNodeTestDefaultFunctionParam(decl, ctx)) &&
|
|
4164
|
+
(pt?.kind === "dyn" || (!pt && isAnyArrayType(checker.getTypeOfSymbol(p), checker)))) {
|
|
4165
|
+
dynRest = true;
|
|
4166
|
+
continue;
|
|
4167
|
+
}
|
|
4168
|
+
if (!pt)
|
|
4169
|
+
return null;
|
|
4170
|
+
if (rest) {
|
|
4171
|
+
if (pt.kind !== "array")
|
|
4172
|
+
return null;
|
|
4173
|
+
typedRest = true;
|
|
4174
|
+
}
|
|
4175
|
+
// `(value: void) => void` (Promise<void>'s resolve) is callable with
|
|
4176
|
+
// no arguments — a void param is dropped, not a mapping failure.
|
|
4177
|
+
if (pt.kind === "void")
|
|
4178
|
+
continue;
|
|
4179
|
+
params.push(pt);
|
|
4180
|
+
}
|
|
4181
|
+
const retT = checker.getReturnTypeOfSignature(sig);
|
|
4182
|
+
// `() => never` (a throw-only lambda's inferred type) is assignable to
|
|
4183
|
+
// `() => void` and its calls never produce a value — map the return
|
|
4184
|
+
// like declaredReturnType does for declarations. JS null/undefined
|
|
4185
|
+
// returns can read mutable fields, so callable values use the same
|
|
4186
|
+
// checked-native return ABI as their implementations.
|
|
4187
|
+
const sigDecl = sig.declaration;
|
|
4188
|
+
const jsUnitReturn = sigDecl !== undefined &&
|
|
4189
|
+
isJsSourceFile(ts.getSourceFileOfNode(sigDecl)) &&
|
|
4190
|
+
(retT.flags & (ts.TypeFlags.Null | ts.TypeFlags.Undefined)) !== 0;
|
|
4191
|
+
let ret = jsUnitReturn || (retT.flags & ts.TypeFlags.Any) !== 0
|
|
4192
|
+
? DYN
|
|
4193
|
+
: retT.flags & ts.TypeFlags.Never
|
|
4194
|
+
? VOID
|
|
4195
|
+
: mapType(retT, ctx);
|
|
4196
|
+
if (sigDecl &&
|
|
4197
|
+
ts.isGetAccessorDeclaration(sigDecl) &&
|
|
4198
|
+
isJsSourceFile(ts.getSourceFileOfNode(sigDecl)))
|
|
4199
|
+
ret = DYN;
|
|
4200
|
+
if (sigDecl && isJsSourceFile(ts.getSourceFileOfNode(sigDecl)) && ret?.kind === "array")
|
|
4201
|
+
ret = DYN;
|
|
4202
|
+
if (sigDecl &&
|
|
4203
|
+
ts.isFunctionLike(sigDecl) &&
|
|
4204
|
+
isJsSourceFile(ts.getSourceFileOfNode(sigDecl)) &&
|
|
4205
|
+
!sigDecl.type &&
|
|
4206
|
+
!/@returns?\b/.test(ts.getSourceFileOfNode(sigDecl).text.slice(sigDecl.pos, ts.tokenStartOfNode(sigDecl))) &&
|
|
4207
|
+
ret?.kind === "record")
|
|
4208
|
+
ret = DYN;
|
|
4209
|
+
if (sigDecl &&
|
|
4210
|
+
ts.isFunctionLike(sigDecl) &&
|
|
4211
|
+
isJsSourceFile(ts.getSourceFileOfNode(sigDecl)) &&
|
|
4212
|
+
!sigDecl.type &&
|
|
4213
|
+
!/@returns?\b/.test(ts.getSourceFileOfNode(sigDecl).text.slice(sigDecl.pos, ts.tokenStartOfNode(sigDecl))) &&
|
|
4214
|
+
(ret?.kind === "date" ||
|
|
4215
|
+
(ret?.kind === "union" &&
|
|
4216
|
+
ctx.unions.get(ret.unionId)?.arms.some((arm) => arm.kind === "func"))))
|
|
4217
|
+
ret = DYN;
|
|
4218
|
+
if (ret &&
|
|
4219
|
+
sigDecl &&
|
|
4220
|
+
isJsSourceFile(ts.getSourceFileOfNode(sigDecl)) &&
|
|
4221
|
+
functionCanReturnUndefined(sigDecl))
|
|
4222
|
+
ret = withUndefinedArm(ret, ctx.unions) ?? ret;
|
|
4223
|
+
if (!ret)
|
|
4224
|
+
return null;
|
|
4225
|
+
return typedRest
|
|
4226
|
+
? { kind: "func", params, ret, rest: true, restAbi: "typed" }
|
|
4227
|
+
: dynRest
|
|
4228
|
+
? { kind: "func", params, ret, rest: true }
|
|
4229
|
+
: funcOf(params, ret);
|
|
4230
|
+
}
|
|
4231
|
+
/** Retain a literal discriminator before widening erases its values. A
|
|
4232
|
+
* structural match alone is insufficient: `{ kind: "loop", body: ... }`
|
|
4233
|
+
* also fits a smaller `{ kind: "empty" }` record. Choosing that layout
|
|
4234
|
+
* makes a later switch on kind read fields outside the allocated object.
|
|
4235
|
+
*
|
|
3590
4236
|
* Require one common, required data property with finite literal values.
|
|
3591
4237
|
* Values may repeat within a single storage arm (several variants share a
|
|
3592
4238
|
* shape), but never select different arms. Non-record arms keep their
|
|
@@ -3596,14 +4242,18 @@ function unionDiscriminant(parts, arms, ctx) {
|
|
|
3596
4242
|
if (arms.filter((arm) => arm.kind === "record").length < 2 || parts.length < 2)
|
|
3597
4243
|
return undefined;
|
|
3598
4244
|
const { checker } = ctx;
|
|
4245
|
+
// Tuple shapes keep positions only: their checker `length` literal has
|
|
4246
|
+
// no slot to compare (discriminantField refuses tuple shapes too).
|
|
4247
|
+
if (parts.some((part) => ctx.shapes.get(part.mapped.shapeId)?.tuple))
|
|
4248
|
+
return undefined;
|
|
3599
4249
|
for (const candidate of checker.getPropertiesOfType(parts[0].source)) {
|
|
3600
|
-
if (candidate.
|
|
4250
|
+
if (ts.symbolName(candidate).startsWith("__@"))
|
|
3601
4251
|
continue;
|
|
3602
4252
|
const byTag = new Map();
|
|
3603
4253
|
const owner = new Map();
|
|
3604
4254
|
let complete = true;
|
|
3605
4255
|
for (const part of parts) {
|
|
3606
|
-
const prop = checker.getPropertyOfType(part.source, candidate
|
|
4256
|
+
const prop = checker.getPropertyOfType(part.source, ts.symbolName(candidate));
|
|
3607
4257
|
if (!prop ||
|
|
3608
4258
|
prop.flags &
|
|
3609
4259
|
(ts.SymbolFlags.Optional | ts.SymbolFlags.GetAccessor | ts.SymbolFlags.SetAccessor)) {
|
|
@@ -3634,7 +4284,7 @@ function unionDiscriminant(parts, arms, ctx) {
|
|
|
3634
4284
|
}
|
|
3635
4285
|
if (complete) {
|
|
3636
4286
|
return {
|
|
3637
|
-
field: candidate
|
|
4287
|
+
field: ts.symbolName(candidate),
|
|
3638
4288
|
cases: [...byTag]
|
|
3639
4289
|
.sort(([a], [b]) => a - b)
|
|
3640
4290
|
.map(([tag, values]) => ({
|
|
@@ -3667,9 +4317,9 @@ function mapClassView(type, ctx, seen = new Set()) {
|
|
|
3667
4317
|
}
|
|
3668
4318
|
else {
|
|
3669
4319
|
const symbol = type.getSymbol();
|
|
3670
|
-
const declarations = symbol ?
|
|
4320
|
+
const declarations = symbol ? symbol.declarations : [];
|
|
3671
4321
|
if (declarations.length === 0 ||
|
|
3672
|
-
!declarations.every((decl) => ts.isInterfaceDeclaration(decl) && !ctx.isStdlibFile(
|
|
4322
|
+
!declarations.every((decl) => ts.isInterfaceDeclaration(decl) && !ctx.isStdlibFile(ts.getSourceFileOfNode(decl))))
|
|
3673
4323
|
return undefined;
|
|
3674
4324
|
const target = type.isTypeReference() ? type.getTarget() : type;
|
|
3675
4325
|
if (target === undefined || !target.isClassOrInterface())
|
|
@@ -3702,10 +4352,10 @@ function mapClassView(type, ctx, seen = new Set()) {
|
|
|
3702
4352
|
let representation;
|
|
3703
4353
|
for (const base of bases) {
|
|
3704
4354
|
const symbol = base.getSymbol();
|
|
3705
|
-
const declaration = symbol ?
|
|
4355
|
+
const declaration = symbol ? symbol.valueDeclaration : undefined;
|
|
3706
4356
|
const classBase = declaration &&
|
|
3707
4357
|
(ts.isClassDeclaration(declaration) || ts.isClassExpression(declaration)) &&
|
|
3708
|
-
!
|
|
4358
|
+
!ts.getSourceFileOfNode(declaration).isDeclarationFile;
|
|
3709
4359
|
const mapped = classBase ? mapType(base, viewCtx) : mapClassView(base, viewCtx, seen);
|
|
3710
4360
|
if (mapped === null)
|
|
3711
4361
|
return null;
|
|
@@ -3723,13 +4373,13 @@ function mapClassView(type, ctx, seen = new Set()) {
|
|
|
3723
4373
|
checker.getIndexInfosOfType(type).length)
|
|
3724
4374
|
return null;
|
|
3725
4375
|
for (const property of checker.getPropertiesOfType(type)) {
|
|
3726
|
-
const original = checker.getPropertyOfType(baseType, property
|
|
4376
|
+
const original = checker.getPropertyOfType(baseType, ts.symbolName(property));
|
|
3727
4377
|
if (!original)
|
|
3728
4378
|
return null;
|
|
3729
4379
|
if (original === property)
|
|
3730
4380
|
continue;
|
|
3731
|
-
const originalDeclarations =
|
|
3732
|
-
const declarations =
|
|
4381
|
+
const originalDeclarations = original.declarations;
|
|
4382
|
+
const declarations = property.declarations;
|
|
3733
4383
|
// Instantiating an inherited member can create a new symbol without
|
|
3734
4384
|
// changing its declaration or ABI. Only refinements need validation.
|
|
3735
4385
|
if (declarations.length > 0 &&
|
|
@@ -3764,9 +4414,9 @@ function mapCollectionView(type, ctx, seen = new Set()) {
|
|
|
3764
4414
|
return null;
|
|
3765
4415
|
const { checker } = ctx;
|
|
3766
4416
|
const symbol = type.getSymbol();
|
|
3767
|
-
const declarations = symbol ?
|
|
4417
|
+
const declarations = symbol ? symbol.declarations : [];
|
|
3768
4418
|
if (declarations.length === 0 ||
|
|
3769
|
-
!declarations.every((decl) => ts.isInterfaceDeclaration(decl) && !ctx.isStdlibFile(
|
|
4419
|
+
!declarations.every((decl) => ts.isInterfaceDeclaration(decl) && !ctx.isStdlibFile(ts.getSourceFileOfNode(decl))))
|
|
3770
4420
|
return null;
|
|
3771
4421
|
const target = type.getTarget();
|
|
3772
4422
|
if (target === undefined ||
|
|
@@ -3807,21 +4457,17 @@ function mapCollectionView(type, ctx, seen = new Set()) {
|
|
|
3807
4457
|
const base = bases[0];
|
|
3808
4458
|
const baseSymbol = base.getSymbol();
|
|
3809
4459
|
const native = baseSymbol &&
|
|
3810
|
-
["Map", "ReadonlyMap", "Set", "ReadonlySet"].includes(baseSymbol
|
|
3811
|
-
|
|
3812
|
-
.declarationsOf(baseSymbol)
|
|
3813
|
-
.some((decl) => ts.isInterfaceDeclaration(decl) && ctx.isStdlibFile(decl.getSourceFile()));
|
|
4460
|
+
["Map", "ReadonlyMap", "Set", "ReadonlySet"].includes(ts.symbolName(baseSymbol)) &&
|
|
4461
|
+
baseSymbol.declarations.some((decl) => ts.isInterfaceDeclaration(decl) && ctx.isStdlibFile(ts.getSourceFileOfNode(decl)));
|
|
3814
4462
|
const mapped = native ? mapType(base, baseCtx) : mapCollectionView(base, baseCtx, seen);
|
|
3815
4463
|
if (mapped?.kind !== "map" && mapped?.kind !== "set")
|
|
3816
4464
|
return null;
|
|
3817
4465
|
const hasType = funcOf([mapped.kind === "map" ? mapped.key : mapped.elem], BOOL);
|
|
3818
4466
|
for (const property of checker.getPropertiesOfType(type)) {
|
|
3819
|
-
const own =
|
|
3820
|
-
.declarationsOf(property)
|
|
3821
|
-
.filter((decl) => !ctx.isStdlibFile(decl.getSourceFile()));
|
|
4467
|
+
const own = property.declarations.filter((decl) => !ctx.isStdlibFile(ts.getSourceFileOfNode(decl)));
|
|
3822
4468
|
if (own.length === 0)
|
|
3823
4469
|
continue;
|
|
3824
|
-
if (property
|
|
4470
|
+
if (ts.symbolName(property) !== "has" ||
|
|
3825
4471
|
property.flags & ts.SymbolFlags.Optional ||
|
|
3826
4472
|
!own.every((decl) => decl.kind === ts.SyntaxKind.MethodSignature))
|
|
3827
4473
|
return null;
|
|
@@ -3931,6 +4577,166 @@ function mapBoundIndexedAccess(type, ctx) {
|
|
|
3931
4577
|
return null;
|
|
3932
4578
|
return mapType(checker.getTypeOfSymbol(prop), ctx);
|
|
3933
4579
|
}
|
|
4580
|
+
/** The standard library's `Parameters<F>` / `ReturnType<F>` over a type
|
|
4581
|
+
* parameter the current instantiation binds to a callable checker type:
|
|
4582
|
+
* that type's one call signature. Concrete arguments never reach here (the
|
|
4583
|
+
* checker evaluates those conditionals itself); generic bodies keep them
|
|
4584
|
+
* symbolic because their `infer` sits in a call signature. */
|
|
4585
|
+
function boundSignatureAlias(type, ctx) {
|
|
4586
|
+
const { checker, resolveTypeParamTs } = ctx;
|
|
4587
|
+
if (!resolveTypeParamTs)
|
|
4588
|
+
return null;
|
|
4589
|
+
const alias = type.getAliasSymbol();
|
|
4590
|
+
const aliasName = alias === undefined ? undefined : ts.symbolName(alias);
|
|
4591
|
+
if (!alias || (aliasName !== "Parameters" && aliasName !== "ReturnType"))
|
|
4592
|
+
return null;
|
|
4593
|
+
const aliasArgs = type.getAliasTypeArguments();
|
|
4594
|
+
const arg = aliasArgs[0];
|
|
4595
|
+
if (aliasArgs.length !== 1 || !arg || !(arg.flags & ts.TypeFlags.TypeParameter))
|
|
4596
|
+
return null;
|
|
4597
|
+
const isLibAlias = alias.declarations.some((d) => ts.isTypeAliasDeclaration(d) && ctx.isStdlibFile(ts.getSourceFileOfNode(d)));
|
|
4598
|
+
if (!isLibAlias)
|
|
4599
|
+
return null;
|
|
4600
|
+
const bound = resolveTypeParamTs(arg);
|
|
4601
|
+
if (!bound || bound.flags & ts.TypeFlags.TypeParameter)
|
|
4602
|
+
return null;
|
|
4603
|
+
const sigs = checker.getCallSignatures(bound);
|
|
4604
|
+
const sig = sigs[0];
|
|
4605
|
+
if (sigs.length !== 1 || !sig || sig.getTypeParameters().length > 0)
|
|
4606
|
+
return null;
|
|
4607
|
+
return { name: aliasName, sig };
|
|
4608
|
+
}
|
|
4609
|
+
/** The positional parameters of a signature as a fixed tuple: a trailing
|
|
4610
|
+
* rest flattened when its own type is a fixed tuple. Null for a variadic
|
|
4611
|
+
* position, which has no fixed native arity. */
|
|
4612
|
+
function signatureParameters(sig, ctx) {
|
|
4613
|
+
const { checker } = ctx;
|
|
4614
|
+
const out = [];
|
|
4615
|
+
for (const p of sig.getParameters()) {
|
|
4616
|
+
const decl = p.valueDeclaration;
|
|
4617
|
+
const type = checker.getTypeOfSymbol(p);
|
|
4618
|
+
if (decl !== undefined && ts.isParameter(decl)) {
|
|
4619
|
+
if (decl.dotDotDotToken !== undefined) {
|
|
4620
|
+
const inner = restTupleElements(type, ctx);
|
|
4621
|
+
if (!inner)
|
|
4622
|
+
return null;
|
|
4623
|
+
out.push(...inner);
|
|
4624
|
+
continue;
|
|
4625
|
+
}
|
|
4626
|
+
out.push({
|
|
4627
|
+
type,
|
|
4628
|
+
optional: decl.questionToken !== undefined || decl.initializer !== undefined,
|
|
4629
|
+
});
|
|
4630
|
+
continue;
|
|
4631
|
+
}
|
|
4632
|
+
out.push({ type, optional: (p.flags & ts.SymbolFlags.Optional) !== 0 });
|
|
4633
|
+
}
|
|
4634
|
+
return out;
|
|
4635
|
+
}
|
|
4636
|
+
/** The required-only positional parameter types of a signature (the
|
|
4637
|
+
* value-level `Parameters<F>` tuple), null when a position is optional
|
|
4638
|
+
* or variadic: such a tuple's length varies per call. */
|
|
4639
|
+
function signatureParameterTypes(sig, ctx) {
|
|
4640
|
+
const elems = signatureParameters(sig, ctx);
|
|
4641
|
+
if (!elems || elems.some((e) => e.optional))
|
|
4642
|
+
return null;
|
|
4643
|
+
return elems.map((e) => e.type);
|
|
4644
|
+
}
|
|
4645
|
+
/** The element types of a REST parameter's type when it is a fixed tuple:
|
|
4646
|
+
* a tuple of required elements (`[number, string]`, the empty `[]`), a type
|
|
4647
|
+
* parameter bound to one, or `Parameters<F>` over a bound function type.
|
|
4648
|
+
* Such a rest parameter has a compile-time arity, so its native ABI is the
|
|
4649
|
+
* flattened positional list (exactly the equivalent fixed signature —
|
|
4650
|
+
* TypeScript treats `(...a: [A, B]) => R` and `(a: A, b: B) => R` alike). */
|
|
4651
|
+
export function restTupleElementTypes(type, ctx) {
|
|
4652
|
+
return restTupleElements(type, ctx)?.map((e) => e.type) ?? null;
|
|
4653
|
+
}
|
|
4654
|
+
/** restTupleElementTypes with each position's optionality: a rest tuple
|
|
4655
|
+
* may end in optional positions (`[A, B?]`, `Parameters<(a: A, b?: B) =>
|
|
4656
|
+
* R>`), which flatten to `T | undefined` slots exactly as the function
|
|
4657
|
+
* type's optional parameters do. */
|
|
4658
|
+
function restTupleElements(type, ctx) {
|
|
4659
|
+
const { checker } = ctx;
|
|
4660
|
+
if (type.flags & ts.TypeFlags.TypeParameter) {
|
|
4661
|
+
const bound = ctx.resolveTypeParamTs?.(type);
|
|
4662
|
+
return bound && bound !== type ? restTupleElements(bound, ctx) : null;
|
|
4663
|
+
}
|
|
4664
|
+
const viaAlias = boundSignatureAlias(type, ctx);
|
|
4665
|
+
if (viaAlias) {
|
|
4666
|
+
return viaAlias.name === "Parameters" ? signatureParameters(viaAlias.sig, ctx) : null;
|
|
4667
|
+
}
|
|
4668
|
+
if (!checker.isTupleType(type))
|
|
4669
|
+
return null;
|
|
4670
|
+
const ref = type;
|
|
4671
|
+
const tupleShape = ref.elementFlags !== undefined
|
|
4672
|
+
? ref
|
|
4673
|
+
: ref.getTarget();
|
|
4674
|
+
const args = checker.getTypeArguments(ref);
|
|
4675
|
+
if (args.length === 0)
|
|
4676
|
+
return [];
|
|
4677
|
+
const flags = tupleShape?.elementFlags;
|
|
4678
|
+
if (flags === undefined)
|
|
4679
|
+
return null;
|
|
4680
|
+
if (flags.some((f) => !(f & (ts.ElementFlags.Required | ts.ElementFlags.Optional))))
|
|
4681
|
+
return null;
|
|
4682
|
+
return args.map((t, i) => ({
|
|
4683
|
+
type: t,
|
|
4684
|
+
optional: (flags[i] & ts.ElementFlags.Optional) !== 0,
|
|
4685
|
+
}));
|
|
4686
|
+
}
|
|
4687
|
+
/** One tuple element's IR type under the tuple mapping's rules. */
|
|
4688
|
+
function mapTupleElement(t, ctx) {
|
|
4689
|
+
let et = (t.flags & ts.TypeFlags.Any) !== 0 ? DYN : mapType(t, ctx);
|
|
4690
|
+
if (et?.kind === "void" && isUnitOnlyTsType(t, ctx.resolveTypeParam))
|
|
4691
|
+
et = unitOnlyUnion(ctx.unions);
|
|
4692
|
+
return !et || et.kind === "void" ? null : et;
|
|
4693
|
+
}
|
|
4694
|
+
/** The mapped element types of a fixed-tuple rest parameter type
|
|
4695
|
+
* (restTupleElementTypes), null when it is not one or an element does not
|
|
4696
|
+
* map. */
|
|
4697
|
+
export function restTupleParamTypes(type, ctx) {
|
|
4698
|
+
const elems = restTupleElements(type, ctx);
|
|
4699
|
+
if (!elems)
|
|
4700
|
+
return null;
|
|
4701
|
+
const out = [];
|
|
4702
|
+
for (const e of elems) {
|
|
4703
|
+
let et = mapTupleElement(e.type, ctx);
|
|
4704
|
+
// An optional position's slot holds undefined when the caller omits
|
|
4705
|
+
// it, as an optional parameter's does (mapCallSignature).
|
|
4706
|
+
if (et && e.optional && et.kind !== "dyn")
|
|
4707
|
+
et = withUndefinedArm(et, ctx.unions);
|
|
4708
|
+
if (!et)
|
|
4709
|
+
return null;
|
|
4710
|
+
out.push(et);
|
|
4711
|
+
}
|
|
4712
|
+
return out;
|
|
4713
|
+
}
|
|
4714
|
+
/** `Parameters<F>` (the fixed tuple of F's parameters, interned exactly as
|
|
4715
|
+
* the spelled tuple maps) and `ReturnType<F>` (F's mapped result) over a
|
|
4716
|
+
* bound function-typed type parameter. */
|
|
4717
|
+
function mapBoundSignatureAlias(type, ctx) {
|
|
4718
|
+
const target = boundSignatureAlias(type, ctx);
|
|
4719
|
+
if (!target)
|
|
4720
|
+
return null;
|
|
4721
|
+
if (target.name === "ReturnType") {
|
|
4722
|
+
const ret = ctx.checker.getReturnTypeOfSignature(target.sig);
|
|
4723
|
+
return ret.flags & ts.TypeFlags.Any ? DYN : mapType(ret, ctx);
|
|
4724
|
+
}
|
|
4725
|
+
const elems = signatureParameterTypes(target.sig, ctx);
|
|
4726
|
+
if (!elems)
|
|
4727
|
+
return null;
|
|
4728
|
+
if (elems.length === 0)
|
|
4729
|
+
return arrayOf(unitOnlyUnion(ctx.unions));
|
|
4730
|
+
const fields = [];
|
|
4731
|
+
for (let i = 0; i < elems.length; i++) {
|
|
4732
|
+
const et = mapTupleElement(elems[i], ctx);
|
|
4733
|
+
if (!et)
|
|
4734
|
+
return null;
|
|
4735
|
+
fields.push({ name: String(i), type: et });
|
|
4736
|
+
}
|
|
4737
|
+
fields.sort((a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0));
|
|
4738
|
+
return { kind: "record", shapeId: ctx.shapes.intern(fields, true) };
|
|
4739
|
+
}
|
|
3934
4740
|
/** `Partial<T>` / `Readonly<T>` where T is a STILL-GENERIC type parameter —
|
|
3935
4741
|
* the one mapped-type spelling a monomorphized body can contain that the
|
|
3936
4742
|
* checker cannot resolve for us (`keyof T` is unknown inside the body, so
|
|
@@ -3970,16 +4776,16 @@ export function underConstAssertion(n) {
|
|
|
3970
4776
|
* panic repair): a property symbol declared by a property assignment whose
|
|
3971
4777
|
* initializer is an EMPTY array literal inside a const assertion — its
|
|
3972
4778
|
* type is provably `readonly []`, whatever the panicked query answered. */
|
|
3973
|
-
function constAssertedEmptyArrayProp(p
|
|
3974
|
-
const d =
|
|
4779
|
+
function constAssertedEmptyArrayProp(p) {
|
|
4780
|
+
const d = p.valueDeclaration;
|
|
3975
4781
|
if (d === undefined || !ts.isPropertyAssignment(d))
|
|
3976
4782
|
return false;
|
|
3977
4783
|
const init = d.initializer;
|
|
3978
4784
|
// `a: [] as const` pins the field type by itself, wherever the literal sits.
|
|
3979
4785
|
if (ts.isAsExpression(init) && isConstAssertionTypeNode(init.type)) {
|
|
3980
|
-
return ts.isArrayLiteralExpression(init.expression) && init.expression.elements.length === 0;
|
|
4786
|
+
return (ts.isArrayLiteralExpression(init.expression) && init.expression.elements.nodes.length === 0);
|
|
3981
4787
|
}
|
|
3982
|
-
if (!ts.isArrayLiteralExpression(init) || init.elements.length > 0)
|
|
4788
|
+
if (!ts.isArrayLiteralExpression(init) || init.elements.nodes.length > 0)
|
|
3983
4789
|
return false;
|
|
3984
4790
|
return underConstAssertion(d);
|
|
3985
4791
|
}
|
|
@@ -3988,21 +4794,22 @@ function mapGenericAwaitedAlias(type, ctx) {
|
|
|
3988
4794
|
if (!resolveTypeParam)
|
|
3989
4795
|
return null;
|
|
3990
4796
|
const alias = type.getAliasSymbol();
|
|
3991
|
-
if (!alias || alias
|
|
4797
|
+
if (!alias || ts.symbolName(alias) !== "Awaited")
|
|
3992
4798
|
return null;
|
|
3993
4799
|
const aliasArgs = type.getAliasTypeArguments();
|
|
3994
4800
|
const arg = aliasArgs[0];
|
|
3995
4801
|
if (aliasArgs.length !== 1 || !arg)
|
|
3996
4802
|
return null;
|
|
3997
|
-
|
|
4803
|
+
// `Awaited<ReturnType<F>>` (an async wrapper's settled result) resolves
|
|
4804
|
+
// through F's bound signature like a bare type parameter.
|
|
4805
|
+
const viaSignature = arg.flags & ts.TypeFlags.TypeParameter ? null : boundSignatureAlias(arg, ctx);
|
|
4806
|
+
if (!(arg.flags & ts.TypeFlags.TypeParameter) && viaSignature?.name !== "ReturnType")
|
|
3998
4807
|
return null;
|
|
3999
4808
|
// Provenance: the STANDARD LIBRARY's alias, not a user's shadowing one.
|
|
4000
|
-
const isLibAlias = ctx.
|
|
4001
|
-
.declarationsOf(alias)
|
|
4002
|
-
.some((d) => ts.isTypeAliasDeclaration(d) && ctx.isStdlibFile(d.getSourceFile()));
|
|
4809
|
+
const isLibAlias = alias.declarations.some((d) => ts.isTypeAliasDeclaration(d) && ctx.isStdlibFile(ts.getSourceFileOfNode(d)));
|
|
4003
4810
|
if (!isLibAlias)
|
|
4004
4811
|
return null;
|
|
4005
|
-
const bound = resolveTypeParam(arg);
|
|
4812
|
+
const bound = viaSignature ? mapBoundSignatureAlias(arg, ctx) : resolveTypeParam(arg);
|
|
4006
4813
|
if (!bound)
|
|
4007
4814
|
return null;
|
|
4008
4815
|
let r = bound;
|
|
@@ -4031,14 +4838,19 @@ function mapGenericIndexedAccess(type, ctx) {
|
|
|
4031
4838
|
if (obj === undefined || !(obj.flags & ts.TypeFlags.TypeParameter))
|
|
4032
4839
|
return null;
|
|
4033
4840
|
const bound = resolveTypeParam(obj);
|
|
4841
|
+
const idx = type.getIndexType();
|
|
4842
|
+
if (idx === undefined)
|
|
4843
|
+
return null;
|
|
4844
|
+
// `T[keyof T]` over a T bound to an unknown-valued record view
|
|
4845
|
+
// (`Record<string, unknown>` maps to the checked-dynamic value, see
|
|
4846
|
+
// mapRecordType): every member reads as unknown.
|
|
4847
|
+
if (bound?.kind === "dyn" && idx.isIndexType() && idx.getTarget() === obj)
|
|
4848
|
+
return DYN;
|
|
4034
4849
|
if (!bound || bound.kind !== "record")
|
|
4035
4850
|
return null;
|
|
4036
4851
|
const shape = shapes.get(bound.shapeId);
|
|
4037
4852
|
if (!shape || shape.tuple)
|
|
4038
4853
|
return null;
|
|
4039
|
-
const idx = type.getIndexType();
|
|
4040
|
-
if (idx === undefined)
|
|
4041
|
-
return null;
|
|
4042
4854
|
let covered = null;
|
|
4043
4855
|
if (idx.isStringLiteralType()) {
|
|
4044
4856
|
const f = shape.fields.find((x) => x.name === idx.value);
|
|
@@ -4057,14 +4869,414 @@ function mapGenericIndexedAccess(type, ctx) {
|
|
|
4057
4869
|
if (!covered || covered.length === 0)
|
|
4058
4870
|
return null;
|
|
4059
4871
|
const first = covered[0];
|
|
4060
|
-
|
|
4872
|
+
if (covered.every((t) => typeEquals(t, first)))
|
|
4873
|
+
return first;
|
|
4874
|
+
// Only the `keyof T` index itself covers every field at once; a key
|
|
4875
|
+
// parameter bound to string keeps its literal-key resolution below.
|
|
4876
|
+
if (!(idx.isIndexType() && idx.getTarget() === obj))
|
|
4877
|
+
return null;
|
|
4878
|
+
// Fields of different scalar types (`Object.entries` over a bound record
|
|
4879
|
+
// reads `T[keyof T]`): any one of them, the union of their types.
|
|
4880
|
+
const arms = [];
|
|
4881
|
+
for (const t of covered) {
|
|
4882
|
+
const parts = t.kind === "union" ? (ctx.unions.get(t.unionId)?.arms ?? null) : [t];
|
|
4883
|
+
if (!parts)
|
|
4884
|
+
return null;
|
|
4885
|
+
for (const part of parts) {
|
|
4886
|
+
if (part.kind !== "f64" &&
|
|
4887
|
+
part.kind !== "string" &&
|
|
4888
|
+
part.kind !== "bool" &&
|
|
4889
|
+
part.kind !== "undefinedT" &&
|
|
4890
|
+
part.kind !== "nullT")
|
|
4891
|
+
return null;
|
|
4892
|
+
if (!arms.some((a) => typeEquals(a, part)))
|
|
4893
|
+
arms.push(part);
|
|
4894
|
+
}
|
|
4895
|
+
}
|
|
4896
|
+
if (arms.length === 1)
|
|
4897
|
+
return arms[0];
|
|
4898
|
+
arms.sort((a, b) => (typeKey(a) < typeKey(b) ? -1 : 1));
|
|
4899
|
+
return { kind: "union", unionId: ctx.unions.intern(arms) };
|
|
4900
|
+
}
|
|
4901
|
+
/** `keyof T extends never ? A : B` over a bound record T (the lib's
|
|
4902
|
+
* Object.entries element spelling): decided by whether the binding has any
|
|
4903
|
+
* key. */
|
|
4904
|
+
function mapBoundKeyofNeverConditional(type, ctx) {
|
|
4905
|
+
const { resolveTypeParam, shapes } = ctx;
|
|
4906
|
+
if (!resolveTypeParam || !type.isConditionalType())
|
|
4907
|
+
return null;
|
|
4908
|
+
const check = type.getCheckType();
|
|
4909
|
+
const ext = type.getExtendsType();
|
|
4910
|
+
if (!check || !ext || !(ext.flags & ts.TypeFlags.Never) || !check.isIndexType())
|
|
4911
|
+
return null;
|
|
4912
|
+
const target = check.getTarget();
|
|
4913
|
+
if (!target || !(target.flags & ts.TypeFlags.TypeParameter))
|
|
4914
|
+
return null;
|
|
4915
|
+
const bound = resolveTypeParam(target);
|
|
4916
|
+
// A T bound to the checked-dynamic value (`Record<string, unknown>`, an
|
|
4917
|
+
// unknown-valued record view) has no static key set to decide the
|
|
4918
|
+
// branch, but both branches of the lib's `keyof T extends never ?
|
|
4919
|
+
// unknown : T[keyof T]` read as unknown there: one answer either way.
|
|
4920
|
+
if (bound?.kind === "dyn") {
|
|
4921
|
+
const whenEmpty = type.getTrueType();
|
|
4922
|
+
const otherwise = type.getFalseType();
|
|
4923
|
+
const a = whenEmpty ? mapType(whenEmpty, ctx) : null;
|
|
4924
|
+
const b = otherwise ? mapType(otherwise, ctx) : null;
|
|
4925
|
+
return a && b && typeEquals(a, b) ? a : null;
|
|
4926
|
+
}
|
|
4927
|
+
if (bound?.kind !== "record")
|
|
4928
|
+
return null;
|
|
4929
|
+
const shape = shapes.get(bound.shapeId);
|
|
4930
|
+
if (!shape || shape.tuple)
|
|
4931
|
+
return null;
|
|
4932
|
+
const hasKeys = shape.fields.length > 0 || shape.indexValue !== undefined;
|
|
4933
|
+
const branch = hasKeys ? type.getFalseType() : type.getTrueType();
|
|
4934
|
+
return branch ? mapType(branch, ctx) : null;
|
|
4935
|
+
}
|
|
4936
|
+
/** A mapped type over a type parameter of the instance being lowered (`{
|
|
4937
|
+
* [K in keyof S]: S[K] }`, `{ [K in keyof S]: Infer<S[K]> }`): the checker
|
|
4938
|
+
* keeps it symbolic inside the generic body, but the instance binds `S`,
|
|
4939
|
+
* so each property of the bound type maps through the template evaluated
|
|
4940
|
+
* with `K` set to that property's key. Optionality follows the `?`
|
|
4941
|
+
* modifier, or the bound property's own for a homomorphic mapping. Null
|
|
4942
|
+
* when the shape is anything else or a template form does not evaluate. */
|
|
4943
|
+
function mapBoundMappedType(widened, ctx) {
|
|
4944
|
+
const { checker, resolveTypeParamTs, shapes, unions } = ctx;
|
|
4945
|
+
if (!resolveTypeParamTs || !isMappedShape(widened))
|
|
4946
|
+
return null;
|
|
4947
|
+
const symbol = widened.getSymbol();
|
|
4948
|
+
const node = symbol
|
|
4949
|
+
? symbol.declarations.find((d) => ts.isMappedTypeNode(d))
|
|
4950
|
+
: undefined;
|
|
4951
|
+
const constraint = node?.typeParameter.constraint;
|
|
4952
|
+
if (!node?.type ||
|
|
4953
|
+
!constraint ||
|
|
4954
|
+
!ts.isTypeOperatorNode(constraint) ||
|
|
4955
|
+
constraint.operator !== ts.SyntaxKind.KeyOfKeyword)
|
|
4956
|
+
return null;
|
|
4957
|
+
const source = checker.getTypeFromTypeNode(constraint.type);
|
|
4958
|
+
if (!(source.flags & ts.TypeFlags.TypeParameter))
|
|
4959
|
+
return null;
|
|
4960
|
+
const bound = resolveTypeParamTs(source);
|
|
4961
|
+
const key = checker.getSymbolAtLocation(node.typeParameter.name);
|
|
4962
|
+
if (!bound || !key)
|
|
4963
|
+
return null;
|
|
4964
|
+
const template = checker.getTypeFromTypeNode(node.type);
|
|
4965
|
+
const modifier = node.questionToken?.kind;
|
|
4966
|
+
const fields = [];
|
|
4967
|
+
const order = [];
|
|
4968
|
+
for (const property of checker.getPropertiesOfType(bound)) {
|
|
4969
|
+
const name = ts.symbolName(property);
|
|
4970
|
+
const evaluated = evalMappedTemplate(template, new Map([[key, name]]), new Map(), ctx);
|
|
4971
|
+
let type = evaluated ? mapType(evaluated, ctx) : null;
|
|
4972
|
+
if (!type)
|
|
4973
|
+
return null;
|
|
4974
|
+
const optional = modifier === ts.SyntaxKind.MinusToken
|
|
4975
|
+
? false
|
|
4976
|
+
: modifier !== undefined || (property.flags & ts.SymbolFlags.Optional) !== 0;
|
|
4977
|
+
if (optional) {
|
|
4978
|
+
const armed = withUndefinedArm(type, unions);
|
|
4979
|
+
if (!armed)
|
|
4980
|
+
return null;
|
|
4981
|
+
type = armed;
|
|
4982
|
+
}
|
|
4983
|
+
fields.push({ name, type });
|
|
4984
|
+
order.push(name);
|
|
4985
|
+
}
|
|
4986
|
+
fields.sort((a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0));
|
|
4987
|
+
return { kind: "record", shapeId: shapes.intern(fields, false, undefined, order) };
|
|
4988
|
+
}
|
|
4989
|
+
/** The checker type a mapped type's template stands for at one key:
|
|
4990
|
+
* `keys` binds the mapped type parameter to a property name, `aliases`
|
|
4991
|
+
* binds type-alias and `infer` parameters met on the way. Handles type
|
|
4992
|
+
* parameters (through the instance's bindings), indexed accesses
|
|
4993
|
+
* (`S[K]`, `S[K]["_output"]`) and conditional types whose `extends` side
|
|
4994
|
+
* is a reference to the same generic type as the checked type
|
|
4995
|
+
* (`S extends Schema<infer T> ? T : never`); answers the type itself
|
|
4996
|
+
* when it mentions none of the bound parameters, null otherwise. */
|
|
4997
|
+
function evalMappedTemplate(type, keys, aliases, ctx) {
|
|
4998
|
+
const { checker, resolveTypeParamTs } = ctx;
|
|
4999
|
+
if (type.flags & ts.TypeFlags.TypeParameter) {
|
|
5000
|
+
const symbol = type.getSymbol();
|
|
5001
|
+
if (symbol && keys.has(symbol))
|
|
5002
|
+
return null;
|
|
5003
|
+
if (symbol && aliases.has(symbol))
|
|
5004
|
+
return aliases.get(symbol);
|
|
5005
|
+
return resolveTypeParamTs?.(type) ?? null;
|
|
5006
|
+
}
|
|
5007
|
+
if (type.isIndexedAccessType()) {
|
|
5008
|
+
const object = type.getObjectType();
|
|
5009
|
+
const index = type.getIndexType();
|
|
5010
|
+
if (!object || !index)
|
|
5011
|
+
return null;
|
|
5012
|
+
const receiver = evalMappedTemplate(object, keys, aliases, ctx);
|
|
5013
|
+
const indexSymbol = index.flags & ts.TypeFlags.TypeParameter ? index.getSymbol() : undefined;
|
|
5014
|
+
const name = indexSymbol && keys.has(indexSymbol)
|
|
5015
|
+
? keys.get(indexSymbol)
|
|
5016
|
+
: index.isStringLiteralType()
|
|
5017
|
+
? index.value
|
|
5018
|
+
: index.isNumberLiteralType()
|
|
5019
|
+
? String(index.value)
|
|
5020
|
+
: null;
|
|
5021
|
+
if (!receiver || name === null)
|
|
5022
|
+
return null;
|
|
5023
|
+
const property = checker.getPropertyOfType(receiver, name);
|
|
5024
|
+
return property ? checker.getTypeOfSymbol(property) : null;
|
|
5025
|
+
}
|
|
5026
|
+
if (type.isConditionalType()) {
|
|
5027
|
+
// A conditional reached through an alias (`Infer<S[K]>`) checks the
|
|
5028
|
+
// alias's own parameters: bind them to the evaluated arguments.
|
|
5029
|
+
let scope = aliases;
|
|
5030
|
+
const alias = type.getAliasSymbol();
|
|
5031
|
+
const aliasArgs = type.getAliasTypeArguments();
|
|
5032
|
+
const aliasDecl = alias
|
|
5033
|
+
? alias.declarations.find((d) => ts.isTypeAliasDeclaration(d))
|
|
5034
|
+
: undefined;
|
|
5035
|
+
if (aliasDecl?.typeParameters?.nodes &&
|
|
5036
|
+
aliasArgs.length === aliasDecl.typeParameters.nodes.length) {
|
|
5037
|
+
scope = new Map(aliases);
|
|
5038
|
+
for (let i = 0; i < aliasArgs.length; i++) {
|
|
5039
|
+
const param = checker.getSymbolAtLocation(aliasDecl.typeParameters.nodes[i].name);
|
|
5040
|
+
const arg = evalMappedTemplate(aliasArgs[i], keys, aliases, ctx);
|
|
5041
|
+
if (!param || !arg)
|
|
5042
|
+
return null;
|
|
5043
|
+
scope.set(param, arg);
|
|
5044
|
+
}
|
|
5045
|
+
}
|
|
5046
|
+
const checkType = type.getCheckType();
|
|
5047
|
+
const extendsType = type.getExtendsType();
|
|
5048
|
+
if (!checkType || !extendsType)
|
|
5049
|
+
return null;
|
|
5050
|
+
const checked = evalMappedTemplate(checkType, keys, scope, ctx);
|
|
5051
|
+
if (!checked)
|
|
5052
|
+
return null;
|
|
5053
|
+
const inferred = matchInferReference(checked, extendsType, ctx);
|
|
5054
|
+
if (inferred === undefined)
|
|
5055
|
+
return null;
|
|
5056
|
+
const branch = inferred ? type.getTrueType() : type.getFalseType();
|
|
5057
|
+
const branchScope = inferred ? new Map([...scope, ...inferred]) : scope;
|
|
5058
|
+
return evalMappedTemplate(branch, keys, branchScope, ctx);
|
|
5059
|
+
}
|
|
5060
|
+
return mentionsMappedParams(type, keys, aliases) ? null : type;
|
|
5061
|
+
}
|
|
5062
|
+
/** `checked extends G<..., infer T, ...>`: the infer bindings when
|
|
5063
|
+
* `checked` is a reference to the same generic `G` (its arguments bind the
|
|
5064
|
+
* infer positions; other positions must be the same types), false when it
|
|
5065
|
+
* is a reference to another type or a primitive, undefined when the match
|
|
5066
|
+
* cannot be decided this way. */
|
|
5067
|
+
function matchInferReference(checked, extendsType, ctx) {
|
|
5068
|
+
const { checker } = ctx;
|
|
5069
|
+
const target = (t) => t.isTypeReference?.() ? t.getTarget?.() : undefined;
|
|
5070
|
+
const wantTarget = target(extendsType) ?? extendsType.getAliasSymbol();
|
|
5071
|
+
if (!wantTarget)
|
|
5072
|
+
return matchInferSignature(checked, extendsType, ctx);
|
|
5073
|
+
const gotTarget = target(checked) ?? checked.getAliasSymbol();
|
|
5074
|
+
if (!gotTarget)
|
|
5075
|
+
return checked.flags & ts.TypeFlags.Object
|
|
5076
|
+
? matchInferThenable(checked, extendsType, ctx)
|
|
5077
|
+
: false;
|
|
5078
|
+
if (gotTarget !== wantTarget)
|
|
5079
|
+
return matchInferThenable(checked, extendsType, ctx);
|
|
5080
|
+
const wantArgs = target(extendsType)
|
|
5081
|
+
? checker.getTypeArguments(extendsType)
|
|
5082
|
+
: extendsType.getAliasTypeArguments();
|
|
5083
|
+
const gotArgs = target(checked)
|
|
5084
|
+
? checker.getTypeArguments(checked)
|
|
5085
|
+
: checked.getAliasTypeArguments();
|
|
5086
|
+
if (wantArgs.length !== gotArgs.length)
|
|
5087
|
+
return undefined;
|
|
5088
|
+
const inferred = new Map();
|
|
5089
|
+
for (let i = 0; i < wantArgs.length; i++) {
|
|
5090
|
+
const want = wantArgs[i];
|
|
5091
|
+
const symbol = want.flags & ts.TypeFlags.TypeParameter ? want.getSymbol() : undefined;
|
|
5092
|
+
const isInfer = symbol
|
|
5093
|
+
? symbol.declarations.some((d) => d.parent !== undefined && ts.isInferTypeNode(d.parent))
|
|
5094
|
+
: false;
|
|
5095
|
+
if (isInfer && symbol)
|
|
5096
|
+
inferred.set(symbol, gotArgs[i]);
|
|
5097
|
+
else if (want !== gotArgs[i])
|
|
5098
|
+
return undefined;
|
|
5099
|
+
}
|
|
5100
|
+
return inferred;
|
|
5101
|
+
}
|
|
5102
|
+
/** The type parameter an `infer X` declares, when `t` is one. */
|
|
5103
|
+
function inferSymbolOf(t, _ctx) {
|
|
5104
|
+
if (!(t.flags & ts.TypeFlags.TypeParameter))
|
|
5105
|
+
return undefined;
|
|
5106
|
+
const symbol = t.getSymbol();
|
|
5107
|
+
return symbol &&
|
|
5108
|
+
symbol.declarations.some((d) => d.parent !== undefined && ts.isInferTypeNode(d.parent))
|
|
5109
|
+
? symbol
|
|
5110
|
+
: undefined;
|
|
5111
|
+
}
|
|
5112
|
+
/** `checked extends (...args: any) => infer R` — the shape of the standard
|
|
5113
|
+
* library's ReturnType, over a concrete function type: R binds to its
|
|
5114
|
+
* result. Pattern parameters must be `any` or `any[]`, and a pattern rest
|
|
5115
|
+
* `any` or `any[]`; anything else stays undecided. The match follows
|
|
5116
|
+
* TypeScript's assignability: a primitive never matches a function type,
|
|
5117
|
+
* a function that needs more arguments than a pattern without a rest
|
|
5118
|
+
* passes never matches, and a positional `any[]` parameter needs the
|
|
5119
|
+
* function's parameter there to accept an array. */
|
|
5120
|
+
function matchInferSignature(checked, extendsType, ctx) {
|
|
5121
|
+
const { checker } = ctx;
|
|
5122
|
+
const wantSigs = checker.getCallSignatures(extendsType);
|
|
5123
|
+
const want = wantSigs[0];
|
|
5124
|
+
if (wantSigs.length !== 1 || !want || want.getTypeParameters().length > 0)
|
|
5125
|
+
return undefined;
|
|
5126
|
+
const wantShape = signatureShape(want, ctx);
|
|
5127
|
+
if (wantShape === undefined)
|
|
5128
|
+
return undefined;
|
|
5129
|
+
const isAny = (t) => (t.flags & ts.TypeFlags.Any) !== 0;
|
|
5130
|
+
const isAnyArray = (t) => checker.isArrayType(t) && isAny(checker.getTypeArguments(t)[0]);
|
|
5131
|
+
if (!wantShape.params.every((p) => isAny(p.type) || isAnyArray(p.type)))
|
|
5132
|
+
return undefined;
|
|
5133
|
+
if (wantShape.rest !== null && !isAny(wantShape.rest))
|
|
5134
|
+
return undefined;
|
|
5135
|
+
if (!(checked.flags & ts.TypeFlags.Object))
|
|
5136
|
+
return false;
|
|
5137
|
+
const gotSigs = checker.getCallSignatures(checked);
|
|
5138
|
+
const got = gotSigs[0];
|
|
5139
|
+
if (gotSigs.length !== 1 || !got || got.getTypeParameters().length > 0)
|
|
5140
|
+
return undefined;
|
|
5141
|
+
const gotShape = signatureShape(got, ctx);
|
|
5142
|
+
if (gotShape !== undefined) {
|
|
5143
|
+
// `(a: any) => infer R` rejects `(a: string, b: string) => R` and
|
|
5144
|
+
// `(...args: [string, number]) => R`: they need more arguments.
|
|
5145
|
+
if (wantShape.rest === null && requiredArguments(gotShape) > wantShape.params.length)
|
|
5146
|
+
return false;
|
|
5147
|
+
for (let i = 0; i < wantShape.params.length; i++) {
|
|
5148
|
+
if (!isAnyArray(wantShape.params[i].type))
|
|
5149
|
+
continue;
|
|
5150
|
+
const param = gotShape.params[i]?.type ?? gotShape.rest;
|
|
5151
|
+
if (param === undefined || param === null)
|
|
5152
|
+
continue;
|
|
5153
|
+
const accepts = acceptsArray(param, ctx);
|
|
5154
|
+
if (accepts !== true)
|
|
5155
|
+
return accepts;
|
|
5156
|
+
}
|
|
5157
|
+
}
|
|
5158
|
+
else if (wantShape.params.some((p) => isAnyArray(p.type))) {
|
|
5159
|
+
return undefined;
|
|
5160
|
+
}
|
|
5161
|
+
const wantRet = checker.getReturnTypeOfSignature(want);
|
|
5162
|
+
const infer = inferSymbolOf(wantRet, ctx);
|
|
5163
|
+
if (infer)
|
|
5164
|
+
return new Map([[infer, checker.getReturnTypeOfSignature(got)]]);
|
|
5165
|
+
return wantRet.flags & ts.TypeFlags.Any ? new Map() : undefined;
|
|
5166
|
+
}
|
|
5167
|
+
/** A signature's parameters as a call sees them: the positional ones, with
|
|
5168
|
+
* a fixed-tuple rest (`...args: [A, B?]`) flattened into positions, and the
|
|
5169
|
+
* element type of an array rest (`any` for `...args: any`). Undefined when
|
|
5170
|
+
* a parameter has no declaration, or the rest is a variadic tuple or
|
|
5171
|
+
* another type. */
|
|
5172
|
+
function signatureShape(sig, ctx) {
|
|
5173
|
+
const { checker } = ctx;
|
|
5174
|
+
const params = [];
|
|
5175
|
+
for (const p of sig.getParameters()) {
|
|
5176
|
+
const decl = p.valueDeclaration;
|
|
5177
|
+
if (decl === undefined || !ts.isParameter(decl))
|
|
5178
|
+
return undefined;
|
|
5179
|
+
const type = checker.getTypeOfSymbol(p);
|
|
5180
|
+
if (decl.dotDotDotToken === undefined) {
|
|
5181
|
+
params.push({
|
|
5182
|
+
type,
|
|
5183
|
+
optional: decl.questionToken !== undefined || decl.initializer !== undefined,
|
|
5184
|
+
});
|
|
5185
|
+
continue;
|
|
5186
|
+
}
|
|
5187
|
+
if (type.flags & ts.TypeFlags.Any)
|
|
5188
|
+
return { params, rest: type };
|
|
5189
|
+
if (checker.isArrayType(type))
|
|
5190
|
+
return { params, rest: checker.getTypeArguments(type)[0] };
|
|
5191
|
+
const elems = restTupleElements(type, ctx);
|
|
5192
|
+
if (!elems)
|
|
5193
|
+
return undefined;
|
|
5194
|
+
for (const e of elems)
|
|
5195
|
+
params.push({ type: e.type, optional: e.optional });
|
|
5196
|
+
return { params, rest: null };
|
|
5197
|
+
}
|
|
5198
|
+
return { params, rest: null };
|
|
5199
|
+
}
|
|
5200
|
+
/** The fewest arguments a call must pass: up to the last required position. */
|
|
5201
|
+
function requiredArguments(shape) {
|
|
5202
|
+
let required = 0;
|
|
5203
|
+
shape.params.forEach((p, i) => {
|
|
5204
|
+
if (!p.optional)
|
|
5205
|
+
required = i + 1;
|
|
5206
|
+
});
|
|
5207
|
+
return required;
|
|
5208
|
+
}
|
|
5209
|
+
/** Whether a parameter of this type accepts an `any[]` argument: true for
|
|
5210
|
+
* `any`, `unknown` and array types, false for primitives, undefined
|
|
5211
|
+
* otherwise. */
|
|
5212
|
+
function acceptsArray(t, ctx) {
|
|
5213
|
+
if (t.flags & (ts.TypeFlags.Any | ts.TypeFlags.Unknown))
|
|
5214
|
+
return true;
|
|
5215
|
+
if (ctx.checker.isArrayType(t))
|
|
5216
|
+
return true;
|
|
5217
|
+
const primitive = ts.TypeFlags.StringLike |
|
|
5218
|
+
ts.TypeFlags.NumberLike |
|
|
5219
|
+
ts.TypeFlags.BooleanLike |
|
|
5220
|
+
ts.TypeFlags.BigIntLike |
|
|
5221
|
+
ts.TypeFlags.ESSymbolLike |
|
|
5222
|
+
ts.TypeFlags.Undefined |
|
|
5223
|
+
ts.TypeFlags.Null |
|
|
5224
|
+
ts.TypeFlags.Void;
|
|
5225
|
+
return t.flags & primitive ? false : undefined;
|
|
5226
|
+
}
|
|
5227
|
+
/** `checked extends PromiseLike<infer U>` (or `Promise<infer U>`) over the
|
|
5228
|
+
* standard library's Promise: U binds to the settled type. An object with
|
|
5229
|
+
* no `then` member is no thenable. Everything else stays undecided. */
|
|
5230
|
+
function matchInferThenable(checked, extendsType, ctx) {
|
|
5231
|
+
const { checker } = ctx;
|
|
5232
|
+
const stdlibNamed = (t, names) => {
|
|
5233
|
+
const symbol = t.getSymbol();
|
|
5234
|
+
return (symbol !== undefined &&
|
|
5235
|
+
names.includes(ts.symbolName(symbol)) &&
|
|
5236
|
+
symbol.declarations.some((d) => ctx.isStdlibFile(ts.getSourceFileOfNode(d))));
|
|
5237
|
+
};
|
|
5238
|
+
if (!stdlibNamed(extendsType, ["PromiseLike", "Promise"]))
|
|
5239
|
+
return undefined;
|
|
5240
|
+
const wantArgs = checker.getTypeArguments(extendsType);
|
|
5241
|
+
const infer = wantArgs.length === 1 ? inferSymbolOf(wantArgs[0], ctx) : undefined;
|
|
5242
|
+
if (!infer)
|
|
5243
|
+
return undefined;
|
|
5244
|
+
if (stdlibNamed(checked, ["Promise", "PromiseLike"])) {
|
|
5245
|
+
const gotArgs = checker.getTypeArguments(checked);
|
|
5246
|
+
return gotArgs.length === 1 ? new Map([[infer, gotArgs[0]]]) : undefined;
|
|
5247
|
+
}
|
|
5248
|
+
return checker.getPropertyOfType(checked, "then") === undefined ? false : undefined;
|
|
5249
|
+
}
|
|
5250
|
+
/** The type mentions a mapped key or bound alias parameter (a template
|
|
5251
|
+
* shape evalMappedTemplate does not reduce). */
|
|
5252
|
+
function mentionsMappedParams(type, keys, aliases) {
|
|
5253
|
+
if (type.flags & ts.TypeFlags.TypeParameter) {
|
|
5254
|
+
const symbol = type.getSymbol();
|
|
5255
|
+
return symbol !== undefined && (keys.has(symbol) || aliases.has(symbol));
|
|
5256
|
+
}
|
|
5257
|
+
if (type.isUnionType() || type.isIntersectionType())
|
|
5258
|
+
return ts.constituentTypes(type).some((part) => mentionsMappedParams(part, keys, aliases));
|
|
5259
|
+
return false;
|
|
5260
|
+
}
|
|
5261
|
+
function readonlyClassType(type, ctx) {
|
|
5262
|
+
const alias = type.getAliasSymbol();
|
|
5263
|
+
if (alias === undefined || ts.symbolName(alias) !== "Readonly")
|
|
5264
|
+
return null;
|
|
5265
|
+
const args = type.getAliasTypeArguments();
|
|
5266
|
+
if (args.length !== 1 || !args[0])
|
|
5267
|
+
return null;
|
|
5268
|
+
const isLibAlias = alias.declarations.some((d) => ts.isTypeAliasDeclaration(d) && ctx.isStdlibFile(ts.getSourceFileOfNode(d)));
|
|
5269
|
+
if (!isLibAlias)
|
|
5270
|
+
return null;
|
|
5271
|
+
const mapped = mapType(args[0], ctx);
|
|
5272
|
+
return mapped !== null && isDynTypedRefType(mapped) ? mapped : null;
|
|
4061
5273
|
}
|
|
4062
5274
|
function mapGenericUtilityAlias(widened, ctx) {
|
|
4063
5275
|
const { resolveTypeParam, shapes, unions } = ctx;
|
|
4064
5276
|
if (!resolveTypeParam)
|
|
4065
5277
|
return null;
|
|
4066
5278
|
const alias = widened.getAliasSymbol();
|
|
4067
|
-
if (!alias || (alias
|
|
5279
|
+
if (!alias || (ts.symbolName(alias) !== "Partial" && ts.symbolName(alias) !== "Readonly"))
|
|
4068
5280
|
return null;
|
|
4069
5281
|
const aliasArgs = widened.getAliasTypeArguments();
|
|
4070
5282
|
const arg = aliasArgs[0];
|
|
@@ -4073,15 +5285,13 @@ function mapGenericUtilityAlias(widened, ctx) {
|
|
|
4073
5285
|
if (!(arg.flags & ts.TypeFlags.TypeParameter))
|
|
4074
5286
|
return null;
|
|
4075
5287
|
// Provenance: the STANDARD LIBRARY's alias, not a user's shadowing one.
|
|
4076
|
-
const isLibAlias = ctx.
|
|
4077
|
-
.declarationsOf(alias)
|
|
4078
|
-
.some((d) => ts.isTypeAliasDeclaration(d) && ctx.isStdlibFile(d.getSourceFile()));
|
|
5288
|
+
const isLibAlias = alias.declarations.some((d) => ts.isTypeAliasDeclaration(d) && ctx.isStdlibFile(ts.getSourceFileOfNode(d)));
|
|
4079
5289
|
if (!isLibAlias)
|
|
4080
5290
|
return null;
|
|
4081
5291
|
const bound = resolveTypeParam(arg);
|
|
4082
5292
|
if (!bound || bound.kind !== "record")
|
|
4083
5293
|
return null;
|
|
4084
|
-
if (alias
|
|
5294
|
+
if (ts.symbolName(alias) === "Readonly")
|
|
4085
5295
|
return bound;
|
|
4086
5296
|
const shape = shapes.get(bound.shapeId);
|
|
4087
5297
|
if (!shape)
|
|
@@ -4191,7 +5401,20 @@ export function isUnitOnlyTsType(t, resolveTypeParam) {
|
|
|
4191
5401
|
const UNIT = ts.TypeFlags.Undefined | ts.TypeFlags.Void | ts.TypeFlags.Null;
|
|
4192
5402
|
const parts = t.isUnionType() ? ts.constituentTypes(t) : [t];
|
|
4193
5403
|
return parts.every((p) => (p.flags & UNIT) !== 0 ||
|
|
4194
|
-
((p.flags & ts.TypeFlags.TypeParameter) !== 0 && resolveTypeParam?.(p)?.kind === "void")
|
|
5404
|
+
((p.flags & ts.TypeFlags.TypeParameter) !== 0 && resolveTypeParam?.(p)?.kind === "void") ||
|
|
5405
|
+
boundVoidReturnType(p, resolveTypeParam));
|
|
5406
|
+
}
|
|
5407
|
+
/** `ReturnType<F>` over a type parameter bound to a void-returning
|
|
5408
|
+
* function (a variadic wrapper's result slot): a unit-only value. */
|
|
5409
|
+
function boundVoidReturnType(p, resolveTypeParam) {
|
|
5410
|
+
if (!resolveTypeParam || ts.symbolNameOf(p.getAliasSymbol()) !== "ReturnType")
|
|
5411
|
+
return false;
|
|
5412
|
+
const args = p.getAliasTypeArguments();
|
|
5413
|
+
const arg = args[0];
|
|
5414
|
+
if (args.length !== 1 || !arg || !(arg.flags & ts.TypeFlags.TypeParameter))
|
|
5415
|
+
return false;
|
|
5416
|
+
const bound = resolveTypeParam(arg);
|
|
5417
|
+
return bound?.kind === "func" && bound.ret.kind === "void";
|
|
4195
5418
|
}
|
|
4196
5419
|
/** IR-level `t | undefined`, canonicalized and fenced exactly like the
|
|
4197
5420
|
* ts-union branch of mapType (typeKey-sorted arms, deduplicated;
|
|
@@ -4274,8 +5497,8 @@ function mapHybridCallableIntersection(widened, ctx) {
|
|
|
4274
5497
|
const pt = mapType(checker.getTypeOfSymbol(p), ctx);
|
|
4275
5498
|
if (!pt || pt.kind === "void")
|
|
4276
5499
|
return null;
|
|
4277
|
-
fields.push({ name: p
|
|
4278
|
-
declaredOrder.push(p
|
|
5500
|
+
fields.push({ name: ts.symbolName(p), type: pt });
|
|
5501
|
+
declaredOrder.push(ts.symbolName(p));
|
|
4279
5502
|
}
|
|
4280
5503
|
if (fields.length === 1)
|
|
4281
5504
|
return null; // no properties — it is just F
|
|
@@ -4318,12 +5541,13 @@ function mapErrorMetadataIntersection(type, ctx) {
|
|
|
4318
5541
|
"URIError",
|
|
4319
5542
|
"AggregateError",
|
|
4320
5543
|
"SuppressedError",
|
|
4321
|
-
].includes(symbol
|
|
4322
|
-
|
|
5544
|
+
].includes(ts.symbolName(symbol)) &&
|
|
5545
|
+
symbol.declarations.some((decl) => ctx.isStdlibFile(ts.getSourceFileOfNode(decl))));
|
|
4323
5546
|
});
|
|
4324
5547
|
if (!hasError)
|
|
4325
5548
|
return null;
|
|
4326
5549
|
let error = null;
|
|
5550
|
+
const extra = [];
|
|
4327
5551
|
for (const part of parts) {
|
|
4328
5552
|
const mapped = mapType(part, ctx);
|
|
4329
5553
|
if (mapped?.kind === "object" && RUNTIME_ERROR_CLASSES.has(mapped.className)) {
|
|
@@ -4337,18 +5561,44 @@ function mapErrorMetadataIntersection(type, ctx) {
|
|
|
4337
5561
|
ctx.checker.getIndexInfosOfType(part).length)
|
|
4338
5562
|
return null;
|
|
4339
5563
|
for (const property of ctx.checker.getPropertiesOfType(part)) {
|
|
4340
|
-
const expected = property
|
|
5564
|
+
const expected = ts.symbolName(property) === "errno"
|
|
4341
5565
|
? "f64"
|
|
4342
|
-
: ["code", "syscall", "path", "dest"].includes(property
|
|
5566
|
+
: ["code", "syscall", "path", "dest"].includes(ts.symbolName(property))
|
|
4343
5567
|
? "string"
|
|
4344
5568
|
: null;
|
|
4345
|
-
if (!expected
|
|
4346
|
-
|
|
5569
|
+
if (!expected) {
|
|
5570
|
+
extra.push(property);
|
|
5571
|
+
continue;
|
|
5572
|
+
}
|
|
4347
5573
|
const field = mapType(ctx.checker.getTypeOfSymbol(property), ctx);
|
|
4348
5574
|
const arms = field?.kind === "union" ? ctx.unions.get(field.unionId)?.arms : field ? [field] : [];
|
|
4349
5575
|
if (!arms?.length || !arms.every((arm) => arm.kind === expected || arm.kind === "undefinedT"))
|
|
4350
5576
|
return null;
|
|
5577
|
+
// A required member must still admit the absent value the slot reads.
|
|
5578
|
+
if (!(property.flags & ts.SymbolFlags.Optional) &&
|
|
5579
|
+
!arms.some((arm) => arm.kind === "undefinedT"))
|
|
5580
|
+
return null;
|
|
5581
|
+
}
|
|
5582
|
+
}
|
|
5583
|
+
if (!error)
|
|
5584
|
+
return null;
|
|
5585
|
+
// Members beyond Error's own and the system-error metadata (`Error & {
|
|
5586
|
+
// status: number }`, Object.assign's result) are own properties of the
|
|
5587
|
+
// error's checked-dynamic node: each must map to a type a checked read
|
|
5588
|
+
// can produce. Error's own string members keep their slots.
|
|
5589
|
+
for (const property of extra) {
|
|
5590
|
+
const field = mapType(ctx.checker.getTypeOfSymbol(property), ctx);
|
|
5591
|
+
if (!field || field.kind === "void")
|
|
5592
|
+
return null;
|
|
5593
|
+
if (ts.symbolName(property) === "message" || ts.symbolName(property) === "name") {
|
|
5594
|
+
if (field.kind !== "string")
|
|
5595
|
+
return null;
|
|
5596
|
+
continue;
|
|
4351
5597
|
}
|
|
5598
|
+
if (ts.symbolName(property) === "stack" || ts.symbolName(property) === "cause")
|
|
5599
|
+
return null;
|
|
5600
|
+
if (!canDynCheckTo(field, (id) => ctx.shapes.get(id), (id) => ctx.unions.get(id)))
|
|
5601
|
+
return null;
|
|
4352
5602
|
}
|
|
4353
5603
|
return error;
|
|
4354
5604
|
}
|
|
@@ -4456,13 +5706,13 @@ function immutableSourceType(type, ctx) {
|
|
|
4456
5706
|
return null;
|
|
4457
5707
|
const { checker } = ctx;
|
|
4458
5708
|
const symbol = type.getSymbol();
|
|
4459
|
-
const decl = symbol ?
|
|
4460
|
-
if (decl === undefined || !CONTRACT_TYPES_FILE.test(
|
|
5709
|
+
const decl = symbol ? symbol.declarations[0] : undefined;
|
|
5710
|
+
if (decl === undefined || !CONTRACT_TYPES_FILE.test(ts.getSourceFileOfNode(decl).fileName))
|
|
4461
5711
|
return null;
|
|
4462
5712
|
const props = checker.getPropertiesOfType(type);
|
|
4463
5713
|
const seen = new Set();
|
|
4464
5714
|
for (const prop of props) {
|
|
4465
|
-
const owner =
|
|
5715
|
+
const owner = prop.declarations[0]?.parent;
|
|
4466
5716
|
if (owner === undefined || seen.has(owner))
|
|
4467
5717
|
continue;
|
|
4468
5718
|
seen.add(owner);
|
|
@@ -4471,7 +5721,7 @@ function immutableSourceType(type, ctx) {
|
|
|
4471
5721
|
source = checker.getTypeFromTypeNode(owner);
|
|
4472
5722
|
else if ((ts.isClassDeclaration(owner) || ts.isInterfaceDeclaration(owner)) &&
|
|
4473
5723
|
owner.name !== undefined &&
|
|
4474
|
-
(owner.typeParameters?.length ?? 0) === 0) {
|
|
5724
|
+
(owner.typeParameters?.nodes.length ?? 0) === 0) {
|
|
4475
5725
|
const ownerSymbol = checker.getSymbolAtLocation(owner.name);
|
|
4476
5726
|
if (ownerSymbol)
|
|
4477
5727
|
source = checker.getDeclaredTypeOfSymbol(ownerSymbol);
|
|
@@ -4489,6 +5739,52 @@ function isMappedShape(t) {
|
|
|
4489
5739
|
return ((t.flags & ts.TypeFlags.Object) !== 0 &&
|
|
4490
5740
|
(t.objectFlags & ts.ObjectFlags.Mapped) !== 0);
|
|
4491
5741
|
}
|
|
5742
|
+
/** A declaration file an installed package ships (its own or an @types
|
|
5743
|
+
* twin), outside the standard library and @types/node: the type surface
|
|
5744
|
+
* of a package the program does not compile. Its pure type shapes —
|
|
5745
|
+
* interfaces, aliases, type literals — describe data a program can build
|
|
5746
|
+
* itself (`import type` from a types-only package such as type-fest). */
|
|
5747
|
+
/** A class an SDK declares only to describe data (aws-sdk's
|
|
5748
|
+
* `declare class PresignedPost { url: string; fields: Fields }`, which
|
|
5749
|
+
* arrives as JSON and is never constructed): public instance fields and
|
|
5750
|
+
* nothing else — no constructor, methods, accessors, index signatures,
|
|
5751
|
+
* static, private or protected members, base classes, implemented
|
|
5752
|
+
* interfaces or type parameters. Its instances are exactly the records
|
|
5753
|
+
* of those fields, so the type maps structurally like an interface. */
|
|
5754
|
+
function isDeclaredDataClass(d) {
|
|
5755
|
+
if (!ts.isClassDeclaration(d) || !d.getSourceFile().isDeclarationFile)
|
|
5756
|
+
return false;
|
|
5757
|
+
if (d.heritageClauses !== undefined && d.heritageClauses.nodes.length > 0)
|
|
5758
|
+
return false;
|
|
5759
|
+
if (d.typeParameters !== undefined && d.typeParameters.nodes.length > 0)
|
|
5760
|
+
return false;
|
|
5761
|
+
return d.members.nodes.every((member) => ts.isPropertyDeclaration(member) &&
|
|
5762
|
+
!ts.isPrivateIdentifier(member.name) &&
|
|
5763
|
+
!(member.modifiers?.nodes ?? []).some((modifier) => modifier.kind === ts.SyntaxKind.StaticKeyword ||
|
|
5764
|
+
modifier.kind === ts.SyntaxKind.PrivateKeyword ||
|
|
5765
|
+
modifier.kind === ts.SyntaxKind.ProtectedKeyword ||
|
|
5766
|
+
modifier.kind === ts.SyntaxKind.AbstractKeyword));
|
|
5767
|
+
}
|
|
5768
|
+
/** A namespace merged into a declared data class that holds only types
|
|
5769
|
+
* (`namespace PresignedPost { interface Fields { … } }`): it adds no value
|
|
5770
|
+
* the program could reach. */
|
|
5771
|
+
function isTypeOnlyNamespace(d) {
|
|
5772
|
+
if (!ts.isModuleDeclaration(d))
|
|
5773
|
+
return false;
|
|
5774
|
+
const body = d.body;
|
|
5775
|
+
if (body === undefined)
|
|
5776
|
+
return true;
|
|
5777
|
+
if (ts.isModuleDeclaration(body))
|
|
5778
|
+
return isTypeOnlyNamespace(body);
|
|
5779
|
+
if (!ts.isModuleBlock(body))
|
|
5780
|
+
return false;
|
|
5781
|
+
return body.statements.nodes.every((statement) => ts.isInterfaceDeclaration(statement) ||
|
|
5782
|
+
ts.isTypeAliasDeclaration(statement) ||
|
|
5783
|
+
isTypeOnlyNamespace(statement));
|
|
5784
|
+
}
|
|
5785
|
+
function packageTypeFile(sf, ctx) {
|
|
5786
|
+
return (sf.isDeclarationFile && /[\\/]node_modules[\\/]/.test(sf.fileName) && !ctx.isStdlibFile(sf));
|
|
5787
|
+
}
|
|
4492
5788
|
/** The record path's provenance fence. Declared shapes (object literals,
|
|
4493
5789
|
* interfaces, type literals) must come from user code or an explicitly
|
|
4494
5790
|
* mapped external type surface, never an arbitrary .d.ts — the empty
|
|
@@ -4514,20 +5810,19 @@ function recordProvenanceOk(t, ctx) {
|
|
|
4514
5810
|
if (isMappedShape(t))
|
|
4515
5811
|
return true;
|
|
4516
5812
|
const tSym = t.getSymbol();
|
|
4517
|
-
const decls = tSym ?
|
|
5813
|
+
const decls = tSym ? tSym.declarations : undefined;
|
|
4518
5814
|
if (!decls || decls.length === 0) {
|
|
4519
5815
|
// Inferred destructuring parameters can have a synthesized anonymous
|
|
4520
5816
|
// shape with no declaration or member symbols to trace to a source.
|
|
4521
5817
|
return checker
|
|
4522
5818
|
.getPropertiesOfType(t)
|
|
4523
|
-
.every((property) =>
|
|
4524
|
-
.
|
|
4525
|
-
.
|
|
4526
|
-
ctx.isExternalTypeFile(decl.getSourceFile())));
|
|
5819
|
+
.every((property) => property.declarations.every((decl) => !ts.getSourceFileOfNode(decl).isDeclarationFile ||
|
|
5820
|
+
ctx.isExternalTypeFile(ts.getSourceFileOfNode(decl)) ||
|
|
5821
|
+
packageTypeFile(ts.getSourceFileOfNode(decl), ctx)));
|
|
4527
5822
|
}
|
|
4528
5823
|
return !decls.some((d) => {
|
|
4529
|
-
const sf =
|
|
4530
|
-
return sf.isDeclarationFile && !ctx.isExternalTypeFile(sf);
|
|
5824
|
+
const sf = ts.getSourceFileOfNode(d);
|
|
5825
|
+
return sf.isDeclarationFile && !ctx.isExternalTypeFile(sf) && !packageTypeFile(sf, ctx);
|
|
4531
5826
|
});
|
|
4532
5827
|
}
|
|
4533
5828
|
/** A GENERIC-callable member type (`m<T>(x: T): T` / `f: <T>(x: T) => T` in
|
|
@@ -4549,6 +5844,213 @@ export function isGenericCallableMemberType(t, checker) {
|
|
|
4549
5844
|
checker.getPropertiesOfType(t).length === 0 &&
|
|
4550
5845
|
checker.getIndexInfosOfType(t).length === 0);
|
|
4551
5846
|
}
|
|
5847
|
+
/** Result containers an erased async function or generator must keep:
|
|
5848
|
+
* their contents are erased instead (`Promise<T>` maps as
|
|
5849
|
+
* `Promise<unknown>`). */
|
|
5850
|
+
const ERASURE_KEPT_CONTAINERS = new Set(["Promise", "Generator", "AsyncGenerator"]);
|
|
5851
|
+
/** The type mentions a type parameter that the active erasure binds to
|
|
5852
|
+
* `unknown` (erasedGenericMemberType, erased bodies). */
|
|
5853
|
+
function mentionsErasedTypeParam(type, ctx, depth) {
|
|
5854
|
+
if (depth > 8)
|
|
5855
|
+
return false;
|
|
5856
|
+
const { checker } = ctx;
|
|
5857
|
+
if (type.flags & ts.TypeFlags.TypeParameter)
|
|
5858
|
+
return ctx.resolveTypeParam?.(type)?.kind === "dyn";
|
|
5859
|
+
if (type.flags &
|
|
5860
|
+
(ts.TypeFlags.IndexedAccess | ts.TypeFlags.Conditional | ts.TypeFlags.Substitution))
|
|
5861
|
+
return true;
|
|
5862
|
+
if (type.isUnionType() || type.isIntersectionType())
|
|
5863
|
+
return ts.constituentTypes(type).some((part) => mentionsErasedTypeParam(part, ctx, depth + 1));
|
|
5864
|
+
if ((type.flags & ts.TypeFlags.Object) === 0)
|
|
5865
|
+
return false;
|
|
5866
|
+
if (type.isTypeReference() &&
|
|
5867
|
+
checker
|
|
5868
|
+
.getTypeArguments(type)
|
|
5869
|
+
.some((arg) => mentionsErasedTypeParam(arg, ctx, depth + 1)))
|
|
5870
|
+
return true;
|
|
5871
|
+
for (const sig of checker.getCallSignatures(type)) {
|
|
5872
|
+
if (mentionsErasedTypeParam(checker.getReturnTypeOfSignature(sig), ctx, depth + 1))
|
|
5873
|
+
return true;
|
|
5874
|
+
for (const param of sig.getParameters())
|
|
5875
|
+
if (mentionsErasedTypeParam(checker.getTypeOfSymbol(param), ctx, depth + 1))
|
|
5876
|
+
return true;
|
|
5877
|
+
}
|
|
5878
|
+
const symbol = type.getSymbol();
|
|
5879
|
+
const anonymous = symbol !== undefined &&
|
|
5880
|
+
(symbol.flags & (ts.SymbolFlags.TypeLiteral | ts.SymbolFlags.ObjectLiteral)) !== 0;
|
|
5881
|
+
if (anonymous)
|
|
5882
|
+
for (const property of checker.getPropertiesOfType(type))
|
|
5883
|
+
if (mentionsErasedTypeParam(checker.getTypeOfSymbol(property), ctx, depth + 1))
|
|
5884
|
+
return true;
|
|
5885
|
+
return false;
|
|
5886
|
+
}
|
|
5887
|
+
/** A generic callable member's runtime type: its one call signature with
|
|
5888
|
+
* every own type parameter bound to `unknown`, the erased instance a stored
|
|
5889
|
+
* or escaping definition carries (JavaScript erases type parameters the
|
|
5890
|
+
* same way). Undefined when the member has overloads or the erased
|
|
5891
|
+
* signature does not map: the member then stays out of the shape, and only
|
|
5892
|
+
* calls on a provable definition compile. */
|
|
5893
|
+
export function erasedGenericMemberType(t, ctx) {
|
|
5894
|
+
const sigs = ctx.checker.getCallSignatures(t);
|
|
5895
|
+
if (sigs.length !== 1)
|
|
5896
|
+
return undefined;
|
|
5897
|
+
const sig = sigs[0];
|
|
5898
|
+
const own = new Set(sig.getTypeParameters());
|
|
5899
|
+
const outer = ctx.resolveTypeParam;
|
|
5900
|
+
const erased = mapType(t, {
|
|
5901
|
+
...ctx,
|
|
5902
|
+
erasingSignature: sig,
|
|
5903
|
+
resolveTypeParam: (param) => (own.has(param) ? DYN : (outer?.(param) ?? null)),
|
|
5904
|
+
});
|
|
5905
|
+
return erased?.kind === "func" ? erased : undefined;
|
|
5906
|
+
}
|
|
5907
|
+
/** An OVERLOADED callable member type (`on(event: "a", h: (x: number) =>
|
|
5908
|
+
* void): () => void; on(event: "b", h: (x: string) => void): () => void`
|
|
5909
|
+
* in a program interface or type literal): two or more call signatures and
|
|
5910
|
+
* nothing else (no data properties, construct signatures, or index
|
|
5911
|
+
* signatures), every one declared in TypeScript program source. Such a
|
|
5912
|
+
* member keeps a record slot holding its erased runtime function
|
|
5913
|
+
* (erasedOverloadMemberType); calls convert per their resolved overload
|
|
5914
|
+
* (lowerRecordFieldCall). */
|
|
5915
|
+
export function isOverloadedCallableMemberType(t, checker) {
|
|
5916
|
+
const sigs = checker.getCallSignatures(t);
|
|
5917
|
+
if (sigs.length < 2)
|
|
5918
|
+
return false;
|
|
5919
|
+
if (checker.getConstructSignatures(t).length > 0 ||
|
|
5920
|
+
checker.getPropertiesOfType(t).length > 0 ||
|
|
5921
|
+
checker.getIndexInfosOfType(t).length > 0)
|
|
5922
|
+
return false;
|
|
5923
|
+
return sigs.every((sig) => {
|
|
5924
|
+
const decl = sig.declaration;
|
|
5925
|
+
if (decl === undefined)
|
|
5926
|
+
return false;
|
|
5927
|
+
if (!ts.isMethodSignatureDeclaration(decl) && !ts.isCallSignatureDeclaration(decl))
|
|
5928
|
+
return false;
|
|
5929
|
+
const file = ts.getSourceFileOfNode(decl);
|
|
5930
|
+
return !file.isDeclarationFile && !isJsSourceFile(file);
|
|
5931
|
+
});
|
|
5932
|
+
}
|
|
5933
|
+
/** Scalar arms an overload join may combine into one union. */
|
|
5934
|
+
const OVERLOAD_JOIN_SCALARS = new Set(["f64", "string", "bool", "undefinedT", "nullT"]);
|
|
5935
|
+
/** The join of one position's types across an overload set: equal types
|
|
5936
|
+
* stay; scalar mixes form their union; anything else is `unknown` when
|
|
5937
|
+
* every joined type crosses the checked-dynamic boundary in both directions
|
|
5938
|
+
* (the call site converts into the slot, the implementation converts out
|
|
5939
|
+
* of it). Differing callbacks (`(x: number) => void` beside `(x: string) =>
|
|
5940
|
+
* void`) therefore travel as checked function values, which any
|
|
5941
|
+
* implementation's own callback type adapts from. Null when no join
|
|
5942
|
+
* exists. */
|
|
5943
|
+
function joinOverloadTypes(types, ctx) {
|
|
5944
|
+
const first = types[0];
|
|
5945
|
+
if (types.every((t) => typeEquals(t, first)))
|
|
5946
|
+
return first;
|
|
5947
|
+
const getRecord = (id) => ctx.shapes.get(id);
|
|
5948
|
+
const getUnion = (id) => ctx.unions.get(id);
|
|
5949
|
+
const arms = new Map();
|
|
5950
|
+
let scalar = true;
|
|
5951
|
+
for (const t of types) {
|
|
5952
|
+
const parts = t.kind === "union" ? (ctx.unions.get(t.unionId)?.arms ?? []) : [t];
|
|
5953
|
+
if (parts.length === 0)
|
|
5954
|
+
scalar = false;
|
|
5955
|
+
for (const part of parts) {
|
|
5956
|
+
if (!OVERLOAD_JOIN_SCALARS.has(part.kind))
|
|
5957
|
+
scalar = false;
|
|
5958
|
+
arms.set(typeKey(part), part);
|
|
5959
|
+
}
|
|
5960
|
+
}
|
|
5961
|
+
if (scalar && [...arms.values()].some((arm) => !isUnitType(arm))) {
|
|
5962
|
+
const sorted = [...arms.values()].sort((a, b) => (typeKey(a) < typeKey(b) ? -1 : 1));
|
|
5963
|
+
return { kind: "union", unionId: ctx.unions.intern(sorted) };
|
|
5964
|
+
}
|
|
5965
|
+
if (types.every((t) => t.kind === "dyn" ||
|
|
5966
|
+
(t.kind !== "void" &&
|
|
5967
|
+
canConvertToDyn(t, getRecord, getUnion) &&
|
|
5968
|
+
canDynCheckTo(t, getRecord, getUnion))))
|
|
5969
|
+
return DYN;
|
|
5970
|
+
return null;
|
|
5971
|
+
}
|
|
5972
|
+
/** An overloaded member's runtime type (isOverloadedCallableMemberType).
|
|
5973
|
+
* JavaScript stores ONE function under the member; overload signatures only
|
|
5974
|
+
* constrain call sites. The slot's type joins the overloads per parameter
|
|
5975
|
+
* position and result (joinOverloadTypes), and a position some overloads
|
|
5976
|
+
* omit is optional. Each overload's own type parameters erase to `unknown`
|
|
5977
|
+
* first. Calls pick their overload statically, convert arguments into the
|
|
5978
|
+
* slot's parameter types and the result back to the overload's; an
|
|
5979
|
+
* implementation converts into the slot like any function value. Undefined
|
|
5980
|
+
* when the set does not join (rest parameters, a void result beside a
|
|
5981
|
+
* value result, a component outside the checked-dynamic boundary): the
|
|
5982
|
+
* member keeps its fence. */
|
|
5983
|
+
export function erasedOverloadMemberType(t, ctx) {
|
|
5984
|
+
const funcs = [];
|
|
5985
|
+
for (const sig of ctx.checker.getCallSignatures(t)) {
|
|
5986
|
+
const own = new Set(sig.getTypeParameters());
|
|
5987
|
+
const outer = ctx.resolveTypeParam;
|
|
5988
|
+
const mapped = mapCallSignature(sig, own.size === 0
|
|
5989
|
+
? ctx
|
|
5990
|
+
: {
|
|
5991
|
+
...ctx,
|
|
5992
|
+
erasingSignature: sig,
|
|
5993
|
+
resolveTypeParam: (param) => (own.has(param) ? DYN : (outer?.(param) ?? null)),
|
|
5994
|
+
});
|
|
5995
|
+
if (mapped?.kind !== "func" || mapped.rest === true || mapped.argumentsAll === true)
|
|
5996
|
+
return undefined;
|
|
5997
|
+
funcs.push(mapped);
|
|
5998
|
+
}
|
|
5999
|
+
const arity = Math.max(...funcs.map((f) => f.params.length));
|
|
6000
|
+
const params = [];
|
|
6001
|
+
for (let i = 0; i < arity; i++) {
|
|
6002
|
+
const present = funcs.filter((f) => i < f.params.length).map((f) => f.params[i]);
|
|
6003
|
+
let param = joinOverloadTypes(present, ctx);
|
|
6004
|
+
if (param !== null && present.length < funcs.length && param.kind !== "dyn")
|
|
6005
|
+
param = withUndefinedArm(param, ctx.unions);
|
|
6006
|
+
if (param === null)
|
|
6007
|
+
return undefined;
|
|
6008
|
+
params.push(param);
|
|
6009
|
+
}
|
|
6010
|
+
const voids = funcs.filter((f) => f.ret.kind === "void").length;
|
|
6011
|
+
if (voids !== 0 && voids !== funcs.length)
|
|
6012
|
+
return undefined;
|
|
6013
|
+
const ret = voids === funcs.length
|
|
6014
|
+
? VOID
|
|
6015
|
+
: joinOverloadTypes(funcs.map((f) => f.ret), ctx);
|
|
6016
|
+
if (ret === null)
|
|
6017
|
+
return undefined;
|
|
6018
|
+
return funcOf(params, ret);
|
|
6019
|
+
}
|
|
6020
|
+
/** Why an overloaded member's set has no erased type
|
|
6021
|
+
* (erasedOverloadMemberType): the first overload, and within it the first
|
|
6022
|
+
* parameter or result, that does not map; otherwise the join itself. A
|
|
6023
|
+
* message tail after "its member 'name'". */
|
|
6024
|
+
function describeOverloadSetBlocker(t, ctx) {
|
|
6025
|
+
const { checker } = ctx;
|
|
6026
|
+
for (const sig of checker.getCallSignatures(t)) {
|
|
6027
|
+
const own = new Set(sig.getTypeParameters());
|
|
6028
|
+
const outer = ctx.resolveTypeParam;
|
|
6029
|
+
const sigCtx = own.size === 0
|
|
6030
|
+
? ctx
|
|
6031
|
+
: {
|
|
6032
|
+
...ctx,
|
|
6033
|
+
erasingSignature: sig,
|
|
6034
|
+
resolveTypeParam: (param) => (own.has(param) ? DYN : (outer?.(param) ?? null)),
|
|
6035
|
+
};
|
|
6036
|
+
const mapped = mapCallSignature(sig, sigCtx);
|
|
6037
|
+
if (mapped?.kind === "func" && mapped.rest !== true && mapped.argumentsAll !== true)
|
|
6038
|
+
continue;
|
|
6039
|
+
const decl = sig.declaration;
|
|
6040
|
+
const spelled = decl ? ts.getTextOfNode(decl).replace(/\s+/g, " ").replace(/;$/, "") : "";
|
|
6041
|
+
const which = spelled ? `overload '${spelled}'` : "one overload";
|
|
6042
|
+
if (mapped?.kind === "func")
|
|
6043
|
+
return `is an overload set, and its ${which} has a rest parameter (an overload set stores one fixed-arity function)`;
|
|
6044
|
+
for (const param of sig.getParameters()) {
|
|
6045
|
+
const paramTs = checker.getTypeOfSymbol(param);
|
|
6046
|
+
if (!mapType(paramTs, sigCtx))
|
|
6047
|
+
return `is an overload set, and its ${which} has parameter '${ts.symbolName(param)}' of type '${checker.typeToString(paramTs)}', which does not compile`;
|
|
6048
|
+
}
|
|
6049
|
+
const retTs = checker.getReturnTypeOfSignature(sig);
|
|
6050
|
+
return `is an overload set, and its ${which} returns '${checker.typeToString(retTs)}', which does not compile`;
|
|
6051
|
+
}
|
|
6052
|
+
return "is an overload set whose signatures do not join into one stored function (a void result beside a value result, or positions whose differing types do not cross the checked-dynamic boundary)";
|
|
6053
|
+
}
|
|
4552
6054
|
function mapRecordType(widened, ctx) {
|
|
4553
6055
|
const { shapes } = ctx;
|
|
4554
6056
|
// A type whose recursive shape already finalized answers its id straight
|
|
@@ -4587,10 +6089,9 @@ function mapRecordType(widened, ctx) {
|
|
|
4587
6089
|
// checker-type identity — fence recursive generic-open shapes.
|
|
4588
6090
|
if (contextResolutions !== sensitivityAtEntry)
|
|
4589
6091
|
return null;
|
|
4590
|
-
|
|
4591
|
-
|
|
4592
|
-
|
|
4593
|
-
};
|
|
6092
|
+
const recursive = shapes.finalizeRecursive(widened, inner.fields, inner.indexValue, inner.declaredOrder);
|
|
6093
|
+
adoptAccessorOrder(shapes.get(recursive), inner.accessorOrder);
|
|
6094
|
+
return { kind: "record", shapeId: recursive };
|
|
4594
6095
|
}
|
|
4595
6096
|
// A record with no typed payload contract is a view of an existing
|
|
4596
6097
|
// object, including across parameters and returns. Building a native
|
|
@@ -4601,18 +6102,294 @@ function mapRecordType(widened, ctx) {
|
|
|
4601
6102
|
inner.fields.every((field) => field.type.kind === "dyn") &&
|
|
4602
6103
|
(inner.indexValue === undefined || inner.indexValue.kind === "dyn"))
|
|
4603
6104
|
return DYN;
|
|
6105
|
+
const covered = coveredOptionalFieldsShape(widened, inner, ctx);
|
|
6106
|
+
if (covered !== null)
|
|
6107
|
+
return { kind: "record", shapeId: covered };
|
|
6108
|
+
const merged = dictSpreadLiteralShape(widened, inner, ctx);
|
|
6109
|
+
if (merged === "dyn")
|
|
6110
|
+
return DYN;
|
|
6111
|
+
if (merged !== null)
|
|
6112
|
+
return { kind: "record", shapeId: merged };
|
|
4604
6113
|
const refined = refinedConstituentShape(widened, inner, ctx);
|
|
4605
6114
|
if (refined !== null)
|
|
4606
6115
|
return { kind: "record", shapeId: refined };
|
|
4607
|
-
|
|
4608
|
-
|
|
4609
|
-
|
|
4610
|
-
};
|
|
6116
|
+
const shapeId = shapes.intern(inner.fields, false, inner.indexValue, inner.declaredOrder);
|
|
6117
|
+
adoptAccessorOrder(shapes.get(shapeId), inner.accessorOrder);
|
|
6118
|
+
return { kind: "record", shapeId };
|
|
4611
6119
|
}
|
|
4612
6120
|
finally {
|
|
4613
6121
|
shapes.inProgress.delete(widened);
|
|
4614
6122
|
}
|
|
4615
6123
|
}
|
|
6124
|
+
/** An index signature already describes every OPTIONAL declared member
|
|
6125
|
+
* whose type is its slot type: @types/node's `ProcessEnv extends
|
|
6126
|
+
* Dict<string> { TZ?: string }` and every spread of it, or a declared
|
|
6127
|
+
* environment `{ CI?: string } & Dictionary<string>`. At runtime such a
|
|
6128
|
+
* member is just another key, so the shape interns as the pure
|
|
6129
|
+
* index-signature record. Its slot admits undefined, as the optional
|
|
6130
|
+
* members do (`env.CI = undefined` keeps the key). A hybrid layout would
|
|
6131
|
+
* give each member a struct slot, which enumerates before the overflow
|
|
6132
|
+
* keys (Node keeps one insertion order) and makes `delete` and spread
|
|
6133
|
+
* answer differently for declared and undeclared keys. Required members,
|
|
6134
|
+
* and members typed otherwise than the slot (whose reads the slot type
|
|
6135
|
+
* could not give back), keep the hybrid shape. */
|
|
6136
|
+
function coveredOptionalFieldsShape(widened, parts, ctx) {
|
|
6137
|
+
const slot = parts.indexValue;
|
|
6138
|
+
if (!slot || parts.fields.length === 0)
|
|
6139
|
+
return null;
|
|
6140
|
+
const { checker, shapes, unions } = ctx;
|
|
6141
|
+
// The members' common type must be the slot plus undefined. Read it off
|
|
6142
|
+
// the members (already interned) rather than building it: a hybrid that
|
|
6143
|
+
// does not qualify must not intern anything new.
|
|
6144
|
+
const optionalSlot = parts.fields[0].type;
|
|
6145
|
+
if (!parts.fields.every((field) => typeEquals(field.type, optionalSlot)))
|
|
6146
|
+
return null;
|
|
6147
|
+
if (optionalSlot.kind !== "union" || unions.armTag(optionalSlot.unionId, UNDEFINED_T) < 0)
|
|
6148
|
+
return null;
|
|
6149
|
+
const memberArms = unions.get(optionalSlot.unionId)?.arms ?? [];
|
|
6150
|
+
const slotArms = slot.kind === "union" ? (unions.get(slot.unionId)?.arms ?? []) : isUnitType(slot) ? [] : [slot];
|
|
6151
|
+
const definedArms = memberArms.filter((arm) => arm.kind !== "undefinedT");
|
|
6152
|
+
const slotDefined = slotArms.filter((arm) => arm.kind !== "undefinedT");
|
|
6153
|
+
if (definedArms.length === 0 ||
|
|
6154
|
+
definedArms.length !== slotDefined.length ||
|
|
6155
|
+
!slotDefined.every((arm) => definedArms.some((other) => typeEquals(arm, other))))
|
|
6156
|
+
return null;
|
|
6157
|
+
if (!isSupportedIndexValue(optionalSlot))
|
|
6158
|
+
return null;
|
|
6159
|
+
const props = checker.getPropertiesOfType(widened);
|
|
6160
|
+
if (props.length !== parts.fields.length)
|
|
6161
|
+
return null;
|
|
6162
|
+
if (!props.every((p) => (p.flags & ts.SymbolFlags.Optional) !== 0))
|
|
6163
|
+
return null;
|
|
6164
|
+
return shapes.intern([], false, optionalSlot, []);
|
|
6165
|
+
}
|
|
6166
|
+
/** The type of an object literal that spreads an index-signature record
|
|
6167
|
+
* (`{ ...tags, bucket: b, status }`, the metric-tags idiom). The checker
|
|
6168
|
+
* drops the signature and types the literal by its explicit members only,
|
|
6169
|
+
* but at run time the object holds every key the spread copied, in one
|
|
6170
|
+
* insertion order. Such a literal maps to the pure index-signature record
|
|
6171
|
+
* whose slot joins the spread slots and the member types, so the merge,
|
|
6172
|
+
* every enumeration and keyed writes see the same keys Node does. A
|
|
6173
|
+
* member read still answers its member type: members written after the
|
|
6174
|
+
* spreads always win, and a member written before a spread must have that
|
|
6175
|
+
* spread's slot type, so an override cannot change its type. The join
|
|
6176
|
+
* covers scalar and unit types only; other literals keep their shape and
|
|
6177
|
+
* the spread fence. */
|
|
6178
|
+
function dictSpreadLiteralShape(widened, parts, ctx) {
|
|
6179
|
+
if (parts.indexValue)
|
|
6180
|
+
return null;
|
|
6181
|
+
const symbol = widened.getSymbol();
|
|
6182
|
+
if (!symbol || (symbol.flags & ts.SymbolFlags.ObjectLiteral) === 0)
|
|
6183
|
+
return null;
|
|
6184
|
+
const literal = symbol.declarations.find((d) => ts.isObjectLiteralExpression(d));
|
|
6185
|
+
if (!literal)
|
|
6186
|
+
return null;
|
|
6187
|
+
const { checker, shapes, unions } = ctx;
|
|
6188
|
+
const props = literal.properties.nodes;
|
|
6189
|
+
if (!props.some((p) => ts.isSpreadAssignment(p)))
|
|
6190
|
+
return null;
|
|
6191
|
+
// Decide on checker types alone before mapping anything: object literals
|
|
6192
|
+
// with ordinary spreads are everywhere, and mapping their sources here
|
|
6193
|
+
// would intern types out of their usual order.
|
|
6194
|
+
// A literal written into a typed index-signature slot already lowers into
|
|
6195
|
+
// it (the merge into the contextual record); its own type keeps its
|
|
6196
|
+
// mapping.
|
|
6197
|
+
const contextualRaw = checker.getContextualType(literal);
|
|
6198
|
+
const contextual = contextualRaw ? checker.getNonNullableType(contextualRaw) : undefined;
|
|
6199
|
+
// A literal written into a declared slot lowers into that slot (a typed
|
|
6200
|
+
// index-signature record merges into it, a declared record converts),
|
|
6201
|
+
// and its own type keeps its mapping. Only a literal with no declared
|
|
6202
|
+
// destination (an unannotated binding, a type parameter, `any` or
|
|
6203
|
+
// `unknown`, an unknown-valued record) is built by its own type.
|
|
6204
|
+
// A generic argument's context is the instantiated parameter: the
|
|
6205
|
+
// literal's own type when the type argument was inferred from it.
|
|
6206
|
+
const ownContext = contextual !== undefined &&
|
|
6207
|
+
(contextual === widened || contextual.getSymbol()?.declarations.includes(literal) === true);
|
|
6208
|
+
if (contextual &&
|
|
6209
|
+
!ownContext &&
|
|
6210
|
+
!(contextual.flags & (ts.TypeFlags.TypeParameter | ts.TypeFlags.Any | ts.TypeFlags.Unknown))) {
|
|
6211
|
+
const infos = checker.getIndexInfosOfType(contextual);
|
|
6212
|
+
const unknownValued = infos.length > 0 &&
|
|
6213
|
+
infos.every((info) => (info.type.flags & (ts.TypeFlags.Any | ts.TypeFlags.Unknown)) !== 0);
|
|
6214
|
+
if (!unknownValued)
|
|
6215
|
+
return null;
|
|
6216
|
+
}
|
|
6217
|
+
const kinds = props.map((p) => ts.isSpreadAssignment(p) ? spreadSourceKindTs(checker, p.expression) : "member");
|
|
6218
|
+
if (kinds.some((k) => k === null) || !kinds.includes("dict"))
|
|
6219
|
+
return null;
|
|
6220
|
+
const dictSlotOf = (e) => {
|
|
6221
|
+
const t = checker.getNonNullableType(checker.getTypeAtLocation(e));
|
|
6222
|
+
if (checker.getPropertiesOfType(t).length === 0) {
|
|
6223
|
+
const infos = checker.getIndexInfosOfType(t);
|
|
6224
|
+
if (infos.length !== 1 || !(infos[0].keyType.flags & ts.TypeFlags.String))
|
|
6225
|
+
return null;
|
|
6226
|
+
return mapType(infos[0].type, ctx);
|
|
6227
|
+
}
|
|
6228
|
+
// Another such literal's type (`{ ...tags, repo }` over a binding
|
|
6229
|
+
// initialized by `{ ...base, plan }`) is stored as the same kind of
|
|
6230
|
+
// pure index-signature record.
|
|
6231
|
+
if (t === widened)
|
|
6232
|
+
return null;
|
|
6233
|
+
const mapped = mapType(t, ctx);
|
|
6234
|
+
if (mapped?.kind === "dyn")
|
|
6235
|
+
return DYN;
|
|
6236
|
+
const shape = mapped?.kind === "record" ? shapes.get(mapped.shapeId) : undefined;
|
|
6237
|
+
return shape?.indexValue && shape.fields.length === 0 && !shape.tuple ? shape.indexValue : null;
|
|
6238
|
+
};
|
|
6239
|
+
const arms = new Map();
|
|
6240
|
+
const addArms = (t) => {
|
|
6241
|
+
const list = t.kind === "union" ? (unions.get(t.unionId)?.arms ?? []) : [t];
|
|
6242
|
+
for (const arm of list) {
|
|
6243
|
+
if (!OVERLOAD_JOIN_SCALARS.has(arm.kind))
|
|
6244
|
+
return false;
|
|
6245
|
+
arms.set(typeKey(arm), arm);
|
|
6246
|
+
}
|
|
6247
|
+
return true;
|
|
6248
|
+
};
|
|
6249
|
+
const before = [];
|
|
6250
|
+
// An unknown-valued spread (`Record<string, unknown>`, or another such
|
|
6251
|
+
// literal) makes the object the checked-dynamic value: it is built like
|
|
6252
|
+
// a JavaScript object literal (copy each spread's own keys in order), and
|
|
6253
|
+
// member reads check their declared types.
|
|
6254
|
+
let unknownValued = false;
|
|
6255
|
+
for (const [i, p] of props.entries()) {
|
|
6256
|
+
// A fixed-shape or conditional spread contributes its own members,
|
|
6257
|
+
// which the checker already types exactly (they are in `parts`).
|
|
6258
|
+
if (kinds[i] === "record") {
|
|
6259
|
+
// Its members may be overwritten by a later dict spread, like members
|
|
6260
|
+
// written before one.
|
|
6261
|
+
before.push(...spreadMemberNamesTs(checker, p.expression));
|
|
6262
|
+
continue;
|
|
6263
|
+
}
|
|
6264
|
+
if (ts.isSpreadAssignment(p)) {
|
|
6265
|
+
const slot = dictSlotOf(p.expression);
|
|
6266
|
+
if (slot?.kind === "dyn") {
|
|
6267
|
+
unknownValued = true;
|
|
6268
|
+
continue;
|
|
6269
|
+
}
|
|
6270
|
+
if (!slot)
|
|
6271
|
+
return null;
|
|
6272
|
+
if (!addArms(slot)) {
|
|
6273
|
+
// A slot outside the scalar join still has the checked-dynamic
|
|
6274
|
+
// representation when it converts to it.
|
|
6275
|
+
if (!canConvertToDyn(slot, (id) => shapes.get(id), (id) => unions.get(id)))
|
|
6276
|
+
return null;
|
|
6277
|
+
unknownValued = true;
|
|
6278
|
+
}
|
|
6279
|
+
// A member written before this spread may be overwritten by it: the
|
|
6280
|
+
// typed join keeps member types only where the slot is that type;
|
|
6281
|
+
// otherwise the checked-dynamic object (whose member reads check
|
|
6282
|
+
// their types) holds whatever the spread wrote.
|
|
6283
|
+
for (const name of before) {
|
|
6284
|
+
const field = parts.fields.find((f) => f.name === name);
|
|
6285
|
+
if (!field)
|
|
6286
|
+
return null;
|
|
6287
|
+
if (!typeEquals(field.type, slot))
|
|
6288
|
+
unknownValued = true;
|
|
6289
|
+
}
|
|
6290
|
+
continue;
|
|
6291
|
+
}
|
|
6292
|
+
if (!(ts.isPropertyAssignment(p) || ts.isShorthandPropertyAssignment(p)))
|
|
6293
|
+
return null;
|
|
6294
|
+
const name = p.name;
|
|
6295
|
+
if (!(ts.isIdentifier(name) || ts.isStringLiteral(name)))
|
|
6296
|
+
return null;
|
|
6297
|
+
before.push(name.text);
|
|
6298
|
+
}
|
|
6299
|
+
if (parts.fields.some((f) => f.name.startsWith("%")))
|
|
6300
|
+
return null;
|
|
6301
|
+
// Members outside the scalar join (an array of labels beside the tags)
|
|
6302
|
+
// make the object the checked-dynamic value too.
|
|
6303
|
+
if (!unknownValued && !parts.fields.every((f) => addArms(f.type)))
|
|
6304
|
+
unknownValued = true;
|
|
6305
|
+
if (unknownValued) {
|
|
6306
|
+
const getRecord = (id) => shapes.get(id);
|
|
6307
|
+
const getUnion = (id) => unions.get(id);
|
|
6308
|
+
return parts.fields.every((f) => f.type.kind === "dyn" || canConvertToDyn(f.type, getRecord, getUnion))
|
|
6309
|
+
? "dyn"
|
|
6310
|
+
: null;
|
|
6311
|
+
}
|
|
6312
|
+
for (const field of parts.fields)
|
|
6313
|
+
if (!addArms(field.type))
|
|
6314
|
+
return null;
|
|
6315
|
+
if (![...arms.values()].some((arm) => !isUnitType(arm)))
|
|
6316
|
+
return null;
|
|
6317
|
+
const sorted = [...arms.values()].sort((a, b) => (typeKey(a) < typeKey(b) ? -1 : 1));
|
|
6318
|
+
const slot = sorted.length === 1 ? sorted[0] : { kind: "union", unionId: unions.intern(sorted) };
|
|
6319
|
+
return shapes.intern([], false, slot, []);
|
|
6320
|
+
}
|
|
6321
|
+
/** How a spread source contributes to dictSpreadLiteralShape, judged on
|
|
6322
|
+
* checker types only: "dict" for a pure string index signature or another
|
|
6323
|
+
* literal that spreads one, "record" for a fixed object shape or a
|
|
6324
|
+
* conditional spread (`...(c && { k: v })`), null otherwise. */
|
|
6325
|
+
function spreadSourceKindTs(checker, e) {
|
|
6326
|
+
if (dictSpreadSourceTs(checker, e, 0))
|
|
6327
|
+
return "dict";
|
|
6328
|
+
let inner = e;
|
|
6329
|
+
while (ts.isParenthesizedExpression(inner))
|
|
6330
|
+
inner = inner.expression;
|
|
6331
|
+
if ((ts.isBinaryExpression(inner) &&
|
|
6332
|
+
inner.operatorToken.kind === ts.SyntaxKind.AmpersandAmpersandToken) ||
|
|
6333
|
+
ts.isConditionalExpression(inner))
|
|
6334
|
+
return "record";
|
|
6335
|
+
const t = checker.getNonNullableType(checker.getTypeAtLocation(e));
|
|
6336
|
+
if ((t.flags & ts.TypeFlags.Object) === 0 || t.isUnionType())
|
|
6337
|
+
return null;
|
|
6338
|
+
if (checker.getIndexInfosOfType(t).length > 0)
|
|
6339
|
+
return null;
|
|
6340
|
+
if (checker.getCallSignatures(t).length > 0 || checker.getConstructSignatures(t).length > 0)
|
|
6341
|
+
return null;
|
|
6342
|
+
const symbol = t.getSymbol();
|
|
6343
|
+
if (symbol && (symbol.flags & ts.SymbolFlags.Class) !== 0)
|
|
6344
|
+
return null;
|
|
6345
|
+
return "record";
|
|
6346
|
+
}
|
|
6347
|
+
/** The member names a fixed-shape or conditional spread contributes. */
|
|
6348
|
+
function spreadMemberNamesTs(checker, e) {
|
|
6349
|
+
let inner = e;
|
|
6350
|
+
while (ts.isParenthesizedExpression(inner))
|
|
6351
|
+
inner = inner.expression;
|
|
6352
|
+
const literals = [];
|
|
6353
|
+
if (ts.isBinaryExpression(inner))
|
|
6354
|
+
literals.push(inner.right);
|
|
6355
|
+
else if (ts.isConditionalExpression(inner))
|
|
6356
|
+
literals.push(inner.whenTrue, inner.whenFalse);
|
|
6357
|
+
else
|
|
6358
|
+
literals.push(inner);
|
|
6359
|
+
const names = [];
|
|
6360
|
+
for (const l of literals) {
|
|
6361
|
+
const t = checker.getNonNullableType(checker.getTypeAtLocation(l));
|
|
6362
|
+
for (const property of checker.getPropertiesOfType(t))
|
|
6363
|
+
names.push(ts.symbolName(property));
|
|
6364
|
+
}
|
|
6365
|
+
return names;
|
|
6366
|
+
}
|
|
6367
|
+
/** A spread source the checker types as a pure string index signature,
|
|
6368
|
+
* or as another object literal that spreads one (dictSpreadLiteralShape),
|
|
6369
|
+
* judged on checker types only. */
|
|
6370
|
+
function dictSpreadSourceTs(checker, e, depth) {
|
|
6371
|
+
const t = checker.getNonNullableType(checker.getTypeAtLocation(e));
|
|
6372
|
+
if (checker.getPropertiesOfType(t).length === 0) {
|
|
6373
|
+
const infos = checker.getIndexInfosOfType(t);
|
|
6374
|
+
return infos.length === 1 && (infos[0].keyType.flags & ts.TypeFlags.String) !== 0;
|
|
6375
|
+
}
|
|
6376
|
+
if (depth > 4)
|
|
6377
|
+
return false;
|
|
6378
|
+
const symbol = t.getSymbol();
|
|
6379
|
+
if (!symbol || (symbol.flags & ts.SymbolFlags.ObjectLiteral) === 0)
|
|
6380
|
+
return false;
|
|
6381
|
+
const literal = symbol.declarations.find((d) => ts.isObjectLiteralExpression(d));
|
|
6382
|
+
if (!literal)
|
|
6383
|
+
return false;
|
|
6384
|
+
const spreads = literal.properties.nodes.filter((p) => ts.isSpreadAssignment(p));
|
|
6385
|
+
return (spreads.length > 0 &&
|
|
6386
|
+
spreads.every((p) => dictSpreadSourceTs(checker, p.expression, depth + 1)));
|
|
6387
|
+
}
|
|
6388
|
+
/** The first-seen accessor key order of a shape with accessor slots. */
|
|
6389
|
+
function adoptAccessorOrder(shape, order) {
|
|
6390
|
+
if (shape !== undefined && order !== undefined && shape.accessorOrder === undefined)
|
|
6391
|
+
shape.accessorOrder = order;
|
|
6392
|
+
}
|
|
4616
6393
|
/** A refinement intersection (`Expr & { kind: "mul" }`, which the checker
|
|
4617
6394
|
* reduces to `Mul & { kind: "mul" }`) keeps the shape of the constituent it
|
|
4618
6395
|
* refines when the refinement changes no field's representation. Recursive
|
|
@@ -4626,12 +6403,12 @@ function refinedConstituentShape(widened, parts, ctx) {
|
|
|
4626
6403
|
if (!widened.isIntersectionType())
|
|
4627
6404
|
return null;
|
|
4628
6405
|
const { checker, shapes } = ctx;
|
|
4629
|
-
const names = checker.getPropertiesOfType(widened).map((prop) => prop
|
|
6406
|
+
const names = checker.getPropertiesOfType(widened).map((prop) => ts.symbolName(prop));
|
|
4630
6407
|
let found = null;
|
|
4631
6408
|
for (const part of ts.constituentTypes(widened)) {
|
|
4632
6409
|
if ((part.flags & ts.TypeFlags.Object) === 0 || shapes.inProgress.has(part))
|
|
4633
6410
|
continue;
|
|
4634
|
-
const own = new Set(checker.getPropertiesOfType(part).map((prop) => prop
|
|
6411
|
+
const own = new Set(checker.getPropertiesOfType(part).map((prop) => ts.symbolName(prop)));
|
|
4635
6412
|
if (own.size !== names.length || !names.every((name) => own.has(name)))
|
|
4636
6413
|
continue;
|
|
4637
6414
|
const mapped = mapType(part, ctx);
|
|
@@ -4651,6 +6428,29 @@ function refinedConstituentShape(widened, parts, ctx) {
|
|
|
4651
6428
|
}
|
|
4652
6429
|
return found;
|
|
4653
6430
|
}
|
|
6431
|
+
/** The optional `undefined` members widening adds to an object literal's
|
|
6432
|
+
* type for properties only its sibling literals declare (`[{ a: 1 }, { b: 2
|
|
6433
|
+
* }]` gives the first `b?: undefined`). They are never own keys of the
|
|
6434
|
+
* literal's value, so they go after the declared members, by name. Where
|
|
6435
|
+
* the checker lists them is not observable: TypeScript 7.0.2 orders them
|
|
6436
|
+
* by the literal its checker widened first, TypeScript 7.1 by the sibling
|
|
6437
|
+
* that declares them. */
|
|
6438
|
+
function wideningAddedProperties(type, props, ctx) {
|
|
6439
|
+
const added = new Set();
|
|
6440
|
+
const literal = type.getSymbol()?.declarations.find(ts.isObjectLiteralExpression);
|
|
6441
|
+
if (literal === undefined || literal.properties.nodes.some(ts.isSpreadAssignment))
|
|
6442
|
+
return added;
|
|
6443
|
+
for (const prop of props) {
|
|
6444
|
+
if ((prop.flags & ts.SymbolFlags.Optional) === 0 || prop.declarations.length === 0)
|
|
6445
|
+
continue;
|
|
6446
|
+
if (prop.declarations.some((d) => d.parent === literal))
|
|
6447
|
+
continue;
|
|
6448
|
+
if ((ctx.checker.getTypeOfSymbol(prop).flags & ts.TypeFlags.Undefined) === 0)
|
|
6449
|
+
continue;
|
|
6450
|
+
added.add(ts.symbolName(prop));
|
|
6451
|
+
}
|
|
6452
|
+
return added;
|
|
6453
|
+
}
|
|
4654
6454
|
function mapRecordTypeInner(widened, ctx) {
|
|
4655
6455
|
const { checker, shapes } = ctx;
|
|
4656
6456
|
if (checker.getConstructSignatures(widened).length > 0)
|
|
@@ -4703,8 +6503,11 @@ function mapRecordTypeInner(widened, ctx) {
|
|
|
4703
6503
|
for (const info of indexInfos) {
|
|
4704
6504
|
if (!stringKey(info.keyType) && !(info.keyType.flags & ts.TypeFlags.Number))
|
|
4705
6505
|
return null;
|
|
4706
|
-
|
|
4707
|
-
//
|
|
6506
|
+
// An `any`-valued signature (`{ [key: string]: any }`, an SDK's
|
|
6507
|
+
// `Dictionary<any>`) holds whatever the program stores: its
|
|
6508
|
+
// overflow values are checked-dynamic, exactly `Record<string,
|
|
6509
|
+
// unknown>`'s.
|
|
6510
|
+
const iv = info.type.flags & ts.TypeFlags.Any ? DYN : mapType(info.type, ctx);
|
|
4708
6511
|
if (!iv || !isSupportedIndexValue(iv))
|
|
4709
6512
|
return null;
|
|
4710
6513
|
if (v !== null && !typeEquals(v, iv))
|
|
@@ -4779,7 +6582,7 @@ function mapRecordTypeInner(widened, ctx) {
|
|
|
4779
6582
|
// stance), records of other shapes at theirs — the declaration itself is
|
|
4780
6583
|
// representable.
|
|
4781
6584
|
const anonSym = widened.getSymbol();
|
|
4782
|
-
const anonymousEmpty = (anonSym === undefined ||
|
|
6585
|
+
const anonymousEmpty = (anonSym === undefined || anonSym.declarations.length === 0) &&
|
|
4783
6586
|
!widened.isIntersectionType() &&
|
|
4784
6587
|
indexValue === undefined &&
|
|
4785
6588
|
checker.getPropertiesOfType(widened).length === 0;
|
|
@@ -4794,7 +6597,7 @@ function mapRecordTypeInner(widened, ctx) {
|
|
|
4794
6597
|
return DYN;
|
|
4795
6598
|
// Symbol-keyed records use the checked object's descriptor table. A
|
|
4796
6599
|
// checker-internal __@ name is not a string field in a native struct.
|
|
4797
|
-
if (props.some((property) => property.
|
|
6600
|
+
if (props.some((property) => ts.symbolName(property).startsWith("__@")))
|
|
4798
6601
|
return DYN;
|
|
4799
6602
|
// A computed shape with NO members is not a real empty record: inside a
|
|
4800
6603
|
// generic body `Partial<T>` resolves to no members at all (keyof T is
|
|
@@ -4821,8 +6624,7 @@ function mapRecordTypeInner(widened, ctx) {
|
|
|
4821
6624
|
indexValue === undefined &&
|
|
4822
6625
|
checker.getCallSignatures(widened).length === 0 &&
|
|
4823
6626
|
checker.getConstructSignatures(widened).length === 0 &&
|
|
4824
|
-
!(anonSym !== undefined &&
|
|
4825
|
-
checker.declarationsOf(anonSym).some((d) => ts.isObjectLiteralExpression(d)))) {
|
|
6627
|
+
!(anonSym !== undefined && anonSym.declarations.some((d) => ts.isObjectLiteralExpression(d)))) {
|
|
4826
6628
|
return DYN;
|
|
4827
6629
|
}
|
|
4828
6630
|
const fields = [];
|
|
@@ -4843,7 +6645,7 @@ function mapRecordTypeInner(widened, ctx) {
|
|
|
4843
6645
|
// their existing paths (the CJS export-table narrowing and the
|
|
4844
6646
|
// checked-dynamic fallback), and .d.ts declarations stay out with
|
|
4845
6647
|
// the rest of the lib's type worlds.
|
|
4846
|
-
const decls =
|
|
6648
|
+
const decls = p.declarations;
|
|
4847
6649
|
const getDecl = decls.find((d) => ts.isGetAccessorDeclaration(d));
|
|
4848
6650
|
const setDecl = decls.find((d) => ts.isSetAccessorDeclaration(d));
|
|
4849
6651
|
const accessorOwned = decls.length > 0 &&
|
|
@@ -4852,13 +6654,13 @@ function mapRecordTypeInner(widened, ctx) {
|
|
|
4852
6654
|
(ts.isObjectLiteralExpression(d.parent) ||
|
|
4853
6655
|
ts.isInterfaceDeclaration(d.parent) ||
|
|
4854
6656
|
d.parent.kind === ts.SyntaxKind.TypeLiteral) &&
|
|
4855
|
-
!
|
|
4856
|
-
!isJsSourceFile(
|
|
6657
|
+
!ts.getSourceFileOfNode(d).isDeclarationFile &&
|
|
6658
|
+
!isJsSourceFile(ts.getSourceFileOfNode(d)));
|
|
4857
6659
|
if (!accessorOwned || (!getDecl && !setDecl))
|
|
4858
6660
|
return null;
|
|
4859
6661
|
// Symbol-keyed accessors have no foldable literal name to fill at
|
|
4860
6662
|
// the literal — no slot to make.
|
|
4861
|
-
if (p.
|
|
6663
|
+
if (ts.symbolName(p).startsWith("__@"))
|
|
4862
6664
|
return null;
|
|
4863
6665
|
// An index-signature shape stores accessor NAMES nowhere the keyed
|
|
4864
6666
|
// read/walk machinery can answer (the overflow would miss where
|
|
@@ -4873,7 +6675,7 @@ function mapRecordTypeInner(widened, ctx) {
|
|
|
4873
6675
|
}
|
|
4874
6676
|
let writeT = null;
|
|
4875
6677
|
if (setDecl) {
|
|
4876
|
-
const param = setDecl.parameters[0];
|
|
6678
|
+
const param = setDecl.parameters.nodes[0];
|
|
4877
6679
|
if (!param)
|
|
4878
6680
|
return null;
|
|
4879
6681
|
writeT = mapType(checker.getTypeAtLocation(param), ctx);
|
|
@@ -4886,9 +6688,9 @@ function mapRecordTypeInner(widened, ctx) {
|
|
|
4886
6688
|
return null;
|
|
4887
6689
|
}
|
|
4888
6690
|
if (readT !== null || getDecl)
|
|
4889
|
-
fields.push({ name: `%get:${p
|
|
6691
|
+
fields.push({ name: `%get:${ts.symbolName(p)}`, type: funcOf([], readT ?? VOID) });
|
|
4890
6692
|
if (writeT !== null)
|
|
4891
|
-
fields.push({ name: `%set:${p
|
|
6693
|
+
fields.push({ name: `%set:${ts.symbolName(p)}`, type: funcOf([writeT], VOID) });
|
|
4892
6694
|
continue;
|
|
4893
6695
|
}
|
|
4894
6696
|
// Computed shapes carry provenance per MEMBER: a utility type over a
|
|
@@ -4896,9 +6698,9 @@ function mapRecordTypeInner(widened, ctx) {
|
|
|
4896
6698
|
// a data shape. Synthesized members (a literal-key Record's) have no
|
|
4897
6699
|
// declarations and pass.
|
|
4898
6700
|
if (computed &&
|
|
4899
|
-
|
|
4900
|
-
const sf =
|
|
4901
|
-
return sf.isDeclarationFile && !ctx.isExternalTypeFile(sf);
|
|
6701
|
+
p.declarations.some((d) => {
|
|
6702
|
+
const sf = ts.getSourceFileOfNode(d);
|
|
6703
|
+
return sf.isDeclarationFile && !ctx.isExternalTypeFile(sf) && !packageTypeFile(sf, ctx);
|
|
4902
6704
|
})) {
|
|
4903
6705
|
return null;
|
|
4904
6706
|
}
|
|
@@ -4907,9 +6709,16 @@ function mapRecordTypeInner(widened, ctx) {
|
|
|
4907
6709
|
// can hold them — see isGenericCallableMemberType): the shape keeps
|
|
4908
6710
|
// its data fields, and calls of the member monomorphize per call
|
|
4909
6711
|
// site against the defining object literal's declaration.
|
|
4910
|
-
|
|
6712
|
+
// OVERLOADED members hold their erased runtime function (see
|
|
6713
|
+
// erasedOverloadMemberType); a set that does not join fails the
|
|
6714
|
+
// shape as before.
|
|
6715
|
+
let pt = isGenericCallableMemberType(fieldTs, checker)
|
|
6716
|
+
? erasedGenericMemberType(fieldTs, ctx)
|
|
6717
|
+
: isOverloadedCallableMemberType(fieldTs, checker)
|
|
6718
|
+
? (erasedOverloadMemberType(fieldTs, ctx) ?? null)
|
|
6719
|
+
: mapType(fieldTs, ctx);
|
|
6720
|
+
if (pt === undefined)
|
|
4911
6721
|
continue;
|
|
4912
|
-
let pt = mapType(fieldTs, ctx);
|
|
4913
6722
|
// tsgo PANICS computing `readonly []` through the symbol-type query
|
|
4914
6723
|
// (the TupleType conversion — the facade's panic fence answers
|
|
4915
6724
|
// `any`), which would absorb the whole shape into the dynamic tier.
|
|
@@ -4919,11 +6728,22 @@ function mapRecordTypeInner(widened, ctx) {
|
|
|
4919
6728
|
// unit-element array; see the `[] as const` rule there).
|
|
4920
6729
|
if (pt === null &&
|
|
4921
6730
|
(fieldTs.flags & ts.TypeFlags.Any) !== 0 &&
|
|
4922
|
-
constAssertedEmptyArrayProp(p
|
|
6731
|
+
constAssertedEmptyArrayProp(p)) {
|
|
4923
6732
|
pt = arrayOf(unitOnlyUnion(ctx.unions));
|
|
4924
6733
|
}
|
|
4925
6734
|
if (pt === null && (fieldTs.flags & ts.TypeFlags.Any) !== 0)
|
|
4926
6735
|
pt = DYN;
|
|
6736
|
+
// An `any[]` field (`list: any[]` in an SDK's message type, also
|
|
6737
|
+
// optional or nullable) is the checked-dynamic array, exactly as
|
|
6738
|
+
// `unknown[]` maps; the checked-dynamic value holds the units too.
|
|
6739
|
+
// Declared members only: an object literal's inferred `any[]` member
|
|
6740
|
+
// keeps its existing story.
|
|
6741
|
+
if (pt === null &&
|
|
6742
|
+
declaredMember(p) &&
|
|
6743
|
+
(fieldTs.isUnionType() ? ts.constituentTypes(fieldTs) : [fieldTs]).every((part) => isAnyArrayType(part, checker) ||
|
|
6744
|
+
(part.flags & (ts.TypeFlags.Undefined | ts.TypeFlags.Null)) !== 0) &&
|
|
6745
|
+
!isUnitOnlyTsType(fieldTs, ctx.resolveTypeParam))
|
|
6746
|
+
pt = DYN;
|
|
4927
6747
|
// Unit-only FIELDS (`{ msg?: undefined }` — the discriminated-union
|
|
4928
6748
|
// absent-field idiom — and `{ p: undefined }` spellings): the
|
|
4929
6749
|
// unit-only union. The runtime value is the interned unit, JSON
|
|
@@ -4940,10 +6760,10 @@ function mapRecordTypeInner(widened, ctx) {
|
|
|
4940
6760
|
// A DATA property spelled like a reserved accessor slot (`{ "%get:x":
|
|
4941
6761
|
// v }` — a string-literal key): mapping it would collide with the
|
|
4942
6762
|
// accessor dispatch, so the shape stays unmapped.
|
|
4943
|
-
if (accessorSlotProp(p
|
|
6763
|
+
if (accessorSlotProp(ts.symbolName(p)) !== null)
|
|
4944
6764
|
return null;
|
|
4945
6765
|
// an options record with `signal?: AbortSignal` must not turn its
|
|
4946
|
-
fields.push({ name: p
|
|
6766
|
+
fields.push({ name: ts.symbolName(p), type: pt });
|
|
4947
6767
|
}
|
|
4948
6768
|
// getPropertiesOfType yields DECLARATION order (interface/alias/literal
|
|
4949
6769
|
// source order) — captured before the canonical sort so Object.keys/
|
|
@@ -4954,9 +6774,23 @@ function mapRecordTypeInner(widened, ctx) {
|
|
|
4954
6774
|
// indices, from folded numeric computed keys and quoted numeric keys)
|
|
4955
6775
|
// enumerate FIRST ascending, then string keys in insertion order
|
|
4956
6776
|
// (OrdinaryOwnPropertyKeys) — Object.keys/JSON/inspect all read it.
|
|
4957
|
-
const
|
|
6777
|
+
const widenedAbsent = wideningAddedProperties(widened, props, ctx);
|
|
6778
|
+
const declaredOrder = esOwnKeyOrder(fields
|
|
6779
|
+
.filter((f) => accessorSlotProp(f.name) === null && !widenedAbsent.has(f.name))
|
|
6780
|
+
.map((f) => f.name)
|
|
6781
|
+
.concat([...widenedAbsent].sort()));
|
|
6782
|
+
// With accessors: every own key in that order, an accessor property
|
|
6783
|
+
// named once for its get/set pair (the checked-dynamic copy lists it).
|
|
6784
|
+
const accessorOrder = fields.some((f) => accessorSlotProp(f.name) !== null)
|
|
6785
|
+
? esOwnKeyOrder([...new Set(fields.map((f) => accessorSlotProp(f.name)?.prop ?? f.name))])
|
|
6786
|
+
: undefined;
|
|
4958
6787
|
fields.sort((a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0));
|
|
4959
|
-
return {
|
|
6788
|
+
return {
|
|
6789
|
+
fields,
|
|
6790
|
+
...(indexValue ? { indexValue } : {}),
|
|
6791
|
+
declaredOrder,
|
|
6792
|
+
...(accessorOrder ? { accessorOrder } : {}),
|
|
6793
|
+
};
|
|
4960
6794
|
}
|
|
4961
6795
|
}
|
|
4962
6796
|
/* ── Component-fence classification (SC2009) ───────────────────────────────
|
|
@@ -4999,16 +6833,81 @@ function dynSubsumableUnionArm(arm, ctx) {
|
|
|
4999
6833
|
case "undefinedT":
|
|
5000
6834
|
case "nullT":
|
|
5001
6835
|
return true;
|
|
6836
|
+
// URL boxes BY REFERENCE (its checked-dynamic handle keeps identity,
|
|
6837
|
+
// reads and writes its members through the native accessors, answers
|
|
6838
|
+
// `instanceof URL`, and checks back out to the typed value), so it
|
|
6839
|
+
// rides the collapse beside fetch's Request/Response handles:
|
|
6840
|
+
// `string | URL | Request`, fetch's own input type under @types/node.
|
|
6841
|
+
case "url":
|
|
6842
|
+
return true;
|
|
5002
6843
|
case "record":
|
|
5003
6844
|
case "array":
|
|
6845
|
+
// `T | Promise<T>` with T bound to `unknown`: the checked-dynamic value
|
|
6846
|
+
// holds a promise by reference, so `unknown` absorbs the promise arm
|
|
6847
|
+
// exactly as the checker's own union reduction does.
|
|
6848
|
+
case "promise":
|
|
5004
6849
|
return canConvertToDyn(arm, (id) => ctx.shapes.get(id), (id) => ctx.unions.get(id));
|
|
5005
6850
|
default:
|
|
5006
6851
|
return false;
|
|
5007
6852
|
}
|
|
5008
6853
|
}
|
|
6854
|
+
/** A parameter of a function type that is the default of a type parameter
|
|
6855
|
+
* declared in node:test's standard-library declarations (MockTracker.fn's
|
|
6856
|
+
* `F extends Function = (...args: any[]) => undefined`). */
|
|
6857
|
+
function isNodeTestDefaultFunctionParam(decl, ctx) {
|
|
6858
|
+
const fnType = decl.parent;
|
|
6859
|
+
return (ts.isParameter(decl) &&
|
|
6860
|
+
fnType !== undefined &&
|
|
6861
|
+
ts.isFunctionTypeNode(fnType) &&
|
|
6862
|
+
fnType.parent !== undefined &&
|
|
6863
|
+
ts.isTypeParameterDeclaration(fnType.parent) &&
|
|
6864
|
+
fnType.parent.defaultType === fnType &&
|
|
6865
|
+
ctx.isStdlibFile(ts.getSourceFileOfNode(decl)) &&
|
|
6866
|
+
isDeclaredInAmbientModule(decl, "test"));
|
|
6867
|
+
}
|
|
6868
|
+
/** `any[]` (or `readonly any[]`): an array type whose element is `any`. */
|
|
6869
|
+
export function isAnyArrayType(t, checker) {
|
|
6870
|
+
if (!checker.isArrayType(t))
|
|
6871
|
+
return false;
|
|
6872
|
+
const elem = checker.getTypeArguments(t)[0];
|
|
6873
|
+
return elem !== undefined && (elem.flags & ts.TypeFlags.Any) !== 0;
|
|
6874
|
+
}
|
|
6875
|
+
/** The maybe-promise union rule (mapTypeInner's union rule; IR
|
|
6876
|
+
* maybePromiseUnionArmsOk): at most one promise arm, and when it has data
|
|
6877
|
+
* siblings none of them may be thenable — `await` and async `return`
|
|
6878
|
+
* dispatch on the union tag, so a data arm whose type declares `then`
|
|
6879
|
+
* would skip the thenable adoption JS performs. */
|
|
6880
|
+
function maybePromiseUnionOk(parts, arms, ctx) {
|
|
6881
|
+
if (unionContainerArmsOk(arms))
|
|
6882
|
+
return true;
|
|
6883
|
+
if (!maybePromiseUnionArmsOk(arms))
|
|
6884
|
+
return false;
|
|
6885
|
+
// A function beside a promise (`Promise<T> | (() => Promise<T>)`, the
|
|
6886
|
+
// assert.rejects argument) keeps its existing representation: callers
|
|
6887
|
+
// dispatch on callability, not on a then-able promise.
|
|
6888
|
+
if (arms.some((arm) => arm.kind === "func"))
|
|
6889
|
+
return false;
|
|
6890
|
+
return maybePromiseThenableArm(parts, ctx) === null;
|
|
6891
|
+
}
|
|
6892
|
+
/** The first non-promise constituent of a promise-armed union whose type
|
|
6893
|
+
* has a `then` member (a thenable data arm), or null. */
|
|
6894
|
+
function maybePromiseThenableArm(parts, ctx) {
|
|
6895
|
+
const { checker } = ctx;
|
|
6896
|
+
for (const part of parts) {
|
|
6897
|
+
if (part.flags & (ts.TypeFlags.Undefined | ts.TypeFlags.Void | ts.TypeFlags.Null))
|
|
6898
|
+
continue;
|
|
6899
|
+
if (mapType(part, ctx)?.kind === "promise")
|
|
6900
|
+
continue;
|
|
6901
|
+
// Primitive arms answer through their wrapper prototypes, none of
|
|
6902
|
+
// which has `then`; object arms answer through their own members.
|
|
6903
|
+
if (checker.getPropertyOfType(part, "then"))
|
|
6904
|
+
return part;
|
|
6905
|
+
}
|
|
6906
|
+
return null;
|
|
6907
|
+
}
|
|
5009
6908
|
/** Arm kinds with no home in a compiled union (mapTypeInner's union rule):
|
|
5010
6909
|
* no runtime narrowing test exists against sibling data arms. */
|
|
5011
|
-
function armHasUnionHome(arm
|
|
6910
|
+
function armHasUnionHome(arm) {
|
|
5012
6911
|
switch (arm.kind) {
|
|
5013
6912
|
case "void":
|
|
5014
6913
|
case "union":
|
|
@@ -5017,9 +6916,6 @@ function armHasUnionHome(arm, siblingCount) {
|
|
|
5017
6916
|
case "generator":
|
|
5018
6917
|
case "dyn":
|
|
5019
6918
|
return false;
|
|
5020
|
-
// Promise data siblings still lack a supported narrowing contract.
|
|
5021
|
-
case "promise":
|
|
5022
|
-
return siblingCount === 0;
|
|
5023
6919
|
default:
|
|
5024
6920
|
return true;
|
|
5025
6921
|
}
|
|
@@ -5037,11 +6933,9 @@ export function describeComponentBlocker(widened, ctx) {
|
|
|
5037
6933
|
// `interface Map` is a record shape and keeps the record stories).
|
|
5038
6934
|
const psym = widened.getSymbol();
|
|
5039
6935
|
const container = psym !== undefined &&
|
|
5040
|
-
Object.prototype.hasOwnProperty.call(STDLIB_CONTAINERS, psym
|
|
5041
|
-
|
|
5042
|
-
|
|
5043
|
-
.some((d) => ts.isInterfaceDeclaration(d) && ctx.isStdlibFile(d.getSourceFile()))
|
|
5044
|
-
? psym.name
|
|
6936
|
+
Object.prototype.hasOwnProperty.call(STDLIB_CONTAINERS, ts.symbolName(psym)) &&
|
|
6937
|
+
psym.declarations.some((d) => ts.isInterfaceDeclaration(d) && ctx.isStdlibFile(ts.getSourceFileOfNode(d)))
|
|
6938
|
+
? ts.symbolName(psym)
|
|
5045
6939
|
: undefined;
|
|
5046
6940
|
if (container !== undefined) {
|
|
5047
6941
|
const spec = STDLIB_CONTAINERS[container];
|
|
@@ -5126,10 +7020,24 @@ export function describeComponentBlocker(widened, ctx) {
|
|
|
5126
7020
|
if (!mapped) {
|
|
5127
7021
|
return `the union shape is supported, but its arm '${text(part)}' does not compile`;
|
|
5128
7022
|
}
|
|
5129
|
-
if (!armHasUnionHome(mapped
|
|
7023
|
+
if (!armHasUnionHome(mapped)) {
|
|
5130
7024
|
return `the union shape is supported, but '${text(part)}' arms have no home in a compiled union yet (no runtime narrowing test exists against sibling arms)`;
|
|
5131
7025
|
}
|
|
5132
7026
|
}
|
|
7027
|
+
const promiseArms = mappedArms.filter(({ mapped }) => mapped?.kind === "promise");
|
|
7028
|
+
if (promiseArms.length > 1) {
|
|
7029
|
+
return `the union shape is supported, but it has several promise arms ('${text(promiseArms[0].p)}' and '${text(promiseArms[1].p)}'), and a compiled union holds at most one (the union tag is the 'instanceof Promise' test)`;
|
|
7030
|
+
}
|
|
7031
|
+
if (promiseArms.length === 1 && dataArms.length > 1) {
|
|
7032
|
+
const callable = mappedArms.find(({ mapped }) => mapped?.kind === "func");
|
|
7033
|
+
if (callable) {
|
|
7034
|
+
return `the union shape is supported, but its function arm '${text(callable.p)}' sits beside a promise arm, and a maybe-promise union holds only data arms beside its promise`;
|
|
7035
|
+
}
|
|
7036
|
+
const thenable = maybePromiseThenableArm(parts, ctx);
|
|
7037
|
+
if (thenable) {
|
|
7038
|
+
return `the union shape is supported, but its arm '${text(thenable)}' declares 'then' beside a promise arm, so 'await' would have to adopt it as a thenable (a maybe-promise union's data arms must not be thenable)`;
|
|
7039
|
+
}
|
|
7040
|
+
}
|
|
5133
7041
|
return null;
|
|
5134
7042
|
}
|
|
5135
7043
|
// Single-signature, non-generic function types: a parameter type or the
|
|
@@ -5142,17 +7050,17 @@ export function describeComponentBlocker(widened, ctx) {
|
|
|
5142
7050
|
const sig = callSigs[0];
|
|
5143
7051
|
if (sig.getTypeParameters().length > 0)
|
|
5144
7052
|
return null;
|
|
5145
|
-
const sigDecl =
|
|
7053
|
+
const sigDecl = sig.declaration;
|
|
5146
7054
|
if (sigDecl !== undefined &&
|
|
5147
7055
|
ts.isFunctionLike(sigDecl) &&
|
|
5148
|
-
(runtimeParameterCount(sigDecl.parameters) !== sig.getParameters().length ||
|
|
7056
|
+
(runtimeParameterCount(sigDecl.parameters.nodes) !== sig.getParameters().length ||
|
|
5149
7057
|
bodyReadsArguments(sigDecl))) {
|
|
5150
7058
|
return `the function shape is supported, but its signature is variadic ('arguments'-reading), and a compiled signature is fixed-arity`;
|
|
5151
7059
|
}
|
|
5152
7060
|
for (const p of sig.getParameters()) {
|
|
5153
7061
|
const pTs = checker.getTypeOfSymbol(p);
|
|
5154
7062
|
if (!mapType(pTs, ctx)) {
|
|
5155
|
-
return `the function shape is supported, but its parameter '${p
|
|
7063
|
+
return `the function shape is supported, but its parameter '${ts.symbolName(p)}' has type '${text(pTs)}', which does not compile`;
|
|
5156
7064
|
}
|
|
5157
7065
|
}
|
|
5158
7066
|
const retTs = checker.getReturnTypeOfSignature(sig);
|
|
@@ -5189,28 +7097,132 @@ export function describeRecordMemberBlocker(widened, ctx) {
|
|
|
5189
7097
|
// rules (mapRecordTypeInner) — no single-member claim is honest there.
|
|
5190
7098
|
if ((p.flags & (ts.SymbolFlags.GetAccessor | ts.SymbolFlags.SetAccessor)) !== 0)
|
|
5191
7099
|
continue;
|
|
5192
|
-
if (p.
|
|
7100
|
+
if (ts.symbolName(p).startsWith("__@"))
|
|
5193
7101
|
continue;
|
|
5194
7102
|
// Computed shapes over LIBRARY members (`Readonly<Date>`): the record
|
|
5195
7103
|
// fence there is per-member PROVENANCE (mapRecordTypeInner's rule), not
|
|
5196
7104
|
// any one member's type — that story stays with the residual fence.
|
|
5197
7105
|
if (computed &&
|
|
5198
|
-
|
|
5199
|
-
const sf =
|
|
5200
|
-
return sf.isDeclarationFile && !ctx.isExternalTypeFile(sf);
|
|
7106
|
+
p.declarations.some((d) => {
|
|
7107
|
+
const sf = ts.getSourceFileOfNode(d);
|
|
7108
|
+
return sf.isDeclarationFile && !ctx.isExternalTypeFile(sf) && !packageTypeFile(sf, ctx);
|
|
5201
7109
|
})) {
|
|
5202
7110
|
return null;
|
|
5203
7111
|
}
|
|
5204
7112
|
const fieldTs = checker.getTypeOfSymbol(p);
|
|
5205
|
-
if (
|
|
7113
|
+
if (isOverloadedCallableMemberType(fieldTs, checker)) {
|
|
7114
|
+
if (erasedOverloadMemberType(fieldTs, ctx) !== undefined)
|
|
7115
|
+
continue;
|
|
7116
|
+
return `the record shape is supported, but its member '${ts.symbolName(p)}' ${describeOverloadSetBlocker(fieldTs, ctx)}`;
|
|
7117
|
+
}
|
|
7118
|
+
if (memberMaps(fieldTs, ctx, p))
|
|
5206
7119
|
continue;
|
|
5207
|
-
|
|
5208
|
-
|
|
5209
|
-
|
|
5210
|
-
|
|
5211
|
-
|
|
7120
|
+
// Name the deepest member the failure comes from (`order.deployment.
|
|
7121
|
+
// builds[].config`): a large message type otherwise points only at
|
|
7122
|
+
// its outermost member.
|
|
7123
|
+
const inner = innerBlockedMember(fieldTs, ctx, new Set());
|
|
7124
|
+
if (inner !== null && inner.path !== "") {
|
|
7125
|
+
return `the record shape is supported, but its member '${ts.symbolName(p)}${inner.path}' has type '${checker.typeToString(inner.type)}', which does not compile`;
|
|
5212
7126
|
}
|
|
7127
|
+
return `the record shape is supported, but its member '${ts.symbolName(p)}' has type '${checker.typeToString(fieldTs)}', which does not compile`;
|
|
5213
7128
|
}
|
|
5214
7129
|
return null;
|
|
5215
7130
|
}
|
|
7131
|
+
/** A member an interface, type literal or class declares (not one an
|
|
7132
|
+
* object literal's inferred type carries). */
|
|
7133
|
+
function declaredMember(member) {
|
|
7134
|
+
return (member.declarations.length > 0 &&
|
|
7135
|
+
member.declarations.every((d) => ts.isPropertySignature(d) || ts.isPropertyDeclaration(d)));
|
|
7136
|
+
}
|
|
7137
|
+
/** Whether a record member of type `fieldTs` maps, by the member rules of
|
|
7138
|
+
* mapRecordTypeInner (generic members erase; `any` and `any[]` members
|
|
7139
|
+
* are checked-dynamic; unit-only members are the unit union). Overloaded
|
|
7140
|
+
* members answer true: describeOverloadSetBlocker tells their story. */
|
|
7141
|
+
function memberMaps(fieldTs, ctx, member) {
|
|
7142
|
+
const { checker } = ctx;
|
|
7143
|
+
if (isOverloadedCallableMemberType(fieldTs, checker))
|
|
7144
|
+
return true;
|
|
7145
|
+
const pt = isGenericCallableMemberType(fieldTs, checker)
|
|
7146
|
+
? erasedGenericMemberType(fieldTs, ctx)
|
|
7147
|
+
: mapType(fieldTs, ctx);
|
|
7148
|
+
if (pt === undefined)
|
|
7149
|
+
return true;
|
|
7150
|
+
if (pt === null && (fieldTs.flags & ts.TypeFlags.Any) !== 0)
|
|
7151
|
+
return true;
|
|
7152
|
+
if (pt === null &&
|
|
7153
|
+
(member === undefined || declaredMember(member)) &&
|
|
7154
|
+
(fieldTs.isUnionType() ? ts.constituentTypes(fieldTs) : [fieldTs]).every((part) => isAnyArrayType(part, checker) ||
|
|
7155
|
+
(part.flags & (ts.TypeFlags.Undefined | ts.TypeFlags.Null)) !== 0) &&
|
|
7156
|
+
!isUnitOnlyTsType(fieldTs, ctx.resolveTypeParam))
|
|
7157
|
+
return true;
|
|
7158
|
+
if (pt?.kind === "void" && isUnitOnlyTsType(fieldTs, ctx.resolveTypeParam))
|
|
7159
|
+
return true;
|
|
7160
|
+
return pt !== null && pt.kind !== "void";
|
|
7161
|
+
}
|
|
7162
|
+
/** The member path inside the unmapped type `t` that its failure comes
|
|
7163
|
+
* from, and that member's type: `.name` steps into record members, `[]`
|
|
7164
|
+
* into array elements, `()` into a function's return; union arms and
|
|
7165
|
+
* promise payloads are transparent. The empty path means `t` itself is
|
|
7166
|
+
* the blocker; null means `t` maps (or is `any`). */
|
|
7167
|
+
function innerBlockedMember(t, ctx, seen) {
|
|
7168
|
+
const { checker } = ctx;
|
|
7169
|
+
// `any` is no component to name: the member holding it is the blocker.
|
|
7170
|
+
if ((t.flags & ts.TypeFlags.Any) !== 0 || mapType(t, ctx) !== null)
|
|
7171
|
+
return null;
|
|
7172
|
+
const here = { path: "", type: t };
|
|
7173
|
+
if (seen.has(t) || seen.size >= 16)
|
|
7174
|
+
return here;
|
|
7175
|
+
seen.add(t);
|
|
7176
|
+
const step = (prefix, inner) => {
|
|
7177
|
+
const found = innerBlockedMember(inner, ctx, seen);
|
|
7178
|
+
return found === null ? here : { path: prefix + found.path, type: found.type };
|
|
7179
|
+
};
|
|
7180
|
+
if (t.isUnionType()) {
|
|
7181
|
+
const UNIT = ts.TypeFlags.Undefined | ts.TypeFlags.Void | ts.TypeFlags.Null;
|
|
7182
|
+
for (const part of ts.constituentTypes(t)) {
|
|
7183
|
+
if ((part.flags & UNIT) !== 0 || mapType(part, ctx) !== null)
|
|
7184
|
+
continue;
|
|
7185
|
+
return step("", part);
|
|
7186
|
+
}
|
|
7187
|
+
return here;
|
|
7188
|
+
}
|
|
7189
|
+
if ((t.flags & ts.TypeFlags.Object) === 0)
|
|
7190
|
+
return here;
|
|
7191
|
+
if (checker.isArrayType(t)) {
|
|
7192
|
+
const elem = checker.getTypeArguments(t)[0];
|
|
7193
|
+
return elem === undefined ? here : step("[]", elem);
|
|
7194
|
+
}
|
|
7195
|
+
const symbol = t.getSymbol();
|
|
7196
|
+
if (symbol !== undefined &&
|
|
7197
|
+
ts.symbolName(symbol) === "Promise" &&
|
|
7198
|
+
symbol.declarations.some((d) => ctx.isStdlibFile(d.getSourceFile()))) {
|
|
7199
|
+
const payload = checker.getTypeArguments(t)[0];
|
|
7200
|
+
return payload === undefined ? here : step("", payload);
|
|
7201
|
+
}
|
|
7202
|
+
const calls = checker.getCallSignatures(t);
|
|
7203
|
+
if (calls.length === 1) {
|
|
7204
|
+
const sig = calls[0];
|
|
7205
|
+
if (sig.getTypeParameters().length > 0)
|
|
7206
|
+
return here;
|
|
7207
|
+
if (sig.getParameters().some((p) => mapType(checker.getTypeOfSymbol(p), ctx) === null))
|
|
7208
|
+
return here;
|
|
7209
|
+
return step("()", checker.getReturnTypeOfSignature(sig));
|
|
7210
|
+
}
|
|
7211
|
+
if (calls.length > 0 ||
|
|
7212
|
+
checker.getConstructSignatures(t).length > 0 ||
|
|
7213
|
+
checker.isTupleType(t) ||
|
|
7214
|
+
checker.getIndexInfosOfType(t).length > 0)
|
|
7215
|
+
return here;
|
|
7216
|
+
for (const p of checker.getPropertiesOfType(t)) {
|
|
7217
|
+
if ((p.flags & (ts.SymbolFlags.GetAccessor | ts.SymbolFlags.SetAccessor)) !== 0)
|
|
7218
|
+
continue;
|
|
7219
|
+
if (ts.symbolName(p).startsWith("__@"))
|
|
7220
|
+
continue;
|
|
7221
|
+
const fieldTs = checker.getTypeOfSymbol(p);
|
|
7222
|
+
if (memberMaps(fieldTs, ctx, p))
|
|
7223
|
+
continue;
|
|
7224
|
+
return step(`.${ts.symbolName(p)}`, fieldTs);
|
|
7225
|
+
}
|
|
7226
|
+
return here;
|
|
7227
|
+
}
|
|
5216
7228
|
//# sourceMappingURL=type-mapper.js.map
|