@scriptc/compiler 0.3.6 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ambient/scriptc-node-fallback.d.ts +682 -50
- package/ambient/scriptc.d.ts +134 -0
- package/dist/backend/cycle-analysis.d.ts +1 -1
- package/dist/backend/cycle-analysis.js +1 -0
- package/dist/backend/cycle-analysis.js.map +1 -1
- package/dist/backend/cycle-analysis.test.js +13 -1
- package/dist/backend/cycle-analysis.test.js.map +1 -1
- package/dist/backend/cycle-mutability.js +16 -5
- package/dist/backend/cycle-mutability.js.map +1 -1
- package/dist/backend/executable-features.js +13 -0
- package/dist/backend/executable-features.js.map +1 -1
- package/dist/backend/immutability.test.js +1 -1
- package/dist/backend/library-pack.js +6 -0
- package/dist/backend/library-pack.js.map +1 -1
- package/dist/backend/llvm/alloc.d.ts +41 -4
- package/dist/backend/llvm/alloc.js +138 -7
- package/dist/backend/llvm/alloc.js.map +1 -1
- package/dist/backend/llvm/alloc.test.js +30 -1
- package/dist/backend/llvm/alloc.test.js.map +1 -1
- package/dist/backend/llvm/appended-array-literals.test.js +1 -1
- package/dist/backend/llvm/array-search.test.js +1 -1
- package/dist/backend/llvm/blocks.d.ts +8 -0
- package/dist/backend/llvm/blocks.js +43 -1
- package/dist/backend/llvm/blocks.js.map +1 -1
- package/dist/backend/llvm/blocks.test.js +22 -1
- package/dist/backend/llvm/blocks.test.js.map +1 -1
- package/dist/backend/llvm/byte-numbers.js +15 -5
- package/dist/backend/llvm/byte-numbers.js.map +1 -1
- package/dist/backend/llvm/bytes-alias.d.ts +14 -0
- package/dist/backend/llvm/bytes-alias.js +20 -0
- package/dist/backend/llvm/bytes-alias.js.map +1 -0
- package/dist/backend/llvm/bytes-loop-versions.d.ts +86 -0
- package/dist/backend/llvm/bytes-loop-versions.js +506 -0
- package/dist/backend/llvm/bytes-loop-versions.js.map +1 -0
- package/dist/backend/llvm/bytes-loop-versions.test.d.ts +1 -0
- package/dist/backend/llvm/bytes-loop-versions.test.js +244 -0
- package/dist/backend/llvm/bytes-loop-versions.test.js.map +1 -0
- package/dist/backend/llvm/call-lifetimes.js +50 -1
- package/dist/backend/llvm/call-lifetimes.js.map +1 -1
- package/dist/backend/llvm/call-lifetimes.test.js +34 -0
- package/dist/backend/llvm/call-lifetimes.test.js.map +1 -1
- package/dist/backend/llvm/checked-narrows.test.js +1 -1
- package/dist/backend/llvm/checked-value-lifetimes.js +4 -1
- package/dist/backend/llvm/checked-value-lifetimes.js.map +1 -1
- package/dist/backend/llvm/classes.d.ts +11 -0
- package/dist/backend/llvm/classes.js +71 -14
- package/dist/backend/llvm/classes.js.map +1 -1
- package/dist/backend/llvm/classes.test.js +58 -8
- package/dist/backend/llvm/classes.test.js.map +1 -1
- package/dist/backend/llvm/common.js +1 -0
- package/dist/backend/llvm/common.js.map +1 -1
- package/dist/backend/llvm/constant-callbacks.d.ts +5 -1
- package/dist/backend/llvm/constant-callbacks.js +55 -12
- package/dist/backend/llvm/constant-callbacks.js.map +1 -1
- package/dist/backend/llvm/constant-callbacks.test.js +88 -1
- package/dist/backend/llvm/constant-callbacks.test.js.map +1 -1
- package/dist/backend/llvm/counted-loops.d.ts +4 -0
- package/dist/backend/llvm/counted-loops.js +37 -0
- package/dist/backend/llvm/counted-loops.js.map +1 -1
- package/dist/backend/llvm/dense-array-access.d.ts +12 -3
- package/dist/backend/llvm/dense-array-access.js +72 -14
- package/dist/backend/llvm/dense-array-access.js.map +1 -1
- package/dist/backend/llvm/dense-array-access.test.js +59 -3
- package/dist/backend/llvm/dense-array-access.test.js.map +1 -1
- package/dist/backend/llvm/dense-array-loops.d.ts +51 -0
- package/dist/backend/llvm/dense-array-loops.js +162 -0
- package/dist/backend/llvm/dense-array-loops.js.map +1 -0
- package/dist/backend/llvm/dense-array-loops.test.d.ts +1 -0
- package/dist/backend/llvm/dense-array-loops.test.js +128 -0
- package/dist/backend/llvm/dense-array-loops.test.js.map +1 -0
- package/dist/backend/llvm/dyn-handle-tags.test.d.ts +1 -0
- package/dist/backend/llvm/dyn-handle-tags.test.js +38 -0
- package/dist/backend/llvm/dyn-handle-tags.test.js.map +1 -0
- package/dist/backend/llvm/dyn.d.ts +28 -4
- package/dist/backend/llvm/dyn.js +293 -178
- package/dist/backend/llvm/dyn.js.map +1 -1
- package/dist/backend/llvm/emit-function.d.ts +64 -0
- package/dist/backend/llvm/emit-function.js +1190 -0
- package/dist/backend/llvm/emit-function.js.map +1 -0
- package/dist/backend/llvm/emit-module.d.ts +24 -0
- package/dist/backend/llvm/emit-module.js +1535 -0
- package/dist/backend/llvm/emit-module.js.map +1 -0
- package/dist/backend/llvm/emit-statements.d.ts +58 -0
- package/dist/backend/llvm/emit-statements.js +1964 -0
- package/dist/backend/llvm/emit-statements.js.map +1 -0
- package/dist/backend/llvm/emitter.d.ts +547 -283
- package/dist/backend/llvm/emitter.js +689 -4643
- package/dist/backend/llvm/emitter.js.map +1 -1
- package/dist/backend/llvm/emitter.test.js +57 -3
- package/dist/backend/llvm/emitter.test.js.map +1 -1
- package/dist/backend/llvm/expr-async.js +73 -46
- package/dist/backend/llvm/expr-async.js.map +1 -1
- package/dist/backend/llvm/expr-async.test.js +1 -1
- package/dist/backend/llvm/expr-bytes.d.ts +2 -0
- package/dist/backend/llvm/expr-bytes.js +76 -29
- package/dist/backend/llvm/expr-bytes.js.map +1 -1
- package/dist/backend/llvm/expr-callbacks.d.ts +6 -2
- package/dist/backend/llvm/expr-callbacks.js +48 -11
- package/dist/backend/llvm/expr-callbacks.js.map +1 -1
- package/dist/backend/llvm/expr-calls.d.ts +1 -1
- package/dist/backend/llvm/expr-calls.js +71 -53
- package/dist/backend/llvm/expr-calls.js.map +1 -1
- package/dist/backend/llvm/expr-calls.test.js +1 -1
- package/dist/backend/llvm/expr-containers.js +39 -15
- package/dist/backend/llvm/expr-containers.js.map +1 -1
- package/dist/backend/llvm/expr-control.js +16 -16
- package/dist/backend/llvm/expr-control.js.map +1 -1
- package/dist/backend/llvm/expr-dynamic.d.ts +3 -0
- package/dist/backend/llvm/expr-dynamic.js +67 -62
- package/dist/backend/llvm/expr-dynamic.js.map +1 -1
- package/dist/backend/llvm/expr-primitives.js +121 -25
- package/dist/backend/llvm/expr-primitives.js.map +1 -1
- package/dist/backend/llvm/expr-primitives.test.js +2 -2
- package/dist/backend/llvm/expr-records.d.ts +1 -1
- package/dist/backend/llvm/expr-records.js +32 -11
- package/dist/backend/llvm/expr-records.js.map +1 -1
- package/dist/backend/llvm/expr-stream-bridges.js +54 -12
- package/dist/backend/llvm/expr-stream-bridges.js.map +1 -1
- package/dist/backend/llvm/expr-stream-bridges.test.js +2 -2
- package/dist/backend/llvm/expr-stream-callbacks.js +22 -1
- package/dist/backend/llvm/expr-stream-callbacks.js.map +1 -1
- package/dist/backend/llvm/int32-abi.test.js +2 -2
- package/dist/backend/llvm/integer-clones.test.js +3 -3
- package/dist/backend/llvm/integer-remainder.d.ts +34 -13
- package/dist/backend/llvm/integer-remainder.js +156 -22
- package/dist/backend/llvm/integer-remainder.js.map +1 -1
- package/dist/backend/llvm/intern-tables.test.js +1 -1
- package/dist/backend/llvm/jsval-encoding.d.ts +21 -0
- package/dist/backend/llvm/jsval-encoding.js +20 -0
- package/dist/backend/llvm/jsval-encoding.js.map +1 -0
- package/dist/backend/llvm/jsval.d.ts +12 -0
- package/dist/backend/llvm/jsval.js +488 -0
- package/dist/backend/llvm/jsval.js.map +1 -0
- package/dist/backend/llvm/lazy-captures.d.ts +12 -2
- package/dist/backend/llvm/lazy-captures.js +39 -17
- package/dist/backend/llvm/lazy-captures.js.map +1 -1
- package/dist/backend/llvm/lib-abi.js +1 -1
- package/dist/backend/llvm/lib-abi.js.map +1 -1
- package/dist/backend/llvm/lib-connect.js +1 -1
- package/dist/backend/llvm/lib-connect.js.map +1 -1
- package/dist/backend/llvm/lib-datagram.js +14 -8
- package/dist/backend/llvm/lib-datagram.js.map +1 -1
- package/dist/backend/llvm/lib-dispatch.js +189 -23
- package/dist/backend/llvm/lib-dispatch.js.map +1 -1
- package/dist/backend/llvm/lib-filesystem.js +42 -13
- package/dist/backend/llvm/lib-filesystem.js.map +1 -1
- package/dist/backend/llvm/lib-http2.js +3 -3
- package/dist/backend/llvm/lib-http2.js.map +1 -1
- package/dist/backend/llvm/lib-lookup.js +2 -2
- package/dist/backend/llvm/lib-lookup.js.map +1 -1
- package/dist/backend/llvm/lib-network.js +56 -22
- package/dist/backend/llvm/lib-network.js.map +1 -1
- package/dist/backend/llvm/lib-process.js +90 -50
- package/dist/backend/llvm/lib-process.js.map +1 -1
- package/dist/backend/llvm/lib-shared.d.ts +12 -0
- package/dist/backend/llvm/lib-shared.js +187 -6
- package/dist/backend/llvm/lib-shared.js.map +1 -1
- package/dist/backend/llvm/lib-stream.js +46 -16
- package/dist/backend/llvm/lib-stream.js.map +1 -1
- package/dist/backend/llvm/lib-test.js +43 -7
- package/dist/backend/llvm/lib-test.js.map +1 -1
- package/dist/backend/llvm/lib-tls.js +4 -9
- package/dist/backend/llvm/lib-tls.js.map +1 -1
- package/dist/backend/llvm/local-array-reads.js +2 -2
- package/dist/backend/llvm/local-array-reads.test.js +1 -1
- package/dist/backend/llvm/local-extents.d.ts +19 -0
- package/dist/backend/llvm/local-extents.js +169 -0
- package/dist/backend/llvm/local-extents.js.map +1 -0
- package/dist/backend/llvm/local-extents.test.d.ts +1 -0
- package/dist/backend/llvm/local-extents.test.js +92 -0
- package/dist/backend/llvm/local-extents.test.js.map +1 -0
- package/dist/backend/llvm/local-union-storage.js +7 -7
- package/dist/backend/llvm/local-union-storage.js.map +1 -1
- package/dist/backend/llvm/local-union-storage.test.js +2 -2
- package/dist/backend/llvm/map-entry-fusion.test.js +1 -1
- package/dist/backend/llvm/map-number-lookup.js +2 -2
- package/dist/backend/llvm/map-number-lookup.test.js +2 -2
- package/dist/backend/llvm/map-read-lifetimes.test.js +2 -2
- package/dist/backend/llvm/narrow-guards.d.ts +38 -0
- package/dist/backend/llvm/narrow-guards.js +151 -0
- package/dist/backend/llvm/narrow-guards.js.map +1 -0
- package/dist/backend/llvm/nullable-unions.d.ts +64 -6
- package/dist/backend/llvm/nullable-unions.js +103 -6
- package/dist/backend/llvm/nullable-unions.js.map +1 -1
- package/dist/backend/llvm/nullable-unions.test.d.ts +1 -0
- package/dist/backend/llvm/nullable-unions.test.js +65 -0
- package/dist/backend/llvm/nullable-unions.test.js.map +1 -0
- package/dist/backend/llvm/publish.d.ts +4 -0
- package/dist/backend/llvm/publish.js +14 -2
- package/dist/backend/llvm/publish.js.map +1 -1
- package/dist/backend/llvm/publish.test.js +1 -1
- package/dist/backend/llvm/receivers.d.ts +31 -0
- package/dist/backend/llvm/receivers.js +395 -0
- package/dist/backend/llvm/receivers.js.map +1 -0
- package/dist/backend/llvm/record-results.d.ts +12 -1
- package/dist/backend/llvm/record-results.js +64 -4
- package/dist/backend/llvm/record-results.js.map +1 -1
- package/dist/backend/llvm/reference-effects.js +9 -0
- package/dist/backend/llvm/reference-effects.js.map +1 -1
- package/dist/backend/llvm/reference-writes.d.ts +4 -0
- package/dist/backend/llvm/reference-writes.js +142 -6
- package/dist/backend/llvm/reference-writes.js.map +1 -1
- package/dist/backend/llvm/reference-writes.test.d.ts +1 -0
- package/dist/backend/llvm/reference-writes.test.js +88 -0
- package/dist/backend/llvm/reference-writes.test.js.map +1 -0
- package/dist/backend/llvm/regex-matchers.d.ts +8 -0
- package/dist/backend/llvm/regex-matchers.js +33 -0
- package/dist/backend/llvm/regex-matchers.js.map +1 -1
- package/dist/backend/llvm/regex-matchers.test.js +23 -1
- package/dist/backend/llvm/regex-matchers.test.js.map +1 -1
- package/dist/backend/llvm/regions.d.ts +1 -1
- package/dist/backend/llvm/regions.js +9 -6
- package/dist/backend/llvm/regions.js.map +1 -1
- package/dist/backend/llvm/regions.test.js +1 -1
- package/dist/backend/llvm/shapes.d.ts +66 -43
- package/dist/backend/llvm/shapes.js +280 -21
- package/dist/backend/llvm/shapes.js.map +1 -1
- package/dist/backend/llvm/shapes.test.js +37 -3
- package/dist/backend/llvm/shapes.test.js.map +1 -1
- package/dist/backend/llvm/split-loops.js +2 -2
- package/dist/backend/llvm/split-loops.js.map +1 -1
- package/dist/backend/llvm/stack-objects.d.ts +26 -6
- package/dist/backend/llvm/stack-objects.js +133 -10
- package/dist/backend/llvm/stack-objects.js.map +1 -1
- package/dist/backend/llvm/stack-objects.test.js +55 -1
- package/dist/backend/llvm/stack-objects.test.js.map +1 -1
- package/dist/backend/llvm/stack-unions.test.js +1 -1
- package/dist/backend/llvm/string-construction.test.js +1 -1
- package/dist/backend/llvm/string-lifetimes.test.js +15 -14
- package/dist/backend/llvm/string-lifetimes.test.js.map +1 -1
- package/dist/backend/llvm/string-slices.d.ts +25 -0
- package/dist/backend/llvm/string-slices.js +207 -1
- package/dist/backend/llvm/string-slices.js.map +1 -1
- package/dist/backend/llvm/string-slices.test.js +139 -2
- package/dist/backend/llvm/string-slices.test.js.map +1 -1
- package/dist/backend/llvm/switch-dispatch.test.js +2 -2
- package/dist/backend/llvm/thread-slots.d.ts +5 -0
- package/dist/backend/llvm/thread-slots.js +142 -0
- package/dist/backend/llvm/thread-slots.js.map +1 -0
- package/dist/backend/llvm/thread-slots.test.d.ts +1 -0
- package/dist/backend/llvm/thread-slots.test.js +110 -0
- package/dist/backend/llvm/thread-slots.test.js.map +1 -0
- package/dist/backend/llvm/union-repr.d.ts +7 -7
- package/dist/backend/llvm/union-repr.js +18 -2
- package/dist/backend/llvm/union-repr.js.map +1 -1
- package/dist/backend/llvm/union-retype.test.js +17 -3
- package/dist/backend/llvm/union-retype.test.js.map +1 -1
- package/dist/backend/llvm/walkers.d.ts +2 -2
- package/dist/backend/llvm/walkers.js +51 -26
- package/dist/backend/llvm/walkers.js.map +1 -1
- package/dist/backend/llvm/wasm-modules.d.ts +16 -0
- package/dist/backend/llvm/wasm-modules.js +66 -0
- package/dist/backend/llvm/wasm-modules.js.map +1 -0
- package/dist/backend/llvm/wrapping-sums.d.ts +7 -0
- package/dist/backend/llvm/wrapping-sums.js +11 -3
- package/dist/backend/llvm/wrapping-sums.js.map +1 -1
- package/dist/backend/mangle.d.ts +7 -0
- package/dist/backend/mangle.js +11 -0
- package/dist/backend/mangle.js.map +1 -1
- package/dist/backend/may-throw.d.ts +3 -0
- package/dist/backend/may-throw.js +4 -2
- package/dist/backend/may-throw.js.map +1 -1
- package/dist/backend/may-throw.test.js +1 -1
- package/dist/backend/native/contracts.d.ts +37 -0
- package/dist/backend/native/executable.js +192 -137
- package/dist/backend/native/executable.js.map +1 -1
- package/dist/backend/native/library.js +1 -0
- package/dist/backend/native/library.js.map +1 -1
- package/dist/backend/native/runtime-inputs.d.ts +1 -1
- package/dist/backend/native/runtime-inputs.js +1 -0
- package/dist/backend/native/runtime-inputs.js.map +1 -1
- package/dist/backend/native-link-info-core.d.ts +30 -0
- package/dist/backend/native-link-info-core.js.map +1 -1
- package/dist/backend/publication.test.js +1 -1
- package/dist/backend/runtime-pack-core.d.ts +9 -1
- package/dist/backend/runtime-pack-core.js +10 -1
- package/dist/backend/runtime-pack-core.js.map +1 -1
- package/dist/backend/runtime-pack-native.js +1 -1
- package/dist/backend/runtime-pack-native.js.map +1 -1
- package/dist/backend/runtime-pack-native.test.d.ts +1 -0
- package/dist/backend/runtime-pack-native.test.js +31 -0
- package/dist/backend/runtime-pack-native.test.js.map +1 -0
- package/dist/backend/runtime-pack-targets.test.js +5 -0
- package/dist/backend/runtime-pack-targets.test.js.map +1 -1
- package/dist/backend/runtime-pack.test.js +5 -0
- package/dist/backend/runtime-pack.test.js.map +1 -1
- package/dist/backend/stack-observations.d.ts +22 -0
- package/dist/backend/stack-observations.js +382 -0
- package/dist/backend/stack-observations.js.map +1 -0
- package/dist/backend/stack-observations.test.d.ts +1 -0
- package/dist/backend/stack-observations.test.js +233 -0
- package/dist/backend/stack-observations.test.js.map +1 -0
- package/dist/backend/target-diagnostics.js +8 -0
- package/dist/backend/target-diagnostics.js.map +1 -1
- package/dist/backend/target-diagnostics.test.js +1 -1
- package/dist/backend/warm-cache.js +5 -0
- package/dist/backend/warm-cache.js.map +1 -1
- package/dist/backend/young-nursery.d.ts +7 -0
- package/dist/backend/young-nursery.js +10 -0
- package/dist/backend/young-nursery.js.map +1 -0
- package/dist/cli/command.js +44 -4
- package/dist/cli/command.js.map +1 -1
- package/dist/cli/usage.d.ts +11 -1
- package/dist/cli/usage.js +20 -1
- package/dist/cli/usage.js.map +1 -1
- package/dist/compat/fetch-profile.js +10 -1
- package/dist/compat/fetch-profile.js.map +1 -1
- package/dist/compile-types.d.ts +13 -0
- package/dist/contracts/check.js +24 -6
- package/dist/contracts/check.js.map +1 -1
- package/dist/contracts/int32-elements.d.ts +115 -0
- package/dist/contracts/int32-elements.js +1179 -0
- package/dist/contracts/int32-elements.js.map +1 -0
- package/dist/coverage/report.d.ts +16 -0
- package/dist/coverage/report.js +182 -1
- package/dist/coverage/report.js.map +1 -1
- package/dist/coverage/surface-manifest.js +16 -3
- package/dist/coverage/surface-manifest.js.map +1 -1
- package/dist/coverage/verdict-cache.d.ts +2 -0
- package/dist/coverage/verdict-cache.js +12 -0
- package/dist/coverage/verdict-cache.js.map +1 -1
- package/dist/coverage/verdict-cache.test.js +2 -1
- package/dist/coverage/verdict-cache.test.js.map +1 -1
- package/dist/diagnostics/diagnostic.d.ts +10 -6
- package/dist/diagnostics/diagnostic.js +29 -21
- package/dist/diagnostics/diagnostic.js.map +1 -1
- package/dist/diagnostics/envelope.d.ts +39 -2
- package/dist/diagnostics/envelope.js.map +1 -1
- package/dist/diagnostics/render.d.ts +7 -0
- package/dist/diagnostics/render.js +50 -13
- package/dist/diagnostics/render.js.map +1 -1
- package/dist/diagnostics/render.test.d.ts +1 -0
- package/dist/diagnostics/render.test.js +49 -0
- package/dist/diagnostics/render.test.js.map +1 -0
- package/dist/executable/executable-cache.d.ts +17 -0
- package/dist/executable/executable-cache.js +13 -1
- package/dist/executable/executable-cache.js.map +1 -1
- package/dist/executable/executable-cache.test.js +7 -1
- package/dist/executable/executable-cache.test.js.map +1 -1
- package/dist/executable/prepare.js +2 -1
- package/dist/executable/prepare.js.map +1 -1
- package/dist/frontend/analysis.js +6 -1
- package/dist/frontend/analysis.js.map +1 -1
- package/dist/frontend/builtin-modules.d.ts +16 -2
- package/dist/frontend/builtin-modules.js +40 -7
- package/dist/frontend/builtin-modules.js.map +1 -1
- package/dist/frontend/cjs-syntax.js +52 -51
- package/dist/frontend/cjs-syntax.js.map +1 -1
- package/dist/frontend/contract-types.d.ts +3 -0
- package/dist/frontend/contract-types.js +36 -7
- package/dist/frontend/contract-types.js.map +1 -1
- package/dist/frontend/experimental-import.d.ts +5 -1
- package/dist/frontend/experimental-import.js +26 -7
- package/dist/frontend/experimental-import.js.map +1 -1
- package/dist/frontend/fork-target.js +20 -22
- package/dist/frontend/fork-target.js.map +1 -1
- package/dist/frontend/fork-target.test.js +2 -1
- package/dist/frontend/fork-target.test.js.map +1 -1
- package/dist/frontend/function-completion.js +6 -6
- package/dist/frontend/function-completion.js.map +1 -1
- package/dist/frontend/helper-tokens.js +15 -3
- package/dist/frontend/helper-tokens.js.map +1 -1
- package/dist/frontend/helper-tokens.test.js +7 -1
- package/dist/frontend/helper-tokens.test.js.map +1 -1
- package/dist/frontend/inferred-js-diagnostics.js +14 -17
- package/dist/frontend/inferred-js-diagnostics.js.map +1 -1
- package/dist/frontend/input-tracker.d.ts +3 -0
- package/dist/frontend/input-tracker.js +32 -3
- package/dist/frontend/input-tracker.js.map +1 -1
- package/dist/frontend/lib-contract.js +36 -32
- package/dist/frontend/lib-contract.js.map +1 -1
- package/dist/frontend/lib-exports.js +3 -3
- package/dist/frontend/lib-exports.js.map +1 -1
- package/dist/frontend/lowering/array-values.d.ts +8 -3
- package/dist/frontend/lowering/array-values.js +60 -11
- package/dist/frontend/lowering/array-values.js.map +1 -1
- package/dist/frontend/lowering/assert-instances.js +4 -4
- package/dist/frontend/lowering/assert-instances.js.map +1 -1
- package/dist/frontend/lowering/assertion-identity.d.ts +12 -0
- package/dist/frontend/lowering/assertion-identity.js +70 -0
- package/dist/frontend/lowering/assertion-identity.js.map +1 -0
- package/dist/frontend/lowering/assertion-members.d.ts +28 -0
- package/dist/frontend/lowering/assertion-members.js +185 -0
- package/dist/frontend/lowering/assertion-members.js.map +1 -0
- package/dist/frontend/lowering/binding-analysis.js +27 -20
- package/dist/frontend/lowering/binding-analysis.js.map +1 -1
- package/dist/frontend/lowering/builtin-calls.js +63 -5
- package/dist/frontend/lowering/builtin-calls.js.map +1 -1
- package/dist/frontend/lowering/builtin-function-fences.d.ts +14 -0
- package/dist/frontend/lowering/builtin-function-fences.js +42 -0
- package/dist/frontend/lowering/builtin-function-fences.js.map +1 -0
- package/dist/frontend/lowering/builtins/arguments.js +1 -1
- package/dist/frontend/lowering/builtins/arguments.js.map +1 -1
- package/dist/frontend/lowering/builtins/async-context.js +53 -52
- package/dist/frontend/lowering/builtins/async-context.js.map +1 -1
- package/dist/frontend/lowering/builtins/atomics.js +6 -6
- package/dist/frontend/lowering/builtins/atomics.js.map +1 -1
- package/dist/frontend/lowering/builtins/blob.js +8 -6
- package/dist/frontend/lowering/builtins/blob.js.map +1 -1
- package/dist/frontend/lowering/builtins/builtin-class-dyn.d.ts +23 -0
- package/dist/frontend/lowering/builtins/builtin-class-dyn.js +156 -0
- package/dist/frontend/lowering/builtins/builtin-class-dyn.js.map +1 -0
- package/dist/frontend/lowering/builtins/callable-aliases.js +16 -5
- package/dist/frontend/lowering/builtins/callable-aliases.js.map +1 -1
- package/dist/frontend/lowering/builtins/child-process-async.js +7 -7
- package/dist/frontend/lowering/builtins/child-process-async.js.map +1 -1
- package/dist/frontend/lowering/builtins/child-process-methods.d.ts +6 -4
- package/dist/frontend/lowering/builtins/child-process-methods.js +310 -57
- package/dist/frontend/lowering/builtins/child-process-methods.js.map +1 -1
- package/dist/frontend/lowering/builtins/child-process-sync.js +16 -10
- package/dist/frontend/lowering/builtins/child-process-sync.js.map +1 -1
- package/dist/frontend/lowering/builtins/child-process.d.ts +6 -4
- package/dist/frontend/lowering/builtins/child-process.js +85 -61
- package/dist/frontend/lowering/builtins/child-process.js.map +1 -1
- package/dist/frontend/lowering/builtins/class-values.d.ts +60 -0
- package/dist/frontend/lowering/builtins/class-values.js +226 -0
- package/dist/frontend/lowering/builtins/class-values.js.map +1 -0
- package/dist/frontend/lowering/builtins/compression.d.ts +9 -0
- package/dist/frontend/lowering/builtins/compression.js +107 -44
- package/dist/frontend/lowering/builtins/compression.js.map +1 -1
- package/dist/frontend/lowering/builtins/constants.d.ts +9 -1
- package/dist/frontend/lowering/builtins/constants.js +28 -7
- package/dist/frontend/lowering/builtins/constants.js.map +1 -1
- package/dist/frontend/lowering/builtins/crypto.d.ts +19 -0
- package/dist/frontend/lowering/builtins/crypto.js +211 -37
- package/dist/frontend/lowering/builtins/crypto.js.map +1 -1
- package/dist/frontend/lowering/builtins/dates.d.ts +7 -1
- package/dist/frontend/lowering/builtins/dates.js +92 -16
- package/dist/frontend/lowering/builtins/dates.js.map +1 -1
- package/dist/frontend/lowering/builtins/disposable-stack.d.ts +18 -0
- package/dist/frontend/lowering/builtins/disposable-stack.js +137 -0
- package/dist/frontend/lowering/builtins/disposable-stack.js.map +1 -0
- package/dist/frontend/lowering/builtins/environment.js +3 -3
- package/dist/frontend/lowering/builtins/environment.js.map +1 -1
- package/dist/frontend/lowering/builtins/errors.d.ts +14 -10
- package/dist/frontend/lowering/builtins/errors.js +169 -3
- package/dist/frontend/lowering/builtins/errors.js.map +1 -1
- package/dist/frontend/lowering/builtins/filesystem-calls.js +128 -116
- package/dist/frontend/lowering/builtins/filesystem-calls.js.map +1 -1
- package/dist/frontend/lowering/builtins/filesystem.js +77 -77
- package/dist/frontend/lowering/builtins/filesystem.js.map +1 -1
- package/dist/frontend/lowering/builtins/fs-glob.js +3 -3
- package/dist/frontend/lowering/builtins/fs-glob.js.map +1 -1
- package/dist/frontend/lowering/builtins/fs-streams.js +10 -11
- package/dist/frontend/lowering/builtins/fs-streams.js.map +1 -1
- package/dist/frontend/lowering/builtins/ipc.js +45 -8
- package/dist/frontend/lowering/builtins/ipc.js.map +1 -1
- package/dist/frontend/lowering/builtins/json.js +232 -24
- package/dist/frontend/lowering/builtins/json.js.map +1 -1
- package/dist/frontend/lowering/builtins/key-object.js +4 -4
- package/dist/frontend/lowering/builtins/key-object.js.map +1 -1
- package/dist/frontend/lowering/builtins/module-bindings.d.ts +8 -0
- package/dist/frontend/lowering/builtins/module-bindings.js +71 -22
- package/dist/frontend/lowering/builtins/module-bindings.js.map +1 -1
- package/dist/frontend/lowering/builtins/module-calls.js +55 -44
- package/dist/frontend/lowering/builtins/module-calls.js.map +1 -1
- package/dist/frontend/lowering/builtins/module-resolution.d.ts +4 -3
- package/dist/frontend/lowering/builtins/module-resolution.js +24 -23
- package/dist/frontend/lowering/builtins/module-resolution.js.map +1 -1
- package/dist/frontend/lowering/builtins/navigator.d.ts +13 -0
- package/dist/frontend/lowering/builtins/navigator.js +40 -0
- package/dist/frontend/lowering/builtins/navigator.js.map +1 -0
- package/dist/frontend/lowering/builtins/net-address.d.ts +19 -0
- package/dist/frontend/lowering/builtins/net-address.js +156 -0
- package/dist/frontend/lowering/builtins/net-address.js.map +1 -0
- package/dist/frontend/lowering/builtins/numbers.js +25 -9
- package/dist/frontend/lowering/builtins/numbers.js.map +1 -1
- package/dist/frontend/lowering/builtins/operating-system.d.ts +4 -0
- package/dist/frontend/lowering/builtins/operating-system.js +25 -12
- package/dist/frontend/lowering/builtins/operating-system.js.map +1 -1
- package/dist/frontend/lowering/builtins/performance.d.ts +12 -0
- package/dist/frontend/lowering/builtins/performance.js +259 -8
- package/dist/frontend/lowering/builtins/performance.js.map +1 -1
- package/dist/frontend/lowering/builtins/process.d.ts +32 -1
- package/dist/frontend/lowering/builtins/process.js +461 -99
- package/dist/frontend/lowering/builtins/process.js.map +1 -1
- package/dist/frontend/lowering/builtins/promises.d.ts +5 -1
- package/dist/frontend/lowering/builtins/promises.js +326 -43
- package/dist/frontend/lowering/builtins/promises.js.map +1 -1
- package/dist/frontend/lowering/builtins/promisify-callback.d.ts +37 -0
- package/dist/frontend/lowering/builtins/promisify-callback.js +320 -0
- package/dist/frontend/lowering/builtins/promisify-callback.js.map +1 -0
- package/dist/frontend/lowering/builtins/properties.js +37 -1
- package/dist/frontend/lowering/builtins/properties.js.map +1 -1
- package/dist/frontend/lowering/builtins/querystring.js +14 -14
- package/dist/frontend/lowering/builtins/querystring.js.map +1 -1
- package/dist/frontend/lowering/builtins/readline.d.ts +12 -2
- package/dist/frontend/lowering/builtins/readline.js +136 -39
- package/dist/frontend/lowering/builtins/readline.js.map +1 -1
- package/dist/frontend/lowering/builtins/receiver-types.js +3 -5
- package/dist/frontend/lowering/builtins/receiver-types.js.map +1 -1
- package/dist/frontend/lowering/builtins/reflection.js +16 -14
- package/dist/frontend/lowering/builtins/reflection.js.map +1 -1
- package/dist/frontend/lowering/builtins/runtime-constructor.d.ts +26 -0
- package/dist/frontend/lowering/builtins/runtime-constructor.js +165 -0
- package/dist/frontend/lowering/builtins/runtime-constructor.js.map +1 -0
- package/dist/frontend/lowering/builtins/strings.js +101 -12
- package/dist/frontend/lowering/builtins/strings.js.map +1 -1
- package/dist/frontend/lowering/builtins/text-codecs.js +41 -38
- package/dist/frontend/lowering/builtins/text-codecs.js.map +1 -1
- package/dist/frontend/lowering/builtins/timers.js +75 -30
- package/dist/frontend/lowering/builtins/timers.js.map +1 -1
- package/dist/frontend/lowering/builtins/url.d.ts +3 -0
- package/dist/frontend/lowering/builtins/url.js +120 -17
- package/dist/frontend/lowering/builtins/url.js.map +1 -1
- package/dist/frontend/lowering/builtins/util-types.js +20 -4
- package/dist/frontend/lowering/builtins/util-types.js.map +1 -1
- package/dist/frontend/lowering/builtins/v8.d.ts +11 -0
- package/dist/frontend/lowering/builtins/v8.js +105 -0
- package/dist/frontend/lowering/builtins/v8.js.map +1 -0
- package/dist/frontend/lowering/builtins/webassembly.d.ts +33 -0
- package/dist/frontend/lowering/builtins/webassembly.js +388 -0
- package/dist/frontend/lowering/builtins/webassembly.js.map +1 -0
- package/dist/frontend/lowering/builtins/webcrypto.d.ts +20 -0
- package/dist/frontend/lowering/builtins/webcrypto.js +112 -0
- package/dist/frontend/lowering/builtins/webcrypto.js.map +1 -0
- package/dist/frontend/lowering/builtins/workers.d.ts +12 -0
- package/dist/frontend/lowering/builtins/workers.js +193 -8
- package/dist/frontend/lowering/builtins/workers.js.map +1 -1
- package/dist/frontend/lowering/call-arguments.js +69 -14
- package/dist/frontend/lowering/call-arguments.js.map +1 -1
- package/dist/frontend/lowering/call-signatures.d.ts +19 -1
- package/dist/frontend/lowering/call-signatures.js +254 -47
- package/dist/frontend/lowering/call-signatures.js.map +1 -1
- package/dist/frontend/lowering/checked-promise-all.d.ts +3 -0
- package/dist/frontend/lowering/checked-promise-all.js +1 -1
- package/dist/frontend/lowering/checked-promise-all.js.map +1 -1
- package/dist/frontend/lowering/cjs-exports-object.d.ts +53 -0
- package/dist/frontend/lowering/cjs-exports-object.js +528 -0
- package/dist/frontend/lowering/cjs-exports-object.js.map +1 -0
- package/dist/frontend/lowering/cjs-inline-require.d.ts +86 -0
- package/dist/frontend/lowering/cjs-inline-require.js +314 -0
- package/dist/frontend/lowering/cjs-inline-require.js.map +1 -0
- package/dist/frontend/lowering/cjs-tsc-interop.d.ts +28 -0
- package/dist/frontend/lowering/cjs-tsc-interop.js +208 -0
- package/dist/frontend/lowering/cjs-tsc-interop.js.map +1 -0
- package/dist/frontend/lowering/class-attributes.d.ts +19 -0
- package/dist/frontend/lowering/class-attributes.js +378 -0
- package/dist/frontend/lowering/class-attributes.js.map +1 -0
- package/dist/frontend/lowering/class-callbacks.d.ts +3 -1
- package/dist/frontend/lowering/class-callbacks.js +21 -10
- package/dist/frontend/lowering/class-callbacks.js.map +1 -1
- package/dist/frontend/lowering/class-construction.js +49 -4
- package/dist/frontend/lowering/class-construction.js.map +1 -1
- package/dist/frontend/lowering/class-descriptors.d.ts +2 -0
- package/dist/frontend/lowering/class-descriptors.js +8 -8
- package/dist/frontend/lowering/class-descriptors.js.map +1 -1
- package/dist/frontend/lowering/class-dynamic-dispatch.d.ts +64 -0
- package/dist/frontend/lowering/class-dynamic-dispatch.js +1115 -89
- package/dist/frontend/lowering/class-dynamic-dispatch.js.map +1 -1
- package/dist/frontend/lowering/class-instance-constructor.js +1 -1
- package/dist/frontend/lowering/class-instance-constructor.js.map +1 -1
- package/dist/frontend/lowering/class-iterables.d.ts +11 -0
- package/dist/frontend/lowering/class-iterables.js +31 -0
- package/dist/frontend/lowering/class-iterables.js.map +1 -0
- package/dist/frontend/lowering/class-method-mutations.js +73 -35
- package/dist/frontend/lowering/class-method-mutations.js.map +1 -1
- package/dist/frontend/lowering/class-method-values.js +56 -10
- package/dist/frontend/lowering/class-method-values.js.map +1 -1
- package/dist/frontend/lowering/class-protocol-dispatch.js +24 -22
- package/dist/frontend/lowering/class-protocol-dispatch.js.map +1 -1
- package/dist/frontend/lowering/class-protocols.js +25 -44
- package/dist/frontend/lowering/class-protocols.js.map +1 -1
- package/dist/frontend/lowering/class-prototypes.d.ts +6 -0
- package/dist/frontend/lowering/class-prototypes.js +80 -18
- package/dist/frontend/lowering/class-prototypes.js.map +1 -1
- package/dist/frontend/lowering/class-runtime-statics.js +1 -1
- package/dist/frontend/lowering/class-runtime-statics.js.map +1 -1
- package/dist/frontend/lowering/class-static-data.js +2 -2
- package/dist/frontend/lowering/class-static-data.js.map +1 -1
- package/dist/frontend/lowering/class-to-primitive.d.ts +25 -0
- package/dist/frontend/lowering/class-to-primitive.js +261 -0
- package/dist/frontend/lowering/class-to-primitive.js.map +1 -0
- package/dist/frontend/lowering/class-unions.d.ts +25 -0
- package/dist/frontend/lowering/class-unions.js +102 -1
- package/dist/frontend/lowering/class-unions.js.map +1 -1
- package/dist/frontend/lowering/code-generation.d.ts +14 -0
- package/dist/frontend/lowering/code-generation.js +127 -0
- package/dist/frontend/lowering/code-generation.js.map +1 -0
- package/dist/frontend/lowering/coercions/function-adapters.d.ts +16 -2
- package/dist/frontend/lowering/coercions/function-adapters.js +145 -3
- package/dist/frontend/lowering/coercions/function-adapters.js.map +1 -1
- package/dist/frontend/lowering/coercions/structural-plans.js +25 -3
- package/dist/frontend/lowering/coercions/structural-plans.js.map +1 -1
- package/dist/frontend/lowering/coercions/structural.js +35 -3
- package/dist/frontend/lowering/coercions/structural.js.map +1 -1
- package/dist/frontend/lowering/coercions/unions.d.ts +15 -0
- package/dist/frontend/lowering/coercions/unions.js +57 -1
- package/dist/frontend/lowering/coercions/unions.js.map +1 -1
- package/dist/frontend/lowering/collection-ingestion.js +2 -2
- package/dist/frontend/lowering/collection-ingestion.js.map +1 -1
- package/dist/frontend/lowering/collection-narrowing.js +2 -4
- package/dist/frontend/lowering/collection-narrowing.js.map +1 -1
- package/dist/frontend/lowering/construction-escapes.js +8 -8
- package/dist/frontend/lowering/construction-escapes.js.map +1 -1
- package/dist/frontend/lowering/construction-escapes.test.js +4 -4
- package/dist/frontend/lowering/construction-escapes.test.js.map +1 -1
- package/dist/frontend/lowering/constructor-returns.d.ts +61 -0
- package/dist/frontend/lowering/constructor-returns.js +477 -0
- package/dist/frontend/lowering/constructor-returns.js.map +1 -0
- package/dist/frontend/lowering/containers/array-callback-call.js +1 -1
- package/dist/frontend/lowering/containers/array-callback-call.js.map +1 -1
- package/dist/frontend/lowering/containers/array-callbacks.d.ts +9 -0
- package/dist/frontend/lowering/containers/array-callbacks.js +266 -100
- package/dist/frontend/lowering/containers/array-callbacks.js.map +1 -1
- package/dist/frontend/lowering/containers/array-concat.js +1 -1
- package/dist/frontend/lowering/containers/array-concat.js.map +1 -1
- package/dist/frontend/lowering/containers/array-construction.d.ts +0 -1
- package/dist/frontend/lowering/containers/array-construction.js +51 -13
- package/dist/frontend/lowering/containers/array-construction.js.map +1 -1
- package/dist/frontend/lowering/containers/array-from-async.d.ts +6 -5
- package/dist/frontend/lowering/containers/array-from-async.js +159 -14
- package/dist/frontend/lowering/containers/array-from-async.js.map +1 -1
- package/dist/frontend/lowering/containers/array-methods.js +89 -77
- package/dist/frontend/lowering/containers/array-methods.js.map +1 -1
- package/dist/frontend/lowering/containers/array-pipelines.js +1 -0
- package/dist/frontend/lowering/containers/array-pipelines.js.map +1 -1
- package/dist/frontend/lowering/containers/bytes.js +161 -101
- package/dist/frontend/lowering/containers/bytes.js.map +1 -1
- package/dist/frontend/lowering/containers/callback-arguments.d.ts +9 -1
- package/dist/frontend/lowering/containers/callback-arguments.js +55 -5
- package/dist/frontend/lowering/containers/callback-arguments.js.map +1 -1
- package/dist/frontend/lowering/containers/collection-grouping.d.ts +7 -8
- package/dist/frontend/lowering/containers/collection-grouping.js +217 -26
- package/dist/frontend/lowering/containers/collection-grouping.js.map +1 -1
- package/dist/frontend/lowering/containers/collection-methods.js +54 -25
- package/dist/frontend/lowering/containers/collection-methods.js.map +1 -1
- package/dist/frontend/lowering/containers/dynamic-receivers.js +1 -1
- package/dist/frontend/lowering/containers/dynamic-receivers.js.map +1 -1
- package/dist/frontend/lowering/containers/exec-result-uses.js +2 -2
- package/dist/frontend/lowering/containers/exec-result-uses.js.map +1 -1
- package/dist/frontend/lowering/containers/for-of.d.ts +6 -0
- package/dist/frontend/lowering/containers/for-of.js +19 -19
- package/dist/frontend/lowering/containers/for-of.js.map +1 -1
- package/dist/frontend/lowering/containers/indexed-objects.js +142 -57
- package/dist/frontend/lowering/containers/indexed-objects.js.map +1 -1
- package/dist/frontend/lowering/containers/iterator-helpers.d.ts +53 -4
- package/dist/frontend/lowering/containers/iterator-helpers.js +1581 -462
- package/dist/frontend/lowering/containers/iterator-helpers.js.map +1 -1
- package/dist/frontend/lowering/containers/match-row-uses.d.ts +17 -0
- package/dist/frontend/lowering/containers/match-row-uses.js +264 -0
- package/dist/frontend/lowering/containers/match-row-uses.js.map +1 -0
- package/dist/frontend/lowering/containers/string-and-regexp.d.ts +14 -0
- package/dist/frontend/lowering/containers/string-and-regexp.js +419 -30
- package/dist/frontend/lowering/containers/string-and-regexp.js.map +1 -1
- package/dist/frontend/lowering/containers/string-replacement.js +1 -1
- package/dist/frontend/lowering/containers/string-replacement.js.map +1 -1
- package/dist/frontend/lowering/cycle-initialization.d.ts +4 -0
- package/dist/frontend/lowering/cycle-initialization.js +39 -0
- package/dist/frontend/lowering/cycle-initialization.js.map +1 -1
- package/dist/frontend/lowering/deferred-module-initializers.js +47 -43
- package/dist/frontend/lowering/deferred-module-initializers.js.map +1 -1
- package/dist/frontend/lowering/devirtualize.d.ts +1 -1
- package/dist/frontend/lowering/devirtualize.js +27 -7
- package/dist/frontend/lowering/devirtualize.js.map +1 -1
- package/dist/frontend/lowering/divergences.d.ts +0 -5
- package/dist/frontend/lowering/divergences.js +62 -125
- package/dist/frontend/lowering/divergences.js.map +1 -1
- package/dist/frontend/lowering/dyn-streams.d.ts +25 -0
- package/dist/frontend/lowering/dyn-streams.js +257 -0
- package/dist/frontend/lowering/dyn-streams.js.map +1 -0
- package/dist/frontend/lowering/error-methods.js +4 -1
- package/dist/frontend/lowering/error-methods.js.map +1 -1
- package/dist/frontend/lowering/error-name-order.d.ts +19 -0
- package/dist/frontend/lowering/error-name-order.js +93 -0
- package/dist/frontend/lowering/error-name-order.js.map +1 -0
- package/dist/frontend/lowering/expressions/array-literals.d.ts +21 -0
- package/dist/frontend/lowering/expressions/array-literals.js +703 -0
- package/dist/frontend/lowering/expressions/array-literals.js.map +1 -0
- package/dist/frontend/lowering/expressions/binary.d.ts +35 -0
- package/dist/frontend/lowering/expressions/binary.js +2483 -0
- package/dist/frontend/lowering/expressions/binary.js.map +1 -0
- package/dist/frontend/lowering/expressions/element-access.d.ts +31 -0
- package/dist/frontend/lowering/expressions/element-access.js +1797 -0
- package/dist/frontend/lowering/expressions/element-access.js.map +1 -0
- package/dist/frontend/lowering/expressions/evaluation-safety.js +4 -3
- package/dist/frontend/lowering/expressions/evaluation-safety.js.map +1 -1
- package/dist/frontend/lowering/expressions/hosted-narrowing.d.ts +38 -0
- package/dist/frontend/lowering/expressions/hosted-narrowing.js +160 -0
- package/dist/frontend/lowering/expressions/hosted-narrowing.js.map +1 -0
- package/dist/frontend/lowering/expressions/identifiers.d.ts +4 -0
- package/dist/frontend/lowering/expressions/identifiers.js +830 -0
- package/dist/frontend/lowering/expressions/identifiers.js.map +1 -0
- package/dist/frontend/lowering/expressions/keyed-field-targets.d.ts +40 -0
- package/dist/frontend/lowering/expressions/keyed-field-targets.js +226 -0
- package/dist/frontend/lowering/expressions/keyed-field-targets.js.map +1 -0
- package/dist/frontend/lowering/expressions/narrowing.d.ts +37 -0
- package/dist/frontend/lowering/expressions/narrowing.js +1322 -0
- package/dist/frontend/lowering/expressions/narrowing.js.map +1 -0
- package/dist/frontend/lowering/expressions/native-proxy.js +4 -4
- package/dist/frontend/lowering/expressions/native-proxy.js.map +1 -1
- package/dist/frontend/lowering/expressions/nullish-assignment.js +45 -0
- package/dist/frontend/lowering/expressions/nullish-assignment.js.map +1 -1
- package/dist/frontend/lowering/expressions/object-literals.d.ts +10 -0
- package/dist/frontend/lowering/expressions/object-literals.js +253 -85
- package/dist/frontend/lowering/expressions/object-literals.js.map +1 -1
- package/dist/frontend/lowering/expressions/optional-chains.d.ts +2 -1
- package/dist/frontend/lowering/expressions/optional-chains.js +91 -14
- package/dist/frontend/lowering/expressions/optional-chains.js.map +1 -1
- package/dist/frontend/lowering/expressions/property-access.d.ts +110 -0
- package/dist/frontend/lowering/expressions/property-access.js +3544 -0
- package/dist/frontend/lowering/expressions/property-access.js.map +1 -0
- package/dist/frontend/lowering/expressions/relational.d.ts +28 -0
- package/dist/frontend/lowering/expressions/relational.js +1679 -0
- package/dist/frontend/lowering/expressions/relational.js.map +1 -0
- package/dist/frontend/lowering/expressions/typeof.d.ts +22 -0
- package/dist/frontend/lowering/expressions/typeof.js +538 -0
- package/dist/frontend/lowering/expressions/typeof.js.map +1 -0
- package/dist/frontend/lowering/expressions/union-fields.js +1 -1
- package/dist/frontend/lowering/expressions/union-fields.js.map +1 -1
- package/dist/frontend/lowering/expressions/updates.d.ts +21 -0
- package/dist/frontend/lowering/expressions/updates.js +780 -0
- package/dist/frontend/lowering/expressions/updates.js.map +1 -0
- package/dist/frontend/lowering/function-context.d.ts +10 -0
- package/dist/frontend/lowering/function-context.js +11 -1
- package/dist/frontend/lowering/function-context.js.map +1 -1
- package/dist/frontend/lowering/function-returns.js +52 -28
- package/dist/frontend/lowering/function-returns.js.map +1 -1
- package/dist/frontend/lowering/general-streams.d.ts +25 -0
- package/dist/frontend/lowering/general-streams.js +108 -0
- package/dist/frontend/lowering/general-streams.js.map +1 -0
- package/dist/frontend/lowering/generator-dynamic-dispatch.d.ts +7 -0
- package/dist/frontend/lowering/generator-dynamic-dispatch.js +172 -69
- package/dist/frontend/lowering/generator-dynamic-dispatch.js.map +1 -1
- package/dist/frontend/lowering/generic-functions.d.ts +39 -0
- package/dist/frontend/lowering/generic-functions.js +393 -75
- package/dist/frontend/lowering/generic-functions.js.map +1 -1
- package/dist/frontend/lowering/import-meta.js +2 -2
- package/dist/frontend/lowering/import-meta.js.map +1 -1
- package/dist/frontend/lowering/intern-tables.js +10 -9
- package/dist/frontend/lowering/intern-tables.js.map +1 -1
- package/dist/frontend/lowering/iterator-adapters.d.ts +19 -0
- package/dist/frontend/lowering/iterator-adapters.js +331 -3
- package/dist/frontend/lowering/iterator-adapters.js.map +1 -1
- package/dist/frontend/lowering/js-class-fields.d.ts +28 -0
- package/dist/frontend/lowering/js-class-fields.js +170 -0
- package/dist/frontend/lowering/js-class-fields.js.map +1 -0
- package/dist/frontend/lowering/js-dynamic-objects.d.ts +15 -0
- package/dist/frontend/lowering/js-dynamic-objects.js +299 -0
- package/dist/frontend/lowering/js-dynamic-objects.js.map +1 -0
- package/dist/frontend/lowering/js-dynamic-objects.test.d.ts +1 -0
- package/dist/frontend/lowering/js-dynamic-objects.test.js +35 -0
- package/dist/frontend/lowering/js-dynamic-objects.test.js.map +1 -0
- package/dist/frontend/lowering/json-require.d.ts +22 -0
- package/dist/frontend/lowering/json-require.js +131 -0
- package/dist/frontend/lowering/json-require.js.map +1 -0
- package/dist/frontend/lowering/key-order-witness.d.ts +44 -0
- package/dist/frontend/lowering/key-order-witness.js +641 -0
- package/dist/frontend/lowering/key-order-witness.js.map +1 -0
- package/dist/frontend/lowering/key-order-witness.test.d.ts +1 -0
- package/dist/frontend/lowering/key-order-witness.test.js +239 -0
- package/dist/frontend/lowering/key-order-witness.test.js.map +1 -0
- package/dist/frontend/lowering/lifetime-regions.js +7 -7
- package/dist/frontend/lowering/lifetime-regions.js.map +1 -1
- package/dist/frontend/lowering/lower-assert.js +61 -60
- package/dist/frontend/lowering/lower-assert.js.map +1 -1
- package/dist/frontend/lowering/lower-async-iteration.d.ts +10 -1
- package/dist/frontend/lowering/lower-async-iteration.js +34 -6
- package/dist/frontend/lowering/lower-async-iteration.js.map +1 -1
- package/dist/frontend/lowering/lower-builtin-values.d.ts +5 -0
- package/dist/frontend/lowering/lower-builtin-values.js +32 -3
- package/dist/frontend/lowering/lower-builtin-values.js.map +1 -1
- package/dist/frontend/lowering/lower-calls.js +1239 -442
- package/dist/frontend/lowering/lower-calls.js.map +1 -1
- package/dist/frontend/lowering/lower-classes.d.ts +50 -3
- package/dist/frontend/lowering/lower-classes.js +1473 -468
- package/dist/frontend/lowering/lower-classes.js.map +1 -1
- package/dist/frontend/lowering/lower-comptime.d.ts +4 -2
- package/dist/frontend/lowering/lower-comptime.js +111 -13
- package/dist/frontend/lowering/lower-comptime.js.map +1 -1
- package/dist/frontend/lowering/lower-console.js +13 -11
- package/dist/frontend/lowering/lower-console.js.map +1 -1
- package/dist/frontend/lowering/lower-dgram.d.ts +10 -0
- package/dist/frontend/lowering/lower-dgram.js +179 -8
- package/dist/frontend/lowering/lower-dgram.js.map +1 -1
- package/dist/frontend/lowering/lower-enums.js +113 -14
- package/dist/frontend/lowering/lower-enums.js.map +1 -1
- package/dist/frontend/lowering/lower-event-emitter.d.ts +16 -7
- package/dist/frontend/lowering/lower-event-emitter.js +258 -70
- package/dist/frontend/lowering/lower-event-emitter.js.map +1 -1
- package/dist/frontend/lowering/lower-event-target.js +2 -2
- package/dist/frontend/lowering/lower-event-target.js.map +1 -1
- package/dist/frontend/lowering/lower-expando.js +17 -13
- package/dist/frontend/lowering/lower-expando.js.map +1 -1
- package/dist/frontend/lowering/lower-exprs.d.ts +188 -186
- package/dist/frontend/lowering/lower-exprs.js +1481 -12489
- package/dist/frontend/lowering/lower-exprs.js.map +1 -1
- package/dist/frontend/lowering/lower-functions.js +68 -22
- package/dist/frontend/lowering/lower-functions.js.map +1 -1
- package/dist/frontend/lowering/lower-generators.d.ts +6 -0
- package/dist/frontend/lowering/lower-generators.js +29 -16
- package/dist/frontend/lowering/lower-generators.js.map +1 -1
- package/dist/frontend/lowering/lower-global-value.js +5 -1
- package/dist/frontend/lowering/lower-global-value.js.map +1 -1
- package/dist/frontend/lowering/lower-inspect.js +331 -96
- package/dist/frontend/lowering/lower-inspect.js.map +1 -1
- package/dist/frontend/lowering/lower-mixins.js +23 -20
- package/dist/frontend/lowering/lower-mixins.js.map +1 -1
- package/dist/frontend/lowering/lower-mock.d.ts +8 -1
- package/dist/frontend/lowering/lower-mock.js +185 -18
- package/dist/frontend/lowering/lower-mock.js.map +1 -1
- package/dist/frontend/lowering/lower-modules.js +267 -61
- package/dist/frontend/lowering/lower-modules.js.map +1 -1
- package/dist/frontend/lowering/lower-namespaces.d.ts +6 -0
- package/dist/frontend/lowering/lower-namespaces.js +45 -33
- package/dist/frontend/lowering/lower-namespaces.js.map +1 -1
- package/dist/frontend/lowering/lower-node-module.d.ts +16 -0
- package/dist/frontend/lowering/lower-node-module.js +147 -14
- package/dist/frontend/lowering/lower-node-module.js.map +1 -1
- package/dist/frontend/lowering/lower-server.d.ts +6 -6
- package/dist/frontend/lowering/lower-server.js +488 -100
- package/dist/frontend/lowering/lower-server.js.map +1 -1
- package/dist/frontend/lowering/lower-stdlib.d.ts +4 -0
- package/dist/frontend/lowering/lower-stdlib.js +151 -109
- package/dist/frontend/lowering/lower-stdlib.js.map +1 -1
- package/dist/frontend/lowering/lower-stmts.d.ts +28 -2
- package/dist/frontend/lowering/lower-stmts.js +1541 -391
- package/dist/frontend/lowering/lower-stmts.js.map +1 -1
- package/dist/frontend/lowering/lower-stream.d.ts +3 -0
- package/dist/frontend/lowering/lower-stream.js +398 -56
- package/dist/frontend/lowering/lower-stream.js.map +1 -1
- package/dist/frontend/lowering/lower-test.d.ts +3 -0
- package/dist/frontend/lowering/lower-test.js +437 -62
- package/dist/frontend/lowering/lower-test.js.map +1 -1
- package/dist/frontend/lowering/lower-timers.js +80 -32
- package/dist/frontend/lowering/lower-timers.js.map +1 -1
- package/dist/frontend/lowering/lower-url.js +1 -1
- package/dist/frontend/lowering/lower-url.js.map +1 -1
- package/dist/frontend/lowering/lowerer.d.ts +399 -26
- package/dist/frontend/lowering/lowerer.js +1910 -305
- package/dist/frontend/lowering/lowerer.js.map +1 -1
- package/dist/frontend/lowering/lowerer.test.js +10 -4
- package/dist/frontend/lowering/lowerer.test.js.map +1 -1
- package/dist/frontend/lowering/maybe-promise.d.ts +46 -0
- package/dist/frontend/lowering/maybe-promise.js +249 -0
- package/dist/frontend/lowering/maybe-promise.js.map +1 -0
- package/dist/frontend/lowering/module-member-this.d.ts +3 -0
- package/dist/frontend/lowering/module-member-this.js +262 -0
- package/dist/frontend/lowering/module-member-this.js.map +1 -0
- package/dist/frontend/lowering/module-namespace-elements.js +1 -1
- package/dist/frontend/lowering/module-namespace-elements.js.map +1 -1
- package/dist/frontend/lowering/nan-coded-reads.d.ts +3 -0
- package/dist/frontend/lowering/nan-coded-reads.js +45 -32
- package/dist/frontend/lowering/nan-coded-reads.js.map +1 -1
- package/dist/frontend/lowering/narrowing-stability.d.ts +18 -3
- package/dist/frontend/lowering/narrowing-stability.js +104 -32
- package/dist/frontend/lowering/narrowing-stability.js.map +1 -1
- package/dist/frontend/lowering/native-ffi.js +11 -11
- package/dist/frontend/lowering/native-ffi.js.map +1 -1
- package/dist/frontend/lowering/object-factory-new.js +6 -8
- package/dist/frontend/lowering/object-factory-new.js.map +1 -1
- package/dist/frontend/lowering/private-brands.d.ts +46 -0
- package/dist/frontend/lowering/private-brands.js +265 -0
- package/dist/frontend/lowering/private-brands.js.map +1 -0
- package/dist/frontend/lowering/promise-executor-adapter.d.ts +11 -0
- package/dist/frontend/lowering/promise-executor-adapter.js +87 -0
- package/dist/frontend/lowering/promise-executor-adapter.js.map +1 -0
- package/dist/frontend/lowering/require-initialization.d.ts +32 -0
- package/dist/frontend/lowering/require-initialization.js +246 -0
- package/dist/frontend/lowering/require-initialization.js.map +1 -0
- package/dist/frontend/lowering/runtime-optional-bounds.js +7 -7
- package/dist/frontend/lowering/runtime-optional-bounds.js.map +1 -1
- package/dist/frontend/lowering/runtime-optional-elements.js +12 -12
- package/dist/frontend/lowering/runtime-optional-elements.js.map +1 -1
- package/dist/frontend/lowering/runtime-optional-guards.js +10 -10
- package/dist/frontend/lowering/runtime-optional-guards.js.map +1 -1
- package/dist/frontend/lowering/runtime-optional-guards.test.js +1 -1
- package/dist/frontend/lowering/runtime-optional-guards.test.js.map +1 -1
- package/dist/frontend/lowering/runtime-optional-ownership.js +10 -9
- package/dist/frontend/lowering/runtime-optional-ownership.js.map +1 -1
- package/dist/frontend/lowering/runtime-optional-provenance.js +2 -2
- package/dist/frontend/lowering/runtime-optional-provenance.js.map +1 -1
- package/dist/frontend/lowering/runtime-optional-records.d.ts +35 -0
- package/dist/frontend/lowering/runtime-optional-records.js +205 -32
- package/dist/frontend/lowering/runtime-optional-records.js.map +1 -1
- package/dist/frontend/lowering/runtime-optional-records.test.js +19 -1
- package/dist/frontend/lowering/runtime-optional-records.test.js.map +1 -1
- package/dist/frontend/lowering/sanitize-class-types.test.js +2 -2
- package/dist/frontend/lowering/split-consumers.js +4 -4
- package/dist/frontend/lowering/split-consumers.js.map +1 -1
- package/dist/frontend/lowering/static-function-names.d.ts +28 -0
- package/dist/frontend/lowering/static-function-names.js +212 -0
- package/dist/frontend/lowering/static-function-names.js.map +1 -0
- package/dist/frontend/lowering/static-this.js +6 -6
- package/dist/frontend/lowering/static-this.js.map +1 -1
- package/dist/frontend/lowering/strict-mode.d.ts +5 -0
- package/dist/frontend/lowering/strict-mode.js +31 -0
- package/dist/frontend/lowering/strict-mode.js.map +1 -0
- package/dist/frontend/lowering/string-index-bounds.js +10 -10
- package/dist/frontend/lowering/string-index-bounds.js.map +1 -1
- package/dist/frontend/lowering/string-index.d.ts +12 -0
- package/dist/frontend/lowering/string-index.js +72 -1
- package/dist/frontend/lowering/string-index.js.map +1 -1
- package/dist/frontend/lowering/surfaces.d.ts +12 -3
- package/dist/frontend/lowering/surfaces.js +252 -41
- package/dist/frontend/lowering/surfaces.js.map +1 -1
- package/dist/frontend/lowering/symbol-fields.d.ts +7 -0
- package/dist/frontend/lowering/symbol-fields.js +204 -36
- package/dist/frontend/lowering/symbol-fields.js.map +1 -1
- package/dist/frontend/lowering/symbol-methods.d.ts +2 -1
- package/dist/frontend/lowering/symbol-methods.js +24 -6
- package/dist/frontend/lowering/symbol-methods.js.map +1 -1
- package/dist/frontend/lowering/thread-slots.d.ts +13 -0
- package/dist/frontend/lowering/thread-slots.js +208 -0
- package/dist/frontend/lowering/thread-slots.js.map +1 -0
- package/dist/frontend/lowering/typed-arguments.d.ts +74 -0
- package/dist/frontend/lowering/typed-arguments.js +472 -0
- package/dist/frontend/lowering/typed-arguments.js.map +1 -0
- package/dist/frontend/lowering/union-retag.d.ts +8 -0
- package/dist/frontend/lowering/union-retag.js +27 -0
- package/dist/frontend/lowering/union-retag.js.map +1 -1
- package/dist/frontend/lowering/union-retag.test.js +24 -1
- package/dist/frontend/lowering/union-retag.test.js.map +1 -1
- package/dist/frontend/lowering/var-hoisting.js +6 -6
- package/dist/frontend/lowering/var-hoisting.js.map +1 -1
- package/dist/frontend/lowering/width-lift.d.ts +4 -0
- package/dist/frontend/mock-shapes.js +13 -6
- package/dist/frontend/mock-shapes.js.map +1 -1
- package/dist/frontend/module-source-candidates.js +1 -1
- package/dist/frontend/module-source-candidates.js.map +1 -1
- package/dist/frontend/module-source-candidates.test.js +2 -1
- package/dist/frontend/module-source-candidates.test.js.map +1 -1
- package/dist/frontend/module-syntax.js +8 -8
- package/dist/frontend/module-syntax.js.map +1 -1
- package/dist/frontend/npm-static-bundled-chunks.d.ts +51 -0
- package/dist/frontend/npm-static-bundled-chunks.js +810 -0
- package/dist/frontend/npm-static-bundled-chunks.js.map +1 -0
- package/dist/frontend/npm-static-bundled-chunks.test.d.ts +1 -0
- package/dist/frontend/npm-static-bundled-chunks.test.js +287 -0
- package/dist/frontend/npm-static-bundled-chunks.test.js.map +1 -0
- package/dist/frontend/npm-static-bundled-cjs.js +24 -23
- package/dist/frontend/npm-static-bundled-cjs.js.map +1 -1
- package/dist/frontend/npm-static-bundled-esm.d.ts +9 -0
- package/dist/frontend/npm-static-bundled-esm.js +768 -0
- package/dist/frontend/npm-static-bundled-esm.js.map +1 -0
- package/dist/frontend/npm-static-bundled-esm.test.d.ts +1 -0
- package/dist/frontend/npm-static-bundled-esm.test.js +207 -0
- package/dist/frontend/npm-static-bundled-esm.test.js.map +1 -0
- package/dist/frontend/npm-static-cjs-exports-alias.d.ts +2 -0
- package/dist/frontend/npm-static-cjs-exports-alias.js +186 -0
- package/dist/frontend/npm-static-cjs-exports-alias.js.map +1 -0
- package/dist/frontend/npm-static-cjs-exports-alias.test.d.ts +1 -0
- package/dist/frontend/npm-static-cjs-exports-alias.test.js +73 -0
- package/dist/frontend/npm-static-cjs-exports-alias.test.js.map +1 -0
- package/dist/frontend/npm-static-cjs-exports-var.d.ts +2 -0
- package/dist/frontend/npm-static-cjs-exports-var.js +236 -0
- package/dist/frontend/npm-static-cjs-exports-var.js.map +1 -0
- package/dist/frontend/npm-static-declaration-syntax.js +102 -101
- package/dist/frontend/npm-static-declaration-syntax.js.map +1 -1
- package/dist/frontend/npm-static-prune.js +36 -24
- package/dist/frontend/npm-static-prune.js.map +1 -1
- package/dist/frontend/npm-static-rewrite-host.d.ts +4 -1
- package/dist/frontend/npm-static-rewrite-host.js +14 -3
- package/dist/frontend/npm-static-rewrite-host.js.map +1 -1
- package/dist/frontend/npm-static-rewrite-syntax.d.ts +19 -0
- package/dist/frontend/npm-static-rewrite-syntax.js +274 -101
- package/dist/frontend/npm-static-rewrite-syntax.js.map +1 -1
- package/dist/frontend/npm-static-subtyping.js +7 -9
- package/dist/frontend/npm-static-subtyping.js.map +1 -1
- package/dist/frontend/npm-static.d.ts +17 -1
- package/dist/frontend/npm-static.js +167 -16
- package/dist/frontend/npm-static.js.map +1 -1
- package/dist/frontend/npm-static.test.js +22 -1
- package/dist/frontend/npm-static.test.js.map +1 -1
- package/dist/frontend/pipeline.js +164 -26
- package/dist/frontend/pipeline.js.map +1 -1
- package/dist/frontend/pipeline.test.js +22 -1
- package/dist/frontend/pipeline.test.js.map +1 -1
- package/dist/frontend/program-analysis.d.ts +6 -1
- package/dist/frontend/program-analysis.js +7 -0
- package/dist/frontend/program-analysis.js.map +1 -1
- package/dist/frontend/program.d.ts +92 -2
- package/dist/frontend/program.js +1557 -255
- package/dist/frontend/program.js.map +1 -1
- package/dist/frontend/program.test.js +76 -6
- package/dist/frontend/program.test.js.map +1 -1
- package/dist/frontend/resolve.js +36 -2
- package/dist/frontend/resolve.js.map +1 -1
- package/dist/frontend/resolve.test.js +49 -0
- package/dist/frontend/resolve.test.js.map +1 -1
- package/dist/frontend/services.d.ts +20 -1
- package/dist/frontend/services.js +40 -3
- package/dist/frontend/services.js.map +1 -1
- package/dist/frontend/services.test.js +2 -1
- package/dist/frontend/services.test.js.map +1 -1
- package/dist/frontend/threads-import.js +1 -1
- package/dist/frontend/threads-import.js.map +1 -1
- package/dist/frontend/tier-analysis.d.ts +71 -0
- package/dist/frontend/tier-analysis.js +522 -0
- package/dist/frontend/tier-analysis.js.map +1 -0
- package/dist/frontend/ts7/api-conformance.d.ts +234 -0
- package/dist/frontend/ts7/api-conformance.js +7 -0
- package/dist/frontend/ts7/api-conformance.js.map +1 -0
- package/dist/frontend/ts7/ast-guards.generated.js +2 -1
- package/dist/frontend/ts7/ast-guards.generated.js.map +1 -1
- package/dist/frontend/ts7/ast-node.d.ts +47 -25
- package/dist/frontend/ts7/ast-node.js +64 -18
- package/dist/frontend/ts7/ast-node.js.map +1 -1
- package/dist/frontend/ts7/ast-node.test.js +36 -12
- package/dist/frontend/ts7/ast-node.test.js.map +1 -1
- package/dist/frontend/ts7/ast-types.d.ts +10 -3
- package/dist/frontend/ts7/ast-types.generated.d.ts +39 -39
- package/dist/frontend/ts7/ast.d.ts +1 -0
- package/dist/frontend/ts7/ast.js +3 -2
- package/dist/frontend/ts7/ast.js.map +1 -1
- package/dist/frontend/ts7/checker-backend.d.ts +23 -0
- package/dist/frontend/ts7/checker-backend.js +88 -0
- package/dist/frontend/ts7/checker-backend.js.map +1 -0
- package/dist/frontend/ts7/checker-backend.test.d.ts +1 -0
- package/dist/frontend/ts7/checker-backend.test.js +63 -0
- package/dist/frontend/ts7/checker-backend.test.js.map +1 -0
- package/dist/frontend/ts7/checker-cache.d.ts +0 -3
- package/dist/frontend/ts7/checker-cache.js +0 -6
- package/dist/frontend/ts7/checker-cache.js.map +1 -1
- package/dist/frontend/ts7/checker.d.ts +18 -11
- package/dist/frontend/ts7/checker.js +42 -55
- package/dist/frontend/ts7/checker.js.map +1 -1
- package/dist/frontend/ts7/checker.test.js +10 -7
- package/dist/frontend/ts7/checker.test.js.map +1 -1
- package/dist/frontend/ts7/diagnostic.d.ts +19 -0
- package/dist/frontend/ts7/diagnostic.js +22 -0
- package/dist/frontend/ts7/diagnostic.js.map +1 -0
- package/dist/frontend/ts7/node-functions.d.ts +8 -0
- package/dist/frontend/ts7/node-functions.js +18 -0
- package/dist/frontend/ts7/node-functions.js.map +1 -0
- package/dist/frontend/ts7/program-host.d.ts +5 -1
- package/dist/frontend/ts7/program-host.js +12 -0
- package/dist/frontend/ts7/program-host.js.map +1 -1
- package/dist/frontend/ts7/rpc-api.d.ts +5 -1
- package/dist/frontend/ts7/rpc-api.js +8 -1
- package/dist/frontend/ts7/rpc-api.js.map +1 -1
- package/dist/frontend/ts7/semantic-checker.d.ts +13 -6
- package/dist/frontend/ts7/semantic-checker.js +26 -8
- package/dist/frontend/ts7/semantic-checker.js.map +1 -1
- package/dist/frontend/ts7/semantic-checker.test.js +12 -9
- package/dist/frontend/ts7/semantic-checker.test.js.map +1 -1
- package/dist/frontend/ts7/semantic-model.d.ts +54 -24
- package/dist/frontend/ts7/semantic-model.js +88 -16
- package/dist/frontend/ts7/semantic-model.js.map +1 -1
- package/dist/frontend/ts7/semantic-model.test.js +4 -4
- package/dist/frontend/ts7/semantic-model.test.js.map +1 -1
- package/dist/frontend/ts7/semantic-types.d.ts +7 -3
- package/dist/frontend/ts7/semantic-types.js +1 -1
- package/dist/frontend/ts7/semantic-types.js.map +1 -1
- package/dist/frontend/ts7/session.d.ts +11 -11
- package/dist/frontend/ts7/session.js +8 -5
- package/dist/frontend/ts7/session.js.map +1 -1
- package/dist/frontend/ts7/session.test.js +9 -5
- package/dist/frontend/ts7/session.test.js.map +1 -1
- package/dist/frontend/ts7/source-parser.d.ts +6 -2
- package/dist/frontend/ts7/source-parser.js +24 -3
- package/dist/frontend/ts7/source-parser.js.map +1 -1
- package/dist/frontend/ts7/source-parser.test.js +38 -17
- package/dist/frontend/ts7/source-parser.test.js.map +1 -1
- package/dist/frontend/type-mapper.d.ts +122 -2
- package/dist/frontend/type-mapper.js +2545 -719
- package/dist/frontend/type-mapper.js.map +1 -1
- package/dist/frontend/type-only-imports.d.ts +28 -0
- package/dist/frontend/type-only-imports.js +122 -0
- package/dist/frontend/type-only-imports.js.map +1 -0
- package/dist/frontend/worker-target.js +8 -8
- package/dist/frontend/worker-target.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +29 -2
- package/dist/index.js.map +1 -1
- package/dist/ir/analysis.js +4 -2
- package/dist/ir/analysis.js.map +1 -1
- package/dist/ir/api.d.ts +1 -1
- package/dist/ir/api.js +1 -1
- package/dist/ir/api.js.map +1 -1
- package/dist/ir/array-length-stability.d.ts +30 -0
- package/dist/ir/array-length-stability.js +236 -0
- package/dist/ir/array-length-stability.js.map +1 -0
- package/dist/ir/array-length-stability.test.d.ts +1 -0
- package/dist/ir/array-length-stability.test.js +113 -0
- package/dist/ir/array-length-stability.test.js.map +1 -0
- package/dist/ir/build.d.ts +2 -2
- package/dist/ir/build.js +1 -1
- package/dist/ir/build.js.map +1 -1
- package/dist/ir/builtin-effects.js +103 -0
- package/dist/ir/builtin-effects.js.map +1 -1
- package/dist/ir/builtin-signatures.d.ts +1 -1
- package/dist/ir/builtin-signatures.js +494 -25
- package/dist/ir/builtin-signatures.js.map +1 -1
- package/dist/ir/byte-numbers.js +3 -0
- package/dist/ir/byte-numbers.js.map +1 -1
- package/dist/ir/callback-specialization.d.ts +37 -0
- package/dist/ir/callback-specialization.js +459 -0
- package/dist/ir/callback-specialization.js.map +1 -0
- package/dist/ir/callback-specialization.test.d.ts +1 -0
- package/dist/ir/callback-specialization.test.js +208 -0
- package/dist/ir/callback-specialization.test.js.map +1 -0
- package/dist/ir/capture-values.d.ts +0 -1
- package/dist/ir/capture-values.js +51 -40
- package/dist/ir/capture-values.js.map +1 -1
- package/dist/ir/constant-globals.test.js +1 -1
- package/dist/ir/constant-tables.test.js +1 -1
- package/dist/ir/field-values.test.js +1 -1
- package/dist/ir/final-fields.test.js +1 -1
- package/dist/ir/function-references.test.js +9 -1
- package/dist/ir/function-references.test.js.map +1 -1
- package/dist/ir/init-only-globals.test.js +1 -1
- package/dist/ir/initializer-bindings.test.js +1 -1
- package/dist/ir/int32-slots.d.ts +14 -0
- package/dist/ir/int32-slots.js +97 -14
- package/dist/ir/int32-slots.js.map +1 -1
- package/dist/ir/int32-slots.test.js +1 -1
- package/dist/ir/integer-loop-facts.d.ts +2 -0
- package/dist/ir/integer-loop-facts.js +24 -3
- package/dist/ir/integer-loop-facts.js.map +1 -1
- package/dist/ir/integer-loops.d.ts +1 -1
- package/dist/ir/integer-loops.js +39 -9
- package/dist/ir/integer-loops.js.map +1 -1
- package/dist/ir/integer-loops.test.js +104 -0
- package/dist/ir/integer-loops.test.js.map +1 -1
- package/dist/ir/integer-ranges.d.ts +3 -0
- package/dist/ir/integer-ranges.js +3 -1
- package/dist/ir/integer-ranges.js.map +1 -1
- package/dist/ir/integer-ranges.test.js +82 -1
- package/dist/ir/integer-ranges.test.js.map +1 -1
- package/dist/ir/intrinsic-signatures.js +6 -0
- package/dist/ir/intrinsic-signatures.js.map +1 -1
- package/dist/ir/ir.d.ts +221 -58
- package/dist/ir/ir.js +119 -12
- package/dist/ir/ir.js.map +1 -1
- package/dist/ir/ir.test.js +10 -0
- package/dist/ir/ir.test.js.map +1 -1
- package/dist/ir/jsval.d.ts +8 -0
- package/dist/ir/jsval.js +365 -0
- package/dist/ir/jsval.js.map +1 -0
- package/dist/ir/jsval.test.d.ts +1 -0
- package/dist/ir/jsval.test.js +239 -0
- package/dist/ir/jsval.test.js.map +1 -0
- package/dist/ir/runtime-features.d.ts +148 -33
- package/dist/ir/runtime-features.js +629 -386
- package/dist/ir/runtime-features.js.map +1 -1
- package/dist/ir/scalar-records.test.js +1 -1
- package/dist/ir/self-captures.d.ts +33 -0
- package/dist/ir/self-captures.js +245 -0
- package/dist/ir/self-captures.js.map +1 -0
- package/dist/ir/self-captures.test.d.ts +1 -0
- package/dist/ir/self-captures.test.js +135 -0
- package/dist/ir/self-captures.test.js.map +1 -0
- package/dist/ir/serialize.d.ts +1 -1
- package/dist/ir/serialize.js +7 -4
- package/dist/ir/serialize.js.map +1 -1
- package/dist/ir/tiers.d.ts +26 -0
- package/dist/ir/tiers.js +101 -0
- package/dist/ir/tiers.js.map +1 -0
- package/dist/ir/tiers.test.d.ts +1 -0
- package/dist/ir/tiers.test.js +140 -0
- package/dist/ir/tiers.test.js.map +1 -0
- package/dist/ir/traverse.js +103 -94
- package/dist/ir/traverse.js.map +1 -1
- package/dist/ir/traverse.test.js +33 -30
- package/dist/ir/traverse.test.js.map +1 -1
- package/dist/ir/unshare.js +65 -3
- package/dist/ir/unshare.js.map +1 -1
- package/dist/ir/unshare.test.js +1 -1
- package/dist/ir/validate.js +175 -68
- package/dist/ir/validate.js.map +1 -1
- package/dist/ir/validate.test.js +26 -9
- package/dist/ir/validate.test.js.map +1 -1
- package/dist/library/fence-eval.test.js +1 -1
- package/dist/library/int-infer.test.js +4 -4
- package/dist/library/ir-policy.js +13 -0
- package/dist/library/ir-policy.js.map +1 -1
- package/dist/library/library-cache.d.ts +1 -0
- package/dist/library/library-cache.js.map +1 -1
- package/dist/library/library-cache.test.js +5 -5
- package/dist/library/library-profile.d.ts +4 -4
- package/dist/library/library-profile.js +35 -7
- package/dist/library/library-profile.js.map +1 -1
- package/dist/library/prepare.js +13 -1
- package/dist/library/prepare.js.map +1 -1
- package/dist/native/cli.js +5 -0
- package/dist/native/cli.js.map +1 -1
- package/dist/native/compiler.js +2 -2
- package/dist/native/compiler.js.map +1 -1
- package/dist/native/compiler.test.js +2 -2
- package/dist/native/prepare.js +7 -0
- package/dist/native/prepare.js.map +1 -1
- package/dist/native/sanitizer.test.js +12 -0
- package/dist/native/sanitizer.test.js.map +1 -1
- package/dist/native/toolchain.d.ts +2 -0
- package/dist/native/toolchain.js +10 -1
- package/dist/native/toolchain.js.map +1 -1
- package/dist/native/toolchain.test.js +39 -1
- package/dist/native/toolchain.test.js.map +1 -1
- package/dist/startup-cache.d.ts +1 -0
- package/dist/startup-cache.js +1 -0
- package/dist/startup-cache.js.map +1 -1
- package/dist/wasm/base64.d.ts +5 -0
- package/dist/wasm/base64.js +62 -0
- package/dist/wasm/base64.js.map +1 -0
- package/dist/wasm/binary.d.ts +36 -0
- package/dist/wasm/binary.js +1976 -0
- package/dist/wasm/binary.js.map +1 -0
- package/dist/wasm/binary.test.d.ts +1 -0
- package/dist/wasm/binary.test.js +190 -0
- package/dist/wasm/binary.test.js.map +1 -0
- package/dist/wasm/discover.d.ts +38 -0
- package/dist/wasm/discover.js +377 -0
- package/dist/wasm/discover.js.map +1 -0
- package/dist/wasm/discover.test.d.ts +1 -0
- package/dist/wasm/discover.test.js +24 -0
- package/dist/wasm/discover.test.js.map +1 -0
- package/dist/wasm/module.d.ts +151 -0
- package/dist/wasm/module.js +575 -0
- package/dist/wasm/module.js.map +1 -0
- package/dist/wasm/translate.d.ts +48 -0
- package/dist/wasm/translate.js +2129 -0
- package/dist/wasm/translate.js.map +1 -0
- package/dist/wasm/translate.test.d.ts +1 -0
- package/dist/wasm/translate.test.js +207 -0
- package/dist/wasm/translate.test.js.map +1 -0
- package/package.json +21 -20
- package/surface-manifest.json +303 -19
|
@@ -1,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,8 +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";
|
|
15
29
|
import { hashStreamOf } from "./builtins/hash-stream.js";
|
|
30
|
+
import { lowerNetAddressCall, lowerNetAddressNew } from "./builtins/net-address.js";
|
|
16
31
|
import { dynUndefinedExpr, nodeThrowExpr, numLit, varRef } from "../../ir/build.js";
|
|
17
32
|
import { iteratorSlotAdapter } from "./iterator-adapters.js";
|
|
18
33
|
import { lowerBuiltinCall } from "./builtin-calls.js";
|
|
@@ -20,7 +35,7 @@ import { CoercionState } from "./coercions/state.js";
|
|
|
20
35
|
import { widthLiftPlan, unitOnlyElem, recordWidthPlan, describeRecordWidthBlocker, objToRecordPlan, recordToClassPlan, } from "./coercions/structural-plans.js";
|
|
21
36
|
import { widthCoerce, applyWidthLift, unionRecordWidthHelper, recordWidthHelper, tupleArrayWidthHelper, emptyArrayLiftHelper, arrayWidthHelper, objRecordWidthHelper, recordClassWidthHelper, classStaticsProjection, } from "./coercions/structural.js";
|
|
22
37
|
import { funcReturnWidthAdapter, coercibleValue, cleanFuncAdaptable, funcCoerceAdapter, spawnResFnAdapterPlan, spawnResFnAdapter, } from "./coercions/function-adapters.js";
|
|
23
|
-
import { unionRetagMappable, narrowedRetagHelper, strandedUnitTrap, strandedCoercionTrap, recordUnionWrapHelper, unionRetagHelper, narrowedArmHelper, checkedNarrowCall, checkedNarrowOperand, deferredReadHelper, } from "./coercions/unions.js";
|
|
38
|
+
import { unionRetagMappable, narrowedRetagHelper, uninhabitedArmRetagHelper, strandedUnitTrap, strandedCoercionTrap, recordUnionRouteHelper, recordUnionWrapHelper, unionRetagHelper, narrowedArmHelper, checkedNarrowCall, checkedNarrowOperand, deferredReadHelper, } from "./coercions/unions.js";
|
|
24
39
|
import { lowerUtilTypeValue, pathModuleValue, utilTypesModuleValue, } from "./lower-builtin-values.js";
|
|
25
40
|
import { devirtualizeVirtualCalls } from "./devirtualize.js";
|
|
26
41
|
import { foldRegexSpanReads } from "./regex-span-reads.js";
|
|
@@ -42,11 +57,17 @@ import { InternalCompilerError } from "../../errors.js";
|
|
|
42
57
|
import { defaultAfterUndefined, lowerStaticallyUndefinedArgument } from "./optional-arguments.js";
|
|
43
58
|
import {} from "./class-protocol-dispatch.js";
|
|
44
59
|
import { ClassDynamicDispatch, trackClassFieldCreation } from "./class-dynamic-dispatch.js";
|
|
60
|
+
import { guardClassAttributeWrites } from "./class-attributes.js";
|
|
45
61
|
import { ClassProtocols } from "./class-protocols.js";
|
|
46
62
|
import { earlyReadVarSymbols } from "./var-hoisting.js";
|
|
47
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";
|
|
48
67
|
import { DeferredModuleInitializers } from "./deferred-module-initializers.js";
|
|
49
68
|
import { finalizeClassMethodValues } from "./class-method-values.js";
|
|
69
|
+
import { finalizePrivateBrands } from "./private-brands.js";
|
|
70
|
+
import { tableKeyFieldType } from "./symbol-fields.js";
|
|
50
71
|
export { newFnCtx } from "./function-context.js";
|
|
51
72
|
/* AST + checker → IR.
|
|
52
73
|
*
|
|
@@ -66,22 +87,27 @@ import { resolve } from "node:path";
|
|
|
66
87
|
import { bindingSource } from "../binding-source.js";
|
|
67
88
|
import { tsgoPath } from "../dts-paths.js";
|
|
68
89
|
import * as ts from "../ts7/adapter.js";
|
|
90
|
+
import { erasedTypeOnlyImport } from "../type-only-imports.js";
|
|
69
91
|
import { literalValues } from "../literal-values.js";
|
|
70
92
|
import { discriminantOwners, literalUnionArm } from "../union-discriminants.js";
|
|
71
93
|
import { unsupportedAnyOperationDiag, blockedBindingUseDiag, checkerPanicDiag, componentTypeDiag, isCheckerPanic, genericSignatureTypeDiag, indexSignatureTypeDiag, intersectionTypeDiag, noLoweringDiag, overloadedSignatureTypeDiag, recordShapeMismatchDiag, unsupportedNativeApiDiag, unsupportedPackageValueDiag, unionMismatchDiag, UNSUPPORTED, unsupportedDiag, unsupportedTypeDiag, } from "../../diagnostics/diagnostic.js";
|
|
72
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";
|
|
73
95
|
import { provenanceActive } from "../provenance-registry.js";
|
|
74
|
-
import { ambientDtsPath, canonicalBuiltinModule, cjsExportAssignmentOf, cjsExportDiscardReason, fallbackDtsPath, isCjsExportTableLiteral, isCjsJsFile, isJsSourceFile, isNodeEsmFile, isNodeTypesPath, locOf, orderedImportsOf, overridesDtsPath, npmStaticDepSf7, requireSpecOf, resolveImport, workspacePackageOfPath, } from "../program.js";
|
|
75
|
-
import { containsRecord, containsUnion, describeComponentBlocker, describeRecordMemberBlocker, formatIrType, FETCH_AMBIENT_TYPES, isOsConstantsSymbol, isUnitOnlyTsType, isWorkerHandleType, jsOpenObjectType, mapType, ShapeRegistry, typeKey, UnionRegistry, withUndefinedArm as withUndefinedArmCanonical, } from "../type-mapper.js";
|
|
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";
|
|
76
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";
|
|
77
100
|
import { splitFiles, collectProgram, collectNpmImports, collectJsonImports, moduleArtifacts, collectGlobals, declSymbolOf, defaultExportSymbolOf, lowerFileInit, lowerDefaultExport, buildMain, appendDynamicImportModules, appendForkModules, appendWorkerModules, } from "./lower-modules.js";
|
|
78
|
-
import { prepareCjsModuleGraph } from "./lower-node-module.js";
|
|
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";
|
|
79
105
|
import { registerBuiltinEventTargetClasses } from "./lower-event-target.js";
|
|
80
|
-
import { registerBuiltinErrorClasses, registerBuiltinEmitterClass, registerBuiltinStreamClasses, builtinErrorInfoOf, builtinEmitterInfoOf, builtinStreamInfoOf, analyzeClassDecoration, classIteratorDrainCall, classIteratorNextCall, classIteratorOf, classIteratorOpenCall, classIteratorRestDrainCall, classMemberNameOf, classValueRef, collectClassShape, exactClassOfReceiver, collectClassShapeInner, ctorAbiEquals, findMethodOn, findStaticOn, genericClassInstanceType, isSubclassOf, inHierarchy, overrideBelow, staticShadowBelow, upcastTo, lowerClassMembers, lowerClassCtor, lowerClassExpression, lowerClassExpressionInfo, lowerClassMethodMember, lowerClassValueProperty, lowerStaticMethod, throwingSetterFn, fieldInitStmts, lowerStaticFieldInits, lowerStaticFieldRead, lowerDerivedCtorBody, superCallStmt, lowerSuperMethodCall, superThisRef, lowerSuperAccessorRead, lowerSuperAccessorWrite, inheritsBuiltinErrorCtor, inheritsBuiltinEmitterCtor, errorConstructorArgs, lowerNew, accessorCall, } from "./lower-classes.js";
|
|
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";
|
|
81
107
|
import { mixinCallClassInfoOf, mixinIntersectionInstanceType, } from "./lower-mixins.js";
|
|
82
108
|
import { tryLowerExpression } from "./expressions/try-lower-expression.js";
|
|
83
109
|
import { funcTypeFromParamShapes, isThisParameter, paramShape, paramShapes, checkDefaultParamBodyType, requireExactArityValue, collectSignature, collectSignatureInner, lambdaSignature, } from "./call-signatures.js";
|
|
84
|
-
import { implicitAnyParamSymbolsOf, implicitMonoFile, collectGenericSignature, genericFnOf, lowerGenericCall, lowerGenericFnValue, inferTypeParamBindings, lowerGenericInstance, } from "./generic-functions.js";
|
|
110
|
+
import { implicitAnyParamSymbolsOf, implicitLocalFnNodeOf, implicitMonoFile, collectGenericSignature, genericFnOf, lowerGenericCall, lowerGenericFnValue, inferTypeParamBindings, lowerGenericInstance, genericLocalClassBinding, } from "./generic-functions.js";
|
|
85
111
|
import { bindingNeverReassigned } from "./binding-analysis.js";
|
|
86
112
|
import { bodyReadsArguments } from "../arguments-usage.js";
|
|
87
113
|
import { completeArgs, wrappedUndefined, undefinedArgFor } from "./call-arguments.js";
|
|
@@ -96,7 +122,7 @@ import { lowerEnvToPairsHelper } from "./containers/indexed-objects.js";
|
|
|
96
122
|
import { lowerBufferStaticCall, lowerBytesMethodCall, lowerBytesNew } from "./containers/bytes.js";
|
|
97
123
|
import { lowerRegexMethodCall, lowerStringMethodCall } from "./containers/string-and-regexp.js";
|
|
98
124
|
import { lowerEmitOverrideSpec, } from "./lower-event-emitter.js";
|
|
99
|
-
import { builtinImportOf, createRequireProgramModuleOf, createRequireSpecOf, fencedBuiltinImportOf, } from "./builtins/module-bindings.js";
|
|
125
|
+
import { builtinImportOf, createRequireProgramModuleOf, createRequireSpecOf, fencedBuiltinImportOf, esmImportBindingKind, } from "./builtins/module-bindings.js";
|
|
100
126
|
import { stripTypeCasts } from "./builtins/arguments.js";
|
|
101
127
|
import { lowerBuiltinModuleCall } from "./builtins/module-calls.js";
|
|
102
128
|
import { lowerTimersPromisesSetInterval, lowerTimeoutMethodCall } from "./builtins/timers.js";
|
|
@@ -115,13 +141,14 @@ import { lowerExecFileAsyncCall } from "./builtins/child-process-async.js";
|
|
|
115
141
|
import { lowerStringDecoderMethodCall, lowerTextCodecCall } from "./builtins/text-codecs.js";
|
|
116
142
|
import { lowerReadlineMethodCall } from "./builtins/readline.js";
|
|
117
143
|
import { lowerDiagnosticsChannelMethodCall, lowerDiagnosticsChannelProperty, lowerAsyncLocalStorageMethodCall, lowerTracingChannelMethodCall, lowerTracingChannelProperty, } from "./builtins/async-context.js";
|
|
144
|
+
import { lowerDisposableStackNew } from "./builtins/disposable-stack.js";
|
|
118
145
|
import { lowerErrorCodeProperty } from "./builtins/errors.js";
|
|
119
146
|
import { lowerProcessProperty, lowerProcessMethodCall, lowerProcessOptionalMethodCall, lowerProcessStreamProperty, } from "./builtins/process.js";
|
|
120
147
|
import { consoleCallMember, consoleMethodMember, isConsoleLog, } from "./builtins/console.js";
|
|
121
148
|
import { lowerConsoleNew } from "./lower-console.js";
|
|
122
149
|
import { lowerNumberStaticCall, lowerNumberStaticProperty } from "./builtins/numbers.js";
|
|
123
|
-
import { lowerDateCall } from "./builtins/dates.js";
|
|
124
|
-
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";
|
|
125
152
|
import { lowerStringStaticCall, lowerStringLastIndexOfCall } from "./builtins/strings.js";
|
|
126
153
|
import { lowerPromiseStaticCall } from "./builtins/promises.js";
|
|
127
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";
|
|
@@ -132,14 +159,15 @@ import { lowerAssertModuleCall, lowerAssertDirectCall } from "./lower-assert.js"
|
|
|
132
159
|
import { lowerUtilModuleCall } from "./lower-inspect.js";
|
|
133
160
|
import { lowerSystemErrorMapValue } from "./lower-system-errors.js";
|
|
134
161
|
import { lowerComptime, comptimeBakeable, rejectComptimeCaptures, comptimeValueToIr, } from "./lower-comptime.js";
|
|
135
|
-
import { lowerStmts, hasJsTypeAnnotation, noteBlockedBindings, isBlockedBinding, lowerScopedBlock, predeclareForwardCapture, predeclareForwardFnDecl, predeclareForwardVar, lowerStmt, lowerVarStatement, lowerDestructuringDecl, lowerDestructuringAssignParts, lowerBindingPattern, checkBindingElement, bindPatternTarget, isParseArgsDynCheckerType, lowerVarDeclList, lowerVarDecl, lowerSwitch, lowerTry, lowerExprStatement, lowerForOf, lowerForStatement, } from "./lower-stmts.js";
|
|
136
|
-
import { lowerExpr, maybeNarrow, lowerUnitComparison, lowerNullishCoalesce, lowerCondition, ensureBool, requireTruthyUnion, eqComparableUnion, lowerIntrinsicProperty, lowerArrayLiteral, lowerElementAccess, lowerElementWrite, lowerRecordKeyRead, ensureString, lowerTemplate, lowerAsExpression, lowerPrefixUnary, lowerBinary, lowerCaughtTypeofTest, caughtRead, caughtLocalOf, caughtToString, lowerInstanceOf, lowerRegexLiteral, lowerFieldRead, lowerUnionProperty, fieldTarget, fieldGetExpr, fieldSetStmt, lowerFieldCompound, uniqueSymbolKeyOf, } from "./lower-exprs.js";
|
|
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";
|
|
137
164
|
import { finishOptionalChain, isOptionalChainTail, lowerOptionalChain, } from "./expressions/optional-chains.js";
|
|
138
165
|
import { foldedStringKeyOf, lowerDynObjectLiteral, lowerObjectLiteral, lowerShorthandValue, rejectThisInObjectMethod, } from "./expressions/object-literals.js";
|
|
139
166
|
import { lowerRecordFieldCall, lowerObjectMethodCall } from "./lower-calls.js";
|
|
140
167
|
import { fenceCrossBlockNsRef, nsPathPrefix } from "./lower-namespaces.js";
|
|
141
168
|
import { isSafeToRepeat } from "./expressions/evaluation-safety.js";
|
|
142
169
|
import { lowerTernary } from "./lower-exprs.js";
|
|
170
|
+
import { maybePromiseReturnStmt, maybePromiseUnionOf, promiseArmedUnionOf, } from "./maybe-promise.js";
|
|
143
171
|
/** Entry function name. '%' cannot appear in a TS identifier, so a user
|
|
144
172
|
* function can never collide with it (mangling is injective per prefix). */
|
|
145
173
|
export const ENTRY_NAME = "%main";
|
|
@@ -160,7 +188,7 @@ export function boundIdentifiersOf(name) {
|
|
|
160
188
|
if (ts.isIdentifier(name))
|
|
161
189
|
return [name];
|
|
162
190
|
const out = [];
|
|
163
|
-
for (const el of name.elements) {
|
|
191
|
+
for (const el of name.elements.nodes) {
|
|
164
192
|
// Elisions: OmittedExpression in 5.9.3, a NAMELESS BindingElement in 7
|
|
165
193
|
// (the parity battery's pinned finding 2) — both spell "no binding".
|
|
166
194
|
if (ts.isOmittedExpression(el) || el.name === undefined)
|
|
@@ -177,7 +205,7 @@ export function countBodyStatements(root) {
|
|
|
177
205
|
let n = 0;
|
|
178
206
|
const visit = (node) => {
|
|
179
207
|
if (ts.isBlock(node) || ts.isCaseClause(node) || ts.isDefaultClause(node)) {
|
|
180
|
-
n += node.statements.length;
|
|
208
|
+
n += node.statements.nodes.length;
|
|
181
209
|
}
|
|
182
210
|
else if ((ts.isIfStatement(node) ||
|
|
183
211
|
ts.isForStatement(node) ||
|
|
@@ -283,16 +311,20 @@ export function lowerToIr(program, entry, moduleOrder, options = {}) {
|
|
|
283
311
|
const libraryCallbacks = options.libraryCallbacks ?? false;
|
|
284
312
|
const externalTypes = options.externalTypes ?? new Map();
|
|
285
313
|
const externalTypeSpecifiersByFile = options.externalTypeSpecifiersByFile ?? directExternalTypeSpecifiersByFile(externalTypes);
|
|
314
|
+
const tierMode = options.tierMode ?? "auto";
|
|
286
315
|
const validation = new Lowerer(program, entry, moduleOrder, {
|
|
287
316
|
frontendServices: options.frontendServices,
|
|
317
|
+
projectCheckJs: options.projectCheckJs ?? false,
|
|
288
318
|
targetPlatform,
|
|
289
319
|
startupCrash,
|
|
320
|
+
inlineRequireCycleCalls: options.inlineRequireCycleCalls,
|
|
290
321
|
ffiImports,
|
|
291
322
|
libraryCallbacks,
|
|
292
323
|
forkTargets,
|
|
293
324
|
workerTargets,
|
|
294
325
|
externalTypes,
|
|
295
326
|
externalTypeSpecifiersByFile,
|
|
327
|
+
tierMode,
|
|
296
328
|
});
|
|
297
329
|
const ffiValidation = validateFfiImports(validation);
|
|
298
330
|
timing("ffi-validate");
|
|
@@ -305,14 +337,17 @@ export function lowerToIr(program, entry, moduleOrder, options = {}) {
|
|
|
305
337
|
? validation
|
|
306
338
|
: new Lowerer(program, entry, moduleOrder, {
|
|
307
339
|
frontendServices: options.frontendServices,
|
|
340
|
+
projectCheckJs: options.projectCheckJs ?? false,
|
|
308
341
|
targetPlatform,
|
|
309
342
|
startupCrash,
|
|
343
|
+
inlineRequireCycleCalls: options.inlineRequireCycleCalls,
|
|
310
344
|
ffiImports,
|
|
311
345
|
libraryCallbacks,
|
|
312
346
|
forkTargets,
|
|
313
347
|
workerTargets,
|
|
314
348
|
externalTypes,
|
|
315
349
|
externalTypeSpecifiersByFile,
|
|
350
|
+
tierMode,
|
|
316
351
|
ffiBindingSymbols: ffiValidation.symbolsByName,
|
|
317
352
|
});
|
|
318
353
|
for (const d of extraModuleCycleDiags)
|
|
@@ -320,10 +355,55 @@ export function lowerToIr(program, entry, moduleOrder, options = {}) {
|
|
|
320
355
|
for (const d of ffiValidation.diagnostics)
|
|
321
356
|
reachableEmit.pushDiag(d);
|
|
322
357
|
const emitted = reachableEmit.emitReachable(options.libRoots);
|
|
323
|
-
|
|
358
|
+
let { reachable } = emitted;
|
|
324
359
|
let result = emitted.result;
|
|
325
360
|
let resultLowerer = reachableEmit;
|
|
326
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
|
+
}
|
|
327
407
|
// A generic class-rest support decision can depend on record metadata
|
|
328
408
|
// whose historical owner is discovered only while retained bodies lower.
|
|
329
409
|
// If the settled answer is a fence, rerun the ordinary reachable emit so
|
|
@@ -331,12 +411,16 @@ export function lowerToIr(program, entry, moduleOrder, options = {}) {
|
|
|
331
411
|
// declarators stay unvisited, bindings block, cascades and stats match the
|
|
332
412
|
// historical compiler. This is a rare compatibility fallback; programs
|
|
333
413
|
// without such a settled fence retain checker-backed IR exactly once.
|
|
334
|
-
if (
|
|
414
|
+
if (resultLowerer.requiresHistoricalOrderRelower) {
|
|
335
415
|
const emit = new Lowerer(program, entry, moduleOrder, {
|
|
336
416
|
frontendServices: options.frontendServices,
|
|
417
|
+
projectCheckJs: options.projectCheckJs ?? false,
|
|
418
|
+
...(generalNodeStreams ? { generalNodeStreams: true } : {}),
|
|
419
|
+
...(dynNodeStreams ? { dynNodeStreams: true } : {}),
|
|
337
420
|
reachable,
|
|
338
421
|
targetPlatform,
|
|
339
422
|
startupCrash,
|
|
423
|
+
inlineRequireCycleCalls: options.inlineRequireCycleCalls,
|
|
340
424
|
ffiImports,
|
|
341
425
|
libraryCallbacks,
|
|
342
426
|
forkTargets,
|
|
@@ -344,6 +428,7 @@ export function lowerToIr(program, entry, moduleOrder, options = {}) {
|
|
|
344
428
|
ffiBindingSymbols: ffiValidation.symbolsByName,
|
|
345
429
|
externalTypes,
|
|
346
430
|
externalTypeSpecifiersByFile,
|
|
431
|
+
tierMode,
|
|
347
432
|
});
|
|
348
433
|
for (const d of extraModuleCycleDiags)
|
|
349
434
|
emit.pushDiag(d);
|
|
@@ -392,13 +477,45 @@ export function lowerToIr(program, entry, moduleOrder, options = {}) {
|
|
|
392
477
|
};
|
|
393
478
|
else if (contracts.count > 0)
|
|
394
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
|
+
}
|
|
395
508
|
if (options.coverage !== true)
|
|
396
509
|
return result;
|
|
397
|
-
const
|
|
510
|
+
const remainderPass = (general, dyn = dynNodeStreams) => new Lowerer(program, entry, moduleOrder, {
|
|
398
511
|
frontendServices: options.frontendServices,
|
|
512
|
+
projectCheckJs: options.projectCheckJs ?? false,
|
|
513
|
+
...(general ? { generalNodeStreams: true } : {}),
|
|
514
|
+
...(general && dyn ? { dynNodeStreams: true } : {}),
|
|
399
515
|
reachable,
|
|
400
516
|
remainder: true,
|
|
401
517
|
alreadyFlushed: resultLowerer.flushedSymbols,
|
|
518
|
+
inlineRequireCycleCalls: options.inlineRequireCycleCalls,
|
|
402
519
|
targetPlatform,
|
|
403
520
|
ffiImports,
|
|
404
521
|
libraryCallbacks,
|
|
@@ -407,19 +524,58 @@ export function lowerToIr(program, entry, moduleOrder, options = {}) {
|
|
|
407
524
|
ffiBindingSymbols: ffiValidation.symbolsByName,
|
|
408
525
|
externalTypes,
|
|
409
526
|
externalTypeSpecifiersByFile,
|
|
527
|
+
tierMode,
|
|
410
528
|
});
|
|
411
|
-
|
|
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 });
|
|
412
560
|
// Unreached JS statements whose fences deferred to runtime count as
|
|
413
561
|
// failed statements in the remainder's stats, so their diagnostics must
|
|
414
562
|
// travel with them: a failed statement is never left unexplained.
|
|
415
|
-
|
|
563
|
+
const covered = {
|
|
416
564
|
...result,
|
|
565
|
+
stats: { ...result.stats, statementsDynamic },
|
|
417
566
|
unreached: {
|
|
418
567
|
diagnostics: rem.diagnostics,
|
|
419
568
|
stats: rem.stats,
|
|
420
569
|
...(rem.runtimeFences.length > 0 ? { runtimeFences: rem.runtimeFences } : {}),
|
|
421
570
|
},
|
|
422
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;
|
|
423
579
|
}
|
|
424
580
|
/** The native namespace type produced by a literal static import() of a
|
|
425
581
|
* compiled program module or supported Node builtin. This syntax-level
|
|
@@ -443,7 +599,7 @@ export function staticImportNamespaceType(lowerer, expr) {
|
|
|
443
599
|
}
|
|
444
600
|
if (!ts.isCallExpression(e) || e.expression.kind !== ts.SyntaxKind.ImportKeyword)
|
|
445
601
|
return null;
|
|
446
|
-
const arg = e.arguments[0];
|
|
602
|
+
const arg = e.arguments.nodes[0];
|
|
447
603
|
if (!arg || !ts.isStringLiteralLike(arg))
|
|
448
604
|
return null;
|
|
449
605
|
const builtin = canonicalBuiltinModule(arg.text);
|
|
@@ -451,9 +607,7 @@ export function staticImportNamespaceType(lowerer, expr) {
|
|
|
451
607
|
if (moduleId === null) {
|
|
452
608
|
const symbol = lowerer.checker.getSymbolAtLocation(arg);
|
|
453
609
|
const source = symbol &&
|
|
454
|
-
|
|
455
|
-
.declarationsOf(symbol)
|
|
456
|
-
.find((decl) => ts.isSourceFile(decl) && !decl.isDeclarationFile);
|
|
610
|
+
symbol.declarations.find((decl) => ts.isSourceFile(decl) && !decl.isDeclarationFile);
|
|
457
611
|
if (source &&
|
|
458
612
|
!source.fileName.endsWith(".cts") &&
|
|
459
613
|
!isCjsJsFile(source, lowerer.program) &&
|
|
@@ -487,7 +641,7 @@ export function uncheckedOverloadHandleCall(_lowerer, _expr) {
|
|
|
487
641
|
* `never` at the ROOT stays out (`for (const v of [])`'s loop var — the
|
|
488
642
|
* dead read the f64 mapping is FOR). */
|
|
489
643
|
export function neverTaintedJsType(lowerer, node, t) {
|
|
490
|
-
if (!isJsSourceFile(
|
|
644
|
+
if (!isJsSourceFile(ts.getSourceFileOfNode(node)))
|
|
491
645
|
return false;
|
|
492
646
|
const walk = (x, depth) => {
|
|
493
647
|
if (depth === 0)
|
|
@@ -514,7 +668,7 @@ export function ladderFenceExpr(lowerer, surface, node, hint) {
|
|
|
514
668
|
const loc = locOf(node);
|
|
515
669
|
const d = noLoweringDiag(surface, loc, hint);
|
|
516
670
|
lowerer.runtimeFences.push(d);
|
|
517
|
-
const sf =
|
|
671
|
+
const sf = ts.getSourceFileOfNode(node);
|
|
518
672
|
const pos = ts.getLineAndCharacterOfPosition(sf, loc.start);
|
|
519
673
|
return {
|
|
520
674
|
kind: "strLit",
|
|
@@ -526,7 +680,7 @@ export function ladderFenceExpr(lowerer, surface, node, hint) {
|
|
|
526
680
|
export function dynFallbackType(lowerer, node, t) {
|
|
527
681
|
if (t.flags & ts.TypeFlags.Void)
|
|
528
682
|
return null;
|
|
529
|
-
if (!isJsSourceFile(
|
|
683
|
+
if (!isJsSourceFile(ts.getSourceFileOfNode(node))) {
|
|
530
684
|
if (t.flags & ts.TypeFlags.Any)
|
|
531
685
|
return DYN;
|
|
532
686
|
const symbol = t.getSymbol();
|
|
@@ -539,14 +693,15 @@ export function dynFallbackType(lowerer, node, t) {
|
|
|
539
693
|
((lowerer.checker.getTypeArguments(x)[0]?.flags ?? 0) &
|
|
540
694
|
ts.TypeFlags.Any) !==
|
|
541
695
|
0;
|
|
542
|
-
if (symbol
|
|
696
|
+
if (symbol !== undefined &&
|
|
697
|
+
ts.symbolName(symbol) === "Promise" &&
|
|
543
698
|
args[0] &&
|
|
544
699
|
(args[0].flags & ts.TypeFlags.Any || anyArray(args[0])))
|
|
545
|
-
return symbol
|
|
700
|
+
return ts.symbolName(symbol) === "Promise" && anyArray(args[0])
|
|
546
701
|
? { kind: "promise", inner: DYN }
|
|
547
702
|
: jsFallbackPromiseType(lowerer, t);
|
|
548
703
|
if (symbol &&
|
|
549
|
-
["Generator", "AsyncGenerator", "IterableIterator"].includes(symbol
|
|
704
|
+
["Generator", "AsyncGenerator", "IterableIterator"].includes(ts.symbolName(symbol)) &&
|
|
550
705
|
args.some((arg) => arg.flags & ts.TypeFlags.Any))
|
|
551
706
|
return jsFallbackGeneratorType(lowerer, t);
|
|
552
707
|
if (lowerer.checker.isArrayType(t) &&
|
|
@@ -566,19 +721,23 @@ export function dynFallbackType(lowerer, node, t) {
|
|
|
566
721
|
if (generator)
|
|
567
722
|
return generator;
|
|
568
723
|
const symbol = t.getSymbol();
|
|
569
|
-
if ((symbol
|
|
724
|
+
if (((symbol !== undefined && ts.symbolName(symbol) === "Map") ||
|
|
725
|
+
(symbol !== undefined && ts.symbolName(symbol) === "ReadonlyMap")) &&
|
|
570
726
|
lowerer.isStdlibSymbol(symbol)) {
|
|
571
727
|
const args = lowerer.checker.getTypeArguments(t);
|
|
572
728
|
if (args.length === 2) {
|
|
573
729
|
const key = lowerer.mapTypeOf(args[0]);
|
|
574
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).
|
|
575
733
|
return {
|
|
576
734
|
kind: "map",
|
|
577
735
|
key: key &&
|
|
736
|
+
key.kind !== "func" &&
|
|
578
737
|
isSupportedMapKey(key, key.kind === "union" ? lowerer.unions.get(key.unionId)?.arms : undefined)
|
|
579
738
|
? key
|
|
580
739
|
: DYN,
|
|
581
|
-
value: value && isSupportedMapValue(value) ? value : DYN,
|
|
740
|
+
value: value && value.kind !== "func" && isSupportedMapValue(value) ? value : DYN,
|
|
582
741
|
};
|
|
583
742
|
}
|
|
584
743
|
}
|
|
@@ -647,7 +806,9 @@ export function dynFallbackType(lowerer, node, t) {
|
|
|
647
806
|
* has no fixed shape. The settled value crosses the checked native boundary. */
|
|
648
807
|
function jsFallbackPromiseType(lowerer, t) {
|
|
649
808
|
const symbol = t.getSymbol();
|
|
650
|
-
if (symbol
|
|
809
|
+
if (symbol === undefined ||
|
|
810
|
+
ts.symbolName(symbol) !== "Promise" ||
|
|
811
|
+
!lowerer.isStdlibSymbol(symbol))
|
|
651
812
|
return null;
|
|
652
813
|
const inner = lowerer.checker.getTypeArguments(t)[0];
|
|
653
814
|
return inner ? { kind: "promise", inner: lowerer.mapTypeOf(inner) ?? DYN } : null;
|
|
@@ -657,14 +818,14 @@ function jsFallbackPromiseType(lowerer, t) {
|
|
|
657
818
|
function jsFallbackGeneratorType(lowerer, t) {
|
|
658
819
|
const symbol = t.getSymbol();
|
|
659
820
|
if (!symbol ||
|
|
660
|
-
!["Generator", "AsyncGenerator", "IterableIterator"].includes(symbol
|
|
821
|
+
!["Generator", "AsyncGenerator", "IterableIterator"].includes(ts.symbolName(symbol)) ||
|
|
661
822
|
!lowerer.isStdlibSymbol(symbol))
|
|
662
823
|
return null;
|
|
663
824
|
const [yielded, returned, resumed] = lowerer.checker.getTypeArguments(t);
|
|
664
825
|
const unit = ts.TypeFlags.Void | ts.TypeFlags.Undefined | ts.TypeFlags.Never;
|
|
665
826
|
return {
|
|
666
827
|
kind: "generator",
|
|
667
|
-
...(symbol
|
|
828
|
+
...(ts.symbolName(symbol) === "AsyncGenerator" ? { async: true } : {}),
|
|
668
829
|
yieldT: yielded && yielded.flags & ts.TypeFlags.Never ? VOID : DYN,
|
|
669
830
|
retT: !returned || returned.flags & unit ? VOID : DYN,
|
|
670
831
|
nextT: !resumed || resumed.flags & unit ? UNDEFINED_T : DYN,
|
|
@@ -683,7 +844,7 @@ function jsFallbackFunctionType(lowerer, node, t) {
|
|
|
683
844
|
// slot. JS inference reports the body type (`boolean` for
|
|
684
845
|
// `enabled = true`) rather than that call-site type, so recover the
|
|
685
846
|
// syntactic optionality from the parameter declaration.
|
|
686
|
-
const decl =
|
|
847
|
+
const decl = p.valueDeclaration;
|
|
687
848
|
mapped = jsOpenObjectType(decl, mapped, lowerer.shapes, lowerer.unions);
|
|
688
849
|
const optional = decl !== undefined &&
|
|
689
850
|
ts.isParameter(decl) &&
|
|
@@ -694,9 +855,9 @@ function jsFallbackFunctionType(lowerer, node, t) {
|
|
|
694
855
|
return mapped;
|
|
695
856
|
});
|
|
696
857
|
const retT = lowerer.checker.getReturnTypeOfSignature(sig);
|
|
697
|
-
const sigDecl =
|
|
858
|
+
const sigDecl = sig.declaration;
|
|
698
859
|
const jsUnitReturn = sigDecl !== undefined &&
|
|
699
|
-
isJsSourceFile(
|
|
860
|
+
isJsSourceFile(ts.getSourceFileOfNode(sigDecl)) &&
|
|
700
861
|
(retT.flags & (ts.TypeFlags.Null | ts.TypeFlags.Undefined)) !== 0;
|
|
701
862
|
const ret = jsUnitReturn
|
|
702
863
|
? DYN
|
|
@@ -720,20 +881,21 @@ function jsArgumentsFunctionType(lowerer, t) {
|
|
|
720
881
|
lowerer.checker.getConstructSignatures(t).length !== 0 ||
|
|
721
882
|
lowerer.checker.getPropertiesOfType(t).length !== 0)
|
|
722
883
|
return null;
|
|
723
|
-
const decl =
|
|
884
|
+
const decl = sigs[0].declaration;
|
|
724
885
|
if (decl === undefined ||
|
|
725
886
|
!(ts.isFunctionDeclaration(decl) ||
|
|
726
887
|
ts.isFunctionExpression(decl) ||
|
|
727
888
|
ts.isArrowFunction(decl)) ||
|
|
728
|
-
!isJsSourceFile(
|
|
889
|
+
!isJsSourceFile(ts.getSourceFileOfNode(decl)))
|
|
729
890
|
return null;
|
|
730
|
-
const hasRest = decl.parameters.some((p) => p.dotDotDotToken !== undefined);
|
|
891
|
+
const hasRest = decl.parameters.nodes.some((p) => p.dotDotDotToken !== undefined);
|
|
731
892
|
if (!hasRest &&
|
|
732
893
|
(ts.isArrowFunction(decl) ||
|
|
733
894
|
!bodyReadsArguments(decl) ||
|
|
734
|
-
(decl.parameters.length > 0 &&
|
|
895
|
+
(decl.parameters.nodes.length > 0 &&
|
|
896
|
+
!isNodeEsmFile(ts.getSourceFileOfNode(decl), lowerer.program))))
|
|
735
897
|
return null;
|
|
736
|
-
const shapes = paramShapes(lowerer, decl.parameters);
|
|
898
|
+
const shapes = paramShapes(lowerer, decl.parameters.nodes);
|
|
737
899
|
const retType = lowerer.checker.getReturnTypeOfSignature(sigs[0]);
|
|
738
900
|
const ret = retType.flags & (ts.TypeFlags.Null | ts.TypeFlags.Undefined)
|
|
739
901
|
? DYN
|
|
@@ -755,15 +917,15 @@ function pureSingleCallSignatureOf(lowerer, t) {
|
|
|
755
917
|
lowerer.checker.getConstructSignatures(t).length === 0 &&
|
|
756
918
|
sigs[0].getTypeParameters().length === 0 &&
|
|
757
919
|
sigs[0].getParameters().every((p) => {
|
|
758
|
-
const pDecl =
|
|
920
|
+
const pDecl = p.valueDeclaration;
|
|
759
921
|
return !pDecl || !ts.isParameter(pDecl) || pDecl.dotDotDotToken === undefined;
|
|
760
922
|
}) &&
|
|
761
923
|
// A SYNTHESIZED rest param (tsc's `arguments` inference — no
|
|
762
924
|
// valueDeclaration to carry the dotDotDot): param-count mismatch
|
|
763
925
|
// against the signature's declaration; the whole value stays dyn.
|
|
764
926
|
(() => {
|
|
765
|
-
const sigDecl =
|
|
766
|
-
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;
|
|
767
929
|
if (declParams !== undefined && declParams.length !== sigs[0].getParameters().length)
|
|
768
930
|
return false;
|
|
769
931
|
// tsgo never synthesizes the `arguments` pseudo-rest into the
|
|
@@ -818,7 +980,7 @@ export function jsFuncNameOf(node, lowerer) {
|
|
|
818
980
|
if (!symbol || seen.has(symbol))
|
|
819
981
|
break;
|
|
820
982
|
seen.add(symbol);
|
|
821
|
-
const declaration =
|
|
983
|
+
const declaration = symbol.valueDeclaration;
|
|
822
984
|
if (declaration && ts.isFunctionDeclaration(declaration)) {
|
|
823
985
|
n = declaration;
|
|
824
986
|
break;
|
|
@@ -871,6 +1033,25 @@ function panicSafe(query, fallback) {
|
|
|
871
1033
|
throw e;
|
|
872
1034
|
}
|
|
873
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
|
+
}
|
|
874
1055
|
export class Lowerer {
|
|
875
1056
|
program;
|
|
876
1057
|
entry;
|
|
@@ -879,6 +1060,12 @@ export class Lowerer {
|
|
|
879
1060
|
checker;
|
|
880
1061
|
diags = [];
|
|
881
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;
|
|
882
1069
|
/** Immutable callable aliases and compiler-generated adapters. The map
|
|
883
1070
|
* is symbol-keyed, so shadowing and cross-module imports keep the same
|
|
884
1071
|
* exact binding discipline as globals/functions. */
|
|
@@ -907,7 +1094,7 @@ export class Lowerer {
|
|
|
907
1094
|
* indexed-read analysis and expression lowering share one instance, so a
|
|
908
1095
|
* read's representation and its callers' signatures always agree. */
|
|
909
1096
|
get stringIndexBounds() {
|
|
910
|
-
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);
|
|
911
1098
|
return this.stringIndexBoundsCache;
|
|
912
1099
|
}
|
|
913
1100
|
/** Syntactic writes indexed once per JS scope. Symbol and RHS type
|
|
@@ -1098,7 +1285,29 @@ export class Lowerer {
|
|
|
1098
1285
|
/** Non-null while an instance body lowers: type-parameter symbol →
|
|
1099
1286
|
* concrete IR type, consulted inside mapType's recursion. */
|
|
1100
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;
|
|
1101
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();
|
|
1102
1311
|
/** The ts-level twin of typeParamBindings, non-null while a CALL-keyed
|
|
1103
1312
|
* instance body lowers: type-parameter symbol → the bound CHECKER type,
|
|
1104
1313
|
* consulted where the mapped IrType has already widened away information
|
|
@@ -1112,6 +1321,19 @@ export class Lowerer {
|
|
|
1112
1321
|
* typeParamBindings — the checker has no `T` to substitute, so the
|
|
1113
1322
|
* binding rides the node-type accessor instead of mapType. */
|
|
1114
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;
|
|
1115
1337
|
/** IMPLICIT-ANY instances lowered EAGERLY at first demand (their return
|
|
1116
1338
|
* types are inferred from the body — the call site needs them settled),
|
|
1117
1339
|
* collected here for run()'s function list (the liftedFns discipline). */
|
|
@@ -1127,8 +1349,13 @@ export class Lowerer {
|
|
|
1127
1349
|
* their symbol/node keys; no module-level cache should retain a pass. */
|
|
1128
1350
|
classSymbolKeys = new Map();
|
|
1129
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();
|
|
1130
1355
|
httpClientFnBindings = new Map();
|
|
1131
1356
|
streamPropMutatedSyms = null;
|
|
1357
|
+
/** Whether some source reads process.exitCode (processReadsExitCode). */
|
|
1358
|
+
readsExitCode = null;
|
|
1132
1359
|
requestInitPropMutatedSyms = null;
|
|
1133
1360
|
emitterEventTable = null;
|
|
1134
1361
|
emitterComputedPatterns = [];
|
|
@@ -1157,6 +1384,12 @@ export class Lowerer {
|
|
|
1157
1384
|
* carry undefined at runtime. Identifier reads keep the union tag so
|
|
1158
1385
|
* typeof and later boundaries observe the real value. */
|
|
1159
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();
|
|
1160
1393
|
/** Bindings whose unchecked string arithmetic can produce either a number
|
|
1161
1394
|
* (NaN for an absent read) or a string. Preserve that result union at bare
|
|
1162
1395
|
* reads instead of applying the checker-bare string narrowing adapter. */
|
|
@@ -1169,7 +1402,9 @@ export class Lowerer {
|
|
|
1169
1402
|
/** A pipeline() function stage's `source` parameter: the IR type of what
|
|
1170
1403
|
* the pipeline passes it (the previous stage as an async iterable), set
|
|
1171
1404
|
* while the stage lowers. Parameter typing and `for await` heads read
|
|
1172
|
-
* 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). */
|
|
1173
1408
|
stageSourceTypes = new Map();
|
|
1174
1409
|
/** Set when a match result lowers to execGroups/matchGroups, the inputs
|
|
1175
1410
|
* of regex span folding. */
|
|
@@ -1179,6 +1414,10 @@ export class Lowerer {
|
|
|
1179
1414
|
* declared optional binding to that read's bare type, so presence tests
|
|
1180
1415
|
* on these bindings consult the stored tag instead. */
|
|
1181
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();
|
|
1182
1421
|
/** Concise callback/lambda returns promoted by the HOF callback prepass;
|
|
1183
1422
|
* arrows have no declaration symbol to key in fnSigsBySymbol. */
|
|
1184
1423
|
runtimeOptionalFunctionReturns = new Map();
|
|
@@ -1192,6 +1431,8 @@ export class Lowerer {
|
|
|
1192
1431
|
/** Record fields promoted to an undefined-armed union by an indexed-read
|
|
1193
1432
|
* value. The key is the concrete emitted shape and field name. */
|
|
1194
1433
|
runtimeOptionalFields = new Set();
|
|
1434
|
+
/** Bindings initialized by a Date's `toJSON()` (analyzeDateJsonResults). */
|
|
1435
|
+
dateJsonBindings = new Set();
|
|
1195
1436
|
/** Record bindings whose flow class reaches storage outside the class:
|
|
1196
1437
|
* they keep the declared layout, so an initializer from unchecked reads
|
|
1197
1438
|
* converts once instead of the binding adopting the widened variant. */
|
|
@@ -1239,7 +1480,7 @@ export class Lowerer {
|
|
|
1239
1480
|
// directly from the aliased declaration as a final read-side hook, so
|
|
1240
1481
|
// the initializer cannot fall back to a narrowing adapter.
|
|
1241
1482
|
if (ts.isIdentifier(node) && fallback?.kind === "func") {
|
|
1242
|
-
const decl =
|
|
1483
|
+
const decl = symbol.valueDeclaration;
|
|
1243
1484
|
if (decl &&
|
|
1244
1485
|
ts.isVariableDeclaration(decl) &&
|
|
1245
1486
|
!decl.type &&
|
|
@@ -1265,6 +1506,63 @@ export class Lowerer {
|
|
|
1265
1506
|
}
|
|
1266
1507
|
return fallback ?? null;
|
|
1267
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
|
+
}
|
|
1268
1566
|
runtimeOptionalIdentifierValue(node) {
|
|
1269
1567
|
if (!ts.isIdentifier(node) || this.chainRecvByNode.has(node))
|
|
1270
1568
|
return null;
|
|
@@ -1284,45 +1582,53 @@ export class Lowerer {
|
|
|
1284
1582
|
unionId: storage.type.unionId,
|
|
1285
1583
|
};
|
|
1286
1584
|
}
|
|
1287
|
-
/**
|
|
1288
|
-
*
|
|
1289
|
-
*
|
|
1290
|
-
* optional-read analysis
|
|
1291
|
-
*
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
if (slot)
|
|
1295
|
-
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) {
|
|
1296
1592
|
let origin = node;
|
|
1297
1593
|
while (ts.isParenthesizedExpression(origin))
|
|
1298
1594
|
origin = origin.expression;
|
|
1299
|
-
|
|
1595
|
+
if (ts.isElementAccessExpression(origin) || ts.isPropertyAccessExpression(origin))
|
|
1596
|
+
return true;
|
|
1300
1597
|
if (ts.isCallExpression(origin)) {
|
|
1301
1598
|
const name = ts.isPropertyAccessExpression(origin.expression)
|
|
1302
1599
|
? origin.expression.name
|
|
1303
1600
|
: origin.expression;
|
|
1304
1601
|
const symbol = ts.isIdentifier(name) ? this.resolveValueSymbol(name) : undefined;
|
|
1305
1602
|
const signature = symbol ? this.fnSigsBySymbol.get(symbol) : undefined;
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
(signature
|
|
1309
|
-
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));
|
|
1310
1606
|
}
|
|
1311
1607
|
if (ts.isIdentifier(origin)) {
|
|
1312
1608
|
const local = this.resolveLocal(origin);
|
|
1313
1609
|
const root = local ? this.runtimeOptionalRootOf(local) : null;
|
|
1314
1610
|
const global = this.globalOf(origin);
|
|
1315
|
-
|
|
1316
|
-
(!!
|
|
1317
|
-
(
|
|
1318
|
-
(this.
|
|
1319
|
-
(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))));
|
|
1320
1615
|
}
|
|
1321
|
-
|
|
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))
|
|
1322
1628
|
return null;
|
|
1323
1629
|
// A checked JavaScript indexed read can already be boxed. The checker
|
|
1324
1630
|
// calls the element present, but that inference is not a runtime guard.
|
|
1325
|
-
if (isJsSourceFile(
|
|
1631
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(node)) &&
|
|
1326
1632
|
value.kind === "dynCheck" &&
|
|
1327
1633
|
value.value.type.kind === "dyn")
|
|
1328
1634
|
return value.value;
|
|
@@ -1338,7 +1644,7 @@ export class Lowerer {
|
|
|
1338
1644
|
* value. Reuse a plain read directly or stabilize an effectful receiver
|
|
1339
1645
|
* once, throw Node's member-read TypeError for a unit arm, and extract the
|
|
1340
1646
|
* expected present arm otherwise. */
|
|
1341
|
-
runtimeOptionalPropertyReceiver(node, value, expected, member) {
|
|
1647
|
+
runtimeOptionalPropertyReceiver(node, value, expected, member, action = "read") {
|
|
1342
1648
|
const source = this.runtimeOptionalSourceValue(node, value);
|
|
1343
1649
|
if (source?.type.kind !== "union")
|
|
1344
1650
|
return null;
|
|
@@ -1376,7 +1682,7 @@ export class Lowerer {
|
|
|
1376
1682
|
type: BOOL,
|
|
1377
1683
|
loc,
|
|
1378
1684
|
},
|
|
1379
|
-
then: nodeThrowExpr(1, "", `Cannot
|
|
1685
|
+
then: nodeThrowExpr(1, "", `Cannot ${action} properties of ${unit} (${action === "read" ? "reading" : "setting"} '${member}')`, expected, loc),
|
|
1380
1686
|
else_: result,
|
|
1381
1687
|
type: expected,
|
|
1382
1688
|
loc,
|
|
@@ -1543,10 +1849,28 @@ export class Lowerer {
|
|
|
1543
1849
|
/** Settled generic class-rest metadata requires the historical emit
|
|
1544
1850
|
* fallback so its fence can poison the original statement atomically. */
|
|
1545
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();
|
|
1546
1867
|
/** Helpers that snapshot shape declaration order into their bodies.
|
|
1547
1868
|
* Reachability lowers inits before the declarations they discover, so
|
|
1548
1869
|
* these rebuild after the worklist restores historical shape metadata. */
|
|
1549
1870
|
shapeOrderHelperFinalizers = [];
|
|
1871
|
+
/** Construction witnesses that choose each shape's enumeration order
|
|
1872
|
+
* once lowering settles (key-order-witness.ts). */
|
|
1873
|
+
keyOrder = new KeyOrderNotes();
|
|
1550
1874
|
/** Emit-override specializations (`%C.emit:<event>` — lower-event-emitter.ts's
|
|
1551
1875
|
* emit-overrides block): interned names, the drive-loop queue, and the
|
|
1552
1876
|
* currently-lowering specialization's context (the super-forward
|
|
@@ -1558,6 +1882,9 @@ export class Lowerer {
|
|
|
1558
1882
|
/** Generated value helpers, keyed by operation and type. Callers own
|
|
1559
1883
|
* their key prefixes; this includes more than structural conversions. */
|
|
1560
1884
|
valueHelpers = new Map();
|
|
1885
|
+
/** structuralNarrowing's assignable classes, keyed by static and
|
|
1886
|
+
* narrowed class name. */
|
|
1887
|
+
structuralClassPeers = new Map();
|
|
1561
1888
|
/** Interned node:assert helpers (deep-equality comparisons keyed by
|
|
1562
1889
|
* typeKey, throws wrappers keyed by callback type + expected class) —
|
|
1563
1890
|
* the valueHelpers pattern with its own namespace. */
|
|
@@ -1578,6 +1905,12 @@ export class Lowerer {
|
|
|
1578
1905
|
/** Method adapter names are owned by class-method-values. Looking them
|
|
1579
1906
|
* up must not scan and retain every unrelated lifted function. */
|
|
1580
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();
|
|
1581
1914
|
classMethodValueSelections = new Map();
|
|
1582
1915
|
/** Callee names of every interned coercion helper whose CALL mints a
|
|
1583
1916
|
* FRESH closure per evaluation (%fn.width.*, %fn.adapt.*,
|
|
@@ -1599,6 +1932,10 @@ export class Lowerer {
|
|
|
1599
1932
|
* lifted lazily as module-level functions and interned per accessor
|
|
1600
1933
|
* declaration: member reads call the getter (lower-exprs). */
|
|
1601
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();
|
|
1602
1939
|
/** Interned `%iter.drain.<n>` helpers (classIteratorDrainCall): one per
|
|
1603
1940
|
* receiver class — the eager drain of a class iterable's protocol into
|
|
1604
1941
|
* a fresh element array, behind array/call spreads. */
|
|
@@ -1623,6 +1960,8 @@ export class Lowerer {
|
|
|
1623
1960
|
* so named imports, namespace reads, CommonJS bindings, and alias chains
|
|
1624
1961
|
* all reuse one immortal zero-capture closure. */
|
|
1625
1962
|
builtinCallableValueFns = new Map();
|
|
1963
|
+
/** Each builtin function-value adapter's Node name, for boxed values. */
|
|
1964
|
+
builtinCallableValueNames = new Map();
|
|
1626
1965
|
/** Optional-chain lowering state. While a chain body lowers, the guarded
|
|
1627
1966
|
* receiver NODE reads as a chainRecv (typed by the narrowed arm) instead
|
|
1628
1967
|
* of re-lowering, its checker type reads non-nullish (typeOf), and the
|
|
@@ -1664,6 +2003,10 @@ export class Lowerer {
|
|
|
1664
2003
|
/** Named method slots observed before class collection need a callable
|
|
1665
2004
|
* ABI and shared prototype descriptors instead of call-site specialization. */
|
|
1666
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();
|
|
1667
2010
|
/** Typed calls through class-backed protocols, by signature; class
|
|
1668
2011
|
* dynamic dispatch adds their native arms (class-protocol-dispatch.ts). */
|
|
1669
2012
|
protocolDispatches = new Map();
|
|
@@ -1681,6 +2024,9 @@ export class Lowerer {
|
|
|
1681
2024
|
* base vtable signature is collected. Unused checked slots carry undefined. */
|
|
1682
2025
|
virtualJsMethodArity = new Map();
|
|
1683
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();
|
|
1684
2030
|
checkedVirtualJsAccessors = new Set();
|
|
1685
2031
|
checkedVirtualJsValueReturns = new Set();
|
|
1686
2032
|
/** The class whose members are lowering — `super` binds lexically to it
|
|
@@ -1704,6 +2050,10 @@ export class Lowerer {
|
|
|
1704
2050
|
* prepended by lowerFileInit so the bindings are live before any
|
|
1705
2051
|
* top-level statement runs. */
|
|
1706
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();
|
|
1707
2057
|
/** Dynamic `import("literal")` resolutions, keyed
|
|
1708
2058
|
* `fileName\u0000specifier` (collectDynamicImports fills it during npm
|
|
1709
2059
|
* collection; lowerDynamicImportCall reads it per site). */
|
|
@@ -1729,6 +2079,12 @@ export class Lowerer {
|
|
|
1729
2079
|
workerTargets;
|
|
1730
2080
|
workerTargetIdByPath = new Map();
|
|
1731
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;
|
|
1732
2088
|
/** The program constructs a LifetimeRegion (lifetime-regions.ts). */
|
|
1733
2089
|
usesLifetimeRegions = false;
|
|
1734
2090
|
/** Per-directory answers of experimental-import.ts's declaration-file test. */
|
|
@@ -1739,6 +2095,12 @@ export class Lowerer {
|
|
|
1739
2095
|
internTableHelpers = new Map();
|
|
1740
2096
|
/** Each InternTable name's type arguments and first construction site. */
|
|
1741
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();
|
|
1742
2104
|
forkTargetIdByPath = new Map();
|
|
1743
2105
|
/** Namespace ModuleBlocks this program lowers, filled by splitFiles:
|
|
1744
2106
|
* "flattened" — an instantiated namespace whose body joined the file's
|
|
@@ -1823,6 +2185,9 @@ export class Lowerer {
|
|
|
1823
2185
|
// top level, top = the innermost nested function currently lowering).
|
|
1824
2186
|
fnStack = [];
|
|
1825
2187
|
liftedFns = [];
|
|
2188
|
+
/** Runtime-provided classes used as values (defineClassValueConstruct),
|
|
2189
|
+
* by IR class name. */
|
|
2190
|
+
runtimeClassValues = new Map();
|
|
1826
2191
|
/** One Error-method helper belongs to this lowering session. Its cached
|
|
1827
2192
|
* dispatch revision needs no weak-key identity or process-global state. */
|
|
1828
2193
|
errorMethodDispatchRevision = null;
|
|
@@ -1849,6 +2214,17 @@ export class Lowerer {
|
|
|
1849
2214
|
* by class name (cycle-initialization.ts). */
|
|
1850
2215
|
classInitFlags = new Map();
|
|
1851
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 = [];
|
|
1852
2228
|
get ctx() {
|
|
1853
2229
|
const top = this.fnStack[this.fnStack.length - 1];
|
|
1854
2230
|
if (!top)
|
|
@@ -1884,6 +2260,16 @@ export class Lowerer {
|
|
|
1884
2260
|
/** Coverage remainder mode: the reachability gate inverts (see wantBody)
|
|
1885
2261
|
* and no module is built. */
|
|
1886
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 = [];
|
|
1887
2273
|
/** Deferred collection diagnostics (failed signatures/class shapes) by
|
|
1888
2274
|
* declaration symbol: an unreached declaration must not fail the build,
|
|
1889
2275
|
* so its diagnostics wait until a reference makes them relevant. */
|
|
@@ -1908,6 +2294,9 @@ export class Lowerer {
|
|
|
1908
2294
|
targetPlatform;
|
|
1909
2295
|
/** LowererMode.startupCrash — buildMain opens %main with the throw. */
|
|
1910
2296
|
startupCrash;
|
|
2297
|
+
/** The project's tsconfig sets `checkJs`. */
|
|
2298
|
+
projectCheckJs;
|
|
2299
|
+
checkedJsFiles = new Map();
|
|
1911
2300
|
/** Outbound native bindings by their source-level ambient name. */
|
|
1912
2301
|
ffiImports;
|
|
1913
2302
|
libraryCallbacks;
|
|
@@ -1946,6 +2335,33 @@ export class Lowerer {
|
|
|
1946
2335
|
* package. Only populated while the registry is active; the remainder
|
|
1947
2336
|
* pass skips it (attribution describes the build). */
|
|
1948
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
|
+
}
|
|
1949
2365
|
/** Bumps the per-file attribution counter (no-op unless provenance is
|
|
1950
2366
|
* active and this is the emit/discovery lane — mirror the CALLER's
|
|
1951
2367
|
* suppressStats guard, this method only gates remainder). */
|
|
@@ -1964,25 +2380,31 @@ export class Lowerer {
|
|
|
1964
2380
|
this.program = program;
|
|
1965
2381
|
this.entry = entry;
|
|
1966
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 ?? [];
|
|
1967
2389
|
this.frontendServices = mode.frontendServices;
|
|
2390
|
+
this.inlineRequireCycleCalls = mode.inlineRequireCycleCalls ?? new Set();
|
|
2391
|
+
this.libraryCallbacks = mode.libraryCallbacks ?? false;
|
|
2392
|
+
this.projectCheckJs = mode.projectCheckJs ?? false;
|
|
1968
2393
|
this.reachable = mode.reachable ?? null;
|
|
1969
2394
|
this.remainder = mode.remainder ?? false;
|
|
1970
|
-
this.alreadyFlushed = mode.alreadyFlushed ?? new Set();
|
|
1971
|
-
this.targetPlatform = mode.targetPlatform ?? process.platform;
|
|
1972
2395
|
this.startupCrash = mode.startupCrash ?? null;
|
|
1973
|
-
this.
|
|
1974
|
-
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);
|
|
1975
2400
|
this.workerTargets = mode.workerTargets ?? [];
|
|
1976
2401
|
this.workerTargets.forEach((sf, id) => {
|
|
1977
2402
|
this.workerTargetIdByPath.set(tsgoPath(resolve(sf.fileName)), id);
|
|
1978
2403
|
});
|
|
1979
|
-
this.forkTargets = mode.forkTargets ?? [];
|
|
1980
2404
|
this.forkTargets.forEach((sf, id) => {
|
|
1981
2405
|
this.forkTargetIdByPath.set(tsgoPath(resolve(sf.fileName)), id);
|
|
1982
2406
|
});
|
|
1983
2407
|
this.ffiImportsByName = new Map(this.ffiImports.map((entry) => [entry.name, entry]));
|
|
1984
|
-
this.ffiBindingSymbols = mode.ffiBindingSymbols ?? null;
|
|
1985
|
-
this.externalTypes = mode.externalTypes ?? new Map();
|
|
1986
2408
|
this.externalTypeSpecifiersByFile =
|
|
1987
2409
|
mode.externalTypeSpecifiersByFile ?? directExternalTypeSpecifiersByFile(this.externalTypes);
|
|
1988
2410
|
this.checker = program.getTypeChecker();
|
|
@@ -1993,18 +2415,25 @@ export class Lowerer {
|
|
|
1993
2415
|
classNamer: this.classNamer,
|
|
1994
2416
|
resolveTypeParam: this.typeParamResolver,
|
|
1995
2417
|
resolveTypeParamTs: this.typeParamTsResolver,
|
|
2418
|
+
isErasing: () => this.erasingDepth > 0,
|
|
1996
2419
|
genericClassInstance: (decl, ref, mapArgument) => this.genericClassInstanceType(decl, ref, mapArgument),
|
|
2420
|
+
runtimeClassValue: (type) => runtimeClassValueOfType(this, type),
|
|
1997
2421
|
mixinClassInstance: (decl) => this.mixinTypeContext && this.mixinTypeContext.classNode === decl
|
|
1998
2422
|
? { kind: "object", className: this.mixinTypeContext.className }
|
|
1999
2423
|
: null,
|
|
2000
|
-
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 };
|
|
2001
2430
|
// Computed heritage can close over parameters of its factory.
|
|
2002
2431
|
// A speculative checker query outside that factory must not lower
|
|
2003
2432
|
// the extends expression in the caller's lexical scope.
|
|
2004
2433
|
if (!this.classes.has(this.classNamer(decl)) &&
|
|
2005
2434
|
!this.collectingExprClasses.has(decl) &&
|
|
2006
|
-
decl.heritageClauses?.some((clause) => clause.token === ts.SyntaxKind.ExtendsKeyword &&
|
|
2007
|
-
clause.types.some((base) => {
|
|
2435
|
+
decl.heritageClauses?.nodes.some((clause) => clause.token === ts.SyntaxKind.ExtendsKeyword &&
|
|
2436
|
+
clause.types.nodes.some((base) => {
|
|
2008
2437
|
const expression = base.expression;
|
|
2009
2438
|
if (ts.isCallExpression(expression))
|
|
2010
2439
|
return true;
|
|
@@ -2032,13 +2461,14 @@ export class Lowerer {
|
|
|
2032
2461
|
continue;
|
|
2033
2462
|
if (this.localClassInstantiations.some((entry) => entry.owner === parent))
|
|
2034
2463
|
break;
|
|
2035
|
-
if (parent.typeParameters?.length ||
|
|
2036
|
-
(implicitMonoFile(
|
|
2464
|
+
if (parent.typeParameters?.nodes.length ||
|
|
2465
|
+
(implicitMonoFile(ts.getSourceFileOfNode(parent)) &&
|
|
2466
|
+
monomorphizedImplicit(this, parent)))
|
|
2037
2467
|
return null;
|
|
2038
2468
|
}
|
|
2039
2469
|
const className = this.classNamer(decl);
|
|
2040
|
-
if (!this.collectingExprClasses.has(decl))
|
|
2041
|
-
|
|
2470
|
+
if (!this.collectingExprClasses.has(decl) && !this.collectLocalClassForType(decl))
|
|
2471
|
+
return null;
|
|
2042
2472
|
return { kind: "object", className };
|
|
2043
2473
|
},
|
|
2044
2474
|
mixinIntersectionInstance: (widened) => mixinIntersectionInstanceType(this, widened),
|
|
@@ -2047,18 +2477,23 @@ export class Lowerer {
|
|
|
2047
2477
|
isNpmFile: this.isNpmFile,
|
|
2048
2478
|
isExternalTypeFile: (sf) => this.externalTypeSpecifiersByFile.has(tsgoPath(resolve(sf.fileName))),
|
|
2049
2479
|
typeMemo: this.typeMemo,
|
|
2480
|
+
...(this.generalNodeStreams ? { generalNodeStreams: true } : {}),
|
|
2481
|
+
...(this.dynNodeStreams ? { dynNodeStreams: true } : {}),
|
|
2050
2482
|
canMemoizeType: () => this.typeParamBindings === null &&
|
|
2051
2483
|
this.typeParamTsBindings === null &&
|
|
2052
2484
|
this.mixinTypeContext === null,
|
|
2053
2485
|
// fileTag is filled just below; the hook is only ever CALLED during
|
|
2054
2486
|
// lowering, long after the constructor completes.
|
|
2055
2487
|
isProgramFile: (sf) => this.fileTag.has(sf),
|
|
2056
|
-
lifetimeRegionClass: (decl) => isExperimentalDeclarationFile(
|
|
2488
|
+
lifetimeRegionClass: (decl) => isExperimentalDeclarationFile(ts.getSourceFileOfNode(decl), this.experimentalFiles)
|
|
2057
2489
|
? lifetimeRegionType(this)
|
|
2058
2490
|
: null,
|
|
2059
|
-
internTableClass: (decl) => isExperimentalDeclarationFile(
|
|
2491
|
+
internTableClass: (decl) => isExperimentalDeclarationFile(ts.getSourceFileOfNode(decl), this.experimentalFiles)
|
|
2060
2492
|
? internTableType(this)
|
|
2061
2493
|
: null,
|
|
2494
|
+
threadSlotsClass: (decl) => isExperimentalDeclarationFile(ts.getSourceFileOfNode(decl), this.experimentalFiles)
|
|
2495
|
+
? threadSlotsType(this)
|
|
2496
|
+
: null,
|
|
2062
2497
|
moduleNamespaceId: (type) => this.moduleNamespaceIdOfType(type),
|
|
2063
2498
|
};
|
|
2064
2499
|
// Modules reachable only through literal import() joined
|
|
@@ -2070,11 +2505,25 @@ export class Lowerer {
|
|
|
2070
2505
|
});
|
|
2071
2506
|
if (this.moduleOrder.length === 0)
|
|
2072
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);
|
|
2073
2511
|
this.registerBuiltinErrorClasses();
|
|
2074
2512
|
registerBuiltinEmitterClass(this);
|
|
2075
2513
|
registerBuiltinStreamClasses(this);
|
|
2076
2514
|
registerBuiltinEventTargetClasses(this);
|
|
2077
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
|
+
}
|
|
2078
2527
|
registerBuiltinErrorClasses() {
|
|
2079
2528
|
return registerBuiltinErrorClasses(this);
|
|
2080
2529
|
}
|
|
@@ -2084,10 +2533,45 @@ export class Lowerer {
|
|
|
2084
2533
|
return this.classProtocols.usesCheckedIdentity(type);
|
|
2085
2534
|
}
|
|
2086
2535
|
/** Declared class fields may store a DYN value only when its static type
|
|
2087
|
-
*
|
|
2088
|
-
*
|
|
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. */
|
|
2089
2542
|
classFieldStoresDyn(type) {
|
|
2090
|
-
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)));
|
|
2091
2575
|
}
|
|
2092
2576
|
/** The nominal identity of a checker module-namespace type. Program
|
|
2093
2577
|
* modules use their normalized absolute source name; supported builtins
|
|
@@ -2098,7 +2582,7 @@ export class Lowerer {
|
|
|
2098
2582
|
return null;
|
|
2099
2583
|
if (sym.flags & ts.SymbolFlags.Alias)
|
|
2100
2584
|
sym = this.checker.getAliasedSymbol(sym);
|
|
2101
|
-
for (const decl of
|
|
2585
|
+
for (const decl of sym.declarations) {
|
|
2102
2586
|
if (ts.isSourceFile(decl) &&
|
|
2103
2587
|
!decl.isDeclarationFile &&
|
|
2104
2588
|
!decl.fileName.endsWith(".cts") &&
|
|
@@ -2129,6 +2613,12 @@ export class Lowerer {
|
|
|
2129
2613
|
builtinStreamInfoOf(symbol) {
|
|
2130
2614
|
return builtinStreamInfoOf(this, symbol);
|
|
2131
2615
|
}
|
|
2616
|
+
builtinClassAliasOf(symbol) {
|
|
2617
|
+
return builtinClassAliasOf(this, symbol);
|
|
2618
|
+
}
|
|
2619
|
+
defineClassValueConstruct(info) {
|
|
2620
|
+
defineClassValueConstruct(this, info);
|
|
2621
|
+
}
|
|
2132
2622
|
/** Program-wide qualified name for a top-level declaration. */
|
|
2133
2623
|
qualify(sf, name) {
|
|
2134
2624
|
return `${this.fileTag.get(sf) ?? ""}${name}`;
|
|
@@ -2150,8 +2640,8 @@ export class Lowerer {
|
|
|
2150
2640
|
}
|
|
2151
2641
|
return false;
|
|
2152
2642
|
})()
|
|
2153
|
-
? this.qualify(
|
|
2154
|
-
: 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"));
|
|
2155
2645
|
for (let index = this.localClassInstantiations.length - 1; index >= 0; index--) {
|
|
2156
2646
|
const entry = this.localClassInstantiations[index];
|
|
2157
2647
|
for (let parent = decl.parent; parent && !ts.isSourceFile(parent); parent = parent.parent) {
|
|
@@ -2196,8 +2686,10 @@ export class Lowerer {
|
|
|
2196
2686
|
ts.isPropertyAccessExpression(ident.parent) &&
|
|
2197
2687
|
ident.parent.name === ident) {
|
|
2198
2688
|
const recv = ident.parent.expression;
|
|
2199
|
-
if (
|
|
2200
|
-
const dep =
|
|
2689
|
+
if (this.cjsLocalModuleBindingOf(recv)) {
|
|
2690
|
+
const dep = ts.isIdentifier(recv)
|
|
2691
|
+
? this.localModuleBindingDepOf(recv)
|
|
2692
|
+
: this.cjsModuleRefDepOf(recv);
|
|
2201
2693
|
const exported = dep ? this.cjsModuleExportSymbol(dep, ident.text) : undefined;
|
|
2202
2694
|
// A createRequire call is typed as `any`, so tsgo can manufacture a
|
|
2203
2695
|
// transient property symbol with no relation to the target module.
|
|
@@ -2290,7 +2782,7 @@ export class Lowerer {
|
|
|
2290
2782
|
}
|
|
2291
2783
|
if (ts.isCallExpression(value)) {
|
|
2292
2784
|
if (value.expression.kind === ts.SyntaxKind.ImportKeyword) {
|
|
2293
|
-
const spec = value.arguments[0];
|
|
2785
|
+
const spec = value.arguments.nodes[0];
|
|
2294
2786
|
return spec !== undefined &&
|
|
2295
2787
|
ts.isStringLiteralLike(spec) &&
|
|
2296
2788
|
this.externalTypes.has(spec.text)
|
|
@@ -2299,8 +2791,8 @@ export class Lowerer {
|
|
|
2299
2791
|
}
|
|
2300
2792
|
if (ts.isIdentifier(value.expression) &&
|
|
2301
2793
|
value.expression.text === "require" &&
|
|
2302
|
-
value.arguments.length === 1) {
|
|
2303
|
-
const spec = value.arguments[0];
|
|
2794
|
+
value.arguments.nodes.length === 1) {
|
|
2795
|
+
const spec = value.arguments.nodes[0];
|
|
2304
2796
|
if (ts.isStringLiteralLike(spec) && this.externalTypes.has(spec.text))
|
|
2305
2797
|
return spec.text;
|
|
2306
2798
|
}
|
|
@@ -2337,7 +2829,7 @@ export class Lowerer {
|
|
|
2337
2829
|
* every project-module spelling. */
|
|
2338
2830
|
moduleSourceFileOf(from, spec) {
|
|
2339
2831
|
const moduleSymbol = this.checker.getSymbolAtLocation(spec);
|
|
2340
|
-
for (const decl of moduleSymbol ?
|
|
2832
|
+
for (const decl of moduleSymbol ? moduleSymbol.declarations : []) {
|
|
2341
2833
|
if (ts.isSourceFile(decl))
|
|
2342
2834
|
return decl;
|
|
2343
2835
|
}
|
|
@@ -2373,9 +2865,7 @@ export class Lowerer {
|
|
|
2373
2865
|
if (!ts.isIdentifier(value))
|
|
2374
2866
|
return null;
|
|
2375
2867
|
const symbol = this.checker.getSymbolAtLocation(value);
|
|
2376
|
-
const namespaceDecl = symbol
|
|
2377
|
-
? this.checker.declarationsOf(symbol).find(ts.isNamespaceImport)
|
|
2378
|
-
: undefined;
|
|
2868
|
+
const namespaceDecl = symbol ? symbol.declarations.find(ts.isNamespaceImport) : undefined;
|
|
2379
2869
|
if (namespaceDecl === undefined)
|
|
2380
2870
|
return null;
|
|
2381
2871
|
const importDecl = namespaceDecl.parent?.parent;
|
|
@@ -2383,7 +2873,7 @@ export class Lowerer {
|
|
|
2383
2873
|
return null;
|
|
2384
2874
|
if (this.externalTypes.has(importDecl.moduleSpecifier.text))
|
|
2385
2875
|
return importDecl.moduleSpecifier.text;
|
|
2386
|
-
const dep = this.moduleSourceFileOf(
|
|
2876
|
+
const dep = this.moduleSourceFileOf(ts.getSourceFileOfNode(importDecl), importDecl.moduleSpecifier);
|
|
2387
2877
|
return dep !== null && !dep.isDeclarationFile
|
|
2388
2878
|
? this.externalTypeSpecifierOfModuleExport(dep, member, new Set(), new Set())
|
|
2389
2879
|
: null;
|
|
@@ -2392,7 +2882,7 @@ export class Lowerer {
|
|
|
2392
2882
|
if (symbol === undefined || seenSymbols.has(symbol))
|
|
2393
2883
|
return null;
|
|
2394
2884
|
seenSymbols.add(symbol);
|
|
2395
|
-
const declarations =
|
|
2885
|
+
const declarations = symbol.declarations;
|
|
2396
2886
|
// Route-aware alias hops run before declaration-file ownership. An
|
|
2397
2887
|
// exact import must keep the specifier it actually named, rather than
|
|
2398
2888
|
// inheriting whichever alias happened to register the shared file last.
|
|
@@ -2439,13 +2929,13 @@ export class Lowerer {
|
|
|
2439
2929
|
// property accesses resolve their selected member separately above.
|
|
2440
2930
|
if (importedName === null)
|
|
2441
2931
|
return null;
|
|
2442
|
-
const dep = this.moduleSourceFileOf(
|
|
2932
|
+
const dep = this.moduleSourceFileOf(ts.getSourceFileOfNode(decl), specNode);
|
|
2443
2933
|
return dep !== null && !dep.isDeclarationFile
|
|
2444
2934
|
? this.externalTypeSpecifierOfModuleExport(dep, importedName, seenSymbols, seenExports)
|
|
2445
2935
|
: null;
|
|
2446
2936
|
}
|
|
2447
2937
|
for (const decl of declarations) {
|
|
2448
|
-
const owners = this.externalTypeSpecifiersByFile.get(tsgoPath(resolve(
|
|
2938
|
+
const owners = this.externalTypeSpecifiersByFile.get(tsgoPath(resolve(ts.getSourceFileOfNode(decl).fileName)));
|
|
2449
2939
|
if (owners !== undefined && owners.length > 0)
|
|
2450
2940
|
return owners[0];
|
|
2451
2941
|
}
|
|
@@ -2468,9 +2958,7 @@ export class Lowerer {
|
|
|
2468
2958
|
for (let hop = 0; sym !== undefined && hop < 32; hop++) {
|
|
2469
2959
|
if (hop > 0 && sym.flags & ts.SymbolFlags.Alias && this.globalsBySymbol.has(sym))
|
|
2470
2960
|
return sym;
|
|
2471
|
-
const d =
|
|
2472
|
-
.declarationsOf(sym)
|
|
2473
|
-
.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));
|
|
2474
2962
|
let spec;
|
|
2475
2963
|
let name;
|
|
2476
2964
|
if (d && ts.isImportClause(d) && ts.isImportDeclaration(d.parent)) {
|
|
@@ -2491,7 +2979,7 @@ export class Lowerer {
|
|
|
2491
2979
|
}
|
|
2492
2980
|
if (d === undefined || spec === undefined || !ts.isStringLiteral(spec) || name !== "default")
|
|
2493
2981
|
return null;
|
|
2494
|
-
const dep = resolveImport(this.program,
|
|
2982
|
+
const dep = resolveImport(this.program, ts.getSourceFileOfNode(d), spec.text);
|
|
2495
2983
|
if (!dep)
|
|
2496
2984
|
return null;
|
|
2497
2985
|
sym = defaultExportSymbolOf(this, dep) ?? undefined;
|
|
@@ -2521,7 +3009,7 @@ export class Lowerer {
|
|
|
2521
3009
|
* see resolveValueSymbol. Null when `symbol` is not such a property (or
|
|
2522
3010
|
* the property's value is not a plain identifier reference). */
|
|
2523
3011
|
cjsExportValueSymbol(symbol) {
|
|
2524
|
-
const d =
|
|
3012
|
+
const d = symbol.declarations[0];
|
|
2525
3013
|
if (!d)
|
|
2526
3014
|
return null;
|
|
2527
3015
|
// MEMBER-form class exports (`exports.C = C` — commander's error.js):
|
|
@@ -2563,8 +3051,6 @@ export class Lowerer {
|
|
|
2563
3051
|
: null;
|
|
2564
3052
|
if (!assign || assign.operatorToken.kind !== ts.SyntaxKind.EqualsToken)
|
|
2565
3053
|
return null;
|
|
2566
|
-
if (!ts.isIdentifier(assign.right))
|
|
2567
|
-
return null;
|
|
2568
3054
|
const stmt = assign.parent;
|
|
2569
3055
|
if (!stmt || !ts.isExpressionStatement(stmt) || !ts.isSourceFile(stmt.parent))
|
|
2570
3056
|
return null;
|
|
@@ -2575,12 +3061,39 @@ export class Lowerer {
|
|
|
2575
3061
|
return null;
|
|
2576
3062
|
if (cjsExportDiscardReason(stmt) !== null)
|
|
2577
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;
|
|
2578
3072
|
let value = this.checker.getSymbolAtLocation(assign.right);
|
|
2579
3073
|
if (!value)
|
|
2580
3074
|
return null;
|
|
2581
3075
|
if (value.flags & ts.SymbolFlags.Alias)
|
|
2582
3076
|
value = this.checker.getAliasedSymbol(value);
|
|
2583
|
-
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));
|
|
2584
3097
|
return isClass ? value : null;
|
|
2585
3098
|
}
|
|
2586
3099
|
/** The CommonJS JS module a DEFAULT-import binding's declaration loads
|
|
@@ -2597,19 +3110,33 @@ export class Lowerer {
|
|
|
2597
3110
|
const spec = importDecl.moduleSpecifier.text;
|
|
2598
3111
|
// Project aliases/self-references resolve through the same entry point as
|
|
2599
3112
|
// relative imports; an opted-in --npm-static package is the fallback.
|
|
2600
|
-
const dep = resolveImport(this.program,
|
|
2601
|
-
npmStaticDepSf7(this.program,
|
|
3113
|
+
const dep = resolveImport(this.program, ts.getSourceFileOfNode(importDecl), spec) ??
|
|
3114
|
+
npmStaticDepSf7(this.program, ts.getSourceFileOfNode(importDecl), spec);
|
|
2602
3115
|
if (!dep || !isJsSourceFile(dep) || isNodeEsmFile(dep, this.program))
|
|
2603
3116
|
return null;
|
|
2604
3117
|
return dep;
|
|
2605
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
|
+
}
|
|
2606
3133
|
/** The compiled module behind a require-like namespace binding: an
|
|
2607
3134
|
* ordinary CommonJS require declaration, a canonical createRequire
|
|
2608
3135
|
* declaration, or an ESM default import of CommonJS. One resolver keeps
|
|
2609
3136
|
* member-symbol fallback and namespace classification in lockstep. */
|
|
2610
3137
|
localModuleBindingDepOf(expr) {
|
|
2611
3138
|
const sym = this.checker.getSymbolAtLocation(expr);
|
|
2612
|
-
const decls = sym ?
|
|
3139
|
+
const decls = sym ? sym.declarations : [];
|
|
2613
3140
|
const decl = decls.find(ts.isImportClause) ?? decls[0];
|
|
2614
3141
|
if (!decl)
|
|
2615
3142
|
return null;
|
|
@@ -2617,10 +3144,17 @@ export class Lowerer {
|
|
|
2617
3144
|
return this.cjsDefaultImportDepOf(decl);
|
|
2618
3145
|
if (!ts.isVariableDeclaration(decl) || !ts.isIdentifier(decl.name) || !decl.initializer)
|
|
2619
3146
|
return null;
|
|
3147
|
+
{
|
|
3148
|
+
const interop = tscInteropModuleOf(this, expr);
|
|
3149
|
+
if (interop !== null)
|
|
3150
|
+
return cjsNamespaceModule(this, interop.dep) ? interop.dep : null;
|
|
3151
|
+
}
|
|
2620
3152
|
const directSpec = requireSpecOf(decl.initializer);
|
|
2621
3153
|
if (directSpec !== null) {
|
|
2622
|
-
|
|
2623
|
-
|
|
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"));
|
|
2624
3158
|
}
|
|
2625
3159
|
return createRequireProgramModuleOf(this, decl.initializer)?.dep ?? null;
|
|
2626
3160
|
}
|
|
@@ -2631,9 +3165,7 @@ export class Lowerer {
|
|
|
2631
3165
|
* static storage or callable/class metadata. */
|
|
2632
3166
|
createRequireWholeExportSymbolOf(ident) {
|
|
2633
3167
|
const binding = this.checker.getSymbolAtLocation(ident);
|
|
2634
|
-
const decl = binding
|
|
2635
|
-
? this.checker.declarationsOf(binding).find(ts.isVariableDeclaration)
|
|
2636
|
-
: undefined;
|
|
3168
|
+
const decl = binding ? binding.declarations.find(ts.isVariableDeclaration) : undefined;
|
|
2637
3169
|
if (!decl || !ts.isIdentifier(decl.name) || !decl.initializer)
|
|
2638
3170
|
return null;
|
|
2639
3171
|
const target = createRequireProgramModuleOf(this, decl.initializer);
|
|
@@ -2643,9 +3175,7 @@ export class Lowerer {
|
|
|
2643
3175
|
let symbol = moduleSym?.getExports().get("export=");
|
|
2644
3176
|
if (!symbol)
|
|
2645
3177
|
return null;
|
|
2646
|
-
const wholeAssignment =
|
|
2647
|
-
.declarationsOf(symbol)
|
|
2648
|
-
.find((d) => {
|
|
3178
|
+
const wholeAssignment = symbol.declarations.find((d) => {
|
|
2649
3179
|
if (!ts.isBinaryExpression(d) ||
|
|
2650
3180
|
!ts.isExpressionStatement(d.parent) ||
|
|
2651
3181
|
!ts.isSourceFile(d.parent.parent))
|
|
@@ -2660,6 +3190,10 @@ export class Lowerer {
|
|
|
2660
3190
|
let rhs = wholeAssignment.right;
|
|
2661
3191
|
while (ts.isParenthesizedExpression(rhs))
|
|
2662
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;
|
|
2663
3197
|
if (ts.isIdentifier(rhs)) {
|
|
2664
3198
|
const value = this.checker.getSymbolAtLocation(rhs);
|
|
2665
3199
|
if (value) {
|
|
@@ -2678,9 +3212,7 @@ export class Lowerer {
|
|
|
2678
3212
|
* target module's real export symbol. */
|
|
2679
3213
|
createRequireDestructuredExportSymbolOf(ident) {
|
|
2680
3214
|
const binding = this.checker.getSymbolAtLocation(ident);
|
|
2681
|
-
const element = binding
|
|
2682
|
-
? this.checker.declarationsOf(binding).find(ts.isBindingElement)
|
|
2683
|
-
: undefined;
|
|
3215
|
+
const element = binding ? binding.declarations.find(ts.isBindingElement) : undefined;
|
|
2684
3216
|
if (!element ||
|
|
2685
3217
|
element.name === undefined ||
|
|
2686
3218
|
!ts.isIdentifier(element.name) ||
|
|
@@ -2709,8 +3241,10 @@ export class Lowerer {
|
|
|
2709
3241
|
* symbols → resolveValueSymbol); the bare value keeps the
|
|
2710
3242
|
* namespace-object fence, like ESM namespace imports of builtins. */
|
|
2711
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).
|
|
2712
3246
|
if (!ts.isIdentifier(expr))
|
|
2713
|
-
return
|
|
3247
|
+
return this.cjsModuleRefDepOf(expr) !== null;
|
|
2714
3248
|
const sym = this.checker.getSymbolAtLocation(expr);
|
|
2715
3249
|
if (this.localModuleBindingDepOf(expr) === null)
|
|
2716
3250
|
return false;
|
|
@@ -2725,7 +3259,10 @@ export class Lowerer {
|
|
|
2725
3259
|
// the object literal) keep the namespace reading — member accesses
|
|
2726
3260
|
// resolve through the table's property symbols.
|
|
2727
3261
|
if (sym && sym.flags & ts.SymbolFlags.Alias) {
|
|
2728
|
-
|
|
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];
|
|
2729
3266
|
if (d && (ts.isClassDeclaration(d) || ts.isFunctionDeclaration(d)))
|
|
2730
3267
|
return false;
|
|
2731
3268
|
if (d && ts.isVariableDeclaration(d)) {
|
|
@@ -2795,7 +3332,7 @@ export class Lowerer {
|
|
|
2795
3332
|
g.type = this.runtimeOptionalBindingType(ident, g.type);
|
|
2796
3333
|
return g;
|
|
2797
3334
|
}
|
|
2798
|
-
for (const d of
|
|
3335
|
+
for (const d of symbol.declarations) {
|
|
2799
3336
|
const byDecl = this.globalsByDeclNode.get(d);
|
|
2800
3337
|
if (byDecl)
|
|
2801
3338
|
return byDecl;
|
|
@@ -2825,6 +3362,16 @@ export class Lowerer {
|
|
|
2825
3362
|
const id = `%g.${tag}%loaded`;
|
|
2826
3363
|
this.moduleGuardOf.set(fp.sf, id);
|
|
2827
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
|
+
}
|
|
2828
3375
|
}
|
|
2829
3376
|
// A module is intrinsically async when an await/for-await occurs
|
|
2830
3377
|
// outside every nested function-like boundary. Then propagate that
|
|
@@ -2944,6 +3491,59 @@ export class Lowerer {
|
|
|
2944
3491
|
if (!indexOf.has(fp.sf))
|
|
2945
3492
|
visit(fp.sf);
|
|
2946
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
|
+
}
|
|
2947
3547
|
/** The lowering of a CommonJS `require("./local")` occurrence: a call of
|
|
2948
3548
|
* the required module's run-once %init at exactly this statement's
|
|
2949
3549
|
* position — Node's inline evaluation, with the guard supplying the
|
|
@@ -2953,6 +3553,8 @@ export class Lowerer {
|
|
|
2953
3553
|
* their external dependencies by name). Null for everything else
|
|
2954
3554
|
* (builtins load nothing; the rest kept its preflight fence). */
|
|
2955
3555
|
requireInitStmt(spec, node) {
|
|
3556
|
+
if (canonicalBuiltinModule(spec) === "punycode")
|
|
3557
|
+
return this.punycodeRequireWarning(node);
|
|
2956
3558
|
// Project requires resolve within the program; another bare require can
|
|
2957
3559
|
// be a program-module edge when it names an opted-in --npm-static package
|
|
2958
3560
|
// (one package requiring another — the resolution answered its shipped
|
|
@@ -2960,8 +3562,8 @@ export class Lowerer {
|
|
|
2960
3562
|
// Without the guarded %init call at this position
|
|
2961
3563
|
// those globals stay uninitialized: the dep's module body would never
|
|
2962
3564
|
// run.
|
|
2963
|
-
const dep = resolveImport(this.program,
|
|
2964
|
-
npmStaticDepSf7(this.program,
|
|
3565
|
+
const dep = resolveImport(this.program, ts.getSourceFileOfNode(node), spec, "require") ??
|
|
3566
|
+
npmStaticDepSf7(this.program, ts.getSourceFileOfNode(node), spec, "require");
|
|
2965
3567
|
if (!dep || dep.fileName.endsWith(".json"))
|
|
2966
3568
|
return null;
|
|
2967
3569
|
if (this.asyncInitFiles.has(dep)) {
|
|
@@ -2976,7 +3578,7 @@ export class Lowerer {
|
|
|
2976
3578
|
expr: { kind: "call", callee: initName, args: [], type: VOID, loc },
|
|
2977
3579
|
loc,
|
|
2978
3580
|
};
|
|
2979
|
-
const parentModule = this.cjsModuleIdOf.get(
|
|
3581
|
+
const parentModule = this.cjsModuleIdOf.get(ts.getSourceFileOfNode(node));
|
|
2980
3582
|
const childModule = this.cjsModuleIdOf.get(dep);
|
|
2981
3583
|
if (parentModule === undefined || childModule === undefined)
|
|
2982
3584
|
return init;
|
|
@@ -3018,6 +3620,97 @@ export class Lowerer {
|
|
|
3018
3620
|
* TypeScript's default indexed-access type is a useful source annotation,
|
|
3019
3621
|
* but it is not a runtime proof; promoting only the affected slots keeps
|
|
3020
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
|
+
}
|
|
3021
3714
|
analyzeRuntimeOptionalArrayReads(parts) {
|
|
3022
3715
|
const provenance = RuntimeOptionalProvenance.fromEnvironment();
|
|
3023
3716
|
// The site whose value the current promotion follows (debug only).
|
|
@@ -3138,7 +3831,7 @@ export class Lowerer {
|
|
|
3138
3831
|
const symbol = (ts.isFunctionDeclaration(fn) || ts.isMethodDeclaration(fn)) && fn.name
|
|
3139
3832
|
? symbolOf(fn.name)
|
|
3140
3833
|
: null;
|
|
3141
|
-
const index = fn.parameters.indexOf(parameter);
|
|
3834
|
+
const index = fn.parameters.nodes.indexOf(parameter);
|
|
3142
3835
|
return (symbol && signatureBySymbol.get(symbol)?.params[index]?.type) ?? null;
|
|
3143
3836
|
};
|
|
3144
3837
|
const returnTypeOf = (fn) => {
|
|
@@ -3147,7 +3840,7 @@ export class Lowerer {
|
|
|
3147
3840
|
};
|
|
3148
3841
|
const recordFlows = new RecordFlowClasses(sourceFiles, {
|
|
3149
3842
|
symbolOf,
|
|
3150
|
-
declarationOf: (symbol) =>
|
|
3843
|
+
declarationOf: (symbol) => symbol.valueDeclaration,
|
|
3151
3844
|
mayBeRecord: (node) => {
|
|
3152
3845
|
if (node.parent && ts.isParameter(node.parent))
|
|
3153
3846
|
return plainRecordShape(parameterType(node)) !== null;
|
|
@@ -3172,11 +3865,12 @@ export class Lowerer {
|
|
|
3172
3865
|
const recordParameterSlots = new Map();
|
|
3173
3866
|
const nanCoded = new NanCodedReads({
|
|
3174
3867
|
symbolOf,
|
|
3175
|
-
declarationOf: (symbol) =>
|
|
3868
|
+
declarationOf: (symbol) => symbol.valueDeclaration,
|
|
3176
3869
|
bytesElemOf: (receiver) => {
|
|
3177
3870
|
const t = mappedOrNull(receiver);
|
|
3178
3871
|
return t?.kind === "bytes" ? t.elem : null;
|
|
3179
3872
|
},
|
|
3873
|
+
isNumberRecordRead: (read) => this.optionalIndexSignatureRead(read)?.kind === "f64",
|
|
3180
3874
|
isNumber: (node) => mappedOrNull(node)?.kind === "f64",
|
|
3181
3875
|
isString: (node) => mappedOrNull(node)?.kind === "string",
|
|
3182
3876
|
hasLength: (node) => {
|
|
@@ -3218,7 +3912,7 @@ export class Lowerer {
|
|
|
3218
3912
|
const seen = new Set();
|
|
3219
3913
|
while (symbol && !signatureBySymbol.has(symbol) && !seen.has(symbol)) {
|
|
3220
3914
|
seen.add(symbol);
|
|
3221
|
-
const declaration =
|
|
3915
|
+
const declaration = symbol.valueDeclaration;
|
|
3222
3916
|
if (declaration && ts.isMethodDeclaration(declaration)) {
|
|
3223
3917
|
symbol = symbolOf(declaration.name);
|
|
3224
3918
|
}
|
|
@@ -3317,14 +4011,109 @@ export class Lowerer {
|
|
|
3317
4011
|
// every consumer treats undefined like NaN.
|
|
3318
4012
|
if (kind === "bytes")
|
|
3319
4013
|
return !nanCoded.isNumericRead(e);
|
|
4014
|
+
if (kind === "record")
|
|
4015
|
+
return this.optionalIndexSignatureRead(e) !== null && !nanCoded.isNumericRead(e);
|
|
3320
4016
|
return kind === "array";
|
|
3321
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
|
+
};
|
|
3322
4111
|
const isDynamicObjectEntryRead = (node) => {
|
|
3323
4112
|
const read = peel(node);
|
|
3324
4113
|
if (!ts.isElementAccessExpression(read) || !ts.isIdentifier(read.expression))
|
|
3325
4114
|
return false;
|
|
3326
4115
|
const source = symbolOf(read.expression);
|
|
3327
|
-
const declaration = source ?
|
|
4116
|
+
const declaration = source ? source.valueDeclaration : undefined;
|
|
3328
4117
|
if (!declaration || !ts.isVariableDeclaration(declaration) || !declaration.initializer)
|
|
3329
4118
|
return false;
|
|
3330
4119
|
const init = peel(declaration.initializer);
|
|
@@ -3333,14 +4122,17 @@ export class Lowerer {
|
|
|
3333
4122
|
if (init.expression.name.text !== "entries" ||
|
|
3334
4123
|
!this.isStdlibGlobal(init.expression.expression, "Object"))
|
|
3335
4124
|
return false;
|
|
3336
|
-
const object = init.arguments[0];
|
|
4125
|
+
const object = init.arguments.nodes[0];
|
|
3337
4126
|
const objectType = object ? this.mapTypeOf(this.typeOf(object)) : null;
|
|
3338
4127
|
return objectType?.kind === "dyn";
|
|
3339
4128
|
};
|
|
3340
4129
|
const addUndefined = (t) => {
|
|
3341
4130
|
if (t.kind === "union")
|
|
3342
4131
|
return this.armTag(t.unionId, UNDEFINED_T) >= 0 ? t : (this.withUndefinedArmOf(t) ?? t);
|
|
3343
|
-
|
|
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")
|
|
3344
4136
|
return t;
|
|
3345
4137
|
return this.withUndefinedArm(t);
|
|
3346
4138
|
};
|
|
@@ -3376,15 +4168,41 @@ export class Lowerer {
|
|
|
3376
4168
|
// Such a binding reads `T | undefined`, so a typed parameter, local or
|
|
3377
4169
|
// field it flows into widens like any other missing element read.
|
|
3378
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
|
+
};
|
|
3379
4193
|
const mayBeOptional = (node) => {
|
|
3380
4194
|
// `xs[i]!` is the explicit proven-present form. Its array read keeps
|
|
3381
4195
|
// the established dense bounds trap and must not promote the enclosing
|
|
3382
4196
|
// function/global ABI to `T | undefined`.
|
|
3383
4197
|
if (explicitlyNonNull(node))
|
|
3384
4198
|
return false;
|
|
4199
|
+
if (assertsDefined(node))
|
|
4200
|
+
return false;
|
|
3385
4201
|
const e = peel(node);
|
|
3386
4202
|
if (isIndexedRead(e))
|
|
3387
4203
|
return true;
|
|
4204
|
+
if (ts.isPropertyAccessExpression(e) && isRecordIndexPropertyRead(e))
|
|
4205
|
+
return true;
|
|
3388
4206
|
if (ts.isPropertyAccessExpression(e) && isOptionalProcessStreamProperty(this, e))
|
|
3389
4207
|
return true;
|
|
3390
4208
|
if (ts.isPropertyAccessExpression(e) && isSettledIteratorValueRead(this, e))
|
|
@@ -3394,7 +4212,7 @@ export class Lowerer {
|
|
|
3394
4212
|
if (ts.isCallExpression(e) && this.runtimeOptionalReduceTypes.has(e))
|
|
3395
4213
|
return true;
|
|
3396
4214
|
if (ts.isCallExpression(e) &&
|
|
3397
|
-
e.arguments.length === 0 &&
|
|
4215
|
+
e.arguments.nodes.length === 0 &&
|
|
3398
4216
|
ts.isPropertyAccessExpression(e.expression) &&
|
|
3399
4217
|
e.expression.name.text === "stringify" &&
|
|
3400
4218
|
this.isStdlibGlobal(e.expression.expression, "JSON"))
|
|
@@ -3532,12 +4350,12 @@ export class Lowerer {
|
|
|
3532
4350
|
* exactly `T | undefined`: an assignment from a missing read stores the
|
|
3533
4351
|
* undefined arm while the checker narrows later reads to `T`. */
|
|
3534
4352
|
const optionalInstanceField = (symbol) => {
|
|
3535
|
-
const decl =
|
|
4353
|
+
const decl = symbol.valueDeclaration;
|
|
3536
4354
|
if (!decl || !ts.isPropertyDeclaration(decl) || !ts.isIdentifier(decl.name))
|
|
3537
4355
|
return false;
|
|
3538
4356
|
if (ts.getCombinedModifierFlags(decl) & ts.ModifierFlags.Static)
|
|
3539
4357
|
return false;
|
|
3540
|
-
const sf =
|
|
4358
|
+
const sf = ts.getSourceFileOfNode(decl);
|
|
3541
4359
|
if (isJsSourceFile(sf) || sf.isDeclarationFile)
|
|
3542
4360
|
return false;
|
|
3543
4361
|
const declared = typeOrNull(decl.name);
|
|
@@ -3569,7 +4387,7 @@ export class Lowerer {
|
|
|
3569
4387
|
// A fresh literal carries the fields its values can leave undefined.
|
|
3570
4388
|
if (ts.isObjectLiteralExpression(e)) {
|
|
3571
4389
|
const out = spreadFieldsOf(e);
|
|
3572
|
-
for (const prop of e.properties) {
|
|
4390
|
+
for (const prop of e.properties.nodes) {
|
|
3573
4391
|
if (!ts.isPropertyAssignment(prop) && !ts.isShorthandPropertyAssignment(prop))
|
|
3574
4392
|
continue;
|
|
3575
4393
|
const name = prop.name;
|
|
@@ -3607,7 +4425,7 @@ export class Lowerer {
|
|
|
3607
4425
|
* the properties a later member writes explicitly. */
|
|
3608
4426
|
const spreadFieldsOf = (object) => {
|
|
3609
4427
|
const out = new Set();
|
|
3610
|
-
for (const prop of object.properties) {
|
|
4428
|
+
for (const prop of object.properties.nodes) {
|
|
3611
4429
|
if (ts.isSpreadAssignment(prop)) {
|
|
3612
4430
|
const fields = fieldsOfValue(prop.expression);
|
|
3613
4431
|
if (fields !== undefined)
|
|
@@ -3622,14 +4440,35 @@ export class Lowerer {
|
|
|
3622
4440
|
return out;
|
|
3623
4441
|
};
|
|
3624
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
|
+
}
|
|
3625
4461
|
if (!ts.isArrayBindingPattern(name))
|
|
3626
4462
|
return false;
|
|
3627
4463
|
const sourceType = this.mapTypeOf(this.typeOf(init));
|
|
3628
4464
|
if (sourceType?.kind !== "array")
|
|
3629
4465
|
return false;
|
|
4466
|
+
return scanPositions(name.elements.nodes.filter((el) => !ts.isOmittedExpression(el)), init, sourceType);
|
|
4467
|
+
};
|
|
4468
|
+
const scanPositions = (elements, init, sourceType) => {
|
|
3630
4469
|
let changed = false;
|
|
3631
|
-
|
|
3632
|
-
if (
|
|
4470
|
+
elements.forEach((el) => {
|
|
4471
|
+
if (el.name === undefined || el.dotDotDotToken)
|
|
3633
4472
|
return;
|
|
3634
4473
|
if (ts.isIdentifier(el.name)) {
|
|
3635
4474
|
const symbol = symbolOf(el.name);
|
|
@@ -3659,6 +4498,47 @@ export class Lowerer {
|
|
|
3659
4498
|
});
|
|
3660
4499
|
return changed;
|
|
3661
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
|
+
};
|
|
3662
4542
|
const hofCallbackIndices = (name, hasInitialValue) => {
|
|
3663
4543
|
if (name === "reduce" || name === "reduceRight")
|
|
3664
4544
|
return hasInitialValue ? [1] : [0, 1];
|
|
@@ -3752,7 +4632,7 @@ export class Lowerer {
|
|
|
3752
4632
|
};
|
|
3753
4633
|
for (const [symbol, signature] of signatureBySymbol) {
|
|
3754
4634
|
const declaration = functionDeclBySymbol.get(symbol);
|
|
3755
|
-
if (!declaration || !isJsSourceFile(
|
|
4635
|
+
if (!declaration || !isJsSourceFile(ts.getSourceFileOfNode(declaration)))
|
|
3756
4636
|
continue;
|
|
3757
4637
|
const checked = this.checker.getSignatureFromDeclaration(declaration);
|
|
3758
4638
|
const checkedReturn = checked ? this.checker.getReturnTypeOfSignature(checked) : null;
|
|
@@ -3780,7 +4660,7 @@ export class Lowerer {
|
|
|
3780
4660
|
for (const parameterIndex of parameterIndices) {
|
|
3781
4661
|
if (parameterIndex === undefined)
|
|
3782
4662
|
continue;
|
|
3783
|
-
const parameter = fn.parameters[parameterIndex];
|
|
4663
|
+
const parameter = fn.parameters.nodes[parameterIndex];
|
|
3784
4664
|
if (!parameter)
|
|
3785
4665
|
continue;
|
|
3786
4666
|
const symbol = ts.isIdentifier(parameter.name) ? symbolOf(parameter.name) : null;
|
|
@@ -3849,7 +4729,7 @@ export class Lowerer {
|
|
|
3849
4729
|
if (this.genericFnsBySymbol.has(symbol))
|
|
3850
4730
|
return false;
|
|
3851
4731
|
seen.add(symbol);
|
|
3852
|
-
const declaration =
|
|
4732
|
+
const declaration = symbol.valueDeclaration;
|
|
3853
4733
|
if (declaration && ts.isVariableDeclaration(declaration) && declaration.initializer) {
|
|
3854
4734
|
if (promoteHofCallback(peel(declaration.initializer), parameterIndices, seen))
|
|
3855
4735
|
changed = true;
|
|
@@ -3904,7 +4784,9 @@ export class Lowerer {
|
|
|
3904
4784
|
owner.name)
|
|
3905
4785
|
ownerSymbol = symbolOf(owner.name);
|
|
3906
4786
|
const ownerSig = ownerSymbol ? signatureBySymbol.get(ownerSymbol) : undefined;
|
|
3907
|
-
const ownerIndex = ts.isFunctionLike(owner)
|
|
4787
|
+
const ownerIndex = ts.isFunctionLike(owner)
|
|
4788
|
+
? owner.parameters.nodes.indexOf(declaration)
|
|
4789
|
+
: -1;
|
|
3908
4790
|
const slot = ownerIndex >= 0 ? ownerSig?.params[ownerIndex] : undefined;
|
|
3909
4791
|
if (slot && !typeEquals(slot.type, promoted)) {
|
|
3910
4792
|
slot.type = promoted;
|
|
@@ -3924,7 +4806,7 @@ export class Lowerer {
|
|
|
3924
4806
|
return false;
|
|
3925
4807
|
let changed = false;
|
|
3926
4808
|
for (const parameterIndex of parameterIndices) {
|
|
3927
|
-
const parameter = fn.parameters[parameterIndex];
|
|
4809
|
+
const parameter = fn.parameters.nodes[parameterIndex];
|
|
3928
4810
|
if (!parameter)
|
|
3929
4811
|
continue;
|
|
3930
4812
|
const checkerType = this.typeOf(parameter.name);
|
|
@@ -3962,7 +4844,7 @@ export class Lowerer {
|
|
|
3962
4844
|
const fn = peel(callback);
|
|
3963
4845
|
let param;
|
|
3964
4846
|
if (ts.isArrowFunction(fn) || ts.isFunctionExpression(fn)) {
|
|
3965
|
-
const parameter = fn.parameters[index];
|
|
4847
|
+
const parameter = fn.parameters.nodes[index];
|
|
3966
4848
|
if (!parameter?.type || parameter.dotDotDotToken)
|
|
3967
4849
|
return true;
|
|
3968
4850
|
const checkerType = this.typeOf(parameter.name);
|
|
@@ -3989,7 +4871,7 @@ export class Lowerer {
|
|
|
3989
4871
|
const fn = functionDeclBySymbol.get(symbol);
|
|
3990
4872
|
if (fn)
|
|
3991
4873
|
return bodyReturnsOptional(fn);
|
|
3992
|
-
const decl =
|
|
4874
|
+
const decl = symbol.valueDeclaration;
|
|
3993
4875
|
return (!!decl &&
|
|
3994
4876
|
ts.isVariableDeclaration(decl) &&
|
|
3995
4877
|
!!decl.initializer &&
|
|
@@ -4067,7 +4949,7 @@ export class Lowerer {
|
|
|
4067
4949
|
};
|
|
4068
4950
|
const ownership = new ArrayOwnership(sourceFiles, {
|
|
4069
4951
|
symbolOf,
|
|
4070
|
-
declarationOf: (symbol) =>
|
|
4952
|
+
declarationOf: (symbol) => symbol.valueDeclaration,
|
|
4071
4953
|
typeOf: typeOrNull,
|
|
4072
4954
|
instanceAssignableTo: (owner, target) => panicSafe(() => this.checker.isTypeAssignableTo(this.checker.getTypeAtLocation(owner), target), true),
|
|
4073
4955
|
isGlobal: (node, name) => this.isStdlibGlobal(node, name),
|
|
@@ -4088,7 +4970,7 @@ export class Lowerer {
|
|
|
4088
4970
|
// flow type such as `Array.isArray(x)`'s `any[]` only narrows it.
|
|
4089
4971
|
const e = peel(node);
|
|
4090
4972
|
const symbol = ts.isIdentifier(e) ? symbolOf(e) : null;
|
|
4091
|
-
const declaration = symbol ?
|
|
4973
|
+
const declaration = symbol ? symbol.valueDeclaration : undefined;
|
|
4092
4974
|
const declared = declaration &&
|
|
4093
4975
|
(ts.isVariableDeclaration(declaration) || ts.isParameter(declaration)) &&
|
|
4094
4976
|
ts.isIdentifier(declaration.name)
|
|
@@ -4144,14 +5026,14 @@ export class Lowerer {
|
|
|
4144
5026
|
else if (ts.isReturnStatement(node) && node.expression && dynamicValue(node.expression))
|
|
4145
5027
|
target(contextualOrNull(node.expression));
|
|
4146
5028
|
else if (ts.isCallExpression(node) || ts.isNewExpression(node)) {
|
|
4147
|
-
for (const arg of node.arguments ?? [])
|
|
5029
|
+
for (const arg of node.arguments?.nodes ?? [])
|
|
4148
5030
|
if (!ts.isSpreadElement(arg) && dynamicValue(arg))
|
|
4149
5031
|
target(contextualOrNull(arg));
|
|
4150
5032
|
}
|
|
4151
5033
|
else if (ts.isPropertyAssignment(node) && dynamicValue(node.initializer))
|
|
4152
5034
|
target(contextualOrNull(node.initializer));
|
|
4153
5035
|
else if (ts.isArrayLiteralExpression(node)) {
|
|
4154
|
-
for (const element of node.elements)
|
|
5036
|
+
for (const element of node.elements.nodes)
|
|
4155
5037
|
if (!ts.isSpreadElement(element) &&
|
|
4156
5038
|
!ts.isOmittedExpression(element) &&
|
|
4157
5039
|
dynamicValue(element))
|
|
@@ -4379,7 +5261,7 @@ export class Lowerer {
|
|
|
4379
5261
|
if (ts.isIdentifier(node.name) &&
|
|
4380
5262
|
ts.isObjectLiteralExpression(peel(node.initializer))) {
|
|
4381
5263
|
const object = peel(node.initializer);
|
|
4382
|
-
for (const prop of object.properties) {
|
|
5264
|
+
for (const prop of object.properties.nodes) {
|
|
4383
5265
|
if (!ts.isPropertyAssignment(prop) && !ts.isShorthandPropertyAssignment(prop))
|
|
4384
5266
|
continue;
|
|
4385
5267
|
const name = prop.name;
|
|
@@ -4412,7 +5294,7 @@ export class Lowerer {
|
|
|
4412
5294
|
const assertion = forwardedAssertion(node.right);
|
|
4413
5295
|
const symbol = assertion ? symbolOf(node.left) : null;
|
|
4414
5296
|
// Only a variable's storage is promoted (see the final pass).
|
|
4415
|
-
const declaration = symbol ?
|
|
5297
|
+
const declaration = symbol ? symbol.valueDeclaration : undefined;
|
|
4416
5298
|
if (assertion &&
|
|
4417
5299
|
symbol &&
|
|
4418
5300
|
declaration &&
|
|
@@ -4466,8 +5348,8 @@ export class Lowerer {
|
|
|
4466
5348
|
}
|
|
4467
5349
|
}
|
|
4468
5350
|
if (ts.isCallExpression(node) && ts.isPropertyAccessExpression(node.expression)) {
|
|
4469
|
-
const callbackIndices = hofCallbackIndices(node.expression.name.text, node.arguments.length >= 2);
|
|
4470
|
-
const callback = node.arguments[0];
|
|
5351
|
+
const callbackIndices = hofCallbackIndices(node.expression.name.text, node.arguments.nodes.length >= 2);
|
|
5352
|
+
const callback = node.arguments.nodes[0];
|
|
4471
5353
|
if (callbackIndices !== null && callback !== undefined && !ts.isSpreadElement(callback)) {
|
|
4472
5354
|
const receiverNode = node.expression.expression;
|
|
4473
5355
|
const receiverTs = this.typeOf(receiverNode);
|
|
@@ -4491,9 +5373,7 @@ export class Lowerer {
|
|
|
4491
5373
|
let nativeArrayReceiver = receiver?.kind === "array" || tuple;
|
|
4492
5374
|
if (nativeArrayReceiver && ts.isIdentifier(receiverNode)) {
|
|
4493
5375
|
const receiverSymbol = symbolOf(receiverNode);
|
|
4494
|
-
const declaration = receiverSymbol
|
|
4495
|
-
? this.checker.valueDeclarationOf(receiverSymbol)
|
|
4496
|
-
: undefined;
|
|
5376
|
+
const declaration = receiverSymbol ? receiverSymbol.valueDeclaration : undefined;
|
|
4497
5377
|
if (declaration && ts.isVariableDeclaration(declaration)) {
|
|
4498
5378
|
const declared = this.mapTypeOf(this.typeOf(declaration.name));
|
|
4499
5379
|
if (declared?.kind !== "array" &&
|
|
@@ -4521,7 +5401,7 @@ export class Lowerer {
|
|
|
4521
5401
|
if (elementsPresent && reduce && retypeInlineCallback(callback, callbackIndices))
|
|
4522
5402
|
changed = true;
|
|
4523
5403
|
if ((method === "reduce" || method === "reduceRight") &&
|
|
4524
|
-
((!elementsPresent && node.arguments.length < 2) ||
|
|
5404
|
+
((!elementsPresent && node.arguments.nodes.length < 2) ||
|
|
4525
5405
|
callbackReturnsOptional(callback))) {
|
|
4526
5406
|
if (promoteHofCallback(callback, [0, 1]))
|
|
4527
5407
|
changed = true;
|
|
@@ -4547,20 +5427,20 @@ export class Lowerer {
|
|
|
4547
5427
|
// parameter, as for a callback the same value is passed as.
|
|
4548
5428
|
if (!ts.isIdentifier(node.expression) || reassigned.has(symbol))
|
|
4549
5429
|
return;
|
|
4550
|
-
const declaration =
|
|
5430
|
+
const declaration = symbol.valueDeclaration;
|
|
4551
5431
|
const value = declaration && ts.isVariableDeclaration(declaration) && declaration.initializer
|
|
4552
5432
|
? peel(declaration.initializer)
|
|
4553
5433
|
: null;
|
|
4554
5434
|
if (!value || !(ts.isArrowFunction(value) || ts.isFunctionExpression(value)))
|
|
4555
5435
|
return;
|
|
4556
5436
|
// Optional, defaulted and rest parameters keep their own ABI.
|
|
4557
|
-
if (value.parameters.some((parameter) => parameter.questionToken !== undefined ||
|
|
5437
|
+
if (value.parameters.nodes.some((parameter) => parameter.questionToken !== undefined ||
|
|
4558
5438
|
parameter.initializer !== undefined ||
|
|
4559
5439
|
parameter.dotDotDotToken !== undefined))
|
|
4560
5440
|
return;
|
|
4561
|
-
const indices = node.arguments.flatMap((arg, i) => !ts.isSpreadElement(arg) &&
|
|
4562
|
-
value.parameters[i] !== undefined &&
|
|
4563
|
-
!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 &&
|
|
4564
5444
|
mayBeOptional(arg)
|
|
4565
5445
|
? [i]
|
|
4566
5446
|
: []);
|
|
@@ -4575,10 +5455,10 @@ export class Lowerer {
|
|
|
4575
5455
|
// agree on that value's representation.
|
|
4576
5456
|
const callee = functionDeclBySymbol.get(symbol);
|
|
4577
5457
|
if (callee &&
|
|
4578
|
-
isJsSourceFile(
|
|
4579
|
-
!node.arguments.some(ts.isSpreadElement)) {
|
|
5458
|
+
isJsSourceFile(ts.getSourceFileOfNode(callee)) &&
|
|
5459
|
+
!node.arguments.nodes.some(ts.isSpreadElement)) {
|
|
4580
5460
|
for (let i = 0; i < sig.params.length; i++) {
|
|
4581
|
-
const arg = node.arguments[i];
|
|
5461
|
+
const arg = node.arguments.nodes[i];
|
|
4582
5462
|
if (arg &&
|
|
4583
5463
|
(this.typeOf(arg).flags & (ts.TypeFlags.Undefined | ts.TypeFlags.Void)) === 0)
|
|
4584
5464
|
continue;
|
|
@@ -4590,7 +5470,7 @@ export class Lowerer {
|
|
|
4590
5470
|
if (typeEquals(shape.type, widened))
|
|
4591
5471
|
continue;
|
|
4592
5472
|
shape.type = widened;
|
|
4593
|
-
const parameter = functionDeclBySymbol.get(target)?.parameters[i];
|
|
5473
|
+
const parameter = functionDeclBySymbol.get(target)?.parameters?.nodes[i];
|
|
4594
5474
|
provenance?.note("parameter", parameter, node, "(omitted or undefined argument)");
|
|
4595
5475
|
if (parameter) {
|
|
4596
5476
|
for (const bound of boundIdentifiersOf(parameter.name)) {
|
|
@@ -4607,7 +5487,7 @@ export class Lowerer {
|
|
|
4607
5487
|
}
|
|
4608
5488
|
}
|
|
4609
5489
|
const restAt = sig.params.findIndex((shape) => shape.mode === "rest" || shape.mode === "dynRest" || shape.mode === "arguments");
|
|
4610
|
-
node.arguments.forEach((arg, argumentIndex) => {
|
|
5490
|
+
node.arguments.nodes.forEach((arg, argumentIndex) => {
|
|
4611
5491
|
const i = restAt >= 0 && argumentIndex >= restAt ? restAt : argumentIndex;
|
|
4612
5492
|
const shape = sig.params[i];
|
|
4613
5493
|
const callbackSlot = shape?.type;
|
|
@@ -4623,7 +5503,7 @@ export class Lowerer {
|
|
|
4623
5503
|
const fields = fieldsOfValue(arg);
|
|
4624
5504
|
for (const target of familyBySymbol.get(symbol) ?? [symbol]) {
|
|
4625
5505
|
const parameterShape = signatureBySymbol.get(target)?.params[i];
|
|
4626
|
-
const parameter = functionDeclBySymbol.get(target)?.parameters[i];
|
|
5506
|
+
const parameter = functionDeclBySymbol.get(target)?.parameters?.nodes[i];
|
|
4627
5507
|
if (!parameterShape || parameterShape.type.kind !== "record")
|
|
4628
5508
|
continue;
|
|
4629
5509
|
if (!parameter || !ts.isIdentifier(parameter.name))
|
|
@@ -4680,7 +5560,7 @@ export class Lowerer {
|
|
|
4680
5560
|
if (typeEquals(rest.type, widened))
|
|
4681
5561
|
continue;
|
|
4682
5562
|
rest.type = widened;
|
|
4683
|
-
const parameter = functionDeclBySymbol.get(target)?.parameters[i];
|
|
5563
|
+
const parameter = functionDeclBySymbol.get(target)?.parameters?.nodes[i];
|
|
4684
5564
|
provenance?.note("rest-parameter", parameter, arg);
|
|
4685
5565
|
if (parameter && ts.isIdentifier(parameter.name)) {
|
|
4686
5566
|
const bound = symbolOf(parameter.name);
|
|
@@ -4707,7 +5587,7 @@ export class Lowerer {
|
|
|
4707
5587
|
optionalParams.set(target, set);
|
|
4708
5588
|
if (set.size !== before) {
|
|
4709
5589
|
changed = true;
|
|
4710
|
-
const parameter = functionDeclBySymbol.get(target)?.parameters[i];
|
|
5590
|
+
const parameter = functionDeclBySymbol.get(target)?.parameters?.nodes[i];
|
|
4711
5591
|
provenance?.note("parameter", parameter, arg, target === symbol ? "" : "(override)");
|
|
4712
5592
|
if (parameter) {
|
|
4713
5593
|
for (const bound of boundIdentifiersOf(parameter.name)) {
|
|
@@ -4767,7 +5647,7 @@ export class Lowerer {
|
|
|
4767
5647
|
// there, whatever its declared type.
|
|
4768
5648
|
for (const symbol of earlyReadVarSymbols(this, sourceFiles)) {
|
|
4769
5649
|
// Text codec bindings keep their own presence-checked storage.
|
|
4770
|
-
const declaration =
|
|
5650
|
+
const declaration = symbol.valueDeclaration;
|
|
4771
5651
|
const mapped = declaration && ts.isVariableDeclaration(declaration)
|
|
4772
5652
|
? mappedOrNull(declaration.name)
|
|
4773
5653
|
: null;
|
|
@@ -4792,6 +5672,25 @@ export class Lowerer {
|
|
|
4792
5672
|
for (const [symbol, decl] of functionDeclBySymbol)
|
|
4793
5673
|
if (scanReturns(symbol, decl))
|
|
4794
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
|
+
}
|
|
4795
5694
|
for (const fn of tsLambdas) {
|
|
4796
5695
|
// An annotated return is the author's contract, as for parameters,
|
|
4797
5696
|
// except that a var read before its first store is undefined
|
|
@@ -4899,7 +5798,7 @@ export class Lowerer {
|
|
|
4899
5798
|
for (const [symbol, params] of optionalParams) {
|
|
4900
5799
|
const decl = functionDeclBySymbol.get(symbol);
|
|
4901
5800
|
for (const index of [...params]) {
|
|
4902
|
-
const name = decl?.parameters[index]?.name;
|
|
5801
|
+
const name = decl?.parameters?.nodes[index]?.name;
|
|
4903
5802
|
const param = name && ts.isIdentifier(name) ? symbolOf(name) : null;
|
|
4904
5803
|
if (param && nanCoded.nanCodedBinding(param))
|
|
4905
5804
|
params.delete(index);
|
|
@@ -4944,20 +5843,52 @@ export class Lowerer {
|
|
|
4944
5843
|
addClassFields(recordFlows.bindingClass(symbol), fields);
|
|
4945
5844
|
for (const [symbol, fields] of returnFields)
|
|
4946
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
|
+
}
|
|
4947
5865
|
const settledFields = (id, own) => id === null
|
|
4948
5866
|
? own
|
|
4949
|
-
: classFields.has(id) && recordFlows.closed(id)
|
|
4950
|
-
? classFields.get(id)
|
|
5867
|
+
: (classFields.has(id) || nestedFields.has(id)) && recordFlows.closed(id)
|
|
5868
|
+
? (classFields.get(id) ?? new Set())
|
|
4951
5869
|
: undefined;
|
|
4952
|
-
const widenRecordFields = (type, fields) => {
|
|
5870
|
+
const widenRecordFields = (type, fields, id = null, seen = new Set()) => {
|
|
4953
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;
|
|
4954
5875
|
for (const field of fields) {
|
|
4955
|
-
const source =
|
|
4956
|
-
? this.shapes.get(promoted.shapeId)?.fields.find((f) => f.name === field)
|
|
4957
|
-
: undefined;
|
|
5876
|
+
const source = fieldOf(field);
|
|
4958
5877
|
if (source)
|
|
4959
5878
|
promoted = this.runtimeOptionalRecordField(promoted, field, addUndefined(source.type));
|
|
4960
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
|
+
}
|
|
4961
5892
|
return promoted;
|
|
4962
5893
|
};
|
|
4963
5894
|
for (const [symbol, id] of recordFlows.bindings())
|
|
@@ -4973,10 +5904,11 @@ export class Lowerer {
|
|
|
4973
5904
|
const shape = signatureBySymbol.get(target)?.params[index];
|
|
4974
5905
|
if (!shape || shape.type.kind !== "record")
|
|
4975
5906
|
continue;
|
|
4976
|
-
const
|
|
5907
|
+
const id = recordFlows.bindingClass(bound);
|
|
5908
|
+
const fields = settledFields(id, optionalFields.get(bound));
|
|
4977
5909
|
if (!fields)
|
|
4978
5910
|
continue;
|
|
4979
|
-
const promoted = widenRecordFields(shape.type, fields);
|
|
5911
|
+
const promoted = widenRecordFields(shape.type, fields, id);
|
|
4980
5912
|
if (typeEquals(promoted, shape.type))
|
|
4981
5913
|
continue;
|
|
4982
5914
|
shape.type = promoted;
|
|
@@ -4986,7 +5918,7 @@ export class Lowerer {
|
|
|
4986
5918
|
const id = recordFlows.returnClass(symbol);
|
|
4987
5919
|
const fields = id === null ? undefined : settledFields(id, undefined);
|
|
4988
5920
|
if (fields && sig.returnType.kind === "record") {
|
|
4989
|
-
const next = widenRecordFields(sig.returnType, fields);
|
|
5921
|
+
const next = widenRecordFields(sig.returnType, fields, id);
|
|
4990
5922
|
sig.returnType = next;
|
|
4991
5923
|
if (sig.top)
|
|
4992
5924
|
sig.top.returnType = next;
|
|
@@ -5028,7 +5960,7 @@ export class Lowerer {
|
|
|
5028
5960
|
for (const [declaration, global] of this.globalsByDeclNode) {
|
|
5029
5961
|
if (global.type.kind !== "func" ||
|
|
5030
5962
|
!ts.isBinaryExpression(declaration) ||
|
|
5031
|
-
!isJsSourceFile(
|
|
5963
|
+
!isJsSourceFile(ts.getSourceFileOfNode(declaration)))
|
|
5032
5964
|
continue;
|
|
5033
5965
|
const value = peel(declaration.right);
|
|
5034
5966
|
if (!ts.isFunctionExpression(value) && !ts.isArrowFunction(value))
|
|
@@ -5077,7 +6009,8 @@ export class Lowerer {
|
|
|
5077
6009
|
global.type = promoted;
|
|
5078
6010
|
}
|
|
5079
6011
|
}
|
|
5080
|
-
const
|
|
6012
|
+
const flowClass = recordFlows.bindingClass(symbol);
|
|
6013
|
+
const fields = settledFields(flowClass, optionalFields.get(symbol));
|
|
5081
6014
|
if (!dynamicObjectEntryRows.has(symbol) && !optionalSymbols.has(symbol) && !fields)
|
|
5082
6015
|
return;
|
|
5083
6016
|
const current = this.mapTypeOf(this.typeOf(node.name));
|
|
@@ -5097,7 +6030,7 @@ export class Lowerer {
|
|
|
5097
6030
|
}
|
|
5098
6031
|
}
|
|
5099
6032
|
if (fields && promoted.kind === "record")
|
|
5100
|
-
promoted = widenRecordFields(promoted, fields);
|
|
6033
|
+
promoted = widenRecordFields(promoted, fields, flowClass);
|
|
5101
6034
|
if (!typeEquals(promoted, current)) {
|
|
5102
6035
|
this.runtimeOptionalBindingTypes.set(symbol, promoted);
|
|
5103
6036
|
const global = ts.isIdentifier(node.name)
|
|
@@ -5130,9 +6063,9 @@ export class Lowerer {
|
|
|
5130
6063
|
continue;
|
|
5131
6064
|
const symbol = callableSymbolOf(node.expression);
|
|
5132
6065
|
const sig = symbol ? signatureBySymbol.get(symbol) : undefined;
|
|
5133
|
-
if (!sig || node.arguments.some(ts.isSpreadElement))
|
|
6066
|
+
if (!sig || node.arguments.nodes.some(ts.isSpreadElement))
|
|
5134
6067
|
continue;
|
|
5135
|
-
node.arguments.forEach((arg, i) => {
|
|
6068
|
+
node.arguments.nodes.forEach((arg, i) => {
|
|
5136
6069
|
let e = arg;
|
|
5137
6070
|
while (ts.isParenthesizedExpression(e))
|
|
5138
6071
|
e = e.expression;
|
|
@@ -5162,7 +6095,12 @@ export class Lowerer {
|
|
|
5162
6095
|
this.checker.prefetchSourceFile(fp.sf);
|
|
5163
6096
|
}
|
|
5164
6097
|
this.collectProgram(parts);
|
|
5165
|
-
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
|
+
});
|
|
5166
6104
|
// Decorated classes analyze AFTER the whole collection pass: a
|
|
5167
6105
|
// decorator's return type may name a subclass declared below the
|
|
5168
6106
|
// class, and reference lowering needs each class's rebindability
|
|
@@ -5287,6 +6225,7 @@ export class Lowerer {
|
|
|
5287
6225
|
// implicit-any instances lowered eagerly at their first call sites.
|
|
5288
6226
|
functions.push(...this.liftedFns);
|
|
5289
6227
|
functions.push(...this.implicitFns);
|
|
6228
|
+
functions.push(...runtimeClassConstructs(this, functions));
|
|
5290
6229
|
if (this.remainder) {
|
|
5291
6230
|
// Deferred collection diagnostics nothing flushed — declarations no
|
|
5292
6231
|
// reference ever made relevant. They belong to the unreached group
|
|
@@ -5314,7 +6253,9 @@ export class Lowerer {
|
|
|
5314
6253
|
if (this.diags.length === 0)
|
|
5315
6254
|
fuseArrayPipelines(this, functions);
|
|
5316
6255
|
finalizeClassMethodValues(this, functions);
|
|
6256
|
+
finalizePrivateBrands(this, functions);
|
|
5317
6257
|
trackClassFieldCreation(this, functions);
|
|
6258
|
+
guardClassAttributeWrites(this, functions);
|
|
5318
6259
|
// Globals typed by a class that never REGISTERED (a JS class whose
|
|
5319
6260
|
// collection fenced — Symbol-keyed fields, an unsupported base): the
|
|
5320
6261
|
// declaration statement and every use compiled to runtime fences, but
|
|
@@ -5402,10 +6343,11 @@ export class Lowerer {
|
|
|
5402
6343
|
// slots), uniformly across params/locals/globals/fields/body types so
|
|
5403
6344
|
// every producer and consumer agrees. Programs with no unregistered
|
|
5404
6345
|
// reference are untouched — byte-stability holds.
|
|
6346
|
+
checkRequireBindingAccesses(this, functions);
|
|
5405
6347
|
const module = this.diags.length > 0
|
|
5406
6348
|
? null
|
|
5407
6349
|
: {
|
|
5408
|
-
irVersion:
|
|
6350
|
+
irVersion: 17,
|
|
5409
6351
|
sourceFile: this.entry.fileName,
|
|
5410
6352
|
functions,
|
|
5411
6353
|
classes: artifacts.classes,
|
|
@@ -5415,6 +6357,9 @@ export class Lowerer {
|
|
|
5415
6357
|
entry: ENTRY_NAME,
|
|
5416
6358
|
...(this.usesWorkers ? { workers: true } : {}),
|
|
5417
6359
|
...(this.usesLifetimeRegions ? { lifetimeRegions: true } : {}),
|
|
6360
|
+
...(this.threadSlotKeys.size > 0
|
|
6361
|
+
? { threadSlotKeys: [...this.threadSlotKeys].sort() }
|
|
6362
|
+
: {}),
|
|
5418
6363
|
...(isNodeEsmFile(this.entry, this.program) ? {} : { commonJsEntry: true }),
|
|
5419
6364
|
...(this.ffiImports.length > 0 ? { ffiImports: [...this.ffiImports] } : {}),
|
|
5420
6365
|
};
|
|
@@ -5422,11 +6367,23 @@ export class Lowerer {
|
|
|
5422
6367
|
sanitizeUnregisteredClassTypes(module, (name) => this.classes.has(name));
|
|
5423
6368
|
if (module)
|
|
5424
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);
|
|
5425
6381
|
return {
|
|
5426
6382
|
module,
|
|
5427
6383
|
diagnostics: this.diags,
|
|
5428
6384
|
runtimeFences: this.runtimeFences,
|
|
5429
6385
|
stats: this.stats,
|
|
6386
|
+
...(this.dynamicFunctions.length > 0 ? { dynamicFunctions: this.dynamicFunctions } : {}),
|
|
5430
6387
|
...(this.statsByFile.size > 0 ? { statsByFile: this.statsByFile } : {}),
|
|
5431
6388
|
...(this.provenanceElided.length > 0 ? { provenanceElided: this.provenanceElided } : {}),
|
|
5432
6389
|
};
|
|
@@ -5497,7 +6454,7 @@ export class Lowerer {
|
|
|
5497
6454
|
return;
|
|
5498
6455
|
this.stats.statementsTotal += n;
|
|
5499
6456
|
this.stats.statementsFailed += n;
|
|
5500
|
-
const file =
|
|
6457
|
+
const file = ts.getSourceFileOfNode(decl).fileName;
|
|
5501
6458
|
for (let i = 0; i < n; i++) {
|
|
5502
6459
|
this.bumpFileStat(file, "total");
|
|
5503
6460
|
this.bumpFileStat(file, "failed");
|
|
@@ -5539,7 +6496,7 @@ export class Lowerer {
|
|
|
5539
6496
|
// declarations before collectProgram visits their signatures.
|
|
5540
6497
|
this.checker.prefetchCollectionTypes(parts.flatMap((fp) => fp.fnDecls
|
|
5541
6498
|
.filter((decl) => decl.body !== undefined && decl.typeParameters === undefined)
|
|
5542
|
-
.flatMap((decl) => decl.parameters.flatMap((param) =>
|
|
6499
|
+
.flatMap((decl) => decl.parameters.nodes.flatMap((param) => param.initializer ? [param.initializer] : []))));
|
|
5543
6500
|
// JavaScript class shapes are partly declared by constructor-body
|
|
5544
6501
|
// assignments. Batch those collection-time queries across declarations
|
|
5545
6502
|
// before collectProgram visits them one by one; reached body lowering
|
|
@@ -5550,7 +6507,12 @@ export class Lowerer {
|
|
|
5550
6507
|
collectionEdges.add(name);
|
|
5551
6508
|
};
|
|
5552
6509
|
this.collectProgram(parts);
|
|
5553
|
-
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
|
+
});
|
|
5554
6516
|
// Decorated classes analyze post-collection here too: the %init seeds
|
|
5555
6517
|
// lower the decoration calls, whose edges (decorator bodies, construct
|
|
5556
6518
|
// thunks) reachable emit must see.
|
|
@@ -5563,8 +6525,8 @@ export class Lowerer {
|
|
|
5563
6525
|
// (qualified declaration names).
|
|
5564
6526
|
const units = new Map();
|
|
5565
6527
|
const bodyRoots = (...roots) => roots.filter((root) => root !== undefined && root !== null);
|
|
5566
|
-
const functionRoots = (decl) => bodyRoots(...decl.parameters.map((param) => param.initializer), decl.body);
|
|
5567
|
-
const classCtorRoots = (info) => bodyRoots(...(info.ctor?.parameters ?? []).map((param) => param.initializer), info.ctor?.body, ...info.fieldOrder.map((field) => field.initializer));
|
|
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));
|
|
5568
6530
|
const classMemberRoots = (info) => {
|
|
5569
6531
|
const roots = classCtorRoots(info);
|
|
5570
6532
|
for (const { member } of this.classMethodMembers(info))
|
|
@@ -5599,7 +6561,7 @@ export class Lowerer {
|
|
|
5599
6561
|
for (const info of this.classes.values()) {
|
|
5600
6562
|
if (info.builtinError)
|
|
5601
6563
|
continue; // runtime-provided; nothing lowers
|
|
5602
|
-
if (info.lifetimeRegion || info.internTable)
|
|
6564
|
+
if (info.lifetimeRegion || info.internTable || info.threadSlots)
|
|
5603
6565
|
continue; // synthesized with the class
|
|
5604
6566
|
// Generic-class INSTANTIATIONS (and mixin instantiations) are
|
|
5605
6567
|
// demand-driven, not units: their members lower unconditionally in
|
|
@@ -5906,6 +6868,13 @@ export class Lowerer {
|
|
|
5906
6868
|
this.shapes.settleDeclaredOrderPriorities();
|
|
5907
6869
|
for (const finalize of this.shapeOrderMetadataFinalizers)
|
|
5908
6870
|
finalize();
|
|
6871
|
+
applyKeyOrderWitnesses(this, [
|
|
6872
|
+
...orderedUnits,
|
|
6873
|
+
...initFunctions,
|
|
6874
|
+
...instanceFunctions,
|
|
6875
|
+
...this.liftedFns,
|
|
6876
|
+
...this.implicitFns,
|
|
6877
|
+
]);
|
|
5909
6878
|
for (const finalize of this.shapeOrderHelperFinalizers)
|
|
5910
6879
|
finalize();
|
|
5911
6880
|
const functions = [
|
|
@@ -5916,6 +6885,7 @@ export class Lowerer {
|
|
|
5916
6885
|
...this.liftedFns,
|
|
5917
6886
|
...this.implicitFns,
|
|
5918
6887
|
];
|
|
6888
|
+
functions.push(...runtimeClassConstructs(this, functions));
|
|
5919
6889
|
if (this.regexGroupResults)
|
|
5920
6890
|
for (const fn of functions)
|
|
5921
6891
|
foldRegexSpanReads(this, fn);
|
|
@@ -5986,23 +6956,8 @@ export class Lowerer {
|
|
|
5986
6956
|
return null;
|
|
5987
6957
|
}
|
|
5988
6958
|
this.runtimeFences.push(...captured);
|
|
5989
|
-
const
|
|
6959
|
+
const fence = this.runtimeFenceStmt(captured[0], node, target.fallback, target.bareMessage);
|
|
5990
6960
|
const loc = locOf(node);
|
|
5991
|
-
const code = first?.code ?? target.fallback.code;
|
|
5992
|
-
const baseMessage = first?.message ?? target.fallback.message;
|
|
5993
|
-
const messageLoc = first?.loc ?? loc;
|
|
5994
|
-
const source = first
|
|
5995
|
-
? (this.program.getSourceFile(messageLoc.file) ?? node.getSourceFile())
|
|
5996
|
-
: node.getSourceFile();
|
|
5997
|
-
const pos = ts.getLineAndCharacterOfPosition(source, messageLoc.start);
|
|
5998
|
-
const fence = {
|
|
5999
|
-
kind: "runtimeFence",
|
|
6000
|
-
code,
|
|
6001
|
-
message: target.bareMessage
|
|
6002
|
-
? baseMessage
|
|
6003
|
-
: `${baseMessage} [${code} at ${messageLoc.file}:${pos.line + 1}]`,
|
|
6004
|
-
loc,
|
|
6005
|
-
};
|
|
6006
6961
|
if (target.kind === "statement")
|
|
6007
6962
|
return fence;
|
|
6008
6963
|
const params = target.params ?? [];
|
|
@@ -6031,6 +6986,46 @@ export class Lowerer {
|
|
|
6031
6986
|
this.liftedFns.push(fn);
|
|
6032
6987
|
return { kind: "closure", fnName: fn.name, captures: [], type: target.type, loc };
|
|
6033
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
|
+
}
|
|
6034
7029
|
/** All diagnostics land here; while a generic instance body is lowering,
|
|
6035
7030
|
* the instantiation context is appended so the user knows which concrete
|
|
6036
7031
|
* types made the (source-anchored) construct fail. */
|
|
@@ -6100,9 +7095,9 @@ export class Lowerer {
|
|
|
6100
7095
|
// fetch values map earlier to checked-dynamic handles and do not reach
|
|
6101
7096
|
// here; constructor objects such as Headers still can.
|
|
6102
7097
|
if (typeSym &&
|
|
6103
|
-
FETCH_AMBIENT_TYPES.includes(typeSym
|
|
7098
|
+
FETCH_AMBIENT_TYPES.includes(ts.symbolName(typeSym)) &&
|
|
6104
7099
|
this.isStdlibSymbol(typeSym)) {
|
|
6105
|
-
this.pushDiag(unsupportedNativeApiDiag(`a value of type '${typeSym
|
|
7100
|
+
this.pushDiag(unsupportedNativeApiDiag(`a value of type '${ts.symbolName(typeSym)}'`, locOf(node)));
|
|
6106
7101
|
throw new PoisonError();
|
|
6107
7102
|
}
|
|
6108
7103
|
// ENUM OBJECTS (`typeof e` — a numeric enum's type carries the
|
|
@@ -6112,7 +7107,7 @@ export class Lowerer {
|
|
|
6112
7107
|
// as the per-site identifier fence — never the index-signature
|
|
6113
7108
|
// recitation.
|
|
6114
7109
|
if (typeSym && (typeSym.flags & ts.SymbolFlags.Enum) !== 0) {
|
|
6115
|
-
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)`));
|
|
6116
7111
|
throw new PoisonError();
|
|
6117
7112
|
}
|
|
6118
7113
|
// Would-be records with INDEX SIGNATURES (`Record<string, T>`,
|
|
@@ -6134,10 +7129,8 @@ export class Lowerer {
|
|
|
6134
7129
|
// (the value type, the key domain) the fences below tell better.
|
|
6135
7130
|
const ownSym = widened.getSymbol();
|
|
6136
7131
|
if (ownSym &&
|
|
6137
|
-
|
|
6138
|
-
.
|
|
6139
|
-
.some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
|
|
6140
|
-
this.isStdlibFile(d.getSourceFile()))) {
|
|
7132
|
+
ownSym.declarations.some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
|
|
7133
|
+
this.isStdlibFile(ts.getSourceFileOfNode(d)))) {
|
|
6141
7134
|
this.pushDiag(noLoweringDiag(this.checker.typeToString(type), locOf(node)));
|
|
6142
7135
|
throw new PoisonError();
|
|
6143
7136
|
}
|
|
@@ -6172,10 +7165,8 @@ export class Lowerer {
|
|
|
6172
7165
|
// tell — rather than an overload/record claim no user can act on.
|
|
6173
7166
|
const stdlibOwnSym = widened.getSymbol();
|
|
6174
7167
|
const stdlibNominal = stdlibOwnSym !== undefined &&
|
|
6175
|
-
|
|
6176
|
-
.
|
|
6177
|
-
.some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
|
|
6178
|
-
this.isStdlibFile(d.getSourceFile()));
|
|
7168
|
+
stdlibOwnSym.declarations.some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
|
|
7169
|
+
this.isStdlibFile(ts.getSourceFileOfNode(d)));
|
|
6179
7170
|
// OVERLOADED call signatures (SC2007) — after the generic branch, so a
|
|
6180
7171
|
// generic overload set keeps the monomorphization story: a value of a
|
|
6181
7172
|
// multi-signature type has no single compiled signature to hold.
|
|
@@ -6227,7 +7218,7 @@ export class Lowerer {
|
|
|
6227
7218
|
TextEncoder: "TextEncoder instances support encode(string) and encode(); other codec operations require a dedicated lowering",
|
|
6228
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",
|
|
6229
7220
|
};
|
|
6230
|
-
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) ?? ""]));
|
|
6231
7222
|
throw new PoisonError();
|
|
6232
7223
|
}
|
|
6233
7224
|
// USER record shapes blocked by ONE member (SC2009's record arm):
|
|
@@ -6254,7 +7245,9 @@ export class Lowerer {
|
|
|
6254
7245
|
return stdlibMemberFence(this, access);
|
|
6255
7246
|
}
|
|
6256
7247
|
fenceStaticResponseMember(access, use) {
|
|
6257
|
-
return fenceStaticResponseMember(this, access, use) ??
|
|
7248
|
+
return (fenceStaticResponseMember(this, access, use) ??
|
|
7249
|
+
fenceStaticBlobMember(this, access, use) ??
|
|
7250
|
+
fenceWebCryptoMember(this, access, use));
|
|
6258
7251
|
}
|
|
6259
7252
|
fenceUnsupportedFetchConstructorMember(access) {
|
|
6260
7253
|
return fenceUnsupportedFetchConstructorMember(this, access);
|
|
@@ -6275,7 +7268,7 @@ export class Lowerer {
|
|
|
6275
7268
|
return fenceStaticReadableStreamMember(this, access, use);
|
|
6276
7269
|
}
|
|
6277
7270
|
typeOf(node) {
|
|
6278
|
-
if (ts.isPropertyAccessExpression(node) && isJsSourceFile(
|
|
7271
|
+
if (ts.isPropertyAccessExpression(node) && isJsSourceFile(ts.getSourceFileOfNode(node))) {
|
|
6279
7272
|
const receiver = node.expression.kind === ts.SyntaxKind.ThisKeyword && this.fnStack.length > 0
|
|
6280
7273
|
? this.resolveThis()?.type
|
|
6281
7274
|
: this.mapTypeOf(this.checker.getTypeAtLocation(node.expression));
|
|
@@ -6290,11 +7283,25 @@ export class Lowerer {
|
|
|
6290
7283
|
return this.checker.getUnknownType();
|
|
6291
7284
|
}
|
|
6292
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
|
+
}
|
|
6293
7300
|
// A checked JS method receives its actual call-site receiver. Its
|
|
6294
7301
|
// declaration's inferred class type must not turn property reads back
|
|
6295
7302
|
// into native field loads when the method is borrowed by another object.
|
|
6296
7303
|
if (node.kind === ts.SyntaxKind.ThisKeyword &&
|
|
6297
|
-
isJsSourceFile(
|
|
7304
|
+
isJsSourceFile(ts.getSourceFileOfNode(node)) &&
|
|
6298
7305
|
this.fnStack.length > 0 &&
|
|
6299
7306
|
this.resolveThis()?.type.kind === "dyn")
|
|
6300
7307
|
return this.checker.getUnknownType();
|
|
@@ -6355,7 +7362,7 @@ export class Lowerer {
|
|
|
6355
7362
|
// JSDoc and initializer inference are declaration types, not flow
|
|
6356
7363
|
// proofs. A checked specialization must not reinstate those
|
|
6357
7364
|
// stale layouts (mutable/null slots and heterogeneous JS arrays).
|
|
6358
|
-
const declaration = sym &&
|
|
7365
|
+
const declaration = sym && sym.valueDeclaration;
|
|
6359
7366
|
const declared = declaration && ts.isParameter(declaration)
|
|
6360
7367
|
? this.mapTypeOf(this.checker.getTypeAtLocation(declaration.name))
|
|
6361
7368
|
: null;
|
|
@@ -6392,6 +7399,14 @@ export class Lowerer {
|
|
|
6392
7399
|
? (jsArgumentsFunctionType(this, t) ?? mapped)
|
|
6393
7400
|
: mapped;
|
|
6394
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
|
+
}
|
|
6395
7410
|
/** The one position where a contextual UNION must not be adopted over the
|
|
6396
7411
|
* expression's own: the LEFT operand of `&&`, `||`, or `??`. Adopting a
|
|
6397
7412
|
* contextual union is normally safe because tsc proved the value
|
|
@@ -6494,7 +7509,15 @@ export class Lowerer {
|
|
|
6494
7509
|
return ts.constituentTypes(part).every(visit);
|
|
6495
7510
|
return false;
|
|
6496
7511
|
};
|
|
6497
|
-
|
|
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
|
+
}
|
|
6498
7521
|
}
|
|
6499
7522
|
/** The lowered static array/tuple value behind checkerAnyArray's
|
|
6500
7523
|
* synthetic `any[]` spelling. Array.isArray can leave readonly tuple
|
|
@@ -6532,7 +7555,7 @@ export class Lowerer {
|
|
|
6532
7555
|
// JS inference can leave mutable fields, accessor parameters and
|
|
6533
7556
|
// locals at null/undefined despite later writes. Keep mutable native
|
|
6534
7557
|
// storage instead of a slot restricted to the initializer's unit value.
|
|
6535
|
-
if (isJsSourceFile(
|
|
7558
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(node)) &&
|
|
6536
7559
|
(t.flags & (ts.TypeFlags.Null | ts.TypeFlags.Undefined)) !== 0)
|
|
6537
7560
|
return DYN;
|
|
6538
7561
|
// A never-tainted JS type (neverTaintedJsType) maps — never rides as
|
|
@@ -6543,6 +7566,9 @@ export class Lowerer {
|
|
|
6543
7566
|
const argumentsType = jsArgumentsFunctionType(this, t);
|
|
6544
7567
|
if (argumentsType !== null)
|
|
6545
7568
|
return argumentsType;
|
|
7569
|
+
const localClass = genericLocalClassBinding(this, node);
|
|
7570
|
+
if (localClass !== null)
|
|
7571
|
+
return localClass;
|
|
6546
7572
|
// The checked-dynamic declaration fallback (dynFallbackType): a
|
|
6547
7573
|
// JAVASCRIPT binding of any inference residue, or a TypeScript
|
|
6548
7574
|
// binding of genuine checker-`any`, becomes the checked-dynamic
|
|
@@ -6570,6 +7596,13 @@ export class Lowerer {
|
|
|
6570
7596
|
requireExactShape(node, actual, expected) {
|
|
6571
7597
|
if (typeEquals(actual, expected))
|
|
6572
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
|
+
}
|
|
6573
7606
|
// dyn mismatches first. A dyn ('unknown') value flowing into a typed
|
|
6574
7607
|
// slot needs a CHECKED cast — the hint points at `as <type>`; tsc
|
|
6575
7608
|
// usually rejects this before we do, so the fence is mostly defensive.
|
|
@@ -6725,6 +7758,15 @@ export class Lowerer {
|
|
|
6725
7758
|
* else (including a DIFFERENT union) is left for requireExactShape, which
|
|
6726
7759
|
* rejects union mismatches with SC2003. */
|
|
6727
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
|
+
}
|
|
6728
7770
|
// A destination that holds undefined takes an unassigned deferred-init
|
|
6729
7771
|
// field's slot as is (Node passes the undefined along).
|
|
6730
7772
|
if (expected.kind === "union" && this.armTag(expected.unionId, UNDEFINED_T) >= 0) {
|
|
@@ -6734,6 +7776,10 @@ export class Lowerer {
|
|
|
6734
7776
|
}
|
|
6735
7777
|
if (expr.type.kind === "void" && expected.kind !== "void" && this.neverValued.has(expr))
|
|
6736
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);
|
|
6737
7783
|
// Iterator-typed slots: native iterators and differently typed
|
|
6738
7784
|
// generators step through an adapter generator.
|
|
6739
7785
|
if (expected.kind === "generator" && !typeEquals(expr.type, expected)) {
|
|
@@ -6754,6 +7800,16 @@ export class Lowerer {
|
|
|
6754
7800
|
// undefined/null literals store the dyn unit values. Types outside the
|
|
6755
7801
|
// dyn's domain (bytes, classes, Maps, ...) fall through to
|
|
6756
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
|
+
}
|
|
6757
7813
|
// Promise payloads may widen at a checked return boundary, including
|
|
6758
7814
|
// arrays inferred as tuple results by Promise.all. Keep both payload
|
|
6759
7815
|
// ABIs explicit: box settlement, then validate the destination payload.
|
|
@@ -6803,6 +7859,12 @@ export class Lowerer {
|
|
|
6803
7859
|
loc: expr.loc,
|
|
6804
7860
|
};
|
|
6805
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
|
+
}
|
|
6806
7868
|
if (expr.kind === "unitLit" || this.dynConvertible(expr.type)) {
|
|
6807
7869
|
// Records and arrays keep their identity as untyped values, including
|
|
6808
7870
|
// when they arrive through a union, so `unknown` views, weak
|
|
@@ -6816,12 +7878,16 @@ export class Lowerer {
|
|
|
6816
7878
|
const liveRef = liveReference(expr.type) ||
|
|
6817
7879
|
(expr.type.kind === "union" &&
|
|
6818
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;
|
|
6819
7884
|
return {
|
|
6820
7885
|
kind: "dynFrom",
|
|
6821
7886
|
value: expr,
|
|
6822
7887
|
type: DYN,
|
|
6823
7888
|
loc: expr.loc,
|
|
6824
7889
|
...(liveRef ? { liveRef: true } : {}),
|
|
7890
|
+
...(builtinName !== undefined ? { fnName: builtinName } : {}),
|
|
6825
7891
|
};
|
|
6826
7892
|
}
|
|
6827
7893
|
return expr;
|
|
@@ -6858,6 +7924,7 @@ export class Lowerer {
|
|
|
6858
7924
|
const funcOk = expected.kind === "func" &&
|
|
6859
7925
|
canAdaptDynFuncTo(expected, (id) => this.shapes.get(id), (id) => this.unions.get(id));
|
|
6860
7926
|
const handleOk = DYN_HANDLE_KINDS.has(expected.kind);
|
|
7927
|
+
noteUntypedStreamFlow(this, expected);
|
|
6861
7928
|
if (canDynCheckTo(expected, (id) => this.shapes.get(id), (id) => this.unions.get(id)) ||
|
|
6862
7929
|
undefArmedOk ||
|
|
6863
7930
|
bytesOk ||
|
|
@@ -6990,6 +8057,7 @@ export class Lowerer {
|
|
|
6990
8057
|
// and no completion target is meaningful — the exact-shape fence
|
|
6991
8058
|
// downstream names the class-value flow instead.
|
|
6992
8059
|
if (sub && sup && !sup.generic && this.ctorAbiEquals(sub, sup)) {
|
|
8060
|
+
defineClassValueConstruct(this, sup);
|
|
6993
8061
|
return { kind: "upcast", value: expr, type: expected, loc: expr.loc };
|
|
6994
8062
|
}
|
|
6995
8063
|
}
|
|
@@ -7026,6 +8094,11 @@ export class Lowerer {
|
|
|
7026
8094
|
return this.applyWidthLift(lift, narrowed, expected, expr.loc);
|
|
7027
8095
|
}
|
|
7028
8096
|
}
|
|
8097
|
+
if (expr.type.kind === "union" && expected.kind === "record") {
|
|
8098
|
+
const lifted = unionArmsWidthLift(this, expr, expected);
|
|
8099
|
+
if (lifted)
|
|
8100
|
+
return lifted;
|
|
8101
|
+
}
|
|
7029
8102
|
if (!typeEquals(expr.type, expected)) {
|
|
7030
8103
|
const w = this.widthCoerce(expr, expected);
|
|
7031
8104
|
if (w)
|
|
@@ -7110,6 +8183,7 @@ export class Lowerer {
|
|
|
7110
8183
|
if (baseTag >= 0) {
|
|
7111
8184
|
if (!sub || !this.ctorAbiEquals(sub, c))
|
|
7112
8185
|
break;
|
|
8186
|
+
defineClassValueConstruct(this, c);
|
|
7113
8187
|
const widened = {
|
|
7114
8188
|
kind: "upcast",
|
|
7115
8189
|
value: expr,
|
|
@@ -7266,6 +8340,9 @@ export class Lowerer {
|
|
|
7266
8340
|
recordUnionWrapHelper(source, toId, loc) {
|
|
7267
8341
|
return recordUnionWrapHelper(this, source, toId, loc);
|
|
7268
8342
|
}
|
|
8343
|
+
recordUnionRouteHelper(source, toId, loc) {
|
|
8344
|
+
return recordUnionRouteHelper(this, source, toId, loc);
|
|
8345
|
+
}
|
|
7269
8346
|
unionRetagHelper(fromId, toId, loc, trappable) {
|
|
7270
8347
|
return unionRetagHelper(this, fromId, toId, loc, trappable);
|
|
7271
8348
|
}
|
|
@@ -7284,6 +8361,7 @@ export class Lowerer {
|
|
|
7284
8361
|
* lowering goes through here (via lowerExprExpecting) or calls this
|
|
7285
8362
|
* directly when the expression was already lowered. */
|
|
7286
8363
|
coerceInto(node, expr, expected) {
|
|
8364
|
+
refuseInferredCallbackDrops(this, node, expr.type, expected);
|
|
7287
8365
|
// A union destination can accept the binding's tagged storage directly.
|
|
7288
8366
|
// The checker's single-arm flow type can be stale after a callback writes
|
|
7289
8367
|
// the binding. Extracting that arm and wrapping it again would discard the
|
|
@@ -7301,9 +8379,16 @@ export class Lowerer {
|
|
|
7301
8379
|
// initial contextual layout was chosen. Its known discriminator still
|
|
7302
8380
|
// selects the destination arm; validate that payload before wrapping.
|
|
7303
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.
|
|
7304
8386
|
if (expr.type.kind === "record" && expected.kind === "union") {
|
|
7305
8387
|
let literal = node;
|
|
7306
|
-
while (ts.isParenthesizedExpression(literal) ||
|
|
8388
|
+
while (ts.isParenthesizedExpression(literal) ||
|
|
8389
|
+
ts.isSatisfiesExpression(literal) ||
|
|
8390
|
+
ts.isAsExpression(literal) ||
|
|
8391
|
+
ts.isTypeAssertion(literal))
|
|
7307
8392
|
literal = literal.expression;
|
|
7308
8393
|
const def = this.unions.get(expected.unionId);
|
|
7309
8394
|
if (def?.discriminant && ts.isObjectLiteralExpression(literal)) {
|
|
@@ -7327,7 +8412,7 @@ export class Lowerer {
|
|
|
7327
8412
|
: [];
|
|
7328
8413
|
const errorOptions = parts.some((part) => {
|
|
7329
8414
|
const sym = part.getAliasSymbol() ?? part.getSymbol();
|
|
7330
|
-
return sym
|
|
8415
|
+
return (sym !== undefined && ts.symbolName(sym) === "ErrorOptions" && this.isStdlibSymbol(sym));
|
|
7331
8416
|
});
|
|
7332
8417
|
if (errorOptions) {
|
|
7333
8418
|
const actual = this.typeOf(node);
|
|
@@ -7357,7 +8442,7 @@ export class Lowerer {
|
|
|
7357
8442
|
let literal = node;
|
|
7358
8443
|
while (ts.isParenthesizedExpression(literal))
|
|
7359
8444
|
literal = literal.expression;
|
|
7360
|
-
if (isJsSourceFile(
|
|
8445
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(node)) &&
|
|
7361
8446
|
!ts.isArrayLiteralExpression(literal) &&
|
|
7362
8447
|
e.kind === "dynFrom" &&
|
|
7363
8448
|
e.value.type.kind === "array") {
|
|
@@ -7376,7 +8461,8 @@ export class Lowerer {
|
|
|
7376
8461
|
// node's CHECKER type proves those arms away, they trap instead — the
|
|
7377
8462
|
// sub-union narrowing bridge (narrowedRetagHelper).
|
|
7378
8463
|
if (e.type.kind === "union" && expected.kind === "union" && !typeEquals(e.type, expected)) {
|
|
7379
|
-
const helper = this.narrowedRetagHelper(node, e.type.unionId, expected.unionId, e.loc)
|
|
8464
|
+
const helper = this.narrowedRetagHelper(node, e.type.unionId, expected.unionId, e.loc) ??
|
|
8465
|
+
uninhabitedArmRetagHelper(this, node, e.type.unionId, expected.unionId, e.loc);
|
|
7380
8466
|
if (helper) {
|
|
7381
8467
|
e = { kind: "call", callee: helper, args: [e], type: expected, loc: e.loc };
|
|
7382
8468
|
}
|
|
@@ -7386,7 +8472,7 @@ export class Lowerer {
|
|
|
7386
8472
|
// never reinterpret an object payload as a scalar union arm.
|
|
7387
8473
|
if (e.type.kind === "union" &&
|
|
7388
8474
|
!typeEquals(e.type, expected) &&
|
|
7389
|
-
isJsSourceFile(
|
|
8475
|
+
isJsSourceFile(ts.getSourceFileOfNode(node)) &&
|
|
7390
8476
|
this.dynConvertible(e.type)) {
|
|
7391
8477
|
const sourceArms = this.unions.get(e.type.unionId)?.arms ?? [];
|
|
7392
8478
|
const targetArms = this.unions.get(expected.unionId)?.arms ?? [];
|
|
@@ -7423,7 +8509,7 @@ export class Lowerer {
|
|
|
7423
8509
|
const sym = this.resolveValueSymbol(n);
|
|
7424
8510
|
if (!sym)
|
|
7425
8511
|
return null;
|
|
7426
|
-
const decls =
|
|
8512
|
+
const decls = sym.declarations;
|
|
7427
8513
|
if (decls.length === 0)
|
|
7428
8514
|
return null;
|
|
7429
8515
|
const units = new Set();
|
|
@@ -7434,7 +8520,7 @@ export class Lowerer {
|
|
|
7434
8520
|
!ts.isIdentifier(d.name) ||
|
|
7435
8521
|
!ts.isVariableDeclarationList(d.parent) ||
|
|
7436
8522
|
!ts.isVariableStatement(d.parent.parent) ||
|
|
7437
|
-
|
|
8523
|
+
ts.getSourceFileOfNode(d).isDeclarationFile ||
|
|
7438
8524
|
(ts.getCombinedModifierFlags(d) & ts.ModifierFlags.Ambient) !== 0) {
|
|
7439
8525
|
return null;
|
|
7440
8526
|
}
|
|
@@ -7551,6 +8637,9 @@ export class Lowerer {
|
|
|
7551
8637
|
if (expected) {
|
|
7552
8638
|
if (ts.isConditionalExpression(node))
|
|
7553
8639
|
return lowerTernary(this, node, expected);
|
|
8640
|
+
const escaped = this.neverAssertionInto(node, expected);
|
|
8641
|
+
if (escaped)
|
|
8642
|
+
return escaped;
|
|
7554
8643
|
const fresh = this.emptyCollectionFor(node, expected);
|
|
7555
8644
|
if (fresh)
|
|
7556
8645
|
return this.coerceInto(node, fresh, expected);
|
|
@@ -7600,10 +8689,10 @@ export class Lowerer {
|
|
|
7600
8689
|
// Construct its actual storage here so identity and WeakMap lifetime
|
|
7601
8690
|
// belong to the array the program keeps, rather than a typed snapshot.
|
|
7602
8691
|
if (ts.isArrayLiteralExpression(x) &&
|
|
7603
|
-
x.elements.every((element) => !ts.isSpreadElement(element) && !ts.isOmittedExpression(element))) {
|
|
8692
|
+
x.elements.nodes.every((element) => !ts.isSpreadElement(element) && !ts.isOmittedExpression(element))) {
|
|
7604
8693
|
return {
|
|
7605
8694
|
kind: "dynArrLit",
|
|
7606
|
-
elems: x.elements.map((element) => this.lowerExprExpecting(element, DYN)),
|
|
8695
|
+
elems: x.elements.nodes.map((element) => this.lowerExprExpecting(element, DYN)),
|
|
7607
8696
|
type: DYN,
|
|
7608
8697
|
loc: locOf(x),
|
|
7609
8698
|
};
|
|
@@ -7617,16 +8706,17 @@ export class Lowerer {
|
|
|
7617
8706
|
: [];
|
|
7618
8707
|
const builtinOption = (name) => parts.some((part) => {
|
|
7619
8708
|
const sym = part.getAliasSymbol() ?? part.getSymbol();
|
|
7620
|
-
return sym
|
|
8709
|
+
return ts.symbolNameOf(sym) === name && this.isStdlibSymbol(sym);
|
|
7621
8710
|
});
|
|
7622
8711
|
if (ts.isObjectLiteralExpression(x)) {
|
|
7623
|
-
if (isJsSourceFile(
|
|
8712
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(x)) ||
|
|
7624
8713
|
builtinOption("RequestInit") ||
|
|
7625
8714
|
builtinOption("ErrorOptions") ||
|
|
7626
8715
|
builtinOption("SpawnOptions") ||
|
|
7627
8716
|
builtinOption("UrlObject") ||
|
|
7628
8717
|
builtinOption("URLFormatOptions") ||
|
|
7629
|
-
!this.mapTypeOf(this.typeOf(x))
|
|
8718
|
+
!this.mapTypeOf(this.typeOf(x)) ||
|
|
8719
|
+
this.excessJsContextualProperty(x, parts)) {
|
|
7630
8720
|
return lowerDynObjectLiteral(this, x);
|
|
7631
8721
|
}
|
|
7632
8722
|
}
|
|
@@ -7647,24 +8737,24 @@ export class Lowerer {
|
|
|
7647
8737
|
// a unit-only-element array — a checker type that degraded to one
|
|
7648
8738
|
// (`[]`-flavored inference over a populated literal) carries no
|
|
7649
8739
|
// element information.
|
|
7650
|
-
const nonUnitElems = x.elements.some((el) => !ts.isOmittedExpression(el) &&
|
|
8740
|
+
const nonUnitElems = x.elements.nodes.some((el) => !ts.isOmittedExpression(el) &&
|
|
7651
8741
|
el.kind !== ts.SyntaxKind.NullKeyword &&
|
|
7652
8742
|
!(ts.isIdentifier(el) && el.text === "undefined"));
|
|
7653
8743
|
const def = this.unions.get(expected.unionId);
|
|
7654
8744
|
const arms = (def?.arms ?? []).filter((a) => (a.kind === "array" && !(nonUnitElems && this.unitOnlyElem(a.elem))) ||
|
|
7655
8745
|
(a.kind === "record" &&
|
|
7656
8746
|
!!this.shapes.get(a.shapeId)?.tuple &&
|
|
7657
|
-
this.shapes.get(a.shapeId).fields.length === x.elements.length &&
|
|
7658
|
-
!x.elements.some(ts.isSpreadElement)));
|
|
8747
|
+
this.shapes.get(a.shapeId).fields.length === x.elements.nodes.length &&
|
|
8748
|
+
!x.elements.nodes.some(ts.isSpreadElement)));
|
|
7659
8749
|
let arm = arms.length === 1 ? arms[0] : undefined;
|
|
7660
8750
|
if (!arm &&
|
|
7661
8751
|
arms.length > 1 &&
|
|
7662
|
-
x.elements.length > 0 &&
|
|
7663
|
-
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))) {
|
|
7664
8754
|
const ownType = this.mapTypeOf(this.typeOf(x));
|
|
7665
8755
|
arm = arms.find((candidate) => ownType !== null && typeEquals(candidate, ownType));
|
|
7666
8756
|
if (!arm) {
|
|
7667
|
-
const elements = x.elements.map((el) => tryLowerExpression(this, el));
|
|
8757
|
+
const elements = x.elements.nodes.map((el) => tryLowerExpression(this, el));
|
|
7668
8758
|
arm = arms.find((candidate) => candidate.kind === "array" &&
|
|
7669
8759
|
elements.every((element) => element !== null && this.widthLiftPlan(element.type, candidate.elem) !== null));
|
|
7670
8760
|
}
|
|
@@ -7675,14 +8765,20 @@ export class Lowerer {
|
|
|
7675
8765
|
}
|
|
7676
8766
|
}
|
|
7677
8767
|
}
|
|
7678
|
-
|
|
7679
|
-
|
|
7680
|
-
|
|
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)))) {
|
|
7681
8777
|
// A destination that accepts undefined must retain an unchecked
|
|
7682
8778
|
// read's storage value even when the checker still calls it present.
|
|
7683
8779
|
e = this.runtimeOptionalSourceValue(node, e) ?? e;
|
|
7684
8780
|
}
|
|
7685
|
-
return
|
|
8781
|
+
return this.coerceInto(node, e, expected);
|
|
7686
8782
|
}
|
|
7687
8783
|
/** An unannotated empty collection has no existing elements or aliases
|
|
7688
8784
|
* that constrain its layout. An explicit type argument still wins. */
|
|
@@ -7692,13 +8788,13 @@ export class Lowerer {
|
|
|
7692
8788
|
value = value.expression;
|
|
7693
8789
|
if (!ts.isNewExpression(value) ||
|
|
7694
8790
|
!ts.isIdentifier(value.expression) ||
|
|
7695
|
-
(value.arguments?.length ?? 0) !== 0 ||
|
|
7696
|
-
(value.typeArguments?.length ?? 0) !== 0)
|
|
8791
|
+
(value.arguments?.nodes.length ?? 0) !== 0 ||
|
|
8792
|
+
(value.typeArguments?.nodes.length ?? 0) !== 0)
|
|
7697
8793
|
return null;
|
|
7698
8794
|
const symbol = this.resolveValueSymbol(value.expression);
|
|
7699
8795
|
if (!symbol || !this.isStdlibSymbol(symbol))
|
|
7700
8796
|
return null;
|
|
7701
|
-
const kind = symbol
|
|
8797
|
+
const kind = ts.symbolName(symbol) === "Map" ? "map" : ts.symbolName(symbol) === "Set" ? "set" : null;
|
|
7702
8798
|
if (!kind)
|
|
7703
8799
|
return null;
|
|
7704
8800
|
const arms = expected.kind === "union" ? (this.unions.get(expected.unionId)?.arms ?? []) : [expected];
|
|
@@ -7752,6 +8848,17 @@ export class Lowerer {
|
|
|
7752
8848
|
this.addedUndefinedArms.set(t.unionId, { type, unions: this.unions.revision });
|
|
7753
8849
|
return type;
|
|
7754
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
|
+
}
|
|
7755
8862
|
/** True when a static type converts to a dyn value (the dynFrom
|
|
7756
8863
|
* walker's domain): JSON-safe, bytes<u8> (Uint8Array/Buffer — the checked-dynamic tree's
|
|
7757
8864
|
* bytes kind, payload copied; stdin chunks into unknown-typed helpers),
|
|
@@ -7786,15 +8893,24 @@ export class Lowerer {
|
|
|
7786
8893
|
// storage directly, just like arguments and variable initializers.
|
|
7787
8894
|
// Contextual types (such as Proxy descriptors' symbol-valued fields)
|
|
7788
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) {
|
|
7789
8903
|
let literal = node;
|
|
7790
8904
|
while (ts.isParenthesizedExpression(literal))
|
|
7791
8905
|
literal = literal.expression;
|
|
7792
|
-
|
|
7793
|
-
isJsSourceFile(
|
|
7794
|
-
ts.isObjectLiteralExpression(literal))
|
|
7795
|
-
|
|
7796
|
-
|
|
7797
|
-
|
|
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) {
|
|
7798
8914
|
if (expected.kind === "void" && e.kind === "unitLit")
|
|
7799
8915
|
return null;
|
|
7800
8916
|
if (this.ctx.isAsync && e.type.kind === "promise" && expected.kind !== "promise") {
|
|
@@ -7858,10 +8974,28 @@ export class Lowerer {
|
|
|
7858
8974
|
}
|
|
7859
8975
|
return s;
|
|
7860
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
|
+
}
|
|
7861
8992
|
lowerReturnOf(node, loc) {
|
|
7862
8993
|
const expected = this.ctx.returnType;
|
|
7863
8994
|
if (expected.kind === "void") {
|
|
7864
8995
|
let e = this.lowerExpr(node);
|
|
8996
|
+
const flattened = this.maybePromiseReturn(node, e, expected);
|
|
8997
|
+
if (flattened)
|
|
8998
|
+
return flattened;
|
|
7865
8999
|
if (this.ctx.isAsync && e.type.kind === "promise") {
|
|
7866
9000
|
if (this.adoptsReturnedPromise())
|
|
7867
9001
|
return this.adoptingReturn(e, VOID, (x) => x);
|
|
@@ -7869,6 +9003,14 @@ export class Lowerer {
|
|
|
7869
9003
|
}
|
|
7870
9004
|
if (e.kind === "unitLit")
|
|
7871
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
|
+
}
|
|
7872
9014
|
if (e.type.kind === "void")
|
|
7873
9015
|
return { kind: "return", value: e, loc };
|
|
7874
9016
|
return {
|
|
@@ -7880,6 +9022,16 @@ export class Lowerer {
|
|
|
7880
9022
|
loc,
|
|
7881
9023
|
};
|
|
7882
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
|
+
}
|
|
7883
9035
|
return { kind: "return", value: this.lowerReturnValue(node), loc };
|
|
7884
9036
|
}
|
|
7885
9037
|
maybeNarrow(expr, node) {
|
|
@@ -8036,7 +9188,7 @@ export class Lowerer {
|
|
|
8036
9188
|
// declaration poisons under a source-anchored diagnostic, deferred
|
|
8037
9189
|
// like any collection fence — never a crashed CLI.
|
|
8038
9190
|
if (isCheckerPanic(e)) {
|
|
8039
|
-
const decl = symbol ?
|
|
9191
|
+
const decl = symbol ? symbol.declarations[0] : undefined;
|
|
8040
9192
|
sink.push(checkerPanicDiag(e.message.split("\n", 1)[0], decl ? locOf(decl) : { file: this.entry.fileName, start: 0, end: 0 }));
|
|
8041
9193
|
}
|
|
8042
9194
|
else if (!(e instanceof PoisonError)) {
|
|
@@ -8147,27 +9299,27 @@ export class Lowerer {
|
|
|
8147
9299
|
const typeNodes = [];
|
|
8148
9300
|
const symbolRoots = [];
|
|
8149
9301
|
for (const decl of decls) {
|
|
8150
|
-
for (const member of decl.members) {
|
|
9302
|
+
for (const member of decl.members.nodes) {
|
|
8151
9303
|
if ((ts.isConstructorDeclaration(member) ||
|
|
8152
9304
|
ts.isMethodDeclaration(member) ||
|
|
8153
9305
|
ts.isGetAccessor(member) ||
|
|
8154
9306
|
ts.isSetAccessor(member)) &&
|
|
8155
9307
|
(!ts.isMethodDeclaration(member) || member.typeParameters === undefined)) {
|
|
8156
|
-
for (const param of member.parameters) {
|
|
9308
|
+
for (const param of member.parameters.nodes) {
|
|
8157
9309
|
if (param.initializer)
|
|
8158
9310
|
defaultTypeNodes.push(param.initializer);
|
|
8159
9311
|
}
|
|
8160
9312
|
}
|
|
8161
9313
|
}
|
|
8162
|
-
if (!isJsSourceFile(
|
|
9314
|
+
if (!isJsSourceFile(ts.getSourceFileOfNode(decl)))
|
|
8163
9315
|
continue;
|
|
8164
|
-
for (const member of decl.members) {
|
|
9316
|
+
for (const member of decl.members.nodes) {
|
|
8165
9317
|
if (ts.isConstructorDeclaration(member)) {
|
|
8166
|
-
for (const param of member.parameters) {
|
|
9318
|
+
for (const param of member.parameters.nodes) {
|
|
8167
9319
|
if (param.initializer)
|
|
8168
9320
|
typeNodes.push(param.initializer);
|
|
8169
9321
|
}
|
|
8170
|
-
for (const stmt of member.body?.statements ?? []) {
|
|
9322
|
+
for (const stmt of member.body?.statements?.nodes ?? []) {
|
|
8171
9323
|
if (!ts.isExpressionStatement(stmt) || !ts.isBinaryExpression(stmt.expression))
|
|
8172
9324
|
continue;
|
|
8173
9325
|
if (stmt.expression.operatorToken.kind !== ts.SyntaxKind.EqualsToken)
|
|
@@ -8186,13 +9338,13 @@ export class Lowerer {
|
|
|
8186
9338
|
if (ts.isMethodDeclaration(member) ||
|
|
8187
9339
|
ts.isGetAccessor(member) ||
|
|
8188
9340
|
ts.isSetAccessor(member)) {
|
|
8189
|
-
for (const param of member.parameters) {
|
|
9341
|
+
for (const param of member.parameters.nodes) {
|
|
8190
9342
|
if (param.initializer)
|
|
8191
9343
|
typeNodes.push(param.initializer);
|
|
8192
9344
|
}
|
|
8193
9345
|
// npm-static implicit-any classification resolves body parameter
|
|
8194
9346
|
// references while collecting the method's shape.
|
|
8195
|
-
if (implicitMonoFile(
|
|
9347
|
+
if (implicitMonoFile(ts.getSourceFileOfNode(decl)) && member.body) {
|
|
8196
9348
|
symbolRoots.push(member.body);
|
|
8197
9349
|
}
|
|
8198
9350
|
}
|
|
@@ -8219,6 +9371,43 @@ export class Lowerer {
|
|
|
8219
9371
|
lowerClassExpressionInfo(expr) {
|
|
8220
9372
|
return lowerClassExpressionInfo(this, expr);
|
|
8221
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
|
+
}
|
|
8222
9411
|
lowerClassExpression(expr) {
|
|
8223
9412
|
return lowerClassExpression(this, expr);
|
|
8224
9413
|
}
|
|
@@ -8226,6 +9415,14 @@ export class Lowerer {
|
|
|
8226
9415
|
findMethodOn(info, name) {
|
|
8227
9416
|
return findMethodOn(this, info, name);
|
|
8228
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
|
+
}
|
|
8229
9426
|
isSubclassOf(sub, sup) {
|
|
8230
9427
|
return isSubclassOf(this, sub, sup);
|
|
8231
9428
|
}
|
|
@@ -8342,7 +9539,7 @@ export class Lowerer {
|
|
|
8342
9539
|
*classMethodMembers(info, includeAbstract = false) {
|
|
8343
9540
|
if (!info.decl)
|
|
8344
9541
|
return; // builtin error classes: runtime-provided bodies
|
|
8345
|
-
for (const member of info.decl.members) {
|
|
9542
|
+
for (const member of info.decl.members.nodes) {
|
|
8346
9543
|
const fnLike = ts.isMethodDeclaration(member) || ts.isGetAccessor(member) || ts.isSetAccessor(member)
|
|
8347
9544
|
? member
|
|
8348
9545
|
: null;
|
|
@@ -8406,6 +9603,9 @@ export class Lowerer {
|
|
|
8406
9603
|
lowerDefaultExport(stmt) {
|
|
8407
9604
|
return lowerDefaultExport(this, stmt);
|
|
8408
9605
|
}
|
|
9606
|
+
/** Statements %main runs before any module initializer: runtime
|
|
9607
|
+
* registrations the lowering passes add. */
|
|
9608
|
+
mainPrelude = [];
|
|
8409
9609
|
buildMain() {
|
|
8410
9610
|
return buildMain(this);
|
|
8411
9611
|
}
|
|
@@ -8461,6 +9661,92 @@ export class Lowerer {
|
|
|
8461
9661
|
declareHiddenLocal(name, type) {
|
|
8462
9662
|
return declareContextLocal(this.ctx, name, type, false, undefined, undefined);
|
|
8463
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
|
+
}
|
|
8464
9750
|
/** Declares a callee's parameter locals from its ParamShapes and builds
|
|
8465
9751
|
* the DEFAULT-PARAM PROLOGUE. Required/optional/rest params bind their
|
|
8466
9752
|
* symbol directly (one local of the ABI type). A defaulted param `x: T = e`
|
|
@@ -8495,6 +9781,15 @@ export class Lowerer {
|
|
|
8495
9781
|
return defaultAfterUndefined(undefinedValue, this.coerceInto(node, absent, expected));
|
|
8496
9782
|
};
|
|
8497
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
|
+
}
|
|
8498
9793
|
const shape = shapes[i];
|
|
8499
9794
|
if (ts.isArrayBindingPattern(decl.name) || ts.isObjectBindingPattern(decl.name)) {
|
|
8500
9795
|
// Pattern parameter: one hidden ABI slot carries the source value;
|
|
@@ -8541,7 +9836,7 @@ export class Lowerer {
|
|
|
8541
9836
|
// RequireObjectCoercible; use V8's default-expression spelling.
|
|
8542
9837
|
if (abi.kind === "dyn" &&
|
|
8543
9838
|
ts.isObjectBindingPattern(decl.name) &&
|
|
8544
|
-
decl.name.elements.length === 0) {
|
|
9839
|
+
decl.name.elements.nodes.length === 0) {
|
|
8545
9840
|
prologue.push({
|
|
8546
9841
|
kind: "exprStmt",
|
|
8547
9842
|
expr: {
|
|
@@ -8620,10 +9915,32 @@ export class Lowerer {
|
|
|
8620
9915
|
srcType = pickedT;
|
|
8621
9916
|
srcRef = () => ({ kind: "varRef", localId: src.id, type: pickedT, loc });
|
|
8622
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
|
+
}
|
|
8623
9929
|
this.lowerBindingPattern(decl.name, srcRef, srcType, true, prologue);
|
|
8624
9930
|
return;
|
|
8625
9931
|
}
|
|
8626
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
|
+
}
|
|
8627
9944
|
if (shape.mode === "omittable" && shape.bodyType && decl.initializer) {
|
|
8628
9945
|
const abi = shape.type;
|
|
8629
9946
|
if (abi.kind === "dyn") {
|
|
@@ -8794,6 +10111,11 @@ export class Lowerer {
|
|
|
8794
10111
|
if (!symbol)
|
|
8795
10112
|
return null;
|
|
8796
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
|
+
}
|
|
8797
10119
|
if (direct)
|
|
8798
10120
|
return direct;
|
|
8799
10121
|
// A PARAMETER PROPERTY declares two symbols: references resolve to the
|
|
@@ -8801,11 +10123,11 @@ export class Lowerer {
|
|
|
8801
10123
|
// symbol — which is what declareParams registered the local under.
|
|
8802
10124
|
// On a miss, normalize to the declaration's key and retry (ordinary
|
|
8803
10125
|
// bindings never reach this — their two sides intern to one symbol).
|
|
8804
|
-
const vd =
|
|
10126
|
+
const vd = symbol.valueDeclaration;
|
|
8805
10127
|
if (vd &&
|
|
8806
10128
|
ts.isParameter(vd) &&
|
|
8807
10129
|
ts.isIdentifier(vd.name) &&
|
|
8808
|
-
vd.modifiers?.some((m) => m.kind === ts.SyntaxKind.PublicKeyword ||
|
|
10130
|
+
vd.modifiers?.nodes.some((m) => m.kind === ts.SyntaxKind.PublicKeyword ||
|
|
8809
10131
|
m.kind === ts.SyntaxKind.PrivateKeyword ||
|
|
8810
10132
|
m.kind === ts.SyntaxKind.ProtectedKeyword ||
|
|
8811
10133
|
m.kind === ts.SyntaxKind.ReadonlyKeyword ||
|
|
@@ -8819,8 +10141,8 @@ export class Lowerer {
|
|
|
8819
10141
|
/** Lexical `this` — the enclosing method's this-param, possibly captured
|
|
8820
10142
|
* through arrows (function expressions/declarations reset `this` in JS;
|
|
8821
10143
|
* their bodies never see an enclosing method's binding). */
|
|
8822
|
-
resolveThis() {
|
|
8823
|
-
return this.resolveKey(undefined);
|
|
10144
|
+
resolveThis(blame) {
|
|
10145
|
+
return this.resolveKey(undefined, blame);
|
|
8824
10146
|
}
|
|
8825
10147
|
peekLocal(ident) {
|
|
8826
10148
|
let symbol = this.checker.getSymbolAtLocation(ident);
|
|
@@ -8845,9 +10167,7 @@ export class Lowerer {
|
|
|
8845
10167
|
this.runtimeOptionalRoots.set(entry, root);
|
|
8846
10168
|
});
|
|
8847
10169
|
if (resolved.error !== null) {
|
|
8848
|
-
const location = blame ??
|
|
8849
|
-
(symbol === undefined ? undefined : this.checker.declarationsOf(symbol)[0]) ??
|
|
8850
|
-
this.entry;
|
|
10170
|
+
const location = blame ?? (symbol === undefined ? undefined : symbol.declarations[0]) ?? this.entry;
|
|
8851
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)`;
|
|
8852
10172
|
this.unsupported("SC1090", location, message);
|
|
8853
10173
|
}
|
|
@@ -8920,7 +10240,7 @@ export class Lowerer {
|
|
|
8920
10240
|
// concrete signature — name the shape instead of the generic
|
|
8921
10241
|
// binding-form text.
|
|
8922
10242
|
if (symbol) {
|
|
8923
|
-
const d =
|
|
10243
|
+
const d = symbol.valueDeclaration;
|
|
8924
10244
|
if (d && ts.isVariableDeclaration(d) && d.initializer === undefined) {
|
|
8925
10245
|
const t = this.checker.getTypeOfSymbol(symbol);
|
|
8926
10246
|
const parts = t.isUnionType() ? ts.constituentTypes(t) : [t];
|
|
@@ -8934,7 +10254,7 @@ export class Lowerer {
|
|
|
8934
10254
|
// assignment are `undefined`, and this binding's type has no slot for
|
|
8935
10255
|
// that value — name the shape instead of the generic no-lowering text.
|
|
8936
10256
|
if (symbol) {
|
|
8937
|
-
const d =
|
|
10257
|
+
const d = symbol.valueDeclaration;
|
|
8938
10258
|
if (d &&
|
|
8939
10259
|
ts.isVariableDeclaration(d) &&
|
|
8940
10260
|
(ts.getCombinedNodeFlags(d) & ts.NodeFlags.BlockScoped) === 0) {
|
|
@@ -9315,8 +10635,13 @@ export class Lowerer {
|
|
|
9315
10635
|
// dispatch. The general identifier-call paths have no lowering for a
|
|
9316
10636
|
// promise-returning ambient global, and `import` is a keyword callee no
|
|
9317
10637
|
// identifier path matches.
|
|
10638
|
+
const webAssembly = lowerWebAssemblyCall(this, expr);
|
|
10639
|
+
if (webAssembly !== null)
|
|
10640
|
+
return webAssembly;
|
|
10641
|
+
refuseWebAssemblyUse(this, expr.expression);
|
|
9318
10642
|
return (lowerLifetimeRegionCall(this, expr) ??
|
|
9319
10643
|
lowerInternTableCall(this, expr) ??
|
|
10644
|
+
lowerThreadSlotsCall(this, expr) ??
|
|
9320
10645
|
lowerFfiCall(this, expr) ??
|
|
9321
10646
|
lowerFetchCall(this, expr) ??
|
|
9322
10647
|
lowerStaticFetchCompanionCall(this, expr) ??
|
|
@@ -9327,7 +10652,9 @@ export class Lowerer {
|
|
|
9327
10652
|
lowerStaticReadableStreamReaderCall(this, expr) ??
|
|
9328
10653
|
lowerStaticResponseCall(this, expr) ??
|
|
9329
10654
|
lowerStaticBlobCall(this, expr) ??
|
|
10655
|
+
lowerWebCryptoCall(this, expr) ??
|
|
9330
10656
|
lowerKeyObjectCall(this, expr) ??
|
|
10657
|
+
lowerNetAddressCall(this, expr) ??
|
|
9331
10658
|
lowerFetchElementMethodCall(this, expr) ??
|
|
9332
10659
|
lowerDynamicImportCall(this, expr) ??
|
|
9333
10660
|
lowerCall(this, expr));
|
|
@@ -9454,13 +10781,20 @@ export class Lowerer {
|
|
|
9454
10781
|
return inheritsBuiltinEmitterCtor(this, info);
|
|
9455
10782
|
}
|
|
9456
10783
|
lowerNew(expr) {
|
|
10784
|
+
const webAssembly = lowerWebAssemblyNew(this, expr);
|
|
10785
|
+
if (webAssembly !== null)
|
|
10786
|
+
return webAssembly;
|
|
10787
|
+
refuseWebAssemblyUse(this, expr.expression, "new ");
|
|
9457
10788
|
const builtin = lowerLifetimeRegionNew(this, expr) ??
|
|
9458
10789
|
lowerInternTableNew(this, expr) ??
|
|
10790
|
+
lowerThreadSlotsNew(this, expr) ??
|
|
9459
10791
|
lowerAbortControllerNew(this, expr) ??
|
|
10792
|
+
lowerDisposableStackNew(this, expr) ??
|
|
9460
10793
|
lowerEventTargetNew(this, expr) ??
|
|
9461
10794
|
lowerFetchWebNew(this, expr) ??
|
|
9462
10795
|
lowerResponseNew(this, expr) ??
|
|
9463
10796
|
lowerBlobNew(this, expr) ??
|
|
10797
|
+
lowerNetAddressNew(this, expr) ??
|
|
9464
10798
|
lowerStaticReadableStreamNew(this, expr) ??
|
|
9465
10799
|
lowerConsoleNew(this, expr);
|
|
9466
10800
|
return (builtin ?? this.withRuntimeOptionalClassValue(expr.expression, () => lowerNew(this, expr)));
|
|
@@ -9541,9 +10875,21 @@ export class Lowerer {
|
|
|
9541
10875
|
if (mapped?.kind === "moduleNs" && mapped.moduleId.startsWith("builtin:")) {
|
|
9542
10876
|
return mapped.moduleId.slice("builtin:".length);
|
|
9543
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
|
+
}
|
|
9544
10890
|
if (ts.isIdentifier(expr)) {
|
|
9545
10891
|
const symbol = this.checker.getSymbolAtLocation(expr);
|
|
9546
|
-
const decl = symbol ?
|
|
10892
|
+
const decl = symbol ? symbol.declarations[0] : undefined;
|
|
9547
10893
|
if (!decl)
|
|
9548
10894
|
return null;
|
|
9549
10895
|
// The CommonJS twin: `const fs = require("fs")` binds the same
|
|
@@ -9612,7 +10958,7 @@ export class Lowerer {
|
|
|
9612
10958
|
}
|
|
9613
10959
|
if (ts.isIdentifier(expr)) {
|
|
9614
10960
|
const symbol = this.checker.getSymbolAtLocation(expr);
|
|
9615
|
-
const decl = symbol ?
|
|
10961
|
+
const decl = symbol ? symbol.declarations[0] : undefined;
|
|
9616
10962
|
if (!decl)
|
|
9617
10963
|
return null;
|
|
9618
10964
|
// The DEFAULT-import twin: Node's default export of a CJS builtin
|
|
@@ -9663,9 +11009,47 @@ export class Lowerer {
|
|
|
9663
11009
|
return { module: "fs", member: "realpathSync.native" };
|
|
9664
11010
|
}
|
|
9665
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
|
+
}
|
|
9666
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;
|
|
9667
11043
|
if (module !== null)
|
|
9668
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
|
+
}
|
|
9669
11053
|
// The RE-EXPORT FACADE's namespace spelling: `import * as assert from
|
|
9670
11054
|
// "./facade.js"` over `export { ok } from "node:assert"` (the formatter idiom's
|
|
9671
11055
|
// universal/assert). The member's symbol is the facade's
|
|
@@ -9705,9 +11089,8 @@ export class Lowerer {
|
|
|
9705
11089
|
COPYFILE_FICLONE_FORCE: 4,
|
|
9706
11090
|
};
|
|
9707
11091
|
const value = own(MODES, expr.name.text);
|
|
9708
|
-
if (value === undefined)
|
|
9709
|
-
|
|
9710
|
-
}
|
|
11092
|
+
if (value === undefined)
|
|
11093
|
+
return fsConstantMemberRead(expr);
|
|
9711
11094
|
return { kind: "numLit", value, type: F64, loc };
|
|
9712
11095
|
}
|
|
9713
11096
|
}
|
|
@@ -9719,9 +11102,18 @@ export class Lowerer {
|
|
|
9719
11102
|
return pathModuleValue(this, `path/${bi.member}`, loc);
|
|
9720
11103
|
}
|
|
9721
11104
|
// events.defaultMaxListeners READS the process-wide default (its
|
|
9722
|
-
// 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.
|
|
9723
11107
|
if (bi.module === "events" && bi.member === "defaultMaxListeners") {
|
|
9724
|
-
|
|
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
|
+
};
|
|
9725
11117
|
}
|
|
9726
11118
|
if (bi.module === "worker_threads") {
|
|
9727
11119
|
const value = lowerWorkerMetadata(bi.member, loc);
|
|
@@ -9739,6 +11131,15 @@ export class Lowerer {
|
|
|
9739
11131
|
if (bi.module === "http" && bi.member === "METHODS") {
|
|
9740
11132
|
return { kind: "libCall", fn: "http.methods", args: [], type: arrayOf(STRING), loc };
|
|
9741
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
|
+
}
|
|
9742
11143
|
if (bi.module === "http" && bi.member === "STATUS_CODES") {
|
|
9743
11144
|
return { kind: "libCall", fn: "http.statusCodes", args: [], type: DYN, loc };
|
|
9744
11145
|
}
|
|
@@ -9760,12 +11161,24 @@ export class Lowerer {
|
|
|
9760
11161
|
if (callable)
|
|
9761
11162
|
return callable;
|
|
9762
11163
|
}
|
|
9763
|
-
|
|
9764
|
-
|
|
9765
|
-
|
|
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);
|
|
9766
11179
|
}
|
|
9767
11180
|
if (builtinModuleFnOf(this, bi.module, bi.member)) {
|
|
9768
|
-
this.unsupported("SC1090", expr, `library functions as values (call '${
|
|
11181
|
+
this.unsupported("SC1090", expr, `library functions as values (call '${ts.getTextOfNode(expr)}' directly)`);
|
|
9769
11182
|
}
|
|
9770
11183
|
this.noLowering(`${bi.module}.${bi.member}`, expr, builtinFenceHintOf(bi.module, bi.member), this.checker.getSymbolAtLocation(expr.name));
|
|
9771
11184
|
}
|
|
@@ -9812,11 +11225,12 @@ export class Lowerer {
|
|
|
9812
11225
|
const adapterShape = valueParams
|
|
9813
11226
|
.map((param) => param.mode === "optional" ? `${param.mode}:${param.defaultValue}` : param.mode)
|
|
9814
11227
|
.join(",");
|
|
9815
|
-
const key = `${fn.fn}:${typeKey(funcType)}:${adapterShape}`;
|
|
11228
|
+
const key = `${fn.valueFn ?? fn.fn}:${typeKey(funcType)}:${adapterShape}`;
|
|
9816
11229
|
let fnName = this.builtinCallableValueFns.get(key);
|
|
9817
11230
|
if (!fnName) {
|
|
9818
|
-
fnName = `%builtin.value.${fn.fn}.${this.builtinCallableValueFns.size}`;
|
|
11231
|
+
fnName = `%builtin.value.${fn.valueFn ?? fn.fn}.${this.builtinCallableValueFns.size}`;
|
|
9819
11232
|
this.builtinCallableValueFns.set(key, fnName);
|
|
11233
|
+
this.builtinCallableValueNames.set(fnName, display.slice(display.lastIndexOf(".") + 1));
|
|
9820
11234
|
const params = funcType.params.map((type, index) => ({
|
|
9821
11235
|
localId: `arg.${index}`,
|
|
9822
11236
|
name: `arg${index}`,
|
|
@@ -9874,7 +11288,7 @@ export class Lowerer {
|
|
|
9874
11288
|
loc,
|
|
9875
11289
|
};
|
|
9876
11290
|
});
|
|
9877
|
-
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 };
|
|
9878
11292
|
const body = fn.result.kind === "void"
|
|
9879
11293
|
? [
|
|
9880
11294
|
{ kind: "exprStmt", expr: call, loc },
|
|
@@ -9919,8 +11333,8 @@ export class Lowerer {
|
|
|
9919
11333
|
lowerSpawnCall(expr, loc) {
|
|
9920
11334
|
return lowerSpawnCall(this, expr, loc);
|
|
9921
11335
|
}
|
|
9922
|
-
lowerExecFileCall(expr, loc) {
|
|
9923
|
-
return lowerExecFileCall(this, expr, loc);
|
|
11336
|
+
lowerExecFileCall(expr, loc, shell = false) {
|
|
11337
|
+
return lowerExecFileCall(this, expr, loc, shell);
|
|
9924
11338
|
}
|
|
9925
11339
|
lowerExecSyncCall(expr, shell, loc) {
|
|
9926
11340
|
return lowerExecSyncCall(this, expr, shell, loc);
|
|
@@ -10118,4 +11532,195 @@ export class Lowerer {
|
|
|
10118
11532
|
return lowerStdlibMethodCall(this, call, access);
|
|
10119
11533
|
}
|
|
10120
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
|
+
}
|
|
10121
11726
|
//# sourceMappingURL=lowerer.js.map
|