@scriptc/compiler 0.3.5 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ambient/scriptc-node-fallback.d.ts +960 -82
- package/ambient/scriptc.d.ts +134 -0
- package/dist/backend/cycle-analysis.d.ts +1 -1
- package/dist/backend/cycle-analysis.js +1 -0
- package/dist/backend/cycle-analysis.js.map +1 -1
- package/dist/backend/cycle-analysis.test.js +13 -1
- package/dist/backend/cycle-analysis.test.js.map +1 -1
- package/dist/backend/cycle-mutability.js +16 -5
- package/dist/backend/cycle-mutability.js.map +1 -1
- package/dist/backend/executable-features.js +13 -0
- package/dist/backend/executable-features.js.map +1 -1
- package/dist/backend/immutability.test.js +1 -1
- package/dist/backend/library-pack.js +6 -0
- package/dist/backend/library-pack.js.map +1 -1
- package/dist/backend/llvm/alloc.d.ts +41 -4
- package/dist/backend/llvm/alloc.js +138 -7
- package/dist/backend/llvm/alloc.js.map +1 -1
- package/dist/backend/llvm/alloc.test.js +30 -1
- package/dist/backend/llvm/alloc.test.js.map +1 -1
- package/dist/backend/llvm/appended-array-literals.test.js +1 -1
- package/dist/backend/llvm/array-search.test.js +1 -1
- package/dist/backend/llvm/blocks.d.ts +8 -0
- package/dist/backend/llvm/blocks.js +43 -1
- package/dist/backend/llvm/blocks.js.map +1 -1
- package/dist/backend/llvm/blocks.test.js +22 -1
- package/dist/backend/llvm/blocks.test.js.map +1 -1
- package/dist/backend/llvm/byte-numbers.js +15 -5
- package/dist/backend/llvm/byte-numbers.js.map +1 -1
- package/dist/backend/llvm/bytes-alias.d.ts +14 -0
- package/dist/backend/llvm/bytes-alias.js +20 -0
- package/dist/backend/llvm/bytes-alias.js.map +1 -0
- package/dist/backend/llvm/bytes-loop-versions.d.ts +86 -0
- package/dist/backend/llvm/bytes-loop-versions.js +506 -0
- package/dist/backend/llvm/bytes-loop-versions.js.map +1 -0
- package/dist/backend/llvm/bytes-loop-versions.test.d.ts +1 -0
- package/dist/backend/llvm/bytes-loop-versions.test.js +244 -0
- package/dist/backend/llvm/bytes-loop-versions.test.js.map +1 -0
- package/dist/backend/llvm/call-lifetimes.js +50 -1
- package/dist/backend/llvm/call-lifetimes.js.map +1 -1
- package/dist/backend/llvm/call-lifetimes.test.js +34 -0
- package/dist/backend/llvm/call-lifetimes.test.js.map +1 -1
- package/dist/backend/llvm/checked-narrows.test.js +1 -1
- package/dist/backend/llvm/checked-value-lifetimes.js +4 -1
- package/dist/backend/llvm/checked-value-lifetimes.js.map +1 -1
- package/dist/backend/llvm/classes.d.ts +11 -0
- package/dist/backend/llvm/classes.js +71 -14
- package/dist/backend/llvm/classes.js.map +1 -1
- package/dist/backend/llvm/classes.test.js +58 -8
- package/dist/backend/llvm/classes.test.js.map +1 -1
- package/dist/backend/llvm/common.js +1 -0
- package/dist/backend/llvm/common.js.map +1 -1
- package/dist/backend/llvm/constant-callbacks.d.ts +5 -1
- package/dist/backend/llvm/constant-callbacks.js +55 -12
- package/dist/backend/llvm/constant-callbacks.js.map +1 -1
- package/dist/backend/llvm/constant-callbacks.test.js +88 -1
- package/dist/backend/llvm/constant-callbacks.test.js.map +1 -1
- package/dist/backend/llvm/counted-loops.d.ts +4 -0
- package/dist/backend/llvm/counted-loops.js +37 -0
- package/dist/backend/llvm/counted-loops.js.map +1 -1
- package/dist/backend/llvm/dense-array-access.d.ts +12 -3
- package/dist/backend/llvm/dense-array-access.js +72 -14
- package/dist/backend/llvm/dense-array-access.js.map +1 -1
- package/dist/backend/llvm/dense-array-access.test.js +59 -3
- package/dist/backend/llvm/dense-array-access.test.js.map +1 -1
- package/dist/backend/llvm/dense-array-loops.d.ts +51 -0
- package/dist/backend/llvm/dense-array-loops.js +162 -0
- package/dist/backend/llvm/dense-array-loops.js.map +1 -0
- package/dist/backend/llvm/dense-array-loops.test.d.ts +1 -0
- package/dist/backend/llvm/dense-array-loops.test.js +128 -0
- package/dist/backend/llvm/dense-array-loops.test.js.map +1 -0
- package/dist/backend/llvm/dyn-handle-tags.test.d.ts +1 -0
- package/dist/backend/llvm/dyn-handle-tags.test.js +38 -0
- package/dist/backend/llvm/dyn-handle-tags.test.js.map +1 -0
- package/dist/backend/llvm/dyn.d.ts +28 -4
- package/dist/backend/llvm/dyn.js +324 -179
- package/dist/backend/llvm/dyn.js.map +1 -1
- package/dist/backend/llvm/emit-function.d.ts +64 -0
- package/dist/backend/llvm/emit-function.js +1190 -0
- package/dist/backend/llvm/emit-function.js.map +1 -0
- package/dist/backend/llvm/emit-module.d.ts +24 -0
- package/dist/backend/llvm/emit-module.js +1535 -0
- package/dist/backend/llvm/emit-module.js.map +1 -0
- package/dist/backend/llvm/emit-statements.d.ts +58 -0
- package/dist/backend/llvm/emit-statements.js +1964 -0
- package/dist/backend/llvm/emit-statements.js.map +1 -0
- package/dist/backend/llvm/emitter.d.ts +576 -268
- package/dist/backend/llvm/emitter.js +801 -4447
- package/dist/backend/llvm/emitter.js.map +1 -1
- package/dist/backend/llvm/emitter.test.js +57 -3
- package/dist/backend/llvm/emitter.test.js.map +1 -1
- package/dist/backend/llvm/expr-async.js +73 -46
- package/dist/backend/llvm/expr-async.js.map +1 -1
- package/dist/backend/llvm/expr-async.test.js +1 -1
- package/dist/backend/llvm/expr-bytes.d.ts +2 -0
- package/dist/backend/llvm/expr-bytes.js +76 -29
- package/dist/backend/llvm/expr-bytes.js.map +1 -1
- package/dist/backend/llvm/expr-callbacks.d.ts +6 -2
- package/dist/backend/llvm/expr-callbacks.js +48 -11
- package/dist/backend/llvm/expr-callbacks.js.map +1 -1
- package/dist/backend/llvm/expr-calls.d.ts +1 -1
- package/dist/backend/llvm/expr-calls.js +71 -53
- package/dist/backend/llvm/expr-calls.js.map +1 -1
- package/dist/backend/llvm/expr-calls.test.js +1 -1
- package/dist/backend/llvm/expr-containers.js +39 -15
- package/dist/backend/llvm/expr-containers.js.map +1 -1
- package/dist/backend/llvm/expr-control.js +16 -16
- package/dist/backend/llvm/expr-control.js.map +1 -1
- package/dist/backend/llvm/expr-dispatch.js +1 -0
- package/dist/backend/llvm/expr-dispatch.js.map +1 -1
- package/dist/backend/llvm/expr-dynamic.d.ts +3 -0
- package/dist/backend/llvm/expr-dynamic.js +92 -63
- package/dist/backend/llvm/expr-dynamic.js.map +1 -1
- package/dist/backend/llvm/expr-primitives.d.ts +1 -1
- package/dist/backend/llvm/expr-primitives.js +132 -25
- package/dist/backend/llvm/expr-primitives.js.map +1 -1
- package/dist/backend/llvm/expr-primitives.test.js +2 -2
- package/dist/backend/llvm/expr-records.d.ts +1 -1
- package/dist/backend/llvm/expr-records.js +32 -11
- package/dist/backend/llvm/expr-records.js.map +1 -1
- package/dist/backend/llvm/expr-stream-bridges.js +54 -12
- package/dist/backend/llvm/expr-stream-bridges.js.map +1 -1
- package/dist/backend/llvm/expr-stream-bridges.test.js +2 -2
- package/dist/backend/llvm/expr-stream-callbacks.js +22 -1
- package/dist/backend/llvm/expr-stream-callbacks.js.map +1 -1
- package/dist/backend/llvm/int32-abi.test.js +2 -2
- package/dist/backend/llvm/integer-clones.test.js +3 -3
- package/dist/backend/llvm/integer-remainder.d.ts +34 -13
- package/dist/backend/llvm/integer-remainder.js +156 -22
- package/dist/backend/llvm/integer-remainder.js.map +1 -1
- package/dist/backend/llvm/intern-tables.test.js +1 -1
- package/dist/backend/llvm/jsval-encoding.d.ts +21 -0
- package/dist/backend/llvm/jsval-encoding.js +20 -0
- package/dist/backend/llvm/jsval-encoding.js.map +1 -0
- package/dist/backend/llvm/jsval.d.ts +12 -0
- package/dist/backend/llvm/jsval.js +488 -0
- package/dist/backend/llvm/jsval.js.map +1 -0
- package/dist/backend/llvm/lazy-captures.d.ts +12 -2
- package/dist/backend/llvm/lazy-captures.js +39 -17
- package/dist/backend/llvm/lazy-captures.js.map +1 -1
- package/dist/backend/llvm/lib-abi.js +1 -1
- package/dist/backend/llvm/lib-abi.js.map +1 -1
- package/dist/backend/llvm/lib-connect.js +1 -1
- package/dist/backend/llvm/lib-connect.js.map +1 -1
- package/dist/backend/llvm/lib-datagram.js +14 -8
- package/dist/backend/llvm/lib-datagram.js.map +1 -1
- package/dist/backend/llvm/lib-dispatch.js +217 -24
- package/dist/backend/llvm/lib-dispatch.js.map +1 -1
- package/dist/backend/llvm/lib-filesystem.js +102 -13
- package/dist/backend/llvm/lib-filesystem.js.map +1 -1
- package/dist/backend/llvm/lib-http2.js +3 -3
- package/dist/backend/llvm/lib-http2.js.map +1 -1
- package/dist/backend/llvm/lib-lookup.js +2 -2
- package/dist/backend/llvm/lib-lookup.js.map +1 -1
- package/dist/backend/llvm/lib-network.js +77 -25
- package/dist/backend/llvm/lib-network.js.map +1 -1
- package/dist/backend/llvm/lib-process.js +100 -50
- package/dist/backend/llvm/lib-process.js.map +1 -1
- package/dist/backend/llvm/lib-shared.d.ts +12 -0
- package/dist/backend/llvm/lib-shared.js +229 -5
- package/dist/backend/llvm/lib-shared.js.map +1 -1
- package/dist/backend/llvm/lib-stream.js +46 -16
- package/dist/backend/llvm/lib-stream.js.map +1 -1
- package/dist/backend/llvm/lib-test.js +57 -8
- package/dist/backend/llvm/lib-test.js.map +1 -1
- package/dist/backend/llvm/lib-tls.js +4 -9
- package/dist/backend/llvm/lib-tls.js.map +1 -1
- package/dist/backend/llvm/local-array-reads.js +2 -2
- package/dist/backend/llvm/local-array-reads.test.js +1 -1
- package/dist/backend/llvm/local-extents.d.ts +19 -0
- package/dist/backend/llvm/local-extents.js +169 -0
- package/dist/backend/llvm/local-extents.js.map +1 -0
- package/dist/backend/llvm/local-extents.test.d.ts +1 -0
- package/dist/backend/llvm/local-extents.test.js +92 -0
- package/dist/backend/llvm/local-extents.test.js.map +1 -0
- package/dist/backend/llvm/local-union-storage.js +7 -7
- package/dist/backend/llvm/local-union-storage.js.map +1 -1
- package/dist/backend/llvm/local-union-storage.test.js +2 -2
- package/dist/backend/llvm/map-entry-fusion.test.js +1 -1
- package/dist/backend/llvm/map-number-lookup.js +2 -2
- package/dist/backend/llvm/map-number-lookup.test.js +2 -2
- package/dist/backend/llvm/map-read-lifetimes.test.js +2 -2
- package/dist/backend/llvm/narrow-guards.d.ts +38 -0
- package/dist/backend/llvm/narrow-guards.js +151 -0
- package/dist/backend/llvm/narrow-guards.js.map +1 -0
- package/dist/backend/llvm/nullable-unions.d.ts +70 -9
- package/dist/backend/llvm/nullable-unions.js +105 -6
- package/dist/backend/llvm/nullable-unions.js.map +1 -1
- package/dist/backend/llvm/nullable-unions.test.d.ts +1 -0
- package/dist/backend/llvm/nullable-unions.test.js +65 -0
- package/dist/backend/llvm/nullable-unions.test.js.map +1 -0
- package/dist/backend/llvm/publish.d.ts +4 -0
- package/dist/backend/llvm/publish.js +14 -2
- package/dist/backend/llvm/publish.js.map +1 -1
- package/dist/backend/llvm/publish.test.js +1 -1
- package/dist/backend/llvm/receivers.d.ts +31 -0
- package/dist/backend/llvm/receivers.js +395 -0
- package/dist/backend/llvm/receivers.js.map +1 -0
- package/dist/backend/llvm/record-results.d.ts +13 -2
- package/dist/backend/llvm/record-results.js +66 -6
- package/dist/backend/llvm/record-results.js.map +1 -1
- package/dist/backend/llvm/reference-effects.js +9 -0
- package/dist/backend/llvm/reference-effects.js.map +1 -1
- package/dist/backend/llvm/reference-writes.d.ts +4 -0
- package/dist/backend/llvm/reference-writes.js +143 -6
- package/dist/backend/llvm/reference-writes.js.map +1 -1
- package/dist/backend/llvm/reference-writes.test.d.ts +1 -0
- package/dist/backend/llvm/reference-writes.test.js +88 -0
- package/dist/backend/llvm/reference-writes.test.js.map +1 -0
- package/dist/backend/llvm/regex-matchers.d.ts +8 -0
- package/dist/backend/llvm/regex-matchers.js +33 -0
- package/dist/backend/llvm/regex-matchers.js.map +1 -1
- package/dist/backend/llvm/regex-matchers.test.js +23 -1
- package/dist/backend/llvm/regex-matchers.test.js.map +1 -1
- package/dist/backend/llvm/regions.d.ts +1 -1
- package/dist/backend/llvm/regions.js +9 -6
- package/dist/backend/llvm/regions.js.map +1 -1
- package/dist/backend/llvm/regions.test.js +1 -1
- package/dist/backend/llvm/shapes.d.ts +69 -43
- package/dist/backend/llvm/shapes.js +285 -21
- package/dist/backend/llvm/shapes.js.map +1 -1
- package/dist/backend/llvm/shapes.test.js +37 -3
- package/dist/backend/llvm/shapes.test.js.map +1 -1
- package/dist/backend/llvm/speculative-integers.d.ts +74 -0
- package/dist/backend/llvm/speculative-integers.js +571 -0
- package/dist/backend/llvm/speculative-integers.js.map +1 -0
- package/dist/backend/llvm/speculative-integers.test.d.ts +1 -0
- package/dist/backend/llvm/speculative-integers.test.js +148 -0
- package/dist/backend/llvm/speculative-integers.test.js.map +1 -0
- package/dist/backend/llvm/split-loops.js +2 -2
- package/dist/backend/llvm/split-loops.js.map +1 -1
- package/dist/backend/llvm/stack-objects.d.ts +26 -6
- package/dist/backend/llvm/stack-objects.js +133 -10
- package/dist/backend/llvm/stack-objects.js.map +1 -1
- package/dist/backend/llvm/stack-objects.test.js +55 -1
- package/dist/backend/llvm/stack-objects.test.js.map +1 -1
- package/dist/backend/llvm/stack-unions.test.js +1 -1
- package/dist/backend/llvm/string-construction.test.js +1 -1
- package/dist/backend/llvm/string-lifetimes.test.js +15 -14
- package/dist/backend/llvm/string-lifetimes.test.js.map +1 -1
- package/dist/backend/llvm/string-slices.d.ts +25 -0
- package/dist/backend/llvm/string-slices.js +207 -1
- package/dist/backend/llvm/string-slices.js.map +1 -1
- package/dist/backend/llvm/string-slices.test.js +139 -2
- package/dist/backend/llvm/string-slices.test.js.map +1 -1
- package/dist/backend/llvm/switch-dispatch.test.js +2 -2
- package/dist/backend/llvm/thread-slots.d.ts +5 -0
- package/dist/backend/llvm/thread-slots.js +142 -0
- package/dist/backend/llvm/thread-slots.js.map +1 -0
- package/dist/backend/llvm/thread-slots.test.d.ts +1 -0
- package/dist/backend/llvm/thread-slots.test.js +110 -0
- package/dist/backend/llvm/thread-slots.test.js.map +1 -0
- package/dist/backend/llvm/union-repr.d.ts +7 -7
- package/dist/backend/llvm/union-repr.js +18 -2
- package/dist/backend/llvm/union-repr.js.map +1 -1
- package/dist/backend/llvm/union-retype.test.js +17 -3
- package/dist/backend/llvm/union-retype.test.js.map +1 -1
- package/dist/backend/llvm/walkers.d.ts +2 -2
- package/dist/backend/llvm/walkers.js +51 -26
- package/dist/backend/llvm/walkers.js.map +1 -1
- package/dist/backend/llvm/wasm-modules.d.ts +16 -0
- package/dist/backend/llvm/wasm-modules.js +66 -0
- package/dist/backend/llvm/wasm-modules.js.map +1 -0
- package/dist/backend/llvm/wrapping-sums.d.ts +7 -0
- package/dist/backend/llvm/wrapping-sums.js +11 -3
- package/dist/backend/llvm/wrapping-sums.js.map +1 -1
- package/dist/backend/mangle.d.ts +7 -0
- package/dist/backend/mangle.js +11 -0
- package/dist/backend/mangle.js.map +1 -1
- package/dist/backend/may-throw.d.ts +3 -0
- package/dist/backend/may-throw.js +6 -2
- package/dist/backend/may-throw.js.map +1 -1
- package/dist/backend/may-throw.test.js +1 -1
- package/dist/backend/native/contracts.d.ts +37 -0
- package/dist/backend/native/executable.js +192 -134
- package/dist/backend/native/executable.js.map +1 -1
- package/dist/backend/native/library.js +1 -0
- package/dist/backend/native/library.js.map +1 -1
- package/dist/backend/native/runtime-inputs.d.ts +1 -1
- package/dist/backend/native/runtime-inputs.js +2 -0
- package/dist/backend/native/runtime-inputs.js.map +1 -1
- package/dist/backend/native-link-info-core.d.ts +30 -0
- package/dist/backend/native-link-info-core.js.map +1 -1
- package/dist/backend/publication.test.js +1 -1
- package/dist/backend/runtime-pack-core.d.ts +9 -1
- package/dist/backend/runtime-pack-core.js +10 -1
- package/dist/backend/runtime-pack-core.js.map +1 -1
- package/dist/backend/runtime-pack-native.js +1 -1
- package/dist/backend/runtime-pack-native.js.map +1 -1
- package/dist/backend/runtime-pack-native.test.d.ts +1 -0
- package/dist/backend/runtime-pack-native.test.js +31 -0
- package/dist/backend/runtime-pack-native.test.js.map +1 -0
- package/dist/backend/runtime-pack-targets.test.js +5 -0
- package/dist/backend/runtime-pack-targets.test.js.map +1 -1
- package/dist/backend/runtime-pack.d.ts +7 -3
- package/dist/backend/runtime-pack.js +12 -6
- package/dist/backend/runtime-pack.js.map +1 -1
- package/dist/backend/runtime-pack.test.js +20 -6
- package/dist/backend/runtime-pack.test.js.map +1 -1
- package/dist/backend/stack-observations.d.ts +22 -0
- package/dist/backend/stack-observations.js +382 -0
- package/dist/backend/stack-observations.js.map +1 -0
- package/dist/backend/stack-observations.test.d.ts +1 -0
- package/dist/backend/stack-observations.test.js +233 -0
- package/dist/backend/stack-observations.test.js.map +1 -0
- package/dist/backend/target-diagnostics.js +8 -0
- package/dist/backend/target-diagnostics.js.map +1 -1
- package/dist/backend/target-diagnostics.test.js +1 -1
- package/dist/backend/warm-cache.js +5 -0
- package/dist/backend/warm-cache.js.map +1 -1
- package/dist/backend/young-nursery.d.ts +7 -0
- package/dist/backend/young-nursery.js +10 -0
- package/dist/backend/young-nursery.js.map +1 -0
- package/dist/cli/command.js +44 -4
- package/dist/cli/command.js.map +1 -1
- package/dist/cli/usage.d.ts +11 -1
- package/dist/cli/usage.js +20 -1
- package/dist/cli/usage.js.map +1 -1
- package/dist/compat/fetch-profile.js +10 -1
- package/dist/compat/fetch-profile.js.map +1 -1
- package/dist/compile-types.d.ts +13 -0
- package/dist/contracts/check.js +25 -6
- package/dist/contracts/check.js.map +1 -1
- package/dist/contracts/int32-elements.d.ts +115 -0
- package/dist/contracts/int32-elements.js +1179 -0
- package/dist/contracts/int32-elements.js.map +1 -0
- package/dist/coverage/report.d.ts +16 -0
- package/dist/coverage/report.js +182 -1
- package/dist/coverage/report.js.map +1 -1
- package/dist/coverage/surface-manifest.js +19 -6
- package/dist/coverage/surface-manifest.js.map +1 -1
- package/dist/coverage/verdict-cache.d.ts +2 -0
- package/dist/coverage/verdict-cache.js +12 -0
- package/dist/coverage/verdict-cache.js.map +1 -1
- package/dist/coverage/verdict-cache.test.js +2 -1
- package/dist/coverage/verdict-cache.test.js.map +1 -1
- package/dist/diagnostics/diagnostic.d.ts +11 -7
- package/dist/diagnostics/diagnostic.js +35 -23
- package/dist/diagnostics/diagnostic.js.map +1 -1
- package/dist/diagnostics/envelope.d.ts +39 -2
- package/dist/diagnostics/envelope.js.map +1 -1
- package/dist/diagnostics/render.d.ts +7 -0
- package/dist/diagnostics/render.js +50 -13
- package/dist/diagnostics/render.js.map +1 -1
- package/dist/diagnostics/render.test.d.ts +1 -0
- package/dist/diagnostics/render.test.js +49 -0
- package/dist/diagnostics/render.test.js.map +1 -0
- package/dist/executable/executable-cache.d.ts +17 -0
- package/dist/executable/executable-cache.js +13 -1
- package/dist/executable/executable-cache.js.map +1 -1
- package/dist/executable/executable-cache.test.js +7 -1
- package/dist/executable/executable-cache.test.js.map +1 -1
- package/dist/executable/prepare.js +2 -1
- package/dist/executable/prepare.js.map +1 -1
- package/dist/frontend/analysis.js +6 -1
- package/dist/frontend/analysis.js.map +1 -1
- package/dist/frontend/builtin-modules.d.ts +16 -2
- package/dist/frontend/builtin-modules.js +40 -7
- package/dist/frontend/builtin-modules.js.map +1 -1
- package/dist/frontend/cjs-syntax.js +52 -51
- package/dist/frontend/cjs-syntax.js.map +1 -1
- package/dist/frontend/contract-types.d.ts +3 -0
- package/dist/frontend/contract-types.js +36 -7
- package/dist/frontend/contract-types.js.map +1 -1
- package/dist/frontend/experimental-import.d.ts +5 -1
- package/dist/frontend/experimental-import.js +26 -7
- package/dist/frontend/experimental-import.js.map +1 -1
- package/dist/frontend/fork-target.js +20 -22
- package/dist/frontend/fork-target.js.map +1 -1
- package/dist/frontend/fork-target.test.js +2 -1
- package/dist/frontend/fork-target.test.js.map +1 -1
- package/dist/frontend/function-completion.js +6 -6
- package/dist/frontend/function-completion.js.map +1 -1
- package/dist/frontend/helper-tokens.js +15 -3
- package/dist/frontend/helper-tokens.js.map +1 -1
- package/dist/frontend/helper-tokens.test.js +7 -1
- package/dist/frontend/helper-tokens.test.js.map +1 -1
- package/dist/frontend/inferred-js-diagnostics.js +14 -17
- package/dist/frontend/inferred-js-diagnostics.js.map +1 -1
- package/dist/frontend/input-tracker.d.ts +3 -0
- package/dist/frontend/input-tracker.js +32 -3
- package/dist/frontend/input-tracker.js.map +1 -1
- package/dist/frontend/lib-contract.js +36 -32
- package/dist/frontend/lib-contract.js.map +1 -1
- package/dist/frontend/lib-exports.js +3 -3
- package/dist/frontend/lib-exports.js.map +1 -1
- package/dist/frontend/lowering/array-values.d.ts +8 -3
- package/dist/frontend/lowering/array-values.js +60 -11
- package/dist/frontend/lowering/array-values.js.map +1 -1
- package/dist/frontend/lowering/assert-instances.js +4 -4
- package/dist/frontend/lowering/assert-instances.js.map +1 -1
- package/dist/frontend/lowering/assertion-identity.d.ts +12 -0
- package/dist/frontend/lowering/assertion-identity.js +70 -0
- package/dist/frontend/lowering/assertion-identity.js.map +1 -0
- package/dist/frontend/lowering/assertion-members.d.ts +28 -0
- package/dist/frontend/lowering/assertion-members.js +185 -0
- package/dist/frontend/lowering/assertion-members.js.map +1 -0
- package/dist/frontend/lowering/binding-analysis.js +27 -20
- package/dist/frontend/lowering/binding-analysis.js.map +1 -1
- package/dist/frontend/lowering/builtin-calls.js +72 -4
- package/dist/frontend/lowering/builtin-calls.js.map +1 -1
- package/dist/frontend/lowering/builtin-function-fences.d.ts +14 -0
- package/dist/frontend/lowering/builtin-function-fences.js +42 -0
- package/dist/frontend/lowering/builtin-function-fences.js.map +1 -0
- package/dist/frontend/lowering/builtins/arguments.js +1 -1
- package/dist/frontend/lowering/builtins/arguments.js.map +1 -1
- package/dist/frontend/lowering/builtins/async-context.js +53 -52
- package/dist/frontend/lowering/builtins/async-context.js.map +1 -1
- package/dist/frontend/lowering/builtins/atomics.js +6 -6
- package/dist/frontend/lowering/builtins/atomics.js.map +1 -1
- package/dist/frontend/lowering/builtins/blob.js +8 -6
- package/dist/frontend/lowering/builtins/blob.js.map +1 -1
- package/dist/frontend/lowering/builtins/builtin-class-dyn.d.ts +23 -0
- package/dist/frontend/lowering/builtins/builtin-class-dyn.js +156 -0
- package/dist/frontend/lowering/builtins/builtin-class-dyn.js.map +1 -0
- package/dist/frontend/lowering/builtins/callable-aliases.js +45 -6
- package/dist/frontend/lowering/builtins/callable-aliases.js.map +1 -1
- package/dist/frontend/lowering/builtins/child-process-async.js +7 -7
- package/dist/frontend/lowering/builtins/child-process-async.js.map +1 -1
- package/dist/frontend/lowering/builtins/child-process-methods.d.ts +6 -4
- package/dist/frontend/lowering/builtins/child-process-methods.js +310 -57
- package/dist/frontend/lowering/builtins/child-process-methods.js.map +1 -1
- package/dist/frontend/lowering/builtins/child-process-sync.js +16 -10
- package/dist/frontend/lowering/builtins/child-process-sync.js.map +1 -1
- package/dist/frontend/lowering/builtins/child-process.d.ts +6 -4
- package/dist/frontend/lowering/builtins/child-process.js +85 -61
- package/dist/frontend/lowering/builtins/child-process.js.map +1 -1
- package/dist/frontend/lowering/builtins/class-values.d.ts +60 -0
- package/dist/frontend/lowering/builtins/class-values.js +226 -0
- package/dist/frontend/lowering/builtins/class-values.js.map +1 -0
- package/dist/frontend/lowering/builtins/compression.d.ts +18 -0
- package/dist/frontend/lowering/builtins/compression.js +230 -52
- package/dist/frontend/lowering/builtins/compression.js.map +1 -1
- package/dist/frontend/lowering/builtins/constants.d.ts +9 -1
- package/dist/frontend/lowering/builtins/constants.js +28 -7
- package/dist/frontend/lowering/builtins/constants.js.map +1 -1
- package/dist/frontend/lowering/builtins/crypto.d.ts +19 -0
- package/dist/frontend/lowering/builtins/crypto.js +223 -38
- package/dist/frontend/lowering/builtins/crypto.js.map +1 -1
- package/dist/frontend/lowering/builtins/dates.d.ts +7 -1
- package/dist/frontend/lowering/builtins/dates.js +92 -16
- package/dist/frontend/lowering/builtins/dates.js.map +1 -1
- package/dist/frontend/lowering/builtins/disposable-stack.d.ts +18 -0
- package/dist/frontend/lowering/builtins/disposable-stack.js +137 -0
- package/dist/frontend/lowering/builtins/disposable-stack.js.map +1 -0
- package/dist/frontend/lowering/builtins/environment.js +3 -3
- package/dist/frontend/lowering/builtins/environment.js.map +1 -1
- package/dist/frontend/lowering/builtins/errors.d.ts +14 -10
- package/dist/frontend/lowering/builtins/errors.js +174 -6
- package/dist/frontend/lowering/builtins/errors.js.map +1 -1
- package/dist/frontend/lowering/builtins/filesystem-calls.d.ts +4 -0
- package/dist/frontend/lowering/builtins/filesystem-calls.js +136 -113
- package/dist/frontend/lowering/builtins/filesystem-calls.js.map +1 -1
- package/dist/frontend/lowering/builtins/filesystem.d.ts +8 -0
- package/dist/frontend/lowering/builtins/filesystem.js +213 -76
- package/dist/frontend/lowering/builtins/filesystem.js.map +1 -1
- package/dist/frontend/lowering/builtins/fs-glob.js +3 -3
- package/dist/frontend/lowering/builtins/fs-glob.js.map +1 -1
- package/dist/frontend/lowering/builtins/fs-streams.js +10 -11
- package/dist/frontend/lowering/builtins/fs-streams.js.map +1 -1
- package/dist/frontend/lowering/builtins/hash-stream.d.ts +12 -0
- package/dist/frontend/lowering/builtins/hash-stream.js +80 -0
- package/dist/frontend/lowering/builtins/hash-stream.js.map +1 -0
- package/dist/frontend/lowering/builtins/ipc.js +45 -8
- package/dist/frontend/lowering/builtins/ipc.js.map +1 -1
- package/dist/frontend/lowering/builtins/json.js +232 -24
- package/dist/frontend/lowering/builtins/json.js.map +1 -1
- package/dist/frontend/lowering/builtins/key-object.js +4 -4
- package/dist/frontend/lowering/builtins/key-object.js.map +1 -1
- package/dist/frontend/lowering/builtins/module-bindings.d.ts +8 -0
- package/dist/frontend/lowering/builtins/module-bindings.js +71 -22
- package/dist/frontend/lowering/builtins/module-bindings.js.map +1 -1
- package/dist/frontend/lowering/builtins/module-calls.js +67 -46
- package/dist/frontend/lowering/builtins/module-calls.js.map +1 -1
- package/dist/frontend/lowering/builtins/module-resolution.d.ts +4 -3
- package/dist/frontend/lowering/builtins/module-resolution.js +24 -23
- package/dist/frontend/lowering/builtins/module-resolution.js.map +1 -1
- package/dist/frontend/lowering/builtins/navigator.d.ts +13 -0
- package/dist/frontend/lowering/builtins/navigator.js +40 -0
- package/dist/frontend/lowering/builtins/navigator.js.map +1 -0
- package/dist/frontend/lowering/builtins/net-address.d.ts +19 -0
- package/dist/frontend/lowering/builtins/net-address.js +156 -0
- package/dist/frontend/lowering/builtins/net-address.js.map +1 -0
- package/dist/frontend/lowering/builtins/numbers.js +25 -9
- package/dist/frontend/lowering/builtins/numbers.js.map +1 -1
- package/dist/frontend/lowering/builtins/operating-system.d.ts +4 -0
- package/dist/frontend/lowering/builtins/operating-system.js +25 -12
- package/dist/frontend/lowering/builtins/operating-system.js.map +1 -1
- package/dist/frontend/lowering/builtins/performance.d.ts +12 -0
- package/dist/frontend/lowering/builtins/performance.js +259 -8
- package/dist/frontend/lowering/builtins/performance.js.map +1 -1
- package/dist/frontend/lowering/builtins/process.d.ts +32 -1
- package/dist/frontend/lowering/builtins/process.js +468 -99
- package/dist/frontend/lowering/builtins/process.js.map +1 -1
- package/dist/frontend/lowering/builtins/promises.d.ts +5 -1
- package/dist/frontend/lowering/builtins/promises.js +326 -43
- package/dist/frontend/lowering/builtins/promises.js.map +1 -1
- package/dist/frontend/lowering/builtins/promisify-callback.d.ts +37 -0
- package/dist/frontend/lowering/builtins/promisify-callback.js +320 -0
- package/dist/frontend/lowering/builtins/promisify-callback.js.map +1 -0
- package/dist/frontend/lowering/builtins/properties.js +37 -1
- package/dist/frontend/lowering/builtins/properties.js.map +1 -1
- package/dist/frontend/lowering/builtins/querystring.js +14 -14
- package/dist/frontend/lowering/builtins/querystring.js.map +1 -1
- package/dist/frontend/lowering/builtins/readline.d.ts +55 -13
- package/dist/frontend/lowering/builtins/readline.js +931 -69
- package/dist/frontend/lowering/builtins/readline.js.map +1 -1
- package/dist/frontend/lowering/builtins/receiver-types.js +3 -5
- package/dist/frontend/lowering/builtins/receiver-types.js.map +1 -1
- package/dist/frontend/lowering/builtins/reflection.js +16 -14
- package/dist/frontend/lowering/builtins/reflection.js.map +1 -1
- package/dist/frontend/lowering/builtins/runtime-constructor.d.ts +26 -0
- package/dist/frontend/lowering/builtins/runtime-constructor.js +165 -0
- package/dist/frontend/lowering/builtins/runtime-constructor.js.map +1 -0
- package/dist/frontend/lowering/builtins/strings.js +101 -12
- package/dist/frontend/lowering/builtins/strings.js.map +1 -1
- package/dist/frontend/lowering/builtins/text-codecs.js +41 -38
- package/dist/frontend/lowering/builtins/text-codecs.js.map +1 -1
- package/dist/frontend/lowering/builtins/timers.js +75 -30
- package/dist/frontend/lowering/builtins/timers.js.map +1 -1
- package/dist/frontend/lowering/builtins/url.d.ts +3 -0
- package/dist/frontend/lowering/builtins/url.js +120 -17
- package/dist/frontend/lowering/builtins/url.js.map +1 -1
- package/dist/frontend/lowering/builtins/util-types.js +20 -4
- package/dist/frontend/lowering/builtins/util-types.js.map +1 -1
- package/dist/frontend/lowering/builtins/v8.d.ts +11 -0
- package/dist/frontend/lowering/builtins/v8.js +105 -0
- package/dist/frontend/lowering/builtins/v8.js.map +1 -0
- package/dist/frontend/lowering/builtins/webassembly.d.ts +33 -0
- package/dist/frontend/lowering/builtins/webassembly.js +388 -0
- package/dist/frontend/lowering/builtins/webassembly.js.map +1 -0
- package/dist/frontend/lowering/builtins/webcrypto.d.ts +20 -0
- package/dist/frontend/lowering/builtins/webcrypto.js +112 -0
- package/dist/frontend/lowering/builtins/webcrypto.js.map +1 -0
- package/dist/frontend/lowering/builtins/workers.d.ts +16 -0
- package/dist/frontend/lowering/builtins/workers.js +246 -3
- package/dist/frontend/lowering/builtins/workers.js.map +1 -1
- package/dist/frontend/lowering/call-arguments.js +69 -14
- package/dist/frontend/lowering/call-arguments.js.map +1 -1
- package/dist/frontend/lowering/call-signatures.d.ts +19 -1
- package/dist/frontend/lowering/call-signatures.js +254 -47
- package/dist/frontend/lowering/call-signatures.js.map +1 -1
- package/dist/frontend/lowering/checked-promise-all.d.ts +3 -0
- package/dist/frontend/lowering/checked-promise-all.js +1 -1
- package/dist/frontend/lowering/checked-promise-all.js.map +1 -1
- package/dist/frontend/lowering/cjs-exports-object.d.ts +53 -0
- package/dist/frontend/lowering/cjs-exports-object.js +528 -0
- package/dist/frontend/lowering/cjs-exports-object.js.map +1 -0
- package/dist/frontend/lowering/cjs-inline-require.d.ts +86 -0
- package/dist/frontend/lowering/cjs-inline-require.js +314 -0
- package/dist/frontend/lowering/cjs-inline-require.js.map +1 -0
- package/dist/frontend/lowering/cjs-tsc-interop.d.ts +28 -0
- package/dist/frontend/lowering/cjs-tsc-interop.js +208 -0
- package/dist/frontend/lowering/cjs-tsc-interop.js.map +1 -0
- package/dist/frontend/lowering/class-attributes.d.ts +19 -0
- package/dist/frontend/lowering/class-attributes.js +378 -0
- package/dist/frontend/lowering/class-attributes.js.map +1 -0
- package/dist/frontend/lowering/class-callbacks.d.ts +3 -1
- package/dist/frontend/lowering/class-callbacks.js +21 -10
- package/dist/frontend/lowering/class-callbacks.js.map +1 -1
- package/dist/frontend/lowering/class-construction.js +49 -4
- package/dist/frontend/lowering/class-construction.js.map +1 -1
- package/dist/frontend/lowering/class-descriptors.d.ts +2 -0
- package/dist/frontend/lowering/class-descriptors.js +8 -8
- package/dist/frontend/lowering/class-descriptors.js.map +1 -1
- package/dist/frontend/lowering/class-dynamic-dispatch.d.ts +64 -0
- package/dist/frontend/lowering/class-dynamic-dispatch.js +1115 -89
- package/dist/frontend/lowering/class-dynamic-dispatch.js.map +1 -1
- package/dist/frontend/lowering/class-instance-constructor.js +1 -1
- package/dist/frontend/lowering/class-instance-constructor.js.map +1 -1
- package/dist/frontend/lowering/class-iterables.d.ts +11 -0
- package/dist/frontend/lowering/class-iterables.js +31 -0
- package/dist/frontend/lowering/class-iterables.js.map +1 -0
- package/dist/frontend/lowering/class-method-mutations.js +73 -35
- package/dist/frontend/lowering/class-method-mutations.js.map +1 -1
- package/dist/frontend/lowering/class-method-values.js +56 -10
- package/dist/frontend/lowering/class-method-values.js.map +1 -1
- package/dist/frontend/lowering/class-protocol-dispatch.js +24 -22
- package/dist/frontend/lowering/class-protocol-dispatch.js.map +1 -1
- package/dist/frontend/lowering/class-protocols.d.ts +55 -0
- package/dist/frontend/lowering/class-protocols.js +738 -22
- package/dist/frontend/lowering/class-protocols.js.map +1 -1
- package/dist/frontend/lowering/class-prototypes.d.ts +6 -0
- package/dist/frontend/lowering/class-prototypes.js +80 -18
- package/dist/frontend/lowering/class-prototypes.js.map +1 -1
- package/dist/frontend/lowering/class-runtime-statics.js +1 -1
- package/dist/frontend/lowering/class-runtime-statics.js.map +1 -1
- package/dist/frontend/lowering/class-static-data.js +2 -2
- package/dist/frontend/lowering/class-static-data.js.map +1 -1
- package/dist/frontend/lowering/class-to-primitive.d.ts +25 -0
- package/dist/frontend/lowering/class-to-primitive.js +261 -0
- package/dist/frontend/lowering/class-to-primitive.js.map +1 -0
- package/dist/frontend/lowering/class-unions.d.ts +25 -0
- package/dist/frontend/lowering/class-unions.js +102 -1
- package/dist/frontend/lowering/class-unions.js.map +1 -1
- package/dist/frontend/lowering/code-generation.d.ts +14 -0
- package/dist/frontend/lowering/code-generation.js +127 -0
- package/dist/frontend/lowering/code-generation.js.map +1 -0
- package/dist/frontend/lowering/coercions/function-adapters.d.ts +16 -2
- package/dist/frontend/lowering/coercions/function-adapters.js +145 -3
- package/dist/frontend/lowering/coercions/function-adapters.js.map +1 -1
- package/dist/frontend/lowering/coercions/structural-plans.js +25 -3
- package/dist/frontend/lowering/coercions/structural-plans.js.map +1 -1
- package/dist/frontend/lowering/coercions/structural.js +35 -3
- package/dist/frontend/lowering/coercions/structural.js.map +1 -1
- package/dist/frontend/lowering/coercions/unions.d.ts +15 -0
- package/dist/frontend/lowering/coercions/unions.js +57 -1
- package/dist/frontend/lowering/coercions/unions.js.map +1 -1
- package/dist/frontend/lowering/collection-ingestion.js +2 -2
- package/dist/frontend/lowering/collection-ingestion.js.map +1 -1
- package/dist/frontend/lowering/collection-narrowing.js +2 -4
- package/dist/frontend/lowering/collection-narrowing.js.map +1 -1
- package/dist/frontend/lowering/construction-escapes.js +8 -8
- package/dist/frontend/lowering/construction-escapes.js.map +1 -1
- package/dist/frontend/lowering/construction-escapes.test.js +4 -4
- package/dist/frontend/lowering/construction-escapes.test.js.map +1 -1
- package/dist/frontend/lowering/constructor-returns.d.ts +61 -0
- package/dist/frontend/lowering/constructor-returns.js +477 -0
- package/dist/frontend/lowering/constructor-returns.js.map +1 -0
- package/dist/frontend/lowering/containers/array-callback-call.js +1 -1
- package/dist/frontend/lowering/containers/array-callback-call.js.map +1 -1
- package/dist/frontend/lowering/containers/array-callbacks.d.ts +9 -0
- package/dist/frontend/lowering/containers/array-callbacks.js +266 -100
- package/dist/frontend/lowering/containers/array-callbacks.js.map +1 -1
- package/dist/frontend/lowering/containers/array-concat.js +1 -1
- package/dist/frontend/lowering/containers/array-concat.js.map +1 -1
- package/dist/frontend/lowering/containers/array-construction.d.ts +0 -1
- package/dist/frontend/lowering/containers/array-construction.js +51 -13
- package/dist/frontend/lowering/containers/array-construction.js.map +1 -1
- package/dist/frontend/lowering/containers/array-from-async.d.ts +19 -0
- package/dist/frontend/lowering/containers/array-from-async.js +427 -0
- package/dist/frontend/lowering/containers/array-from-async.js.map +1 -0
- package/dist/frontend/lowering/containers/array-methods.js +89 -77
- package/dist/frontend/lowering/containers/array-methods.js.map +1 -1
- package/dist/frontend/lowering/containers/array-pipelines.js +1 -0
- package/dist/frontend/lowering/containers/array-pipelines.js.map +1 -1
- package/dist/frontend/lowering/containers/bytes.js +161 -101
- package/dist/frontend/lowering/containers/bytes.js.map +1 -1
- package/dist/frontend/lowering/containers/callback-arguments.d.ts +9 -1
- package/dist/frontend/lowering/containers/callback-arguments.js +55 -5
- package/dist/frontend/lowering/containers/callback-arguments.js.map +1 -1
- package/dist/frontend/lowering/containers/collection-grouping.d.ts +7 -8
- package/dist/frontend/lowering/containers/collection-grouping.js +219 -27
- package/dist/frontend/lowering/containers/collection-grouping.js.map +1 -1
- package/dist/frontend/lowering/containers/collection-methods.js +81 -48
- package/dist/frontend/lowering/containers/collection-methods.js.map +1 -1
- package/dist/frontend/lowering/containers/dynamic-receivers.js +1 -1
- package/dist/frontend/lowering/containers/dynamic-receivers.js.map +1 -1
- package/dist/frontend/lowering/containers/exec-result-uses.js +2 -2
- package/dist/frontend/lowering/containers/exec-result-uses.js.map +1 -1
- package/dist/frontend/lowering/containers/for-of.d.ts +6 -0
- package/dist/frontend/lowering/containers/for-of.js +19 -19
- package/dist/frontend/lowering/containers/for-of.js.map +1 -1
- package/dist/frontend/lowering/containers/indexed-objects.js +142 -57
- package/dist/frontend/lowering/containers/indexed-objects.js.map +1 -1
- package/dist/frontend/lowering/containers/iterator-helpers.d.ts +53 -4
- package/dist/frontend/lowering/containers/iterator-helpers.js +1581 -462
- package/dist/frontend/lowering/containers/iterator-helpers.js.map +1 -1
- package/dist/frontend/lowering/containers/match-row-uses.d.ts +17 -0
- package/dist/frontend/lowering/containers/match-row-uses.js +264 -0
- package/dist/frontend/lowering/containers/match-row-uses.js.map +1 -0
- package/dist/frontend/lowering/containers/string-and-regexp.d.ts +14 -0
- package/dist/frontend/lowering/containers/string-and-regexp.js +419 -30
- package/dist/frontend/lowering/containers/string-and-regexp.js.map +1 -1
- package/dist/frontend/lowering/containers/string-replacement.js +1 -1
- package/dist/frontend/lowering/containers/string-replacement.js.map +1 -1
- package/dist/frontend/lowering/cycle-initialization.d.ts +4 -0
- package/dist/frontend/lowering/cycle-initialization.js +39 -0
- package/dist/frontend/lowering/cycle-initialization.js.map +1 -1
- package/dist/frontend/lowering/deferred-module-initializers.js +47 -43
- package/dist/frontend/lowering/deferred-module-initializers.js.map +1 -1
- package/dist/frontend/lowering/devirtualize.d.ts +1 -1
- package/dist/frontend/lowering/devirtualize.js +27 -7
- package/dist/frontend/lowering/devirtualize.js.map +1 -1
- package/dist/frontend/lowering/divergences.d.ts +0 -5
- package/dist/frontend/lowering/divergences.js +238 -128
- package/dist/frontend/lowering/divergences.js.map +1 -1
- package/dist/frontend/lowering/dyn-streams.d.ts +25 -0
- package/dist/frontend/lowering/dyn-streams.js +257 -0
- package/dist/frontend/lowering/dyn-streams.js.map +1 -0
- package/dist/frontend/lowering/error-methods.js +4 -1
- package/dist/frontend/lowering/error-methods.js.map +1 -1
- package/dist/frontend/lowering/error-name-order.d.ts +19 -0
- package/dist/frontend/lowering/error-name-order.js +93 -0
- package/dist/frontend/lowering/error-name-order.js.map +1 -0
- package/dist/frontend/lowering/expressions/array-literals.d.ts +21 -0
- package/dist/frontend/lowering/expressions/array-literals.js +703 -0
- package/dist/frontend/lowering/expressions/array-literals.js.map +1 -0
- package/dist/frontend/lowering/expressions/binary.d.ts +35 -0
- package/dist/frontend/lowering/expressions/binary.js +2483 -0
- package/dist/frontend/lowering/expressions/binary.js.map +1 -0
- package/dist/frontend/lowering/expressions/element-access.d.ts +31 -0
- package/dist/frontend/lowering/expressions/element-access.js +1797 -0
- package/dist/frontend/lowering/expressions/element-access.js.map +1 -0
- package/dist/frontend/lowering/expressions/evaluation-safety.js +4 -3
- package/dist/frontend/lowering/expressions/evaluation-safety.js.map +1 -1
- package/dist/frontend/lowering/expressions/hosted-narrowing.d.ts +38 -0
- package/dist/frontend/lowering/expressions/hosted-narrowing.js +160 -0
- package/dist/frontend/lowering/expressions/hosted-narrowing.js.map +1 -0
- package/dist/frontend/lowering/expressions/identifiers.d.ts +4 -0
- package/dist/frontend/lowering/expressions/identifiers.js +830 -0
- package/dist/frontend/lowering/expressions/identifiers.js.map +1 -0
- package/dist/frontend/lowering/expressions/keyed-field-targets.d.ts +40 -0
- package/dist/frontend/lowering/expressions/keyed-field-targets.js +226 -0
- package/dist/frontend/lowering/expressions/keyed-field-targets.js.map +1 -0
- package/dist/frontend/lowering/expressions/narrowing.d.ts +37 -0
- package/dist/frontend/lowering/expressions/narrowing.js +1322 -0
- package/dist/frontend/lowering/expressions/narrowing.js.map +1 -0
- package/dist/frontend/lowering/expressions/native-proxy.js +4 -4
- package/dist/frontend/lowering/expressions/native-proxy.js.map +1 -1
- package/dist/frontend/lowering/expressions/nullish-assignment.js +45 -0
- package/dist/frontend/lowering/expressions/nullish-assignment.js.map +1 -1
- package/dist/frontend/lowering/expressions/object-literals.d.ts +10 -0
- package/dist/frontend/lowering/expressions/object-literals.js +253 -85
- package/dist/frontend/lowering/expressions/object-literals.js.map +1 -1
- package/dist/frontend/lowering/expressions/optional-chains.d.ts +2 -1
- package/dist/frontend/lowering/expressions/optional-chains.js +91 -14
- package/dist/frontend/lowering/expressions/optional-chains.js.map +1 -1
- package/dist/frontend/lowering/expressions/property-access.d.ts +110 -0
- package/dist/frontend/lowering/expressions/property-access.js +3544 -0
- package/dist/frontend/lowering/expressions/property-access.js.map +1 -0
- package/dist/frontend/lowering/expressions/relational.d.ts +28 -0
- package/dist/frontend/lowering/expressions/relational.js +1679 -0
- package/dist/frontend/lowering/expressions/relational.js.map +1 -0
- package/dist/frontend/lowering/expressions/typeof.d.ts +22 -0
- package/dist/frontend/lowering/expressions/typeof.js +538 -0
- package/dist/frontend/lowering/expressions/typeof.js.map +1 -0
- package/dist/frontend/lowering/expressions/union-fields.js +1 -1
- package/dist/frontend/lowering/expressions/union-fields.js.map +1 -1
- package/dist/frontend/lowering/expressions/updates.d.ts +21 -0
- package/dist/frontend/lowering/expressions/updates.js +780 -0
- package/dist/frontend/lowering/expressions/updates.js.map +1 -0
- package/dist/frontend/lowering/function-context.d.ts +10 -0
- package/dist/frontend/lowering/function-context.js +11 -1
- package/dist/frontend/lowering/function-context.js.map +1 -1
- package/dist/frontend/lowering/function-returns.js +52 -28
- package/dist/frontend/lowering/function-returns.js.map +1 -1
- package/dist/frontend/lowering/general-streams.d.ts +25 -0
- package/dist/frontend/lowering/general-streams.js +108 -0
- package/dist/frontend/lowering/general-streams.js.map +1 -0
- package/dist/frontend/lowering/generator-dynamic-dispatch.d.ts +7 -0
- package/dist/frontend/lowering/generator-dynamic-dispatch.js +172 -69
- package/dist/frontend/lowering/generator-dynamic-dispatch.js.map +1 -1
- package/dist/frontend/lowering/generic-functions.d.ts +39 -0
- package/dist/frontend/lowering/generic-functions.js +393 -75
- package/dist/frontend/lowering/generic-functions.js.map +1 -1
- package/dist/frontend/lowering/import-meta.js +2 -2
- package/dist/frontend/lowering/import-meta.js.map +1 -1
- package/dist/frontend/lowering/intern-tables.js +10 -9
- package/dist/frontend/lowering/intern-tables.js.map +1 -1
- package/dist/frontend/lowering/iterator-adapters.d.ts +19 -0
- package/dist/frontend/lowering/iterator-adapters.js +331 -3
- package/dist/frontend/lowering/iterator-adapters.js.map +1 -1
- package/dist/frontend/lowering/js-class-fields.d.ts +28 -0
- package/dist/frontend/lowering/js-class-fields.js +170 -0
- package/dist/frontend/lowering/js-class-fields.js.map +1 -0
- package/dist/frontend/lowering/js-dynamic-objects.d.ts +15 -0
- package/dist/frontend/lowering/js-dynamic-objects.js +299 -0
- package/dist/frontend/lowering/js-dynamic-objects.js.map +1 -0
- package/dist/frontend/lowering/js-dynamic-objects.test.d.ts +1 -0
- package/dist/frontend/lowering/js-dynamic-objects.test.js +35 -0
- package/dist/frontend/lowering/js-dynamic-objects.test.js.map +1 -0
- package/dist/frontend/lowering/json-require.d.ts +22 -0
- package/dist/frontend/lowering/json-require.js +131 -0
- package/dist/frontend/lowering/json-require.js.map +1 -0
- package/dist/frontend/lowering/key-order-witness.d.ts +44 -0
- package/dist/frontend/lowering/key-order-witness.js +641 -0
- package/dist/frontend/lowering/key-order-witness.js.map +1 -0
- package/dist/frontend/lowering/key-order-witness.test.d.ts +1 -0
- package/dist/frontend/lowering/key-order-witness.test.js +239 -0
- package/dist/frontend/lowering/key-order-witness.test.js.map +1 -0
- package/dist/frontend/lowering/lifetime-regions.js +7 -7
- package/dist/frontend/lowering/lifetime-regions.js.map +1 -1
- package/dist/frontend/lowering/lower-assert.js +61 -60
- package/dist/frontend/lowering/lower-assert.js.map +1 -1
- package/dist/frontend/lowering/lower-async-iteration.d.ts +10 -1
- package/dist/frontend/lowering/lower-async-iteration.js +34 -6
- package/dist/frontend/lowering/lower-async-iteration.js.map +1 -1
- package/dist/frontend/lowering/lower-builtin-values.d.ts +5 -0
- package/dist/frontend/lowering/lower-builtin-values.js +32 -3
- package/dist/frontend/lowering/lower-builtin-values.js.map +1 -1
- package/dist/frontend/lowering/lower-calls.js +1298 -452
- package/dist/frontend/lowering/lower-calls.js.map +1 -1
- package/dist/frontend/lowering/lower-classes.d.ts +50 -3
- package/dist/frontend/lowering/lower-classes.js +1499 -456
- package/dist/frontend/lowering/lower-classes.js.map +1 -1
- package/dist/frontend/lowering/lower-comptime.d.ts +4 -2
- package/dist/frontend/lowering/lower-comptime.js +111 -13
- package/dist/frontend/lowering/lower-comptime.js.map +1 -1
- package/dist/frontend/lowering/lower-console.js +13 -11
- package/dist/frontend/lowering/lower-console.js.map +1 -1
- package/dist/frontend/lowering/lower-dgram.d.ts +10 -0
- package/dist/frontend/lowering/lower-dgram.js +179 -8
- package/dist/frontend/lowering/lower-dgram.js.map +1 -1
- package/dist/frontend/lowering/lower-enums.js +113 -14
- package/dist/frontend/lowering/lower-enums.js.map +1 -1
- package/dist/frontend/lowering/lower-event-emitter.d.ts +16 -7
- package/dist/frontend/lowering/lower-event-emitter.js +268 -71
- package/dist/frontend/lowering/lower-event-emitter.js.map +1 -1
- package/dist/frontend/lowering/lower-event-target.js +2 -2
- package/dist/frontend/lowering/lower-event-target.js.map +1 -1
- package/dist/frontend/lowering/lower-expando.js +17 -13
- package/dist/frontend/lowering/lower-expando.js.map +1 -1
- package/dist/frontend/lowering/lower-exprs.d.ts +188 -186
- package/dist/frontend/lowering/lower-exprs.js +1493 -12407
- package/dist/frontend/lowering/lower-exprs.js.map +1 -1
- package/dist/frontend/lowering/lower-functions.js +68 -22
- package/dist/frontend/lowering/lower-functions.js.map +1 -1
- package/dist/frontend/lowering/lower-generators.d.ts +6 -0
- package/dist/frontend/lowering/lower-generators.js +29 -16
- package/dist/frontend/lowering/lower-generators.js.map +1 -1
- package/dist/frontend/lowering/lower-global-value.js +5 -1
- package/dist/frontend/lowering/lower-global-value.js.map +1 -1
- package/dist/frontend/lowering/lower-inspect.js +354 -99
- package/dist/frontend/lowering/lower-inspect.js.map +1 -1
- package/dist/frontend/lowering/lower-mixins.js +23 -20
- package/dist/frontend/lowering/lower-mixins.js.map +1 -1
- package/dist/frontend/lowering/lower-mock.d.ts +19 -2
- package/dist/frontend/lowering/lower-mock.js +557 -74
- package/dist/frontend/lowering/lower-mock.js.map +1 -1
- package/dist/frontend/lowering/lower-modules.js +268 -61
- package/dist/frontend/lowering/lower-modules.js.map +1 -1
- package/dist/frontend/lowering/lower-namespaces.d.ts +6 -0
- package/dist/frontend/lowering/lower-namespaces.js +45 -33
- package/dist/frontend/lowering/lower-namespaces.js.map +1 -1
- package/dist/frontend/lowering/lower-node-module.d.ts +16 -0
- package/dist/frontend/lowering/lower-node-module.js +147 -14
- package/dist/frontend/lowering/lower-node-module.js.map +1 -1
- package/dist/frontend/lowering/lower-server.d.ts +6 -6
- package/dist/frontend/lowering/lower-server.js +638 -105
- package/dist/frontend/lowering/lower-server.js.map +1 -1
- package/dist/frontend/lowering/lower-stdlib.d.ts +4 -0
- package/dist/frontend/lowering/lower-stdlib.js +151 -109
- package/dist/frontend/lowering/lower-stdlib.js.map +1 -1
- package/dist/frontend/lowering/lower-stmts.d.ts +28 -2
- package/dist/frontend/lowering/lower-stmts.js +1589 -398
- package/dist/frontend/lowering/lower-stmts.js.map +1 -1
- package/dist/frontend/lowering/lower-stream.d.ts +4 -3
- package/dist/frontend/lowering/lower-stream.js +714 -75
- package/dist/frontend/lowering/lower-stream.js.map +1 -1
- package/dist/frontend/lowering/lower-test.d.ts +3 -0
- package/dist/frontend/lowering/lower-test.js +574 -100
- package/dist/frontend/lowering/lower-test.js.map +1 -1
- package/dist/frontend/lowering/lower-timers.js +80 -32
- package/dist/frontend/lowering/lower-timers.js.map +1 -1
- package/dist/frontend/lowering/lower-url.js +1 -1
- package/dist/frontend/lowering/lower-url.js.map +1 -1
- package/dist/frontend/lowering/lowerer.d.ts +409 -26
- package/dist/frontend/lowering/lowerer.js +1918 -305
- package/dist/frontend/lowering/lowerer.js.map +1 -1
- package/dist/frontend/lowering/lowerer.test.js +10 -4
- package/dist/frontend/lowering/lowerer.test.js.map +1 -1
- package/dist/frontend/lowering/maybe-promise.d.ts +46 -0
- package/dist/frontend/lowering/maybe-promise.js +249 -0
- package/dist/frontend/lowering/maybe-promise.js.map +1 -0
- package/dist/frontend/lowering/module-member-this.d.ts +3 -0
- package/dist/frontend/lowering/module-member-this.js +262 -0
- package/dist/frontend/lowering/module-member-this.js.map +1 -0
- package/dist/frontend/lowering/module-namespace-elements.js +1 -1
- package/dist/frontend/lowering/module-namespace-elements.js.map +1 -1
- package/dist/frontend/lowering/nan-coded-reads.d.ts +3 -0
- package/dist/frontend/lowering/nan-coded-reads.js +45 -32
- package/dist/frontend/lowering/nan-coded-reads.js.map +1 -1
- package/dist/frontend/lowering/narrowing-stability.d.ts +18 -3
- package/dist/frontend/lowering/narrowing-stability.js +104 -32
- package/dist/frontend/lowering/narrowing-stability.js.map +1 -1
- package/dist/frontend/lowering/native-ffi.js +11 -11
- package/dist/frontend/lowering/native-ffi.js.map +1 -1
- package/dist/frontend/lowering/null-prototype.d.ts +13 -0
- package/dist/frontend/lowering/null-prototype.js +33 -0
- package/dist/frontend/lowering/null-prototype.js.map +1 -0
- package/dist/frontend/lowering/object-factory-new.js +6 -8
- package/dist/frontend/lowering/object-factory-new.js.map +1 -1
- package/dist/frontend/lowering/private-brands.d.ts +46 -0
- package/dist/frontend/lowering/private-brands.js +265 -0
- package/dist/frontend/lowering/private-brands.js.map +1 -0
- package/dist/frontend/lowering/promise-executor-adapter.d.ts +11 -0
- package/dist/frontend/lowering/promise-executor-adapter.js +87 -0
- package/dist/frontend/lowering/promise-executor-adapter.js.map +1 -0
- package/dist/frontend/lowering/require-initialization.d.ts +32 -0
- package/dist/frontend/lowering/require-initialization.js +246 -0
- package/dist/frontend/lowering/require-initialization.js.map +1 -0
- package/dist/frontend/lowering/runtime-optional-bounds.js +7 -7
- package/dist/frontend/lowering/runtime-optional-bounds.js.map +1 -1
- package/dist/frontend/lowering/runtime-optional-elements.js +12 -12
- package/dist/frontend/lowering/runtime-optional-elements.js.map +1 -1
- package/dist/frontend/lowering/runtime-optional-guards.js +10 -10
- package/dist/frontend/lowering/runtime-optional-guards.js.map +1 -1
- package/dist/frontend/lowering/runtime-optional-guards.test.js +1 -1
- package/dist/frontend/lowering/runtime-optional-guards.test.js.map +1 -1
- package/dist/frontend/lowering/runtime-optional-ownership.js +10 -9
- package/dist/frontend/lowering/runtime-optional-ownership.js.map +1 -1
- package/dist/frontend/lowering/runtime-optional-provenance.js +2 -2
- package/dist/frontend/lowering/runtime-optional-provenance.js.map +1 -1
- package/dist/frontend/lowering/runtime-optional-records.d.ts +35 -0
- package/dist/frontend/lowering/runtime-optional-records.js +205 -32
- package/dist/frontend/lowering/runtime-optional-records.js.map +1 -1
- package/dist/frontend/lowering/runtime-optional-records.test.js +19 -1
- package/dist/frontend/lowering/runtime-optional-records.test.js.map +1 -1
- package/dist/frontend/lowering/sanitize-class-types.test.js +2 -2
- package/dist/frontend/lowering/split-consumers.js +4 -4
- package/dist/frontend/lowering/split-consumers.js.map +1 -1
- package/dist/frontend/lowering/static-function-names.d.ts +28 -0
- package/dist/frontend/lowering/static-function-names.js +212 -0
- package/dist/frontend/lowering/static-function-names.js.map +1 -0
- package/dist/frontend/lowering/static-this.js +6 -6
- package/dist/frontend/lowering/static-this.js.map +1 -1
- package/dist/frontend/lowering/strict-mode.d.ts +5 -0
- package/dist/frontend/lowering/strict-mode.js +31 -0
- package/dist/frontend/lowering/strict-mode.js.map +1 -0
- package/dist/frontend/lowering/string-index-bounds.js +10 -10
- package/dist/frontend/lowering/string-index-bounds.js.map +1 -1
- package/dist/frontend/lowering/string-index.d.ts +12 -0
- package/dist/frontend/lowering/string-index.js +72 -1
- package/dist/frontend/lowering/string-index.js.map +1 -1
- package/dist/frontend/lowering/surfaces.d.ts +15 -6
- package/dist/frontend/lowering/surfaces.js +278 -45
- package/dist/frontend/lowering/surfaces.js.map +1 -1
- package/dist/frontend/lowering/symbol-fields.d.ts +7 -0
- package/dist/frontend/lowering/symbol-fields.js +204 -36
- package/dist/frontend/lowering/symbol-fields.js.map +1 -1
- package/dist/frontend/lowering/symbol-methods.d.ts +2 -1
- package/dist/frontend/lowering/symbol-methods.js +24 -6
- package/dist/frontend/lowering/symbol-methods.js.map +1 -1
- package/dist/frontend/lowering/thread-slots.d.ts +13 -0
- package/dist/frontend/lowering/thread-slots.js +208 -0
- package/dist/frontend/lowering/thread-slots.js.map +1 -0
- package/dist/frontend/lowering/typed-arguments.d.ts +74 -0
- package/dist/frontend/lowering/typed-arguments.js +472 -0
- package/dist/frontend/lowering/typed-arguments.js.map +1 -0
- package/dist/frontend/lowering/union-retag.d.ts +8 -0
- package/dist/frontend/lowering/union-retag.js +27 -0
- package/dist/frontend/lowering/union-retag.js.map +1 -1
- package/dist/frontend/lowering/union-retag.test.js +24 -1
- package/dist/frontend/lowering/union-retag.test.js.map +1 -1
- package/dist/frontend/lowering/var-hoisting.js +6 -6
- package/dist/frontend/lowering/var-hoisting.js.map +1 -1
- package/dist/frontend/lowering/width-lift.d.ts +4 -0
- package/dist/frontend/mock-shapes.d.ts +5 -0
- package/dist/frontend/mock-shapes.js +39 -7
- package/dist/frontend/mock-shapes.js.map +1 -1
- package/dist/frontend/module-source-candidates.js +1 -1
- package/dist/frontend/module-source-candidates.js.map +1 -1
- package/dist/frontend/module-source-candidates.test.js +2 -1
- package/dist/frontend/module-source-candidates.test.js.map +1 -1
- package/dist/frontend/module-syntax.js +8 -8
- package/dist/frontend/module-syntax.js.map +1 -1
- package/dist/frontend/npm-static-bundled-chunks.d.ts +51 -0
- package/dist/frontend/npm-static-bundled-chunks.js +810 -0
- package/dist/frontend/npm-static-bundled-chunks.js.map +1 -0
- package/dist/frontend/npm-static-bundled-chunks.test.d.ts +1 -0
- package/dist/frontend/npm-static-bundled-chunks.test.js +287 -0
- package/dist/frontend/npm-static-bundled-chunks.test.js.map +1 -0
- package/dist/frontend/npm-static-bundled-cjs.js +24 -23
- package/dist/frontend/npm-static-bundled-cjs.js.map +1 -1
- package/dist/frontend/npm-static-bundled-esm.d.ts +9 -0
- package/dist/frontend/npm-static-bundled-esm.js +768 -0
- package/dist/frontend/npm-static-bundled-esm.js.map +1 -0
- package/dist/frontend/npm-static-bundled-esm.test.d.ts +1 -0
- package/dist/frontend/npm-static-bundled-esm.test.js +207 -0
- package/dist/frontend/npm-static-bundled-esm.test.js.map +1 -0
- package/dist/frontend/npm-static-cjs-exports-alias.d.ts +2 -0
- package/dist/frontend/npm-static-cjs-exports-alias.js +186 -0
- package/dist/frontend/npm-static-cjs-exports-alias.js.map +1 -0
- package/dist/frontend/npm-static-cjs-exports-alias.test.d.ts +1 -0
- package/dist/frontend/npm-static-cjs-exports-alias.test.js +73 -0
- package/dist/frontend/npm-static-cjs-exports-alias.test.js.map +1 -0
- package/dist/frontend/npm-static-cjs-exports-var.d.ts +2 -0
- package/dist/frontend/npm-static-cjs-exports-var.js +236 -0
- package/dist/frontend/npm-static-cjs-exports-var.js.map +1 -0
- package/dist/frontend/npm-static-declaration-syntax.js +102 -101
- package/dist/frontend/npm-static-declaration-syntax.js.map +1 -1
- package/dist/frontend/npm-static-prune.js +36 -24
- package/dist/frontend/npm-static-prune.js.map +1 -1
- package/dist/frontend/npm-static-rewrite-host.d.ts +4 -1
- package/dist/frontend/npm-static-rewrite-host.js +14 -3
- package/dist/frontend/npm-static-rewrite-host.js.map +1 -1
- package/dist/frontend/npm-static-rewrite-syntax.d.ts +19 -0
- package/dist/frontend/npm-static-rewrite-syntax.js +274 -101
- package/dist/frontend/npm-static-rewrite-syntax.js.map +1 -1
- package/dist/frontend/npm-static-subtyping.js +7 -9
- package/dist/frontend/npm-static-subtyping.js.map +1 -1
- package/dist/frontend/npm-static.d.ts +17 -1
- package/dist/frontend/npm-static.js +167 -16
- package/dist/frontend/npm-static.js.map +1 -1
- package/dist/frontend/npm-static.test.js +22 -1
- package/dist/frontend/npm-static.test.js.map +1 -1
- package/dist/frontend/pipeline.js +164 -26
- package/dist/frontend/pipeline.js.map +1 -1
- package/dist/frontend/pipeline.test.js +22 -1
- package/dist/frontend/pipeline.test.js.map +1 -1
- package/dist/frontend/program-analysis.d.ts +6 -1
- package/dist/frontend/program-analysis.js +7 -0
- package/dist/frontend/program-analysis.js.map +1 -1
- package/dist/frontend/program.d.ts +92 -2
- package/dist/frontend/program.js +1557 -254
- package/dist/frontend/program.js.map +1 -1
- package/dist/frontend/program.test.js +76 -6
- package/dist/frontend/program.test.js.map +1 -1
- package/dist/frontend/resolve.js +36 -2
- package/dist/frontend/resolve.js.map +1 -1
- package/dist/frontend/resolve.test.js +49 -0
- package/dist/frontend/resolve.test.js.map +1 -1
- package/dist/frontend/services.d.ts +20 -1
- package/dist/frontend/services.js +40 -3
- package/dist/frontend/services.js.map +1 -1
- package/dist/frontend/services.test.js +2 -1
- package/dist/frontend/services.test.js.map +1 -1
- package/dist/frontend/threads-import.js +1 -1
- package/dist/frontend/threads-import.js.map +1 -1
- package/dist/frontend/tier-analysis.d.ts +71 -0
- package/dist/frontend/tier-analysis.js +522 -0
- package/dist/frontend/tier-analysis.js.map +1 -0
- package/dist/frontend/ts7/api-conformance.d.ts +234 -0
- package/dist/frontend/ts7/api-conformance.js +7 -0
- package/dist/frontend/ts7/api-conformance.js.map +1 -0
- package/dist/frontend/ts7/ast-guards.generated.js +2 -1
- package/dist/frontend/ts7/ast-guards.generated.js.map +1 -1
- package/dist/frontend/ts7/ast-node.d.ts +47 -25
- package/dist/frontend/ts7/ast-node.js +64 -18
- package/dist/frontend/ts7/ast-node.js.map +1 -1
- package/dist/frontend/ts7/ast-node.test.js +36 -12
- package/dist/frontend/ts7/ast-node.test.js.map +1 -1
- package/dist/frontend/ts7/ast-types.d.ts +10 -3
- package/dist/frontend/ts7/ast-types.generated.d.ts +39 -39
- package/dist/frontend/ts7/ast.d.ts +1 -0
- package/dist/frontend/ts7/ast.js +3 -2
- package/dist/frontend/ts7/ast.js.map +1 -1
- package/dist/frontend/ts7/checker-backend.d.ts +23 -0
- package/dist/frontend/ts7/checker-backend.js +88 -0
- package/dist/frontend/ts7/checker-backend.js.map +1 -0
- package/dist/frontend/ts7/checker-backend.test.d.ts +1 -0
- package/dist/frontend/ts7/checker-backend.test.js +63 -0
- package/dist/frontend/ts7/checker-backend.test.js.map +1 -0
- package/dist/frontend/ts7/checker-cache.d.ts +0 -3
- package/dist/frontend/ts7/checker-cache.js +0 -6
- package/dist/frontend/ts7/checker-cache.js.map +1 -1
- package/dist/frontend/ts7/checker.d.ts +18 -11
- package/dist/frontend/ts7/checker.js +42 -55
- package/dist/frontend/ts7/checker.js.map +1 -1
- package/dist/frontend/ts7/checker.test.js +10 -7
- package/dist/frontend/ts7/checker.test.js.map +1 -1
- package/dist/frontend/ts7/diagnostic.d.ts +19 -0
- package/dist/frontend/ts7/diagnostic.js +22 -0
- package/dist/frontend/ts7/diagnostic.js.map +1 -0
- package/dist/frontend/ts7/node-functions.d.ts +8 -0
- package/dist/frontend/ts7/node-functions.js +18 -0
- package/dist/frontend/ts7/node-functions.js.map +1 -0
- package/dist/frontend/ts7/program-host.d.ts +5 -1
- package/dist/frontend/ts7/program-host.js +12 -0
- package/dist/frontend/ts7/program-host.js.map +1 -1
- package/dist/frontend/ts7/rpc-api.d.ts +5 -1
- package/dist/frontend/ts7/rpc-api.js +8 -1
- package/dist/frontend/ts7/rpc-api.js.map +1 -1
- package/dist/frontend/ts7/semantic-checker.d.ts +13 -6
- package/dist/frontend/ts7/semantic-checker.js +26 -8
- package/dist/frontend/ts7/semantic-checker.js.map +1 -1
- package/dist/frontend/ts7/semantic-checker.test.js +12 -9
- package/dist/frontend/ts7/semantic-checker.test.js.map +1 -1
- package/dist/frontend/ts7/semantic-model.d.ts +54 -24
- package/dist/frontend/ts7/semantic-model.js +88 -16
- package/dist/frontend/ts7/semantic-model.js.map +1 -1
- package/dist/frontend/ts7/semantic-model.test.js +4 -4
- package/dist/frontend/ts7/semantic-model.test.js.map +1 -1
- package/dist/frontend/ts7/semantic-types.d.ts +7 -3
- package/dist/frontend/ts7/semantic-types.js +1 -1
- package/dist/frontend/ts7/semantic-types.js.map +1 -1
- package/dist/frontend/ts7/session.d.ts +11 -11
- package/dist/frontend/ts7/session.js +8 -5
- package/dist/frontend/ts7/session.js.map +1 -1
- package/dist/frontend/ts7/session.test.js +9 -5
- package/dist/frontend/ts7/session.test.js.map +1 -1
- package/dist/frontend/ts7/source-parser.d.ts +6 -2
- package/dist/frontend/ts7/source-parser.js +24 -3
- package/dist/frontend/ts7/source-parser.js.map +1 -1
- package/dist/frontend/ts7/source-parser.test.js +38 -17
- package/dist/frontend/ts7/source-parser.test.js.map +1 -1
- package/dist/frontend/type-mapper.d.ts +122 -2
- package/dist/frontend/type-mapper.js +2612 -695
- package/dist/frontend/type-mapper.js.map +1 -1
- package/dist/frontend/type-only-imports.d.ts +28 -0
- package/dist/frontend/type-only-imports.js +122 -0
- package/dist/frontend/type-only-imports.js.map +1 -0
- package/dist/frontend/worker-target.js +8 -8
- package/dist/frontend/worker-target.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +47 -10
- package/dist/index.js.map +1 -1
- package/dist/ir/analysis.js +4 -2
- package/dist/ir/analysis.js.map +1 -1
- package/dist/ir/api.d.ts +1 -1
- package/dist/ir/api.js +1 -1
- package/dist/ir/api.js.map +1 -1
- package/dist/ir/array-length-stability.d.ts +30 -0
- package/dist/ir/array-length-stability.js +236 -0
- package/dist/ir/array-length-stability.js.map +1 -0
- package/dist/ir/array-length-stability.test.d.ts +1 -0
- package/dist/ir/array-length-stability.test.js +113 -0
- package/dist/ir/array-length-stability.test.js.map +1 -0
- package/dist/ir/build.d.ts +2 -2
- package/dist/ir/build.js +1 -1
- package/dist/ir/build.js.map +1 -1
- package/dist/ir/builtin-effects.js +139 -0
- package/dist/ir/builtin-effects.js.map +1 -1
- package/dist/ir/builtin-signatures.d.ts +1 -1
- package/dist/ir/builtin-signatures.js +655 -25
- package/dist/ir/builtin-signatures.js.map +1 -1
- package/dist/ir/byte-numbers.js +3 -0
- package/dist/ir/byte-numbers.js.map +1 -1
- package/dist/ir/callback-specialization.d.ts +37 -0
- package/dist/ir/callback-specialization.js +459 -0
- package/dist/ir/callback-specialization.js.map +1 -0
- package/dist/ir/callback-specialization.test.d.ts +1 -0
- package/dist/ir/callback-specialization.test.js +208 -0
- package/dist/ir/callback-specialization.test.js.map +1 -0
- package/dist/ir/capture-values.d.ts +0 -1
- package/dist/ir/capture-values.js +51 -40
- package/dist/ir/capture-values.js.map +1 -1
- package/dist/ir/constant-globals.test.js +1 -1
- package/dist/ir/constant-tables.test.js +1 -1
- package/dist/ir/field-values.test.js +1 -1
- package/dist/ir/final-fields.test.js +1 -1
- package/dist/ir/function-references.test.js +10 -1
- package/dist/ir/function-references.test.js.map +1 -1
- package/dist/ir/init-only-globals.test.js +1 -1
- package/dist/ir/initializer-bindings.test.js +1 -1
- package/dist/ir/int32-slots.d.ts +14 -0
- package/dist/ir/int32-slots.js +119 -14
- package/dist/ir/int32-slots.js.map +1 -1
- package/dist/ir/int32-slots.test.js +29 -1
- package/dist/ir/int32-slots.test.js.map +1 -1
- package/dist/ir/integer-loop-facts.d.ts +16 -6
- package/dist/ir/integer-loop-facts.js +143 -38
- package/dist/ir/integer-loop-facts.js.map +1 -1
- package/dist/ir/integer-loops.d.ts +1 -1
- package/dist/ir/integer-loops.js +39 -9
- package/dist/ir/integer-loops.js.map +1 -1
- package/dist/ir/integer-loops.test.js +104 -0
- package/dist/ir/integer-loops.test.js.map +1 -1
- package/dist/ir/integer-ranges.d.ts +3 -0
- package/dist/ir/integer-ranges.js +4 -6
- package/dist/ir/integer-ranges.js.map +1 -1
- package/dist/ir/integer-ranges.test.js +142 -1
- package/dist/ir/integer-ranges.test.js.map +1 -1
- package/dist/ir/intrinsic-signatures.js +6 -0
- package/dist/ir/intrinsic-signatures.js.map +1 -1
- package/dist/ir/ir.d.ts +234 -58
- package/dist/ir/ir.js +123 -12
- package/dist/ir/ir.js.map +1 -1
- package/dist/ir/ir.test.js +10 -0
- package/dist/ir/ir.test.js.map +1 -1
- package/dist/ir/jsval.d.ts +8 -0
- package/dist/ir/jsval.js +365 -0
- package/dist/ir/jsval.js.map +1 -0
- package/dist/ir/jsval.test.d.ts +1 -0
- package/dist/ir/jsval.test.js +239 -0
- package/dist/ir/jsval.test.js.map +1 -0
- package/dist/ir/runtime-features.d.ts +150 -33
- package/dist/ir/runtime-features.js +672 -339
- package/dist/ir/runtime-features.js.map +1 -1
- package/dist/ir/runtime-features.test.js +62 -0
- package/dist/ir/runtime-features.test.js.map +1 -1
- package/dist/ir/scalar-records.test.js +1 -1
- package/dist/ir/self-captures.d.ts +33 -0
- package/dist/ir/self-captures.js +245 -0
- package/dist/ir/self-captures.js.map +1 -0
- package/dist/ir/self-captures.test.d.ts +1 -0
- package/dist/ir/self-captures.test.js +135 -0
- package/dist/ir/self-captures.test.js.map +1 -0
- package/dist/ir/serialize.d.ts +1 -1
- package/dist/ir/serialize.js +7 -4
- package/dist/ir/serialize.js.map +1 -1
- package/dist/ir/tiers.d.ts +26 -0
- package/dist/ir/tiers.js +101 -0
- package/dist/ir/tiers.js.map +1 -0
- package/dist/ir/tiers.test.d.ts +1 -0
- package/dist/ir/tiers.test.js +140 -0
- package/dist/ir/tiers.test.js.map +1 -0
- package/dist/ir/traverse.js +107 -94
- package/dist/ir/traverse.js.map +1 -1
- package/dist/ir/traverse.test.js +33 -30
- package/dist/ir/traverse.test.js.map +1 -1
- package/dist/ir/unshare.js +65 -3
- package/dist/ir/unshare.js.map +1 -1
- package/dist/ir/unshare.test.js +1 -1
- package/dist/ir/validate.js +220 -71
- package/dist/ir/validate.js.map +1 -1
- package/dist/ir/validate.test.js +64 -9
- package/dist/ir/validate.test.js.map +1 -1
- package/dist/library/fence-eval.test.js +1 -1
- package/dist/library/int-infer.test.js +4 -4
- package/dist/library/ir-policy.js +18 -0
- package/dist/library/ir-policy.js.map +1 -1
- package/dist/library/library-cache.d.ts +1 -0
- package/dist/library/library-cache.js.map +1 -1
- package/dist/library/library-cache.test.js +5 -5
- package/dist/library/library-profile.d.ts +4 -4
- package/dist/library/library-profile.js +35 -7
- package/dist/library/library-profile.js.map +1 -1
- package/dist/library/prepare.js +13 -1
- package/dist/library/prepare.js.map +1 -1
- package/dist/native/cli.js +5 -0
- package/dist/native/cli.js.map +1 -1
- package/dist/native/compiler.js +2 -2
- package/dist/native/compiler.js.map +1 -1
- package/dist/native/compiler.test.js +2 -2
- package/dist/native/prepare.js +7 -0
- package/dist/native/prepare.js.map +1 -1
- package/dist/native/sanitizer.test.js +12 -0
- package/dist/native/sanitizer.test.js.map +1 -1
- package/dist/native/toolchain.d.ts +2 -0
- package/dist/native/toolchain.js +10 -1
- package/dist/native/toolchain.js.map +1 -1
- package/dist/native/toolchain.test.js +39 -1
- package/dist/native/toolchain.test.js.map +1 -1
- package/dist/startup-cache.d.ts +1 -0
- package/dist/startup-cache.js +1 -0
- package/dist/startup-cache.js.map +1 -1
- package/dist/wasm/base64.d.ts +5 -0
- package/dist/wasm/base64.js +62 -0
- package/dist/wasm/base64.js.map +1 -0
- package/dist/wasm/binary.d.ts +36 -0
- package/dist/wasm/binary.js +1976 -0
- package/dist/wasm/binary.js.map +1 -0
- package/dist/wasm/binary.test.d.ts +1 -0
- package/dist/wasm/binary.test.js +190 -0
- package/dist/wasm/binary.test.js.map +1 -0
- package/dist/wasm/discover.d.ts +38 -0
- package/dist/wasm/discover.js +377 -0
- package/dist/wasm/discover.js.map +1 -0
- package/dist/wasm/discover.test.d.ts +1 -0
- package/dist/wasm/discover.test.js +24 -0
- package/dist/wasm/discover.test.js.map +1 -0
- package/dist/wasm/module.d.ts +151 -0
- package/dist/wasm/module.js +575 -0
- package/dist/wasm/module.js.map +1 -0
- package/dist/wasm/translate.d.ts +48 -0
- package/dist/wasm/translate.js +2129 -0
- package/dist/wasm/translate.js.map +1 -0
- package/dist/wasm/translate.test.d.ts +1 -0
- package/dist/wasm/translate.test.js +207 -0
- package/dist/wasm/translate.test.js.map +1 -0
- package/package.json +21 -20
- package/surface-manifest.json +332 -36
|
@@ -1,9 +1,18 @@
|
|
|
1
|
+
import { onlyForwarded } from "./typed-arguments.js";
|
|
2
|
+
import { needsGeneralNodeStreams, noteUntypedStreamFlow, stdioIntoGeneralStream, } from "./general-streams.js";
|
|
3
|
+
import { extendAssertedRecordMembers } from "./assertion-members.js";
|
|
4
|
+
import { jsDynamicDeclarations } from "./js-dynamic-objects.js";
|
|
5
|
+
import { builtinClassValue, builtinMemberClassKind } from "./builtins/builtin-class-dyn.js";
|
|
1
6
|
import { lifetimeRegionType, lowerLifetimeRegionCall, lowerLifetimeRegionNew, } from "./lifetime-regions.js";
|
|
2
7
|
import { internTableType, lowerInternTableCall, lowerInternTableNew } from "./intern-tables.js";
|
|
8
|
+
import { lowerThreadSlotsCall, lowerThreadSlotsNew, threadSlotsType } from "./thread-slots.js";
|
|
3
9
|
import { isExperimentalDeclarationFile } from "../experimental-import.js";
|
|
4
10
|
import { checkCycleBindingAccesses, refuseUncheckedCycleReads, } from "./cycle-initialization.js";
|
|
11
|
+
import { isJsonRequireDecl } from "./json-require.js";
|
|
12
|
+
import { checkRequireBindingAccesses, } from "./require-initialization.js";
|
|
5
13
|
import { identityPreservingWidening } from "./coercions/identity.js";
|
|
6
14
|
import { scanDivergences } from "./divergences.js";
|
|
15
|
+
import { applyKeyOrderWitnesses, KeyOrderNotes } from "./key-order-witness.js";
|
|
7
16
|
import { checkedClassAssertion } from "./class-assertions.js";
|
|
8
17
|
import { narrowStoredClassValue, narrowGenericClassValue } from "./class-unions.js";
|
|
9
18
|
import { isOptionalProcessStreamProperty } from "./builtins/process.js";
|
|
@@ -11,7 +20,14 @@ import { isSettledIteratorValueRead } from "./lower-generators.js";
|
|
|
11
20
|
import { concreteCollectionNarrow } from "./collection-narrowing.js";
|
|
12
21
|
import { lowerWorkerMetadata } from "./builtins/workers.js";
|
|
13
22
|
import { fenceStaticBlobMember, lowerBlobNew, lowerStaticBlobCall } from "./builtins/blob.js";
|
|
23
|
+
import { lowerWebAssemblyCall, lowerWebAssemblyNew, refuseWebAssemblyUse, } from "./builtins/webassembly.js";
|
|
24
|
+
import { discoverWasmModules } from "../../wasm/discover.js";
|
|
25
|
+
import { encodeBase64 } from "../../wasm/base64.js";
|
|
26
|
+
import { resolveRequireRuntime } from "../runtime-resolve.js";
|
|
14
27
|
import { lowerKeyObjectCall } from "./builtins/key-object.js";
|
|
28
|
+
import { fenceWebCryptoMember, lowerWebCryptoCall } from "./builtins/webcrypto.js";
|
|
29
|
+
import { hashStreamOf } from "./builtins/hash-stream.js";
|
|
30
|
+
import { lowerNetAddressCall, lowerNetAddressNew } from "./builtins/net-address.js";
|
|
15
31
|
import { dynUndefinedExpr, nodeThrowExpr, numLit, varRef } from "../../ir/build.js";
|
|
16
32
|
import { iteratorSlotAdapter } from "./iterator-adapters.js";
|
|
17
33
|
import { lowerBuiltinCall } from "./builtin-calls.js";
|
|
@@ -19,7 +35,7 @@ import { CoercionState } from "./coercions/state.js";
|
|
|
19
35
|
import { widthLiftPlan, unitOnlyElem, recordWidthPlan, describeRecordWidthBlocker, objToRecordPlan, recordToClassPlan, } from "./coercions/structural-plans.js";
|
|
20
36
|
import { widthCoerce, applyWidthLift, unionRecordWidthHelper, recordWidthHelper, tupleArrayWidthHelper, emptyArrayLiftHelper, arrayWidthHelper, objRecordWidthHelper, recordClassWidthHelper, classStaticsProjection, } from "./coercions/structural.js";
|
|
21
37
|
import { funcReturnWidthAdapter, coercibleValue, cleanFuncAdaptable, funcCoerceAdapter, spawnResFnAdapterPlan, spawnResFnAdapter, } from "./coercions/function-adapters.js";
|
|
22
|
-
import { unionRetagMappable, narrowedRetagHelper, strandedUnitTrap, strandedCoercionTrap, recordUnionWrapHelper, unionRetagHelper, narrowedArmHelper, checkedNarrowCall, checkedNarrowOperand, deferredReadHelper, } from "./coercions/unions.js";
|
|
38
|
+
import { unionRetagMappable, narrowedRetagHelper, uninhabitedArmRetagHelper, strandedUnitTrap, strandedCoercionTrap, recordUnionRouteHelper, recordUnionWrapHelper, unionRetagHelper, narrowedArmHelper, checkedNarrowCall, checkedNarrowOperand, deferredReadHelper, } from "./coercions/unions.js";
|
|
23
39
|
import { lowerUtilTypeValue, pathModuleValue, utilTypesModuleValue, } from "./lower-builtin-values.js";
|
|
24
40
|
import { devirtualizeVirtualCalls } from "./devirtualize.js";
|
|
25
41
|
import { foldRegexSpanReads } from "./regex-span-reads.js";
|
|
@@ -41,11 +57,17 @@ import { InternalCompilerError } from "../../errors.js";
|
|
|
41
57
|
import { defaultAfterUndefined, lowerStaticallyUndefinedArgument } from "./optional-arguments.js";
|
|
42
58
|
import {} from "./class-protocol-dispatch.js";
|
|
43
59
|
import { ClassDynamicDispatch, trackClassFieldCreation } from "./class-dynamic-dispatch.js";
|
|
60
|
+
import { guardClassAttributeWrites } from "./class-attributes.js";
|
|
44
61
|
import { ClassProtocols } from "./class-protocols.js";
|
|
45
62
|
import { earlyReadVarSymbols } from "./var-hoisting.js";
|
|
46
63
|
import { recordTextCodecClass } from "../../ir/ir.js";
|
|
64
|
+
import { assignLegacyTiers } from "../../ir/tiers.js";
|
|
65
|
+
import { promoteJsvals } from "../../ir/jsval.js";
|
|
66
|
+
import { analyzeTiers, dynamicStatementCount, } from "../tier-analysis.js";
|
|
47
67
|
import { DeferredModuleInitializers } from "./deferred-module-initializers.js";
|
|
48
68
|
import { finalizeClassMethodValues } from "./class-method-values.js";
|
|
69
|
+
import { finalizePrivateBrands } from "./private-brands.js";
|
|
70
|
+
import { tableKeyFieldType } from "./symbol-fields.js";
|
|
49
71
|
export { newFnCtx } from "./function-context.js";
|
|
50
72
|
/* AST + checker → IR.
|
|
51
73
|
*
|
|
@@ -65,22 +87,27 @@ import { resolve } from "node:path";
|
|
|
65
87
|
import { bindingSource } from "../binding-source.js";
|
|
66
88
|
import { tsgoPath } from "../dts-paths.js";
|
|
67
89
|
import * as ts from "../ts7/adapter.js";
|
|
90
|
+
import { erasedTypeOnlyImport } from "../type-only-imports.js";
|
|
68
91
|
import { literalValues } from "../literal-values.js";
|
|
69
92
|
import { discriminantOwners, literalUnionArm } from "../union-discriminants.js";
|
|
70
93
|
import { unsupportedAnyOperationDiag, blockedBindingUseDiag, checkerPanicDiag, componentTypeDiag, isCheckerPanic, genericSignatureTypeDiag, indexSignatureTypeDiag, intersectionTypeDiag, noLoweringDiag, overloadedSignatureTypeDiag, recordShapeMismatchDiag, unsupportedNativeApiDiag, unsupportedPackageValueDiag, unionMismatchDiag, UNSUPPORTED, unsupportedDiag, unsupportedTypeDiag, } from "../../diagnostics/diagnostic.js";
|
|
71
94
|
import { arrayOf, BOOL, canAdaptDynFuncTo, canDynCheckTo, canConvertToDyn, DYN, DYN_HANDLE_KINDS, F64, isDynTypedRefType, isJsonSafeType, isJsonStringifySafeType, isPrimitiveCollectionKey, isSupportedMapKey, isSupportedMapValue, isUndefinedArmedUnion, isUnitType, NULL_T, RUNTIME_ERROR_CLASSES, STRING, typeEquals, UNDEFINED_T, VOID, } from "../../ir/ir.js";
|
|
72
95
|
import { provenanceActive } from "../provenance-registry.js";
|
|
73
|
-
import { ambientDtsPath, canonicalBuiltinModule, cjsExportAssignmentOf, cjsExportDiscardReason, fallbackDtsPath, isCjsExportTableLiteral, isCjsJsFile, isJsSourceFile, isNodeEsmFile, isNodeTypesPath, locOf, orderedImportsOf, overridesDtsPath, npmStaticDepSf7, requireSpecOf, resolveImport, workspacePackageOfPath, } from "../program.js";
|
|
74
|
-
import { containsRecord, containsUnion, describeComponentBlocker, describeRecordMemberBlocker, formatIrType, FETCH_AMBIENT_TYPES, isOsConstantsSymbol, isUnitOnlyTsType, isWorkerHandleType, jsOpenObjectType, mapType, ShapeRegistry, typeKey, UnionRegistry, withUndefinedArm as withUndefinedArmCanonical, } from "../type-mapper.js";
|
|
96
|
+
import { ambientDtsPath, canonicalBuiltinModule, cjsExportAssignmentOf, cjsExportDiscardReason, fallbackDtsPath, isCheckedJsSourceFile, isCjsExportTableLiteral, isCjsJsFile, isJsSourceFile, isNodeEsmFile, isNodeTypesPath, locOf, orderedImportsOf, overridesDtsPath, npmStaticDepSf7, requireSpecOf, resolveImport, workspacePackageOfPath, } from "../program.js";
|
|
97
|
+
import { containsRecord, containsUnion, describeComponentBlocker, describeRecordMemberBlocker, erasedOverloadMemberType, formatIrType, FETCH_AMBIENT_TYPES, isOsConstantsSymbol, isOverloadedCallableMemberType, isUnitOnlyTsType, isWorkerHandleType, isFetchHandleType, jsOpenObjectType, mapType, ShapeRegistry, typeKey, UnionRegistry, withUndefinedArm as withUndefinedArmCanonical, } from "../type-mapper.js";
|
|
75
98
|
import { builtinConstLit, builtinModuleConstOf, builtinModulesArrayLit, builtinFenceHintOf, builtinModuleFnOf, stdlibMemberFence, isStdlibMember, isStdlibSymbol, isStdlibGlobal, stdlibGlobalNameOf, stdlibGlobalMember, nodeTypesOnlySymbol, } from "./surfaces.js";
|
|
99
|
+
import { builtinClassAliasOf, runtimeClassValueOfType, } from "./builtins/class-values.js";
|
|
76
100
|
import { splitFiles, collectProgram, collectNpmImports, collectJsonImports, moduleArtifacts, collectGlobals, declSymbolOf, defaultExportSymbolOf, lowerFileInit, lowerDefaultExport, buildMain, appendDynamicImportModules, appendForkModules, appendWorkerModules, } from "./lower-modules.js";
|
|
77
|
-
import { prepareCjsModuleGraph } from "./lower-node-module.js";
|
|
101
|
+
import { prepareCjsModuleGraph, usesCjsTopLevelThis } from "./lower-node-module.js";
|
|
102
|
+
import { cjsNamespaceModule, cjsWholeExportValueOf, inlineNamespaceRequireOf, inlineProgramRequireOf, } from "./cjs-inline-require.js";
|
|
103
|
+
import { tscInteropModuleOf } from "./cjs-tsc-interop.js";
|
|
104
|
+
import { usesCjsExportsIdentity } from "./cjs-exports-object.js";
|
|
78
105
|
import { registerBuiltinEventTargetClasses } from "./lower-event-target.js";
|
|
79
|
-
import { registerBuiltinErrorClasses, registerBuiltinEmitterClass, registerBuiltinStreamClasses, builtinErrorInfoOf, builtinEmitterInfoOf, builtinStreamInfoOf, analyzeClassDecoration, classIteratorDrainCall, classIteratorNextCall, classIteratorOf, classIteratorOpenCall, classIteratorRestDrainCall, classMemberNameOf, classValueRef, collectClassShape, exactClassOfReceiver, collectClassShapeInner, ctorAbiEquals, findMethodOn, findStaticOn, genericClassInstanceType, isSubclassOf, inHierarchy, overrideBelow, staticShadowBelow, upcastTo, lowerClassMembers, lowerClassCtor, lowerClassExpression, lowerClassExpressionInfo, lowerClassMethodMember, lowerClassValueProperty, lowerStaticMethod, throwingSetterFn, fieldInitStmts, lowerStaticFieldInits, lowerStaticFieldRead, lowerDerivedCtorBody, superCallStmt, lowerSuperMethodCall, superThisRef, lowerSuperAccessorRead, lowerSuperAccessorWrite, inheritsBuiltinErrorCtor, inheritsBuiltinEmitterCtor, errorConstructorArgs, lowerNew, accessorCall, } from "./lower-classes.js";
|
|
106
|
+
import { registerBuiltinErrorClasses, defineClassValueConstruct, runtimeClassConstructs, registerBuiltinEmitterClass, registerBuiltinStreamClasses, builtinErrorInfoOf, builtinEmitterInfoOf, builtinStreamInfoOf, analyzeClassDecoration, classIteratorDrainCall, classIteratorNextCall, classIteratorOf, classIteratorOpenCall, classIteratorRestDrainCall, classMemberNameOf, classValueRef, collectClassShape, exactClassOfReceiver, collectClassShapeInner, ctorAbiEquals, findMethodOn, findStaticOn, genericClassInstanceType, isSubclassOf, inHierarchy, overrideBelow, staticShadowBelow, upcastTo, lowerClassMembers, lowerClassCtor, lowerClassExpression, lowerClassExpressionInfo, lowerClassMethodMember, lowerClassValueProperty, lowerStaticMethod, throwingSetterFn, fieldInitStmts, lowerStaticFieldInits, lowerStaticFieldRead, lowerDerivedCtorBody, superCallStmt, lowerSuperMethodCall, superThisRef, lowerSuperAccessorRead, lowerSuperAccessorWrite, inheritsBuiltinErrorCtor, inheritsBuiltinEmitterCtor, errorConstructorArgs, lowerNew, accessorCall, } from "./lower-classes.js";
|
|
80
107
|
import { mixinCallClassInfoOf, mixinIntersectionInstanceType, } from "./lower-mixins.js";
|
|
81
108
|
import { tryLowerExpression } from "./expressions/try-lower-expression.js";
|
|
82
109
|
import { funcTypeFromParamShapes, isThisParameter, paramShape, paramShapes, checkDefaultParamBodyType, requireExactArityValue, collectSignature, collectSignatureInner, lambdaSignature, } from "./call-signatures.js";
|
|
83
|
-
import { implicitAnyParamSymbolsOf, implicitMonoFile, collectGenericSignature, genericFnOf, lowerGenericCall, lowerGenericFnValue, inferTypeParamBindings, lowerGenericInstance, } from "./generic-functions.js";
|
|
110
|
+
import { implicitAnyParamSymbolsOf, implicitLocalFnNodeOf, implicitMonoFile, collectGenericSignature, genericFnOf, lowerGenericCall, lowerGenericFnValue, inferTypeParamBindings, lowerGenericInstance, genericLocalClassBinding, } from "./generic-functions.js";
|
|
84
111
|
import { bindingNeverReassigned } from "./binding-analysis.js";
|
|
85
112
|
import { bodyReadsArguments } from "../arguments-usage.js";
|
|
86
113
|
import { completeArgs, wrappedUndefined, undefinedArgFor } from "./call-arguments.js";
|
|
@@ -95,7 +122,7 @@ import { lowerEnvToPairsHelper } from "./containers/indexed-objects.js";
|
|
|
95
122
|
import { lowerBufferStaticCall, lowerBytesMethodCall, lowerBytesNew } from "./containers/bytes.js";
|
|
96
123
|
import { lowerRegexMethodCall, lowerStringMethodCall } from "./containers/string-and-regexp.js";
|
|
97
124
|
import { lowerEmitOverrideSpec, } from "./lower-event-emitter.js";
|
|
98
|
-
import { builtinImportOf, createRequireProgramModuleOf, createRequireSpecOf, fencedBuiltinImportOf, } from "./builtins/module-bindings.js";
|
|
125
|
+
import { builtinImportOf, createRequireProgramModuleOf, createRequireSpecOf, fencedBuiltinImportOf, esmImportBindingKind, } from "./builtins/module-bindings.js";
|
|
99
126
|
import { stripTypeCasts } from "./builtins/arguments.js";
|
|
100
127
|
import { lowerBuiltinModuleCall } from "./builtins/module-calls.js";
|
|
101
128
|
import { lowerTimersPromisesSetInterval, lowerTimeoutMethodCall } from "./builtins/timers.js";
|
|
@@ -114,13 +141,14 @@ import { lowerExecFileAsyncCall } from "./builtins/child-process-async.js";
|
|
|
114
141
|
import { lowerStringDecoderMethodCall, lowerTextCodecCall } from "./builtins/text-codecs.js";
|
|
115
142
|
import { lowerReadlineMethodCall } from "./builtins/readline.js";
|
|
116
143
|
import { lowerDiagnosticsChannelMethodCall, lowerDiagnosticsChannelProperty, lowerAsyncLocalStorageMethodCall, lowerTracingChannelMethodCall, lowerTracingChannelProperty, } from "./builtins/async-context.js";
|
|
144
|
+
import { lowerDisposableStackNew } from "./builtins/disposable-stack.js";
|
|
117
145
|
import { lowerErrorCodeProperty } from "./builtins/errors.js";
|
|
118
146
|
import { lowerProcessProperty, lowerProcessMethodCall, lowerProcessOptionalMethodCall, lowerProcessStreamProperty, } from "./builtins/process.js";
|
|
119
147
|
import { consoleCallMember, consoleMethodMember, isConsoleLog, } from "./builtins/console.js";
|
|
120
148
|
import { lowerConsoleNew } from "./lower-console.js";
|
|
121
149
|
import { lowerNumberStaticCall, lowerNumberStaticProperty } from "./builtins/numbers.js";
|
|
122
|
-
import { lowerDateCall } from "./builtins/dates.js";
|
|
123
|
-
import { lowerFsConstantsProperty, lowerBuiltinConstantsProperty, builtinConstantBindingOf, builtinConstantsDestructureDecl, } from "./builtins/constants.js";
|
|
150
|
+
import { dateJsonType, isDateJsonSource, lowerDateCall } from "./builtins/dates.js";
|
|
151
|
+
import { fsConstantMemberRead, fsConstantsObject, lowerFsConstantsProperty, lowerBuiltinConstantsProperty, builtinConstantBindingOf, builtinConstantsDestructureDecl, } from "./builtins/constants.js";
|
|
124
152
|
import { lowerStringStaticCall, lowerStringLastIndexOfCall } from "./builtins/strings.js";
|
|
125
153
|
import { lowerPromiseStaticCall } from "./builtins/promises.js";
|
|
126
154
|
import { fenceFetchObjectAssignment, fenceFetchObjectBinding, fenceStaticAbortControllerMemberRead, fenceStaticHeadersIteration, fenceStaticHeadersMember, fenceStaticReadableStreamMember, fenceStaticResponseMember, fenceUnsupportedFetchConstructorMember, refuseUnsupportedApi, stdlibGlobalFnOf, lowerAbortControllerNew, lowerEventTargetNew, lowerLiveWebValue, lowerDynamicImportCall, lowerFetchCall, lowerFetchElementMethodCall, lowerResponseNew, lowerFetchWebNew, lowerStaticFetchCompanionCall, lowerStaticAbortControllerCall, lowerStaticAbortSignalListenerCall, lowerStaticReadableStreamCancelCall, lowerStaticReadableStreamControllerCall, lowerStaticReadableStreamNew, lowerStaticReadableStreamReaderCall, lowerStaticResponseCall, lowerStdlibMethodCall, lowerMathProperty, npmPackageOf, npmMemberFence, npmPackageOfSymbol, } from "./lower-stdlib.js";
|
|
@@ -131,14 +159,15 @@ import { lowerAssertModuleCall, lowerAssertDirectCall } from "./lower-assert.js"
|
|
|
131
159
|
import { lowerUtilModuleCall } from "./lower-inspect.js";
|
|
132
160
|
import { lowerSystemErrorMapValue } from "./lower-system-errors.js";
|
|
133
161
|
import { lowerComptime, comptimeBakeable, rejectComptimeCaptures, comptimeValueToIr, } from "./lower-comptime.js";
|
|
134
|
-
import { lowerStmts, hasJsTypeAnnotation, noteBlockedBindings, isBlockedBinding, lowerScopedBlock, predeclareForwardCapture, predeclareForwardFnDecl, predeclareForwardVar, lowerStmt, lowerVarStatement, lowerDestructuringDecl, lowerDestructuringAssignParts, lowerBindingPattern, checkBindingElement, bindPatternTarget, isParseArgsDynCheckerType, lowerVarDeclList, lowerVarDecl, lowerSwitch, lowerTry, lowerExprStatement, lowerForOf, lowerForStatement, } from "./lower-stmts.js";
|
|
135
|
-
import { lowerExpr, maybeNarrow, lowerUnitComparison, lowerNullishCoalesce, lowerCondition, ensureBool, requireTruthyUnion, eqComparableUnion, lowerIntrinsicProperty, lowerArrayLiteral, lowerElementAccess, lowerElementWrite, lowerRecordKeyRead, ensureString, lowerTemplate, lowerAsExpression, lowerPrefixUnary, lowerBinary, lowerCaughtTypeofTest, caughtRead, caughtLocalOf, caughtToString, lowerInstanceOf, lowerRegexLiteral, lowerFieldRead, lowerUnionProperty, fieldTarget, fieldGetExpr, fieldSetStmt, lowerFieldCompound, uniqueSymbolKeyOf, } from "./lower-exprs.js";
|
|
162
|
+
import { lowerStmts, hasJsTypeAnnotation, noteBlockedBindings, isBlockedBinding, lowerScopedBlock, predeclareForwardCapture, predeclareForwardFnDecl, predeclareForwardVar, lowerStmt, lowerVarStatement, lowerDestructuringDecl, lowerDestructuringAssignParts, lowerBindingPattern, checkBindingElement, bindPatternTarget, isParseArgsDynCheckerType, lowerVarDeclList, lowerVarDecl, lowerSwitch, lowerTry, lowerExprStatement, lowerForOf, lowerForStatement, matchGroupsPatternSource, isGuardedRecordRead, } from "./lower-stmts.js";
|
|
163
|
+
import { lowerExpr, maybeNarrow, lowerUnitComparison, lowerNullishCoalesce, lowerCondition, ensureBool, requireTruthyUnion, eqComparableUnion, lowerIntrinsicProperty, lowerArrayLiteral, lowerElementAccess, lowerElementWrite, lowerRecordKeyRead, ensureString, lowerTemplate, lowerAsExpression, lowerPrefixUnary, lowerBinary, lowerCaughtTypeofTest, caughtRead, caughtLocalOf, caughtToString, lowerInstanceOf, lowerRegexLiteral, lowerFieldRead, lowerUnionProperty, fieldTarget, fieldGetExpr, fieldSetStmt, lowerFieldCompound, uniqueSymbolKeyOf, matchCallbackParamGroupsOf, } from "./lower-exprs.js";
|
|
136
164
|
import { finishOptionalChain, isOptionalChainTail, lowerOptionalChain, } from "./expressions/optional-chains.js";
|
|
137
165
|
import { foldedStringKeyOf, lowerDynObjectLiteral, lowerObjectLiteral, lowerShorthandValue, rejectThisInObjectMethod, } from "./expressions/object-literals.js";
|
|
138
166
|
import { lowerRecordFieldCall, lowerObjectMethodCall } from "./lower-calls.js";
|
|
139
167
|
import { fenceCrossBlockNsRef, nsPathPrefix } from "./lower-namespaces.js";
|
|
140
168
|
import { isSafeToRepeat } from "./expressions/evaluation-safety.js";
|
|
141
169
|
import { lowerTernary } from "./lower-exprs.js";
|
|
170
|
+
import { maybePromiseReturnStmt, maybePromiseUnionOf, promiseArmedUnionOf, } from "./maybe-promise.js";
|
|
142
171
|
/** Entry function name. '%' cannot appear in a TS identifier, so a user
|
|
143
172
|
* function can never collide with it (mangling is injective per prefix). */
|
|
144
173
|
export const ENTRY_NAME = "%main";
|
|
@@ -159,7 +188,7 @@ export function boundIdentifiersOf(name) {
|
|
|
159
188
|
if (ts.isIdentifier(name))
|
|
160
189
|
return [name];
|
|
161
190
|
const out = [];
|
|
162
|
-
for (const el of name.elements) {
|
|
191
|
+
for (const el of name.elements.nodes) {
|
|
163
192
|
// Elisions: OmittedExpression in 5.9.3, a NAMELESS BindingElement in 7
|
|
164
193
|
// (the parity battery's pinned finding 2) — both spell "no binding".
|
|
165
194
|
if (ts.isOmittedExpression(el) || el.name === undefined)
|
|
@@ -176,7 +205,7 @@ export function countBodyStatements(root) {
|
|
|
176
205
|
let n = 0;
|
|
177
206
|
const visit = (node) => {
|
|
178
207
|
if (ts.isBlock(node) || ts.isCaseClause(node) || ts.isDefaultClause(node)) {
|
|
179
|
-
n += node.statements.length;
|
|
208
|
+
n += node.statements.nodes.length;
|
|
180
209
|
}
|
|
181
210
|
else if ((ts.isIfStatement(node) ||
|
|
182
211
|
ts.isForStatement(node) ||
|
|
@@ -282,16 +311,20 @@ export function lowerToIr(program, entry, moduleOrder, options = {}) {
|
|
|
282
311
|
const libraryCallbacks = options.libraryCallbacks ?? false;
|
|
283
312
|
const externalTypes = options.externalTypes ?? new Map();
|
|
284
313
|
const externalTypeSpecifiersByFile = options.externalTypeSpecifiersByFile ?? directExternalTypeSpecifiersByFile(externalTypes);
|
|
314
|
+
const tierMode = options.tierMode ?? "auto";
|
|
285
315
|
const validation = new Lowerer(program, entry, moduleOrder, {
|
|
286
316
|
frontendServices: options.frontendServices,
|
|
317
|
+
projectCheckJs: options.projectCheckJs ?? false,
|
|
287
318
|
targetPlatform,
|
|
288
319
|
startupCrash,
|
|
320
|
+
inlineRequireCycleCalls: options.inlineRequireCycleCalls,
|
|
289
321
|
ffiImports,
|
|
290
322
|
libraryCallbacks,
|
|
291
323
|
forkTargets,
|
|
292
324
|
workerTargets,
|
|
293
325
|
externalTypes,
|
|
294
326
|
externalTypeSpecifiersByFile,
|
|
327
|
+
tierMode,
|
|
295
328
|
});
|
|
296
329
|
const ffiValidation = validateFfiImports(validation);
|
|
297
330
|
timing("ffi-validate");
|
|
@@ -304,14 +337,17 @@ export function lowerToIr(program, entry, moduleOrder, options = {}) {
|
|
|
304
337
|
? validation
|
|
305
338
|
: new Lowerer(program, entry, moduleOrder, {
|
|
306
339
|
frontendServices: options.frontendServices,
|
|
340
|
+
projectCheckJs: options.projectCheckJs ?? false,
|
|
307
341
|
targetPlatform,
|
|
308
342
|
startupCrash,
|
|
343
|
+
inlineRequireCycleCalls: options.inlineRequireCycleCalls,
|
|
309
344
|
ffiImports,
|
|
310
345
|
libraryCallbacks,
|
|
311
346
|
forkTargets,
|
|
312
347
|
workerTargets,
|
|
313
348
|
externalTypes,
|
|
314
349
|
externalTypeSpecifiersByFile,
|
|
350
|
+
tierMode,
|
|
315
351
|
ffiBindingSymbols: ffiValidation.symbolsByName,
|
|
316
352
|
});
|
|
317
353
|
for (const d of extraModuleCycleDiags)
|
|
@@ -319,10 +355,55 @@ export function lowerToIr(program, entry, moduleOrder, options = {}) {
|
|
|
319
355
|
for (const d of ffiValidation.diagnostics)
|
|
320
356
|
reachableEmit.pushDiag(d);
|
|
321
357
|
const emitted = reachableEmit.emitReachable(options.libRoots);
|
|
322
|
-
|
|
358
|
+
let { reachable } = emitted;
|
|
323
359
|
let result = emitted.result;
|
|
324
360
|
let resultLowerer = reachableEmit;
|
|
325
361
|
timing("reachable-emit", { reachable: reachable.size });
|
|
362
|
+
// The general stream representation (TypeMapperCtx.generalNodeStreams)
|
|
363
|
+
// is a per-program decision: only a program whose reachable code moved
|
|
364
|
+
// a general stream into a stdio-represented stream slot lowers again
|
|
365
|
+
// with it. Every other program keeps the single pass above unchanged.
|
|
366
|
+
const generalNodeStreams = reachableEmit.requiresGeneralNodeStreams;
|
|
367
|
+
// Checked-dynamic stream slots (dyn-streams.ts) are a further per-program
|
|
368
|
+
// decision under the general representation: only a program that moves an
|
|
369
|
+
// untyped value into a stream slot lowers again with them.
|
|
370
|
+
let dynNodeStreams = reachableEmit.requiresDynNodeStreams;
|
|
371
|
+
const streamPass = (dyn) => {
|
|
372
|
+
const general = new Lowerer(program, entry, moduleOrder, {
|
|
373
|
+
frontendServices: options.frontendServices,
|
|
374
|
+
projectCheckJs: options.projectCheckJs ?? false,
|
|
375
|
+
targetPlatform,
|
|
376
|
+
startupCrash,
|
|
377
|
+
inlineRequireCycleCalls: options.inlineRequireCycleCalls,
|
|
378
|
+
ffiImports,
|
|
379
|
+
libraryCallbacks,
|
|
380
|
+
forkTargets,
|
|
381
|
+
workerTargets,
|
|
382
|
+
externalTypes,
|
|
383
|
+
externalTypeSpecifiersByFile,
|
|
384
|
+
tierMode,
|
|
385
|
+
ffiBindingSymbols: ffiValidation.symbolsByName,
|
|
386
|
+
generalNodeStreams: true,
|
|
387
|
+
...(dyn ? { dynNodeStreams: true } : {}),
|
|
388
|
+
});
|
|
389
|
+
for (const d of extraModuleCycleDiags)
|
|
390
|
+
general.pushDiag(d);
|
|
391
|
+
for (const d of ffiValidation.diagnostics)
|
|
392
|
+
general.pushDiag(d);
|
|
393
|
+
const generalEmitted = general.emitReachable(options.libRoots);
|
|
394
|
+
reachable = generalEmitted.reachable;
|
|
395
|
+
result = generalEmitted.result;
|
|
396
|
+
resultLowerer = general;
|
|
397
|
+
timing(dyn ? "dyn-streams-relower" : "general-streams-relower", { reachable: reachable.size });
|
|
398
|
+
return general;
|
|
399
|
+
};
|
|
400
|
+
if (generalNodeStreams) {
|
|
401
|
+
const general = streamPass(dynNodeStreams);
|
|
402
|
+
if (!dynNodeStreams && general.requiresDynNodeStreams) {
|
|
403
|
+
dynNodeStreams = true;
|
|
404
|
+
streamPass(true);
|
|
405
|
+
}
|
|
406
|
+
}
|
|
326
407
|
// A generic class-rest support decision can depend on record metadata
|
|
327
408
|
// whose historical owner is discovered only while retained bodies lower.
|
|
328
409
|
// If the settled answer is a fence, rerun the ordinary reachable emit so
|
|
@@ -330,12 +411,16 @@ export function lowerToIr(program, entry, moduleOrder, options = {}) {
|
|
|
330
411
|
// declarators stay unvisited, bindings block, cascades and stats match the
|
|
331
412
|
// historical compiler. This is a rare compatibility fallback; programs
|
|
332
413
|
// without such a settled fence retain checker-backed IR exactly once.
|
|
333
|
-
if (
|
|
414
|
+
if (resultLowerer.requiresHistoricalOrderRelower) {
|
|
334
415
|
const emit = new Lowerer(program, entry, moduleOrder, {
|
|
335
416
|
frontendServices: options.frontendServices,
|
|
417
|
+
projectCheckJs: options.projectCheckJs ?? false,
|
|
418
|
+
...(generalNodeStreams ? { generalNodeStreams: true } : {}),
|
|
419
|
+
...(dynNodeStreams ? { dynNodeStreams: true } : {}),
|
|
336
420
|
reachable,
|
|
337
421
|
targetPlatform,
|
|
338
422
|
startupCrash,
|
|
423
|
+
inlineRequireCycleCalls: options.inlineRequireCycleCalls,
|
|
339
424
|
ffiImports,
|
|
340
425
|
libraryCallbacks,
|
|
341
426
|
forkTargets,
|
|
@@ -343,6 +428,7 @@ export function lowerToIr(program, entry, moduleOrder, options = {}) {
|
|
|
343
428
|
ffiBindingSymbols: ffiValidation.symbolsByName,
|
|
344
429
|
externalTypes,
|
|
345
430
|
externalTypeSpecifiersByFile,
|
|
431
|
+
tierMode,
|
|
346
432
|
});
|
|
347
433
|
for (const d of extraModuleCycleDiags)
|
|
348
434
|
emit.pushDiag(d);
|
|
@@ -391,13 +477,45 @@ export function lowerToIr(program, entry, moduleOrder, options = {}) {
|
|
|
391
477
|
};
|
|
392
478
|
else if (contracts.count > 0)
|
|
393
479
|
result = { ...result, contracts };
|
|
480
|
+
const discoverModules = (onModule) => discoverWasmModules({
|
|
481
|
+
files: moduleOrder.includes(entry) ? moduleOrder : [...moduleOrder, entry],
|
|
482
|
+
entry: entry.fileName,
|
|
483
|
+
configured: options.wasmFiles ?? [],
|
|
484
|
+
resolveRequest: (fromFile, specifier) => {
|
|
485
|
+
const resolved = resolveRequireRuntime(fromFile, specifier, targetPlatform, undefined, options.frontendServices);
|
|
486
|
+
return resolved.ok ? resolved.value : null;
|
|
487
|
+
},
|
|
488
|
+
...(onModule === undefined ? {} : { onModule }),
|
|
489
|
+
});
|
|
490
|
+
// A program that uses the WebAssembly API carries every module the build
|
|
491
|
+
// can see and translate (wasm/translate.ts); the rest fail at run time
|
|
492
|
+
// with the CompileError for untranslated bytes.
|
|
493
|
+
if (result.module !== null && resultLowerer.usesWebAssembly) {
|
|
494
|
+
const bytesByHash = new Map();
|
|
495
|
+
const reports = discoverModules((sha256, bytes) => bytesByHash.set(sha256, bytes));
|
|
496
|
+
const wasmModules = [];
|
|
497
|
+
for (const report of reports) {
|
|
498
|
+
const bytes = bytesByHash.get(report.sha256);
|
|
499
|
+
if (report.status !== "valid" || bytes === undefined)
|
|
500
|
+
continue;
|
|
501
|
+
wasmModules.push({ sha256: report.sha256, bytes: encodeBase64(bytes) });
|
|
502
|
+
}
|
|
503
|
+
result.module.wasmModules = wasmModules;
|
|
504
|
+
if (resultLowerer.usesWasmCustomSections)
|
|
505
|
+
result.module.wasmCustomSections = true;
|
|
506
|
+
timing("wasm-discovery", { modules: wasmModules.length });
|
|
507
|
+
}
|
|
394
508
|
if (options.coverage !== true)
|
|
395
509
|
return result;
|
|
396
|
-
const
|
|
510
|
+
const remainderPass = (general, dyn = dynNodeStreams) => new Lowerer(program, entry, moduleOrder, {
|
|
397
511
|
frontendServices: options.frontendServices,
|
|
512
|
+
projectCheckJs: options.projectCheckJs ?? false,
|
|
513
|
+
...(general ? { generalNodeStreams: true } : {}),
|
|
514
|
+
...(general && dyn ? { dynNodeStreams: true } : {}),
|
|
398
515
|
reachable,
|
|
399
516
|
remainder: true,
|
|
400
517
|
alreadyFlushed: resultLowerer.flushedSymbols,
|
|
518
|
+
inlineRequireCycleCalls: options.inlineRequireCycleCalls,
|
|
401
519
|
targetPlatform,
|
|
402
520
|
ffiImports,
|
|
403
521
|
libraryCallbacks,
|
|
@@ -406,19 +524,58 @@ export function lowerToIr(program, entry, moduleOrder, options = {}) {
|
|
|
406
524
|
ffiBindingSymbols: ffiValidation.symbolsByName,
|
|
407
525
|
externalTypes,
|
|
408
526
|
externalTypeSpecifiersByFile,
|
|
527
|
+
tierMode,
|
|
409
528
|
});
|
|
410
|
-
|
|
529
|
+
let remainder = remainderPass(generalNodeStreams);
|
|
530
|
+
let rem = remainder.run();
|
|
531
|
+
// Unreached code reports what it would compile to once reached: a
|
|
532
|
+
// stream flow there that needs the general representation lowers the
|
|
533
|
+
// remainder again with it, as reachable emit would.
|
|
534
|
+
if (!generalNodeStreams && remainder.requiresGeneralNodeStreams) {
|
|
535
|
+
remainder = remainderPass(true, remainder.requiresDynNodeStreams);
|
|
536
|
+
rem = remainder.run();
|
|
537
|
+
}
|
|
538
|
+
if (!dynNodeStreams && remainder.generalNodeStreams && remainder.requiresDynNodeStreams) {
|
|
539
|
+
remainder = remainderPass(true, true);
|
|
540
|
+
rem = remainder.run();
|
|
541
|
+
}
|
|
542
|
+
timing("coverage-remainder");
|
|
543
|
+
// Tiers (tier-analysis.ts): reached statements in dynamic-tier functions,
|
|
544
|
+
// and with tierReport the report-only demotion analysis.
|
|
545
|
+
const dynamicFunctions = resultLowerer.dynamicBodies;
|
|
546
|
+
const tiers = options.tierReport === undefined
|
|
547
|
+
? undefined
|
|
548
|
+
: analyzeTiers(program, {
|
|
549
|
+
mode: tierMode,
|
|
550
|
+
dynamicFunctions,
|
|
551
|
+
reached: [...options.tierReport.preflight, ...result.diagnostics],
|
|
552
|
+
deferred: result.runtimeFences,
|
|
553
|
+
unreached: [...rem.diagnostics, ...rem.runtimeFences],
|
|
554
|
+
});
|
|
555
|
+
// A dynamic function's own statements can include ones that failed.
|
|
556
|
+
const statementsDynamic = Math.min(tiers?.statementsDynamic ?? dynamicStatementCount(program, dynamicFunctions), result.stats.statementsTotal - result.stats.statementsFailed);
|
|
557
|
+
if (tiers !== undefined)
|
|
558
|
+
tiers.statementsDynamic = statementsDynamic;
|
|
559
|
+
timing("tier-analysis", { dynamic: dynamicFunctions.length });
|
|
411
560
|
// Unreached JS statements whose fences deferred to runtime count as
|
|
412
561
|
// failed statements in the remainder's stats, so their diagnostics must
|
|
413
562
|
// travel with them: a failed statement is never left unexplained.
|
|
414
|
-
|
|
563
|
+
const covered = {
|
|
415
564
|
...result,
|
|
565
|
+
stats: { ...result.stats, statementsDynamic },
|
|
416
566
|
unreached: {
|
|
417
567
|
diagnostics: rem.diagnostics,
|
|
418
568
|
stats: rem.stats,
|
|
419
569
|
...(rem.runtimeFences.length > 0 ? { runtimeFences: rem.runtimeFences } : {}),
|
|
420
570
|
},
|
|
421
571
|
};
|
|
572
|
+
if (tiers !== undefined)
|
|
573
|
+
covered.tiers = tiers;
|
|
574
|
+
const wasmModules = discoverModules();
|
|
575
|
+
timing("wasm-discovery", { modules: wasmModules.length });
|
|
576
|
+
if (wasmModules.length > 0)
|
|
577
|
+
covered.wasmModules = wasmModules;
|
|
578
|
+
return covered;
|
|
422
579
|
}
|
|
423
580
|
/** The native namespace type produced by a literal static import() of a
|
|
424
581
|
* compiled program module or supported Node builtin. This syntax-level
|
|
@@ -442,7 +599,7 @@ export function staticImportNamespaceType(lowerer, expr) {
|
|
|
442
599
|
}
|
|
443
600
|
if (!ts.isCallExpression(e) || e.expression.kind !== ts.SyntaxKind.ImportKeyword)
|
|
444
601
|
return null;
|
|
445
|
-
const arg = e.arguments[0];
|
|
602
|
+
const arg = e.arguments.nodes[0];
|
|
446
603
|
if (!arg || !ts.isStringLiteralLike(arg))
|
|
447
604
|
return null;
|
|
448
605
|
const builtin = canonicalBuiltinModule(arg.text);
|
|
@@ -450,9 +607,7 @@ export function staticImportNamespaceType(lowerer, expr) {
|
|
|
450
607
|
if (moduleId === null) {
|
|
451
608
|
const symbol = lowerer.checker.getSymbolAtLocation(arg);
|
|
452
609
|
const source = symbol &&
|
|
453
|
-
|
|
454
|
-
.declarationsOf(symbol)
|
|
455
|
-
.find((decl) => ts.isSourceFile(decl) && !decl.isDeclarationFile);
|
|
610
|
+
symbol.declarations.find((decl) => ts.isSourceFile(decl) && !decl.isDeclarationFile);
|
|
456
611
|
if (source &&
|
|
457
612
|
!source.fileName.endsWith(".cts") &&
|
|
458
613
|
!isCjsJsFile(source, lowerer.program) &&
|
|
@@ -486,7 +641,7 @@ export function uncheckedOverloadHandleCall(_lowerer, _expr) {
|
|
|
486
641
|
* `never` at the ROOT stays out (`for (const v of [])`'s loop var — the
|
|
487
642
|
* dead read the f64 mapping is FOR). */
|
|
488
643
|
export function neverTaintedJsType(lowerer, node, t) {
|
|
489
|
-
if (!isJsSourceFile(
|
|
644
|
+
if (!isJsSourceFile(ts.getSourceFileOfNode(node)))
|
|
490
645
|
return false;
|
|
491
646
|
const walk = (x, depth) => {
|
|
492
647
|
if (depth === 0)
|
|
@@ -513,7 +668,7 @@ export function ladderFenceExpr(lowerer, surface, node, hint) {
|
|
|
513
668
|
const loc = locOf(node);
|
|
514
669
|
const d = noLoweringDiag(surface, loc, hint);
|
|
515
670
|
lowerer.runtimeFences.push(d);
|
|
516
|
-
const sf =
|
|
671
|
+
const sf = ts.getSourceFileOfNode(node);
|
|
517
672
|
const pos = ts.getLineAndCharacterOfPosition(sf, loc.start);
|
|
518
673
|
return {
|
|
519
674
|
kind: "strLit",
|
|
@@ -525,7 +680,7 @@ export function ladderFenceExpr(lowerer, surface, node, hint) {
|
|
|
525
680
|
export function dynFallbackType(lowerer, node, t) {
|
|
526
681
|
if (t.flags & ts.TypeFlags.Void)
|
|
527
682
|
return null;
|
|
528
|
-
if (!isJsSourceFile(
|
|
683
|
+
if (!isJsSourceFile(ts.getSourceFileOfNode(node))) {
|
|
529
684
|
if (t.flags & ts.TypeFlags.Any)
|
|
530
685
|
return DYN;
|
|
531
686
|
const symbol = t.getSymbol();
|
|
@@ -538,14 +693,15 @@ export function dynFallbackType(lowerer, node, t) {
|
|
|
538
693
|
((lowerer.checker.getTypeArguments(x)[0]?.flags ?? 0) &
|
|
539
694
|
ts.TypeFlags.Any) !==
|
|
540
695
|
0;
|
|
541
|
-
if (symbol
|
|
696
|
+
if (symbol !== undefined &&
|
|
697
|
+
ts.symbolName(symbol) === "Promise" &&
|
|
542
698
|
args[0] &&
|
|
543
699
|
(args[0].flags & ts.TypeFlags.Any || anyArray(args[0])))
|
|
544
|
-
return symbol
|
|
700
|
+
return ts.symbolName(symbol) === "Promise" && anyArray(args[0])
|
|
545
701
|
? { kind: "promise", inner: DYN }
|
|
546
702
|
: jsFallbackPromiseType(lowerer, t);
|
|
547
703
|
if (symbol &&
|
|
548
|
-
["Generator", "AsyncGenerator", "IterableIterator"].includes(symbol
|
|
704
|
+
["Generator", "AsyncGenerator", "IterableIterator"].includes(ts.symbolName(symbol)) &&
|
|
549
705
|
args.some((arg) => arg.flags & ts.TypeFlags.Any))
|
|
550
706
|
return jsFallbackGeneratorType(lowerer, t);
|
|
551
707
|
if (lowerer.checker.isArrayType(t) &&
|
|
@@ -565,19 +721,23 @@ export function dynFallbackType(lowerer, node, t) {
|
|
|
565
721
|
if (generator)
|
|
566
722
|
return generator;
|
|
567
723
|
const symbol = t.getSymbol();
|
|
568
|
-
if ((symbol
|
|
724
|
+
if (((symbol !== undefined && ts.symbolName(symbol) === "Map") ||
|
|
725
|
+
(symbol !== undefined && ts.symbolName(symbol) === "ReadonlyMap")) &&
|
|
569
726
|
lowerer.isStdlibSymbol(symbol)) {
|
|
570
727
|
const args = lowerer.checker.getTypeArguments(t);
|
|
571
728
|
if (args.length === 2) {
|
|
572
729
|
const key = lowerer.mapTypeOf(args[0]);
|
|
573
730
|
const value = lowerer.mapTypeOf(args[1]);
|
|
731
|
+
// Inferred JS function types keep the checked-dynamic slot (their
|
|
732
|
+
// closures carry JS arity, not a typed closure ABI).
|
|
574
733
|
return {
|
|
575
734
|
kind: "map",
|
|
576
735
|
key: key &&
|
|
736
|
+
key.kind !== "func" &&
|
|
577
737
|
isSupportedMapKey(key, key.kind === "union" ? lowerer.unions.get(key.unionId)?.arms : undefined)
|
|
578
738
|
? key
|
|
579
739
|
: DYN,
|
|
580
|
-
value: value && isSupportedMapValue(value) ? value : DYN,
|
|
740
|
+
value: value && value.kind !== "func" && isSupportedMapValue(value) ? value : DYN,
|
|
581
741
|
};
|
|
582
742
|
}
|
|
583
743
|
}
|
|
@@ -646,7 +806,9 @@ export function dynFallbackType(lowerer, node, t) {
|
|
|
646
806
|
* has no fixed shape. The settled value crosses the checked native boundary. */
|
|
647
807
|
function jsFallbackPromiseType(lowerer, t) {
|
|
648
808
|
const symbol = t.getSymbol();
|
|
649
|
-
if (symbol
|
|
809
|
+
if (symbol === undefined ||
|
|
810
|
+
ts.symbolName(symbol) !== "Promise" ||
|
|
811
|
+
!lowerer.isStdlibSymbol(symbol))
|
|
650
812
|
return null;
|
|
651
813
|
const inner = lowerer.checker.getTypeArguments(t)[0];
|
|
652
814
|
return inner ? { kind: "promise", inner: lowerer.mapTypeOf(inner) ?? DYN } : null;
|
|
@@ -656,14 +818,14 @@ function jsFallbackPromiseType(lowerer, t) {
|
|
|
656
818
|
function jsFallbackGeneratorType(lowerer, t) {
|
|
657
819
|
const symbol = t.getSymbol();
|
|
658
820
|
if (!symbol ||
|
|
659
|
-
!["Generator", "AsyncGenerator", "IterableIterator"].includes(symbol
|
|
821
|
+
!["Generator", "AsyncGenerator", "IterableIterator"].includes(ts.symbolName(symbol)) ||
|
|
660
822
|
!lowerer.isStdlibSymbol(symbol))
|
|
661
823
|
return null;
|
|
662
824
|
const [yielded, returned, resumed] = lowerer.checker.getTypeArguments(t);
|
|
663
825
|
const unit = ts.TypeFlags.Void | ts.TypeFlags.Undefined | ts.TypeFlags.Never;
|
|
664
826
|
return {
|
|
665
827
|
kind: "generator",
|
|
666
|
-
...(symbol
|
|
828
|
+
...(ts.symbolName(symbol) === "AsyncGenerator" ? { async: true } : {}),
|
|
667
829
|
yieldT: yielded && yielded.flags & ts.TypeFlags.Never ? VOID : DYN,
|
|
668
830
|
retT: !returned || returned.flags & unit ? VOID : DYN,
|
|
669
831
|
nextT: !resumed || resumed.flags & unit ? UNDEFINED_T : DYN,
|
|
@@ -682,7 +844,7 @@ function jsFallbackFunctionType(lowerer, node, t) {
|
|
|
682
844
|
// slot. JS inference reports the body type (`boolean` for
|
|
683
845
|
// `enabled = true`) rather than that call-site type, so recover the
|
|
684
846
|
// syntactic optionality from the parameter declaration.
|
|
685
|
-
const decl =
|
|
847
|
+
const decl = p.valueDeclaration;
|
|
686
848
|
mapped = jsOpenObjectType(decl, mapped, lowerer.shapes, lowerer.unions);
|
|
687
849
|
const optional = decl !== undefined &&
|
|
688
850
|
ts.isParameter(decl) &&
|
|
@@ -693,9 +855,9 @@ function jsFallbackFunctionType(lowerer, node, t) {
|
|
|
693
855
|
return mapped;
|
|
694
856
|
});
|
|
695
857
|
const retT = lowerer.checker.getReturnTypeOfSignature(sig);
|
|
696
|
-
const sigDecl =
|
|
858
|
+
const sigDecl = sig.declaration;
|
|
697
859
|
const jsUnitReturn = sigDecl !== undefined &&
|
|
698
|
-
isJsSourceFile(
|
|
860
|
+
isJsSourceFile(ts.getSourceFileOfNode(sigDecl)) &&
|
|
699
861
|
(retT.flags & (ts.TypeFlags.Null | ts.TypeFlags.Undefined)) !== 0;
|
|
700
862
|
const ret = jsUnitReturn
|
|
701
863
|
? DYN
|
|
@@ -719,20 +881,21 @@ function jsArgumentsFunctionType(lowerer, t) {
|
|
|
719
881
|
lowerer.checker.getConstructSignatures(t).length !== 0 ||
|
|
720
882
|
lowerer.checker.getPropertiesOfType(t).length !== 0)
|
|
721
883
|
return null;
|
|
722
|
-
const decl =
|
|
884
|
+
const decl = sigs[0].declaration;
|
|
723
885
|
if (decl === undefined ||
|
|
724
886
|
!(ts.isFunctionDeclaration(decl) ||
|
|
725
887
|
ts.isFunctionExpression(decl) ||
|
|
726
888
|
ts.isArrowFunction(decl)) ||
|
|
727
|
-
!isJsSourceFile(
|
|
889
|
+
!isJsSourceFile(ts.getSourceFileOfNode(decl)))
|
|
728
890
|
return null;
|
|
729
|
-
const hasRest = decl.parameters.some((p) => p.dotDotDotToken !== undefined);
|
|
891
|
+
const hasRest = decl.parameters.nodes.some((p) => p.dotDotDotToken !== undefined);
|
|
730
892
|
if (!hasRest &&
|
|
731
893
|
(ts.isArrowFunction(decl) ||
|
|
732
894
|
!bodyReadsArguments(decl) ||
|
|
733
|
-
(decl.parameters.length > 0 &&
|
|
895
|
+
(decl.parameters.nodes.length > 0 &&
|
|
896
|
+
!isNodeEsmFile(ts.getSourceFileOfNode(decl), lowerer.program))))
|
|
734
897
|
return null;
|
|
735
|
-
const shapes = paramShapes(lowerer, decl.parameters);
|
|
898
|
+
const shapes = paramShapes(lowerer, decl.parameters.nodes);
|
|
736
899
|
const retType = lowerer.checker.getReturnTypeOfSignature(sigs[0]);
|
|
737
900
|
const ret = retType.flags & (ts.TypeFlags.Null | ts.TypeFlags.Undefined)
|
|
738
901
|
? DYN
|
|
@@ -754,15 +917,15 @@ function pureSingleCallSignatureOf(lowerer, t) {
|
|
|
754
917
|
lowerer.checker.getConstructSignatures(t).length === 0 &&
|
|
755
918
|
sigs[0].getTypeParameters().length === 0 &&
|
|
756
919
|
sigs[0].getParameters().every((p) => {
|
|
757
|
-
const pDecl =
|
|
920
|
+
const pDecl = p.valueDeclaration;
|
|
758
921
|
return !pDecl || !ts.isParameter(pDecl) || pDecl.dotDotDotToken === undefined;
|
|
759
922
|
}) &&
|
|
760
923
|
// A SYNTHESIZED rest param (tsc's `arguments` inference — no
|
|
761
924
|
// valueDeclaration to carry the dotDotDot): param-count mismatch
|
|
762
925
|
// against the signature's declaration; the whole value stays dyn.
|
|
763
926
|
(() => {
|
|
764
|
-
const sigDecl =
|
|
765
|
-
const declParams = sigDecl !== undefined && ts.isFunctionLike(sigDecl) ? sigDecl.parameters : undefined;
|
|
927
|
+
const sigDecl = sigs[0].declaration;
|
|
928
|
+
const declParams = sigDecl !== undefined && ts.isFunctionLike(sigDecl) ? sigDecl.parameters.nodes : undefined;
|
|
766
929
|
if (declParams !== undefined && declParams.length !== sigs[0].getParameters().length)
|
|
767
930
|
return false;
|
|
768
931
|
// tsgo never synthesizes the `arguments` pseudo-rest into the
|
|
@@ -817,7 +980,7 @@ export function jsFuncNameOf(node, lowerer) {
|
|
|
817
980
|
if (!symbol || seen.has(symbol))
|
|
818
981
|
break;
|
|
819
982
|
seen.add(symbol);
|
|
820
|
-
const declaration =
|
|
983
|
+
const declaration = symbol.valueDeclaration;
|
|
821
984
|
if (declaration && ts.isFunctionDeclaration(declaration)) {
|
|
822
985
|
n = declaration;
|
|
823
986
|
break;
|
|
@@ -870,6 +1033,25 @@ function panicSafe(query, fallback) {
|
|
|
870
1033
|
throw e;
|
|
871
1034
|
}
|
|
872
1035
|
}
|
|
1036
|
+
/** The function's class expressions lower once per implicit-any instance.
|
|
1037
|
+
* A function whose only implicit slots are destructured options and that
|
|
1038
|
+
* is bound to a variable the implicit-instance probe rejects runs as one
|
|
1039
|
+
* shared body, so its classes keep a single name. */
|
|
1040
|
+
function monomorphizedImplicit(lowerer, fn) {
|
|
1041
|
+
const slots = implicitAnyParamSymbolsOf(lowerer, fn);
|
|
1042
|
+
if (!slots)
|
|
1043
|
+
return false;
|
|
1044
|
+
if (slots.some((slot) => slot !== null))
|
|
1045
|
+
return true;
|
|
1046
|
+
let binding = fn.parent;
|
|
1047
|
+
while (binding && ts.isParenthesizedExpression(binding))
|
|
1048
|
+
binding = binding.parent;
|
|
1049
|
+
if ((ts.isArrowFunction(fn) || ts.isFunctionExpression(fn)) &&
|
|
1050
|
+
binding &&
|
|
1051
|
+
ts.isVariableDeclaration(binding))
|
|
1052
|
+
return implicitLocalFnNodeOf(lowerer, binding) !== null;
|
|
1053
|
+
return true;
|
|
1054
|
+
}
|
|
873
1055
|
export class Lowerer {
|
|
874
1056
|
program;
|
|
875
1057
|
entry;
|
|
@@ -878,6 +1060,12 @@ export class Lowerer {
|
|
|
878
1060
|
checker;
|
|
879
1061
|
diags = [];
|
|
880
1062
|
fnSigsBySymbol = new Map();
|
|
1063
|
+
/** Per file: whether it assigns `exports` and `module.exports`
|
|
1064
|
+
* (cjs-exports-object.ts). */
|
|
1065
|
+
cjsExportsAssignments = new Map();
|
|
1066
|
+
/** Inline require() calls whose module edge closes a require cycle
|
|
1067
|
+
* (LoadResult.inlineRequireCycleCalls). */
|
|
1068
|
+
inlineRequireCycleCalls;
|
|
881
1069
|
/** Immutable callable aliases and compiler-generated adapters. The map
|
|
882
1070
|
* is symbol-keyed, so shadowing and cross-module imports keep the same
|
|
883
1071
|
* exact binding discipline as globals/functions. */
|
|
@@ -906,7 +1094,7 @@ export class Lowerer {
|
|
|
906
1094
|
* indexed-read analysis and expression lowering share one instance, so a
|
|
907
1095
|
* read's representation and its callers' signatures always agree. */
|
|
908
1096
|
get stringIndexBounds() {
|
|
909
|
-
this.stringIndexBoundsCache ??= new StringIndexBounds((node) => this.checker.getSymbolAtLocation(node) ?? null, (symbol) =>
|
|
1097
|
+
this.stringIndexBoundsCache ??= new StringIndexBounds((node) => this.checker.getSymbolAtLocation(node) ?? null, (symbol) => symbol.valueDeclaration, (node) => (this.typeOf(node).flags & ts.TypeFlags.StringLike) !== 0);
|
|
910
1098
|
return this.stringIndexBoundsCache;
|
|
911
1099
|
}
|
|
912
1100
|
/** Syntactic writes indexed once per JS scope. Symbol and RHS type
|
|
@@ -1097,7 +1285,29 @@ export class Lowerer {
|
|
|
1097
1285
|
/** Non-null while an instance body lowers: type-parameter symbol →
|
|
1098
1286
|
* concrete IR type, consulted inside mapType's recursion. */
|
|
1099
1287
|
typeParamBindings = null;
|
|
1288
|
+
/** Generic lambdas lowering as erased values (lowerLambda): their own
|
|
1289
|
+
* type parameters are bound to `unknown`, so lambdaSignature admits
|
|
1290
|
+
* them. */
|
|
1291
|
+
erasingLambdas = new Set();
|
|
1292
|
+
/** Function expressions lowered against a fixed target signature with a
|
|
1293
|
+
* tuple-typed `arguments` (typed-arguments.ts). */
|
|
1294
|
+
typedArgumentsLambdas = new Set();
|
|
1295
|
+
/** Const bindings holding a forwarded fixed tuple (`const args =
|
|
1296
|
+
* arguments as any` in a typed-arguments function) → the tuple type. */
|
|
1297
|
+
tupleAliasSymbols = new Map();
|
|
1298
|
+
/** `??` expressions whose result is the optional callback's own function
|
|
1299
|
+
* type (an adapted function default); their bindings take that type. */
|
|
1300
|
+
nullishFuncResults = new Set();
|
|
1301
|
+
/** The static names of the current generic instance's name-keyed
|
|
1302
|
+
* function parameters (static-function-names.ts). */
|
|
1303
|
+
staticFnNames = null;
|
|
1304
|
+
/** Nesting depth of erased generic bodies being lowered (erased lambdas
|
|
1305
|
+
* and erased instances). */
|
|
1306
|
+
erasingDepth = 0;
|
|
1100
1307
|
localClassInstantiations = [];
|
|
1308
|
+
/** Instance types (by checker type id) of the local classes generic
|
|
1309
|
+
* factory calls return, and the per-instance class each names. */
|
|
1310
|
+
localClassInstanceTypes = new Map();
|
|
1101
1311
|
/** The ts-level twin of typeParamBindings, non-null while a CALL-keyed
|
|
1102
1312
|
* instance body lowers: type-parameter symbol → the bound CHECKER type,
|
|
1103
1313
|
* consulted where the mapped IrType has already widened away information
|
|
@@ -1111,6 +1321,19 @@ export class Lowerer {
|
|
|
1111
1321
|
* typeParamBindings — the checker has no `T` to substitute, so the
|
|
1112
1322
|
* binding rides the node-type accessor instead of mapType. */
|
|
1113
1323
|
implicitParamTypes = null;
|
|
1324
|
+
/** The builtin class each binding names (`const E = EventEmitter`,
|
|
1325
|
+
* `const C = zlib.Gzip`), keyed by the binding's symbol; null for
|
|
1326
|
+
* bindings that name none (builtinClassAliasOf). new, instanceof,
|
|
1327
|
+
* typeof, .name and === resolve at compile time. */
|
|
1328
|
+
builtinClassAliases = new Map();
|
|
1329
|
+
/** Whether some net.Socket in this program may get an encoding: a
|
|
1330
|
+
* setEncoding call whose receiver is a socket or an untyped value.
|
|
1331
|
+
* Computed once on first use (null until then). */
|
|
1332
|
+
socketEncodingReachable = null;
|
|
1333
|
+
/** Whether some server in this program may listen on a Unix socket: a
|
|
1334
|
+
* listen call whose first argument is a string. Computed once on first
|
|
1335
|
+
* use (null until then); address() answers the path only when true. */
|
|
1336
|
+
unixListenReachable = null;
|
|
1114
1337
|
/** IMPLICIT-ANY instances lowered EAGERLY at first demand (their return
|
|
1115
1338
|
* types are inferred from the body — the call site needs them settled),
|
|
1116
1339
|
* collected here for run()'s function list (the liftedFns discipline). */
|
|
@@ -1126,8 +1349,13 @@ export class Lowerer {
|
|
|
1126
1349
|
* their symbol/node keys; no module-level cache should retain a pass. */
|
|
1127
1350
|
classSymbolKeys = new Map();
|
|
1128
1351
|
registeredClassSymbols = new Map();
|
|
1352
|
+
/** Symbol-key identities by description, in resolution order (the slot
|
|
1353
|
+
* ordinals of key-table keys — symbolKeyOf). */
|
|
1354
|
+
symbolFieldIdentities = new Map();
|
|
1129
1355
|
httpClientFnBindings = new Map();
|
|
1130
1356
|
streamPropMutatedSyms = null;
|
|
1357
|
+
/** Whether some source reads process.exitCode (processReadsExitCode). */
|
|
1358
|
+
readsExitCode = null;
|
|
1131
1359
|
requestInitPropMutatedSyms = null;
|
|
1132
1360
|
emitterEventTable = null;
|
|
1133
1361
|
emitterComputedPatterns = [];
|
|
@@ -1156,6 +1384,12 @@ export class Lowerer {
|
|
|
1156
1384
|
* carry undefined at runtime. Identifier reads keep the union tag so
|
|
1157
1385
|
* typeof and later boundaries observe the real value. */
|
|
1158
1386
|
runtimeOptionalGlobals = new Set();
|
|
1387
|
+
/** Per CommonJS file using top-level `this`: the global holding the
|
|
1388
|
+
* object that stands for its original exports (lowerCjsTopLevelThis). */
|
|
1389
|
+
cjsExportsThis = new Map();
|
|
1390
|
+
/** Inline program-module require calls whose %init the enclosing member
|
|
1391
|
+
* read or member call is already sequencing (cjs-inline-require.ts). */
|
|
1392
|
+
inlineRequireInitDone = new Set();
|
|
1159
1393
|
/** Bindings whose unchecked string arithmetic can produce either a number
|
|
1160
1394
|
* (NaN for an absent read) or a string. Preserve that result union at bare
|
|
1161
1395
|
* reads instead of applying the checker-bare string narrowing adapter. */
|
|
@@ -1168,7 +1402,9 @@ export class Lowerer {
|
|
|
1168
1402
|
/** A pipeline() function stage's `source` parameter: the IR type of what
|
|
1169
1403
|
* the pipeline passes it (the previous stage as an async iterable), set
|
|
1170
1404
|
* while the stage lowers. Parameter typing and `for await` heads read
|
|
1171
|
-
* it before the checker's `AsyncIterable<T>`.
|
|
1405
|
+
* it before the checker's `AsyncIterable<T>`. A stream option callback's
|
|
1406
|
+
* completion parameter declared with an any-typed `data` is pinned here
|
|
1407
|
+
* too while the callback lowers (pinAnyDataCompletion). */
|
|
1172
1408
|
stageSourceTypes = new Map();
|
|
1173
1409
|
/** Set when a match result lowers to execGroups/matchGroups, the inputs
|
|
1174
1410
|
* of regex span folding. */
|
|
@@ -1178,6 +1414,10 @@ export class Lowerer {
|
|
|
1178
1414
|
* declared optional binding to that read's bare type, so presence tests
|
|
1179
1415
|
* on these bindings consult the stored tag instead. */
|
|
1180
1416
|
runtimeOptionalAssignedSymbols = new Set();
|
|
1417
|
+
/** Generic function declarations whose body can return an indexed read
|
|
1418
|
+
* that misses.
|
|
1419
|
+
* Each instance's result admits undefined (generic-functions.ts). */
|
|
1420
|
+
runtimeOptionalGenericReturns = new Set();
|
|
1181
1421
|
/** Concise callback/lambda returns promoted by the HOF callback prepass;
|
|
1182
1422
|
* arrows have no declaration symbol to key in fnSigsBySymbol. */
|
|
1183
1423
|
runtimeOptionalFunctionReturns = new Map();
|
|
@@ -1191,6 +1431,8 @@ export class Lowerer {
|
|
|
1191
1431
|
/** Record fields promoted to an undefined-armed union by an indexed-read
|
|
1192
1432
|
* value. The key is the concrete emitted shape and field name. */
|
|
1193
1433
|
runtimeOptionalFields = new Set();
|
|
1434
|
+
/** Bindings initialized by a Date's `toJSON()` (analyzeDateJsonResults). */
|
|
1435
|
+
dateJsonBindings = new Set();
|
|
1194
1436
|
/** Record bindings whose flow class reaches storage outside the class:
|
|
1195
1437
|
* they keep the declared layout, so an initializer from unchecked reads
|
|
1196
1438
|
* converts once instead of the binding adopting the widened variant. */
|
|
@@ -1238,7 +1480,7 @@ export class Lowerer {
|
|
|
1238
1480
|
// directly from the aliased declaration as a final read-side hook, so
|
|
1239
1481
|
// the initializer cannot fall back to a narrowing adapter.
|
|
1240
1482
|
if (ts.isIdentifier(node) && fallback?.kind === "func") {
|
|
1241
|
-
const decl =
|
|
1483
|
+
const decl = symbol.valueDeclaration;
|
|
1242
1484
|
if (decl &&
|
|
1243
1485
|
ts.isVariableDeclaration(decl) &&
|
|
1244
1486
|
!decl.type &&
|
|
@@ -1264,6 +1506,63 @@ export class Lowerer {
|
|
|
1264
1506
|
}
|
|
1265
1507
|
return fallback ?? null;
|
|
1266
1508
|
}
|
|
1509
|
+
/** A TypeScript object literal handed to a JavaScript checked-value
|
|
1510
|
+
* parameter whose inferred type is open (`constructor({ factory, ...options
|
|
1511
|
+
* } = {})` — the rest element admits any property): the literal names a
|
|
1512
|
+
* property the contextual JS type does not declare, so it has no record
|
|
1513
|
+
* layout there and is built as the plain object the JS side receives. */
|
|
1514
|
+
excessJsContextualProperty(literal, contextual) {
|
|
1515
|
+
const objects = contextual.filter((part) => !(part.flags & (ts.TypeFlags.Undefined | ts.TypeFlags.Null)));
|
|
1516
|
+
if (objects.length === 0)
|
|
1517
|
+
return false;
|
|
1518
|
+
// Only a destructuring pattern with a rest element is open; other
|
|
1519
|
+
// inferred JS types keep their record lowering.
|
|
1520
|
+
const fromJs = objects.every((part) => {
|
|
1521
|
+
const sym = part.getSymbol();
|
|
1522
|
+
return (sym !== undefined &&
|
|
1523
|
+
sym.declarations.some((d) => {
|
|
1524
|
+
if (!isJsSourceFile(ts.getSourceFileOfNode(d)))
|
|
1525
|
+
return false;
|
|
1526
|
+
// The pattern itself, or the `= {}` default of a pattern parameter.
|
|
1527
|
+
const pattern = ts.isObjectLiteralExpression(d) &&
|
|
1528
|
+
d.parent !== undefined &&
|
|
1529
|
+
ts.isParameter(d.parent) &&
|
|
1530
|
+
d.parent.initializer === d
|
|
1531
|
+
? d.parent.name
|
|
1532
|
+
: d;
|
|
1533
|
+
return (ts.isObjectBindingPattern(pattern) &&
|
|
1534
|
+
pattern.elements.nodes.some((element) => element.dotDotDotToken !== undefined));
|
|
1535
|
+
}));
|
|
1536
|
+
});
|
|
1537
|
+
if (!fromJs)
|
|
1538
|
+
return false;
|
|
1539
|
+
return literal.properties.nodes.some((prop) => {
|
|
1540
|
+
if (!prop.name || !(ts.isIdentifier(prop.name) || ts.isStringLiteral(prop.name)))
|
|
1541
|
+
return false;
|
|
1542
|
+
const name = prop.name.text;
|
|
1543
|
+
return objects.every((part) => !this.checker.getPropertyOfType(part, name));
|
|
1544
|
+
});
|
|
1545
|
+
}
|
|
1546
|
+
/** The index value of a keyed read of a record's index signature that
|
|
1547
|
+
* can answer undefined for a missing key while its checker type does not
|
|
1548
|
+
* admit undefined, or null. A literal key naming a declared field is a
|
|
1549
|
+
* field read. */
|
|
1550
|
+
optionalIndexSignatureRead(e) {
|
|
1551
|
+
const receiver = panicSafe(() => this.mapTypeOf(this.typeOf(e.expression)), null);
|
|
1552
|
+
if (receiver?.kind !== "record")
|
|
1553
|
+
return null;
|
|
1554
|
+
const shape = this.shapes.get(receiver.shapeId);
|
|
1555
|
+
if (!shape || shape.tuple || !shape.indexValue || shape.indexValue.kind === "dyn")
|
|
1556
|
+
return null;
|
|
1557
|
+
const key = e.argumentExpression;
|
|
1558
|
+
if ((ts.isStringLiteral(key) || ts.isNumericLiteral(key)) &&
|
|
1559
|
+
shape.fields.some((field) => field.name === key.text))
|
|
1560
|
+
return null;
|
|
1561
|
+
const read = panicSafe(() => this.mapTypeOf(this.typeOf(e)), null);
|
|
1562
|
+
if (read?.kind === "union" && this.armTag(read.unionId, UNDEFINED_T) >= 0)
|
|
1563
|
+
return null;
|
|
1564
|
+
return shape.indexValue;
|
|
1565
|
+
}
|
|
1267
1566
|
runtimeOptionalIdentifierValue(node) {
|
|
1268
1567
|
if (!ts.isIdentifier(node) || this.chainRecvByNode.has(node))
|
|
1269
1568
|
return null;
|
|
@@ -1283,45 +1582,53 @@ export class Lowerer {
|
|
|
1283
1582
|
unionId: storage.type.unionId,
|
|
1284
1583
|
};
|
|
1285
1584
|
}
|
|
1286
|
-
/**
|
|
1287
|
-
*
|
|
1288
|
-
*
|
|
1289
|
-
* optional-read analysis
|
|
1290
|
-
*
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
if (slot)
|
|
1294
|
-
return slot;
|
|
1585
|
+
/** True when `node`'s lowered value can hold a hidden `undefined` the
|
|
1586
|
+
* checker type does not admit: an unchecked element or member read, a call
|
|
1587
|
+
* whose lowered return admits undefined, or a binding whose storage the
|
|
1588
|
+
* optional-read analysis marked. Whether the value actually carries the
|
|
1589
|
+
* undefined arm is only known once it is lowered
|
|
1590
|
+
* (runtimeOptionalSourceValue); this is the syntactic precondition. */
|
|
1591
|
+
isRuntimeOptionalOrigin(node) {
|
|
1295
1592
|
let origin = node;
|
|
1296
1593
|
while (ts.isParenthesizedExpression(origin))
|
|
1297
1594
|
origin = origin.expression;
|
|
1298
|
-
|
|
1595
|
+
if (ts.isElementAccessExpression(origin) || ts.isPropertyAccessExpression(origin))
|
|
1596
|
+
return true;
|
|
1299
1597
|
if (ts.isCallExpression(origin)) {
|
|
1300
1598
|
const name = ts.isPropertyAccessExpression(origin.expression)
|
|
1301
1599
|
? origin.expression.name
|
|
1302
1600
|
: origin.expression;
|
|
1303
1601
|
const symbol = ts.isIdentifier(name) ? this.resolveValueSymbol(name) : undefined;
|
|
1304
1602
|
const signature = symbol ? this.fnSigsBySymbol.get(symbol) : undefined;
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
(signature
|
|
1308
|
-
this.armTag(signature.returnType.unionId, UNDEFINED_T) >= 0);
|
|
1603
|
+
return (this.runtimeOptionalFunctionReturns.has(origin) ||
|
|
1604
|
+
(signature?.returnType.kind === "union" &&
|
|
1605
|
+
this.armTag(signature.returnType.unionId, UNDEFINED_T) >= 0));
|
|
1309
1606
|
}
|
|
1310
1607
|
if (ts.isIdentifier(origin)) {
|
|
1311
1608
|
const local = this.resolveLocal(origin);
|
|
1312
1609
|
const root = local ? this.runtimeOptionalRootOf(local) : null;
|
|
1313
1610
|
const global = this.globalOf(origin);
|
|
1314
|
-
|
|
1315
|
-
(!!
|
|
1316
|
-
(
|
|
1317
|
-
(this.
|
|
1318
|
-
(global.type.kind === "union" && this.armTag(global.type.unionId, UNDEFINED_T) >= 0)));
|
|
1611
|
+
return ((!!root && this.runtimeOptionalStorageLocals.has(root)) ||
|
|
1612
|
+
(!!global &&
|
|
1613
|
+
(this.isRuntimeOptionalGlobal(global) ||
|
|
1614
|
+
(global.type.kind === "union" && this.armTag(global.type.unionId, UNDEFINED_T) >= 0))));
|
|
1319
1615
|
}
|
|
1320
|
-
|
|
1616
|
+
return false;
|
|
1617
|
+
}
|
|
1618
|
+
/** Recover the original optional union when a checked single-arm helper
|
|
1619
|
+
* was installed before a strict property consumer could name its member.
|
|
1620
|
+
* Recovery covers member reads and storage roots marked by the
|
|
1621
|
+
* optional-read analysis, so ordinary assertions keep their generic
|
|
1622
|
+
* checked-narrow behavior. */
|
|
1623
|
+
runtimeOptionalSourceValue(node, value) {
|
|
1624
|
+
const slot = this.deferredFieldSlot(value);
|
|
1625
|
+
if (slot)
|
|
1626
|
+
return slot;
|
|
1627
|
+
if (!this.isRuntimeOptionalOrigin(node))
|
|
1321
1628
|
return null;
|
|
1322
1629
|
// A checked JavaScript indexed read can already be boxed. The checker
|
|
1323
1630
|
// calls the element present, but that inference is not a runtime guard.
|
|
1324
|
-
if (isJsSourceFile(
|
|
1631
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(node)) &&
|
|
1325
1632
|
value.kind === "dynCheck" &&
|
|
1326
1633
|
value.value.type.kind === "dyn")
|
|
1327
1634
|
return value.value;
|
|
@@ -1337,7 +1644,7 @@ export class Lowerer {
|
|
|
1337
1644
|
* value. Reuse a plain read directly or stabilize an effectful receiver
|
|
1338
1645
|
* once, throw Node's member-read TypeError for a unit arm, and extract the
|
|
1339
1646
|
* expected present arm otherwise. */
|
|
1340
|
-
runtimeOptionalPropertyReceiver(node, value, expected, member) {
|
|
1647
|
+
runtimeOptionalPropertyReceiver(node, value, expected, member, action = "read") {
|
|
1341
1648
|
const source = this.runtimeOptionalSourceValue(node, value);
|
|
1342
1649
|
if (source?.type.kind !== "union")
|
|
1343
1650
|
return null;
|
|
@@ -1375,7 +1682,7 @@ export class Lowerer {
|
|
|
1375
1682
|
type: BOOL,
|
|
1376
1683
|
loc,
|
|
1377
1684
|
},
|
|
1378
|
-
then: nodeThrowExpr(1, "", `Cannot
|
|
1685
|
+
then: nodeThrowExpr(1, "", `Cannot ${action} properties of ${unit} (${action === "read" ? "reading" : "setting"} '${member}')`, expected, loc),
|
|
1379
1686
|
else_: result,
|
|
1380
1687
|
type: expected,
|
|
1381
1688
|
loc,
|
|
@@ -1542,10 +1849,28 @@ export class Lowerer {
|
|
|
1542
1849
|
/** Settled generic class-rest metadata requires the historical emit
|
|
1543
1850
|
* fallback so its fence can poison the original statement atomically. */
|
|
1544
1851
|
requiresHistoricalOrderRelower = false;
|
|
1852
|
+
/** A general stream value (a runtime stream class instance) reached a
|
|
1853
|
+
* slot the child/process stdio handles represent — NodeJS.ReadableStream,
|
|
1854
|
+
* NodeJS.WritableStream, or @types/node's stream.Readable/Writable — or
|
|
1855
|
+
* a stdio handle reached an 'unknown' slot. lowerToIr then lowers the
|
|
1856
|
+
* program again under the general stream representation. */
|
|
1857
|
+
requiresGeneralNodeStreams = false;
|
|
1858
|
+
/** An untyped value reached a stream slot (a checked unwrap into a
|
|
1859
|
+
* runtime stream class, or an untyped pipe/pipeline stage). lowerToIr
|
|
1860
|
+
* then lowers the program again with checked-dynamic stream slots
|
|
1861
|
+
* (dyn-streams.ts). */
|
|
1862
|
+
requiresDynNodeStreams = false;
|
|
1863
|
+
/** Receiver representations forced by the per-value stream dispatch
|
|
1864
|
+
* (dyn-streams.ts): the native arm lowers a member call on the unboxed
|
|
1865
|
+
* stream through the ordinary class-method path. */
|
|
1866
|
+
receiverTypeOverrides = new Map();
|
|
1545
1867
|
/** Helpers that snapshot shape declaration order into their bodies.
|
|
1546
1868
|
* Reachability lowers inits before the declarations they discover, so
|
|
1547
1869
|
* these rebuild after the worklist restores historical shape metadata. */
|
|
1548
1870
|
shapeOrderHelperFinalizers = [];
|
|
1871
|
+
/** Construction witnesses that choose each shape's enumeration order
|
|
1872
|
+
* once lowering settles (key-order-witness.ts). */
|
|
1873
|
+
keyOrder = new KeyOrderNotes();
|
|
1549
1874
|
/** Emit-override specializations (`%C.emit:<event>` — lower-event-emitter.ts's
|
|
1550
1875
|
* emit-overrides block): interned names, the drive-loop queue, and the
|
|
1551
1876
|
* currently-lowering specialization's context (the super-forward
|
|
@@ -1557,6 +1882,9 @@ export class Lowerer {
|
|
|
1557
1882
|
/** Generated value helpers, keyed by operation and type. Callers own
|
|
1558
1883
|
* their key prefixes; this includes more than structural conversions. */
|
|
1559
1884
|
valueHelpers = new Map();
|
|
1885
|
+
/** structuralNarrowing's assignable classes, keyed by static and
|
|
1886
|
+
* narrowed class name. */
|
|
1887
|
+
structuralClassPeers = new Map();
|
|
1560
1888
|
/** Interned node:assert helpers (deep-equality comparisons keyed by
|
|
1561
1889
|
* typeKey, throws wrappers keyed by callback type + expected class) —
|
|
1562
1890
|
* the valueHelpers pattern with its own namespace. */
|
|
@@ -1577,6 +1905,12 @@ export class Lowerer {
|
|
|
1577
1905
|
/** Method adapter names are owned by class-method-values. Looking them
|
|
1578
1906
|
* up must not scan and retain every unrelated lifted function. */
|
|
1579
1907
|
classMethodValueHelpers = new Set();
|
|
1908
|
+
/** Reflected class methods whose lambda is lowering right now (null
|
|
1909
|
+
* until lowerLambda named it), with the closure it will produce: a
|
|
1910
|
+
* method that reads itself as a value inside its own body
|
|
1911
|
+
* (`o.create = K.create`) takes this closure instead of lowering the
|
|
1912
|
+
* method again. */
|
|
1913
|
+
methodLambdasInProgress = new Map();
|
|
1580
1914
|
classMethodValueSelections = new Map();
|
|
1581
1915
|
/** Callee names of every interned coercion helper whose CALL mints a
|
|
1582
1916
|
* FRESH closure per evaluation (%fn.width.*, %fn.adapt.*,
|
|
@@ -1598,6 +1932,10 @@ export class Lowerer {
|
|
|
1598
1932
|
* lifted lazily as module-level functions and interned per accessor
|
|
1599
1933
|
* declaration: member reads call the getter (lower-exprs). */
|
|
1600
1934
|
cjsAccessorFns = new Map();
|
|
1935
|
+
/** Accessor exports' link-time values for ES-module importers, and the
|
|
1936
|
+
* per-module flag that the copy already ran (cjsAccessorSnapshotStores). */
|
|
1937
|
+
cjsAccessorSnapshots = new Map();
|
|
1938
|
+
cjsSnapshotReady = new Map();
|
|
1601
1939
|
/** Interned `%iter.drain.<n>` helpers (classIteratorDrainCall): one per
|
|
1602
1940
|
* receiver class — the eager drain of a class iterable's protocol into
|
|
1603
1941
|
* a fresh element array, behind array/call spreads. */
|
|
@@ -1622,6 +1960,8 @@ export class Lowerer {
|
|
|
1622
1960
|
* so named imports, namespace reads, CommonJS bindings, and alias chains
|
|
1623
1961
|
* all reuse one immortal zero-capture closure. */
|
|
1624
1962
|
builtinCallableValueFns = new Map();
|
|
1963
|
+
/** Each builtin function-value adapter's Node name, for boxed values. */
|
|
1964
|
+
builtinCallableValueNames = new Map();
|
|
1625
1965
|
/** Optional-chain lowering state. While a chain body lowers, the guarded
|
|
1626
1966
|
* receiver NODE reads as a chainRecv (typed by the narrowed arm) instead
|
|
1627
1967
|
* of re-lowering, its checker type reads non-nullish (typeOf), and the
|
|
@@ -1663,6 +2003,10 @@ export class Lowerer {
|
|
|
1663
2003
|
/** Named method slots observed before class collection need a callable
|
|
1664
2004
|
* ABI and shared prototype descriptors instead of call-site specialization. */
|
|
1665
2005
|
prototypeMethodAccesses = new Map();
|
|
2006
|
+
/** Well-known symbol methods (`sym:iterator`) the program may replace
|
|
2007
|
+
* through a symbol-keyed write: an instance or prototype property, or a
|
|
2008
|
+
* reflection call. */
|
|
2009
|
+
replacedSymbolMethods = new Set();
|
|
1666
2010
|
/** Typed calls through class-backed protocols, by signature; class
|
|
1667
2011
|
* dynamic dispatch adds their native arms (class-protocol-dispatch.ts). */
|
|
1668
2012
|
protocolDispatches = new Map();
|
|
@@ -1680,6 +2024,9 @@ export class Lowerer {
|
|
|
1680
2024
|
* base vtable signature is collected. Unused checked slots carry undefined. */
|
|
1681
2025
|
virtualJsMethodArity = new Map();
|
|
1682
2026
|
checkedVirtualJsMethods = new Set();
|
|
2027
|
+
/** Overrides whose return narrows part of the base's union return; they
|
|
2028
|
+
* return through the base's union ABI (overrideReturnAbi). */
|
|
2029
|
+
unionReturnOverrides = new Set();
|
|
1683
2030
|
checkedVirtualJsAccessors = new Set();
|
|
1684
2031
|
checkedVirtualJsValueReturns = new Set();
|
|
1685
2032
|
/** The class whose members are lowering — `super` binds lexically to it
|
|
@@ -1703,6 +2050,10 @@ export class Lowerer {
|
|
|
1703
2050
|
* prepended by lowerFileInit so the bindings are live before any
|
|
1704
2051
|
* top-level statement runs. */
|
|
1705
2052
|
jsonInitActions = new Map();
|
|
2053
|
+
/** CommonJS require() of JSON documents: the shared object per document
|
|
2054
|
+
* and the calls reading it (json-require.ts). */
|
|
2055
|
+
jsonRequireModules = new Map();
|
|
2056
|
+
jsonRequireCalls = new Map();
|
|
1706
2057
|
/** Dynamic `import("literal")` resolutions, keyed
|
|
1707
2058
|
* `fileName\u0000specifier` (collectDynamicImports fills it during npm
|
|
1708
2059
|
* collection; lowerDynamicImportCall reads it per site). */
|
|
@@ -1716,6 +2067,10 @@ export class Lowerer {
|
|
|
1716
2067
|
/** Inline Promise.then parameters whose contextual type is a builtin
|
|
1717
2068
|
* module namespace anonymous object. The settled native token is the
|
|
1718
2069
|
* ABI truth even when the checker type has no stable module symbol. */
|
|
2070
|
+
/** Receivers of a stream call on a Hash or Hmac (lowerHashStreamCall):
|
|
2071
|
+
* for the duration of that call, the receiver lowers to the Transform of
|
|
2072
|
+
* the value held in the named local. */
|
|
2073
|
+
hashStreamReceivers = new Map();
|
|
1719
2074
|
moduleNsParamOverrides = new Map();
|
|
1720
2075
|
/** File → qualifier prefix: "" for the entry, "%mI." otherwise. */
|
|
1721
2076
|
fileTag = new Map();
|
|
@@ -1724,6 +2079,12 @@ export class Lowerer {
|
|
|
1724
2079
|
workerTargets;
|
|
1725
2080
|
workerTargetIdByPath = new Map();
|
|
1726
2081
|
usesWorkers = false;
|
|
2082
|
+
/** The program uses the WebAssembly API (builtins/webassembly.ts): the
|
|
2083
|
+
* build translates the modules it discovers. */
|
|
2084
|
+
usesWebAssembly = false;
|
|
2085
|
+
/** The program calls WebAssembly.Module.customSections: translated
|
|
2086
|
+
* modules keep their custom sections. */
|
|
2087
|
+
usesWasmCustomSections = false;
|
|
1727
2088
|
/** The program constructs a LifetimeRegion (lifetime-regions.ts). */
|
|
1728
2089
|
usesLifetimeRegions = false;
|
|
1729
2090
|
/** Per-directory answers of experimental-import.ts's declaration-file test. */
|
|
@@ -1734,6 +2095,12 @@ export class Lowerer {
|
|
|
1734
2095
|
internTableHelpers = new Map();
|
|
1735
2096
|
/** Each InternTable name's type arguments and first construction site. */
|
|
1736
2097
|
internTableNames = new Map();
|
|
2098
|
+
/** Each ThreadSlots name's type arguments (thread-slots.ts). */
|
|
2099
|
+
threadSlotNames = new Map();
|
|
2100
|
+
/** The family each `new ThreadSlots(...)` opens. */
|
|
2101
|
+
threadSlotFamilies = new Map();
|
|
2102
|
+
/** Classes used as ThreadSlots keys: their hierarchies carry a slot word. */
|
|
2103
|
+
threadSlotKeys = new Set();
|
|
1737
2104
|
forkTargetIdByPath = new Map();
|
|
1738
2105
|
/** Namespace ModuleBlocks this program lowers, filled by splitFiles:
|
|
1739
2106
|
* "flattened" — an instantiated namespace whose body joined the file's
|
|
@@ -1818,6 +2185,9 @@ export class Lowerer {
|
|
|
1818
2185
|
// top level, top = the innermost nested function currently lowering).
|
|
1819
2186
|
fnStack = [];
|
|
1820
2187
|
liftedFns = [];
|
|
2188
|
+
/** Runtime-provided classes used as values (defineClassValueConstruct),
|
|
2189
|
+
* by IR class name. */
|
|
2190
|
+
runtimeClassValues = new Map();
|
|
1821
2191
|
/** One Error-method helper belongs to this lowering session. Its cached
|
|
1822
2192
|
* dispatch revision needs no weak-key identity or process-global state. */
|
|
1823
2193
|
errorMethodDispatchRevision = null;
|
|
@@ -1844,6 +2214,17 @@ export class Lowerer {
|
|
|
1844
2214
|
* by class name (cycle-initialization.ts). */
|
|
1845
2215
|
classInitFlags = new Map();
|
|
1846
2216
|
cycleInitDeclarations = new Map();
|
|
2217
|
+
/** Each class's constructor return plan by class name
|
|
2218
|
+
* (constructor-returns.ts); null when no return can yield an object. */
|
|
2219
|
+
constructorReturnPlans = new Map();
|
|
2220
|
+
/** Pointer-guarded (`tdz`) module bindings declared without an
|
|
2221
|
+
* initializer (`let f: T;`): an initialization flag tracks their
|
|
2222
|
+
* declaration (markCycleEarlyBindings). */
|
|
2223
|
+
uninitializedLexicalGlobals = new Map();
|
|
2224
|
+
/** CommonJS require declarations whose bindings code running before the
|
|
2225
|
+
* require can read, and those references (require-initialization.ts). */
|
|
2226
|
+
requireInitFlags = new Map();
|
|
2227
|
+
requireEarlyReferences = [];
|
|
1847
2228
|
get ctx() {
|
|
1848
2229
|
const top = this.fnStack[this.fnStack.length - 1];
|
|
1849
2230
|
if (!top)
|
|
@@ -1879,6 +2260,16 @@ export class Lowerer {
|
|
|
1879
2260
|
/** Coverage remainder mode: the reachability gate inverts (see wantBody)
|
|
1880
2261
|
* and no module is built. */
|
|
1881
2262
|
remainder;
|
|
2263
|
+
/** `--tier` (tier-analysis.ts). Stage S2 is report-only: both modes
|
|
2264
|
+
* refuse and fence exactly as before. Stage S6 demotes the units of
|
|
2265
|
+
* committed refusals in "auto" and keeps them refusals in "static-only". */
|
|
2266
|
+
tierMode;
|
|
2267
|
+
generalNodeStreams;
|
|
2268
|
+
dynNodeStreams;
|
|
2269
|
+
/** Functions finishModule placed in the dynamic tier (ir/tiers.ts). */
|
|
2270
|
+
dynamicFunctions = [];
|
|
2271
|
+
/** Their IR, for coverage's dynamic statement count. */
|
|
2272
|
+
dynamicBodies = [];
|
|
1882
2273
|
/** Deferred collection diagnostics (failed signatures/class shapes) by
|
|
1883
2274
|
* declaration symbol: an unreached declaration must not fail the build,
|
|
1884
2275
|
* so its diagnostics wait until a reference makes them relevant. */
|
|
@@ -1903,6 +2294,9 @@ export class Lowerer {
|
|
|
1903
2294
|
targetPlatform;
|
|
1904
2295
|
/** LowererMode.startupCrash — buildMain opens %main with the throw. */
|
|
1905
2296
|
startupCrash;
|
|
2297
|
+
/** The project's tsconfig sets `checkJs`. */
|
|
2298
|
+
projectCheckJs;
|
|
2299
|
+
checkedJsFiles = new Map();
|
|
1906
2300
|
/** Outbound native bindings by their source-level ambient name. */
|
|
1907
2301
|
ffiImports;
|
|
1908
2302
|
libraryCallbacks;
|
|
@@ -1941,6 +2335,33 @@ export class Lowerer {
|
|
|
1941
2335
|
* package. Only populated while the registry is active; the remainder
|
|
1942
2336
|
* pass skips it (attribution describes the build). */
|
|
1943
2337
|
statsByFile = new Map();
|
|
2338
|
+
/** Statements and field initializers already in the coverage totals, and
|
|
2339
|
+
* those already counted as failed. Speculative lowering can lower one
|
|
2340
|
+
* function body several times: each receiver probe of
|
|
2341
|
+
* `(function () { ... }).call(this)` lowers it. A source statement counts
|
|
2342
|
+
* once however many times it lowers. */
|
|
2343
|
+
countedStatements = new Set();
|
|
2344
|
+
failedStatements = new Set();
|
|
2345
|
+
/** Adds `node` to the coverage totals unless it is already counted (the
|
|
2346
|
+
* caller checks suppressStats). */
|
|
2347
|
+
countStatement(node, file) {
|
|
2348
|
+
if (this.countedStatements.has(node))
|
|
2349
|
+
return;
|
|
2350
|
+
this.countedStatements.add(node);
|
|
2351
|
+
this.stats.statementsTotal++;
|
|
2352
|
+
if (file !== undefined)
|
|
2353
|
+
this.bumpFileStat(file, "total");
|
|
2354
|
+
}
|
|
2355
|
+
/** Counts `node` as failed unless it already is (the caller checks
|
|
2356
|
+
* suppressStats). */
|
|
2357
|
+
countStatementFailed(node, file) {
|
|
2358
|
+
if (this.failedStatements.has(node))
|
|
2359
|
+
return;
|
|
2360
|
+
this.failedStatements.add(node);
|
|
2361
|
+
this.stats.statementsFailed++;
|
|
2362
|
+
if (file !== undefined)
|
|
2363
|
+
this.bumpFileStat(file, "failed");
|
|
2364
|
+
}
|
|
1944
2365
|
/** Bumps the per-file attribution counter (no-op unless provenance is
|
|
1945
2366
|
* active and this is the emit/discovery lane — mirror the CALLER's
|
|
1946
2367
|
* suppressStats guard, this method only gates remainder). */
|
|
@@ -1959,25 +2380,31 @@ export class Lowerer {
|
|
|
1959
2380
|
this.program = program;
|
|
1960
2381
|
this.entry = entry;
|
|
1961
2382
|
this.moduleOrder = moduleOrder;
|
|
2383
|
+
// The mode's options, sorted by name; the values derived from them follow.
|
|
2384
|
+
this.alreadyFlushed = mode.alreadyFlushed ?? new Set();
|
|
2385
|
+
this.externalTypes = mode.externalTypes ?? new Map();
|
|
2386
|
+
this.ffiBindingSymbols = mode.ffiBindingSymbols ?? null;
|
|
2387
|
+
this.ffiImports = mode.ffiImports ?? [];
|
|
2388
|
+
this.forkTargets = mode.forkTargets ?? [];
|
|
1962
2389
|
this.frontendServices = mode.frontendServices;
|
|
2390
|
+
this.inlineRequireCycleCalls = mode.inlineRequireCycleCalls ?? new Set();
|
|
2391
|
+
this.libraryCallbacks = mode.libraryCallbacks ?? false;
|
|
2392
|
+
this.projectCheckJs = mode.projectCheckJs ?? false;
|
|
1963
2393
|
this.reachable = mode.reachable ?? null;
|
|
1964
2394
|
this.remainder = mode.remainder ?? false;
|
|
1965
|
-
this.alreadyFlushed = mode.alreadyFlushed ?? new Set();
|
|
1966
|
-
this.targetPlatform = mode.targetPlatform ?? process.platform;
|
|
1967
2395
|
this.startupCrash = mode.startupCrash ?? null;
|
|
1968
|
-
this.
|
|
1969
|
-
this.
|
|
2396
|
+
this.targetPlatform = mode.targetPlatform ?? process.platform;
|
|
2397
|
+
this.tierMode = mode.tierMode ?? "auto";
|
|
2398
|
+
this.generalNodeStreams = mode.generalNodeStreams ?? false;
|
|
2399
|
+
this.dynNodeStreams = this.generalNodeStreams && (mode.dynNodeStreams ?? false);
|
|
1970
2400
|
this.workerTargets = mode.workerTargets ?? [];
|
|
1971
2401
|
this.workerTargets.forEach((sf, id) => {
|
|
1972
2402
|
this.workerTargetIdByPath.set(tsgoPath(resolve(sf.fileName)), id);
|
|
1973
2403
|
});
|
|
1974
|
-
this.forkTargets = mode.forkTargets ?? [];
|
|
1975
2404
|
this.forkTargets.forEach((sf, id) => {
|
|
1976
2405
|
this.forkTargetIdByPath.set(tsgoPath(resolve(sf.fileName)), id);
|
|
1977
2406
|
});
|
|
1978
2407
|
this.ffiImportsByName = new Map(this.ffiImports.map((entry) => [entry.name, entry]));
|
|
1979
|
-
this.ffiBindingSymbols = mode.ffiBindingSymbols ?? null;
|
|
1980
|
-
this.externalTypes = mode.externalTypes ?? new Map();
|
|
1981
2408
|
this.externalTypeSpecifiersByFile =
|
|
1982
2409
|
mode.externalTypeSpecifiersByFile ?? directExternalTypeSpecifiersByFile(this.externalTypes);
|
|
1983
2410
|
this.checker = program.getTypeChecker();
|
|
@@ -1988,18 +2415,25 @@ export class Lowerer {
|
|
|
1988
2415
|
classNamer: this.classNamer,
|
|
1989
2416
|
resolveTypeParam: this.typeParamResolver,
|
|
1990
2417
|
resolveTypeParamTs: this.typeParamTsResolver,
|
|
2418
|
+
isErasing: () => this.erasingDepth > 0,
|
|
1991
2419
|
genericClassInstance: (decl, ref, mapArgument) => this.genericClassInstanceType(decl, ref, mapArgument),
|
|
2420
|
+
runtimeClassValue: (type) => runtimeClassValueOfType(this, type),
|
|
1992
2421
|
mixinClassInstance: (decl) => this.mixinTypeContext && this.mixinTypeContext.classNode === decl
|
|
1993
2422
|
? { kind: "object", className: this.mixinTypeContext.className }
|
|
1994
2423
|
: null,
|
|
1995
|
-
localClassInstance: (decl) => {
|
|
2424
|
+
localClassInstance: (decl, instanceType) => {
|
|
2425
|
+
// A generic factory's local class, by the instance type a call of
|
|
2426
|
+
// the factory produced (localClassResultInstance).
|
|
2427
|
+
const instanceClass = instanceType && this.localClassInstanceTypes.get(instanceType.id);
|
|
2428
|
+
if (instanceClass)
|
|
2429
|
+
return { kind: "object", className: instanceClass };
|
|
1996
2430
|
// Computed heritage can close over parameters of its factory.
|
|
1997
2431
|
// A speculative checker query outside that factory must not lower
|
|
1998
2432
|
// the extends expression in the caller's lexical scope.
|
|
1999
2433
|
if (!this.classes.has(this.classNamer(decl)) &&
|
|
2000
2434
|
!this.collectingExprClasses.has(decl) &&
|
|
2001
|
-
decl.heritageClauses?.some((clause) => clause.token === ts.SyntaxKind.ExtendsKeyword &&
|
|
2002
|
-
clause.types.some((base) => {
|
|
2435
|
+
decl.heritageClauses?.nodes.some((clause) => clause.token === ts.SyntaxKind.ExtendsKeyword &&
|
|
2436
|
+
clause.types.nodes.some((base) => {
|
|
2003
2437
|
const expression = base.expression;
|
|
2004
2438
|
if (ts.isCallExpression(expression))
|
|
2005
2439
|
return true;
|
|
@@ -2027,13 +2461,14 @@ export class Lowerer {
|
|
|
2027
2461
|
continue;
|
|
2028
2462
|
if (this.localClassInstantiations.some((entry) => entry.owner === parent))
|
|
2029
2463
|
break;
|
|
2030
|
-
if (parent.typeParameters?.length ||
|
|
2031
|
-
(implicitMonoFile(
|
|
2464
|
+
if (parent.typeParameters?.nodes.length ||
|
|
2465
|
+
(implicitMonoFile(ts.getSourceFileOfNode(parent)) &&
|
|
2466
|
+
monomorphizedImplicit(this, parent)))
|
|
2032
2467
|
return null;
|
|
2033
2468
|
}
|
|
2034
2469
|
const className = this.classNamer(decl);
|
|
2035
|
-
if (!this.collectingExprClasses.has(decl))
|
|
2036
|
-
|
|
2470
|
+
if (!this.collectingExprClasses.has(decl) && !this.collectLocalClassForType(decl))
|
|
2471
|
+
return null;
|
|
2037
2472
|
return { kind: "object", className };
|
|
2038
2473
|
},
|
|
2039
2474
|
mixinIntersectionInstance: (widened) => mixinIntersectionInstanceType(this, widened),
|
|
@@ -2042,18 +2477,23 @@ export class Lowerer {
|
|
|
2042
2477
|
isNpmFile: this.isNpmFile,
|
|
2043
2478
|
isExternalTypeFile: (sf) => this.externalTypeSpecifiersByFile.has(tsgoPath(resolve(sf.fileName))),
|
|
2044
2479
|
typeMemo: this.typeMemo,
|
|
2480
|
+
...(this.generalNodeStreams ? { generalNodeStreams: true } : {}),
|
|
2481
|
+
...(this.dynNodeStreams ? { dynNodeStreams: true } : {}),
|
|
2045
2482
|
canMemoizeType: () => this.typeParamBindings === null &&
|
|
2046
2483
|
this.typeParamTsBindings === null &&
|
|
2047
2484
|
this.mixinTypeContext === null,
|
|
2048
2485
|
// fileTag is filled just below; the hook is only ever CALLED during
|
|
2049
2486
|
// lowering, long after the constructor completes.
|
|
2050
2487
|
isProgramFile: (sf) => this.fileTag.has(sf),
|
|
2051
|
-
lifetimeRegionClass: (decl) => isExperimentalDeclarationFile(
|
|
2488
|
+
lifetimeRegionClass: (decl) => isExperimentalDeclarationFile(ts.getSourceFileOfNode(decl), this.experimentalFiles)
|
|
2052
2489
|
? lifetimeRegionType(this)
|
|
2053
2490
|
: null,
|
|
2054
|
-
internTableClass: (decl) => isExperimentalDeclarationFile(
|
|
2491
|
+
internTableClass: (decl) => isExperimentalDeclarationFile(ts.getSourceFileOfNode(decl), this.experimentalFiles)
|
|
2055
2492
|
? internTableType(this)
|
|
2056
2493
|
: null,
|
|
2494
|
+
threadSlotsClass: (decl) => isExperimentalDeclarationFile(ts.getSourceFileOfNode(decl), this.experimentalFiles)
|
|
2495
|
+
? threadSlotsType(this)
|
|
2496
|
+
: null,
|
|
2057
2497
|
moduleNamespaceId: (type) => this.moduleNamespaceIdOfType(type),
|
|
2058
2498
|
};
|
|
2059
2499
|
// Modules reachable only through literal import() joined
|
|
@@ -2065,11 +2505,25 @@ export class Lowerer {
|
|
|
2065
2505
|
});
|
|
2066
2506
|
if (this.moduleOrder.length === 0)
|
|
2067
2507
|
this.fileTag.set(entry, "");
|
|
2508
|
+
const jsDynamic = jsDynamicDeclarations(this.moduleOrder, this.checker);
|
|
2509
|
+
if (jsDynamic.size > 0)
|
|
2510
|
+
this.typeCtx.jsDynamicDeclaration = (decl) => jsDynamic.has(decl);
|
|
2068
2511
|
this.registerBuiltinErrorClasses();
|
|
2069
2512
|
registerBuiltinEmitterClass(this);
|
|
2070
2513
|
registerBuiltinStreamClasses(this);
|
|
2071
2514
|
registerBuiltinEventTargetClasses(this);
|
|
2072
2515
|
}
|
|
2516
|
+
/** A JavaScript file TypeScript type-checks (`// @ts-check`, or the
|
|
2517
|
+
* project's `checkJs`). Its JSDoc types are enforced like TypeScript
|
|
2518
|
+
* annotations, so its classes use them as a TypeScript file would. */
|
|
2519
|
+
checkedJsFile(sf) {
|
|
2520
|
+
let checked = this.checkedJsFiles.get(sf);
|
|
2521
|
+
if (checked === undefined) {
|
|
2522
|
+
checked = isCheckedJsSourceFile(sf, this.projectCheckJs);
|
|
2523
|
+
this.checkedJsFiles.set(sf, checked);
|
|
2524
|
+
}
|
|
2525
|
+
return checked;
|
|
2526
|
+
}
|
|
2073
2527
|
registerBuiltinErrorClasses() {
|
|
2074
2528
|
return registerBuiltinErrorClasses(this);
|
|
2075
2529
|
}
|
|
@@ -2079,10 +2533,45 @@ export class Lowerer {
|
|
|
2079
2533
|
return this.classProtocols.usesCheckedIdentity(type);
|
|
2080
2534
|
}
|
|
2081
2535
|
/** Declared class fields may store a DYN value only when its static type
|
|
2082
|
-
*
|
|
2083
|
-
*
|
|
2536
|
+
* is `unknown` or `object` (also with `null` or `undefined`, or an array
|
|
2537
|
+
* of those), names checked protocol identity, is an owned runtime
|
|
2538
|
+
* handle (a Worker or MessagePort, or a fetch Headers/Request/Response),
|
|
2539
|
+
* or is a WeakMap/WeakSet (native weak collections live in
|
|
2540
|
+
* checked-dynamic storage, as locals of those types do); `any` fields
|
|
2541
|
+
* stay refused. */
|
|
2084
2542
|
classFieldStoresDyn(type) {
|
|
2085
|
-
return this.
|
|
2543
|
+
return (this.opaqueValueType(type) ||
|
|
2544
|
+
this.classImplementedProtocol(type) ||
|
|
2545
|
+
isWorkerHandleType(type, this.typeCtx) ||
|
|
2546
|
+
isFetchHandleType(type, this.typeCtx) ||
|
|
2547
|
+
this.weakCollectionType(type));
|
|
2548
|
+
}
|
|
2549
|
+
/** A stdlib WeakMap or WeakSet, alone or with `null`/`undefined`. */
|
|
2550
|
+
weakCollectionType(type) {
|
|
2551
|
+
const weak = (part) => {
|
|
2552
|
+
const symbol = part.getSymbol();
|
|
2553
|
+
return (((symbol !== undefined && ts.symbolName(symbol) === "WeakMap") ||
|
|
2554
|
+
(symbol !== undefined && ts.symbolName(symbol) === "WeakSet")) &&
|
|
2555
|
+
symbol.declarations.some((d) => ts.isInterfaceDeclaration(d) && this.isStdlibFile(ts.getSourceFileOfNode(d))));
|
|
2556
|
+
};
|
|
2557
|
+
if (!type.isUnionType())
|
|
2558
|
+
return weak(type);
|
|
2559
|
+
const parts = ts.constituentTypes(type);
|
|
2560
|
+
return (parts.some(weak) &&
|
|
2561
|
+
parts.every((part) => (part.flags & (ts.TypeFlags.Null | ts.TypeFlags.Undefined)) !== 0 || weak(part)));
|
|
2562
|
+
}
|
|
2563
|
+
/** `unknown`, `object`, an array of those, or a union of those with
|
|
2564
|
+
* `null` and `undefined`: types whose values use checked-dynamic storage
|
|
2565
|
+
* as they do in JavaScript class fields. */
|
|
2566
|
+
opaqueValueType(type) {
|
|
2567
|
+
const opaque = (part) => (part.flags & (ts.TypeFlags.Unknown | ts.TypeFlags.NonPrimitive)) !== 0 ||
|
|
2568
|
+
(this.checker.isArrayType(part) &&
|
|
2569
|
+
this.checker.getTypeArguments(part).every(opaque));
|
|
2570
|
+
if (!type.isUnionType())
|
|
2571
|
+
return opaque(type);
|
|
2572
|
+
const parts = ts.constituentTypes(type);
|
|
2573
|
+
return (parts.some(opaque) &&
|
|
2574
|
+
parts.every((part) => (part.flags & (ts.TypeFlags.Null | ts.TypeFlags.Undefined)) !== 0 || opaque(part)));
|
|
2086
2575
|
}
|
|
2087
2576
|
/** The nominal identity of a checker module-namespace type. Program
|
|
2088
2577
|
* modules use their normalized absolute source name; supported builtins
|
|
@@ -2093,7 +2582,7 @@ export class Lowerer {
|
|
|
2093
2582
|
return null;
|
|
2094
2583
|
if (sym.flags & ts.SymbolFlags.Alias)
|
|
2095
2584
|
sym = this.checker.getAliasedSymbol(sym);
|
|
2096
|
-
for (const decl of
|
|
2585
|
+
for (const decl of sym.declarations) {
|
|
2097
2586
|
if (ts.isSourceFile(decl) &&
|
|
2098
2587
|
!decl.isDeclarationFile &&
|
|
2099
2588
|
!decl.fileName.endsWith(".cts") &&
|
|
@@ -2124,6 +2613,12 @@ export class Lowerer {
|
|
|
2124
2613
|
builtinStreamInfoOf(symbol) {
|
|
2125
2614
|
return builtinStreamInfoOf(this, symbol);
|
|
2126
2615
|
}
|
|
2616
|
+
builtinClassAliasOf(symbol) {
|
|
2617
|
+
return builtinClassAliasOf(this, symbol);
|
|
2618
|
+
}
|
|
2619
|
+
defineClassValueConstruct(info) {
|
|
2620
|
+
defineClassValueConstruct(this, info);
|
|
2621
|
+
}
|
|
2127
2622
|
/** Program-wide qualified name for a top-level declaration. */
|
|
2128
2623
|
qualify(sf, name) {
|
|
2129
2624
|
return `${this.fileTag.get(sf) ?? ""}${name}`;
|
|
@@ -2145,8 +2640,8 @@ export class Lowerer {
|
|
|
2145
2640
|
}
|
|
2146
2641
|
return false;
|
|
2147
2642
|
})()
|
|
2148
|
-
? this.qualify(
|
|
2149
|
-
: this.qualify(
|
|
2643
|
+
? this.qualify(ts.getSourceFileOfNode(decl), `%cx${ts.tokenStartOfNode(decl)}.${decl.name?.text ?? ""}`)
|
|
2644
|
+
: this.qualify(ts.getSourceFileOfNode(decl), nsPathPrefix(decl) + (decl.name ? decl.name.text : "%anon"));
|
|
2150
2645
|
for (let index = this.localClassInstantiations.length - 1; index >= 0; index--) {
|
|
2151
2646
|
const entry = this.localClassInstantiations[index];
|
|
2152
2647
|
for (let parent = decl.parent; parent && !ts.isSourceFile(parent); parent = parent.parent) {
|
|
@@ -2191,8 +2686,10 @@ export class Lowerer {
|
|
|
2191
2686
|
ts.isPropertyAccessExpression(ident.parent) &&
|
|
2192
2687
|
ident.parent.name === ident) {
|
|
2193
2688
|
const recv = ident.parent.expression;
|
|
2194
|
-
if (
|
|
2195
|
-
const dep =
|
|
2689
|
+
if (this.cjsLocalModuleBindingOf(recv)) {
|
|
2690
|
+
const dep = ts.isIdentifier(recv)
|
|
2691
|
+
? this.localModuleBindingDepOf(recv)
|
|
2692
|
+
: this.cjsModuleRefDepOf(recv);
|
|
2196
2693
|
const exported = dep ? this.cjsModuleExportSymbol(dep, ident.text) : undefined;
|
|
2197
2694
|
// A createRequire call is typed as `any`, so tsgo can manufacture a
|
|
2198
2695
|
// transient property symbol with no relation to the target module.
|
|
@@ -2285,7 +2782,7 @@ export class Lowerer {
|
|
|
2285
2782
|
}
|
|
2286
2783
|
if (ts.isCallExpression(value)) {
|
|
2287
2784
|
if (value.expression.kind === ts.SyntaxKind.ImportKeyword) {
|
|
2288
|
-
const spec = value.arguments[0];
|
|
2785
|
+
const spec = value.arguments.nodes[0];
|
|
2289
2786
|
return spec !== undefined &&
|
|
2290
2787
|
ts.isStringLiteralLike(spec) &&
|
|
2291
2788
|
this.externalTypes.has(spec.text)
|
|
@@ -2294,8 +2791,8 @@ export class Lowerer {
|
|
|
2294
2791
|
}
|
|
2295
2792
|
if (ts.isIdentifier(value.expression) &&
|
|
2296
2793
|
value.expression.text === "require" &&
|
|
2297
|
-
value.arguments.length === 1) {
|
|
2298
|
-
const spec = value.arguments[0];
|
|
2794
|
+
value.arguments.nodes.length === 1) {
|
|
2795
|
+
const spec = value.arguments.nodes[0];
|
|
2299
2796
|
if (ts.isStringLiteralLike(spec) && this.externalTypes.has(spec.text))
|
|
2300
2797
|
return spec.text;
|
|
2301
2798
|
}
|
|
@@ -2332,7 +2829,7 @@ export class Lowerer {
|
|
|
2332
2829
|
* every project-module spelling. */
|
|
2333
2830
|
moduleSourceFileOf(from, spec) {
|
|
2334
2831
|
const moduleSymbol = this.checker.getSymbolAtLocation(spec);
|
|
2335
|
-
for (const decl of moduleSymbol ?
|
|
2832
|
+
for (const decl of moduleSymbol ? moduleSymbol.declarations : []) {
|
|
2336
2833
|
if (ts.isSourceFile(decl))
|
|
2337
2834
|
return decl;
|
|
2338
2835
|
}
|
|
@@ -2368,9 +2865,7 @@ export class Lowerer {
|
|
|
2368
2865
|
if (!ts.isIdentifier(value))
|
|
2369
2866
|
return null;
|
|
2370
2867
|
const symbol = this.checker.getSymbolAtLocation(value);
|
|
2371
|
-
const namespaceDecl = symbol
|
|
2372
|
-
? this.checker.declarationsOf(symbol).find(ts.isNamespaceImport)
|
|
2373
|
-
: undefined;
|
|
2868
|
+
const namespaceDecl = symbol ? symbol.declarations.find(ts.isNamespaceImport) : undefined;
|
|
2374
2869
|
if (namespaceDecl === undefined)
|
|
2375
2870
|
return null;
|
|
2376
2871
|
const importDecl = namespaceDecl.parent?.parent;
|
|
@@ -2378,7 +2873,7 @@ export class Lowerer {
|
|
|
2378
2873
|
return null;
|
|
2379
2874
|
if (this.externalTypes.has(importDecl.moduleSpecifier.text))
|
|
2380
2875
|
return importDecl.moduleSpecifier.text;
|
|
2381
|
-
const dep = this.moduleSourceFileOf(
|
|
2876
|
+
const dep = this.moduleSourceFileOf(ts.getSourceFileOfNode(importDecl), importDecl.moduleSpecifier);
|
|
2382
2877
|
return dep !== null && !dep.isDeclarationFile
|
|
2383
2878
|
? this.externalTypeSpecifierOfModuleExport(dep, member, new Set(), new Set())
|
|
2384
2879
|
: null;
|
|
@@ -2387,7 +2882,7 @@ export class Lowerer {
|
|
|
2387
2882
|
if (symbol === undefined || seenSymbols.has(symbol))
|
|
2388
2883
|
return null;
|
|
2389
2884
|
seenSymbols.add(symbol);
|
|
2390
|
-
const declarations =
|
|
2885
|
+
const declarations = symbol.declarations;
|
|
2391
2886
|
// Route-aware alias hops run before declaration-file ownership. An
|
|
2392
2887
|
// exact import must keep the specifier it actually named, rather than
|
|
2393
2888
|
// inheriting whichever alias happened to register the shared file last.
|
|
@@ -2434,13 +2929,13 @@ export class Lowerer {
|
|
|
2434
2929
|
// property accesses resolve their selected member separately above.
|
|
2435
2930
|
if (importedName === null)
|
|
2436
2931
|
return null;
|
|
2437
|
-
const dep = this.moduleSourceFileOf(
|
|
2932
|
+
const dep = this.moduleSourceFileOf(ts.getSourceFileOfNode(decl), specNode);
|
|
2438
2933
|
return dep !== null && !dep.isDeclarationFile
|
|
2439
2934
|
? this.externalTypeSpecifierOfModuleExport(dep, importedName, seenSymbols, seenExports)
|
|
2440
2935
|
: null;
|
|
2441
2936
|
}
|
|
2442
2937
|
for (const decl of declarations) {
|
|
2443
|
-
const owners = this.externalTypeSpecifiersByFile.get(tsgoPath(resolve(
|
|
2938
|
+
const owners = this.externalTypeSpecifiersByFile.get(tsgoPath(resolve(ts.getSourceFileOfNode(decl).fileName)));
|
|
2444
2939
|
if (owners !== undefined && owners.length > 0)
|
|
2445
2940
|
return owners[0];
|
|
2446
2941
|
}
|
|
@@ -2463,9 +2958,7 @@ export class Lowerer {
|
|
|
2463
2958
|
for (let hop = 0; sym !== undefined && hop < 32; hop++) {
|
|
2464
2959
|
if (hop > 0 && sym.flags & ts.SymbolFlags.Alias && this.globalsBySymbol.has(sym))
|
|
2465
2960
|
return sym;
|
|
2466
|
-
const d =
|
|
2467
|
-
.declarationsOf(sym)
|
|
2468
|
-
.find((x) => ts.isImportClause(x) || ts.isImportSpecifier(x) || ts.isExportSpecifier(x));
|
|
2961
|
+
const d = sym.declarations.find((x) => ts.isImportClause(x) || ts.isImportSpecifier(x) || ts.isExportSpecifier(x));
|
|
2469
2962
|
let spec;
|
|
2470
2963
|
let name;
|
|
2471
2964
|
if (d && ts.isImportClause(d) && ts.isImportDeclaration(d.parent)) {
|
|
@@ -2486,7 +2979,7 @@ export class Lowerer {
|
|
|
2486
2979
|
}
|
|
2487
2980
|
if (d === undefined || spec === undefined || !ts.isStringLiteral(spec) || name !== "default")
|
|
2488
2981
|
return null;
|
|
2489
|
-
const dep = resolveImport(this.program,
|
|
2982
|
+
const dep = resolveImport(this.program, ts.getSourceFileOfNode(d), spec.text);
|
|
2490
2983
|
if (!dep)
|
|
2491
2984
|
return null;
|
|
2492
2985
|
sym = defaultExportSymbolOf(this, dep) ?? undefined;
|
|
@@ -2516,7 +3009,7 @@ export class Lowerer {
|
|
|
2516
3009
|
* see resolveValueSymbol. Null when `symbol` is not such a property (or
|
|
2517
3010
|
* the property's value is not a plain identifier reference). */
|
|
2518
3011
|
cjsExportValueSymbol(symbol) {
|
|
2519
|
-
const d =
|
|
3012
|
+
const d = symbol.declarations[0];
|
|
2520
3013
|
if (!d)
|
|
2521
3014
|
return null;
|
|
2522
3015
|
// MEMBER-form class exports (`exports.C = C` — commander's error.js):
|
|
@@ -2558,8 +3051,6 @@ export class Lowerer {
|
|
|
2558
3051
|
: null;
|
|
2559
3052
|
if (!assign || assign.operatorToken.kind !== ts.SyntaxKind.EqualsToken)
|
|
2560
3053
|
return null;
|
|
2561
|
-
if (!ts.isIdentifier(assign.right))
|
|
2562
|
-
return null;
|
|
2563
3054
|
const stmt = assign.parent;
|
|
2564
3055
|
if (!stmt || !ts.isExpressionStatement(stmt) || !ts.isSourceFile(stmt.parent))
|
|
2565
3056
|
return null;
|
|
@@ -2570,12 +3061,39 @@ export class Lowerer {
|
|
|
2570
3061
|
return null;
|
|
2571
3062
|
if (cjsExportDiscardReason(stmt) !== null)
|
|
2572
3063
|
return null;
|
|
3064
|
+
// `module.exports.C = require('./c')` over a module whose whole export
|
|
3065
|
+
// is a class identifier: the same alias plumbing; the statement keeps
|
|
3066
|
+
// the require's module evaluation at its position.
|
|
3067
|
+
const required = this.memberExportRequiredClass(assign.right);
|
|
3068
|
+
if (required !== undefined)
|
|
3069
|
+
return required;
|
|
3070
|
+
if (!ts.isIdentifier(assign.right))
|
|
3071
|
+
return null;
|
|
2573
3072
|
let value = this.checker.getSymbolAtLocation(assign.right);
|
|
2574
3073
|
if (!value)
|
|
2575
3074
|
return null;
|
|
2576
3075
|
if (value.flags & ts.SymbolFlags.Alias)
|
|
2577
3076
|
value = this.checker.getAliasedSymbol(value);
|
|
2578
|
-
const isClass =
|
|
3077
|
+
const isClass = value.declarations.some((decl) => ts.isClassDeclaration(decl));
|
|
3078
|
+
return isClass ? value : null;
|
|
3079
|
+
}
|
|
3080
|
+
/** For an inline program `require("./c")`: the class symbol its module's
|
|
3081
|
+
* kept `module.exports = <class identifier>` names, or null when the
|
|
3082
|
+
* whole export is something else. Undefined when `expr` is not such a
|
|
3083
|
+
* require. */
|
|
3084
|
+
memberExportRequiredClass(expr) {
|
|
3085
|
+
const req = inlineProgramRequireOf(this, expr);
|
|
3086
|
+
if (req === null)
|
|
3087
|
+
return undefined;
|
|
3088
|
+
const whole = cjsWholeExportValueOf(req.dep);
|
|
3089
|
+
if (whole === null || !ts.isIdentifier(whole.rhs))
|
|
3090
|
+
return null;
|
|
3091
|
+
let value = this.checker.getSymbolAtLocation(whole.rhs);
|
|
3092
|
+
if (!value)
|
|
3093
|
+
return null;
|
|
3094
|
+
if (value.flags & ts.SymbolFlags.Alias)
|
|
3095
|
+
value = this.checker.getAliasedSymbol(value);
|
|
3096
|
+
const isClass = value.declarations.some((decl) => ts.isClassDeclaration(decl));
|
|
2579
3097
|
return isClass ? value : null;
|
|
2580
3098
|
}
|
|
2581
3099
|
/** The CommonJS JS module a DEFAULT-import binding's declaration loads
|
|
@@ -2592,19 +3110,33 @@ export class Lowerer {
|
|
|
2592
3110
|
const spec = importDecl.moduleSpecifier.text;
|
|
2593
3111
|
// Project aliases/self-references resolve through the same entry point as
|
|
2594
3112
|
// relative imports; an opted-in --npm-static package is the fallback.
|
|
2595
|
-
const dep = resolveImport(this.program,
|
|
2596
|
-
npmStaticDepSf7(this.program,
|
|
3113
|
+
const dep = resolveImport(this.program, ts.getSourceFileOfNode(importDecl), spec) ??
|
|
3114
|
+
npmStaticDepSf7(this.program, ts.getSourceFileOfNode(importDecl), spec);
|
|
2597
3115
|
if (!dep || !isJsSourceFile(dep) || isNodeEsmFile(dep, this.program))
|
|
2598
3116
|
return null;
|
|
2599
3117
|
return dep;
|
|
2600
3118
|
}
|
|
3119
|
+
/** The table module a non-identifier module reference names: an inline
|
|
3120
|
+
* `require("./x")` (cjs-inline-require.ts) or tsc's unstamped
|
|
3121
|
+
* `x_1.default` interop read (cjs-tsc-interop.ts). */
|
|
3122
|
+
cjsModuleRefDepOf(expr) {
|
|
3123
|
+
const inline = inlineNamespaceRequireOf(this, expr);
|
|
3124
|
+
if (inline !== null)
|
|
3125
|
+
return inline.dep;
|
|
3126
|
+
const interop = tscInteropModuleOf(this, expr);
|
|
3127
|
+
return interop !== null && cjsNamespaceModule(this, interop.dep) ? interop.dep : null;
|
|
3128
|
+
}
|
|
3129
|
+
/** The table module a CommonJS module binding identifier names. */
|
|
3130
|
+
cjsModuleBindingDepOf(expr) {
|
|
3131
|
+
return this.localModuleBindingDepOf(expr);
|
|
3132
|
+
}
|
|
2601
3133
|
/** The compiled module behind a require-like namespace binding: an
|
|
2602
3134
|
* ordinary CommonJS require declaration, a canonical createRequire
|
|
2603
3135
|
* declaration, or an ESM default import of CommonJS. One resolver keeps
|
|
2604
3136
|
* member-symbol fallback and namespace classification in lockstep. */
|
|
2605
3137
|
localModuleBindingDepOf(expr) {
|
|
2606
3138
|
const sym = this.checker.getSymbolAtLocation(expr);
|
|
2607
|
-
const decls = sym ?
|
|
3139
|
+
const decls = sym ? sym.declarations : [];
|
|
2608
3140
|
const decl = decls.find(ts.isImportClause) ?? decls[0];
|
|
2609
3141
|
if (!decl)
|
|
2610
3142
|
return null;
|
|
@@ -2612,10 +3144,17 @@ export class Lowerer {
|
|
|
2612
3144
|
return this.cjsDefaultImportDepOf(decl);
|
|
2613
3145
|
if (!ts.isVariableDeclaration(decl) || !ts.isIdentifier(decl.name) || !decl.initializer)
|
|
2614
3146
|
return null;
|
|
3147
|
+
{
|
|
3148
|
+
const interop = tscInteropModuleOf(this, expr);
|
|
3149
|
+
if (interop !== null)
|
|
3150
|
+
return cjsNamespaceModule(this, interop.dep) ? interop.dep : null;
|
|
3151
|
+
}
|
|
2615
3152
|
const directSpec = requireSpecOf(decl.initializer);
|
|
2616
3153
|
if (directSpec !== null) {
|
|
2617
|
-
|
|
2618
|
-
|
|
3154
|
+
if (isJsonRequireDecl(this, decl))
|
|
3155
|
+
return null;
|
|
3156
|
+
return (resolveImport(this.program, ts.getSourceFileOfNode(decl), directSpec, "require") ??
|
|
3157
|
+
npmStaticDepSf7(this.program, ts.getSourceFileOfNode(decl), directSpec, "require"));
|
|
2619
3158
|
}
|
|
2620
3159
|
return createRequireProgramModuleOf(this, decl.initializer)?.dep ?? null;
|
|
2621
3160
|
}
|
|
@@ -2626,9 +3165,7 @@ export class Lowerer {
|
|
|
2626
3165
|
* static storage or callable/class metadata. */
|
|
2627
3166
|
createRequireWholeExportSymbolOf(ident) {
|
|
2628
3167
|
const binding = this.checker.getSymbolAtLocation(ident);
|
|
2629
|
-
const decl = binding
|
|
2630
|
-
? this.checker.declarationsOf(binding).find(ts.isVariableDeclaration)
|
|
2631
|
-
: undefined;
|
|
3168
|
+
const decl = binding ? binding.declarations.find(ts.isVariableDeclaration) : undefined;
|
|
2632
3169
|
if (!decl || !ts.isIdentifier(decl.name) || !decl.initializer)
|
|
2633
3170
|
return null;
|
|
2634
3171
|
const target = createRequireProgramModuleOf(this, decl.initializer);
|
|
@@ -2638,9 +3175,7 @@ export class Lowerer {
|
|
|
2638
3175
|
let symbol = moduleSym?.getExports().get("export=");
|
|
2639
3176
|
if (!symbol)
|
|
2640
3177
|
return null;
|
|
2641
|
-
const wholeAssignment =
|
|
2642
|
-
.declarationsOf(symbol)
|
|
2643
|
-
.find((d) => {
|
|
3178
|
+
const wholeAssignment = symbol.declarations.find((d) => {
|
|
2644
3179
|
if (!ts.isBinaryExpression(d) ||
|
|
2645
3180
|
!ts.isExpressionStatement(d.parent) ||
|
|
2646
3181
|
!ts.isSourceFile(d.parent.parent))
|
|
@@ -2655,6 +3190,10 @@ export class Lowerer {
|
|
|
2655
3190
|
let rhs = wholeAssignment.right;
|
|
2656
3191
|
while (ts.isParenthesizedExpression(rhs))
|
|
2657
3192
|
rhs = rhs.expression;
|
|
3193
|
+
// A pure re-export (`module.exports = require("./core")`) is the inner
|
|
3194
|
+
// module's export table, read like any namespace binding.
|
|
3195
|
+
if (inlineProgramRequireOf(this, rhs) !== null && !this.globalsByDeclNode.has(wholeAssignment))
|
|
3196
|
+
return null;
|
|
2658
3197
|
if (ts.isIdentifier(rhs)) {
|
|
2659
3198
|
const value = this.checker.getSymbolAtLocation(rhs);
|
|
2660
3199
|
if (value) {
|
|
@@ -2673,9 +3212,7 @@ export class Lowerer {
|
|
|
2673
3212
|
* target module's real export symbol. */
|
|
2674
3213
|
createRequireDestructuredExportSymbolOf(ident) {
|
|
2675
3214
|
const binding = this.checker.getSymbolAtLocation(ident);
|
|
2676
|
-
const element = binding
|
|
2677
|
-
? this.checker.declarationsOf(binding).find(ts.isBindingElement)
|
|
2678
|
-
: undefined;
|
|
3215
|
+
const element = binding ? binding.declarations.find(ts.isBindingElement) : undefined;
|
|
2679
3216
|
if (!element ||
|
|
2680
3217
|
element.name === undefined ||
|
|
2681
3218
|
!ts.isIdentifier(element.name) ||
|
|
@@ -2704,8 +3241,10 @@ export class Lowerer {
|
|
|
2704
3241
|
* symbols → resolveValueSymbol); the bare value keeps the
|
|
2705
3242
|
* namespace-object fence, like ESM namespace imports of builtins. */
|
|
2706
3243
|
cjsLocalModuleBindingOf(expr) {
|
|
3244
|
+
// An inline `require("./x")` over a table module reads its members like
|
|
3245
|
+
// a binding (cjs-inline-require.ts sequences the module's %init).
|
|
2707
3246
|
if (!ts.isIdentifier(expr))
|
|
2708
|
-
return
|
|
3247
|
+
return this.cjsModuleRefDepOf(expr) !== null;
|
|
2709
3248
|
const sym = this.checker.getSymbolAtLocation(expr);
|
|
2710
3249
|
if (this.localModuleBindingDepOf(expr) === null)
|
|
2711
3250
|
return false;
|
|
@@ -2720,7 +3259,10 @@ export class Lowerer {
|
|
|
2720
3259
|
// the object literal) keep the namespace reading — member accesses
|
|
2721
3260
|
// resolve through the table's property symbols.
|
|
2722
3261
|
if (sym && sym.flags & ts.SymbolFlags.Alias) {
|
|
2723
|
-
|
|
3262
|
+
// `module.exports = TypeError`: the binding IS the builtin global.
|
|
3263
|
+
if (this.isStdlibSymbol(this.checker.getAliasedSymbol(sym)))
|
|
3264
|
+
return false;
|
|
3265
|
+
const d = this.checker.getAliasedSymbol(sym).declarations[0];
|
|
2724
3266
|
if (d && (ts.isClassDeclaration(d) || ts.isFunctionDeclaration(d)))
|
|
2725
3267
|
return false;
|
|
2726
3268
|
if (d && ts.isVariableDeclaration(d)) {
|
|
@@ -2790,7 +3332,7 @@ export class Lowerer {
|
|
|
2790
3332
|
g.type = this.runtimeOptionalBindingType(ident, g.type);
|
|
2791
3333
|
return g;
|
|
2792
3334
|
}
|
|
2793
|
-
for (const d of
|
|
3335
|
+
for (const d of symbol.declarations) {
|
|
2794
3336
|
const byDecl = this.globalsByDeclNode.get(d);
|
|
2795
3337
|
if (byDecl)
|
|
2796
3338
|
return byDecl;
|
|
@@ -2820,6 +3362,16 @@ export class Lowerer {
|
|
|
2820
3362
|
const id = `%g.${tag}%loaded`;
|
|
2821
3363
|
this.moduleGuardOf.set(fp.sf, id);
|
|
2822
3364
|
this.globalsList.push({ id, name: "%loaded", type: BOOL, mutable: true });
|
|
3365
|
+
if (usesCjsTopLevelThis(this, fp.sf) || usesCjsExportsIdentity(this, fp.sf)) {
|
|
3366
|
+
const exportsThis = {
|
|
3367
|
+
id: `%g.${tag}%exportsThis`,
|
|
3368
|
+
name: "%exportsThis",
|
|
3369
|
+
type: DYN,
|
|
3370
|
+
mutable: true,
|
|
3371
|
+
};
|
|
3372
|
+
this.globalsList.push(exportsThis);
|
|
3373
|
+
this.cjsExportsThis.set(fp.sf, exportsThis);
|
|
3374
|
+
}
|
|
2823
3375
|
}
|
|
2824
3376
|
// A module is intrinsically async when an await/for-await occurs
|
|
2825
3377
|
// outside every nested function-like boundary. Then propagate that
|
|
@@ -2939,6 +3491,59 @@ export class Lowerer {
|
|
|
2939
3491
|
if (!indexOf.has(fp.sf))
|
|
2940
3492
|
visit(fp.sf);
|
|
2941
3493
|
}
|
|
3494
|
+
/** node:punycode's load at a require() call: the module body reports
|
|
3495
|
+
* DEP0040 when it first runs, unless isInsideNodeModules() finds the
|
|
3496
|
+
* requiring frame in a dependency, and process.emitWarning delivers the
|
|
3497
|
+
* report on the next tick. Later loads are cache hits either way. */
|
|
3498
|
+
punycodeRequireWarning(node) {
|
|
3499
|
+
const loc = locOf(node);
|
|
3500
|
+
const fromDependency = /[\\/]node_modules[\\/]/.test(ts.getSourceFileOfNode(node).fileName);
|
|
3501
|
+
return {
|
|
3502
|
+
kind: "exprStmt",
|
|
3503
|
+
expr: {
|
|
3504
|
+
kind: "libCall",
|
|
3505
|
+
fn: "punycode.warn",
|
|
3506
|
+
args: [
|
|
3507
|
+
{ kind: "boolLit", value: false, type: BOOL, loc },
|
|
3508
|
+
{ kind: "boolLit", value: !fromDependency, type: BOOL, loc },
|
|
3509
|
+
],
|
|
3510
|
+
type: VOID,
|
|
3511
|
+
loc,
|
|
3512
|
+
},
|
|
3513
|
+
loc,
|
|
3514
|
+
};
|
|
3515
|
+
}
|
|
3516
|
+
/** node:punycode's DEP0040 for a static ES import anywhere in the module
|
|
3517
|
+
* graph: Node links builtins before any module evaluates, so the report
|
|
3518
|
+
* comes first, before the program can register a 'warning' listener —
|
|
3519
|
+
* whichever file imports it (a dependency's ES import has no requiring
|
|
3520
|
+
* frame either). Prepended to the entry's %init. */
|
|
3521
|
+
punycodeLinkWarning() {
|
|
3522
|
+
const imports = this.moduleOrder.some((sf) => sf.statements.nodes.some((stmt) => ((ts.isImportDeclaration(stmt) && !erasedTypeOnlyImport(stmt)) ||
|
|
3523
|
+
(ts.isExportDeclaration(stmt) && !stmt.isTypeOnly)) &&
|
|
3524
|
+
stmt.moduleSpecifier !== undefined &&
|
|
3525
|
+
ts.isStringLiteral(stmt.moduleSpecifier) &&
|
|
3526
|
+
canonicalBuiltinModule(stmt.moduleSpecifier.text) === "punycode"));
|
|
3527
|
+
if (!imports)
|
|
3528
|
+
return [];
|
|
3529
|
+
const loc = { file: this.entry.fileName, start: 0, end: 0 };
|
|
3530
|
+
return [
|
|
3531
|
+
{
|
|
3532
|
+
kind: "exprStmt",
|
|
3533
|
+
expr: {
|
|
3534
|
+
kind: "libCall",
|
|
3535
|
+
fn: "punycode.warn",
|
|
3536
|
+
args: [
|
|
3537
|
+
{ kind: "boolLit", value: true, type: BOOL, loc },
|
|
3538
|
+
{ kind: "boolLit", value: true, type: BOOL, loc },
|
|
3539
|
+
],
|
|
3540
|
+
type: VOID,
|
|
3541
|
+
loc,
|
|
3542
|
+
},
|
|
3543
|
+
loc,
|
|
3544
|
+
},
|
|
3545
|
+
];
|
|
3546
|
+
}
|
|
2942
3547
|
/** The lowering of a CommonJS `require("./local")` occurrence: a call of
|
|
2943
3548
|
* the required module's run-once %init at exactly this statement's
|
|
2944
3549
|
* position — Node's inline evaluation, with the guard supplying the
|
|
@@ -2948,6 +3553,8 @@ export class Lowerer {
|
|
|
2948
3553
|
* their external dependencies by name). Null for everything else
|
|
2949
3554
|
* (builtins load nothing; the rest kept its preflight fence). */
|
|
2950
3555
|
requireInitStmt(spec, node) {
|
|
3556
|
+
if (canonicalBuiltinModule(spec) === "punycode")
|
|
3557
|
+
return this.punycodeRequireWarning(node);
|
|
2951
3558
|
// Project requires resolve within the program; another bare require can
|
|
2952
3559
|
// be a program-module edge when it names an opted-in --npm-static package
|
|
2953
3560
|
// (one package requiring another — the resolution answered its shipped
|
|
@@ -2955,8 +3562,8 @@ export class Lowerer {
|
|
|
2955
3562
|
// Without the guarded %init call at this position
|
|
2956
3563
|
// those globals stay uninitialized: the dep's module body would never
|
|
2957
3564
|
// run.
|
|
2958
|
-
const dep = resolveImport(this.program,
|
|
2959
|
-
npmStaticDepSf7(this.program,
|
|
3565
|
+
const dep = resolveImport(this.program, ts.getSourceFileOfNode(node), spec, "require") ??
|
|
3566
|
+
npmStaticDepSf7(this.program, ts.getSourceFileOfNode(node), spec, "require");
|
|
2960
3567
|
if (!dep || dep.fileName.endsWith(".json"))
|
|
2961
3568
|
return null;
|
|
2962
3569
|
if (this.asyncInitFiles.has(dep)) {
|
|
@@ -2971,7 +3578,7 @@ export class Lowerer {
|
|
|
2971
3578
|
expr: { kind: "call", callee: initName, args: [], type: VOID, loc },
|
|
2972
3579
|
loc,
|
|
2973
3580
|
};
|
|
2974
|
-
const parentModule = this.cjsModuleIdOf.get(
|
|
3581
|
+
const parentModule = this.cjsModuleIdOf.get(ts.getSourceFileOfNode(node));
|
|
2975
3582
|
const childModule = this.cjsModuleIdOf.get(dep);
|
|
2976
3583
|
if (parentModule === undefined || childModule === undefined)
|
|
2977
3584
|
return init;
|
|
@@ -3013,6 +3620,97 @@ export class Lowerer {
|
|
|
3013
3620
|
* TypeScript's default indexed-access type is a useful source annotation,
|
|
3014
3621
|
* but it is not a runtime proof; promoting only the affected slots keeps
|
|
3015
3622
|
* the rest of the dense ABI unchanged. */
|
|
3623
|
+
/** A Date's `toJSON()` answers null for an invalid date while the lib
|
|
3624
|
+
* types say `string`: unannotated bindings initialized by such a call,
|
|
3625
|
+
* and object-literal fields holding one, keep `string | null`. */
|
|
3626
|
+
analyzeDateJsonResults(parts) {
|
|
3627
|
+
const nullable = dateJsonType(this);
|
|
3628
|
+
for (const { sf } of parts) {
|
|
3629
|
+
if (!sf.text.includes("toJSON"))
|
|
3630
|
+
continue;
|
|
3631
|
+
ts.walkPreorder(sf, (node) => {
|
|
3632
|
+
// `x = d.toJSON()`: the checker narrows x to string after the
|
|
3633
|
+
// assignment, so its reads must stay checked.
|
|
3634
|
+
if (ts.isBinaryExpression(node) &&
|
|
3635
|
+
node.operatorToken.kind === ts.SyntaxKind.EqualsToken &&
|
|
3636
|
+
ts.isIdentifier(node.left) &&
|
|
3637
|
+
isDateJsonSource(this, node.right)) {
|
|
3638
|
+
const symbol = this.checker.getSymbolAtLocation(node.left);
|
|
3639
|
+
if (symbol)
|
|
3640
|
+
this.dateJsonBindings.add(symbol);
|
|
3641
|
+
return undefined;
|
|
3642
|
+
}
|
|
3643
|
+
if (!ts.isVariableDeclaration(node) || !node.initializer)
|
|
3644
|
+
return undefined;
|
|
3645
|
+
if (!ts.isIdentifier(node.name))
|
|
3646
|
+
return undefined;
|
|
3647
|
+
const symbol = this.checker.getSymbolAtLocation(node.name);
|
|
3648
|
+
if (!symbol)
|
|
3649
|
+
return undefined;
|
|
3650
|
+
let init = node.initializer;
|
|
3651
|
+
while (ts.isParenthesizedExpression(init))
|
|
3652
|
+
init = init.expression;
|
|
3653
|
+
if (isDateJsonSource(this, init)) {
|
|
3654
|
+
this.dateJsonBindings.add(symbol);
|
|
3655
|
+
// An annotation keeps its declared storage.
|
|
3656
|
+
if (!node.type)
|
|
3657
|
+
this.runtimeOptionalBindingTypes.set(symbol, nullable);
|
|
3658
|
+
return undefined;
|
|
3659
|
+
}
|
|
3660
|
+
if (node.type)
|
|
3661
|
+
return undefined;
|
|
3662
|
+
if (!ts.isObjectLiteralExpression(init))
|
|
3663
|
+
return undefined;
|
|
3664
|
+
const declared = this.mapTypeOf(this.typeOf(node.name));
|
|
3665
|
+
if (declared?.kind !== "record")
|
|
3666
|
+
return undefined;
|
|
3667
|
+
let widened = declared;
|
|
3668
|
+
for (const property of init.properties.nodes) {
|
|
3669
|
+
const value = ts.isPropertyAssignment(property)
|
|
3670
|
+
? property.initializer
|
|
3671
|
+
: ts.isShorthandPropertyAssignment(property)
|
|
3672
|
+
? property.name
|
|
3673
|
+
: null;
|
|
3674
|
+
const name = property.name && (ts.isIdentifier(property.name) || ts.isStringLiteral(property.name))
|
|
3675
|
+
? property.name.text
|
|
3676
|
+
: null;
|
|
3677
|
+
if (value && name !== null && isDateJsonSource(this, value))
|
|
3678
|
+
widened = this.runtimeOptionalRecordField(widened, name, nullable);
|
|
3679
|
+
}
|
|
3680
|
+
if (widened !== declared)
|
|
3681
|
+
this.runtimeOptionalBindingTypes.set(symbol, widened);
|
|
3682
|
+
return undefined;
|
|
3683
|
+
});
|
|
3684
|
+
}
|
|
3685
|
+
}
|
|
3686
|
+
/** A file-scope get-or-create read (`let e = map[k]; if (e ===
|
|
3687
|
+
* undefined) ...` over an index-signature record) keeps a missing key as
|
|
3688
|
+
* undefined (isGuardedRecordRead). Its pre-registered global takes the
|
|
3689
|
+
* undefined arm before any body reads it; the declaration lowers its
|
|
3690
|
+
* initializer as the matching absence probe. */
|
|
3691
|
+
analyzeGuardedRecordReadGlobals(parts) {
|
|
3692
|
+
for (const { sf } of parts) {
|
|
3693
|
+
for (const statement of sf.statements.nodes) {
|
|
3694
|
+
if (!ts.isVariableStatement(statement))
|
|
3695
|
+
continue;
|
|
3696
|
+
for (const decl of statement.declarationList.declarations.nodes) {
|
|
3697
|
+
if (!ts.isIdentifier(decl.name) || !isGuardedRecordRead(this, decl))
|
|
3698
|
+
continue;
|
|
3699
|
+
const global = this.globalOf(decl.name);
|
|
3700
|
+
const symbol = this.resolveValueSymbol(decl.name);
|
|
3701
|
+
if (!global || !symbol || global.tdz || this.runtimeOptionalBindingTypes.has(symbol))
|
|
3702
|
+
continue;
|
|
3703
|
+
const widened = global.type.kind === "union"
|
|
3704
|
+
? this.withUndefinedArmOf(global.type)
|
|
3705
|
+
: this.withUndefinedArm(global.type);
|
|
3706
|
+
if (!widened || typeEquals(widened, global.type))
|
|
3707
|
+
continue;
|
|
3708
|
+
global.type = widened;
|
|
3709
|
+
this.runtimeOptionalBindingTypes.set(symbol, widened);
|
|
3710
|
+
}
|
|
3711
|
+
}
|
|
3712
|
+
}
|
|
3713
|
+
}
|
|
3016
3714
|
analyzeRuntimeOptionalArrayReads(parts) {
|
|
3017
3715
|
const provenance = RuntimeOptionalProvenance.fromEnvironment();
|
|
3018
3716
|
// The site whose value the current promotion follows (debug only).
|
|
@@ -3133,7 +3831,7 @@ export class Lowerer {
|
|
|
3133
3831
|
const symbol = (ts.isFunctionDeclaration(fn) || ts.isMethodDeclaration(fn)) && fn.name
|
|
3134
3832
|
? symbolOf(fn.name)
|
|
3135
3833
|
: null;
|
|
3136
|
-
const index = fn.parameters.indexOf(parameter);
|
|
3834
|
+
const index = fn.parameters.nodes.indexOf(parameter);
|
|
3137
3835
|
return (symbol && signatureBySymbol.get(symbol)?.params[index]?.type) ?? null;
|
|
3138
3836
|
};
|
|
3139
3837
|
const returnTypeOf = (fn) => {
|
|
@@ -3142,7 +3840,7 @@ export class Lowerer {
|
|
|
3142
3840
|
};
|
|
3143
3841
|
const recordFlows = new RecordFlowClasses(sourceFiles, {
|
|
3144
3842
|
symbolOf,
|
|
3145
|
-
declarationOf: (symbol) =>
|
|
3843
|
+
declarationOf: (symbol) => symbol.valueDeclaration,
|
|
3146
3844
|
mayBeRecord: (node) => {
|
|
3147
3845
|
if (node.parent && ts.isParameter(node.parent))
|
|
3148
3846
|
return plainRecordShape(parameterType(node)) !== null;
|
|
@@ -3167,11 +3865,12 @@ export class Lowerer {
|
|
|
3167
3865
|
const recordParameterSlots = new Map();
|
|
3168
3866
|
const nanCoded = new NanCodedReads({
|
|
3169
3867
|
symbolOf,
|
|
3170
|
-
declarationOf: (symbol) =>
|
|
3868
|
+
declarationOf: (symbol) => symbol.valueDeclaration,
|
|
3171
3869
|
bytesElemOf: (receiver) => {
|
|
3172
3870
|
const t = mappedOrNull(receiver);
|
|
3173
3871
|
return t?.kind === "bytes" ? t.elem : null;
|
|
3174
3872
|
},
|
|
3873
|
+
isNumberRecordRead: (read) => this.optionalIndexSignatureRead(read)?.kind === "f64",
|
|
3175
3874
|
isNumber: (node) => mappedOrNull(node)?.kind === "f64",
|
|
3176
3875
|
isString: (node) => mappedOrNull(node)?.kind === "string",
|
|
3177
3876
|
hasLength: (node) => {
|
|
@@ -3213,7 +3912,7 @@ export class Lowerer {
|
|
|
3213
3912
|
const seen = new Set();
|
|
3214
3913
|
while (symbol && !signatureBySymbol.has(symbol) && !seen.has(symbol)) {
|
|
3215
3914
|
seen.add(symbol);
|
|
3216
|
-
const declaration =
|
|
3915
|
+
const declaration = symbol.valueDeclaration;
|
|
3217
3916
|
if (declaration && ts.isMethodDeclaration(declaration)) {
|
|
3218
3917
|
symbol = symbolOf(declaration.name);
|
|
3219
3918
|
}
|
|
@@ -3312,14 +4011,109 @@ export class Lowerer {
|
|
|
3312
4011
|
// every consumer treats undefined like NaN.
|
|
3313
4012
|
if (kind === "bytes")
|
|
3314
4013
|
return !nanCoded.isNumericRead(e);
|
|
4014
|
+
if (kind === "record")
|
|
4015
|
+
return this.optionalIndexSignatureRead(e) !== null && !nanCoded.isNumericRead(e);
|
|
3315
4016
|
return kind === "array";
|
|
3316
4017
|
};
|
|
4018
|
+
/** `r.name` where the name resolves to the receiver's index signature. */
|
|
4019
|
+
const isRecordIndexPropertyRead = (e) => {
|
|
4020
|
+
// A name that resolves to a declared member is not an index read, and
|
|
4021
|
+
// only a receiver with an index signature maps to an indexed record.
|
|
4022
|
+
if (symbolOf(e.name))
|
|
4023
|
+
return false;
|
|
4024
|
+
const receiverType = this.typeOf(e.expression);
|
|
4025
|
+
if (this.checker.getIndexInfosOfType(receiverType).length === 0)
|
|
4026
|
+
return false;
|
|
4027
|
+
const receiver = this.mapTypeOf(receiverType);
|
|
4028
|
+
if (receiver?.kind !== "record")
|
|
4029
|
+
return false;
|
|
4030
|
+
const shape = this.shapes.get(receiver.shapeId);
|
|
4031
|
+
if (!shape || shape.tuple || !shape.indexValue || shape.indexValue.kind === "dyn")
|
|
4032
|
+
return false;
|
|
4033
|
+
if (shape.fields.some((field) => field.name === e.name.text))
|
|
4034
|
+
return false;
|
|
4035
|
+
const read = this.mapTypeOf(this.typeOf(e));
|
|
4036
|
+
return !(read?.kind === "union" && this.armTag(read.unionId, UNDEFINED_T) >= 0);
|
|
4037
|
+
};
|
|
4038
|
+
/** An optional value in a generic body, where element types are type
|
|
4039
|
+
* parameters with no IR mapping yet: an element read of an array or a
|
|
4040
|
+
* read of a string index signature, judged on checker types. */
|
|
4041
|
+
const genericClassMethods = [];
|
|
4042
|
+
for (const sf of sourceFiles) {
|
|
4043
|
+
if (isJsSourceFile(sf) || sf.isDeclarationFile)
|
|
4044
|
+
continue;
|
|
4045
|
+
ts.walkPreorder(sf, (node) => {
|
|
4046
|
+
if (!ts.isClassDeclaration(node))
|
|
4047
|
+
return undefined;
|
|
4048
|
+
const genericClass = (node.typeParameters?.nodes.length ?? 0) > 0;
|
|
4049
|
+
for (const member of node.members.nodes)
|
|
4050
|
+
if (ts.isMethodDeclaration(member) &&
|
|
4051
|
+
member.body &&
|
|
4052
|
+
(genericClass || (member.typeParameters?.nodes.length ?? 0) > 0))
|
|
4053
|
+
genericClassMethods.push(member);
|
|
4054
|
+
return undefined;
|
|
4055
|
+
});
|
|
4056
|
+
}
|
|
4057
|
+
const genericMayBeOptional = (node) => {
|
|
4058
|
+
if (explicitlyNonNull(node))
|
|
4059
|
+
return false;
|
|
4060
|
+
if (mayBeOptional(node))
|
|
4061
|
+
return true;
|
|
4062
|
+
const e = peel(node);
|
|
4063
|
+
if (ts.isConditionalExpression(e))
|
|
4064
|
+
return genericMayBeOptional(e.whenTrue) || genericMayBeOptional(e.whenFalse);
|
|
4065
|
+
if (ts.isBinaryExpression(e)) {
|
|
4066
|
+
const op = e.operatorToken.kind;
|
|
4067
|
+
if (op === ts.SyntaxKind.BarBarToken || op === ts.SyntaxKind.QuestionQuestionToken)
|
|
4068
|
+
return genericMayBeOptional(e.right);
|
|
4069
|
+
if (op === ts.SyntaxKind.AmpersandAmpersandToken)
|
|
4070
|
+
return genericMayBeOptional(e.left) || genericMayBeOptional(e.right);
|
|
4071
|
+
return false;
|
|
4072
|
+
}
|
|
4073
|
+
if (ts.isIdentifier(e)) {
|
|
4074
|
+
// A binding initialized from such a read and never reassigned.
|
|
4075
|
+
const symbol = symbolOf(e);
|
|
4076
|
+
const decl = symbol ? symbol.valueDeclaration : undefined;
|
|
4077
|
+
return (symbol !== null &&
|
|
4078
|
+
!reassigned.has(symbol) &&
|
|
4079
|
+
decl !== undefined &&
|
|
4080
|
+
ts.isVariableDeclaration(decl) &&
|
|
4081
|
+
decl.initializer !== undefined &&
|
|
4082
|
+
ts.isIdentifier(decl.name) &&
|
|
4083
|
+
!provenPresent(e, symbol) &&
|
|
4084
|
+
genericIndexedRead(decl.initializer));
|
|
4085
|
+
}
|
|
4086
|
+
return genericIndexedRead(e);
|
|
4087
|
+
};
|
|
4088
|
+
const genericIndexedRead = (node) => {
|
|
4089
|
+
const e = peel(node);
|
|
4090
|
+
if (!ts.isElementAccessExpression(e) || explicitlyNonNull(node))
|
|
4091
|
+
return false;
|
|
4092
|
+
const read = typeOrNull(e);
|
|
4093
|
+
if (!read || (read.flags & (ts.TypeFlags.Undefined | ts.TypeFlags.Any)) !== 0)
|
|
4094
|
+
return false;
|
|
4095
|
+
if (read.isUnionType() &&
|
|
4096
|
+
ts.constituentTypes(read).some((t) => (t.flags & ts.TypeFlags.Undefined) !== 0))
|
|
4097
|
+
return false;
|
|
4098
|
+
const receiver = typeOrNull(e.expression);
|
|
4099
|
+
if (!receiver || this.checker.isTupleType(receiver))
|
|
4100
|
+
return false;
|
|
4101
|
+
if (this.checker.isArrayType(receiver))
|
|
4102
|
+
return true;
|
|
4103
|
+
const key = e.argumentExpression;
|
|
4104
|
+
if ((ts.isStringLiteral(key) || ts.isNumericLiteral(key)) &&
|
|
4105
|
+
this.checker.getPropertyOfType(receiver, key.text) !== undefined)
|
|
4106
|
+
return false;
|
|
4107
|
+
return this.checker
|
|
4108
|
+
.getIndexInfosOfType(receiver)
|
|
4109
|
+
.some((info) => (info.keyType.flags & ts.TypeFlags.StringLike) !== 0);
|
|
4110
|
+
};
|
|
3317
4111
|
const isDynamicObjectEntryRead = (node) => {
|
|
3318
4112
|
const read = peel(node);
|
|
3319
4113
|
if (!ts.isElementAccessExpression(read) || !ts.isIdentifier(read.expression))
|
|
3320
4114
|
return false;
|
|
3321
4115
|
const source = symbolOf(read.expression);
|
|
3322
|
-
const declaration = source ?
|
|
4116
|
+
const declaration = source ? source.valueDeclaration : undefined;
|
|
3323
4117
|
if (!declaration || !ts.isVariableDeclaration(declaration) || !declaration.initializer)
|
|
3324
4118
|
return false;
|
|
3325
4119
|
const init = peel(declaration.initializer);
|
|
@@ -3328,14 +4122,17 @@ export class Lowerer {
|
|
|
3328
4122
|
if (init.expression.name.text !== "entries" ||
|
|
3329
4123
|
!this.isStdlibGlobal(init.expression.expression, "Object"))
|
|
3330
4124
|
return false;
|
|
3331
|
-
const object = init.arguments[0];
|
|
4125
|
+
const object = init.arguments.nodes[0];
|
|
3332
4126
|
const objectType = object ? this.mapTypeOf(this.typeOf(object)) : null;
|
|
3333
4127
|
return objectType?.kind === "dyn";
|
|
3334
4128
|
};
|
|
3335
4129
|
const addUndefined = (t) => {
|
|
3336
4130
|
if (t.kind === "union")
|
|
3337
4131
|
return this.armTag(t.unionId, UNDEFINED_T) >= 0 ? t : (this.withUndefinedArmOf(t) ?? t);
|
|
3338
|
-
|
|
4132
|
+
// A Date has no undefined-armed union (it is not a union arm kind):
|
|
4133
|
+
// like a generator it keeps its type, and the site that would store
|
|
4134
|
+
// undefined into it keeps its own diagnostic.
|
|
4135
|
+
if (t.kind === "void" || t.kind === "dyn" || t.kind === "generator" || t.kind === "date")
|
|
3339
4136
|
return t;
|
|
3340
4137
|
return this.withUndefinedArm(t);
|
|
3341
4138
|
};
|
|
@@ -3371,15 +4168,41 @@ export class Lowerer {
|
|
|
3371
4168
|
// Such a binding reads `T | undefined`, so a typed parameter, local or
|
|
3372
4169
|
// field it flows into widens like any other missing element read.
|
|
3373
4170
|
const holeyIterationSymbols = new Set();
|
|
4171
|
+
// `xs[i] as number` and `stack.pop() as number`: an assertion to a type
|
|
4172
|
+
// without undefined checks the value (lowerAsExpression narrows to the
|
|
4173
|
+
// asserted type and throws a TypeError for undefined), so its result is
|
|
4174
|
+
// never undefined.
|
|
4175
|
+
const assertsDefined = (node) => {
|
|
4176
|
+
let e = node;
|
|
4177
|
+
while (ts.isParenthesizedExpression(e))
|
|
4178
|
+
e = e.expression;
|
|
4179
|
+
if (!ts.isAsExpression(e) && !ts.isTypeAssertion(e))
|
|
4180
|
+
return false;
|
|
4181
|
+
const asserted = typeOrNull(e);
|
|
4182
|
+
const admits = (type) => (type.flags &
|
|
4183
|
+
(ts.TypeFlags.Any |
|
|
4184
|
+
ts.TypeFlags.Unknown |
|
|
4185
|
+
ts.TypeFlags.Undefined |
|
|
4186
|
+
ts.TypeFlags.Void |
|
|
4187
|
+
ts.TypeFlags.TypeParameter)) !==
|
|
4188
|
+
0;
|
|
4189
|
+
return (asserted !== null &&
|
|
4190
|
+
!admits(asserted) &&
|
|
4191
|
+
!(asserted.isUnionType() && ts.constituentTypes(asserted).some(admits)));
|
|
4192
|
+
};
|
|
3374
4193
|
const mayBeOptional = (node) => {
|
|
3375
4194
|
// `xs[i]!` is the explicit proven-present form. Its array read keeps
|
|
3376
4195
|
// the established dense bounds trap and must not promote the enclosing
|
|
3377
4196
|
// function/global ABI to `T | undefined`.
|
|
3378
4197
|
if (explicitlyNonNull(node))
|
|
3379
4198
|
return false;
|
|
4199
|
+
if (assertsDefined(node))
|
|
4200
|
+
return false;
|
|
3380
4201
|
const e = peel(node);
|
|
3381
4202
|
if (isIndexedRead(e))
|
|
3382
4203
|
return true;
|
|
4204
|
+
if (ts.isPropertyAccessExpression(e) && isRecordIndexPropertyRead(e))
|
|
4205
|
+
return true;
|
|
3383
4206
|
if (ts.isPropertyAccessExpression(e) && isOptionalProcessStreamProperty(this, e))
|
|
3384
4207
|
return true;
|
|
3385
4208
|
if (ts.isPropertyAccessExpression(e) && isSettledIteratorValueRead(this, e))
|
|
@@ -3389,7 +4212,7 @@ export class Lowerer {
|
|
|
3389
4212
|
if (ts.isCallExpression(e) && this.runtimeOptionalReduceTypes.has(e))
|
|
3390
4213
|
return true;
|
|
3391
4214
|
if (ts.isCallExpression(e) &&
|
|
3392
|
-
e.arguments.length === 0 &&
|
|
4215
|
+
e.arguments.nodes.length === 0 &&
|
|
3393
4216
|
ts.isPropertyAccessExpression(e.expression) &&
|
|
3394
4217
|
e.expression.name.text === "stringify" &&
|
|
3395
4218
|
this.isStdlibGlobal(e.expression.expression, "JSON"))
|
|
@@ -3527,12 +4350,12 @@ export class Lowerer {
|
|
|
3527
4350
|
* exactly `T | undefined`: an assignment from a missing read stores the
|
|
3528
4351
|
* undefined arm while the checker narrows later reads to `T`. */
|
|
3529
4352
|
const optionalInstanceField = (symbol) => {
|
|
3530
|
-
const decl =
|
|
4353
|
+
const decl = symbol.valueDeclaration;
|
|
3531
4354
|
if (!decl || !ts.isPropertyDeclaration(decl) || !ts.isIdentifier(decl.name))
|
|
3532
4355
|
return false;
|
|
3533
4356
|
if (ts.getCombinedModifierFlags(decl) & ts.ModifierFlags.Static)
|
|
3534
4357
|
return false;
|
|
3535
|
-
const sf =
|
|
4358
|
+
const sf = ts.getSourceFileOfNode(decl);
|
|
3536
4359
|
if (isJsSourceFile(sf) || sf.isDeclarationFile)
|
|
3537
4360
|
return false;
|
|
3538
4361
|
const declared = typeOrNull(decl.name);
|
|
@@ -3564,7 +4387,7 @@ export class Lowerer {
|
|
|
3564
4387
|
// A fresh literal carries the fields its values can leave undefined.
|
|
3565
4388
|
if (ts.isObjectLiteralExpression(e)) {
|
|
3566
4389
|
const out = spreadFieldsOf(e);
|
|
3567
|
-
for (const prop of e.properties) {
|
|
4390
|
+
for (const prop of e.properties.nodes) {
|
|
3568
4391
|
if (!ts.isPropertyAssignment(prop) && !ts.isShorthandPropertyAssignment(prop))
|
|
3569
4392
|
continue;
|
|
3570
4393
|
const name = prop.name;
|
|
@@ -3602,7 +4425,7 @@ export class Lowerer {
|
|
|
3602
4425
|
* the properties a later member writes explicitly. */
|
|
3603
4426
|
const spreadFieldsOf = (object) => {
|
|
3604
4427
|
const out = new Set();
|
|
3605
|
-
for (const prop of object.properties) {
|
|
4428
|
+
for (const prop of object.properties.nodes) {
|
|
3606
4429
|
if (ts.isSpreadAssignment(prop)) {
|
|
3607
4430
|
const fields = fieldsOfValue(prop.expression);
|
|
3608
4431
|
if (fields !== undefined)
|
|
@@ -3617,14 +4440,35 @@ export class Lowerer {
|
|
|
3617
4440
|
return out;
|
|
3618
4441
|
};
|
|
3619
4442
|
const scanPattern = (name, init) => {
|
|
4443
|
+
if (ts.isObjectBindingPattern(name)) {
|
|
4444
|
+
// `const { 0: a, 1: b, length } = parts` reads positions like the
|
|
4445
|
+
// equivalent array pattern: each may sit past the end.
|
|
4446
|
+
// Regex match results keep their own pattern lowering.
|
|
4447
|
+
const arrayType = this.mapTypeOf(this.typeOf(init));
|
|
4448
|
+
const initType = this.checker.getNonNullableType(this.typeOf(init));
|
|
4449
|
+
const initSymbol = initType.getAliasSymbol() ?? initType.getSymbol();
|
|
4450
|
+
const matchResult = initSymbol !== undefined &&
|
|
4451
|
+
(ts.symbolName(initSymbol) === "RegExpExecArray" ||
|
|
4452
|
+
ts.symbolName(initSymbol) === "RegExpMatchArray");
|
|
4453
|
+
if (arrayType?.kind !== "array" || matchResult)
|
|
4454
|
+
return scanRecordPattern(name, init);
|
|
4455
|
+
const positions = name.elements.nodes.filter((el) => {
|
|
4456
|
+
const key = el.propertyName;
|
|
4457
|
+
return (key !== undefined && ts.isNumericLiteral(key) && /^(?:0|[1-9]\d{0,8})$/.test(key.text));
|
|
4458
|
+
});
|
|
4459
|
+
return scanPositions(positions, init, arrayType);
|
|
4460
|
+
}
|
|
3620
4461
|
if (!ts.isArrayBindingPattern(name))
|
|
3621
4462
|
return false;
|
|
3622
4463
|
const sourceType = this.mapTypeOf(this.typeOf(init));
|
|
3623
4464
|
if (sourceType?.kind !== "array")
|
|
3624
4465
|
return false;
|
|
4466
|
+
return scanPositions(name.elements.nodes.filter((el) => !ts.isOmittedExpression(el)), init, sourceType);
|
|
4467
|
+
};
|
|
4468
|
+
const scanPositions = (elements, init, sourceType) => {
|
|
3625
4469
|
let changed = false;
|
|
3626
|
-
|
|
3627
|
-
if (
|
|
4470
|
+
elements.forEach((el) => {
|
|
4471
|
+
if (el.name === undefined || el.dotDotDotToken)
|
|
3628
4472
|
return;
|
|
3629
4473
|
if (ts.isIdentifier(el.name)) {
|
|
3630
4474
|
const symbol = symbolOf(el.name);
|
|
@@ -3654,6 +4498,47 @@ export class Lowerer {
|
|
|
3654
4498
|
});
|
|
3655
4499
|
return changed;
|
|
3656
4500
|
};
|
|
4501
|
+
/** `const { a, b } = table` over an index-signature record: a name that
|
|
4502
|
+
* is not a declared field reads the index signature and can be
|
|
4503
|
+
* missing. */
|
|
4504
|
+
const scanRecordPattern = (name, init) => {
|
|
4505
|
+
const sourceType = this.mapTypeOf(this.typeOf(init));
|
|
4506
|
+
if (sourceType?.kind !== "record")
|
|
4507
|
+
return false;
|
|
4508
|
+
const shape = this.shapes.get(sourceType.shapeId);
|
|
4509
|
+
const indexValue = shape?.indexValue;
|
|
4510
|
+
if (!shape || shape.tuple || !indexValue || indexValue.kind === "dyn")
|
|
4511
|
+
return false;
|
|
4512
|
+
let changed = false;
|
|
4513
|
+
for (const el of name.elements.nodes) {
|
|
4514
|
+
if (el.dotDotDotToken || el.initializer || !ts.isIdentifier(el.name))
|
|
4515
|
+
continue;
|
|
4516
|
+
const key = el.propertyName ?? el.name;
|
|
4517
|
+
if (!ts.isIdentifier(key) && !ts.isStringLiteral(key) && !ts.isNumericLiteral(key))
|
|
4518
|
+
continue;
|
|
4519
|
+
if (shape.fields.some((field) => field.name === key.text))
|
|
4520
|
+
continue;
|
|
4521
|
+
const symbol = symbolOf(el.name);
|
|
4522
|
+
if (!symbol || optionalSymbols.has(symbol))
|
|
4523
|
+
continue;
|
|
4524
|
+
const read = this.mapTypeOf(this.typeOf(el.name));
|
|
4525
|
+
if (read?.kind === "union" && this.armTag(read.unionId, UNDEFINED_T) >= 0)
|
|
4526
|
+
continue;
|
|
4527
|
+
const widened = this.withUndefinedArmOf(indexValue);
|
|
4528
|
+
if (!widened)
|
|
4529
|
+
continue;
|
|
4530
|
+
optionalSymbols.add(symbol);
|
|
4531
|
+
provenance?.note("pattern-binding", el.name, init);
|
|
4532
|
+
this.runtimeOptionalBindingTypes.set(symbol, widened);
|
|
4533
|
+
const global = this.globalsBySymbol.get(symbol);
|
|
4534
|
+
if (global) {
|
|
4535
|
+
global.type = widened;
|
|
4536
|
+
this.runtimeOptionalGlobals.add(global);
|
|
4537
|
+
}
|
|
4538
|
+
changed = true;
|
|
4539
|
+
}
|
|
4540
|
+
return changed;
|
|
4541
|
+
};
|
|
3657
4542
|
const hofCallbackIndices = (name, hasInitialValue) => {
|
|
3658
4543
|
if (name === "reduce" || name === "reduceRight")
|
|
3659
4544
|
return hasInitialValue ? [1] : [0, 1];
|
|
@@ -3747,7 +4632,7 @@ export class Lowerer {
|
|
|
3747
4632
|
};
|
|
3748
4633
|
for (const [symbol, signature] of signatureBySymbol) {
|
|
3749
4634
|
const declaration = functionDeclBySymbol.get(symbol);
|
|
3750
|
-
if (!declaration || !isJsSourceFile(
|
|
4635
|
+
if (!declaration || !isJsSourceFile(ts.getSourceFileOfNode(declaration)))
|
|
3751
4636
|
continue;
|
|
3752
4637
|
const checked = this.checker.getSignatureFromDeclaration(declaration);
|
|
3753
4638
|
const checkedReturn = checked ? this.checker.getReturnTypeOfSignature(checked) : null;
|
|
@@ -3775,7 +4660,7 @@ export class Lowerer {
|
|
|
3775
4660
|
for (const parameterIndex of parameterIndices) {
|
|
3776
4661
|
if (parameterIndex === undefined)
|
|
3777
4662
|
continue;
|
|
3778
|
-
const parameter = fn.parameters[parameterIndex];
|
|
4663
|
+
const parameter = fn.parameters.nodes[parameterIndex];
|
|
3779
4664
|
if (!parameter)
|
|
3780
4665
|
continue;
|
|
3781
4666
|
const symbol = ts.isIdentifier(parameter.name) ? symbolOf(parameter.name) : null;
|
|
@@ -3844,7 +4729,7 @@ export class Lowerer {
|
|
|
3844
4729
|
if (this.genericFnsBySymbol.has(symbol))
|
|
3845
4730
|
return false;
|
|
3846
4731
|
seen.add(symbol);
|
|
3847
|
-
const declaration =
|
|
4732
|
+
const declaration = symbol.valueDeclaration;
|
|
3848
4733
|
if (declaration && ts.isVariableDeclaration(declaration) && declaration.initializer) {
|
|
3849
4734
|
if (promoteHofCallback(peel(declaration.initializer), parameterIndices, seen))
|
|
3850
4735
|
changed = true;
|
|
@@ -3899,7 +4784,9 @@ export class Lowerer {
|
|
|
3899
4784
|
owner.name)
|
|
3900
4785
|
ownerSymbol = symbolOf(owner.name);
|
|
3901
4786
|
const ownerSig = ownerSymbol ? signatureBySymbol.get(ownerSymbol) : undefined;
|
|
3902
|
-
const ownerIndex = ts.isFunctionLike(owner)
|
|
4787
|
+
const ownerIndex = ts.isFunctionLike(owner)
|
|
4788
|
+
? owner.parameters.nodes.indexOf(declaration)
|
|
4789
|
+
: -1;
|
|
3903
4790
|
const slot = ownerIndex >= 0 ? ownerSig?.params[ownerIndex] : undefined;
|
|
3904
4791
|
if (slot && !typeEquals(slot.type, promoted)) {
|
|
3905
4792
|
slot.type = promoted;
|
|
@@ -3919,7 +4806,7 @@ export class Lowerer {
|
|
|
3919
4806
|
return false;
|
|
3920
4807
|
let changed = false;
|
|
3921
4808
|
for (const parameterIndex of parameterIndices) {
|
|
3922
|
-
const parameter = fn.parameters[parameterIndex];
|
|
4809
|
+
const parameter = fn.parameters.nodes[parameterIndex];
|
|
3923
4810
|
if (!parameter)
|
|
3924
4811
|
continue;
|
|
3925
4812
|
const checkerType = this.typeOf(parameter.name);
|
|
@@ -3957,7 +4844,7 @@ export class Lowerer {
|
|
|
3957
4844
|
const fn = peel(callback);
|
|
3958
4845
|
let param;
|
|
3959
4846
|
if (ts.isArrowFunction(fn) || ts.isFunctionExpression(fn)) {
|
|
3960
|
-
const parameter = fn.parameters[index];
|
|
4847
|
+
const parameter = fn.parameters.nodes[index];
|
|
3961
4848
|
if (!parameter?.type || parameter.dotDotDotToken)
|
|
3962
4849
|
return true;
|
|
3963
4850
|
const checkerType = this.typeOf(parameter.name);
|
|
@@ -3984,7 +4871,7 @@ export class Lowerer {
|
|
|
3984
4871
|
const fn = functionDeclBySymbol.get(symbol);
|
|
3985
4872
|
if (fn)
|
|
3986
4873
|
return bodyReturnsOptional(fn);
|
|
3987
|
-
const decl =
|
|
4874
|
+
const decl = symbol.valueDeclaration;
|
|
3988
4875
|
return (!!decl &&
|
|
3989
4876
|
ts.isVariableDeclaration(decl) &&
|
|
3990
4877
|
!!decl.initializer &&
|
|
@@ -4062,7 +4949,7 @@ export class Lowerer {
|
|
|
4062
4949
|
};
|
|
4063
4950
|
const ownership = new ArrayOwnership(sourceFiles, {
|
|
4064
4951
|
symbolOf,
|
|
4065
|
-
declarationOf: (symbol) =>
|
|
4952
|
+
declarationOf: (symbol) => symbol.valueDeclaration,
|
|
4066
4953
|
typeOf: typeOrNull,
|
|
4067
4954
|
instanceAssignableTo: (owner, target) => panicSafe(() => this.checker.isTypeAssignableTo(this.checker.getTypeAtLocation(owner), target), true),
|
|
4068
4955
|
isGlobal: (node, name) => this.isStdlibGlobal(node, name),
|
|
@@ -4083,7 +4970,7 @@ export class Lowerer {
|
|
|
4083
4970
|
// flow type such as `Array.isArray(x)`'s `any[]` only narrows it.
|
|
4084
4971
|
const e = peel(node);
|
|
4085
4972
|
const symbol = ts.isIdentifier(e) ? symbolOf(e) : null;
|
|
4086
|
-
const declaration = symbol ?
|
|
4973
|
+
const declaration = symbol ? symbol.valueDeclaration : undefined;
|
|
4087
4974
|
const declared = declaration &&
|
|
4088
4975
|
(ts.isVariableDeclaration(declaration) || ts.isParameter(declaration)) &&
|
|
4089
4976
|
ts.isIdentifier(declaration.name)
|
|
@@ -4139,14 +5026,14 @@ export class Lowerer {
|
|
|
4139
5026
|
else if (ts.isReturnStatement(node) && node.expression && dynamicValue(node.expression))
|
|
4140
5027
|
target(contextualOrNull(node.expression));
|
|
4141
5028
|
else if (ts.isCallExpression(node) || ts.isNewExpression(node)) {
|
|
4142
|
-
for (const arg of node.arguments ?? [])
|
|
5029
|
+
for (const arg of node.arguments?.nodes ?? [])
|
|
4143
5030
|
if (!ts.isSpreadElement(arg) && dynamicValue(arg))
|
|
4144
5031
|
target(contextualOrNull(arg));
|
|
4145
5032
|
}
|
|
4146
5033
|
else if (ts.isPropertyAssignment(node) && dynamicValue(node.initializer))
|
|
4147
5034
|
target(contextualOrNull(node.initializer));
|
|
4148
5035
|
else if (ts.isArrayLiteralExpression(node)) {
|
|
4149
|
-
for (const element of node.elements)
|
|
5036
|
+
for (const element of node.elements.nodes)
|
|
4150
5037
|
if (!ts.isSpreadElement(element) &&
|
|
4151
5038
|
!ts.isOmittedExpression(element) &&
|
|
4152
5039
|
dynamicValue(element))
|
|
@@ -4374,7 +5261,7 @@ export class Lowerer {
|
|
|
4374
5261
|
if (ts.isIdentifier(node.name) &&
|
|
4375
5262
|
ts.isObjectLiteralExpression(peel(node.initializer))) {
|
|
4376
5263
|
const object = peel(node.initializer);
|
|
4377
|
-
for (const prop of object.properties) {
|
|
5264
|
+
for (const prop of object.properties.nodes) {
|
|
4378
5265
|
if (!ts.isPropertyAssignment(prop) && !ts.isShorthandPropertyAssignment(prop))
|
|
4379
5266
|
continue;
|
|
4380
5267
|
const name = prop.name;
|
|
@@ -4407,7 +5294,7 @@ export class Lowerer {
|
|
|
4407
5294
|
const assertion = forwardedAssertion(node.right);
|
|
4408
5295
|
const symbol = assertion ? symbolOf(node.left) : null;
|
|
4409
5296
|
// Only a variable's storage is promoted (see the final pass).
|
|
4410
|
-
const declaration = symbol ?
|
|
5297
|
+
const declaration = symbol ? symbol.valueDeclaration : undefined;
|
|
4411
5298
|
if (assertion &&
|
|
4412
5299
|
symbol &&
|
|
4413
5300
|
declaration &&
|
|
@@ -4461,8 +5348,8 @@ export class Lowerer {
|
|
|
4461
5348
|
}
|
|
4462
5349
|
}
|
|
4463
5350
|
if (ts.isCallExpression(node) && ts.isPropertyAccessExpression(node.expression)) {
|
|
4464
|
-
const callbackIndices = hofCallbackIndices(node.expression.name.text, node.arguments.length >= 2);
|
|
4465
|
-
const callback = node.arguments[0];
|
|
5351
|
+
const callbackIndices = hofCallbackIndices(node.expression.name.text, node.arguments.nodes.length >= 2);
|
|
5352
|
+
const callback = node.arguments.nodes[0];
|
|
4466
5353
|
if (callbackIndices !== null && callback !== undefined && !ts.isSpreadElement(callback)) {
|
|
4467
5354
|
const receiverNode = node.expression.expression;
|
|
4468
5355
|
const receiverTs = this.typeOf(receiverNode);
|
|
@@ -4486,9 +5373,7 @@ export class Lowerer {
|
|
|
4486
5373
|
let nativeArrayReceiver = receiver?.kind === "array" || tuple;
|
|
4487
5374
|
if (nativeArrayReceiver && ts.isIdentifier(receiverNode)) {
|
|
4488
5375
|
const receiverSymbol = symbolOf(receiverNode);
|
|
4489
|
-
const declaration = receiverSymbol
|
|
4490
|
-
? this.checker.valueDeclarationOf(receiverSymbol)
|
|
4491
|
-
: undefined;
|
|
5376
|
+
const declaration = receiverSymbol ? receiverSymbol.valueDeclaration : undefined;
|
|
4492
5377
|
if (declaration && ts.isVariableDeclaration(declaration)) {
|
|
4493
5378
|
const declared = this.mapTypeOf(this.typeOf(declaration.name));
|
|
4494
5379
|
if (declared?.kind !== "array" &&
|
|
@@ -4516,7 +5401,7 @@ export class Lowerer {
|
|
|
4516
5401
|
if (elementsPresent && reduce && retypeInlineCallback(callback, callbackIndices))
|
|
4517
5402
|
changed = true;
|
|
4518
5403
|
if ((method === "reduce" || method === "reduceRight") &&
|
|
4519
|
-
((!elementsPresent && node.arguments.length < 2) ||
|
|
5404
|
+
((!elementsPresent && node.arguments.nodes.length < 2) ||
|
|
4520
5405
|
callbackReturnsOptional(callback))) {
|
|
4521
5406
|
if (promoteHofCallback(callback, [0, 1]))
|
|
4522
5407
|
changed = true;
|
|
@@ -4542,20 +5427,20 @@ export class Lowerer {
|
|
|
4542
5427
|
// parameter, as for a callback the same value is passed as.
|
|
4543
5428
|
if (!ts.isIdentifier(node.expression) || reassigned.has(symbol))
|
|
4544
5429
|
return;
|
|
4545
|
-
const declaration =
|
|
5430
|
+
const declaration = symbol.valueDeclaration;
|
|
4546
5431
|
const value = declaration && ts.isVariableDeclaration(declaration) && declaration.initializer
|
|
4547
5432
|
? peel(declaration.initializer)
|
|
4548
5433
|
: null;
|
|
4549
5434
|
if (!value || !(ts.isArrowFunction(value) || ts.isFunctionExpression(value)))
|
|
4550
5435
|
return;
|
|
4551
5436
|
// Optional, defaulted and rest parameters keep their own ABI.
|
|
4552
|
-
if (value.parameters.some((parameter) => parameter.questionToken !== undefined ||
|
|
5437
|
+
if (value.parameters.nodes.some((parameter) => parameter.questionToken !== undefined ||
|
|
4553
5438
|
parameter.initializer !== undefined ||
|
|
4554
5439
|
parameter.dotDotDotToken !== undefined))
|
|
4555
5440
|
return;
|
|
4556
|
-
const indices = node.arguments.flatMap((arg, i) => !ts.isSpreadElement(arg) &&
|
|
4557
|
-
value.parameters[i] !== undefined &&
|
|
4558
|
-
!value.parameters[i].dotDotDotToken &&
|
|
5441
|
+
const indices = node.arguments.nodes.flatMap((arg, i) => !ts.isSpreadElement(arg) &&
|
|
5442
|
+
value.parameters.nodes[i] !== undefined &&
|
|
5443
|
+
!value.parameters.nodes[i].dotDotDotToken &&
|
|
4559
5444
|
mayBeOptional(arg)
|
|
4560
5445
|
? [i]
|
|
4561
5446
|
: []);
|
|
@@ -4570,10 +5455,10 @@ export class Lowerer {
|
|
|
4570
5455
|
// agree on that value's representation.
|
|
4571
5456
|
const callee = functionDeclBySymbol.get(symbol);
|
|
4572
5457
|
if (callee &&
|
|
4573
|
-
isJsSourceFile(
|
|
4574
|
-
!node.arguments.some(ts.isSpreadElement)) {
|
|
5458
|
+
isJsSourceFile(ts.getSourceFileOfNode(callee)) &&
|
|
5459
|
+
!node.arguments.nodes.some(ts.isSpreadElement)) {
|
|
4575
5460
|
for (let i = 0; i < sig.params.length; i++) {
|
|
4576
|
-
const arg = node.arguments[i];
|
|
5461
|
+
const arg = node.arguments.nodes[i];
|
|
4577
5462
|
if (arg &&
|
|
4578
5463
|
(this.typeOf(arg).flags & (ts.TypeFlags.Undefined | ts.TypeFlags.Void)) === 0)
|
|
4579
5464
|
continue;
|
|
@@ -4585,7 +5470,7 @@ export class Lowerer {
|
|
|
4585
5470
|
if (typeEquals(shape.type, widened))
|
|
4586
5471
|
continue;
|
|
4587
5472
|
shape.type = widened;
|
|
4588
|
-
const parameter = functionDeclBySymbol.get(target)?.parameters[i];
|
|
5473
|
+
const parameter = functionDeclBySymbol.get(target)?.parameters?.nodes[i];
|
|
4589
5474
|
provenance?.note("parameter", parameter, node, "(omitted or undefined argument)");
|
|
4590
5475
|
if (parameter) {
|
|
4591
5476
|
for (const bound of boundIdentifiersOf(parameter.name)) {
|
|
@@ -4602,7 +5487,7 @@ export class Lowerer {
|
|
|
4602
5487
|
}
|
|
4603
5488
|
}
|
|
4604
5489
|
const restAt = sig.params.findIndex((shape) => shape.mode === "rest" || shape.mode === "dynRest" || shape.mode === "arguments");
|
|
4605
|
-
node.arguments.forEach((arg, argumentIndex) => {
|
|
5490
|
+
node.arguments.nodes.forEach((arg, argumentIndex) => {
|
|
4606
5491
|
const i = restAt >= 0 && argumentIndex >= restAt ? restAt : argumentIndex;
|
|
4607
5492
|
const shape = sig.params[i];
|
|
4608
5493
|
const callbackSlot = shape?.type;
|
|
@@ -4618,7 +5503,7 @@ export class Lowerer {
|
|
|
4618
5503
|
const fields = fieldsOfValue(arg);
|
|
4619
5504
|
for (const target of familyBySymbol.get(symbol) ?? [symbol]) {
|
|
4620
5505
|
const parameterShape = signatureBySymbol.get(target)?.params[i];
|
|
4621
|
-
const parameter = functionDeclBySymbol.get(target)?.parameters[i];
|
|
5506
|
+
const parameter = functionDeclBySymbol.get(target)?.parameters?.nodes[i];
|
|
4622
5507
|
if (!parameterShape || parameterShape.type.kind !== "record")
|
|
4623
5508
|
continue;
|
|
4624
5509
|
if (!parameter || !ts.isIdentifier(parameter.name))
|
|
@@ -4675,7 +5560,7 @@ export class Lowerer {
|
|
|
4675
5560
|
if (typeEquals(rest.type, widened))
|
|
4676
5561
|
continue;
|
|
4677
5562
|
rest.type = widened;
|
|
4678
|
-
const parameter = functionDeclBySymbol.get(target)?.parameters[i];
|
|
5563
|
+
const parameter = functionDeclBySymbol.get(target)?.parameters?.nodes[i];
|
|
4679
5564
|
provenance?.note("rest-parameter", parameter, arg);
|
|
4680
5565
|
if (parameter && ts.isIdentifier(parameter.name)) {
|
|
4681
5566
|
const bound = symbolOf(parameter.name);
|
|
@@ -4702,7 +5587,7 @@ export class Lowerer {
|
|
|
4702
5587
|
optionalParams.set(target, set);
|
|
4703
5588
|
if (set.size !== before) {
|
|
4704
5589
|
changed = true;
|
|
4705
|
-
const parameter = functionDeclBySymbol.get(target)?.parameters[i];
|
|
5590
|
+
const parameter = functionDeclBySymbol.get(target)?.parameters?.nodes[i];
|
|
4706
5591
|
provenance?.note("parameter", parameter, arg, target === symbol ? "" : "(override)");
|
|
4707
5592
|
if (parameter) {
|
|
4708
5593
|
for (const bound of boundIdentifiersOf(parameter.name)) {
|
|
@@ -4762,7 +5647,7 @@ export class Lowerer {
|
|
|
4762
5647
|
// there, whatever its declared type.
|
|
4763
5648
|
for (const symbol of earlyReadVarSymbols(this, sourceFiles)) {
|
|
4764
5649
|
// Text codec bindings keep their own presence-checked storage.
|
|
4765
|
-
const declaration =
|
|
5650
|
+
const declaration = symbol.valueDeclaration;
|
|
4766
5651
|
const mapped = declaration && ts.isVariableDeclaration(declaration)
|
|
4767
5652
|
? mappedOrNull(declaration.name)
|
|
4768
5653
|
: null;
|
|
@@ -4787,6 +5672,25 @@ export class Lowerer {
|
|
|
4787
5672
|
for (const [symbol, decl] of functionDeclBySymbol)
|
|
4788
5673
|
if (scanReturns(symbol, decl))
|
|
4789
5674
|
changed = true;
|
|
5675
|
+
const noteGenericReturn = (symbol, decl) => {
|
|
5676
|
+
if (optionalReturns.has(symbol) || isJsSourceFile(ts.getSourceFileOfNode(decl)))
|
|
5677
|
+
return;
|
|
5678
|
+
if (!returnsOf(decl).some(genericMayBeOptional))
|
|
5679
|
+
return;
|
|
5680
|
+
optionalReturns.add(symbol);
|
|
5681
|
+
this.runtimeOptionalGenericReturns.add(decl);
|
|
5682
|
+
provenance?.note("return", decl.name ?? decl, decl);
|
|
5683
|
+
changed = true;
|
|
5684
|
+
};
|
|
5685
|
+
for (const [symbol, info] of this.genericFnsBySymbol)
|
|
5686
|
+
noteGenericReturn(symbol, info.decl);
|
|
5687
|
+
// Generic methods and methods of a generic class collect with their
|
|
5688
|
+
// class, after this analysis; their result admits undefined there.
|
|
5689
|
+
for (const method of genericClassMethods) {
|
|
5690
|
+
const symbol = method.name ? symbolOf(method.name) : null;
|
|
5691
|
+
if (symbol)
|
|
5692
|
+
noteGenericReturn(symbol, method);
|
|
5693
|
+
}
|
|
4790
5694
|
for (const fn of tsLambdas) {
|
|
4791
5695
|
// An annotated return is the author's contract, as for parameters,
|
|
4792
5696
|
// except that a var read before its first store is undefined
|
|
@@ -4894,7 +5798,7 @@ export class Lowerer {
|
|
|
4894
5798
|
for (const [symbol, params] of optionalParams) {
|
|
4895
5799
|
const decl = functionDeclBySymbol.get(symbol);
|
|
4896
5800
|
for (const index of [...params]) {
|
|
4897
|
-
const name = decl?.parameters[index]?.name;
|
|
5801
|
+
const name = decl?.parameters?.nodes[index]?.name;
|
|
4898
5802
|
const param = name && ts.isIdentifier(name) ? symbolOf(name) : null;
|
|
4899
5803
|
if (param && nanCoded.nanCodedBinding(param))
|
|
4900
5804
|
params.delete(index);
|
|
@@ -4939,20 +5843,52 @@ export class Lowerer {
|
|
|
4939
5843
|
addClassFields(recordFlows.bindingClass(symbol), fields);
|
|
4940
5844
|
for (const [symbol, fields] of returnFields)
|
|
4941
5845
|
addClassFields(recordFlows.returnClass(symbol), fields);
|
|
5846
|
+
// A record field that flows into other slots (`fill(args, state.parsed)`)
|
|
5847
|
+
// widens with its owner's class: every member takes the field's widened
|
|
5848
|
+
// layout, so the field and the slots it reaches share one record.
|
|
5849
|
+
const nestedFields = new Map();
|
|
5850
|
+
for (let changed = true; changed;) {
|
|
5851
|
+
changed = false;
|
|
5852
|
+
for (const { owner, name, classId } of recordFlows.fields()) {
|
|
5853
|
+
if (nestedFields.get(owner)?.has(name))
|
|
5854
|
+
continue;
|
|
5855
|
+
if (!(classFields.has(classId) || nestedFields.has(classId)))
|
|
5856
|
+
continue;
|
|
5857
|
+
if (!recordFlows.closed(classId))
|
|
5858
|
+
continue;
|
|
5859
|
+
const byName = nestedFields.get(owner) ?? new Map();
|
|
5860
|
+
byName.set(name, classId);
|
|
5861
|
+
nestedFields.set(owner, byName);
|
|
5862
|
+
changed = true;
|
|
5863
|
+
}
|
|
5864
|
+
}
|
|
4942
5865
|
const settledFields = (id, own) => id === null
|
|
4943
5866
|
? own
|
|
4944
|
-
: classFields.has(id) && recordFlows.closed(id)
|
|
4945
|
-
? classFields.get(id)
|
|
5867
|
+
: (classFields.has(id) || nestedFields.has(id)) && recordFlows.closed(id)
|
|
5868
|
+
? (classFields.get(id) ?? new Set())
|
|
4946
5869
|
: undefined;
|
|
4947
|
-
const widenRecordFields = (type, fields) => {
|
|
5870
|
+
const widenRecordFields = (type, fields, id = null, seen = new Set()) => {
|
|
4948
5871
|
let promoted = type;
|
|
5872
|
+
const fieldOf = (name) => promoted.kind === "record"
|
|
5873
|
+
? this.shapes.get(promoted.shapeId)?.fields.find((f) => f.name === name)
|
|
5874
|
+
: undefined;
|
|
4949
5875
|
for (const field of fields) {
|
|
4950
|
-
const source =
|
|
4951
|
-
? this.shapes.get(promoted.shapeId)?.fields.find((f) => f.name === field)
|
|
4952
|
-
: undefined;
|
|
5876
|
+
const source = fieldOf(field);
|
|
4953
5877
|
if (source)
|
|
4954
5878
|
promoted = this.runtimeOptionalRecordField(promoted, field, addUndefined(source.type));
|
|
4955
5879
|
}
|
|
5880
|
+
if (id === null || seen.has(id))
|
|
5881
|
+
return promoted;
|
|
5882
|
+
const nested = nestedFields.get(id);
|
|
5883
|
+
if (!nested)
|
|
5884
|
+
return promoted;
|
|
5885
|
+
for (const [field, inner] of nested) {
|
|
5886
|
+
const source = fieldOf(field);
|
|
5887
|
+
if (source?.type.kind !== "record")
|
|
5888
|
+
continue;
|
|
5889
|
+
const widened = widenRecordFields(source.type, classFields.get(inner) ?? new Set(), inner, new Set([...seen, id]));
|
|
5890
|
+
promoted = this.runtimeOptionalRecordField(promoted, field, widened);
|
|
5891
|
+
}
|
|
4956
5892
|
return promoted;
|
|
4957
5893
|
};
|
|
4958
5894
|
for (const [symbol, id] of recordFlows.bindings())
|
|
@@ -4968,10 +5904,11 @@ export class Lowerer {
|
|
|
4968
5904
|
const shape = signatureBySymbol.get(target)?.params[index];
|
|
4969
5905
|
if (!shape || shape.type.kind !== "record")
|
|
4970
5906
|
continue;
|
|
4971
|
-
const
|
|
5907
|
+
const id = recordFlows.bindingClass(bound);
|
|
5908
|
+
const fields = settledFields(id, optionalFields.get(bound));
|
|
4972
5909
|
if (!fields)
|
|
4973
5910
|
continue;
|
|
4974
|
-
const promoted = widenRecordFields(shape.type, fields);
|
|
5911
|
+
const promoted = widenRecordFields(shape.type, fields, id);
|
|
4975
5912
|
if (typeEquals(promoted, shape.type))
|
|
4976
5913
|
continue;
|
|
4977
5914
|
shape.type = promoted;
|
|
@@ -4981,7 +5918,7 @@ export class Lowerer {
|
|
|
4981
5918
|
const id = recordFlows.returnClass(symbol);
|
|
4982
5919
|
const fields = id === null ? undefined : settledFields(id, undefined);
|
|
4983
5920
|
if (fields && sig.returnType.kind === "record") {
|
|
4984
|
-
const next = widenRecordFields(sig.returnType, fields);
|
|
5921
|
+
const next = widenRecordFields(sig.returnType, fields, id);
|
|
4985
5922
|
sig.returnType = next;
|
|
4986
5923
|
if (sig.top)
|
|
4987
5924
|
sig.top.returnType = next;
|
|
@@ -5023,7 +5960,7 @@ export class Lowerer {
|
|
|
5023
5960
|
for (const [declaration, global] of this.globalsByDeclNode) {
|
|
5024
5961
|
if (global.type.kind !== "func" ||
|
|
5025
5962
|
!ts.isBinaryExpression(declaration) ||
|
|
5026
|
-
!isJsSourceFile(
|
|
5963
|
+
!isJsSourceFile(ts.getSourceFileOfNode(declaration)))
|
|
5027
5964
|
continue;
|
|
5028
5965
|
const value = peel(declaration.right);
|
|
5029
5966
|
if (!ts.isFunctionExpression(value) && !ts.isArrowFunction(value))
|
|
@@ -5072,7 +6009,8 @@ export class Lowerer {
|
|
|
5072
6009
|
global.type = promoted;
|
|
5073
6010
|
}
|
|
5074
6011
|
}
|
|
5075
|
-
const
|
|
6012
|
+
const flowClass = recordFlows.bindingClass(symbol);
|
|
6013
|
+
const fields = settledFields(flowClass, optionalFields.get(symbol));
|
|
5076
6014
|
if (!dynamicObjectEntryRows.has(symbol) && !optionalSymbols.has(symbol) && !fields)
|
|
5077
6015
|
return;
|
|
5078
6016
|
const current = this.mapTypeOf(this.typeOf(node.name));
|
|
@@ -5092,7 +6030,7 @@ export class Lowerer {
|
|
|
5092
6030
|
}
|
|
5093
6031
|
}
|
|
5094
6032
|
if (fields && promoted.kind === "record")
|
|
5095
|
-
promoted = widenRecordFields(promoted, fields);
|
|
6033
|
+
promoted = widenRecordFields(promoted, fields, flowClass);
|
|
5096
6034
|
if (!typeEquals(promoted, current)) {
|
|
5097
6035
|
this.runtimeOptionalBindingTypes.set(symbol, promoted);
|
|
5098
6036
|
const global = ts.isIdentifier(node.name)
|
|
@@ -5125,9 +6063,9 @@ export class Lowerer {
|
|
|
5125
6063
|
continue;
|
|
5126
6064
|
const symbol = callableSymbolOf(node.expression);
|
|
5127
6065
|
const sig = symbol ? signatureBySymbol.get(symbol) : undefined;
|
|
5128
|
-
if (!sig || node.arguments.some(ts.isSpreadElement))
|
|
6066
|
+
if (!sig || node.arguments.nodes.some(ts.isSpreadElement))
|
|
5129
6067
|
continue;
|
|
5130
|
-
node.arguments.forEach((arg, i) => {
|
|
6068
|
+
node.arguments.nodes.forEach((arg, i) => {
|
|
5131
6069
|
let e = arg;
|
|
5132
6070
|
while (ts.isParenthesizedExpression(e))
|
|
5133
6071
|
e = e.expression;
|
|
@@ -5157,7 +6095,12 @@ export class Lowerer {
|
|
|
5157
6095
|
this.checker.prefetchSourceFile(fp.sf);
|
|
5158
6096
|
}
|
|
5159
6097
|
this.collectProgram(parts);
|
|
5160
|
-
this.
|
|
6098
|
+
this.speculativeTypeQueries(() => {
|
|
6099
|
+
extendAssertedRecordMembers(this, parts.map((fp) => fp.sf));
|
|
6100
|
+
this.analyzeRuntimeOptionalArrayReads(parts);
|
|
6101
|
+
this.analyzeDateJsonResults(parts);
|
|
6102
|
+
this.analyzeGuardedRecordReadGlobals(parts);
|
|
6103
|
+
});
|
|
5161
6104
|
// Decorated classes analyze AFTER the whole collection pass: a
|
|
5162
6105
|
// decorator's return type may name a subclass declared below the
|
|
5163
6106
|
// class, and reference lowering needs each class's rebindability
|
|
@@ -5282,6 +6225,7 @@ export class Lowerer {
|
|
|
5282
6225
|
// implicit-any instances lowered eagerly at their first call sites.
|
|
5283
6226
|
functions.push(...this.liftedFns);
|
|
5284
6227
|
functions.push(...this.implicitFns);
|
|
6228
|
+
functions.push(...runtimeClassConstructs(this, functions));
|
|
5285
6229
|
if (this.remainder) {
|
|
5286
6230
|
// Deferred collection diagnostics nothing flushed — declarations no
|
|
5287
6231
|
// reference ever made relevant. They belong to the unreached group
|
|
@@ -5309,7 +6253,9 @@ export class Lowerer {
|
|
|
5309
6253
|
if (this.diags.length === 0)
|
|
5310
6254
|
fuseArrayPipelines(this, functions);
|
|
5311
6255
|
finalizeClassMethodValues(this, functions);
|
|
6256
|
+
finalizePrivateBrands(this, functions);
|
|
5312
6257
|
trackClassFieldCreation(this, functions);
|
|
6258
|
+
guardClassAttributeWrites(this, functions);
|
|
5313
6259
|
// Globals typed by a class that never REGISTERED (a JS class whose
|
|
5314
6260
|
// collection fenced — Symbol-keyed fields, an unsupported base): the
|
|
5315
6261
|
// declaration statement and every use compiled to runtime fences, but
|
|
@@ -5397,10 +6343,11 @@ export class Lowerer {
|
|
|
5397
6343
|
// slots), uniformly across params/locals/globals/fields/body types so
|
|
5398
6344
|
// every producer and consumer agrees. Programs with no unregistered
|
|
5399
6345
|
// reference are untouched — byte-stability holds.
|
|
6346
|
+
checkRequireBindingAccesses(this, functions);
|
|
5400
6347
|
const module = this.diags.length > 0
|
|
5401
6348
|
? null
|
|
5402
6349
|
: {
|
|
5403
|
-
irVersion:
|
|
6350
|
+
irVersion: 17,
|
|
5404
6351
|
sourceFile: this.entry.fileName,
|
|
5405
6352
|
functions,
|
|
5406
6353
|
classes: artifacts.classes,
|
|
@@ -5410,6 +6357,9 @@ export class Lowerer {
|
|
|
5410
6357
|
entry: ENTRY_NAME,
|
|
5411
6358
|
...(this.usesWorkers ? { workers: true } : {}),
|
|
5412
6359
|
...(this.usesLifetimeRegions ? { lifetimeRegions: true } : {}),
|
|
6360
|
+
...(this.threadSlotKeys.size > 0
|
|
6361
|
+
? { threadSlotKeys: [...this.threadSlotKeys].sort() }
|
|
6362
|
+
: {}),
|
|
5413
6363
|
...(isNodeEsmFile(this.entry, this.program) ? {} : { commonJsEntry: true }),
|
|
5414
6364
|
...(this.ffiImports.length > 0 ? { ffiImports: [...this.ffiImports] } : {}),
|
|
5415
6365
|
};
|
|
@@ -5417,11 +6367,23 @@ export class Lowerer {
|
|
|
5417
6367
|
sanitizeUnregisteredClassTypes(module, (name) => this.classes.has(name));
|
|
5418
6368
|
if (module)
|
|
5419
6369
|
checkCycleBindingAccesses(this, module);
|
|
6370
|
+
// Execution tiers from the final bodies (ir/tiers.ts). Assigned with or
|
|
6371
|
+
// without a module: coverage reports the dynamic tier of programs that
|
|
6372
|
+
// still have blockers.
|
|
6373
|
+
this.dynamicFunctions = assignLegacyTiers(functions);
|
|
6374
|
+
if (this.dynamicFunctions.length > 0)
|
|
6375
|
+
this.dynamicBodies = functions.filter((fn) => fn.tier === "dynamic");
|
|
6376
|
+
// Dynamic-tier functions compute with jsval values (ir/jsval.ts). The
|
|
6377
|
+
// rewrite keeps every dynamic operation dynamic (each dyn operator
|
|
6378
|
+
// becomes its js twin), so coverage's dynamic statements are unchanged.
|
|
6379
|
+
if (module && this.dynamicFunctions.length > 0)
|
|
6380
|
+
promoteJsvals(module);
|
|
5420
6381
|
return {
|
|
5421
6382
|
module,
|
|
5422
6383
|
diagnostics: this.diags,
|
|
5423
6384
|
runtimeFences: this.runtimeFences,
|
|
5424
6385
|
stats: this.stats,
|
|
6386
|
+
...(this.dynamicFunctions.length > 0 ? { dynamicFunctions: this.dynamicFunctions } : {}),
|
|
5425
6387
|
...(this.statsByFile.size > 0 ? { statsByFile: this.statsByFile } : {}),
|
|
5426
6388
|
...(this.provenanceElided.length > 0 ? { provenanceElided: this.provenanceElided } : {}),
|
|
5427
6389
|
};
|
|
@@ -5492,7 +6454,7 @@ export class Lowerer {
|
|
|
5492
6454
|
return;
|
|
5493
6455
|
this.stats.statementsTotal += n;
|
|
5494
6456
|
this.stats.statementsFailed += n;
|
|
5495
|
-
const file =
|
|
6457
|
+
const file = ts.getSourceFileOfNode(decl).fileName;
|
|
5496
6458
|
for (let i = 0; i < n; i++) {
|
|
5497
6459
|
this.bumpFileStat(file, "total");
|
|
5498
6460
|
this.bumpFileStat(file, "failed");
|
|
@@ -5534,7 +6496,7 @@ export class Lowerer {
|
|
|
5534
6496
|
// declarations before collectProgram visits their signatures.
|
|
5535
6497
|
this.checker.prefetchCollectionTypes(parts.flatMap((fp) => fp.fnDecls
|
|
5536
6498
|
.filter((decl) => decl.body !== undefined && decl.typeParameters === undefined)
|
|
5537
|
-
.flatMap((decl) => decl.parameters.flatMap((param) =>
|
|
6499
|
+
.flatMap((decl) => decl.parameters.nodes.flatMap((param) => param.initializer ? [param.initializer] : []))));
|
|
5538
6500
|
// JavaScript class shapes are partly declared by constructor-body
|
|
5539
6501
|
// assignments. Batch those collection-time queries across declarations
|
|
5540
6502
|
// before collectProgram visits them one by one; reached body lowering
|
|
@@ -5545,7 +6507,12 @@ export class Lowerer {
|
|
|
5545
6507
|
collectionEdges.add(name);
|
|
5546
6508
|
};
|
|
5547
6509
|
this.collectProgram(parts);
|
|
5548
|
-
this.
|
|
6510
|
+
this.speculativeTypeQueries(() => {
|
|
6511
|
+
extendAssertedRecordMembers(this, parts.map((fp) => fp.sf));
|
|
6512
|
+
this.analyzeRuntimeOptionalArrayReads(parts);
|
|
6513
|
+
this.analyzeDateJsonResults(parts);
|
|
6514
|
+
this.analyzeGuardedRecordReadGlobals(parts);
|
|
6515
|
+
});
|
|
5549
6516
|
// Decorated classes analyze post-collection here too: the %init seeds
|
|
5550
6517
|
// lower the decoration calls, whose edges (decorator bodies, construct
|
|
5551
6518
|
// thunks) reachable emit must see.
|
|
@@ -5558,8 +6525,8 @@ export class Lowerer {
|
|
|
5558
6525
|
// (qualified declaration names).
|
|
5559
6526
|
const units = new Map();
|
|
5560
6527
|
const bodyRoots = (...roots) => roots.filter((root) => root !== undefined && root !== null);
|
|
5561
|
-
const functionRoots = (decl) => bodyRoots(...decl.parameters.map((param) => param.initializer), decl.body);
|
|
5562
|
-
const classCtorRoots = (info) => bodyRoots(...(info.ctor?.parameters ?? []).map((param) => param.initializer), info.ctor?.body, ...info.fieldOrder.map((field) => field.initializer));
|
|
6528
|
+
const functionRoots = (decl) => bodyRoots(...decl.parameters.nodes.map((param) => param.initializer), decl.body);
|
|
6529
|
+
const classCtorRoots = (info) => bodyRoots(...(info.ctor?.parameters?.nodes ?? []).map((param) => param.initializer), info.ctor?.body, ...info.fieldOrder.map((field) => field.initializer));
|
|
5563
6530
|
const classMemberRoots = (info) => {
|
|
5564
6531
|
const roots = classCtorRoots(info);
|
|
5565
6532
|
for (const { member } of this.classMethodMembers(info))
|
|
@@ -5594,7 +6561,7 @@ export class Lowerer {
|
|
|
5594
6561
|
for (const info of this.classes.values()) {
|
|
5595
6562
|
if (info.builtinError)
|
|
5596
6563
|
continue; // runtime-provided; nothing lowers
|
|
5597
|
-
if (info.lifetimeRegion || info.internTable)
|
|
6564
|
+
if (info.lifetimeRegion || info.internTable || info.threadSlots)
|
|
5598
6565
|
continue; // synthesized with the class
|
|
5599
6566
|
// Generic-class INSTANTIATIONS (and mixin instantiations) are
|
|
5600
6567
|
// demand-driven, not units: their members lower unconditionally in
|
|
@@ -5901,6 +6868,13 @@ export class Lowerer {
|
|
|
5901
6868
|
this.shapes.settleDeclaredOrderPriorities();
|
|
5902
6869
|
for (const finalize of this.shapeOrderMetadataFinalizers)
|
|
5903
6870
|
finalize();
|
|
6871
|
+
applyKeyOrderWitnesses(this, [
|
|
6872
|
+
...orderedUnits,
|
|
6873
|
+
...initFunctions,
|
|
6874
|
+
...instanceFunctions,
|
|
6875
|
+
...this.liftedFns,
|
|
6876
|
+
...this.implicitFns,
|
|
6877
|
+
]);
|
|
5904
6878
|
for (const finalize of this.shapeOrderHelperFinalizers)
|
|
5905
6879
|
finalize();
|
|
5906
6880
|
const functions = [
|
|
@@ -5911,6 +6885,7 @@ export class Lowerer {
|
|
|
5911
6885
|
...this.liftedFns,
|
|
5912
6886
|
...this.implicitFns,
|
|
5913
6887
|
];
|
|
6888
|
+
functions.push(...runtimeClassConstructs(this, functions));
|
|
5914
6889
|
if (this.regexGroupResults)
|
|
5915
6890
|
for (const fn of functions)
|
|
5916
6891
|
foldRegexSpanReads(this, fn);
|
|
@@ -5981,23 +6956,8 @@ export class Lowerer {
|
|
|
5981
6956
|
return null;
|
|
5982
6957
|
}
|
|
5983
6958
|
this.runtimeFences.push(...captured);
|
|
5984
|
-
const
|
|
6959
|
+
const fence = this.runtimeFenceStmt(captured[0], node, target.fallback, target.bareMessage);
|
|
5985
6960
|
const loc = locOf(node);
|
|
5986
|
-
const code = first?.code ?? target.fallback.code;
|
|
5987
|
-
const baseMessage = first?.message ?? target.fallback.message;
|
|
5988
|
-
const messageLoc = first?.loc ?? loc;
|
|
5989
|
-
const source = first
|
|
5990
|
-
? (this.program.getSourceFile(messageLoc.file) ?? node.getSourceFile())
|
|
5991
|
-
: node.getSourceFile();
|
|
5992
|
-
const pos = ts.getLineAndCharacterOfPosition(source, messageLoc.start);
|
|
5993
|
-
const fence = {
|
|
5994
|
-
kind: "runtimeFence",
|
|
5995
|
-
code,
|
|
5996
|
-
message: target.bareMessage
|
|
5997
|
-
? baseMessage
|
|
5998
|
-
: `${baseMessage} [${code} at ${messageLoc.file}:${pos.line + 1}]`,
|
|
5999
|
-
loc,
|
|
6000
|
-
};
|
|
6001
6961
|
if (target.kind === "statement")
|
|
6002
6962
|
return fence;
|
|
6003
6963
|
const params = target.params ?? [];
|
|
@@ -6026,6 +6986,46 @@ export class Lowerer {
|
|
|
6026
6986
|
this.liftedFns.push(fn);
|
|
6027
6987
|
return { kind: "closure", fnName: fn.name, captures: [], type: target.type, loc };
|
|
6028
6988
|
}
|
|
6989
|
+
/** The runtimeFence statement that throws `first`'s message (or the
|
|
6990
|
+
* fallback's) at `node`. */
|
|
6991
|
+
runtimeFenceStmt(first, node, fallback, bareMessage = false) {
|
|
6992
|
+
const loc = locOf(node);
|
|
6993
|
+
const code = first?.code ?? fallback?.code ?? "SC1090";
|
|
6994
|
+
const baseMessage = first?.message ??
|
|
6995
|
+
fallback?.message ??
|
|
6996
|
+
"this statement uses a construct with no static lowering";
|
|
6997
|
+
const messageLoc = first?.loc ?? loc;
|
|
6998
|
+
const source = first
|
|
6999
|
+
? (this.program.getSourceFile(messageLoc.file) ?? ts.getSourceFileOfNode(node))
|
|
7000
|
+
: ts.getSourceFileOfNode(node);
|
|
7001
|
+
const pos = ts.getLineAndCharacterOfPosition(source, messageLoc.start);
|
|
7002
|
+
return {
|
|
7003
|
+
kind: "runtimeFence",
|
|
7004
|
+
code,
|
|
7005
|
+
message: bareMessage
|
|
7006
|
+
? baseMessage
|
|
7007
|
+
: `${baseMessage} [${code} at ${messageLoc.file}:${pos.line + 1}]`,
|
|
7008
|
+
loc,
|
|
7009
|
+
};
|
|
7010
|
+
}
|
|
7011
|
+
/** The current length of the capture buffer (diagSink), or 0 without one:
|
|
7012
|
+
* the mark capturedRuntimeFence reads the refusal from. */
|
|
7013
|
+
diagSinkMark() {
|
|
7014
|
+
return this.diagSink?.length ?? 0;
|
|
7015
|
+
}
|
|
7016
|
+
/** The runtimeFence for a JavaScript statement refused while a capture
|
|
7017
|
+
* buffer (diagSink) is active. The buffer's owner decides whether its
|
|
7018
|
+
* diagnostics report, and some owners keep the lowered result (a
|
|
7019
|
+
* successful tryLowerExpression candidate, a computed class base whose
|
|
7020
|
+
* diagnostics defer to the class). Without a fence the refused statement
|
|
7021
|
+
* would vanish from that result; with one it throws the refusal when it
|
|
7022
|
+
* runs, exactly like the fence lowerStmts emits outside a buffer. The
|
|
7023
|
+
* diagnostics stay in the buffer for its owner. Null without a buffer. */
|
|
7024
|
+
capturedRuntimeFence(sinkMark, node) {
|
|
7025
|
+
if (this.diagSink === null)
|
|
7026
|
+
return null;
|
|
7027
|
+
return this.runtimeFenceStmt(this.diagSink[sinkMark], node, undefined);
|
|
7028
|
+
}
|
|
6029
7029
|
/** All diagnostics land here; while a generic instance body is lowering,
|
|
6030
7030
|
* the instantiation context is appended so the user knows which concrete
|
|
6031
7031
|
* types made the (source-anchored) construct fail. */
|
|
@@ -6095,9 +7095,9 @@ export class Lowerer {
|
|
|
6095
7095
|
// fetch values map earlier to checked-dynamic handles and do not reach
|
|
6096
7096
|
// here; constructor objects such as Headers still can.
|
|
6097
7097
|
if (typeSym &&
|
|
6098
|
-
FETCH_AMBIENT_TYPES.includes(typeSym
|
|
7098
|
+
FETCH_AMBIENT_TYPES.includes(ts.symbolName(typeSym)) &&
|
|
6099
7099
|
this.isStdlibSymbol(typeSym)) {
|
|
6100
|
-
this.pushDiag(unsupportedNativeApiDiag(`a value of type '${typeSym
|
|
7100
|
+
this.pushDiag(unsupportedNativeApiDiag(`a value of type '${ts.symbolName(typeSym)}'`, locOf(node)));
|
|
6101
7101
|
throw new PoisonError();
|
|
6102
7102
|
}
|
|
6103
7103
|
// ENUM OBJECTS (`typeof e` — a numeric enum's type carries the
|
|
@@ -6107,7 +7107,7 @@ export class Lowerer {
|
|
|
6107
7107
|
// as the per-site identifier fence — never the index-signature
|
|
6108
7108
|
// recitation.
|
|
6109
7109
|
if (typeSym && (typeSym.flags & ts.SymbolFlags.Enum) !== 0) {
|
|
6110
|
-
this.pushDiag(unsupportedDiag("SC1090", locOf(node), `enum objects as values ('${typeSym
|
|
7110
|
+
this.pushDiag(unsupportedDiag("SC1090", locOf(node), `enum objects as values ('${ts.symbolName(typeSym)}' — member reads like '${ts.symbolName(typeSym)}.X' compile to constants; the object itself has no runtime representation)`));
|
|
6111
7111
|
throw new PoisonError();
|
|
6112
7112
|
}
|
|
6113
7113
|
// Would-be records with INDEX SIGNATURES (`Record<string, T>`,
|
|
@@ -6129,10 +7129,8 @@ export class Lowerer {
|
|
|
6129
7129
|
// (the value type, the key domain) the fences below tell better.
|
|
6130
7130
|
const ownSym = widened.getSymbol();
|
|
6131
7131
|
if (ownSym &&
|
|
6132
|
-
|
|
6133
|
-
.
|
|
6134
|
-
.some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
|
|
6135
|
-
this.isStdlibFile(d.getSourceFile()))) {
|
|
7132
|
+
ownSym.declarations.some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
|
|
7133
|
+
this.isStdlibFile(ts.getSourceFileOfNode(d)))) {
|
|
6136
7134
|
this.pushDiag(noLoweringDiag(this.checker.typeToString(type), locOf(node)));
|
|
6137
7135
|
throw new PoisonError();
|
|
6138
7136
|
}
|
|
@@ -6167,10 +7165,8 @@ export class Lowerer {
|
|
|
6167
7165
|
// tell — rather than an overload/record claim no user can act on.
|
|
6168
7166
|
const stdlibOwnSym = widened.getSymbol();
|
|
6169
7167
|
const stdlibNominal = stdlibOwnSym !== undefined &&
|
|
6170
|
-
|
|
6171
|
-
.
|
|
6172
|
-
.some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
|
|
6173
|
-
this.isStdlibFile(d.getSourceFile()));
|
|
7168
|
+
stdlibOwnSym.declarations.some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
|
|
7169
|
+
this.isStdlibFile(ts.getSourceFileOfNode(d)));
|
|
6174
7170
|
// OVERLOADED call signatures (SC2007) — after the generic branch, so a
|
|
6175
7171
|
// generic overload set keeps the monomorphization story: a value of a
|
|
6176
7172
|
// multi-signature type has no single compiled signature to hold.
|
|
@@ -6222,7 +7218,7 @@ export class Lowerer {
|
|
|
6222
7218
|
TextEncoder: "TextEncoder instances support encode(string) and encode(); other codec operations require a dedicated lowering",
|
|
6223
7219
|
TextDecoder: "TextDecoder instances support recognized labels, fatal/ignoreBOM option literals, and streaming UTF-8/UTF-16/single-byte decode; runtime option objects remain unsupported",
|
|
6224
7220
|
};
|
|
6225
|
-
this.pushDiag(noLoweringDiag(this.checker.typeToString(type), locOf(node), typeHints[stdlibOwnSym
|
|
7221
|
+
this.pushDiag(noLoweringDiag(this.checker.typeToString(type), locOf(node), typeHints[ts.symbolNameOf(stdlibOwnSym) ?? ""]));
|
|
6226
7222
|
throw new PoisonError();
|
|
6227
7223
|
}
|
|
6228
7224
|
// USER record shapes blocked by ONE member (SC2009's record arm):
|
|
@@ -6249,7 +7245,9 @@ export class Lowerer {
|
|
|
6249
7245
|
return stdlibMemberFence(this, access);
|
|
6250
7246
|
}
|
|
6251
7247
|
fenceStaticResponseMember(access, use) {
|
|
6252
|
-
return fenceStaticResponseMember(this, access, use) ??
|
|
7248
|
+
return (fenceStaticResponseMember(this, access, use) ??
|
|
7249
|
+
fenceStaticBlobMember(this, access, use) ??
|
|
7250
|
+
fenceWebCryptoMember(this, access, use));
|
|
6253
7251
|
}
|
|
6254
7252
|
fenceUnsupportedFetchConstructorMember(access) {
|
|
6255
7253
|
return fenceUnsupportedFetchConstructorMember(this, access);
|
|
@@ -6270,7 +7268,7 @@ export class Lowerer {
|
|
|
6270
7268
|
return fenceStaticReadableStreamMember(this, access, use);
|
|
6271
7269
|
}
|
|
6272
7270
|
typeOf(node) {
|
|
6273
|
-
if (ts.isPropertyAccessExpression(node) && isJsSourceFile(
|
|
7271
|
+
if (ts.isPropertyAccessExpression(node) && isJsSourceFile(ts.getSourceFileOfNode(node))) {
|
|
6274
7272
|
const receiver = node.expression.kind === ts.SyntaxKind.ThisKeyword && this.fnStack.length > 0
|
|
6275
7273
|
? this.resolveThis()?.type
|
|
6276
7274
|
: this.mapTypeOf(this.checker.getTypeAtLocation(node.expression));
|
|
@@ -6285,11 +7283,25 @@ export class Lowerer {
|
|
|
6285
7283
|
return this.checker.getUnknownType();
|
|
6286
7284
|
}
|
|
6287
7285
|
}
|
|
7286
|
+
// A symbol-keyed field read through a CommonJS key-table key reads as
|
|
7287
|
+
// the field's layout type (tableKeyFieldType).
|
|
7288
|
+
if (ts.isElementAccessExpression(node) && isJsSourceFile(ts.getSourceFileOfNode(node))) {
|
|
7289
|
+
const field = tableKeyFieldType(this, node);
|
|
7290
|
+
if (field) {
|
|
7291
|
+
if (field.kind === "f64")
|
|
7292
|
+
return this.checker.getNumberType();
|
|
7293
|
+
if (field.kind === "string")
|
|
7294
|
+
return this.checker.getStringType();
|
|
7295
|
+
if (field.kind === "bool")
|
|
7296
|
+
return this.checker.getBooleanType();
|
|
7297
|
+
return this.checker.getUnknownType();
|
|
7298
|
+
}
|
|
7299
|
+
}
|
|
6288
7300
|
// A checked JS method receives its actual call-site receiver. Its
|
|
6289
7301
|
// declaration's inferred class type must not turn property reads back
|
|
6290
7302
|
// into native field loads when the method is borrowed by another object.
|
|
6291
7303
|
if (node.kind === ts.SyntaxKind.ThisKeyword &&
|
|
6292
|
-
isJsSourceFile(
|
|
7304
|
+
isJsSourceFile(ts.getSourceFileOfNode(node)) &&
|
|
6293
7305
|
this.fnStack.length > 0 &&
|
|
6294
7306
|
this.resolveThis()?.type.kind === "dyn")
|
|
6295
7307
|
return this.checker.getUnknownType();
|
|
@@ -6350,7 +7362,7 @@ export class Lowerer {
|
|
|
6350
7362
|
// JSDoc and initializer inference are declaration types, not flow
|
|
6351
7363
|
// proofs. A checked specialization must not reinstate those
|
|
6352
7364
|
// stale layouts (mutable/null slots and heterogeneous JS arrays).
|
|
6353
|
-
const declaration = sym &&
|
|
7365
|
+
const declaration = sym && sym.valueDeclaration;
|
|
6354
7366
|
const declared = declaration && ts.isParameter(declaration)
|
|
6355
7367
|
? this.mapTypeOf(this.checker.getTypeAtLocation(declaration.name))
|
|
6356
7368
|
: null;
|
|
@@ -6387,6 +7399,14 @@ export class Lowerer {
|
|
|
6387
7399
|
? (jsArgumentsFunctionType(this, t) ?? mapped)
|
|
6388
7400
|
: mapped;
|
|
6389
7401
|
}
|
|
7402
|
+
/** The runtime type of a record member slot typed `t`: an overloaded
|
|
7403
|
+
* member's erased function (erasedOverloadMemberType — the type a record
|
|
7404
|
+
* shape stores for it), otherwise mapTypeOf. */
|
|
7405
|
+
memberSlotTypeOf(t) {
|
|
7406
|
+
if (isOverloadedCallableMemberType(t, this.checker))
|
|
7407
|
+
return erasedOverloadMemberType(t, this.typeCtx) ?? null;
|
|
7408
|
+
return this.mapTypeOf(t);
|
|
7409
|
+
}
|
|
6390
7410
|
/** The one position where a contextual UNION must not be adopted over the
|
|
6391
7411
|
* expression's own: the LEFT operand of `&&`, `||`, or `??`. Adopting a
|
|
6392
7412
|
* contextual union is normally safe because tsc proved the value
|
|
@@ -6489,7 +7509,15 @@ export class Lowerer {
|
|
|
6489
7509
|
return ts.constituentTypes(part).every(visit);
|
|
6490
7510
|
return false;
|
|
6491
7511
|
};
|
|
6492
|
-
|
|
7512
|
+
// A union typescript-go cannot describe is not proven an array.
|
|
7513
|
+
try {
|
|
7514
|
+
return visit(t);
|
|
7515
|
+
}
|
|
7516
|
+
catch (e) {
|
|
7517
|
+
if (ts.isUnreadableConstituentsPanic(e))
|
|
7518
|
+
return false;
|
|
7519
|
+
throw e;
|
|
7520
|
+
}
|
|
6493
7521
|
}
|
|
6494
7522
|
/** The lowered static array/tuple value behind checkerAnyArray's
|
|
6495
7523
|
* synthetic `any[]` spelling. Array.isArray can leave readonly tuple
|
|
@@ -6527,7 +7555,7 @@ export class Lowerer {
|
|
|
6527
7555
|
// JS inference can leave mutable fields, accessor parameters and
|
|
6528
7556
|
// locals at null/undefined despite later writes. Keep mutable native
|
|
6529
7557
|
// storage instead of a slot restricted to the initializer's unit value.
|
|
6530
|
-
if (isJsSourceFile(
|
|
7558
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(node)) &&
|
|
6531
7559
|
(t.flags & (ts.TypeFlags.Null | ts.TypeFlags.Undefined)) !== 0)
|
|
6532
7560
|
return DYN;
|
|
6533
7561
|
// A never-tainted JS type (neverTaintedJsType) maps — never rides as
|
|
@@ -6538,6 +7566,9 @@ export class Lowerer {
|
|
|
6538
7566
|
const argumentsType = jsArgumentsFunctionType(this, t);
|
|
6539
7567
|
if (argumentsType !== null)
|
|
6540
7568
|
return argumentsType;
|
|
7569
|
+
const localClass = genericLocalClassBinding(this, node);
|
|
7570
|
+
if (localClass !== null)
|
|
7571
|
+
return localClass;
|
|
6541
7572
|
// The checked-dynamic declaration fallback (dynFallbackType): a
|
|
6542
7573
|
// JAVASCRIPT binding of any inference residue, or a TypeScript
|
|
6543
7574
|
// binding of genuine checker-`any`, becomes the checked-dynamic
|
|
@@ -6565,6 +7596,13 @@ export class Lowerer {
|
|
|
6565
7596
|
requireExactShape(node, actual, expected) {
|
|
6566
7597
|
if (typeEquals(actual, expected))
|
|
6567
7598
|
return;
|
|
7599
|
+
if (!this.generalNodeStreams && needsGeneralNodeStreams(this, actual, expected)) {
|
|
7600
|
+
this.requiresGeneralNodeStreams = true;
|
|
7601
|
+
// An untyped value into a stream slot also needs the checked-dynamic
|
|
7602
|
+
// slots (dyn-streams.ts).
|
|
7603
|
+
if (actual.kind === "dyn")
|
|
7604
|
+
this.requiresDynNodeStreams = true;
|
|
7605
|
+
}
|
|
6568
7606
|
// dyn mismatches first. A dyn ('unknown') value flowing into a typed
|
|
6569
7607
|
// slot needs a CHECKED cast — the hint points at `as <type>`; tsc
|
|
6570
7608
|
// usually rejects this before we do, so the fence is mostly defensive.
|
|
@@ -6720,6 +7758,15 @@ export class Lowerer {
|
|
|
6720
7758
|
* else (including a DIFFERENT union) is left for requireExactShape, which
|
|
6721
7759
|
* rejects union mismatches with SC2003. */
|
|
6722
7760
|
coerceToExpected(expr, expected) {
|
|
7761
|
+
// A comma expression ending in a unit literal (`return log(), null`):
|
|
7762
|
+
// its effects run first, unchanged, and the unit value takes the
|
|
7763
|
+
// destination's representation (a bare unit literal has none).
|
|
7764
|
+
if (expr.kind === "seqExpr" &&
|
|
7765
|
+
expr.result.kind === "unitLit" &&
|
|
7766
|
+
!typeEquals(expr.type, expected)) {
|
|
7767
|
+
const result = this.coerceToExpected(expr.result, expected);
|
|
7768
|
+
return { ...expr, result, type: result.type };
|
|
7769
|
+
}
|
|
6723
7770
|
// A destination that holds undefined takes an unassigned deferred-init
|
|
6724
7771
|
// field's slot as is (Node passes the undefined along).
|
|
6725
7772
|
if (expected.kind === "union" && this.armTag(expected.unionId, UNDEFINED_T) >= 0) {
|
|
@@ -6729,6 +7776,10 @@ export class Lowerer {
|
|
|
6729
7776
|
}
|
|
6730
7777
|
if (expr.type.kind === "void" && expected.kind !== "void" && this.neverValued.has(expr))
|
|
6731
7778
|
return this.divergentValue(expr, expected);
|
|
7779
|
+
// process.stdout/stderr into a general Writable slot (general-streams.ts).
|
|
7780
|
+
const stdioStream = stdioIntoGeneralStream(this, expr, expected);
|
|
7781
|
+
if (stdioStream)
|
|
7782
|
+
return this.coerceToExpected(stdioStream, expected);
|
|
6732
7783
|
// Iterator-typed slots: native iterators and differently typed
|
|
6733
7784
|
// generators step through an adapter generator.
|
|
6734
7785
|
if (expected.kind === "generator" && !typeEquals(expr.type, expected)) {
|
|
@@ -6749,6 +7800,16 @@ export class Lowerer {
|
|
|
6749
7800
|
// undefined/null literals store the dyn unit values. Types outside the
|
|
6750
7801
|
// dyn's domain (bytes, classes, Maps, ...) fall through to
|
|
6751
7802
|
// requireExactShape's SC1101 fence.
|
|
7803
|
+
// A promise entering a maybe-promise union whose promise arm has a
|
|
7804
|
+
// wider payload (`Promise<R>` into `Promise<R | void> | R | void`)
|
|
7805
|
+
// takes the payload widening below first, then wraps into that arm.
|
|
7806
|
+
if (expected.kind === "union" && expr.type.kind === "promise") {
|
|
7807
|
+
const mp = maybePromiseUnionOf(this, expected);
|
|
7808
|
+
if (mp &&
|
|
7809
|
+
!typeEquals(mp.promise, expr.type) &&
|
|
7810
|
+
this.promisePayloadWidens(expr.type, mp.promise))
|
|
7811
|
+
expr = this.coerceToExpected(expr, mp.promise);
|
|
7812
|
+
}
|
|
6752
7813
|
// Promise payloads may widen at a checked return boundary, including
|
|
6753
7814
|
// arrays inferred as tuple results by Promise.all. Keep both payload
|
|
6754
7815
|
// ABIs explicit: box settlement, then validate the destination payload.
|
|
@@ -6798,6 +7859,12 @@ export class Lowerer {
|
|
|
6798
7859
|
loc: expr.loc,
|
|
6799
7860
|
};
|
|
6800
7861
|
}
|
|
7862
|
+
// A runtime-provided class value has no checked-dynamic form that
|
|
7863
|
+
// inspects as Node's does (`[Function: EventEmitter] { ... }`).
|
|
7864
|
+
if (expr.type.kind === "classval" && this.classes.get(expr.type.className)?.def.runtime) {
|
|
7865
|
+
this.pushDiag(unsupportedDiag("SC1090", expr.loc, `a runtime-provided class value ('${expr.type.className.slice(1)}') as an untyped value`));
|
|
7866
|
+
throw new PoisonError();
|
|
7867
|
+
}
|
|
6801
7868
|
if (expr.kind === "unitLit" || this.dynConvertible(expr.type)) {
|
|
6802
7869
|
// Records and arrays keep their identity as untyped values, including
|
|
6803
7870
|
// when they arrive through a union, so `unknown` views, weak
|
|
@@ -6811,12 +7878,16 @@ export class Lowerer {
|
|
|
6811
7878
|
const liveRef = liveReference(expr.type) ||
|
|
6812
7879
|
(expr.type.kind === "union" &&
|
|
6813
7880
|
(this.unions.get(expr.type.unionId)?.arms.some(liveReference) ?? false));
|
|
7881
|
+
// A builtin function's adapter boxes under the builtin's name, the
|
|
7882
|
+
// name Node's function carries (`[Function: randomUUID]`).
|
|
7883
|
+
const builtinName = expr.kind === "closure" ? this.builtinCallableValueNames.get(expr.fnName) : undefined;
|
|
6814
7884
|
return {
|
|
6815
7885
|
kind: "dynFrom",
|
|
6816
7886
|
value: expr,
|
|
6817
7887
|
type: DYN,
|
|
6818
7888
|
loc: expr.loc,
|
|
6819
7889
|
...(liveRef ? { liveRef: true } : {}),
|
|
7890
|
+
...(builtinName !== undefined ? { fnName: builtinName } : {}),
|
|
6820
7891
|
};
|
|
6821
7892
|
}
|
|
6822
7893
|
return expr;
|
|
@@ -6853,6 +7924,7 @@ export class Lowerer {
|
|
|
6853
7924
|
const funcOk = expected.kind === "func" &&
|
|
6854
7925
|
canAdaptDynFuncTo(expected, (id) => this.shapes.get(id), (id) => this.unions.get(id));
|
|
6855
7926
|
const handleOk = DYN_HANDLE_KINDS.has(expected.kind);
|
|
7927
|
+
noteUntypedStreamFlow(this, expected);
|
|
6856
7928
|
if (canDynCheckTo(expected, (id) => this.shapes.get(id), (id) => this.unions.get(id)) ||
|
|
6857
7929
|
undefArmedOk ||
|
|
6858
7930
|
bytesOk ||
|
|
@@ -6985,6 +8057,7 @@ export class Lowerer {
|
|
|
6985
8057
|
// and no completion target is meaningful — the exact-shape fence
|
|
6986
8058
|
// downstream names the class-value flow instead.
|
|
6987
8059
|
if (sub && sup && !sup.generic && this.ctorAbiEquals(sub, sup)) {
|
|
8060
|
+
defineClassValueConstruct(this, sup);
|
|
6988
8061
|
return { kind: "upcast", value: expr, type: expected, loc: expr.loc };
|
|
6989
8062
|
}
|
|
6990
8063
|
}
|
|
@@ -7021,6 +8094,11 @@ export class Lowerer {
|
|
|
7021
8094
|
return this.applyWidthLift(lift, narrowed, expected, expr.loc);
|
|
7022
8095
|
}
|
|
7023
8096
|
}
|
|
8097
|
+
if (expr.type.kind === "union" && expected.kind === "record") {
|
|
8098
|
+
const lifted = unionArmsWidthLift(this, expr, expected);
|
|
8099
|
+
if (lifted)
|
|
8100
|
+
return lifted;
|
|
8101
|
+
}
|
|
7024
8102
|
if (!typeEquals(expr.type, expected)) {
|
|
7025
8103
|
const w = this.widthCoerce(expr, expected);
|
|
7026
8104
|
if (w)
|
|
@@ -7105,6 +8183,7 @@ export class Lowerer {
|
|
|
7105
8183
|
if (baseTag >= 0) {
|
|
7106
8184
|
if (!sub || !this.ctorAbiEquals(sub, c))
|
|
7107
8185
|
break;
|
|
8186
|
+
defineClassValueConstruct(this, c);
|
|
7108
8187
|
const widened = {
|
|
7109
8188
|
kind: "upcast",
|
|
7110
8189
|
value: expr,
|
|
@@ -7261,6 +8340,9 @@ export class Lowerer {
|
|
|
7261
8340
|
recordUnionWrapHelper(source, toId, loc) {
|
|
7262
8341
|
return recordUnionWrapHelper(this, source, toId, loc);
|
|
7263
8342
|
}
|
|
8343
|
+
recordUnionRouteHelper(source, toId, loc) {
|
|
8344
|
+
return recordUnionRouteHelper(this, source, toId, loc);
|
|
8345
|
+
}
|
|
7264
8346
|
unionRetagHelper(fromId, toId, loc, trappable) {
|
|
7265
8347
|
return unionRetagHelper(this, fromId, toId, loc, trappable);
|
|
7266
8348
|
}
|
|
@@ -7279,6 +8361,7 @@ export class Lowerer {
|
|
|
7279
8361
|
* lowering goes through here (via lowerExprExpecting) or calls this
|
|
7280
8362
|
* directly when the expression was already lowered. */
|
|
7281
8363
|
coerceInto(node, expr, expected) {
|
|
8364
|
+
refuseInferredCallbackDrops(this, node, expr.type, expected);
|
|
7282
8365
|
// A union destination can accept the binding's tagged storage directly.
|
|
7283
8366
|
// The checker's single-arm flow type can be stale after a callback writes
|
|
7284
8367
|
// the binding. Extracting that arm and wrapping it again would discard the
|
|
@@ -7296,9 +8379,16 @@ export class Lowerer {
|
|
|
7296
8379
|
// initial contextual layout was chosen. Its known discriminator still
|
|
7297
8380
|
// selects the destination arm; validate that payload before wrapping.
|
|
7298
8381
|
// Work with the already lowered value so property effects run once.
|
|
8382
|
+
// A type assertion keeps the literal's own record layout, which can
|
|
8383
|
+
// equal another arm's layout (`{ kind: "return", value, loc } as Stmt`
|
|
8384
|
+
// when a `throw` arm has the same fields), so assertions are looked
|
|
8385
|
+
// through as well.
|
|
7299
8386
|
if (expr.type.kind === "record" && expected.kind === "union") {
|
|
7300
8387
|
let literal = node;
|
|
7301
|
-
while (ts.isParenthesizedExpression(literal) ||
|
|
8388
|
+
while (ts.isParenthesizedExpression(literal) ||
|
|
8389
|
+
ts.isSatisfiesExpression(literal) ||
|
|
8390
|
+
ts.isAsExpression(literal) ||
|
|
8391
|
+
ts.isTypeAssertion(literal))
|
|
7302
8392
|
literal = literal.expression;
|
|
7303
8393
|
const def = this.unions.get(expected.unionId);
|
|
7304
8394
|
if (def?.discriminant && ts.isObjectLiteralExpression(literal)) {
|
|
@@ -7322,7 +8412,7 @@ export class Lowerer {
|
|
|
7322
8412
|
: [];
|
|
7323
8413
|
const errorOptions = parts.some((part) => {
|
|
7324
8414
|
const sym = part.getAliasSymbol() ?? part.getSymbol();
|
|
7325
|
-
return sym
|
|
8415
|
+
return (sym !== undefined && ts.symbolName(sym) === "ErrorOptions" && this.isStdlibSymbol(sym));
|
|
7326
8416
|
});
|
|
7327
8417
|
if (errorOptions) {
|
|
7328
8418
|
const actual = this.typeOf(node);
|
|
@@ -7352,7 +8442,7 @@ export class Lowerer {
|
|
|
7352
8442
|
let literal = node;
|
|
7353
8443
|
while (ts.isParenthesizedExpression(literal))
|
|
7354
8444
|
literal = literal.expression;
|
|
7355
|
-
if (isJsSourceFile(
|
|
8445
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(node)) &&
|
|
7356
8446
|
!ts.isArrayLiteralExpression(literal) &&
|
|
7357
8447
|
e.kind === "dynFrom" &&
|
|
7358
8448
|
e.value.type.kind === "array") {
|
|
@@ -7371,7 +8461,8 @@ export class Lowerer {
|
|
|
7371
8461
|
// node's CHECKER type proves those arms away, they trap instead — the
|
|
7372
8462
|
// sub-union narrowing bridge (narrowedRetagHelper).
|
|
7373
8463
|
if (e.type.kind === "union" && expected.kind === "union" && !typeEquals(e.type, expected)) {
|
|
7374
|
-
const helper = this.narrowedRetagHelper(node, e.type.unionId, expected.unionId, e.loc)
|
|
8464
|
+
const helper = this.narrowedRetagHelper(node, e.type.unionId, expected.unionId, e.loc) ??
|
|
8465
|
+
uninhabitedArmRetagHelper(this, node, e.type.unionId, expected.unionId, e.loc);
|
|
7375
8466
|
if (helper) {
|
|
7376
8467
|
e = { kind: "call", callee: helper, args: [e], type: expected, loc: e.loc };
|
|
7377
8468
|
}
|
|
@@ -7381,7 +8472,7 @@ export class Lowerer {
|
|
|
7381
8472
|
// never reinterpret an object payload as a scalar union arm.
|
|
7382
8473
|
if (e.type.kind === "union" &&
|
|
7383
8474
|
!typeEquals(e.type, expected) &&
|
|
7384
|
-
isJsSourceFile(
|
|
8475
|
+
isJsSourceFile(ts.getSourceFileOfNode(node)) &&
|
|
7385
8476
|
this.dynConvertible(e.type)) {
|
|
7386
8477
|
const sourceArms = this.unions.get(e.type.unionId)?.arms ?? [];
|
|
7387
8478
|
const targetArms = this.unions.get(expected.unionId)?.arms ?? [];
|
|
@@ -7418,7 +8509,7 @@ export class Lowerer {
|
|
|
7418
8509
|
const sym = this.resolveValueSymbol(n);
|
|
7419
8510
|
if (!sym)
|
|
7420
8511
|
return null;
|
|
7421
|
-
const decls =
|
|
8512
|
+
const decls = sym.declarations;
|
|
7422
8513
|
if (decls.length === 0)
|
|
7423
8514
|
return null;
|
|
7424
8515
|
const units = new Set();
|
|
@@ -7429,7 +8520,7 @@ export class Lowerer {
|
|
|
7429
8520
|
!ts.isIdentifier(d.name) ||
|
|
7430
8521
|
!ts.isVariableDeclarationList(d.parent) ||
|
|
7431
8522
|
!ts.isVariableStatement(d.parent.parent) ||
|
|
7432
|
-
|
|
8523
|
+
ts.getSourceFileOfNode(d).isDeclarationFile ||
|
|
7433
8524
|
(ts.getCombinedModifierFlags(d) & ts.ModifierFlags.Ambient) !== 0) {
|
|
7434
8525
|
return null;
|
|
7435
8526
|
}
|
|
@@ -7546,6 +8637,9 @@ export class Lowerer {
|
|
|
7546
8637
|
if (expected) {
|
|
7547
8638
|
if (ts.isConditionalExpression(node))
|
|
7548
8639
|
return lowerTernary(this, node, expected);
|
|
8640
|
+
const escaped = this.neverAssertionInto(node, expected);
|
|
8641
|
+
if (escaped)
|
|
8642
|
+
return escaped;
|
|
7549
8643
|
const fresh = this.emptyCollectionFor(node, expected);
|
|
7550
8644
|
if (fresh)
|
|
7551
8645
|
return this.coerceInto(node, fresh, expected);
|
|
@@ -7595,10 +8689,10 @@ export class Lowerer {
|
|
|
7595
8689
|
// Construct its actual storage here so identity and WeakMap lifetime
|
|
7596
8690
|
// belong to the array the program keeps, rather than a typed snapshot.
|
|
7597
8691
|
if (ts.isArrayLiteralExpression(x) &&
|
|
7598
|
-
x.elements.every((element) => !ts.isSpreadElement(element) && !ts.isOmittedExpression(element))) {
|
|
8692
|
+
x.elements.nodes.every((element) => !ts.isSpreadElement(element) && !ts.isOmittedExpression(element))) {
|
|
7599
8693
|
return {
|
|
7600
8694
|
kind: "dynArrLit",
|
|
7601
|
-
elems: x.elements.map((element) => this.lowerExprExpecting(element, DYN)),
|
|
8695
|
+
elems: x.elements.nodes.map((element) => this.lowerExprExpecting(element, DYN)),
|
|
7602
8696
|
type: DYN,
|
|
7603
8697
|
loc: locOf(x),
|
|
7604
8698
|
};
|
|
@@ -7612,16 +8706,17 @@ export class Lowerer {
|
|
|
7612
8706
|
: [];
|
|
7613
8707
|
const builtinOption = (name) => parts.some((part) => {
|
|
7614
8708
|
const sym = part.getAliasSymbol() ?? part.getSymbol();
|
|
7615
|
-
return sym
|
|
8709
|
+
return ts.symbolNameOf(sym) === name && this.isStdlibSymbol(sym);
|
|
7616
8710
|
});
|
|
7617
8711
|
if (ts.isObjectLiteralExpression(x)) {
|
|
7618
|
-
if (isJsSourceFile(
|
|
8712
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(x)) ||
|
|
7619
8713
|
builtinOption("RequestInit") ||
|
|
7620
8714
|
builtinOption("ErrorOptions") ||
|
|
7621
8715
|
builtinOption("SpawnOptions") ||
|
|
7622
8716
|
builtinOption("UrlObject") ||
|
|
7623
8717
|
builtinOption("URLFormatOptions") ||
|
|
7624
|
-
!this.mapTypeOf(this.typeOf(x))
|
|
8718
|
+
!this.mapTypeOf(this.typeOf(x)) ||
|
|
8719
|
+
this.excessJsContextualProperty(x, parts)) {
|
|
7625
8720
|
return lowerDynObjectLiteral(this, x);
|
|
7626
8721
|
}
|
|
7627
8722
|
}
|
|
@@ -7642,24 +8737,24 @@ export class Lowerer {
|
|
|
7642
8737
|
// a unit-only-element array — a checker type that degraded to one
|
|
7643
8738
|
// (`[]`-flavored inference over a populated literal) carries no
|
|
7644
8739
|
// element information.
|
|
7645
|
-
const nonUnitElems = x.elements.some((el) => !ts.isOmittedExpression(el) &&
|
|
8740
|
+
const nonUnitElems = x.elements.nodes.some((el) => !ts.isOmittedExpression(el) &&
|
|
7646
8741
|
el.kind !== ts.SyntaxKind.NullKeyword &&
|
|
7647
8742
|
!(ts.isIdentifier(el) && el.text === "undefined"));
|
|
7648
8743
|
const def = this.unions.get(expected.unionId);
|
|
7649
8744
|
const arms = (def?.arms ?? []).filter((a) => (a.kind === "array" && !(nonUnitElems && this.unitOnlyElem(a.elem))) ||
|
|
7650
8745
|
(a.kind === "record" &&
|
|
7651
8746
|
!!this.shapes.get(a.shapeId)?.tuple &&
|
|
7652
|
-
this.shapes.get(a.shapeId).fields.length === x.elements.length &&
|
|
7653
|
-
!x.elements.some(ts.isSpreadElement)));
|
|
8747
|
+
this.shapes.get(a.shapeId).fields.length === x.elements.nodes.length &&
|
|
8748
|
+
!x.elements.nodes.some(ts.isSpreadElement)));
|
|
7654
8749
|
let arm = arms.length === 1 ? arms[0] : undefined;
|
|
7655
8750
|
if (!arm &&
|
|
7656
8751
|
arms.length > 1 &&
|
|
7657
|
-
x.elements.length > 0 &&
|
|
7658
|
-
x.elements.every((el) => !ts.isSpreadElement(el) && !ts.isOmittedExpression(el))) {
|
|
8752
|
+
x.elements.nodes.length > 0 &&
|
|
8753
|
+
x.elements.nodes.every((el) => !ts.isSpreadElement(el) && !ts.isOmittedExpression(el))) {
|
|
7659
8754
|
const ownType = this.mapTypeOf(this.typeOf(x));
|
|
7660
8755
|
arm = arms.find((candidate) => ownType !== null && typeEquals(candidate, ownType));
|
|
7661
8756
|
if (!arm) {
|
|
7662
|
-
const elements = x.elements.map((el) => tryLowerExpression(this, el));
|
|
8757
|
+
const elements = x.elements.nodes.map((el) => tryLowerExpression(this, el));
|
|
7663
8758
|
arm = arms.find((candidate) => candidate.kind === "array" &&
|
|
7664
8759
|
elements.every((element) => element !== null && this.widthLiftPlan(element.type, candidate.elem) !== null));
|
|
7665
8760
|
}
|
|
@@ -7670,14 +8765,20 @@ export class Lowerer {
|
|
|
7670
8765
|
}
|
|
7671
8766
|
}
|
|
7672
8767
|
}
|
|
7673
|
-
|
|
7674
|
-
|
|
7675
|
-
|
|
8768
|
+
const e = this.lowerExpr(node);
|
|
8769
|
+
return expected ? this.coerceExistingInto(node, e, expected) : e;
|
|
8770
|
+
}
|
|
8771
|
+
/** The conversion lowerExprExpecting applies to `e`, the lowered value
|
|
8772
|
+
* of `node` when it is not fresh construction the destination directs
|
|
8773
|
+
* (a literal, conditional, or empty collection). */
|
|
8774
|
+
coerceExistingInto(node, e, expected) {
|
|
8775
|
+
if ((expected.kind === "union" && this.armTag(expected.unionId, UNDEFINED_T) >= 0) ||
|
|
8776
|
+
(expected.kind === "dyn" && isJsSourceFile(ts.getSourceFileOfNode(node)))) {
|
|
7676
8777
|
// A destination that accepts undefined must retain an unchecked
|
|
7677
8778
|
// read's storage value even when the checker still calls it present.
|
|
7678
8779
|
e = this.runtimeOptionalSourceValue(node, e) ?? e;
|
|
7679
8780
|
}
|
|
7680
|
-
return
|
|
8781
|
+
return this.coerceInto(node, e, expected);
|
|
7681
8782
|
}
|
|
7682
8783
|
/** An unannotated empty collection has no existing elements or aliases
|
|
7683
8784
|
* that constrain its layout. An explicit type argument still wins. */
|
|
@@ -7687,13 +8788,13 @@ export class Lowerer {
|
|
|
7687
8788
|
value = value.expression;
|
|
7688
8789
|
if (!ts.isNewExpression(value) ||
|
|
7689
8790
|
!ts.isIdentifier(value.expression) ||
|
|
7690
|
-
(value.arguments?.length ?? 0) !== 0 ||
|
|
7691
|
-
(value.typeArguments?.length ?? 0) !== 0)
|
|
8791
|
+
(value.arguments?.nodes.length ?? 0) !== 0 ||
|
|
8792
|
+
(value.typeArguments?.nodes.length ?? 0) !== 0)
|
|
7692
8793
|
return null;
|
|
7693
8794
|
const symbol = this.resolveValueSymbol(value.expression);
|
|
7694
8795
|
if (!symbol || !this.isStdlibSymbol(symbol))
|
|
7695
8796
|
return null;
|
|
7696
|
-
const kind = symbol
|
|
8797
|
+
const kind = ts.symbolName(symbol) === "Map" ? "map" : ts.symbolName(symbol) === "Set" ? "set" : null;
|
|
7697
8798
|
if (!kind)
|
|
7698
8799
|
return null;
|
|
7699
8800
|
const arms = expected.kind === "union" ? (this.unions.get(expected.unionId)?.arms ?? []) : [expected];
|
|
@@ -7747,6 +8848,17 @@ export class Lowerer {
|
|
|
7747
8848
|
this.addedUndefinedArms.set(t.unionId, { type, unions: this.unions.revision });
|
|
7748
8849
|
return type;
|
|
7749
8850
|
}
|
|
8851
|
+
/** Whether a promise of `from` converts to a promise of `to` through the
|
|
8852
|
+
* checked payload widening (coerceToExpected's boxed-settlement rule,
|
|
8853
|
+
* which keeps the promise's identity and settlement turn). */
|
|
8854
|
+
promisePayloadWidens(from, to) {
|
|
8855
|
+
if (typeEquals(from, to))
|
|
8856
|
+
return true;
|
|
8857
|
+
if (to.inner.kind === "void")
|
|
8858
|
+
return from.inner.kind !== "void";
|
|
8859
|
+
return (this.dynConvertible(from) &&
|
|
8860
|
+
canDynCheckTo(to, (id) => this.shapes.get(id), (id) => this.unions.get(id)));
|
|
8861
|
+
}
|
|
7750
8862
|
/** True when a static type converts to a dyn value (the dynFrom
|
|
7751
8863
|
* walker's domain): JSON-safe, bytes<u8> (Uint8Array/Buffer — the checked-dynamic tree's
|
|
7752
8864
|
* bytes kind, payload copied; stdin chunks into unknown-typed helpers),
|
|
@@ -7781,15 +8893,24 @@ export class Lowerer {
|
|
|
7781
8893
|
// storage directly, just like arguments and variable initializers.
|
|
7782
8894
|
// Contextual types (such as Proxy descriptors' symbol-valued fields)
|
|
7783
8895
|
// must not force an intermediate record with incompatible field slots.
|
|
8896
|
+
if (this.returnsLiteralIntoDyn(node, expected))
|
|
8897
|
+
return this.lowerExprExpecting(node, expected);
|
|
8898
|
+
return this.asyncReturnValueOf(node, this.lowerExpr(node), expected);
|
|
8899
|
+
}
|
|
8900
|
+
/** A fresh JS object literal returned into a checked-native (dyn) result,
|
|
8901
|
+
* which lowers straight into that storage. */
|
|
8902
|
+
returnsLiteralIntoDyn(node, expected) {
|
|
7784
8903
|
let literal = node;
|
|
7785
8904
|
while (ts.isParenthesizedExpression(literal))
|
|
7786
8905
|
literal = literal.expression;
|
|
7787
|
-
|
|
7788
|
-
isJsSourceFile(
|
|
7789
|
-
ts.isObjectLiteralExpression(literal))
|
|
7790
|
-
|
|
7791
|
-
|
|
7792
|
-
|
|
8906
|
+
return (expected.kind === "dyn" &&
|
|
8907
|
+
isJsSourceFile(ts.getSourceFileOfNode(node)) &&
|
|
8908
|
+
ts.isObjectLiteralExpression(literal));
|
|
8909
|
+
}
|
|
8910
|
+
/** The value of `return <e>` (already lowered untyped) in an async or
|
|
8911
|
+
* void context: a promise flattens through the returned-promise await,
|
|
8912
|
+
* everything else converts into the declared result. */
|
|
8913
|
+
asyncReturnValueOf(node, e, expected) {
|
|
7793
8914
|
if (expected.kind === "void" && e.kind === "unitLit")
|
|
7794
8915
|
return null;
|
|
7795
8916
|
if (this.ctx.isAsync && e.type.kind === "promise" && expected.kind !== "promise") {
|
|
@@ -7853,10 +8974,28 @@ export class Lowerer {
|
|
|
7853
8974
|
}
|
|
7854
8975
|
return s;
|
|
7855
8976
|
}
|
|
8977
|
+
/** `return u` of a promise-armed union (maybe-promise, or promise-or-
|
|
8978
|
+
* unit) in an async function: adopt the promise arm, fulfill with the
|
|
8979
|
+
* others (maybe-promise.ts). Null when the return is not that shape. */
|
|
8980
|
+
maybePromiseReturn(node, e, expected) {
|
|
8981
|
+
if (!this.adoptsReturnedPromise())
|
|
8982
|
+
return null;
|
|
8983
|
+
const mp = promiseArmedUnionOf(this, e.type);
|
|
8984
|
+
if (!mp || promiseArmedUnionOf(this, expected))
|
|
8985
|
+
return null;
|
|
8986
|
+
const stmt = maybePromiseReturnStmt(this, e, mp, expected, (x) => this.coerceInto(node, x, expected));
|
|
8987
|
+
if (stmt === null) {
|
|
8988
|
+
this.unsupported("SC1090", node, `returning '${this.fmt(e.type)}' from an async function whose result is '${this.fmt(expected)}' (an arm does not convert to the result)`);
|
|
8989
|
+
}
|
|
8990
|
+
return stmt;
|
|
8991
|
+
}
|
|
7856
8992
|
lowerReturnOf(node, loc) {
|
|
7857
8993
|
const expected = this.ctx.returnType;
|
|
7858
8994
|
if (expected.kind === "void") {
|
|
7859
8995
|
let e = this.lowerExpr(node);
|
|
8996
|
+
const flattened = this.maybePromiseReturn(node, e, expected);
|
|
8997
|
+
if (flattened)
|
|
8998
|
+
return flattened;
|
|
7860
8999
|
if (this.ctx.isAsync && e.type.kind === "promise") {
|
|
7861
9000
|
if (this.adoptsReturnedPromise())
|
|
7862
9001
|
return this.adoptingReturn(e, VOID, (x) => x);
|
|
@@ -7864,6 +9003,14 @@ export class Lowerer {
|
|
|
7864
9003
|
}
|
|
7865
9004
|
if (e.kind === "unitLit")
|
|
7866
9005
|
return { kind: "return", value: null, loc };
|
|
9006
|
+
// `return c ? f() : g()` over void calls: a void conditional has no
|
|
9007
|
+
// value representation, so its branch selection becomes control flow.
|
|
9008
|
+
if (e.kind === "ternary" && e.type.kind === "void") {
|
|
9009
|
+
const branch = (x) => x.kind === "ternary" && x.type.kind === "void"
|
|
9010
|
+
? { kind: "if", cond: x.cond, then: [branch(x.then)], else_: [branch(x.else_)], loc }
|
|
9011
|
+
: { kind: "exprStmt", expr: x, loc };
|
|
9012
|
+
return { kind: "block", body: [branch(e), { kind: "return", value: null, loc }], loc };
|
|
9013
|
+
}
|
|
7867
9014
|
if (e.type.kind === "void")
|
|
7868
9015
|
return { kind: "return", value: e, loc };
|
|
7869
9016
|
return {
|
|
@@ -7875,6 +9022,16 @@ export class Lowerer {
|
|
|
7875
9022
|
loc,
|
|
7876
9023
|
};
|
|
7877
9024
|
}
|
|
9025
|
+
if (this.adoptsReturnedPromise() && !this.returnsLiteralIntoDyn(node, expected)) {
|
|
9026
|
+
// The async return lowers its operand untyped first (a promise
|
|
9027
|
+
// adopts before its payload converts); a maybe-promise union needs
|
|
9028
|
+
// the statement form, which branches between adoption and fulfillment.
|
|
9029
|
+
const e = this.lowerExpr(node);
|
|
9030
|
+
const flattened = this.maybePromiseReturn(node, e, expected);
|
|
9031
|
+
if (flattened)
|
|
9032
|
+
return flattened;
|
|
9033
|
+
return { kind: "return", value: this.asyncReturnValueOf(node, e, expected), loc };
|
|
9034
|
+
}
|
|
7878
9035
|
return { kind: "return", value: this.lowerReturnValue(node), loc };
|
|
7879
9036
|
}
|
|
7880
9037
|
maybeNarrow(expr, node) {
|
|
@@ -8031,7 +9188,7 @@ export class Lowerer {
|
|
|
8031
9188
|
// declaration poisons under a source-anchored diagnostic, deferred
|
|
8032
9189
|
// like any collection fence — never a crashed CLI.
|
|
8033
9190
|
if (isCheckerPanic(e)) {
|
|
8034
|
-
const decl = symbol ?
|
|
9191
|
+
const decl = symbol ? symbol.declarations[0] : undefined;
|
|
8035
9192
|
sink.push(checkerPanicDiag(e.message.split("\n", 1)[0], decl ? locOf(decl) : { file: this.entry.fileName, start: 0, end: 0 }));
|
|
8036
9193
|
}
|
|
8037
9194
|
else if (!(e instanceof PoisonError)) {
|
|
@@ -8142,27 +9299,27 @@ export class Lowerer {
|
|
|
8142
9299
|
const typeNodes = [];
|
|
8143
9300
|
const symbolRoots = [];
|
|
8144
9301
|
for (const decl of decls) {
|
|
8145
|
-
for (const member of decl.members) {
|
|
9302
|
+
for (const member of decl.members.nodes) {
|
|
8146
9303
|
if ((ts.isConstructorDeclaration(member) ||
|
|
8147
9304
|
ts.isMethodDeclaration(member) ||
|
|
8148
9305
|
ts.isGetAccessor(member) ||
|
|
8149
9306
|
ts.isSetAccessor(member)) &&
|
|
8150
9307
|
(!ts.isMethodDeclaration(member) || member.typeParameters === undefined)) {
|
|
8151
|
-
for (const param of member.parameters) {
|
|
9308
|
+
for (const param of member.parameters.nodes) {
|
|
8152
9309
|
if (param.initializer)
|
|
8153
9310
|
defaultTypeNodes.push(param.initializer);
|
|
8154
9311
|
}
|
|
8155
9312
|
}
|
|
8156
9313
|
}
|
|
8157
|
-
if (!isJsSourceFile(
|
|
9314
|
+
if (!isJsSourceFile(ts.getSourceFileOfNode(decl)))
|
|
8158
9315
|
continue;
|
|
8159
|
-
for (const member of decl.members) {
|
|
9316
|
+
for (const member of decl.members.nodes) {
|
|
8160
9317
|
if (ts.isConstructorDeclaration(member)) {
|
|
8161
|
-
for (const param of member.parameters) {
|
|
9318
|
+
for (const param of member.parameters.nodes) {
|
|
8162
9319
|
if (param.initializer)
|
|
8163
9320
|
typeNodes.push(param.initializer);
|
|
8164
9321
|
}
|
|
8165
|
-
for (const stmt of member.body?.statements ?? []) {
|
|
9322
|
+
for (const stmt of member.body?.statements?.nodes ?? []) {
|
|
8166
9323
|
if (!ts.isExpressionStatement(stmt) || !ts.isBinaryExpression(stmt.expression))
|
|
8167
9324
|
continue;
|
|
8168
9325
|
if (stmt.expression.operatorToken.kind !== ts.SyntaxKind.EqualsToken)
|
|
@@ -8181,13 +9338,13 @@ export class Lowerer {
|
|
|
8181
9338
|
if (ts.isMethodDeclaration(member) ||
|
|
8182
9339
|
ts.isGetAccessor(member) ||
|
|
8183
9340
|
ts.isSetAccessor(member)) {
|
|
8184
|
-
for (const param of member.parameters) {
|
|
9341
|
+
for (const param of member.parameters.nodes) {
|
|
8185
9342
|
if (param.initializer)
|
|
8186
9343
|
typeNodes.push(param.initializer);
|
|
8187
9344
|
}
|
|
8188
9345
|
// npm-static implicit-any classification resolves body parameter
|
|
8189
9346
|
// references while collecting the method's shape.
|
|
8190
|
-
if (implicitMonoFile(
|
|
9347
|
+
if (implicitMonoFile(ts.getSourceFileOfNode(decl)) && member.body) {
|
|
8191
9348
|
symbolRoots.push(member.body);
|
|
8192
9349
|
}
|
|
8193
9350
|
}
|
|
@@ -8214,6 +9371,43 @@ export class Lowerer {
|
|
|
8214
9371
|
lowerClassExpressionInfo(expr) {
|
|
8215
9372
|
return lowerClassExpressionInfo(this, expr);
|
|
8216
9373
|
}
|
|
9374
|
+
/** Depth of the whole-program analyses that query types across every
|
|
9375
|
+
* file before reachability is known (speculativeTypeQueries). */
|
|
9376
|
+
speculativeTypeQueryDepth = 0;
|
|
9377
|
+
/** Runs a whole-program analysis whose type queries are speculative: they
|
|
9378
|
+
* visit every file, reached or not, and no statement or declaration owns
|
|
9379
|
+
* a refusal they trigger (collectLocalClassForType). */
|
|
9380
|
+
speculativeTypeQueries(analysis) {
|
|
9381
|
+
this.speculativeTypeQueryDepth++;
|
|
9382
|
+
try {
|
|
9383
|
+
analysis();
|
|
9384
|
+
}
|
|
9385
|
+
finally {
|
|
9386
|
+
this.speculativeTypeQueryDepth--;
|
|
9387
|
+
}
|
|
9388
|
+
}
|
|
9389
|
+
/** Collects a function-local class because a type query named its
|
|
9390
|
+
* instance type. Collection and body lowering own a refusal of that
|
|
9391
|
+
* class: the poison reaches the declaration or statement that asked, as
|
|
9392
|
+
* before. A speculative whole-program analysis owns none, so there the
|
|
9393
|
+
* refusal stays reported (the build fails with it, as it did where such
|
|
9394
|
+
* an analysis already caught the poison) and the class is unmappable for
|
|
9395
|
+
* the query instead of the poison escaping the compiler. */
|
|
9396
|
+
collectLocalClassForType(decl) {
|
|
9397
|
+
if (this.speculativeTypeQueryDepth === 0 || this.fnStack.length > 0) {
|
|
9398
|
+
this.lowerClassExpressionInfo(decl);
|
|
9399
|
+
return true;
|
|
9400
|
+
}
|
|
9401
|
+
try {
|
|
9402
|
+
this.lowerClassExpressionInfo(decl);
|
|
9403
|
+
return true;
|
|
9404
|
+
}
|
|
9405
|
+
catch (e) {
|
|
9406
|
+
if (e instanceof PoisonError)
|
|
9407
|
+
return false;
|
|
9408
|
+
throw e;
|
|
9409
|
+
}
|
|
9410
|
+
}
|
|
8217
9411
|
lowerClassExpression(expr) {
|
|
8218
9412
|
return lowerClassExpression(this, expr);
|
|
8219
9413
|
}
|
|
@@ -8221,6 +9415,14 @@ export class Lowerer {
|
|
|
8221
9415
|
findMethodOn(info, name) {
|
|
8222
9416
|
return findMethodOn(this, info, name);
|
|
8223
9417
|
}
|
|
9418
|
+
/** A class whose root is the runtime's %Error (builtin errors and their
|
|
9419
|
+
* program subclasses). */
|
|
9420
|
+
isErrorRootedClass(className) {
|
|
9421
|
+
let info = this.classes.get(className) ?? null;
|
|
9422
|
+
while (info && info.base)
|
|
9423
|
+
info = info.base;
|
|
9424
|
+
return info?.def.name === "%Error";
|
|
9425
|
+
}
|
|
8224
9426
|
isSubclassOf(sub, sup) {
|
|
8225
9427
|
return isSubclassOf(this, sub, sup);
|
|
8226
9428
|
}
|
|
@@ -8337,7 +9539,7 @@ export class Lowerer {
|
|
|
8337
9539
|
*classMethodMembers(info, includeAbstract = false) {
|
|
8338
9540
|
if (!info.decl)
|
|
8339
9541
|
return; // builtin error classes: runtime-provided bodies
|
|
8340
|
-
for (const member of info.decl.members) {
|
|
9542
|
+
for (const member of info.decl.members.nodes) {
|
|
8341
9543
|
const fnLike = ts.isMethodDeclaration(member) || ts.isGetAccessor(member) || ts.isSetAccessor(member)
|
|
8342
9544
|
? member
|
|
8343
9545
|
: null;
|
|
@@ -8401,6 +9603,9 @@ export class Lowerer {
|
|
|
8401
9603
|
lowerDefaultExport(stmt) {
|
|
8402
9604
|
return lowerDefaultExport(this, stmt);
|
|
8403
9605
|
}
|
|
9606
|
+
/** Statements %main runs before any module initializer: runtime
|
|
9607
|
+
* registrations the lowering passes add. */
|
|
9608
|
+
mainPrelude = [];
|
|
8404
9609
|
buildMain() {
|
|
8405
9610
|
return buildMain(this);
|
|
8406
9611
|
}
|
|
@@ -8456,6 +9661,92 @@ export class Lowerer {
|
|
|
8456
9661
|
declareHiddenLocal(name, type) {
|
|
8457
9662
|
return declareContextLocal(this.ctx, name, type, false, undefined, undefined);
|
|
8458
9663
|
}
|
|
9664
|
+
/** The body binding of a fixed-tuple rest parameter: one native slot per
|
|
9665
|
+
* position (the flattened ABI), rebuilt into the tuple the source names.
|
|
9666
|
+
* The empty tuple rides the empty-array representation. */
|
|
9667
|
+
declareRestTupleParam(decl, nameNode, elemShapes, params, prologue) {
|
|
9668
|
+
const loc = locOf(decl);
|
|
9669
|
+
const name = nameNode.text;
|
|
9670
|
+
const fn = decl.parent;
|
|
9671
|
+
const symbol = this.checker.getSymbolAtLocation(nameNode);
|
|
9672
|
+
const isRead = (id) => id !== nameNode && this.checker.getSymbolAtLocation(id) === symbol;
|
|
9673
|
+
const pure = fn !== undefined && symbol !== undefined && onlyForwarded(this, fn, isRead);
|
|
9674
|
+
// A forwarded-only tuple is never built: a tuple with optional
|
|
9675
|
+
// positions (`Parameters<(n?: T) => R>`, whose length varies per call)
|
|
9676
|
+
// forwards its slots, an omitted position as undefined — which a
|
|
9677
|
+
// callee's default treats exactly as an omitted argument. Its length
|
|
9678
|
+
// is the one read that would observe the difference.
|
|
9679
|
+
const tupleType = pure &&
|
|
9680
|
+
elemShapes.length > 0 &&
|
|
9681
|
+
this.mapTypeOf(this.typeOf(nameNode)) === null &&
|
|
9682
|
+
!readsLength(fn, isRead)
|
|
9683
|
+
? this.forwardedSlotsTuple(elemShapes)
|
|
9684
|
+
: this.irTypeOf(nameNode);
|
|
9685
|
+
const slots = elemShapes.map((shape, i) => {
|
|
9686
|
+
const slot = this.declareHiddenLocal(`%${name}.${i}`, shape.type);
|
|
9687
|
+
params.push({ localId: slot.id, name: `%${name}.${i}`, type: shape.type });
|
|
9688
|
+
return slot;
|
|
9689
|
+
});
|
|
9690
|
+
const body = this.declareLocal(nameNode, name, tupleType, true);
|
|
9691
|
+
if (pure) {
|
|
9692
|
+
this.ctx.pureTuples.set(body.id, slots);
|
|
9693
|
+
return;
|
|
9694
|
+
}
|
|
9695
|
+
const init = this.tupleOfSlots(slots, tupleType, nameNode, loc);
|
|
9696
|
+
prologue.push({ kind: "varDecl", localId: body.id, init, loc });
|
|
9697
|
+
}
|
|
9698
|
+
/** `value as never` flowing into a typed slot: `never` is assignable to
|
|
9699
|
+
* every type, so the assertion promises the slot's type. A dynamic value
|
|
9700
|
+
* takes the checked extraction to it, as `value as T` would. Null for
|
|
9701
|
+
* every other form, and for numeric, dynamic and union slots, which
|
|
9702
|
+
* keep the existing lowering. */
|
|
9703
|
+
neverAssertionInto(node, expected) {
|
|
9704
|
+
if (!(ts.isAsExpression(node) || ts.isTypeAssertion(node)))
|
|
9705
|
+
return null;
|
|
9706
|
+
if (expected.kind === "f64" || expected.kind === "dyn" || expected.kind === "union")
|
|
9707
|
+
return null;
|
|
9708
|
+
if (!(this.checker.getTypeFromTypeNode(node.type).flags & ts.TypeFlags.Never))
|
|
9709
|
+
return null;
|
|
9710
|
+
const innerTs = this.typeOf(node.expression);
|
|
9711
|
+
if (!(innerTs.flags & ts.TypeFlags.Any) && this.mapTypeOf(innerTs)?.kind !== "dyn")
|
|
9712
|
+
return null;
|
|
9713
|
+
if (!canDynCheckTo(expected, (id) => this.shapes.get(id), (id) => this.unions.get(id)))
|
|
9714
|
+
return null;
|
|
9715
|
+
const inner = this.lowerExpr(node.expression);
|
|
9716
|
+
if (inner.type.kind !== "dyn")
|
|
9717
|
+
return null;
|
|
9718
|
+
return { kind: "dynCheck", value: inner, type: expected, loc: locOf(node) };
|
|
9719
|
+
}
|
|
9720
|
+
/** The tuple record of a forwarded-only rest tuple's native slots. */
|
|
9721
|
+
forwardedSlotsTuple(elemShapes) {
|
|
9722
|
+
const fields = elemShapes.map((shape, i) => ({ name: String(i), type: shape.type }));
|
|
9723
|
+
fields.sort((a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0));
|
|
9724
|
+
return { kind: "record", shapeId: this.shapes.intern(fields, true) };
|
|
9725
|
+
}
|
|
9726
|
+
/** A fresh tuple holding the given positional slots, typed `tupleType`
|
|
9727
|
+
* (a tuple record, or the empty-array form of `[]`). */
|
|
9728
|
+
tupleOfSlots(slots, tupleType, blame, loc) {
|
|
9729
|
+
if (slots.length === 0) {
|
|
9730
|
+
if (tupleType.kind !== "array")
|
|
9731
|
+
this.badType(blame, this.typeOf(blame));
|
|
9732
|
+
return { kind: "arrayLit", elems: [], type: tupleType, loc };
|
|
9733
|
+
}
|
|
9734
|
+
const shape = tupleType.kind === "record" ? this.shapes.get(tupleType.shapeId) : undefined;
|
|
9735
|
+
if (!shape?.tuple || shape.fields.length !== slots.length)
|
|
9736
|
+
this.badType(blame, this.typeOf(blame));
|
|
9737
|
+
return {
|
|
9738
|
+
kind: "recordLit",
|
|
9739
|
+
fields: slots.map((slot, i) => {
|
|
9740
|
+
const field = shape.fields.find((f) => f.name === String(i));
|
|
9741
|
+
return {
|
|
9742
|
+
name: field.name,
|
|
9743
|
+
value: this.coerceToExpected({ kind: "varRef", localId: slot.id, type: slot.type, loc }, field.type),
|
|
9744
|
+
};
|
|
9745
|
+
}),
|
|
9746
|
+
type: tupleType,
|
|
9747
|
+
loc,
|
|
9748
|
+
};
|
|
9749
|
+
}
|
|
8459
9750
|
/** Declares a callee's parameter locals from its ParamShapes and builds
|
|
8460
9751
|
* the DEFAULT-PARAM PROLOGUE. Required/optional/rest params bind their
|
|
8461
9752
|
* symbol directly (one local of the ABI type). A defaulted param `x: T = e`
|
|
@@ -8490,6 +9781,15 @@ export class Lowerer {
|
|
|
8490
9781
|
return defaultAfterUndefined(undefinedValue, this.coerceInto(node, absent, expected));
|
|
8491
9782
|
};
|
|
8492
9783
|
decls.forEach((decl, i) => {
|
|
9784
|
+
// A fixed-tuple rest parameter owns every remaining (flattened)
|
|
9785
|
+
// shape, possibly none for `[]` (restTupleShapes).
|
|
9786
|
+
if (decl.dotDotDotToken !== undefined &&
|
|
9787
|
+
ts.isIdentifier(decl.name) &&
|
|
9788
|
+
i === decls.length - 1 &&
|
|
9789
|
+
(shapes[i] === undefined ? shapes.length === i : shapes[i].restTuple === true)) {
|
|
9790
|
+
this.declareRestTupleParam(decl, decl.name, shapes.slice(i), params, prologue);
|
|
9791
|
+
return;
|
|
9792
|
+
}
|
|
8493
9793
|
const shape = shapes[i];
|
|
8494
9794
|
if (ts.isArrayBindingPattern(decl.name) || ts.isObjectBindingPattern(decl.name)) {
|
|
8495
9795
|
// Pattern parameter: one hidden ABI slot carries the source value;
|
|
@@ -8536,7 +9836,7 @@ export class Lowerer {
|
|
|
8536
9836
|
// RequireObjectCoercible; use V8's default-expression spelling.
|
|
8537
9837
|
if (abi.kind === "dyn" &&
|
|
8538
9838
|
ts.isObjectBindingPattern(decl.name) &&
|
|
8539
|
-
decl.name.elements.length === 0) {
|
|
9839
|
+
decl.name.elements.nodes.length === 0) {
|
|
8540
9840
|
prologue.push({
|
|
8541
9841
|
kind: "exprStmt",
|
|
8542
9842
|
expr: {
|
|
@@ -8615,10 +9915,32 @@ export class Lowerer {
|
|
|
8615
9915
|
srcType = pickedT;
|
|
8616
9916
|
srcRef = () => ({ kind: "varRef", localId: src.id, type: pickedT, loc });
|
|
8617
9917
|
}
|
|
9918
|
+
else {
|
|
9919
|
+
// `({ groups }) => ...` over matchAll rows.
|
|
9920
|
+
const groupsSource = matchGroupsPatternSource(this, decl.name, srcRef(), () => matchCallbackParamGroupsOf(this, decl), loc);
|
|
9921
|
+
if (groupsSource !== null) {
|
|
9922
|
+
const src = this.declareHiddenLocal("%psrc", groupsSource.type);
|
|
9923
|
+
prologue.push({ kind: "varDecl", localId: src.id, init: groupsSource, loc });
|
|
9924
|
+
const groupsT = groupsSource.type;
|
|
9925
|
+
srcType = groupsT;
|
|
9926
|
+
srcRef = () => ({ kind: "varRef", localId: src.id, type: groupsT, loc });
|
|
9927
|
+
}
|
|
9928
|
+
}
|
|
8618
9929
|
this.lowerBindingPattern(decl.name, srcRef, srcType, true, prologue);
|
|
8619
9930
|
return;
|
|
8620
9931
|
}
|
|
8621
9932
|
const name = decl.name.text;
|
|
9933
|
+
if (shape.entryNarrow) {
|
|
9934
|
+
// A typed override parameter over an inherited checked-value slot:
|
|
9935
|
+
// the body local narrows from the dyn argument at entry.
|
|
9936
|
+
const loc = locOf(decl);
|
|
9937
|
+
const slot = this.declareHiddenLocal(name, shape.type);
|
|
9938
|
+
params.push({ localId: slot.id, name, type: shape.type });
|
|
9939
|
+
const narrowed = this.coerceInto(decl.name, { kind: "varRef", localId: slot.id, type: shape.type, loc }, shape.entryNarrow);
|
|
9940
|
+
const body = this.declareLocal(decl.name, name, shape.entryNarrow, true);
|
|
9941
|
+
prologue.push({ kind: "varDecl", localId: body.id, init: narrowed, loc });
|
|
9942
|
+
return;
|
|
9943
|
+
}
|
|
8622
9944
|
if (shape.mode === "omittable" && shape.bodyType && decl.initializer) {
|
|
8623
9945
|
const abi = shape.type;
|
|
8624
9946
|
if (abi.kind === "dyn") {
|
|
@@ -8789,6 +10111,11 @@ export class Lowerer {
|
|
|
8789
10111
|
if (!symbol)
|
|
8790
10112
|
return null;
|
|
8791
10113
|
const direct = this.resolveKey(symbol, ident);
|
|
10114
|
+
if (direct && this.ctx.pureTuples.has(direct.id)) {
|
|
10115
|
+
// onlyForwarded proved every read forwards; a plain read here means
|
|
10116
|
+
// the analysis and the lowering disagree.
|
|
10117
|
+
throw new InternalCompilerError(`lowerer bug: forwarded-only tuple '${ident.text}' read as a value`);
|
|
10118
|
+
}
|
|
8792
10119
|
if (direct)
|
|
8793
10120
|
return direct;
|
|
8794
10121
|
// A PARAMETER PROPERTY declares two symbols: references resolve to the
|
|
@@ -8796,11 +10123,11 @@ export class Lowerer {
|
|
|
8796
10123
|
// symbol — which is what declareParams registered the local under.
|
|
8797
10124
|
// On a miss, normalize to the declaration's key and retry (ordinary
|
|
8798
10125
|
// bindings never reach this — their two sides intern to one symbol).
|
|
8799
|
-
const vd =
|
|
10126
|
+
const vd = symbol.valueDeclaration;
|
|
8800
10127
|
if (vd &&
|
|
8801
10128
|
ts.isParameter(vd) &&
|
|
8802
10129
|
ts.isIdentifier(vd.name) &&
|
|
8803
|
-
vd.modifiers?.some((m) => m.kind === ts.SyntaxKind.PublicKeyword ||
|
|
10130
|
+
vd.modifiers?.nodes.some((m) => m.kind === ts.SyntaxKind.PublicKeyword ||
|
|
8804
10131
|
m.kind === ts.SyntaxKind.PrivateKeyword ||
|
|
8805
10132
|
m.kind === ts.SyntaxKind.ProtectedKeyword ||
|
|
8806
10133
|
m.kind === ts.SyntaxKind.ReadonlyKeyword ||
|
|
@@ -8814,8 +10141,8 @@ export class Lowerer {
|
|
|
8814
10141
|
/** Lexical `this` — the enclosing method's this-param, possibly captured
|
|
8815
10142
|
* through arrows (function expressions/declarations reset `this` in JS;
|
|
8816
10143
|
* their bodies never see an enclosing method's binding). */
|
|
8817
|
-
resolveThis() {
|
|
8818
|
-
return this.resolveKey(undefined);
|
|
10144
|
+
resolveThis(blame) {
|
|
10145
|
+
return this.resolveKey(undefined, blame);
|
|
8819
10146
|
}
|
|
8820
10147
|
peekLocal(ident) {
|
|
8821
10148
|
let symbol = this.checker.getSymbolAtLocation(ident);
|
|
@@ -8840,9 +10167,7 @@ export class Lowerer {
|
|
|
8840
10167
|
this.runtimeOptionalRoots.set(entry, root);
|
|
8841
10168
|
});
|
|
8842
10169
|
if (resolved.error !== null) {
|
|
8843
|
-
const location = blame ??
|
|
8844
|
-
(symbol === undefined ? undefined : this.checker.declarationsOf(symbol)[0]) ??
|
|
8845
|
-
this.entry;
|
|
10170
|
+
const location = blame ?? (symbol === undefined ? undefined : symbol.declarations[0]) ?? this.entry;
|
|
8846
10171
|
const message = `the binding '${resolved.origin.name}' captured through a plain nested function (the declaration has no static storage a capture can thread — bind the value through a typed const, or read it in the declaring scope)`;
|
|
8847
10172
|
this.unsupported("SC1090", location, message);
|
|
8848
10173
|
}
|
|
@@ -8915,7 +10240,7 @@ export class Lowerer {
|
|
|
8915
10240
|
// concrete signature — name the shape instead of the generic
|
|
8916
10241
|
// binding-form text.
|
|
8917
10242
|
if (symbol) {
|
|
8918
|
-
const d =
|
|
10243
|
+
const d = symbol.valueDeclaration;
|
|
8919
10244
|
if (d && ts.isVariableDeclaration(d) && d.initializer === undefined) {
|
|
8920
10245
|
const t = this.checker.getTypeOfSymbol(symbol);
|
|
8921
10246
|
const parts = t.isUnionType() ? ts.constituentTypes(t) : [t];
|
|
@@ -8929,7 +10254,7 @@ export class Lowerer {
|
|
|
8929
10254
|
// assignment are `undefined`, and this binding's type has no slot for
|
|
8930
10255
|
// that value — name the shape instead of the generic no-lowering text.
|
|
8931
10256
|
if (symbol) {
|
|
8932
|
-
const d =
|
|
10257
|
+
const d = symbol.valueDeclaration;
|
|
8933
10258
|
if (d &&
|
|
8934
10259
|
ts.isVariableDeclaration(d) &&
|
|
8935
10260
|
(ts.getCombinedNodeFlags(d) & ts.NodeFlags.BlockScoped) === 0) {
|
|
@@ -9033,6 +10358,9 @@ export class Lowerer {
|
|
|
9033
10358
|
}
|
|
9034
10359
|
/* ── expressions ──────────────────────────────────────────────────── */
|
|
9035
10360
|
lowerExpr(expr) {
|
|
10361
|
+
const hash = this.hashStreamReceivers.get(expr);
|
|
10362
|
+
if (hash)
|
|
10363
|
+
return hashStreamOf(varRef(hash.localId, hash.type, locOf(expr)));
|
|
9036
10364
|
return lowerExpr(this, expr);
|
|
9037
10365
|
}
|
|
9038
10366
|
lowerIntrinsicProperty(expr) {
|
|
@@ -9307,8 +10635,13 @@ export class Lowerer {
|
|
|
9307
10635
|
// dispatch. The general identifier-call paths have no lowering for a
|
|
9308
10636
|
// promise-returning ambient global, and `import` is a keyword callee no
|
|
9309
10637
|
// identifier path matches.
|
|
10638
|
+
const webAssembly = lowerWebAssemblyCall(this, expr);
|
|
10639
|
+
if (webAssembly !== null)
|
|
10640
|
+
return webAssembly;
|
|
10641
|
+
refuseWebAssemblyUse(this, expr.expression);
|
|
9310
10642
|
return (lowerLifetimeRegionCall(this, expr) ??
|
|
9311
10643
|
lowerInternTableCall(this, expr) ??
|
|
10644
|
+
lowerThreadSlotsCall(this, expr) ??
|
|
9312
10645
|
lowerFfiCall(this, expr) ??
|
|
9313
10646
|
lowerFetchCall(this, expr) ??
|
|
9314
10647
|
lowerStaticFetchCompanionCall(this, expr) ??
|
|
@@ -9319,7 +10652,9 @@ export class Lowerer {
|
|
|
9319
10652
|
lowerStaticReadableStreamReaderCall(this, expr) ??
|
|
9320
10653
|
lowerStaticResponseCall(this, expr) ??
|
|
9321
10654
|
lowerStaticBlobCall(this, expr) ??
|
|
10655
|
+
lowerWebCryptoCall(this, expr) ??
|
|
9322
10656
|
lowerKeyObjectCall(this, expr) ??
|
|
10657
|
+
lowerNetAddressCall(this, expr) ??
|
|
9323
10658
|
lowerFetchElementMethodCall(this, expr) ??
|
|
9324
10659
|
lowerDynamicImportCall(this, expr) ??
|
|
9325
10660
|
lowerCall(this, expr));
|
|
@@ -9446,13 +10781,20 @@ export class Lowerer {
|
|
|
9446
10781
|
return inheritsBuiltinEmitterCtor(this, info);
|
|
9447
10782
|
}
|
|
9448
10783
|
lowerNew(expr) {
|
|
10784
|
+
const webAssembly = lowerWebAssemblyNew(this, expr);
|
|
10785
|
+
if (webAssembly !== null)
|
|
10786
|
+
return webAssembly;
|
|
10787
|
+
refuseWebAssemblyUse(this, expr.expression, "new ");
|
|
9449
10788
|
const builtin = lowerLifetimeRegionNew(this, expr) ??
|
|
9450
10789
|
lowerInternTableNew(this, expr) ??
|
|
10790
|
+
lowerThreadSlotsNew(this, expr) ??
|
|
9451
10791
|
lowerAbortControllerNew(this, expr) ??
|
|
10792
|
+
lowerDisposableStackNew(this, expr) ??
|
|
9452
10793
|
lowerEventTargetNew(this, expr) ??
|
|
9453
10794
|
lowerFetchWebNew(this, expr) ??
|
|
9454
10795
|
lowerResponseNew(this, expr) ??
|
|
9455
10796
|
lowerBlobNew(this, expr) ??
|
|
10797
|
+
lowerNetAddressNew(this, expr) ??
|
|
9456
10798
|
lowerStaticReadableStreamNew(this, expr) ??
|
|
9457
10799
|
lowerConsoleNew(this, expr);
|
|
9458
10800
|
return (builtin ?? this.withRuntimeOptionalClassValue(expr.expression, () => lowerNew(this, expr)));
|
|
@@ -9533,9 +10875,21 @@ export class Lowerer {
|
|
|
9533
10875
|
if (mapped?.kind === "moduleNs" && mapped.moduleId.startsWith("builtin:")) {
|
|
9534
10876
|
return mapped.moduleId.slice("builtin:".length);
|
|
9535
10877
|
}
|
|
10878
|
+
// A nullable namespace binding (`const os: typeof NodeOs | null`, a
|
|
10879
|
+
// probed process.getBuiltinModule result) read where the checker
|
|
10880
|
+
// narrowed it present: its members key the same tables.
|
|
10881
|
+
if (stored?.kind === "union") {
|
|
10882
|
+
const present = this.unions.get(stored.unionId)?.arms.filter((arm) => !isUnitType(arm));
|
|
10883
|
+
const only = present?.length === 1 ? present[0] : undefined;
|
|
10884
|
+
if (only?.kind === "moduleNs" && only.moduleId.startsWith("builtin:")) {
|
|
10885
|
+
const narrowed = this.mapTypeOf(this.typeOf(expr));
|
|
10886
|
+
if (narrowed?.kind === "moduleNs" && narrowed.moduleId === only.moduleId)
|
|
10887
|
+
return only.moduleId.slice("builtin:".length);
|
|
10888
|
+
}
|
|
10889
|
+
}
|
|
9536
10890
|
if (ts.isIdentifier(expr)) {
|
|
9537
10891
|
const symbol = this.checker.getSymbolAtLocation(expr);
|
|
9538
|
-
const decl = symbol ?
|
|
10892
|
+
const decl = symbol ? symbol.declarations[0] : undefined;
|
|
9539
10893
|
if (!decl)
|
|
9540
10894
|
return null;
|
|
9541
10895
|
// The CommonJS twin: `const fs = require("fs")` binds the same
|
|
@@ -9604,7 +10958,7 @@ export class Lowerer {
|
|
|
9604
10958
|
}
|
|
9605
10959
|
if (ts.isIdentifier(expr)) {
|
|
9606
10960
|
const symbol = this.checker.getSymbolAtLocation(expr);
|
|
9607
|
-
const decl = symbol ?
|
|
10961
|
+
const decl = symbol ? symbol.declarations[0] : undefined;
|
|
9608
10962
|
if (!decl)
|
|
9609
10963
|
return null;
|
|
9610
10964
|
// The DEFAULT-import twin: Node's default export of a CJS builtin
|
|
@@ -9655,9 +11009,47 @@ export class Lowerer {
|
|
|
9655
11009
|
return { module: "fs", member: "realpathSync.native" };
|
|
9656
11010
|
}
|
|
9657
11011
|
}
|
|
11012
|
+
// timers/promises scheduler.wait / scheduler.yield: methods of the
|
|
11013
|
+
// module's scheduler object, dispatched as module members.
|
|
11014
|
+
if (access.name.text === "wait" || access.name.text === "yield") {
|
|
11015
|
+
const owner = access.expression;
|
|
11016
|
+
const imported = ts.isIdentifier(owner)
|
|
11017
|
+
? this.builtinImportOf(owner)
|
|
11018
|
+
: ts.isPropertyAccessExpression(owner)
|
|
11019
|
+
? this.builtinMemberOf(owner)
|
|
11020
|
+
: null;
|
|
11021
|
+
if (imported?.module === "timers/promises" && imported.member === "scheduler") {
|
|
11022
|
+
return { module: "timers/promises", member: `scheduler.${access.name.text}` };
|
|
11023
|
+
}
|
|
11024
|
+
}
|
|
11025
|
+
// punycode.ucs2.decode / encode: methods of the module's ucs2 object,
|
|
11026
|
+
// dispatched as module members.
|
|
11027
|
+
if (access.name.text === "decode" || access.name.text === "encode") {
|
|
11028
|
+
const owner = access.expression;
|
|
11029
|
+
const imported = ts.isIdentifier(owner)
|
|
11030
|
+
? this.builtinImportOf(owner)
|
|
11031
|
+
: ts.isPropertyAccessExpression(owner)
|
|
11032
|
+
? this.builtinMemberOf(owner)
|
|
11033
|
+
: null;
|
|
11034
|
+
if (imported?.module === "punycode" && imported.member === "ucs2") {
|
|
11035
|
+
return { module: "punycode", member: `ucs2.${access.name.text}` };
|
|
11036
|
+
}
|
|
11037
|
+
}
|
|
9658
11038
|
const module = this.builtinNamespaceModuleOf(access.expression);
|
|
11039
|
+
// node:constants is one checked-dynamic object: its members read
|
|
11040
|
+
// through the object itself (builtinConstantsObject), not the tables.
|
|
11041
|
+
if (module === "constants")
|
|
11042
|
+
return null;
|
|
9659
11043
|
if (module !== null)
|
|
9660
11044
|
return { module, member: access.name.text };
|
|
11045
|
+
// The events module object IS the EventEmitter class, so the class's
|
|
11046
|
+
// defaultMaxListeners is the module property.
|
|
11047
|
+
if (access.name.text === "defaultMaxListeners" && ts.isIdentifier(access.expression)) {
|
|
11048
|
+
const imported = this.builtinImportOf(access.expression);
|
|
11049
|
+
if (imported?.module === "events" && imported.member === "EventEmitter") {
|
|
11050
|
+
return { module: "events", member: "defaultMaxListeners" };
|
|
11051
|
+
}
|
|
11052
|
+
}
|
|
9661
11053
|
// The RE-EXPORT FACADE's namespace spelling: `import * as assert from
|
|
9662
11054
|
// "./facade.js"` over `export { ok } from "node:assert"` (the formatter idiom's
|
|
9663
11055
|
// universal/assert). The member's symbol is the facade's
|
|
@@ -9697,9 +11089,8 @@ export class Lowerer {
|
|
|
9697
11089
|
COPYFILE_FICLONE_FORCE: 4,
|
|
9698
11090
|
};
|
|
9699
11091
|
const value = own(MODES, expr.name.text);
|
|
9700
|
-
if (value === undefined)
|
|
9701
|
-
|
|
9702
|
-
}
|
|
11092
|
+
if (value === undefined)
|
|
11093
|
+
return fsConstantMemberRead(expr);
|
|
9703
11094
|
return { kind: "numLit", value, type: F64, loc };
|
|
9704
11095
|
}
|
|
9705
11096
|
}
|
|
@@ -9711,9 +11102,18 @@ export class Lowerer {
|
|
|
9711
11102
|
return pathModuleValue(this, `path/${bi.member}`, loc);
|
|
9712
11103
|
}
|
|
9713
11104
|
// events.defaultMaxListeners READS the process-wide default (its
|
|
9714
|
-
// write twin routes through emitter.setDefaultMaxChk).
|
|
11105
|
+
// write twin routes through emitter.setDefaultMaxChk). Through an ES
|
|
11106
|
+
// module namespace it reads the namespace's copy instead.
|
|
9715
11107
|
if (bi.module === "events" && bi.member === "defaultMaxListeners") {
|
|
9716
|
-
|
|
11108
|
+
const esm = ts.isIdentifier(expr.expression) &&
|
|
11109
|
+
esmImportBindingKind(this, expr.expression) === "namespace";
|
|
11110
|
+
return {
|
|
11111
|
+
kind: "libCall",
|
|
11112
|
+
fn: esm ? "emitter.esmDefaultMax" : "emitter.getDefaultMax",
|
|
11113
|
+
args: [],
|
|
11114
|
+
type: F64,
|
|
11115
|
+
loc,
|
|
11116
|
+
};
|
|
9717
11117
|
}
|
|
9718
11118
|
if (bi.module === "worker_threads") {
|
|
9719
11119
|
const value = lowerWorkerMetadata(bi.member, loc);
|
|
@@ -9731,6 +11131,15 @@ export class Lowerer {
|
|
|
9731
11131
|
if (bi.module === "http" && bi.member === "METHODS") {
|
|
9732
11132
|
return { kind: "libCall", fn: "http.methods", args: [], type: arrayOf(STRING), loc };
|
|
9733
11133
|
}
|
|
11134
|
+
if ((bi.module === "http" || bi.module === "https") && bi.member === "globalAgent") {
|
|
11135
|
+
return {
|
|
11136
|
+
kind: "libCall",
|
|
11137
|
+
fn: "http.globalAgent",
|
|
11138
|
+
args: [{ kind: "boolLit", value: bi.module === "https", type: BOOL, loc }],
|
|
11139
|
+
type: DYN,
|
|
11140
|
+
loc,
|
|
11141
|
+
};
|
|
11142
|
+
}
|
|
9734
11143
|
if (bi.module === "http" && bi.member === "STATUS_CODES") {
|
|
9735
11144
|
return { kind: "libCall", fn: "http.statusCodes", args: [], type: DYN, loc };
|
|
9736
11145
|
}
|
|
@@ -9752,12 +11161,24 @@ export class Lowerer {
|
|
|
9752
11161
|
if (callable)
|
|
9753
11162
|
return callable;
|
|
9754
11163
|
}
|
|
9755
|
-
|
|
9756
|
-
|
|
9757
|
-
|
|
11164
|
+
// node:stream/web's exports are the web stream globals themselves: in
|
|
11165
|
+
// JavaScript sources the same identity token as the global spelling
|
|
11166
|
+
// (`require("stream/web").ReadableStream === globalThis.ReadableStream`).
|
|
11167
|
+
if (bi.module === "stream/web" && isJsSourceFile(ts.getSourceFileOfNode(expr))) {
|
|
11168
|
+
return { kind: "strLit", value: `[builtin ${bi.member}]`, type: STRING, loc };
|
|
11169
|
+
}
|
|
11170
|
+
// A bare `fs.constants` read (not one of the baked bits above).
|
|
11171
|
+
if (bi.member === "constants" && bi.module === "fs")
|
|
11172
|
+
return fsConstantsObject(loc);
|
|
11173
|
+
// `stream.Readable` as a JavaScript value: the runtime's untyped
|
|
11174
|
+
// constructor, the base a constructor function inherits.
|
|
11175
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(expr))) {
|
|
11176
|
+
const classKind = builtinMemberClassKind(bi.module, bi.member);
|
|
11177
|
+
if (classKind !== null)
|
|
11178
|
+
return builtinClassValue(classKind, loc);
|
|
9758
11179
|
}
|
|
9759
11180
|
if (builtinModuleFnOf(this, bi.module, bi.member)) {
|
|
9760
|
-
this.unsupported("SC1090", expr, `library functions as values (call '${
|
|
11181
|
+
this.unsupported("SC1090", expr, `library functions as values (call '${ts.getTextOfNode(expr)}' directly)`);
|
|
9761
11182
|
}
|
|
9762
11183
|
this.noLowering(`${bi.module}.${bi.member}`, expr, builtinFenceHintOf(bi.module, bi.member), this.checker.getSymbolAtLocation(expr.name));
|
|
9763
11184
|
}
|
|
@@ -9804,11 +11225,12 @@ export class Lowerer {
|
|
|
9804
11225
|
const adapterShape = valueParams
|
|
9805
11226
|
.map((param) => param.mode === "optional" ? `${param.mode}:${param.defaultValue}` : param.mode)
|
|
9806
11227
|
.join(",");
|
|
9807
|
-
const key = `${fn.fn}:${typeKey(funcType)}:${adapterShape}`;
|
|
11228
|
+
const key = `${fn.valueFn ?? fn.fn}:${typeKey(funcType)}:${adapterShape}`;
|
|
9808
11229
|
let fnName = this.builtinCallableValueFns.get(key);
|
|
9809
11230
|
if (!fnName) {
|
|
9810
|
-
fnName = `%builtin.value.${fn.fn}.${this.builtinCallableValueFns.size}`;
|
|
11231
|
+
fnName = `%builtin.value.${fn.valueFn ?? fn.fn}.${this.builtinCallableValueFns.size}`;
|
|
9811
11232
|
this.builtinCallableValueFns.set(key, fnName);
|
|
11233
|
+
this.builtinCallableValueNames.set(fnName, display.slice(display.lastIndexOf(".") + 1));
|
|
9812
11234
|
const params = funcType.params.map((type, index) => ({
|
|
9813
11235
|
localId: `arg.${index}`,
|
|
9814
11236
|
name: `arg${index}`,
|
|
@@ -9866,7 +11288,7 @@ export class Lowerer {
|
|
|
9866
11288
|
loc,
|
|
9867
11289
|
};
|
|
9868
11290
|
});
|
|
9869
|
-
const call = { kind: "libCall", fn: fn.fn, args, type: fn.result, loc };
|
|
11291
|
+
const call = { kind: "libCall", fn: fn.valueFn ?? fn.fn, args, type: fn.result, loc };
|
|
9870
11292
|
const body = fn.result.kind === "void"
|
|
9871
11293
|
? [
|
|
9872
11294
|
{ kind: "exprStmt", expr: call, loc },
|
|
@@ -9911,8 +11333,8 @@ export class Lowerer {
|
|
|
9911
11333
|
lowerSpawnCall(expr, loc) {
|
|
9912
11334
|
return lowerSpawnCall(this, expr, loc);
|
|
9913
11335
|
}
|
|
9914
|
-
lowerExecFileCall(expr, loc) {
|
|
9915
|
-
return lowerExecFileCall(this, expr, loc);
|
|
11336
|
+
lowerExecFileCall(expr, loc, shell = false) {
|
|
11337
|
+
return lowerExecFileCall(this, expr, loc, shell);
|
|
9916
11338
|
}
|
|
9917
11339
|
lowerExecSyncCall(expr, shell, loc) {
|
|
9918
11340
|
return lowerExecSyncCall(this, expr, shell, loc);
|
|
@@ -10110,4 +11532,195 @@ export class Lowerer {
|
|
|
10110
11532
|
return lowerStdlibMethodCall(this, call, access);
|
|
10111
11533
|
}
|
|
10112
11534
|
}
|
|
11535
|
+
/** Whether some read of a binding (identified by `isRead`) in `fn` takes
|
|
11536
|
+
* its `.length`. */
|
|
11537
|
+
function readsLength(fn, isRead) {
|
|
11538
|
+
let found = false;
|
|
11539
|
+
ts.walkPreorder(fn, (n) => {
|
|
11540
|
+
if (found)
|
|
11541
|
+
return "stop";
|
|
11542
|
+
if (!ts.isIdentifier(n) || !isRead(n))
|
|
11543
|
+
return undefined;
|
|
11544
|
+
let top = n;
|
|
11545
|
+
while (top.parent &&
|
|
11546
|
+
(ts.isParenthesizedExpression(top.parent) ||
|
|
11547
|
+
ts.isAsExpression(top.parent) ||
|
|
11548
|
+
ts.isTypeAssertion(top.parent) ||
|
|
11549
|
+
ts.isSatisfiesExpression(top.parent) ||
|
|
11550
|
+
ts.isNonNullExpression(top.parent)))
|
|
11551
|
+
top = top.parent;
|
|
11552
|
+
const p = top.parent;
|
|
11553
|
+
if (p && ts.isPropertyAccessExpression(p) && p.expression === top && p.name.text === "length")
|
|
11554
|
+
found = true;
|
|
11555
|
+
return undefined;
|
|
11556
|
+
});
|
|
11557
|
+
return found;
|
|
11558
|
+
}
|
|
11559
|
+
/** A union of record layouts flowing into one record slot: a function
|
|
11560
|
+
* returning differently-shaped object literals (`{ ok: false }` and
|
|
11561
|
+
* `{ ok: true, size }`, whose union the checker normalizes to arms with
|
|
11562
|
+
* `size?: undefined`) into its declared result type. Each record arm
|
|
11563
|
+
* width-lifts into the slot on its own tag; unit arms take the stranded
|
|
11564
|
+
* TypeError (the checker excluded them). Null when some record arm does
|
|
11565
|
+
* not lift, or when there is a non-record, non-unit arm. */
|
|
11566
|
+
function unionArmsWidthLift(lowerer, expr, expected) {
|
|
11567
|
+
if (expr.type.kind !== "union")
|
|
11568
|
+
return null;
|
|
11569
|
+
const unionId = expr.type.unionId;
|
|
11570
|
+
const arms = lowerer.unions.get(unionId)?.arms ?? [];
|
|
11571
|
+
const lifts = [];
|
|
11572
|
+
let records = 0;
|
|
11573
|
+
for (const arm of arms) {
|
|
11574
|
+
if (isUnitType(arm)) {
|
|
11575
|
+
lifts.push(null);
|
|
11576
|
+
continue;
|
|
11577
|
+
}
|
|
11578
|
+
if (arm.kind !== "record")
|
|
11579
|
+
return null;
|
|
11580
|
+
const lift = lowerer.widthLiftPlan(arm, expected);
|
|
11581
|
+
if (!lift)
|
|
11582
|
+
return null;
|
|
11583
|
+
lifts.push(lift);
|
|
11584
|
+
records++;
|
|
11585
|
+
}
|
|
11586
|
+
if (records < 2)
|
|
11587
|
+
return null;
|
|
11588
|
+
const loc = expr.loc;
|
|
11589
|
+
const local = lowerer.declareHiddenLocal("%unionLift", expr.type);
|
|
11590
|
+
const ref = () => ({ kind: "varRef", localId: local.id, type: expr.type, loc });
|
|
11591
|
+
let result = null;
|
|
11592
|
+
for (let tag = arms.length - 1; tag >= 0; tag--) {
|
|
11593
|
+
const lift = lifts[tag];
|
|
11594
|
+
const arm = arms[tag];
|
|
11595
|
+
const branch = lift
|
|
11596
|
+
? lowerer.applyWidthLift(lift, { kind: "unionNarrow", unionId, tag, value: ref(), type: arm, loc }, expected, loc)
|
|
11597
|
+
: nodeThrowExpr(1, "", `${arm.kind === "nullT" ? "null" : "undefined"} is not representable in a '${lowerer.fmt(expected)}' slot (a value narrowed or asserted past the type still held it)`, expected, loc);
|
|
11598
|
+
result =
|
|
11599
|
+
result === null
|
|
11600
|
+
? branch
|
|
11601
|
+
: {
|
|
11602
|
+
kind: "ternary",
|
|
11603
|
+
cond: {
|
|
11604
|
+
kind: "unionIsTag",
|
|
11605
|
+
unionId,
|
|
11606
|
+
tag,
|
|
11607
|
+
negated: false,
|
|
11608
|
+
value: ref(),
|
|
11609
|
+
type: BOOL,
|
|
11610
|
+
loc,
|
|
11611
|
+
},
|
|
11612
|
+
then: branch,
|
|
11613
|
+
else_: result,
|
|
11614
|
+
type: expected,
|
|
11615
|
+
loc,
|
|
11616
|
+
};
|
|
11617
|
+
}
|
|
11618
|
+
return {
|
|
11619
|
+
kind: "seqExpr",
|
|
11620
|
+
stmts: [{ kind: "varDecl", localId: local.id, init: expr, loc }],
|
|
11621
|
+
result: result,
|
|
11622
|
+
type: expected,
|
|
11623
|
+
loc,
|
|
11624
|
+
};
|
|
11625
|
+
}
|
|
11626
|
+
/** A callback passed to a generic call without a return annotation, whose
|
|
11627
|
+
* returns the checker unified into a narrower result type: `trace(name,
|
|
11628
|
+
* async () => (cond ? items : items.map((i) => ({ ...i, sum }))))` infers
|
|
11629
|
+
* `T` from the narrower `Item[]`, though at run time the extended objects
|
|
11630
|
+
* keep `sum`. Converting such a return into the inferred type copies the
|
|
11631
|
+
* records and drops the members the narrower type lacks, which Node keeps
|
|
11632
|
+
* and any later wider view (`Promise<ItemWithSum[]>`) reads back. Refuse
|
|
11633
|
+
* that conversion by name rather than lose the members silently; an
|
|
11634
|
+
* annotation on the callback's return type or on the call's type argument
|
|
11635
|
+
* names a type that keeps them. */
|
|
11636
|
+
function refuseInferredCallbackDrops(lowerer, node, actual, expected) {
|
|
11637
|
+
if (typeEquals(actual, expected))
|
|
11638
|
+
return;
|
|
11639
|
+
const structured = (t) => t.kind === "record" || t.kind === "array" || t.kind === "promise";
|
|
11640
|
+
if (!structured(actual) || !structured(expected))
|
|
11641
|
+
return;
|
|
11642
|
+
let site = node;
|
|
11643
|
+
while (yieldsOperand(site))
|
|
11644
|
+
site = site.parent;
|
|
11645
|
+
let fn;
|
|
11646
|
+
if (ts.isReturnStatement(site.parent) && site.parent.expression === site) {
|
|
11647
|
+
fn = site.parent.parent;
|
|
11648
|
+
while (fn && !ts.isFunctionLike(fn))
|
|
11649
|
+
fn = fn.parent;
|
|
11650
|
+
}
|
|
11651
|
+
else if (ts.isArrowFunction(site.parent) && site.parent.body === site) {
|
|
11652
|
+
fn = site.parent;
|
|
11653
|
+
}
|
|
11654
|
+
if (!fn || !(ts.isArrowFunction(fn) || ts.isFunctionExpression(fn)) || fn.type)
|
|
11655
|
+
return;
|
|
11656
|
+
let arg = fn;
|
|
11657
|
+
while (ts.isParenthesizedExpression(arg.parent))
|
|
11658
|
+
arg = arg.parent;
|
|
11659
|
+
const call = arg.parent;
|
|
11660
|
+
if (!(ts.isCallExpression(call) || ts.isNewExpression(call)))
|
|
11661
|
+
return;
|
|
11662
|
+
if (!call.arguments?.nodes.includes(arg))
|
|
11663
|
+
return;
|
|
11664
|
+
const dropped = droppedMembers(lowerer, actual, expected, new Set());
|
|
11665
|
+
if (dropped.length === 0)
|
|
11666
|
+
return;
|
|
11667
|
+
lowerer.unsupported("SC1090", node, `returning '${lowerer.fmt(actual)}' from a callback whose result the checker infers as the narrower '${lowerer.fmt(expected)}' (the conversion would drop ${dropped.map((d) => `'${d}'`).join(", ")}, which the object keeps at run time — annotate the callback's return type or the call's type argument with a type that declares them)`);
|
|
11668
|
+
}
|
|
11669
|
+
/** True when the value of `node`'s parent can be `node`'s own value:
|
|
11670
|
+
* parentheses, `await`, `satisfies`, a non-null assertion, a conditional's
|
|
11671
|
+
* branch, either operand of `??`, `||` and `&&`, and the right operand of a
|
|
11672
|
+
* comma. */
|
|
11673
|
+
function yieldsOperand(node) {
|
|
11674
|
+
const p = node.parent;
|
|
11675
|
+
if (p === undefined)
|
|
11676
|
+
return false;
|
|
11677
|
+
if (ts.isParenthesizedExpression(p) ||
|
|
11678
|
+
ts.isAwaitExpression(p) ||
|
|
11679
|
+
ts.isSatisfiesExpression(p) ||
|
|
11680
|
+
ts.isNonNullExpression(p))
|
|
11681
|
+
return true;
|
|
11682
|
+
if (ts.isConditionalExpression(p))
|
|
11683
|
+
return p.whenTrue === node || p.whenFalse === node;
|
|
11684
|
+
if (ts.isBinaryExpression(p)) {
|
|
11685
|
+
const op = p.operatorToken.kind;
|
|
11686
|
+
if (op === ts.SyntaxKind.QuestionQuestionToken ||
|
|
11687
|
+
op === ts.SyntaxKind.BarBarToken ||
|
|
11688
|
+
op === ts.SyntaxKind.AmpersandAmpersandToken)
|
|
11689
|
+
return true;
|
|
11690
|
+
return op === ts.SyntaxKind.CommaToken && p.right === node;
|
|
11691
|
+
}
|
|
11692
|
+
return false;
|
|
11693
|
+
}
|
|
11694
|
+
/** Member names a structural conversion from `from` into `to` drops:
|
|
11695
|
+
* declared fields of a source record the target record lacks, through
|
|
11696
|
+
* array elements and promise payloads. */
|
|
11697
|
+
function droppedMembers(lowerer, from, to, seen) {
|
|
11698
|
+
if (typeEquals(from, to))
|
|
11699
|
+
return [];
|
|
11700
|
+
if (from.kind === "array" && to.kind === "array")
|
|
11701
|
+
return droppedMembers(lowerer, from.elem, to.elem, seen);
|
|
11702
|
+
if (from.kind === "promise" && to.kind === "promise")
|
|
11703
|
+
return droppedMembers(lowerer, from.inner, to.inner, seen);
|
|
11704
|
+
if (from.kind !== "record" || to.kind !== "record")
|
|
11705
|
+
return [];
|
|
11706
|
+
const key = `${from.shapeId}>${to.shapeId}`;
|
|
11707
|
+
if (seen.has(key))
|
|
11708
|
+
return [];
|
|
11709
|
+
seen.add(key);
|
|
11710
|
+
const source = lowerer.shapes.get(from.shapeId);
|
|
11711
|
+
const target = lowerer.shapes.get(to.shapeId);
|
|
11712
|
+
if (!source || !target || source.tuple || target.tuple || target.indexValue)
|
|
11713
|
+
return [];
|
|
11714
|
+
const out = [];
|
|
11715
|
+
for (const f of source.fields) {
|
|
11716
|
+
if (f.name.startsWith("%"))
|
|
11717
|
+
continue;
|
|
11718
|
+
const t = target.fields.find((x) => x.name === f.name);
|
|
11719
|
+
if (!t)
|
|
11720
|
+
out.push(f.name);
|
|
11721
|
+
else
|
|
11722
|
+
out.push(...droppedMembers(lowerer, f.type, t.type, seen).map((n) => `${f.name}.${n}`));
|
|
11723
|
+
}
|
|
11724
|
+
return out;
|
|
11725
|
+
}
|
|
10113
11726
|
//# sourceMappingURL=lowerer.js.map
|