@scriptc/compiler 0.3.6 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ambient/scriptc-node-fallback.d.ts +717 -55
- package/ambient/scriptc.d.ts +134 -0
- package/dist/backend/cycle-analysis.d.ts +1 -1
- package/dist/backend/cycle-analysis.js +1 -0
- package/dist/backend/cycle-analysis.js.map +1 -1
- package/dist/backend/cycle-analysis.test.js +13 -1
- package/dist/backend/cycle-analysis.test.js.map +1 -1
- package/dist/backend/cycle-mutability.js +16 -5
- package/dist/backend/cycle-mutability.js.map +1 -1
- package/dist/backend/executable-features.js +20 -0
- package/dist/backend/executable-features.js.map +1 -1
- package/dist/backend/immutability.test.js +1 -1
- package/dist/backend/library-pack.js +9 -0
- package/dist/backend/library-pack.js.map +1 -1
- package/dist/backend/link-plan-core.d.ts +2 -0
- package/dist/backend/link-plan-core.js +2 -0
- package/dist/backend/link-plan-core.js.map +1 -1
- package/dist/backend/link-plan.d.ts +1 -0
- package/dist/backend/link-plan.js +1 -0
- package/dist/backend/link-plan.js.map +1 -1
- package/dist/backend/llvm/alloc.d.ts +41 -4
- package/dist/backend/llvm/alloc.js +138 -7
- package/dist/backend/llvm/alloc.js.map +1 -1
- package/dist/backend/llvm/alloc.test.js +30 -1
- package/dist/backend/llvm/alloc.test.js.map +1 -1
- package/dist/backend/llvm/appended-array-literals.test.js +1 -1
- package/dist/backend/llvm/array-search.js +3 -1
- package/dist/backend/llvm/array-search.js.map +1 -1
- package/dist/backend/llvm/array-search.test.js +1 -1
- package/dist/backend/llvm/blocks.d.ts +8 -0
- package/dist/backend/llvm/blocks.js +43 -1
- package/dist/backend/llvm/blocks.js.map +1 -1
- package/dist/backend/llvm/blocks.test.js +22 -1
- package/dist/backend/llvm/blocks.test.js.map +1 -1
- package/dist/backend/llvm/byte-numbers.js +15 -5
- package/dist/backend/llvm/byte-numbers.js.map +1 -1
- package/dist/backend/llvm/bytes-alias.d.ts +14 -0
- package/dist/backend/llvm/bytes-alias.js +20 -0
- package/dist/backend/llvm/bytes-alias.js.map +1 -0
- package/dist/backend/llvm/bytes-loop-versions.d.ts +86 -0
- package/dist/backend/llvm/bytes-loop-versions.js +506 -0
- package/dist/backend/llvm/bytes-loop-versions.js.map +1 -0
- package/dist/backend/llvm/bytes-loop-versions.test.d.ts +1 -0
- package/dist/backend/llvm/bytes-loop-versions.test.js +244 -0
- package/dist/backend/llvm/bytes-loop-versions.test.js.map +1 -0
- package/dist/backend/llvm/call-lifetimes.js +50 -1
- package/dist/backend/llvm/call-lifetimes.js.map +1 -1
- package/dist/backend/llvm/call-lifetimes.test.js +34 -0
- package/dist/backend/llvm/call-lifetimes.test.js.map +1 -1
- package/dist/backend/llvm/checked-narrows.test.js +1 -1
- package/dist/backend/llvm/checked-value-lifetimes.js +4 -1
- package/dist/backend/llvm/checked-value-lifetimes.js.map +1 -1
- package/dist/backend/llvm/classes.d.ts +38 -1
- package/dist/backend/llvm/classes.js +185 -35
- package/dist/backend/llvm/classes.js.map +1 -1
- package/dist/backend/llvm/classes.test.js +79 -17
- package/dist/backend/llvm/classes.test.js.map +1 -1
- package/dist/backend/llvm/common.d.ts +21 -3
- package/dist/backend/llvm/common.js +51 -3
- package/dist/backend/llvm/common.js.map +1 -1
- package/dist/backend/llvm/constant-callbacks.d.ts +5 -1
- package/dist/backend/llvm/constant-callbacks.js +55 -12
- package/dist/backend/llvm/constant-callbacks.js.map +1 -1
- package/dist/backend/llvm/constant-callbacks.test.js +88 -1
- package/dist/backend/llvm/constant-callbacks.test.js.map +1 -1
- package/dist/backend/llvm/counted-loops.d.ts +4 -0
- package/dist/backend/llvm/counted-loops.js +37 -0
- package/dist/backend/llvm/counted-loops.js.map +1 -1
- package/dist/backend/llvm/dense-array-access.d.ts +15 -4
- package/dist/backend/llvm/dense-array-access.js +125 -44
- package/dist/backend/llvm/dense-array-access.js.map +1 -1
- package/dist/backend/llvm/dense-array-access.test.js +63 -3
- package/dist/backend/llvm/dense-array-access.test.js.map +1 -1
- package/dist/backend/llvm/dense-array-loops.d.ts +51 -0
- package/dist/backend/llvm/dense-array-loops.js +162 -0
- package/dist/backend/llvm/dense-array-loops.js.map +1 -0
- package/dist/backend/llvm/dense-array-loops.test.d.ts +1 -0
- package/dist/backend/llvm/dense-array-loops.test.js +128 -0
- package/dist/backend/llvm/dense-array-loops.test.js.map +1 -0
- package/dist/backend/llvm/dyn-handle-tags.test.d.ts +1 -0
- package/dist/backend/llvm/dyn-handle-tags.test.js +38 -0
- package/dist/backend/llvm/dyn-handle-tags.test.js.map +1 -0
- package/dist/backend/llvm/dyn.d.ts +37 -4
- package/dist/backend/llvm/dyn.js +354 -183
- package/dist/backend/llvm/dyn.js.map +1 -1
- package/dist/backend/llvm/emit-function.d.ts +64 -0
- package/dist/backend/llvm/emit-function.js +1193 -0
- package/dist/backend/llvm/emit-function.js.map +1 -0
- package/dist/backend/llvm/emit-module.d.ts +24 -0
- package/dist/backend/llvm/emit-module.js +1557 -0
- package/dist/backend/llvm/emit-module.js.map +1 -0
- package/dist/backend/llvm/emit-statements.d.ts +59 -0
- package/dist/backend/llvm/emit-statements.js +2041 -0
- package/dist/backend/llvm/emit-statements.js.map +1 -0
- package/dist/backend/llvm/emitter.d.ts +566 -291
- package/dist/backend/llvm/emitter.js +728 -4671
- package/dist/backend/llvm/emitter.js.map +1 -1
- package/dist/backend/llvm/emitter.test.js +57 -3
- package/dist/backend/llvm/emitter.test.js.map +1 -1
- package/dist/backend/llvm/expr-async.js +73 -46
- package/dist/backend/llvm/expr-async.js.map +1 -1
- package/dist/backend/llvm/expr-async.test.js +1 -1
- package/dist/backend/llvm/expr-bytes.d.ts +2 -0
- package/dist/backend/llvm/expr-bytes.js +76 -29
- package/dist/backend/llvm/expr-bytes.js.map +1 -1
- package/dist/backend/llvm/expr-callbacks.d.ts +6 -2
- package/dist/backend/llvm/expr-callbacks.js +48 -11
- package/dist/backend/llvm/expr-callbacks.js.map +1 -1
- package/dist/backend/llvm/expr-calls.d.ts +1 -1
- package/dist/backend/llvm/expr-calls.js +87 -56
- package/dist/backend/llvm/expr-calls.js.map +1 -1
- package/dist/backend/llvm/expr-calls.test.js +1 -1
- package/dist/backend/llvm/expr-containers.js +45 -24
- package/dist/backend/llvm/expr-containers.js.map +1 -1
- package/dist/backend/llvm/expr-control.js +16 -16
- package/dist/backend/llvm/expr-control.js.map +1 -1
- package/dist/backend/llvm/expr-dynamic.d.ts +3 -0
- package/dist/backend/llvm/expr-dynamic.js +113 -66
- package/dist/backend/llvm/expr-dynamic.js.map +1 -1
- package/dist/backend/llvm/expr-primitives.js +124 -28
- package/dist/backend/llvm/expr-primitives.js.map +1 -1
- package/dist/backend/llvm/expr-primitives.test.js +57 -2
- package/dist/backend/llvm/expr-primitives.test.js.map +1 -1
- package/dist/backend/llvm/expr-records.d.ts +1 -1
- package/dist/backend/llvm/expr-records.js +32 -11
- package/dist/backend/llvm/expr-records.js.map +1 -1
- package/dist/backend/llvm/expr-stream-bridges.js +65 -27
- package/dist/backend/llvm/expr-stream-bridges.js.map +1 -1
- package/dist/backend/llvm/expr-stream-bridges.test.js +2 -2
- package/dist/backend/llvm/expr-stream-callbacks.js +22 -1
- package/dist/backend/llvm/expr-stream-callbacks.js.map +1 -1
- package/dist/backend/llvm/int32-abi.test.js +2 -2
- package/dist/backend/llvm/integer-clones.js +3 -3
- package/dist/backend/llvm/integer-clones.js.map +1 -1
- package/dist/backend/llvm/integer-clones.test.js +3 -3
- package/dist/backend/llvm/integer-remainder.d.ts +34 -13
- package/dist/backend/llvm/integer-remainder.js +156 -22
- package/dist/backend/llvm/integer-remainder.js.map +1 -1
- package/dist/backend/llvm/intern-tables.test.js +1 -1
- package/dist/backend/llvm/js-ic.d.ts +18 -0
- package/dist/backend/llvm/js-ic.js +712 -0
- package/dist/backend/llvm/js-ic.js.map +1 -0
- package/dist/backend/llvm/jsval-encoding.d.ts +21 -0
- package/dist/backend/llvm/jsval-encoding.js +20 -0
- package/dist/backend/llvm/jsval-encoding.js.map +1 -0
- package/dist/backend/llvm/jsval.d.ts +12 -0
- package/dist/backend/llvm/jsval.js +616 -0
- package/dist/backend/llvm/jsval.js.map +1 -0
- package/dist/backend/llvm/lazy-captures.d.ts +12 -2
- package/dist/backend/llvm/lazy-captures.js +39 -17
- package/dist/backend/llvm/lazy-captures.js.map +1 -1
- package/dist/backend/llvm/lib-abi.js +1 -1
- package/dist/backend/llvm/lib-abi.js.map +1 -1
- package/dist/backend/llvm/lib-connect.js +1 -1
- package/dist/backend/llvm/lib-connect.js.map +1 -1
- package/dist/backend/llvm/lib-datagram.js +14 -8
- package/dist/backend/llvm/lib-datagram.js.map +1 -1
- package/dist/backend/llvm/lib-dispatch.js +189 -23
- package/dist/backend/llvm/lib-dispatch.js.map +1 -1
- package/dist/backend/llvm/lib-filesystem.js +42 -13
- package/dist/backend/llvm/lib-filesystem.js.map +1 -1
- package/dist/backend/llvm/lib-http2.js +3 -3
- package/dist/backend/llvm/lib-http2.js.map +1 -1
- package/dist/backend/llvm/lib-lookup.js +2 -2
- package/dist/backend/llvm/lib-lookup.js.map +1 -1
- package/dist/backend/llvm/lib-network.js +56 -22
- package/dist/backend/llvm/lib-network.js.map +1 -1
- package/dist/backend/llvm/lib-process.js +94 -53
- package/dist/backend/llvm/lib-process.js.map +1 -1
- package/dist/backend/llvm/lib-shared.d.ts +12 -0
- package/dist/backend/llvm/lib-shared.js +209 -6
- package/dist/backend/llvm/lib-shared.js.map +1 -1
- package/dist/backend/llvm/lib-stream.js +46 -16
- package/dist/backend/llvm/lib-stream.js.map +1 -1
- package/dist/backend/llvm/lib-test.js +43 -7
- package/dist/backend/llvm/lib-test.js.map +1 -1
- package/dist/backend/llvm/lib-tls.js +4 -9
- package/dist/backend/llvm/lib-tls.js.map +1 -1
- package/dist/backend/llvm/local-array-reads.js +42 -33
- package/dist/backend/llvm/local-array-reads.js.map +1 -1
- package/dist/backend/llvm/local-array-reads.test.js +1 -1
- package/dist/backend/llvm/local-extents.d.ts +19 -0
- package/dist/backend/llvm/local-extents.js +169 -0
- package/dist/backend/llvm/local-extents.js.map +1 -0
- package/dist/backend/llvm/local-extents.test.d.ts +1 -0
- package/dist/backend/llvm/local-extents.test.js +92 -0
- package/dist/backend/llvm/local-extents.test.js.map +1 -0
- package/dist/backend/llvm/local-union-storage.js +7 -7
- package/dist/backend/llvm/local-union-storage.js.map +1 -1
- package/dist/backend/llvm/local-union-storage.test.js +2 -2
- package/dist/backend/llvm/map-entry-fusion.test.js +1 -1
- package/dist/backend/llvm/map-number-lookup.d.ts +20 -4
- package/dist/backend/llvm/map-number-lookup.js +45 -9
- package/dist/backend/llvm/map-number-lookup.js.map +1 -1
- package/dist/backend/llvm/map-number-lookup.test.js +2 -2
- package/dist/backend/llvm/map-read-lifetimes.test.js +2 -2
- package/dist/backend/llvm/narrow-guards.d.ts +38 -0
- package/dist/backend/llvm/narrow-guards.js +215 -0
- package/dist/backend/llvm/narrow-guards.js.map +1 -0
- package/dist/backend/llvm/nullable-unions.d.ts +64 -6
- package/dist/backend/llvm/nullable-unions.js +103 -6
- package/dist/backend/llvm/nullable-unions.js.map +1 -1
- package/dist/backend/llvm/nullable-unions.test.d.ts +1 -0
- package/dist/backend/llvm/nullable-unions.test.js +65 -0
- package/dist/backend/llvm/nullable-unions.test.js.map +1 -0
- package/dist/backend/llvm/publish.d.ts +7 -0
- package/dist/backend/llvm/publish.js +50 -19
- package/dist/backend/llvm/publish.js.map +1 -1
- package/dist/backend/llvm/publish.test.js +1 -1
- package/dist/backend/llvm/receivers.d.ts +31 -0
- package/dist/backend/llvm/receivers.js +395 -0
- package/dist/backend/llvm/receivers.js.map +1 -0
- package/dist/backend/llvm/record-results.d.ts +12 -1
- package/dist/backend/llvm/record-results.js +64 -4
- package/dist/backend/llvm/record-results.js.map +1 -1
- package/dist/backend/llvm/reference-effects.js +9 -0
- package/dist/backend/llvm/reference-effects.js.map +1 -1
- package/dist/backend/llvm/reference-writes.d.ts +4 -0
- package/dist/backend/llvm/reference-writes.js +142 -6
- package/dist/backend/llvm/reference-writes.js.map +1 -1
- package/dist/backend/llvm/reference-writes.test.d.ts +1 -0
- package/dist/backend/llvm/reference-writes.test.js +88 -0
- package/dist/backend/llvm/reference-writes.test.js.map +1 -0
- package/dist/backend/llvm/regex-matchers.d.ts +8 -0
- package/dist/backend/llvm/regex-matchers.js +33 -0
- package/dist/backend/llvm/regex-matchers.js.map +1 -1
- package/dist/backend/llvm/regex-matchers.test.js +23 -1
- package/dist/backend/llvm/regex-matchers.test.js.map +1 -1
- package/dist/backend/llvm/regions.d.ts +1 -1
- package/dist/backend/llvm/regions.js +10 -7
- package/dist/backend/llvm/regions.js.map +1 -1
- package/dist/backend/llvm/regions.test.js +8 -2
- package/dist/backend/llvm/regions.test.js.map +1 -1
- package/dist/backend/llvm/shapes.d.ts +74 -45
- package/dist/backend/llvm/shapes.js +289 -28
- package/dist/backend/llvm/shapes.js.map +1 -1
- package/dist/backend/llvm/shapes.test.js +37 -3
- package/dist/backend/llvm/shapes.test.js.map +1 -1
- package/dist/backend/llvm/speculative-integers.d.ts +20 -1
- package/dist/backend/llvm/speculative-integers.js +94 -6
- package/dist/backend/llvm/speculative-integers.js.map +1 -1
- package/dist/backend/llvm/speculative-integers.test.js +55 -1
- package/dist/backend/llvm/speculative-integers.test.js.map +1 -1
- package/dist/backend/llvm/split-loops.js +2 -2
- package/dist/backend/llvm/split-loops.js.map +1 -1
- package/dist/backend/llvm/stack-objects.d.ts +26 -6
- package/dist/backend/llvm/stack-objects.js +133 -10
- package/dist/backend/llvm/stack-objects.js.map +1 -1
- package/dist/backend/llvm/stack-objects.test.js +55 -1
- package/dist/backend/llvm/stack-objects.test.js.map +1 -1
- package/dist/backend/llvm/stack-unions.test.js +1 -1
- package/dist/backend/llvm/string-construction.test.js +1 -1
- package/dist/backend/llvm/string-lifetimes.test.js +15 -14
- package/dist/backend/llvm/string-lifetimes.test.js.map +1 -1
- package/dist/backend/llvm/string-reads.d.ts +1 -1
- package/dist/backend/llvm/string-reads.js +4 -4
- package/dist/backend/llvm/string-reads.js.map +1 -1
- package/dist/backend/llvm/string-slices.d.ts +25 -0
- package/dist/backend/llvm/string-slices.js +207 -1
- package/dist/backend/llvm/string-slices.js.map +1 -1
- package/dist/backend/llvm/string-slices.test.js +139 -2
- package/dist/backend/llvm/string-slices.test.js.map +1 -1
- package/dist/backend/llvm/switch-dispatch.test.js +2 -2
- package/dist/backend/llvm/thread-slots.d.ts +5 -0
- package/dist/backend/llvm/thread-slots.js +142 -0
- package/dist/backend/llvm/thread-slots.js.map +1 -0
- package/dist/backend/llvm/thread-slots.test.d.ts +1 -0
- package/dist/backend/llvm/thread-slots.test.js +111 -0
- package/dist/backend/llvm/thread-slots.test.js.map +1 -0
- package/dist/backend/llvm/union-repr.d.ts +7 -7
- package/dist/backend/llvm/union-repr.js +18 -2
- package/dist/backend/llvm/union-repr.js.map +1 -1
- package/dist/backend/llvm/union-retype.test.js +17 -3
- package/dist/backend/llvm/union-retype.test.js.map +1 -1
- package/dist/backend/llvm/walkers.d.ts +2 -2
- package/dist/backend/llvm/walkers.js +51 -26
- package/dist/backend/llvm/walkers.js.map +1 -1
- package/dist/backend/llvm/wasm-modules.d.ts +16 -0
- package/dist/backend/llvm/wasm-modules.js +66 -0
- package/dist/backend/llvm/wasm-modules.js.map +1 -0
- package/dist/backend/llvm/wrapping-sums.d.ts +7 -0
- package/dist/backend/llvm/wrapping-sums.js +11 -3
- package/dist/backend/llvm/wrapping-sums.js.map +1 -1
- package/dist/backend/mangle.d.ts +12 -0
- package/dist/backend/mangle.js +18 -0
- package/dist/backend/mangle.js.map +1 -1
- package/dist/backend/may-throw.d.ts +3 -0
- package/dist/backend/may-throw.js +4 -2
- package/dist/backend/may-throw.js.map +1 -1
- package/dist/backend/may-throw.test.js +1 -1
- package/dist/backend/native/contracts.d.ts +57 -0
- package/dist/backend/native/executable.js +211 -139
- package/dist/backend/native/executable.js.map +1 -1
- package/dist/backend/native/library.js +2 -0
- package/dist/backend/native/library.js.map +1 -1
- package/dist/backend/native/runtime-inputs.d.ts +1 -1
- package/dist/backend/native/runtime-inputs.js +1 -0
- package/dist/backend/native/runtime-inputs.js.map +1 -1
- package/dist/backend/native-codegen.d.ts +6 -0
- package/dist/backend/native-codegen.js +19 -0
- package/dist/backend/native-codegen.js.map +1 -1
- package/dist/backend/native-codegen.test.js +27 -0
- package/dist/backend/native-codegen.test.js.map +1 -1
- package/dist/backend/native-link-info-core.d.ts +48 -0
- package/dist/backend/native-link-info-core.js.map +1 -1
- package/dist/backend/native-profile.d.ts +32 -0
- package/dist/backend/native-profile.js +39 -0
- package/dist/backend/native-profile.js.map +1 -0
- package/dist/backend/native-profile.test.d.ts +1 -0
- package/dist/backend/native-profile.test.js +58 -0
- package/dist/backend/native-profile.test.js.map +1 -0
- package/dist/backend/native-tools.d.ts +14 -0
- package/dist/backend/native-tools.js +13 -0
- package/dist/backend/native-tools.js.map +1 -1
- package/dist/backend/publication.test.js +1 -1
- package/dist/backend/runtime-abi.d.ts +2 -2
- package/dist/backend/runtime-abi.js +2 -2
- package/dist/backend/runtime-pack-core.d.ts +13 -1
- package/dist/backend/runtime-pack-core.js +14 -1
- package/dist/backend/runtime-pack-core.js.map +1 -1
- package/dist/backend/runtime-pack-native.js +1 -1
- package/dist/backend/runtime-pack-native.js.map +1 -1
- package/dist/backend/runtime-pack-native.test.d.ts +1 -0
- package/dist/backend/runtime-pack-native.test.js +31 -0
- package/dist/backend/runtime-pack-native.test.js.map +1 -0
- package/dist/backend/runtime-pack-targets.test.js +9 -1
- package/dist/backend/runtime-pack-targets.test.js.map +1 -1
- package/dist/backend/runtime-pack.test.js +9 -1
- package/dist/backend/runtime-pack.test.js.map +1 -1
- package/dist/backend/stack-observations.d.ts +22 -0
- package/dist/backend/stack-observations.js +382 -0
- package/dist/backend/stack-observations.js.map +1 -0
- package/dist/backend/stack-observations.test.d.ts +1 -0
- package/dist/backend/stack-observations.test.js +233 -0
- package/dist/backend/stack-observations.test.js.map +1 -0
- package/dist/backend/target-diagnostics.js +15 -0
- package/dist/backend/target-diagnostics.js.map +1 -1
- package/dist/backend/target-diagnostics.test.js +1 -1
- package/dist/backend/warm-cache.js +8 -0
- package/dist/backend/warm-cache.js.map +1 -1
- package/dist/backend/young-nursery.d.ts +7 -0
- package/dist/backend/young-nursery.js +10 -0
- package/dist/backend/young-nursery.js.map +1 -0
- package/dist/cli/command.js +106 -4
- package/dist/cli/command.js.map +1 -1
- package/dist/cli/host.d.ts +3 -0
- package/dist/cli/output-options.d.ts +2 -0
- package/dist/cli/output-options.js +9 -0
- package/dist/cli/output-options.js.map +1 -1
- package/dist/cli/usage.d.ts +21 -1
- package/dist/cli/usage.js +43 -1
- package/dist/cli/usage.js.map +1 -1
- package/dist/compat/fetch-profile.js +10 -1
- package/dist/compat/fetch-profile.js.map +1 -1
- package/dist/compile-types.d.ts +22 -0
- package/dist/contracts/check.js +25 -8
- package/dist/contracts/check.js.map +1 -1
- package/dist/contracts/int32-elements.d.ts +115 -0
- package/dist/contracts/int32-elements.js +1179 -0
- package/dist/contracts/int32-elements.js.map +1 -0
- package/dist/coverage/report.d.ts +16 -0
- package/dist/coverage/report.js +182 -1
- package/dist/coverage/report.js.map +1 -1
- package/dist/coverage/surface-manifest.js +16 -3
- package/dist/coverage/surface-manifest.js.map +1 -1
- package/dist/coverage/verdict-cache.d.ts +2 -0
- package/dist/coverage/verdict-cache.js +12 -0
- package/dist/coverage/verdict-cache.js.map +1 -1
- package/dist/coverage/verdict-cache.test.js +2 -1
- package/dist/coverage/verdict-cache.test.js.map +1 -1
- package/dist/diagnostics/diagnostic.d.ts +10 -6
- package/dist/diagnostics/diagnostic.js +29 -21
- package/dist/diagnostics/diagnostic.js.map +1 -1
- package/dist/diagnostics/envelope.d.ts +39 -2
- package/dist/diagnostics/envelope.js.map +1 -1
- package/dist/diagnostics/render.d.ts +7 -0
- package/dist/diagnostics/render.js +50 -13
- package/dist/diagnostics/render.js.map +1 -1
- package/dist/diagnostics/render.test.d.ts +1 -0
- package/dist/diagnostics/render.test.js +49 -0
- package/dist/diagnostics/render.test.js.map +1 -0
- package/dist/executable/executable-cache.d.ts +27 -0
- package/dist/executable/executable-cache.js +19 -1
- package/dist/executable/executable-cache.js.map +1 -1
- package/dist/executable/executable-cache.test.js +12 -1
- package/dist/executable/executable-cache.test.js.map +1 -1
- package/dist/executable/prepare.js +2 -1
- package/dist/executable/prepare.js.map +1 -1
- package/dist/frontend/analysis.js +6 -1
- package/dist/frontend/analysis.js.map +1 -1
- package/dist/frontend/arguments-usage.d.ts +8 -0
- package/dist/frontend/arguments-usage.js +98 -0
- package/dist/frontend/arguments-usage.js.map +1 -1
- package/dist/frontend/arguments-usage.test.d.ts +1 -0
- package/dist/frontend/arguments-usage.test.js +32 -0
- package/dist/frontend/arguments-usage.test.js.map +1 -0
- package/dist/frontend/builtin-modules.d.ts +16 -2
- package/dist/frontend/builtin-modules.js +40 -7
- package/dist/frontend/builtin-modules.js.map +1 -1
- package/dist/frontend/builtin-package-aliases.d.ts +24 -0
- package/dist/frontend/builtin-package-aliases.js +133 -0
- package/dist/frontend/builtin-package-aliases.js.map +1 -0
- package/dist/frontend/builtin-package-aliases.test.d.ts +1 -0
- package/dist/frontend/builtin-package-aliases.test.js +48 -0
- package/dist/frontend/builtin-package-aliases.test.js.map +1 -0
- package/dist/frontend/cjs-syntax.js +52 -51
- package/dist/frontend/cjs-syntax.js.map +1 -1
- package/dist/frontend/contract-types.d.ts +3 -0
- package/dist/frontend/contract-types.js +36 -7
- package/dist/frontend/contract-types.js.map +1 -1
- package/dist/frontend/dts-paths.d.ts +4 -0
- package/dist/frontend/dts-paths.js +9 -1
- package/dist/frontend/dts-paths.js.map +1 -1
- package/dist/frontend/experimental-import.d.ts +5 -1
- package/dist/frontend/experimental-import.js +26 -7
- package/dist/frontend/experimental-import.js.map +1 -1
- package/dist/frontend/fork-target.js +20 -22
- package/dist/frontend/fork-target.js.map +1 -1
- package/dist/frontend/fork-target.test.js +2 -1
- package/dist/frontend/fork-target.test.js.map +1 -1
- package/dist/frontend/function-completion.js +6 -6
- package/dist/frontend/function-completion.js.map +1 -1
- package/dist/frontend/helper-tokens.js +15 -3
- package/dist/frontend/helper-tokens.js.map +1 -1
- package/dist/frontend/helper-tokens.test.js +7 -1
- package/dist/frontend/helper-tokens.test.js.map +1 -1
- package/dist/frontend/inferred-js-diagnostics.js +14 -17
- package/dist/frontend/inferred-js-diagnostics.js.map +1 -1
- package/dist/frontend/input-tracker.d.ts +3 -0
- package/dist/frontend/input-tracker.js +32 -3
- package/dist/frontend/input-tracker.js.map +1 -1
- package/dist/frontend/lib-contract.js +36 -32
- package/dist/frontend/lib-contract.js.map +1 -1
- package/dist/frontend/lib-exports.js +3 -3
- package/dist/frontend/lib-exports.js.map +1 -1
- package/dist/frontend/lowering/array-values.d.ts +8 -3
- package/dist/frontend/lowering/array-values.js +60 -11
- package/dist/frontend/lowering/array-values.js.map +1 -1
- package/dist/frontend/lowering/assert-instances.js +4 -4
- package/dist/frontend/lowering/assert-instances.js.map +1 -1
- package/dist/frontend/lowering/assertion-identity.d.ts +12 -0
- package/dist/frontend/lowering/assertion-identity.js +70 -0
- package/dist/frontend/lowering/assertion-identity.js.map +1 -0
- package/dist/frontend/lowering/assertion-members.d.ts +28 -0
- package/dist/frontend/lowering/assertion-members.js +185 -0
- package/dist/frontend/lowering/assertion-members.js.map +1 -0
- package/dist/frontend/lowering/binding-analysis.js +27 -20
- package/dist/frontend/lowering/binding-analysis.js.map +1 -1
- package/dist/frontend/lowering/builtin-calls.js +63 -5
- package/dist/frontend/lowering/builtin-calls.js.map +1 -1
- package/dist/frontend/lowering/builtin-function-fences.d.ts +14 -0
- package/dist/frontend/lowering/builtin-function-fences.js +42 -0
- package/dist/frontend/lowering/builtin-function-fences.js.map +1 -0
- package/dist/frontend/lowering/builtins/arguments.js +1 -1
- package/dist/frontend/lowering/builtins/arguments.js.map +1 -1
- package/dist/frontend/lowering/builtins/async-context.js +53 -52
- package/dist/frontend/lowering/builtins/async-context.js.map +1 -1
- package/dist/frontend/lowering/builtins/atomics.js +6 -6
- package/dist/frontend/lowering/builtins/atomics.js.map +1 -1
- package/dist/frontend/lowering/builtins/blob.js +8 -6
- package/dist/frontend/lowering/builtins/blob.js.map +1 -1
- package/dist/frontend/lowering/builtins/builtin-class-dyn.d.ts +31 -0
- package/dist/frontend/lowering/builtins/builtin-class-dyn.js +205 -0
- package/dist/frontend/lowering/builtins/builtin-class-dyn.js.map +1 -0
- package/dist/frontend/lowering/builtins/callable-aliases.js +17 -5
- package/dist/frontend/lowering/builtins/callable-aliases.js.map +1 -1
- package/dist/frontend/lowering/builtins/child-process-async.js +7 -7
- package/dist/frontend/lowering/builtins/child-process-async.js.map +1 -1
- package/dist/frontend/lowering/builtins/child-process-methods.d.ts +6 -4
- package/dist/frontend/lowering/builtins/child-process-methods.js +310 -57
- package/dist/frontend/lowering/builtins/child-process-methods.js.map +1 -1
- package/dist/frontend/lowering/builtins/child-process-sync.js +16 -10
- package/dist/frontend/lowering/builtins/child-process-sync.js.map +1 -1
- package/dist/frontend/lowering/builtins/child-process.d.ts +6 -4
- package/dist/frontend/lowering/builtins/child-process.js +85 -61
- package/dist/frontend/lowering/builtins/child-process.js.map +1 -1
- package/dist/frontend/lowering/builtins/class-values.d.ts +60 -0
- package/dist/frontend/lowering/builtins/class-values.js +226 -0
- package/dist/frontend/lowering/builtins/class-values.js.map +1 -0
- package/dist/frontend/lowering/builtins/compression.d.ts +9 -0
- package/dist/frontend/lowering/builtins/compression.js +107 -44
- package/dist/frontend/lowering/builtins/compression.js.map +1 -1
- package/dist/frontend/lowering/builtins/constants.d.ts +9 -1
- package/dist/frontend/lowering/builtins/constants.js +28 -7
- package/dist/frontend/lowering/builtins/constants.js.map +1 -1
- package/dist/frontend/lowering/builtins/crypto.d.ts +22 -0
- package/dist/frontend/lowering/builtins/crypto.js +215 -38
- package/dist/frontend/lowering/builtins/crypto.js.map +1 -1
- package/dist/frontend/lowering/builtins/dates.d.ts +7 -1
- package/dist/frontend/lowering/builtins/dates.js +92 -16
- package/dist/frontend/lowering/builtins/dates.js.map +1 -1
- package/dist/frontend/lowering/builtins/disposable-stack.d.ts +18 -0
- package/dist/frontend/lowering/builtins/disposable-stack.js +137 -0
- package/dist/frontend/lowering/builtins/disposable-stack.js.map +1 -0
- package/dist/frontend/lowering/builtins/ecdh.d.ts +10 -0
- package/dist/frontend/lowering/builtins/ecdh.js +208 -0
- package/dist/frontend/lowering/builtins/ecdh.js.map +1 -0
- package/dist/frontend/lowering/builtins/environment.js +3 -3
- package/dist/frontend/lowering/builtins/environment.js.map +1 -1
- package/dist/frontend/lowering/builtins/errors.d.ts +14 -10
- package/dist/frontend/lowering/builtins/errors.js +169 -3
- package/dist/frontend/lowering/builtins/errors.js.map +1 -1
- package/dist/frontend/lowering/builtins/filesystem-calls.js +128 -116
- package/dist/frontend/lowering/builtins/filesystem-calls.js.map +1 -1
- package/dist/frontend/lowering/builtins/filesystem.js +77 -77
- package/dist/frontend/lowering/builtins/filesystem.js.map +1 -1
- package/dist/frontend/lowering/builtins/fs-glob.js +3 -3
- package/dist/frontend/lowering/builtins/fs-glob.js.map +1 -1
- package/dist/frontend/lowering/builtins/fs-streams.js +10 -11
- package/dist/frontend/lowering/builtins/fs-streams.js.map +1 -1
- package/dist/frontend/lowering/builtins/ipc.js +45 -8
- package/dist/frontend/lowering/builtins/ipc.js.map +1 -1
- package/dist/frontend/lowering/builtins/json.js +284 -24
- package/dist/frontend/lowering/builtins/json.js.map +1 -1
- package/dist/frontend/lowering/builtins/key-object.js +4 -4
- package/dist/frontend/lowering/builtins/key-object.js.map +1 -1
- package/dist/frontend/lowering/builtins/module-bindings.d.ts +8 -0
- package/dist/frontend/lowering/builtins/module-bindings.js +71 -22
- package/dist/frontend/lowering/builtins/module-bindings.js.map +1 -1
- package/dist/frontend/lowering/builtins/module-calls.js +55 -44
- package/dist/frontend/lowering/builtins/module-calls.js.map +1 -1
- package/dist/frontend/lowering/builtins/module-resolution.d.ts +4 -3
- package/dist/frontend/lowering/builtins/module-resolution.js +24 -23
- package/dist/frontend/lowering/builtins/module-resolution.js.map +1 -1
- package/dist/frontend/lowering/builtins/navigator.d.ts +13 -0
- package/dist/frontend/lowering/builtins/navigator.js +40 -0
- package/dist/frontend/lowering/builtins/navigator.js.map +1 -0
- package/dist/frontend/lowering/builtins/net-address.d.ts +19 -0
- package/dist/frontend/lowering/builtins/net-address.js +156 -0
- package/dist/frontend/lowering/builtins/net-address.js.map +1 -0
- package/dist/frontend/lowering/builtins/numbers.js +25 -9
- package/dist/frontend/lowering/builtins/numbers.js.map +1 -1
- package/dist/frontend/lowering/builtins/operating-system.d.ts +4 -0
- package/dist/frontend/lowering/builtins/operating-system.js +25 -12
- package/dist/frontend/lowering/builtins/operating-system.js.map +1 -1
- package/dist/frontend/lowering/builtins/performance.d.ts +12 -0
- package/dist/frontend/lowering/builtins/performance.js +259 -8
- package/dist/frontend/lowering/builtins/performance.js.map +1 -1
- package/dist/frontend/lowering/builtins/process.d.ts +41 -1
- package/dist/frontend/lowering/builtins/process.js +505 -99
- package/dist/frontend/lowering/builtins/process.js.map +1 -1
- package/dist/frontend/lowering/builtins/promises.d.ts +5 -1
- package/dist/frontend/lowering/builtins/promises.js +326 -43
- package/dist/frontend/lowering/builtins/promises.js.map +1 -1
- package/dist/frontend/lowering/builtins/promisify-callback.d.ts +40 -0
- package/dist/frontend/lowering/builtins/promisify-callback.js +338 -0
- package/dist/frontend/lowering/builtins/promisify-callback.js.map +1 -0
- package/dist/frontend/lowering/builtins/properties.js +37 -1
- package/dist/frontend/lowering/builtins/properties.js.map +1 -1
- package/dist/frontend/lowering/builtins/querystring.js +14 -14
- package/dist/frontend/lowering/builtins/querystring.js.map +1 -1
- package/dist/frontend/lowering/builtins/readline.d.ts +12 -2
- package/dist/frontend/lowering/builtins/readline.js +136 -39
- package/dist/frontend/lowering/builtins/readline.js.map +1 -1
- package/dist/frontend/lowering/builtins/receiver-types.js +3 -5
- package/dist/frontend/lowering/builtins/receiver-types.js.map +1 -1
- package/dist/frontend/lowering/builtins/reflection.js +42 -14
- package/dist/frontend/lowering/builtins/reflection.js.map +1 -1
- package/dist/frontend/lowering/builtins/runtime-constructor.d.ts +26 -0
- package/dist/frontend/lowering/builtins/runtime-constructor.js +165 -0
- package/dist/frontend/lowering/builtins/runtime-constructor.js.map +1 -0
- package/dist/frontend/lowering/builtins/strings.js +101 -12
- package/dist/frontend/lowering/builtins/strings.js.map +1 -1
- package/dist/frontend/lowering/builtins/text-codecs.js +41 -38
- package/dist/frontend/lowering/builtins/text-codecs.js.map +1 -1
- package/dist/frontend/lowering/builtins/timers.js +79 -30
- package/dist/frontend/lowering/builtins/timers.js.map +1 -1
- package/dist/frontend/lowering/builtins/typed-array-members.d.ts +7 -0
- package/dist/frontend/lowering/builtins/typed-array-members.js +160 -0
- package/dist/frontend/lowering/builtins/typed-array-members.js.map +1 -0
- package/dist/frontend/lowering/builtins/url.d.ts +3 -0
- package/dist/frontend/lowering/builtins/url.js +120 -17
- package/dist/frontend/lowering/builtins/url.js.map +1 -1
- package/dist/frontend/lowering/builtins/util-types.js +20 -4
- package/dist/frontend/lowering/builtins/util-types.js.map +1 -1
- package/dist/frontend/lowering/builtins/v8.d.ts +11 -0
- package/dist/frontend/lowering/builtins/v8.js +105 -0
- package/dist/frontend/lowering/builtins/v8.js.map +1 -0
- package/dist/frontend/lowering/builtins/webassembly.d.ts +33 -0
- package/dist/frontend/lowering/builtins/webassembly.js +388 -0
- package/dist/frontend/lowering/builtins/webassembly.js.map +1 -0
- package/dist/frontend/lowering/builtins/webcrypto.d.ts +20 -0
- package/dist/frontend/lowering/builtins/webcrypto.js +112 -0
- package/dist/frontend/lowering/builtins/webcrypto.js.map +1 -0
- package/dist/frontend/lowering/builtins/workers.d.ts +12 -0
- package/dist/frontend/lowering/builtins/workers.js +193 -8
- package/dist/frontend/lowering/builtins/workers.js.map +1 -1
- package/dist/frontend/lowering/call-arguments.js +69 -14
- package/dist/frontend/lowering/call-arguments.js.map +1 -1
- package/dist/frontend/lowering/call-signatures.d.ts +23 -1
- package/dist/frontend/lowering/call-signatures.js +379 -55
- package/dist/frontend/lowering/call-signatures.js.map +1 -1
- package/dist/frontend/lowering/checked-promise-all.d.ts +3 -0
- package/dist/frontend/lowering/checked-promise-all.js +1 -1
- package/dist/frontend/lowering/checked-promise-all.js.map +1 -1
- package/dist/frontend/lowering/cjs-exports-object.d.ts +53 -0
- package/dist/frontend/lowering/cjs-exports-object.js +561 -0
- package/dist/frontend/lowering/cjs-exports-object.js.map +1 -0
- package/dist/frontend/lowering/cjs-inline-require.d.ts +86 -0
- package/dist/frontend/lowering/cjs-inline-require.js +314 -0
- package/dist/frontend/lowering/cjs-inline-require.js.map +1 -0
- package/dist/frontend/lowering/cjs-tsc-interop.d.ts +28 -0
- package/dist/frontend/lowering/cjs-tsc-interop.js +208 -0
- package/dist/frontend/lowering/cjs-tsc-interop.js.map +1 -0
- package/dist/frontend/lowering/class-attributes.d.ts +19 -0
- package/dist/frontend/lowering/class-attributes.js +378 -0
- package/dist/frontend/lowering/class-attributes.js.map +1 -0
- package/dist/frontend/lowering/class-callbacks.d.ts +3 -1
- package/dist/frontend/lowering/class-callbacks.js +21 -10
- package/dist/frontend/lowering/class-callbacks.js.map +1 -1
- package/dist/frontend/lowering/class-construction.js +49 -4
- package/dist/frontend/lowering/class-construction.js.map +1 -1
- package/dist/frontend/lowering/class-descriptors.d.ts +2 -0
- package/dist/frontend/lowering/class-descriptors.js +8 -8
- package/dist/frontend/lowering/class-descriptors.js.map +1 -1
- package/dist/frontend/lowering/class-dynamic-dispatch.d.ts +64 -0
- package/dist/frontend/lowering/class-dynamic-dispatch.js +1124 -90
- package/dist/frontend/lowering/class-dynamic-dispatch.js.map +1 -1
- package/dist/frontend/lowering/class-instance-constructor.js +1 -1
- package/dist/frontend/lowering/class-instance-constructor.js.map +1 -1
- package/dist/frontend/lowering/class-iterables.d.ts +11 -0
- package/dist/frontend/lowering/class-iterables.js +31 -0
- package/dist/frontend/lowering/class-iterables.js.map +1 -0
- package/dist/frontend/lowering/class-method-mutations.js +73 -35
- package/dist/frontend/lowering/class-method-mutations.js.map +1 -1
- package/dist/frontend/lowering/class-method-values.js +56 -10
- package/dist/frontend/lowering/class-method-values.js.map +1 -1
- package/dist/frontend/lowering/class-protocol-dispatch.js +24 -22
- package/dist/frontend/lowering/class-protocol-dispatch.js.map +1 -1
- package/dist/frontend/lowering/class-protocols.d.ts +10 -0
- package/dist/frontend/lowering/class-protocols.js +76 -45
- package/dist/frontend/lowering/class-protocols.js.map +1 -1
- package/dist/frontend/lowering/class-prototypes.d.ts +6 -0
- package/dist/frontend/lowering/class-prototypes.js +86 -19
- package/dist/frontend/lowering/class-prototypes.js.map +1 -1
- package/dist/frontend/lowering/class-runtime-statics.js +1 -1
- package/dist/frontend/lowering/class-runtime-statics.js.map +1 -1
- package/dist/frontend/lowering/class-static-data.js +2 -2
- package/dist/frontend/lowering/class-static-data.js.map +1 -1
- package/dist/frontend/lowering/class-to-primitive.d.ts +25 -0
- package/dist/frontend/lowering/class-to-primitive.js +264 -0
- package/dist/frontend/lowering/class-to-primitive.js.map +1 -0
- package/dist/frontend/lowering/class-unions.d.ts +25 -0
- package/dist/frontend/lowering/class-unions.js +102 -1
- package/dist/frontend/lowering/class-unions.js.map +1 -1
- package/dist/frontend/lowering/code-generation.d.ts +14 -0
- package/dist/frontend/lowering/code-generation.js +127 -0
- package/dist/frontend/lowering/code-generation.js.map +1 -0
- package/dist/frontend/lowering/coercions/fresh-spread.d.ts +13 -0
- package/dist/frontend/lowering/coercions/fresh-spread.js +95 -0
- package/dist/frontend/lowering/coercions/fresh-spread.js.map +1 -0
- package/dist/frontend/lowering/coercions/function-adapters.d.ts +16 -2
- package/dist/frontend/lowering/coercions/function-adapters.js +239 -68
- package/dist/frontend/lowering/coercions/function-adapters.js.map +1 -1
- package/dist/frontend/lowering/coercions/structural-plans.js +25 -3
- package/dist/frontend/lowering/coercions/structural-plans.js.map +1 -1
- package/dist/frontend/lowering/coercions/structural.js +35 -3
- package/dist/frontend/lowering/coercions/structural.js.map +1 -1
- package/dist/frontend/lowering/coercions/unions.d.ts +15 -0
- package/dist/frontend/lowering/coercions/unions.js +57 -1
- package/dist/frontend/lowering/coercions/unions.js.map +1 -1
- package/dist/frontend/lowering/collection-ingestion.js +2 -2
- package/dist/frontend/lowering/collection-ingestion.js.map +1 -1
- package/dist/frontend/lowering/collection-narrowing.js +2 -4
- package/dist/frontend/lowering/collection-narrowing.js.map +1 -1
- package/dist/frontend/lowering/construction-escapes.js +8 -8
- package/dist/frontend/lowering/construction-escapes.js.map +1 -1
- package/dist/frontend/lowering/construction-escapes.test.js +4 -4
- package/dist/frontend/lowering/construction-escapes.test.js.map +1 -1
- package/dist/frontend/lowering/constructor-returns.d.ts +61 -0
- package/dist/frontend/lowering/constructor-returns.js +477 -0
- package/dist/frontend/lowering/constructor-returns.js.map +1 -0
- package/dist/frontend/lowering/containers/array-callback-call.js +1 -1
- package/dist/frontend/lowering/containers/array-callback-call.js.map +1 -1
- package/dist/frontend/lowering/containers/array-callbacks.d.ts +17 -0
- package/dist/frontend/lowering/containers/array-callbacks.js +287 -118
- package/dist/frontend/lowering/containers/array-callbacks.js.map +1 -1
- package/dist/frontend/lowering/containers/array-concat.js +1 -1
- package/dist/frontend/lowering/containers/array-concat.js.map +1 -1
- package/dist/frontend/lowering/containers/array-construction.d.ts +0 -1
- package/dist/frontend/lowering/containers/array-construction.js +58 -13
- package/dist/frontend/lowering/containers/array-construction.js.map +1 -1
- package/dist/frontend/lowering/containers/array-from-async.d.ts +6 -5
- package/dist/frontend/lowering/containers/array-from-async.js +159 -14
- package/dist/frontend/lowering/containers/array-from-async.js.map +1 -1
- package/dist/frontend/lowering/containers/array-methods.js +94 -77
- package/dist/frontend/lowering/containers/array-methods.js.map +1 -1
- package/dist/frontend/lowering/containers/array-pipelines.js +1 -0
- package/dist/frontend/lowering/containers/array-pipelines.js.map +1 -1
- package/dist/frontend/lowering/containers/bytes.d.ts +9 -0
- package/dist/frontend/lowering/containers/bytes.js +649 -113
- package/dist/frontend/lowering/containers/bytes.js.map +1 -1
- package/dist/frontend/lowering/containers/callback-arguments.d.ts +9 -1
- package/dist/frontend/lowering/containers/callback-arguments.js +55 -5
- package/dist/frontend/lowering/containers/callback-arguments.js.map +1 -1
- package/dist/frontend/lowering/containers/collection-grouping.d.ts +7 -8
- package/dist/frontend/lowering/containers/collection-grouping.js +217 -26
- package/dist/frontend/lowering/containers/collection-grouping.js.map +1 -1
- package/dist/frontend/lowering/containers/collection-methods.js +126 -28
- package/dist/frontend/lowering/containers/collection-methods.js.map +1 -1
- package/dist/frontend/lowering/containers/dynamic-receivers.js +1 -1
- package/dist/frontend/lowering/containers/dynamic-receivers.js.map +1 -1
- package/dist/frontend/lowering/containers/exec-result-uses.js +2 -2
- package/dist/frontend/lowering/containers/exec-result-uses.js.map +1 -1
- package/dist/frontend/lowering/containers/for-of.d.ts +6 -0
- package/dist/frontend/lowering/containers/for-of.js +19 -19
- package/dist/frontend/lowering/containers/for-of.js.map +1 -1
- package/dist/frontend/lowering/containers/indexed-objects.js +142 -57
- package/dist/frontend/lowering/containers/indexed-objects.js.map +1 -1
- package/dist/frontend/lowering/containers/iterator-helpers.d.ts +53 -4
- package/dist/frontend/lowering/containers/iterator-helpers.js +1581 -462
- package/dist/frontend/lowering/containers/iterator-helpers.js.map +1 -1
- package/dist/frontend/lowering/containers/match-row-uses.d.ts +17 -0
- package/dist/frontend/lowering/containers/match-row-uses.js +264 -0
- package/dist/frontend/lowering/containers/match-row-uses.js.map +1 -0
- package/dist/frontend/lowering/containers/string-and-regexp.d.ts +14 -0
- package/dist/frontend/lowering/containers/string-and-regexp.js +455 -30
- package/dist/frontend/lowering/containers/string-and-regexp.js.map +1 -1
- package/dist/frontend/lowering/containers/string-replacement.js +1 -1
- package/dist/frontend/lowering/containers/string-replacement.js.map +1 -1
- package/dist/frontend/lowering/cycle-initialization.d.ts +30 -10
- package/dist/frontend/lowering/cycle-initialization.js +191 -35
- package/dist/frontend/lowering/cycle-initialization.js.map +1 -1
- package/dist/frontend/lowering/deferred-module-initializers.js +47 -43
- package/dist/frontend/lowering/deferred-module-initializers.js.map +1 -1
- package/dist/frontend/lowering/devirtualize.d.ts +1 -1
- package/dist/frontend/lowering/devirtualize.js +27 -7
- package/dist/frontend/lowering/devirtualize.js.map +1 -1
- package/dist/frontend/lowering/divergences.d.ts +0 -5
- package/dist/frontend/lowering/divergences.js +62 -125
- package/dist/frontend/lowering/divergences.js.map +1 -1
- package/dist/frontend/lowering/dyn-streams.d.ts +25 -0
- package/dist/frontend/lowering/dyn-streams.js +257 -0
- package/dist/frontend/lowering/dyn-streams.js.map +1 -0
- package/dist/frontend/lowering/error-methods.js +4 -1
- package/dist/frontend/lowering/error-methods.js.map +1 -1
- package/dist/frontend/lowering/error-name-order.d.ts +19 -0
- package/dist/frontend/lowering/error-name-order.js +93 -0
- package/dist/frontend/lowering/error-name-order.js.map +1 -0
- package/dist/frontend/lowering/expressions/array-literals.d.ts +21 -0
- package/dist/frontend/lowering/expressions/array-literals.js +723 -0
- package/dist/frontend/lowering/expressions/array-literals.js.map +1 -0
- package/dist/frontend/lowering/expressions/binary.d.ts +35 -0
- package/dist/frontend/lowering/expressions/binary.js +2557 -0
- package/dist/frontend/lowering/expressions/binary.js.map +1 -0
- package/dist/frontend/lowering/expressions/element-access.d.ts +31 -0
- package/dist/frontend/lowering/expressions/element-access.js +1804 -0
- package/dist/frontend/lowering/expressions/element-access.js.map +1 -0
- package/dist/frontend/lowering/expressions/evaluation-safety.js +4 -3
- package/dist/frontend/lowering/expressions/evaluation-safety.js.map +1 -1
- package/dist/frontend/lowering/expressions/hosted-narrowing.d.ts +38 -0
- package/dist/frontend/lowering/expressions/hosted-narrowing.js +160 -0
- package/dist/frontend/lowering/expressions/hosted-narrowing.js.map +1 -0
- package/dist/frontend/lowering/expressions/identifiers.d.ts +4 -0
- package/dist/frontend/lowering/expressions/identifiers.js +830 -0
- package/dist/frontend/lowering/expressions/identifiers.js.map +1 -0
- package/dist/frontend/lowering/expressions/keyed-field-targets.d.ts +52 -0
- package/dist/frontend/lowering/expressions/keyed-field-targets.js +307 -0
- package/dist/frontend/lowering/expressions/keyed-field-targets.js.map +1 -0
- package/dist/frontend/lowering/expressions/narrowing.d.ts +37 -0
- package/dist/frontend/lowering/expressions/narrowing.js +1337 -0
- package/dist/frontend/lowering/expressions/narrowing.js.map +1 -0
- package/dist/frontend/lowering/expressions/native-proxy.js +4 -4
- package/dist/frontend/lowering/expressions/native-proxy.js.map +1 -1
- package/dist/frontend/lowering/expressions/nullish-assignment.js +45 -0
- package/dist/frontend/lowering/expressions/nullish-assignment.js.map +1 -1
- package/dist/frontend/lowering/expressions/object-literals.d.ts +10 -0
- package/dist/frontend/lowering/expressions/object-literals.js +301 -86
- package/dist/frontend/lowering/expressions/object-literals.js.map +1 -1
- package/dist/frontend/lowering/expressions/optional-chains.d.ts +3 -2
- package/dist/frontend/lowering/expressions/optional-chains.js +103 -17
- package/dist/frontend/lowering/expressions/optional-chains.js.map +1 -1
- package/dist/frontend/lowering/expressions/property-access.d.ts +115 -0
- package/dist/frontend/lowering/expressions/property-access.js +3787 -0
- package/dist/frontend/lowering/expressions/property-access.js.map +1 -0
- package/dist/frontend/lowering/expressions/relational.d.ts +28 -0
- package/dist/frontend/lowering/expressions/relational.js +1724 -0
- package/dist/frontend/lowering/expressions/relational.js.map +1 -0
- package/dist/frontend/lowering/expressions/typeof.d.ts +22 -0
- package/dist/frontend/lowering/expressions/typeof.js +551 -0
- package/dist/frontend/lowering/expressions/typeof.js.map +1 -0
- package/dist/frontend/lowering/expressions/union-fields.js +1 -1
- package/dist/frontend/lowering/expressions/union-fields.js.map +1 -1
- package/dist/frontend/lowering/expressions/updates.d.ts +21 -0
- package/dist/frontend/lowering/expressions/updates.js +780 -0
- package/dist/frontend/lowering/expressions/updates.js.map +1 -0
- package/dist/frontend/lowering/function-context.d.ts +10 -0
- package/dist/frontend/lowering/function-context.js +11 -1
- package/dist/frontend/lowering/function-context.js.map +1 -1
- package/dist/frontend/lowering/function-returns.js +52 -28
- package/dist/frontend/lowering/function-returns.js.map +1 -1
- package/dist/frontend/lowering/general-streams.d.ts +25 -0
- package/dist/frontend/lowering/general-streams.js +108 -0
- package/dist/frontend/lowering/general-streams.js.map +1 -0
- package/dist/frontend/lowering/generator-delegation.d.ts +8 -0
- package/dist/frontend/lowering/generator-delegation.js +191 -1
- package/dist/frontend/lowering/generator-delegation.js.map +1 -1
- package/dist/frontend/lowering/generator-dynamic-dispatch.d.ts +7 -0
- package/dist/frontend/lowering/generator-dynamic-dispatch.js +172 -69
- package/dist/frontend/lowering/generator-dynamic-dispatch.js.map +1 -1
- package/dist/frontend/lowering/generic-functions.d.ts +43 -0
- package/dist/frontend/lowering/generic-functions.js +593 -118
- package/dist/frontend/lowering/generic-functions.js.map +1 -1
- package/dist/frontend/lowering/handle-properties.d.ts +24 -0
- package/dist/frontend/lowering/handle-properties.js +281 -0
- package/dist/frontend/lowering/handle-properties.js.map +1 -0
- package/dist/frontend/lowering/import-meta.js +2 -2
- package/dist/frontend/lowering/import-meta.js.map +1 -1
- package/dist/frontend/lowering/intern-tables.js +10 -9
- package/dist/frontend/lowering/intern-tables.js.map +1 -1
- package/dist/frontend/lowering/iterable-spelling.d.ts +7 -0
- package/dist/frontend/lowering/iterable-spelling.js +38 -0
- package/dist/frontend/lowering/iterable-spelling.js.map +1 -0
- package/dist/frontend/lowering/iterator-adapters.d.ts +19 -0
- package/dist/frontend/lowering/iterator-adapters.js +331 -3
- package/dist/frontend/lowering/iterator-adapters.js.map +1 -1
- package/dist/frontend/lowering/js-class-fields.d.ts +28 -0
- package/dist/frontend/lowering/js-class-fields.js +170 -0
- package/dist/frontend/lowering/js-class-fields.js.map +1 -0
- package/dist/frontend/lowering/js-dynamic-objects.d.ts +15 -0
- package/dist/frontend/lowering/js-dynamic-objects.js +299 -0
- package/dist/frontend/lowering/js-dynamic-objects.js.map +1 -0
- package/dist/frontend/lowering/js-dynamic-objects.test.d.ts +1 -0
- package/dist/frontend/lowering/js-dynamic-objects.test.js +35 -0
- package/dist/frontend/lowering/js-dynamic-objects.test.js.map +1 -0
- package/dist/frontend/lowering/json-require.d.ts +22 -0
- package/dist/frontend/lowering/json-require.js +131 -0
- package/dist/frontend/lowering/json-require.js.map +1 -0
- package/dist/frontend/lowering/key-order-witness.d.ts +44 -0
- package/dist/frontend/lowering/key-order-witness.js +641 -0
- package/dist/frontend/lowering/key-order-witness.js.map +1 -0
- package/dist/frontend/lowering/key-order-witness.test.d.ts +1 -0
- package/dist/frontend/lowering/key-order-witness.test.js +239 -0
- package/dist/frontend/lowering/key-order-witness.test.js.map +1 -0
- package/dist/frontend/lowering/lifetime-regions.js +7 -7
- package/dist/frontend/lowering/lifetime-regions.js.map +1 -1
- package/dist/frontend/lowering/lower-array-sort.d.ts +33 -15
- package/dist/frontend/lowering/lower-array-sort.js +117 -21
- package/dist/frontend/lowering/lower-array-sort.js.map +1 -1
- package/dist/frontend/lowering/lower-array-sort.test.js +93 -14
- package/dist/frontend/lowering/lower-array-sort.test.js.map +1 -1
- package/dist/frontend/lowering/lower-assert.js +61 -60
- package/dist/frontend/lowering/lower-assert.js.map +1 -1
- package/dist/frontend/lowering/lower-async-iteration.d.ts +10 -1
- package/dist/frontend/lowering/lower-async-iteration.js +34 -6
- package/dist/frontend/lowering/lower-async-iteration.js.map +1 -1
- package/dist/frontend/lowering/lower-builtin-values.d.ts +5 -0
- package/dist/frontend/lowering/lower-builtin-values.js +33 -3
- package/dist/frontend/lowering/lower-builtin-values.js.map +1 -1
- package/dist/frontend/lowering/lower-calls.js +1404 -448
- package/dist/frontend/lowering/lower-calls.js.map +1 -1
- package/dist/frontend/lowering/lower-classes.d.ts +54 -3
- package/dist/frontend/lowering/lower-classes.js +1529 -472
- package/dist/frontend/lowering/lower-classes.js.map +1 -1
- package/dist/frontend/lowering/lower-comptime.d.ts +4 -2
- package/dist/frontend/lowering/lower-comptime.js +111 -13
- package/dist/frontend/lowering/lower-comptime.js.map +1 -1
- package/dist/frontend/lowering/lower-console.js +13 -11
- package/dist/frontend/lowering/lower-console.js.map +1 -1
- package/dist/frontend/lowering/lower-dgram.d.ts +10 -0
- package/dist/frontend/lowering/lower-dgram.js +241 -21
- package/dist/frontend/lowering/lower-dgram.js.map +1 -1
- package/dist/frontend/lowering/lower-enums.js +113 -14
- package/dist/frontend/lowering/lower-enums.js.map +1 -1
- package/dist/frontend/lowering/lower-event-emitter.d.ts +16 -7
- package/dist/frontend/lowering/lower-event-emitter.js +258 -70
- package/dist/frontend/lowering/lower-event-emitter.js.map +1 -1
- package/dist/frontend/lowering/lower-event-target.js +2 -2
- package/dist/frontend/lowering/lower-event-target.js.map +1 -1
- package/dist/frontend/lowering/lower-expando.js +17 -13
- package/dist/frontend/lowering/lower-expando.js.map +1 -1
- package/dist/frontend/lowering/lower-exprs.d.ts +188 -186
- package/dist/frontend/lowering/lower-exprs.js +1509 -12486
- package/dist/frontend/lowering/lower-exprs.js.map +1 -1
- package/dist/frontend/lowering/lower-functions.js +72 -22
- package/dist/frontend/lowering/lower-functions.js.map +1 -1
- package/dist/frontend/lowering/lower-generators.d.ts +6 -0
- package/dist/frontend/lowering/lower-generators.js +39 -20
- package/dist/frontend/lowering/lower-generators.js.map +1 -1
- package/dist/frontend/lowering/lower-global-value.js +5 -1
- package/dist/frontend/lowering/lower-global-value.js.map +1 -1
- package/dist/frontend/lowering/lower-inspect.js +900 -107
- package/dist/frontend/lowering/lower-inspect.js.map +1 -1
- package/dist/frontend/lowering/lower-mixins.js +23 -20
- package/dist/frontend/lowering/lower-mixins.js.map +1 -1
- package/dist/frontend/lowering/lower-mock.d.ts +8 -1
- package/dist/frontend/lowering/lower-mock.js +185 -18
- package/dist/frontend/lowering/lower-mock.js.map +1 -1
- package/dist/frontend/lowering/lower-modules.d.ts +11 -3
- package/dist/frontend/lowering/lower-modules.js +445 -94
- package/dist/frontend/lowering/lower-modules.js.map +1 -1
- package/dist/frontend/lowering/lower-namespaces.d.ts +6 -0
- package/dist/frontend/lowering/lower-namespaces.js +65 -33
- package/dist/frontend/lowering/lower-namespaces.js.map +1 -1
- package/dist/frontend/lowering/lower-node-module.d.ts +16 -0
- package/dist/frontend/lowering/lower-node-module.js +147 -14
- package/dist/frontend/lowering/lower-node-module.js.map +1 -1
- package/dist/frontend/lowering/lower-server.d.ts +6 -6
- package/dist/frontend/lowering/lower-server.js +514 -101
- package/dist/frontend/lowering/lower-server.js.map +1 -1
- package/dist/frontend/lowering/lower-stdlib.d.ts +4 -0
- package/dist/frontend/lowering/lower-stdlib.js +179 -118
- package/dist/frontend/lowering/lower-stdlib.js.map +1 -1
- package/dist/frontend/lowering/lower-stmts.d.ts +30 -7
- package/dist/frontend/lowering/lower-stmts.js +1950 -433
- package/dist/frontend/lowering/lower-stmts.js.map +1 -1
- package/dist/frontend/lowering/lower-stream.d.ts +3 -0
- package/dist/frontend/lowering/lower-stream.js +398 -56
- package/dist/frontend/lowering/lower-stream.js.map +1 -1
- package/dist/frontend/lowering/lower-test.d.ts +3 -0
- package/dist/frontend/lowering/lower-test.js +437 -62
- package/dist/frontend/lowering/lower-test.js.map +1 -1
- package/dist/frontend/lowering/lower-timers.js +96 -32
- package/dist/frontend/lowering/lower-timers.js.map +1 -1
- package/dist/frontend/lowering/lower-url.js +1 -1
- package/dist/frontend/lowering/lower-url.js.map +1 -1
- package/dist/frontend/lowering/lowerer.d.ts +424 -27
- package/dist/frontend/lowering/lowerer.js +2062 -310
- package/dist/frontend/lowering/lowerer.js.map +1 -1
- package/dist/frontend/lowering/lowerer.test.js +10 -4
- package/dist/frontend/lowering/lowerer.test.js.map +1 -1
- package/dist/frontend/lowering/maybe-promise.d.ts +46 -0
- package/dist/frontend/lowering/maybe-promise.js +249 -0
- package/dist/frontend/lowering/maybe-promise.js.map +1 -0
- package/dist/frontend/lowering/module-member-this.d.ts +3 -0
- package/dist/frontend/lowering/module-member-this.js +262 -0
- package/dist/frontend/lowering/module-member-this.js.map +1 -0
- package/dist/frontend/lowering/module-namespace-elements.js +1 -1
- package/dist/frontend/lowering/module-namespace-elements.js.map +1 -1
- package/dist/frontend/lowering/nan-coded-reads.d.ts +3 -0
- package/dist/frontend/lowering/nan-coded-reads.js +45 -32
- package/dist/frontend/lowering/nan-coded-reads.js.map +1 -1
- package/dist/frontend/lowering/narrowing-stability.d.ts +18 -3
- package/dist/frontend/lowering/narrowing-stability.js +104 -32
- package/dist/frontend/lowering/narrowing-stability.js.map +1 -1
- package/dist/frontend/lowering/native-ffi.js +11 -11
- package/dist/frontend/lowering/native-ffi.js.map +1 -1
- package/dist/frontend/lowering/object-factory-new.js +6 -8
- package/dist/frontend/lowering/object-factory-new.js.map +1 -1
- package/dist/frontend/lowering/private-brands.d.ts +46 -0
- package/dist/frontend/lowering/private-brands.js +265 -0
- package/dist/frontend/lowering/private-brands.js.map +1 -0
- package/dist/frontend/lowering/promise-executor-adapter.d.ts +11 -0
- package/dist/frontend/lowering/promise-executor-adapter.js +87 -0
- package/dist/frontend/lowering/promise-executor-adapter.js.map +1 -0
- package/dist/frontend/lowering/rebindable-functions.d.ts +8 -0
- package/dist/frontend/lowering/rebindable-functions.js +54 -0
- package/dist/frontend/lowering/rebindable-functions.js.map +1 -0
- package/dist/frontend/lowering/require-initialization.d.ts +32 -0
- package/dist/frontend/lowering/require-initialization.js +246 -0
- package/dist/frontend/lowering/require-initialization.js.map +1 -0
- package/dist/frontend/lowering/runtime-optional-bounds.js +7 -7
- package/dist/frontend/lowering/runtime-optional-bounds.js.map +1 -1
- package/dist/frontend/lowering/runtime-optional-elements.js +12 -12
- package/dist/frontend/lowering/runtime-optional-elements.js.map +1 -1
- package/dist/frontend/lowering/runtime-optional-guards.js +10 -10
- package/dist/frontend/lowering/runtime-optional-guards.js.map +1 -1
- package/dist/frontend/lowering/runtime-optional-guards.test.js +1 -1
- package/dist/frontend/lowering/runtime-optional-guards.test.js.map +1 -1
- package/dist/frontend/lowering/runtime-optional-ownership.js +10 -9
- package/dist/frontend/lowering/runtime-optional-ownership.js.map +1 -1
- package/dist/frontend/lowering/runtime-optional-provenance.js +2 -2
- package/dist/frontend/lowering/runtime-optional-provenance.js.map +1 -1
- package/dist/frontend/lowering/runtime-optional-records.d.ts +35 -0
- package/dist/frontend/lowering/runtime-optional-records.js +205 -32
- package/dist/frontend/lowering/runtime-optional-records.js.map +1 -1
- package/dist/frontend/lowering/runtime-optional-records.test.js +19 -1
- package/dist/frontend/lowering/runtime-optional-records.test.js.map +1 -1
- package/dist/frontend/lowering/sanitize-class-types.test.js +2 -2
- package/dist/frontend/lowering/split-consumers.js +4 -4
- package/dist/frontend/lowering/split-consumers.js.map +1 -1
- package/dist/frontend/lowering/static-function-names.d.ts +28 -0
- package/dist/frontend/lowering/static-function-names.js +212 -0
- package/dist/frontend/lowering/static-function-names.js.map +1 -0
- package/dist/frontend/lowering/static-this.js +6 -6
- package/dist/frontend/lowering/static-this.js.map +1 -1
- package/dist/frontend/lowering/static-typeof.d.ts +26 -0
- package/dist/frontend/lowering/static-typeof.js +133 -0
- package/dist/frontend/lowering/static-typeof.js.map +1 -0
- package/dist/frontend/lowering/strict-mode.d.ts +5 -0
- package/dist/frontend/lowering/strict-mode.js +31 -0
- package/dist/frontend/lowering/strict-mode.js.map +1 -0
- package/dist/frontend/lowering/string-index-bounds.js +13 -12
- package/dist/frontend/lowering/string-index-bounds.js.map +1 -1
- package/dist/frontend/lowering/string-index.d.ts +12 -0
- package/dist/frontend/lowering/string-index.js +72 -1
- package/dist/frontend/lowering/string-index.js.map +1 -1
- package/dist/frontend/lowering/surfaces.d.ts +12 -3
- package/dist/frontend/lowering/surfaces.js +282 -45
- package/dist/frontend/lowering/surfaces.js.map +1 -1
- package/dist/frontend/lowering/symbol-fields.d.ts +7 -0
- package/dist/frontend/lowering/symbol-fields.js +204 -36
- package/dist/frontend/lowering/symbol-fields.js.map +1 -1
- package/dist/frontend/lowering/symbol-methods.d.ts +2 -1
- package/dist/frontend/lowering/symbol-methods.js +24 -6
- package/dist/frontend/lowering/symbol-methods.js.map +1 -1
- package/dist/frontend/lowering/thenables.d.ts +16 -0
- package/dist/frontend/lowering/thenables.js +124 -0
- package/dist/frontend/lowering/thenables.js.map +1 -0
- package/dist/frontend/lowering/thread-slots.d.ts +13 -0
- package/dist/frontend/lowering/thread-slots.js +208 -0
- package/dist/frontend/lowering/thread-slots.js.map +1 -0
- package/dist/frontend/lowering/typed-arguments.d.ts +74 -0
- package/dist/frontend/lowering/typed-arguments.js +472 -0
- package/dist/frontend/lowering/typed-arguments.js.map +1 -0
- package/dist/frontend/lowering/union-retag.d.ts +8 -0
- package/dist/frontend/lowering/union-retag.js +27 -0
- package/dist/frontend/lowering/union-retag.js.map +1 -1
- package/dist/frontend/lowering/union-retag.test.js +24 -1
- package/dist/frontend/lowering/union-retag.test.js.map +1 -1
- package/dist/frontend/lowering/var-hoisting.js +6 -6
- package/dist/frontend/lowering/var-hoisting.js.map +1 -1
- package/dist/frontend/lowering/width-lift.d.ts +4 -0
- package/dist/frontend/mock-shapes.js +13 -6
- package/dist/frontend/mock-shapes.js.map +1 -1
- package/dist/frontend/module-source-candidates.js +1 -1
- package/dist/frontend/module-source-candidates.js.map +1 -1
- package/dist/frontend/module-source-candidates.test.js +2 -1
- package/dist/frontend/module-source-candidates.test.js.map +1 -1
- package/dist/frontend/module-syntax.js +8 -8
- package/dist/frontend/module-syntax.js.map +1 -1
- package/dist/frontend/npm-static-builtin-aliases.d.ts +8 -0
- package/dist/frontend/npm-static-builtin-aliases.js +65 -0
- package/dist/frontend/npm-static-builtin-aliases.js.map +1 -0
- package/dist/frontend/npm-static-bundled-chunks.d.ts +58 -0
- package/dist/frontend/npm-static-bundled-chunks.js +981 -0
- package/dist/frontend/npm-static-bundled-chunks.js.map +1 -0
- package/dist/frontend/npm-static-bundled-chunks.test.d.ts +1 -0
- package/dist/frontend/npm-static-bundled-chunks.test.js +399 -0
- package/dist/frontend/npm-static-bundled-chunks.test.js.map +1 -0
- package/dist/frontend/npm-static-bundled-cjs.js +24 -23
- package/dist/frontend/npm-static-bundled-cjs.js.map +1 -1
- package/dist/frontend/npm-static-bundled-esm.d.ts +9 -0
- package/dist/frontend/npm-static-bundled-esm.js +988 -0
- package/dist/frontend/npm-static-bundled-esm.js.map +1 -0
- package/dist/frontend/npm-static-bundled-esm.test.d.ts +1 -0
- package/dist/frontend/npm-static-bundled-esm.test.js +336 -0
- package/dist/frontend/npm-static-bundled-esm.test.js.map +1 -0
- package/dist/frontend/npm-static-cjs-exports-alias.d.ts +2 -0
- package/dist/frontend/npm-static-cjs-exports-alias.js +186 -0
- package/dist/frontend/npm-static-cjs-exports-alias.js.map +1 -0
- package/dist/frontend/npm-static-cjs-exports-alias.test.d.ts +1 -0
- package/dist/frontend/npm-static-cjs-exports-alias.test.js +73 -0
- package/dist/frontend/npm-static-cjs-exports-alias.test.js.map +1 -0
- package/dist/frontend/npm-static-cjs-exports-var.d.ts +2 -0
- package/dist/frontend/npm-static-cjs-exports-var.js +236 -0
- package/dist/frontend/npm-static-cjs-exports-var.js.map +1 -0
- package/dist/frontend/npm-static-declaration-syntax.js +102 -101
- package/dist/frontend/npm-static-declaration-syntax.js.map +1 -1
- package/dist/frontend/npm-static-enum-iife.d.ts +6 -0
- package/dist/frontend/npm-static-enum-iife.js +280 -0
- package/dist/frontend/npm-static-enum-iife.js.map +1 -0
- package/dist/frontend/npm-static-enum-iife.test.d.ts +1 -0
- package/dist/frontend/npm-static-enum-iife.test.js +116 -0
- package/dist/frontend/npm-static-enum-iife.test.js.map +1 -0
- package/dist/frontend/npm-static-prune.js +36 -24
- package/dist/frontend/npm-static-prune.js.map +1 -1
- package/dist/frontend/npm-static-rewrite-host.d.ts +4 -1
- package/dist/frontend/npm-static-rewrite-host.js +14 -3
- package/dist/frontend/npm-static-rewrite-host.js.map +1 -1
- package/dist/frontend/npm-static-rewrite-syntax.d.ts +19 -0
- package/dist/frontend/npm-static-rewrite-syntax.js +274 -101
- package/dist/frontend/npm-static-rewrite-syntax.js.map +1 -1
- package/dist/frontend/npm-static-subtyping.js +7 -9
- package/dist/frontend/npm-static-subtyping.js.map +1 -1
- package/dist/frontend/npm-static.d.ts +25 -1
- package/dist/frontend/npm-static.js +212 -16
- package/dist/frontend/npm-static.js.map +1 -1
- package/dist/frontend/npm-static.test.js +22 -1
- package/dist/frontend/npm-static.test.js.map +1 -1
- package/dist/frontend/npm.js +13 -0
- package/dist/frontend/npm.js.map +1 -1
- package/dist/frontend/package-shims.d.ts +47 -0
- package/dist/frontend/package-shims.js +300 -0
- package/dist/frontend/package-shims.js.map +1 -0
- package/dist/frontend/pipeline.js +230 -26
- package/dist/frontend/pipeline.js.map +1 -1
- package/dist/frontend/pipeline.test.js +22 -1
- package/dist/frontend/pipeline.test.js.map +1 -1
- package/dist/frontend/program-analysis.d.ts +6 -1
- package/dist/frontend/program-analysis.js +7 -0
- package/dist/frontend/program-analysis.js.map +1 -1
- package/dist/frontend/program.d.ts +100 -2
- package/dist/frontend/program.js +1627 -262
- package/dist/frontend/program.js.map +1 -1
- package/dist/frontend/program.test.js +76 -6
- package/dist/frontend/program.test.js.map +1 -1
- package/dist/frontend/resolve.js +49 -2
- package/dist/frontend/resolve.js.map +1 -1
- package/dist/frontend/resolve.test.js +49 -0
- package/dist/frontend/resolve.test.js.map +1 -1
- package/dist/frontend/services.d.ts +26 -1
- package/dist/frontend/services.js +59 -3
- package/dist/frontend/services.js.map +1 -1
- package/dist/frontend/services.test.js +2 -1
- package/dist/frontend/services.test.js.map +1 -1
- package/dist/frontend/threads-import.js +1 -1
- package/dist/frontend/threads-import.js.map +1 -1
- package/dist/frontend/tier-analysis.d.ts +71 -0
- package/dist/frontend/tier-analysis.js +522 -0
- package/dist/frontend/tier-analysis.js.map +1 -0
- package/dist/frontend/ts7/api-conformance.d.ts +234 -0
- package/dist/frontend/ts7/api-conformance.js +7 -0
- package/dist/frontend/ts7/api-conformance.js.map +1 -0
- package/dist/frontend/ts7/ast-guards.generated.js +2 -1
- package/dist/frontend/ts7/ast-guards.generated.js.map +1 -1
- package/dist/frontend/ts7/ast-node.d.ts +47 -25
- package/dist/frontend/ts7/ast-node.js +64 -18
- package/dist/frontend/ts7/ast-node.js.map +1 -1
- package/dist/frontend/ts7/ast-node.test.js +36 -12
- package/dist/frontend/ts7/ast-node.test.js.map +1 -1
- package/dist/frontend/ts7/ast-types.d.ts +10 -3
- package/dist/frontend/ts7/ast-types.generated.d.ts +39 -39
- package/dist/frontend/ts7/ast.d.ts +1 -0
- package/dist/frontend/ts7/ast.js +3 -2
- package/dist/frontend/ts7/ast.js.map +1 -1
- package/dist/frontend/ts7/checker-backend.d.ts +23 -0
- package/dist/frontend/ts7/checker-backend.js +88 -0
- package/dist/frontend/ts7/checker-backend.js.map +1 -0
- package/dist/frontend/ts7/checker-backend.test.d.ts +1 -0
- package/dist/frontend/ts7/checker-backend.test.js +63 -0
- package/dist/frontend/ts7/checker-backend.test.js.map +1 -0
- package/dist/frontend/ts7/checker-cache.d.ts +0 -3
- package/dist/frontend/ts7/checker-cache.js +0 -6
- package/dist/frontend/ts7/checker-cache.js.map +1 -1
- package/dist/frontend/ts7/checker.d.ts +18 -11
- package/dist/frontend/ts7/checker.js +42 -55
- package/dist/frontend/ts7/checker.js.map +1 -1
- package/dist/frontend/ts7/checker.test.js +10 -7
- package/dist/frontend/ts7/checker.test.js.map +1 -1
- package/dist/frontend/ts7/diagnostic.d.ts +19 -0
- package/dist/frontend/ts7/diagnostic.js +22 -0
- package/dist/frontend/ts7/diagnostic.js.map +1 -0
- package/dist/frontend/ts7/node-functions.d.ts +8 -0
- package/dist/frontend/ts7/node-functions.js +18 -0
- package/dist/frontend/ts7/node-functions.js.map +1 -0
- package/dist/frontend/ts7/program-host.d.ts +10 -5
- package/dist/frontend/ts7/program-host.js +19 -0
- package/dist/frontend/ts7/program-host.js.map +1 -1
- package/dist/frontend/ts7/rpc-api.d.ts +5 -1
- package/dist/frontend/ts7/rpc-api.js +8 -1
- package/dist/frontend/ts7/rpc-api.js.map +1 -1
- package/dist/frontend/ts7/semantic-checker.d.ts +13 -6
- package/dist/frontend/ts7/semantic-checker.js +26 -8
- package/dist/frontend/ts7/semantic-checker.js.map +1 -1
- package/dist/frontend/ts7/semantic-checker.test.js +12 -9
- package/dist/frontend/ts7/semantic-checker.test.js.map +1 -1
- package/dist/frontend/ts7/semantic-model.d.ts +57 -24
- package/dist/frontend/ts7/semantic-model.js +114 -16
- package/dist/frontend/ts7/semantic-model.js.map +1 -1
- package/dist/frontend/ts7/semantic-model.test.js +4 -4
- package/dist/frontend/ts7/semantic-model.test.js.map +1 -1
- package/dist/frontend/ts7/semantic-types.d.ts +7 -3
- package/dist/frontend/ts7/semantic-types.js +1 -1
- package/dist/frontend/ts7/semantic-types.js.map +1 -1
- package/dist/frontend/ts7/session.d.ts +30 -15
- package/dist/frontend/ts7/session.js +8 -5
- package/dist/frontend/ts7/session.js.map +1 -1
- package/dist/frontend/ts7/session.test.js +9 -5
- package/dist/frontend/ts7/session.test.js.map +1 -1
- package/dist/frontend/ts7/source-parser.d.ts +6 -2
- package/dist/frontend/ts7/source-parser.js +24 -3
- package/dist/frontend/ts7/source-parser.js.map +1 -1
- package/dist/frontend/ts7/source-parser.test.js +38 -17
- package/dist/frontend/ts7/source-parser.test.js.map +1 -1
- package/dist/frontend/type-mapper.d.ts +122 -2
- package/dist/frontend/type-mapper.js +2735 -723
- package/dist/frontend/type-mapper.js.map +1 -1
- package/dist/frontend/type-only-imports.d.ts +28 -0
- package/dist/frontend/type-only-imports.js +122 -0
- package/dist/frontend/type-only-imports.js.map +1 -0
- package/dist/frontend/worker-target.js +8 -8
- package/dist/frontend/worker-target.js.map +1 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.js +87 -8
- package/dist/index.js.map +1 -1
- package/dist/ir/analysis.js +4 -2
- package/dist/ir/analysis.js.map +1 -1
- package/dist/ir/api.d.ts +1 -1
- package/dist/ir/api.js +1 -1
- package/dist/ir/api.js.map +1 -1
- package/dist/ir/array-length-stability.d.ts +31 -0
- package/dist/ir/array-length-stability.js +249 -0
- package/dist/ir/array-length-stability.js.map +1 -0
- package/dist/ir/array-length-stability.test.d.ts +1 -0
- package/dist/ir/array-length-stability.test.js +134 -0
- package/dist/ir/array-length-stability.test.js.map +1 -0
- package/dist/ir/build.d.ts +2 -2
- package/dist/ir/build.js +1 -1
- package/dist/ir/build.js.map +1 -1
- package/dist/ir/builtin-effects.js +116 -0
- package/dist/ir/builtin-effects.js.map +1 -1
- package/dist/ir/builtin-signatures.d.ts +1 -1
- package/dist/ir/builtin-signatures.js +540 -29
- package/dist/ir/builtin-signatures.js.map +1 -1
- package/dist/ir/byte-numbers.js +3 -0
- package/dist/ir/byte-numbers.js.map +1 -1
- package/dist/ir/callback-specialization.d.ts +37 -0
- package/dist/ir/callback-specialization.js +459 -0
- package/dist/ir/callback-specialization.js.map +1 -0
- package/dist/ir/callback-specialization.test.d.ts +1 -0
- package/dist/ir/callback-specialization.test.js +208 -0
- package/dist/ir/callback-specialization.test.js.map +1 -0
- package/dist/ir/capture-values.d.ts +0 -1
- package/dist/ir/capture-values.js +51 -40
- package/dist/ir/capture-values.js.map +1 -1
- package/dist/ir/constant-globals.test.js +1 -1
- package/dist/ir/constant-tables.test.js +1 -1
- package/dist/ir/field-values.test.js +1 -1
- package/dist/ir/final-fields.test.js +1 -1
- package/dist/ir/function-references.test.js +9 -1
- package/dist/ir/function-references.test.js.map +1 -1
- package/dist/ir/init-only-globals.test.js +1 -1
- package/dist/ir/initializer-bindings.test.js +1 -1
- package/dist/ir/int32-slots.d.ts +14 -0
- package/dist/ir/int32-slots.js +97 -14
- package/dist/ir/int32-slots.js.map +1 -1
- package/dist/ir/int32-slots.test.js +1 -1
- package/dist/ir/integer-loop-facts.d.ts +7 -0
- package/dist/ir/integer-loop-facts.js +103 -17
- package/dist/ir/integer-loop-facts.js.map +1 -1
- package/dist/ir/integer-loops.d.ts +1 -1
- package/dist/ir/integer-loops.js +39 -9
- package/dist/ir/integer-loops.js.map +1 -1
- package/dist/ir/integer-loops.test.js +104 -0
- package/dist/ir/integer-loops.test.js.map +1 -1
- package/dist/ir/integer-ranges.d.ts +13 -1
- package/dist/ir/integer-ranges.js +125 -26
- package/dist/ir/integer-ranges.js.map +1 -1
- package/dist/ir/integer-ranges.test.js +273 -2
- package/dist/ir/integer-ranges.test.js.map +1 -1
- package/dist/ir/intrinsic-signatures.js +6 -0
- package/dist/ir/intrinsic-signatures.js.map +1 -1
- package/dist/ir/ir.d.ts +221 -58
- package/dist/ir/ir.js +127 -12
- package/dist/ir/ir.js.map +1 -1
- package/dist/ir/ir.test.js +10 -0
- package/dist/ir/ir.test.js.map +1 -1
- package/dist/ir/js-ic.d.ts +52 -0
- package/dist/ir/js-ic.js +199 -0
- package/dist/ir/js-ic.js.map +1 -0
- package/dist/ir/js-ic.test.d.ts +1 -0
- package/dist/ir/js-ic.test.js +148 -0
- package/dist/ir/js-ic.test.js.map +1 -0
- package/dist/ir/jsval.d.ts +8 -0
- package/dist/ir/jsval.js +399 -0
- package/dist/ir/jsval.js.map +1 -0
- package/dist/ir/jsval.test.d.ts +1 -0
- package/dist/ir/jsval.test.js +239 -0
- package/dist/ir/jsval.test.js.map +1 -0
- package/dist/ir/runtime-features.d.ts +183 -33
- package/dist/ir/runtime-features.js +795 -422
- package/dist/ir/runtime-features.js.map +1 -1
- package/dist/ir/scalar-records.test.js +1 -1
- package/dist/ir/self-captures.d.ts +33 -0
- package/dist/ir/self-captures.js +245 -0
- package/dist/ir/self-captures.js.map +1 -0
- package/dist/ir/self-captures.test.d.ts +1 -0
- package/dist/ir/self-captures.test.js +135 -0
- package/dist/ir/self-captures.test.js.map +1 -0
- package/dist/ir/serialize.d.ts +1 -1
- package/dist/ir/serialize.js +7 -4
- package/dist/ir/serialize.js.map +1 -1
- package/dist/ir/tiers.d.ts +26 -0
- package/dist/ir/tiers.js +101 -0
- package/dist/ir/tiers.js.map +1 -0
- package/dist/ir/tiers.test.d.ts +1 -0
- package/dist/ir/tiers.test.js +140 -0
- package/dist/ir/tiers.test.js.map +1 -0
- package/dist/ir/traverse.js +201 -150
- package/dist/ir/traverse.js.map +1 -1
- package/dist/ir/traverse.test.js +33 -30
- package/dist/ir/traverse.test.js.map +1 -1
- package/dist/ir/unshare.js +65 -3
- package/dist/ir/unshare.js.map +1 -1
- package/dist/ir/unshare.test.js +1 -1
- package/dist/ir/validate.js +196 -76
- package/dist/ir/validate.js.map +1 -1
- package/dist/ir/validate.test.js +41 -11
- package/dist/ir/validate.test.js.map +1 -1
- package/dist/library/fence-eval.test.js +1 -1
- package/dist/library/int-infer.test.js +4 -4
- package/dist/library/ir-policy.js +14 -0
- package/dist/library/ir-policy.js.map +1 -1
- package/dist/library/library-cache.d.ts +1 -0
- package/dist/library/library-cache.js.map +1 -1
- package/dist/library/library-cache.test.js +5 -5
- package/dist/library/library-profile.d.ts +4 -4
- package/dist/library/library-profile.js +35 -7
- package/dist/library/library-profile.js.map +1 -1
- package/dist/library/prepare.js +13 -1
- package/dist/library/prepare.js.map +1 -1
- package/dist/native/cli.js +22 -0
- package/dist/native/cli.js.map +1 -1
- package/dist/native/compiler.js +35 -6
- package/dist/native/compiler.js.map +1 -1
- package/dist/native/compiler.test.js +2 -2
- package/dist/native/executable-cache.js +3 -0
- package/dist/native/executable-cache.js.map +1 -1
- package/dist/native/prepare.js +10 -0
- package/dist/native/prepare.js.map +1 -1
- package/dist/native/sanitizer.test.js +19 -0
- package/dist/native/sanitizer.test.js.map +1 -1
- package/dist/native/toolchain.d.ts +2 -0
- package/dist/native/toolchain.js +10 -1
- package/dist/native/toolchain.js.map +1 -1
- package/dist/native/toolchain.test.js +39 -1
- package/dist/native/toolchain.test.js.map +1 -1
- package/dist/startup-cache.d.ts +1 -0
- package/dist/startup-cache.js +1 -0
- package/dist/startup-cache.js.map +1 -1
- package/dist/wasm/base64.d.ts +5 -0
- package/dist/wasm/base64.js +62 -0
- package/dist/wasm/base64.js.map +1 -0
- package/dist/wasm/binary.d.ts +36 -0
- package/dist/wasm/binary.js +1976 -0
- package/dist/wasm/binary.js.map +1 -0
- package/dist/wasm/binary.test.d.ts +1 -0
- package/dist/wasm/binary.test.js +190 -0
- package/dist/wasm/binary.test.js.map +1 -0
- package/dist/wasm/discover.d.ts +38 -0
- package/dist/wasm/discover.js +377 -0
- package/dist/wasm/discover.js.map +1 -0
- package/dist/wasm/discover.test.d.ts +1 -0
- package/dist/wasm/discover.test.js +24 -0
- package/dist/wasm/discover.test.js.map +1 -0
- package/dist/wasm/module.d.ts +151 -0
- package/dist/wasm/module.js +575 -0
- package/dist/wasm/module.js.map +1 -0
- package/dist/wasm/translate.d.ts +48 -0
- package/dist/wasm/translate.js +2129 -0
- package/dist/wasm/translate.js.map +1 -0
- package/dist/wasm/translate.test.d.ts +1 -0
- package/dist/wasm/translate.test.js +207 -0
- package/dist/wasm/translate.test.js.map +1 -0
- package/package.json +22 -20
- package/shims/fs-extra/core/api.ts +1192 -0
- package/shims/fs-extra/index.ts +9 -0
- package/shims/undici/core/agent.ts +163 -0
- package/shims/undici/core/api.ts +93 -0
- package/shims/undici/core/client.ts +1304 -0
- package/shims/undici/core/connector.ts +157 -0
- package/shims/undici/core/diagnostics-types.ts +68 -0
- package/shims/undici/core/diagnostics.ts +16 -0
- package/shims/undici/core/dispatcher.ts +574 -0
- package/shims/undici/core/errors-v5.ts +22 -0
- package/shims/undici/core/errors-v7.ts +25 -0
- package/shims/undici/core/errors.ts +255 -0
- package/shims/undici/core/fetch.ts +635 -0
- package/shims/undici/core/pool.ts +280 -0
- package/shims/undici/core/readable.ts +268 -0
- package/shims/undici/core/request.ts +313 -0
- package/shims/undici/core/timers.ts +80 -0
- package/shims/undici/core/types.ts +167 -0
- package/shims/undici/core/util.ts +67 -0
- package/shims/undici/v5.ts +119 -0
- package/shims/undici/v7.ts +119 -0
- package/surface-manifest.json +304 -22
|
@@ -1,6 +1,11 @@
|
|
|
1
|
+
import { lowerValueReturningConstructorNew } from "./js-dynamic-objects.js";
|
|
2
|
+
import { adaptPromiseExecutor } from "./promise-executor-adapter.js";
|
|
1
3
|
import { dynUndefinedExpr, nodeThrowExpr, varRef } from "../../ir/build.js";
|
|
4
|
+
import { constructedFromValue, constructedValue, superIntoResultSlot, } from "./constructor-returns.js";
|
|
2
5
|
import { checkedIterableSpread } from "./checked-iterable-spread.js";
|
|
3
6
|
import { lowerReadlineUiNew } from "./builtins/readline.js";
|
|
7
|
+
import { builtinMemberRequireDecl } from "./builtins/module-bindings.js";
|
|
8
|
+
import { checkedClassUnionAssertion } from "./class-assertions.js";
|
|
4
9
|
import { collectClassMethodMutations } from "./class-method-mutations.js";
|
|
5
10
|
import { InternalCompilerError } from "../../errors.js";
|
|
6
11
|
/* Class lowering: shape collection over the single-inheritance graph
|
|
@@ -9,40 +14,48 @@ import { InternalCompilerError } from "../../errors.js";
|
|
|
9
14
|
* accessor access, upcasts, `new` expressions, and the builtin Error
|
|
10
15
|
* hierarchy registration. */
|
|
11
16
|
import { fsStreamClassOf, lowerFsStreamNew } from "./builtins/fs-streams.js";
|
|
17
|
+
import { codeGenerationCalleeOf, lowerCodeGenerationCall } from "./code-generation.js";
|
|
18
|
+
import { TEMPORAL_GLOBAL } from "../builtin-modules.js";
|
|
12
19
|
import * as ts from "../ts7/adapter.js";
|
|
13
|
-
import { lowerZlibStreamNew, zlibStreamModeOf } from "./builtins/compression.js";
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
20
|
+
import { lowerZlibStreamNew, zlibClassName, zlibStreamModeOf } from "./builtins/compression.js";
|
|
21
|
+
import { everyStmtList } from "../../ir/traverse.js";
|
|
22
|
+
import { builtinClassAliasOf, builtinClassRefOf, } from "./builtins/class-values.js";
|
|
23
|
+
import { inlineNamespaceRequireOf, lowerWithInlineRequireInit } from "./cjs-inline-require.js";
|
|
24
|
+
import { BOOL, canDynCheckTo, DATE_T, DYN, F64, bytesOf, RUNTIME_EMITTER_CLASS, RUNTIME_ERROR_CLASSES, RUNTIME_STREAM_CLASSES, STRING, classValueConstructor, UNDEFINED_T, VOID, arrayOf, isSupportedMapKey, isSupportedMapValue, isSupportedSetElem, isUnitType, typeEquals, } from "../../ir/ir.js";
|
|
25
|
+
import { genericCallInstance, implicitAnyParamSymbolsOf, implicitCallInstance, implicitMonoFile, genericLocalClassResult, } from "./generic-functions.js";
|
|
16
26
|
import { extendInstantiationPath, MAX_INSTANTIATION_RECURSION, } from "./instantiation-path.js";
|
|
17
27
|
import { appendImplicitUndefinedReturn, hasExplicitJsDocReturn } from "./function-returns.js";
|
|
18
28
|
import { bodyReadsArguments } from "../arguments-usage.js";
|
|
19
|
-
import {
|
|
29
|
+
import { errorNameAfterField, errorViewFields } from "./error-name-order.js";
|
|
30
|
+
import { checkedJsDocumentedParameter, documentedParameter, generatorMeta, } from "./call-signatures.js";
|
|
20
31
|
import { omittedArgFor } from "./call-arguments.js";
|
|
21
32
|
import { isGenericCallableMemberType, jsOpenObjectType, typeKey, withUnitArm, } from "../type-mapper.js";
|
|
22
|
-
import { cjsClassExprWholeExportOf, isCjsJsFile, isJsSourceFile, isModuleExportsAccess,
|
|
23
|
-
import { PoisonError, dynFallbackType, newFnCtx, own } from "./lowerer.js";
|
|
33
|
+
import { canonicalBuiltinModule, cjsClassExprWholeExportOf, isCjsJsFile, isJsSourceFile, isModuleExportsAccess, locOf, requireSpecOf, } from "../program.js";
|
|
34
|
+
import { PoisonError, dynFallbackType, jsFuncNameOf, newFnCtx, own } from "./lowerer.js";
|
|
24
35
|
import { isAssertClassNew } from "./assert-instances.js";
|
|
36
|
+
import { isCjsRequireGlobal } from "./lower-node-module.js";
|
|
25
37
|
import { lowerArrayConstructor } from "./containers/array-construction.js";
|
|
26
38
|
import { lowerMapSeedNew, lowerSetSeedNew } from "./containers/collection-methods.js";
|
|
27
39
|
import { lowerObjectConstructor } from "./containers/indexed-objects.js";
|
|
28
|
-
import {
|
|
40
|
+
import { knownBufEncoding, lowerNodeModulesBufferConstruct } from "./containers/bytes.js";
|
|
29
41
|
import { isSafeToRepeat } from "./expressions/evaluation-safety.js";
|
|
30
42
|
import { lowerSearchParamsNew } from "./builtins/url.js";
|
|
31
43
|
import { lowerTextCodecNew } from "./builtins/text-codecs.js";
|
|
32
|
-
import { lowerMessageChannelNew, lowerWorkerNew } from "./builtins/workers.js";
|
|
44
|
+
import { lowerBroadcastChannelNew, lowerMessageChannelNew, lowerWorkerNew, } from "./builtins/workers.js";
|
|
33
45
|
import { unsupportedPackageValueDiag, unsupportedDiag, } from "../../diagnostics/diagnostic.js";
|
|
34
|
-
import { STREAM_API_MEMBERS, STREAM_PROP_MEMBERS, UNDERSCORE_METHODS, lowerStreamNew, lowerStreamSuperCall, streamCtorShape, } from "./lower-stream.js";
|
|
46
|
+
import { STREAM_API_MEMBERS, STREAM_PROP_MEMBERS, STREAM_COMPLETION_CALLBACK_INDEX, UNDERSCORE_METHODS, lowerStreamNew, lowerStreamSuperCall, streamCtorShape, } from "./lower-stream.js";
|
|
35
47
|
import { builtinEventTargetBaseOf, eventTargetApiMembers, eventTargetApiMethod, eventTargetRootOf, eventTargetSuperCall, lowerEventTargetMethodCall, } from "./lower-event-target.js";
|
|
36
48
|
import { emitOverrideShapeReason, emitSpecSuperForward, emitterRooted, lowerEmitterSuperCall, } from "./lower-event-emitter.js";
|
|
37
49
|
import { declSymbolOf } from "./lower-modules.js";
|
|
38
50
|
import { classSymbolKeyOf, classSymbolKeyOfSymbol, symbolFieldDisplayName, } from "./symbol-fields.js";
|
|
39
51
|
import { lowerHttpAgentNew, lowerHttpServerNew } from "./lower-server.js";
|
|
40
|
-
import { ambientNsRootOf, ambientUndefReadType, ambientUndefVarRootOf, ambientUndefinedFnSymbolOf, fenceEarlyAliasUse, fenceEarlyNsMemberRef, nsMemberIdentOf, nsUndefRead, } from "./lower-namespaces.js";
|
|
52
|
+
import { ambientNsRootOf, ambientUndefReadType, ambientUndefVarRootOf, ambientUndefinedFnSymbolOf, contextualUndefReadType, fenceEarlyAliasUse, fenceEarlyNsMemberRef, nsMemberIdentOf, nsUndefRead, } from "./lower-namespaces.js";
|
|
41
53
|
import { mixinResultBindingClassOf } from "./lower-mixins.js";
|
|
42
54
|
import { hasLexicalPrivateReference, hasStaticThis, rejectStaticThis } from "./static-this.js";
|
|
43
55
|
import { lowerUrlNew } from "./lower-url.js";
|
|
44
56
|
import { isNativeProxyInitializer, lowerNativeProxy } from "./expressions/native-proxy.js";
|
|
45
57
|
import { classStaticDataFor } from "./class-static-data.js";
|
|
58
|
+
import { construction, constructionPrefix } from "./js-class-fields.js";
|
|
46
59
|
import { lowerObjectFactoryNew } from "./object-factory-new.js";
|
|
47
60
|
import { tryLowerExpression } from "./expressions/try-lower-expression.js";
|
|
48
61
|
import { lowerInstanceConstructorNew } from "./class-instance-constructor.js";
|
|
@@ -53,7 +66,7 @@ import { initializeRuntimeStatics, hasRuntimeStatics } from "./class-runtime-sta
|
|
|
53
66
|
import { reflectedClassStaticMethodValue } from "./class-method-values.js";
|
|
54
67
|
export function returnsOnlyThis(member) {
|
|
55
68
|
const body = member.body;
|
|
56
|
-
const last = body?.statements.at(-1);
|
|
69
|
+
const last = body?.statements?.nodes.at(-1);
|
|
57
70
|
if (!body || !last || !ts.isReturnStatement(last))
|
|
58
71
|
return false;
|
|
59
72
|
let valid = true;
|
|
@@ -67,9 +80,43 @@ export function returnsOnlyThis(member) {
|
|
|
67
80
|
if (!value || value.kind !== ts.SyntaxKind.ThisKeyword)
|
|
68
81
|
valid = false;
|
|
69
82
|
}
|
|
70
|
-
|
|
83
|
+
ts.forEachChild(node, visit);
|
|
71
84
|
};
|
|
72
|
-
|
|
85
|
+
ts.forEachChild(body, visit);
|
|
86
|
+
return valid;
|
|
87
|
+
}
|
|
88
|
+
/** returnsOnlyThis, also accepting a comma expression whose last operand
|
|
89
|
+
* is `this` (the minifier's `return a(), this.x = v, this`, jose's fluent
|
|
90
|
+
* claim setters). Used only to narrow a call's result back to the
|
|
91
|
+
* receiver's class. */
|
|
92
|
+
export function returnsOnlyThisValue(member) {
|
|
93
|
+
const body = member.body;
|
|
94
|
+
const last = body?.statements?.nodes.at(-1);
|
|
95
|
+
if (!body || !last || !ts.isReturnStatement(last))
|
|
96
|
+
return false;
|
|
97
|
+
let valid = true;
|
|
98
|
+
const visit = (node) => {
|
|
99
|
+
if (ts.isFunctionLike(node))
|
|
100
|
+
return;
|
|
101
|
+
if (ts.isReturnStatement(node)) {
|
|
102
|
+
let value = node.expression;
|
|
103
|
+
for (;;) {
|
|
104
|
+
while (value && ts.isParenthesizedExpression(value))
|
|
105
|
+
value = value.expression;
|
|
106
|
+
if (value &&
|
|
107
|
+
ts.isBinaryExpression(value) &&
|
|
108
|
+
value.operatorToken.kind === ts.SyntaxKind.CommaToken) {
|
|
109
|
+
value = value.right;
|
|
110
|
+
continue;
|
|
111
|
+
}
|
|
112
|
+
break;
|
|
113
|
+
}
|
|
114
|
+
if (!value || value.kind !== ts.SyntaxKind.ThisKeyword)
|
|
115
|
+
valid = false;
|
|
116
|
+
}
|
|
117
|
+
ts.forEachChild(node, visit);
|
|
118
|
+
};
|
|
119
|
+
ts.forEachChild(body, visit);
|
|
73
120
|
return valid;
|
|
74
121
|
}
|
|
75
122
|
function functionLocalClass(decl) {
|
|
@@ -107,9 +154,7 @@ export function storedClassValueType(lowerer, expression, visiting = new Set())
|
|
|
107
154
|
return stored.type;
|
|
108
155
|
const symbol = lowerer.resolveValueSymbol(expression);
|
|
109
156
|
const declaration = symbol &&
|
|
110
|
-
|
|
111
|
-
.declarationsOf(symbol)
|
|
112
|
-
.find((decl) => ts.isVariableDeclaration(decl) &&
|
|
157
|
+
symbol.declarations.find((decl) => ts.isVariableDeclaration(decl) &&
|
|
113
158
|
decl.initializer &&
|
|
114
159
|
(ts.getCombinedNodeFlags(decl) & ts.NodeFlags.Const) !== 0);
|
|
115
160
|
if (declaration && ts.isVariableDeclaration(declaration) && declaration.initializer) {
|
|
@@ -118,11 +163,17 @@ export function storedClassValueType(lowerer, expression, visiting = new Set())
|
|
|
118
163
|
return value;
|
|
119
164
|
}
|
|
120
165
|
}
|
|
166
|
+
// A generic factory's own local class has one class per instance.
|
|
167
|
+
if (ts.isCallExpression(expression)) {
|
|
168
|
+
const local = genericLocalClassResult(lowerer, expression);
|
|
169
|
+
if (local?.kind === "classval")
|
|
170
|
+
return local;
|
|
171
|
+
}
|
|
121
172
|
const type = lowerer.typeOf(expression);
|
|
122
173
|
const mapped = lowerer.mapTypeOf(type);
|
|
123
174
|
if (mapped?.kind === "classval" && !lowerer.classes.has(mapped.className)) {
|
|
124
175
|
for (const signature of lowerer.checker.getConstructSignatures(type)) {
|
|
125
|
-
const constructor =
|
|
176
|
+
const constructor = signature.declaration;
|
|
126
177
|
const declaration = constructor && ts.isConstructorDeclaration(constructor) ? constructor.parent : undefined;
|
|
127
178
|
if (declaration &&
|
|
128
179
|
ts.isClassExpression(declaration) &&
|
|
@@ -161,9 +212,7 @@ export function storedClassValueType(lowerer, expression, visiting = new Set())
|
|
|
161
212
|
if (ts.isIdentifier(callee)) {
|
|
162
213
|
const symbol = lowerer.resolveValueSymbol(callee);
|
|
163
214
|
const declaration = symbol &&
|
|
164
|
-
|
|
165
|
-
.declarationsOf(symbol)
|
|
166
|
-
.find((decl) => ts.isVariableDeclaration(decl) &&
|
|
215
|
+
symbol.declarations.find((decl) => ts.isVariableDeclaration(decl) &&
|
|
167
216
|
decl.initializer &&
|
|
168
217
|
(ts.getCombinedNodeFlags(decl) & ts.NodeFlags.Const) !== 0);
|
|
169
218
|
if (declaration && ts.isVariableDeclaration(declaration) && declaration.initializer) {
|
|
@@ -174,8 +223,8 @@ export function storedClassValueType(lowerer, expression, visiting = new Set())
|
|
|
174
223
|
break;
|
|
175
224
|
}
|
|
176
225
|
if ((ts.isArrowFunction(callee) || ts.isFunctionExpression(callee)) &&
|
|
177
|
-
isJsSourceFile(
|
|
178
|
-
!callee.typeParameters?.length &&
|
|
226
|
+
isJsSourceFile(ts.getSourceFileOfNode(callee)) &&
|
|
227
|
+
!callee.typeParameters?.nodes.length &&
|
|
179
228
|
!lowerer.preparingClassFactories.has(callee)) {
|
|
180
229
|
const signature = lowerer.checker.getSignatureFromDeclaration(callee);
|
|
181
230
|
let result = signature && lowerer.checker.getReturnTypeOfSignature(signature);
|
|
@@ -227,7 +276,7 @@ export function storedClassValueType(lowerer, expression, visiting = new Set())
|
|
|
227
276
|
// Cache the module-level closure so its captures and lifted bodies are
|
|
228
277
|
// exactly the ones used when the declaration executes.
|
|
229
278
|
for (const signature of lowerer.checker.getConstructSignatures(type)) {
|
|
230
|
-
const declaration =
|
|
279
|
+
const declaration = signature.declaration;
|
|
231
280
|
const cls = declaration && ts.isConstructorDeclaration(declaration) ? declaration.parent : null;
|
|
232
281
|
if (!cls || (!ts.isClassExpression(cls) && !ts.isClassDeclaration(cls)))
|
|
233
282
|
continue;
|
|
@@ -241,8 +290,8 @@ export function storedClassValueType(lowerer, expression, visiting = new Set())
|
|
|
241
290
|
}
|
|
242
291
|
}
|
|
243
292
|
if (!factory ||
|
|
244
|
-
!isJsSourceFile(
|
|
245
|
-
factory.typeParameters?.length ||
|
|
293
|
+
!isJsSourceFile(ts.getSourceFileOfNode(factory)) ||
|
|
294
|
+
factory.typeParameters?.nodes.length ||
|
|
246
295
|
!ts.isVariableDeclaration(factory.parent) ||
|
|
247
296
|
factory.parent.initializer !== factory ||
|
|
248
297
|
!ts.isVariableDeclarationList(factory.parent.parent) ||
|
|
@@ -277,7 +326,7 @@ export function storedClassValueType(lowerer, expression, visiting = new Set())
|
|
|
277
326
|
* or the ElementAccessExpression itself). Null when no declaration has
|
|
278
327
|
* that shape (well-known-symbol members like `[Symbol.iterator]`). */
|
|
279
328
|
function lateBoundKeySymOf(lowerer, p) {
|
|
280
|
-
for (const d of
|
|
329
|
+
for (const d of p.declarations) {
|
|
281
330
|
const access = ts.isBinaryExpression(d) && ts.isElementAccessExpression(d.left)
|
|
282
331
|
? d.left
|
|
283
332
|
: ts.isElementAccessExpression(d)
|
|
@@ -311,13 +360,13 @@ function symbolSlotReturnType(lowerer, fnLike, symbolFields, fields) {
|
|
|
311
360
|
return null;
|
|
312
361
|
if (fnLike.type !== undefined || !fnLike.body)
|
|
313
362
|
return null;
|
|
314
|
-
if (!isJsSourceFile(
|
|
363
|
+
if (!isJsSourceFile(ts.getSourceFileOfNode(fnLike)))
|
|
315
364
|
return null;
|
|
316
365
|
if (fnLike.asteriskToken !== undefined)
|
|
317
366
|
return null;
|
|
318
|
-
if (fnLike.modifiers?.some((m) => m.kind === ts.SyntaxKind.AsyncKeyword))
|
|
367
|
+
if (fnLike.modifiers?.nodes.some((m) => m.kind === ts.SyntaxKind.AsyncKeyword))
|
|
319
368
|
return null;
|
|
320
|
-
const stmts = fnLike.body.statements;
|
|
369
|
+
const stmts = fnLike.body.statements.nodes;
|
|
321
370
|
const last = stmts[stmts.length - 1];
|
|
322
371
|
if (!last || !ts.isReturnStatement(last))
|
|
323
372
|
return null;
|
|
@@ -327,9 +376,9 @@ function symbolSlotReturnType(lowerer, fnLike, symbolFields, fields) {
|
|
|
327
376
|
return;
|
|
328
377
|
if (ts.isReturnStatement(n))
|
|
329
378
|
returns.push(n);
|
|
330
|
-
|
|
379
|
+
ts.forEachChild(n, visit);
|
|
331
380
|
};
|
|
332
|
-
fnLike.body
|
|
381
|
+
ts.forEachChild(fnLike.body, visit);
|
|
333
382
|
let out = null;
|
|
334
383
|
for (const r of returns) {
|
|
335
384
|
let e = r.expression;
|
|
@@ -350,6 +399,16 @@ function symbolSlotReturnType(lowerer, fnLike, symbolFields, fields) {
|
|
|
350
399
|
}
|
|
351
400
|
return out;
|
|
352
401
|
}
|
|
402
|
+
/** The error classes whose values construct through error.newOptions. */
|
|
403
|
+
const ERROR_CLASS_VALUES = new Set([
|
|
404
|
+
"%Error",
|
|
405
|
+
"%TypeError",
|
|
406
|
+
"%RangeError",
|
|
407
|
+
"%SyntaxError",
|
|
408
|
+
"%ReferenceError",
|
|
409
|
+
"%EvalError",
|
|
410
|
+
"%URIError",
|
|
411
|
+
]);
|
|
353
412
|
/** The builtin Error hierarchy
|
|
354
413
|
* as eagerly-registered ClassInfos: mapType names them the moment a lib
|
|
355
414
|
* Error type appears, so the infos must exist before any lowering. They
|
|
@@ -418,6 +477,17 @@ export function registerBuiltinErrorClasses(lowerer) {
|
|
|
418
477
|
{ type: DYN, mode: "omittable" },
|
|
419
478
|
{ type: DYN, mode: "omittable" },
|
|
420
479
|
],
|
|
480
|
+
// The ECMAScript error constructors take (message?, options?);
|
|
481
|
+
// DOMException, AggregateError, AssertionError and SuppressedError
|
|
482
|
+
// have their own construction and are not values.
|
|
483
|
+
...(ERROR_CLASS_VALUES.has(irName)
|
|
484
|
+
? {
|
|
485
|
+
valueCtorParams: [
|
|
486
|
+
{ type: DYN, mode: "omittable" },
|
|
487
|
+
{ type: DYN, mode: "omittable" },
|
|
488
|
+
],
|
|
489
|
+
}
|
|
490
|
+
: {}),
|
|
421
491
|
base,
|
|
422
492
|
subclasses: [],
|
|
423
493
|
throwingSetters: [],
|
|
@@ -450,6 +520,7 @@ export function registerBuiltinEmitterClass(lowerer) {
|
|
|
450
520
|
// `new EventEmitter()` — zero-argument (the options bag fences at
|
|
451
521
|
// construction sites; the checker may admit it via @types/node).
|
|
452
522
|
ctorParams: [],
|
|
523
|
+
valueCtorParams: [],
|
|
453
524
|
base: null,
|
|
454
525
|
subclasses: [],
|
|
455
526
|
throwingSetters: [],
|
|
@@ -457,6 +528,22 @@ export function registerBuiltinEmitterClass(lowerer) {
|
|
|
457
528
|
};
|
|
458
529
|
lowerer.classes.set(RUNTIME_EMITTER_CLASS, info);
|
|
459
530
|
}
|
|
531
|
+
/** `class Bus extends require("events") {}` in a CommonJS module: the
|
|
532
|
+
* events module is the EventEmitter class itself, so the base is the
|
|
533
|
+
* runtime emitter, exactly as through a `require("events")` binding. */
|
|
534
|
+
export function builtinRequireBaseOf(lowerer, node) {
|
|
535
|
+
let expr = node;
|
|
536
|
+
while (ts.isParenthesizedExpression(expr))
|
|
537
|
+
expr = expr.expression;
|
|
538
|
+
if (!ts.isCallExpression(expr) || !isJsSourceFile(expr.getSourceFile()))
|
|
539
|
+
return null;
|
|
540
|
+
const spec = requireSpecOf(expr);
|
|
541
|
+
if (spec === null || canonicalBuiltinModule(spec) !== "events")
|
|
542
|
+
return null;
|
|
543
|
+
if (!isCjsRequireGlobal(lowerer, expr.expression))
|
|
544
|
+
return null;
|
|
545
|
+
return lowerer.classes.get(RUNTIME_EMITTER_CLASS) ?? null;
|
|
546
|
+
}
|
|
460
547
|
/** The runtime-provided node:stream classes as eagerly-registered
|
|
461
548
|
* ClassInfos (the emitter story): mapType names `%Readable` et al the
|
|
462
549
|
* moment a stream type appears, so the infos must exist before any
|
|
@@ -480,6 +567,9 @@ export function registerBuiltinStreamClasses(lowerer) {
|
|
|
480
567
|
// `new Readable(opts?)` — the options bag is parsed structurally
|
|
481
568
|
// by the stream spoke (lowerNew never completes against this).
|
|
482
569
|
ctorParams: [],
|
|
570
|
+
// Construction through a class value builds the stream without
|
|
571
|
+
// options (lowerNew reports options passed through a value).
|
|
572
|
+
valueCtorParams: [],
|
|
483
573
|
base,
|
|
484
574
|
subclasses: [],
|
|
485
575
|
throwingSetters: [],
|
|
@@ -496,10 +586,14 @@ export function registerBuiltinStreamClasses(lowerer) {
|
|
|
496
586
|
* "stream" ambient module, EXCLUDING @types/node's (whose stream.Readable
|
|
497
587
|
* also types child stdio — under @types/node the childStream mapping
|
|
498
588
|
* keeps priority and the static stream classes stand down; the shipped
|
|
499
|
-
* fallback declarations are the supported surface).
|
|
589
|
+
* fallback declarations are the supported surface). A const binding of
|
|
590
|
+
* one (`const R = Readable`) names the same class (builtinClassAliasOf). */
|
|
500
591
|
export function builtinStreamInfoOf(lowerer, symbol) {
|
|
501
592
|
if (!symbol)
|
|
502
593
|
return null;
|
|
594
|
+
const alias = builtinClassAliasOf(lowerer, symbol);
|
|
595
|
+
if (alias !== null)
|
|
596
|
+
return alias.kind === "stream" ? alias.info : null;
|
|
503
597
|
if (!lowerer.isStdlibSymbol(symbol)) {
|
|
504
598
|
// A const ALIAS of a namespace member (`const Writable =
|
|
505
599
|
// stream.Writable` — the two-step spelling; the one-step
|
|
@@ -507,10 +601,15 @@ export function builtinStreamInfoOf(lowerer, symbol) {
|
|
|
507
601
|
// member to the stdlib class symbol. The declaration itself is
|
|
508
602
|
// alias plumbing (streamClassAliasDecl — both declaration walks
|
|
509
603
|
// skip it).
|
|
510
|
-
|
|
604
|
+
// A `var`/`let` binding of the inline require member
|
|
605
|
+
// (`var Transform = require("stream").Transform`) is the same alias
|
|
606
|
+
// plumbing as builtinMemberRequireDecl's: its declaration owns no
|
|
607
|
+
// storage either way.
|
|
608
|
+
const decl = symbol.valueDeclaration;
|
|
511
609
|
if (decl &&
|
|
512
610
|
ts.isVariableDeclaration(decl) &&
|
|
513
|
-
(ts.getCombinedNodeFlags(decl) & ts.NodeFlags.Const) !== 0
|
|
611
|
+
((ts.getCombinedNodeFlags(decl) & ts.NodeFlags.Const) !== 0 ||
|
|
612
|
+
builtinMemberRequireDecl(decl.name, decl.initializer)) &&
|
|
514
613
|
decl.initializer !== undefined &&
|
|
515
614
|
ts.isPropertyAccessExpression(decl.initializer) &&
|
|
516
615
|
!decl.initializer.questionDotToken &&
|
|
@@ -524,16 +623,17 @@ export function builtinStreamInfoOf(lowerer, symbol) {
|
|
|
524
623
|
}
|
|
525
624
|
let irName = null;
|
|
526
625
|
for (const [name, rec] of RUNTIME_STREAM_CLASSES) {
|
|
527
|
-
if (rec.lib === symbol
|
|
626
|
+
if (rec.lib === ts.symbolName(symbol))
|
|
528
627
|
irName = name;
|
|
529
628
|
}
|
|
530
629
|
if (!irName)
|
|
531
630
|
return null;
|
|
532
|
-
|
|
631
|
+
// Both the bundled declarations and @types/node declare the classes
|
|
632
|
+
// inside `declare module "stream"` (@types/node nests them in the module's
|
|
633
|
+
// `internal` namespace).
|
|
634
|
+
const declared = symbol.declarations.some((d) => {
|
|
533
635
|
if (!ts.isClassDeclaration(d))
|
|
534
636
|
return false;
|
|
535
|
-
if (isNodeTypesPath(d.getSourceFile().fileName))
|
|
536
|
-
return false;
|
|
537
637
|
let node = d.parent;
|
|
538
638
|
while (node) {
|
|
539
639
|
if (ts.isModuleDeclaration(node) && ts.isStringLiteral(node.name)) {
|
|
@@ -551,10 +651,9 @@ function jsFieldInitializerType(lowerer, type, expression) {
|
|
|
551
651
|
if (ts.isIdentifier(expression)) {
|
|
552
652
|
const symbol = lowerer.checker.getSymbolAtLocation(expression);
|
|
553
653
|
if (symbol &&
|
|
554
|
-
|
|
555
|
-
.
|
|
556
|
-
|
|
557
|
-
(ts.isConstructorDeclaration(decl.parent) ||
|
|
654
|
+
symbol.declarations.some((decl) => ts.isParameter(decl) &&
|
|
655
|
+
((ts.isConstructorDeclaration(decl.parent) &&
|
|
656
|
+
!checkedJsDocumentedParameter(lowerer, decl)) ||
|
|
558
657
|
(lowerer.typeOf(expression).flags & (ts.TypeFlags.Any | ts.TypeFlags.Unknown)) !== 0)))
|
|
559
658
|
return DYN;
|
|
560
659
|
}
|
|
@@ -563,7 +662,7 @@ function jsFieldInitializerType(lowerer, type, expression) {
|
|
|
563
662
|
// JavaScript documentation cannot guarantee that a call or an indexed
|
|
564
663
|
// read returns a present number. Numeric fields receiving those values
|
|
565
664
|
// must retain undefined, so later arithmetic performs JS coercion (NaN).
|
|
566
|
-
if (type.kind === "f64" && isJsSourceFile(
|
|
665
|
+
if (type.kind === "f64" && isJsSourceFile(ts.getSourceFileOfNode(expression))) {
|
|
567
666
|
const assignment = expression.parent;
|
|
568
667
|
const left = ts.isBinaryExpression(assignment) ? assignment.left : null;
|
|
569
668
|
const field = left &&
|
|
@@ -591,7 +690,7 @@ function jsFieldInitializerType(lowerer, type, expression) {
|
|
|
591
690
|
if (ts.isCallExpression(rhs) || ts.isElementAccessExpression(rhs))
|
|
592
691
|
acceptsUnchecked = true;
|
|
593
692
|
}
|
|
594
|
-
|
|
693
|
+
ts.forEachChild(node, scan);
|
|
595
694
|
};
|
|
596
695
|
scan(owner);
|
|
597
696
|
if (acceptsUnchecked)
|
|
@@ -603,14 +702,14 @@ function jsFieldInitializerType(lowerer, type, expression) {
|
|
|
603
702
|
node = node.expression;
|
|
604
703
|
if (ts.isCallExpression(node) && type.kind === "bytes") {
|
|
605
704
|
let prototypeArgument = false;
|
|
606
|
-
for (const argument of node.arguments)
|
|
705
|
+
for (const argument of node.arguments.nodes)
|
|
607
706
|
ts.walkPreorder(argument, (part) => {
|
|
608
707
|
if (!ts.isPropertyAccessExpression(part) ||
|
|
609
708
|
part.expression.kind !== ts.SyntaxKind.ThisKeyword)
|
|
610
709
|
return;
|
|
611
710
|
const symbol = lowerer.checker.getSymbolAtLocation(part.name);
|
|
612
711
|
if (symbol &&
|
|
613
|
-
|
|
712
|
+
symbol.declarations.some((decl) => {
|
|
614
713
|
const member = ts.isBinaryExpression(decl) ? decl.left : decl;
|
|
615
714
|
return (ts.isPropertyAccessExpression(member) &&
|
|
616
715
|
ts.isPropertyAccessExpression(member.expression) &&
|
|
@@ -624,7 +723,7 @@ function jsFieldInitializerType(lowerer, type, expression) {
|
|
|
624
723
|
owner = owner.parent;
|
|
625
724
|
if (owner && (ts.isClassDeclaration(owner) || ts.isClassExpression(owner)) && owner.name) {
|
|
626
725
|
const className = owner.name.text;
|
|
627
|
-
for (const statement of
|
|
726
|
+
for (const statement of ts.getSourceFileOfNode(owner).statements.nodes) {
|
|
628
727
|
if (!ts.isExpressionStatement(statement) ||
|
|
629
728
|
!ts.isBinaryExpression(statement.expression))
|
|
630
729
|
continue;
|
|
@@ -702,7 +801,7 @@ function inheritedJsFieldType(lowerer, decl, name, type) {
|
|
|
702
801
|
return type;
|
|
703
802
|
}
|
|
704
803
|
function returnsWidenedJsField(lowerer, decl, member, fields, ret) {
|
|
705
|
-
if (!isJsSourceFile(
|
|
804
|
+
if (!isJsSourceFile(ts.getSourceFileOfNode(member)) ||
|
|
706
805
|
member.type ||
|
|
707
806
|
member.asteriskToken ||
|
|
708
807
|
hasExplicitJsDocReturn(member))
|
|
@@ -720,10 +819,7 @@ function returnsWidenedJsField(lowerer, decl, member, fields, ret) {
|
|
|
720
819
|
? lowerer.checker.getPropertyOfType(lowerer.typeOf(callee.expression), lowerer.foldedStringKeyOf(callee.argumentExpression) ?? "")
|
|
721
820
|
: undefined;
|
|
722
821
|
if (symbol &&
|
|
723
|
-
lowerer.
|
|
724
|
-
.declarationsOf(symbol)
|
|
725
|
-
.some((declaration) => ts.isMethodDeclaration(declaration) &&
|
|
726
|
-
lowerer.checkedVirtualJsMethods.has(declaration)))
|
|
822
|
+
symbol.declarations.some((declaration) => ts.isMethodDeclaration(declaration) && lowerer.checkedVirtualJsMethods.has(declaration)))
|
|
727
823
|
return true;
|
|
728
824
|
}
|
|
729
825
|
const name = ts.isPropertyAccessExpression(expression)
|
|
@@ -734,9 +830,7 @@ function returnsWidenedJsField(lowerer, decl, member, fields, ret) {
|
|
|
734
830
|
if (ts.isPropertyAccessExpression(expression)) {
|
|
735
831
|
const symbol = lowerer.checker.getSymbolAtLocation(expression.name);
|
|
736
832
|
if (symbol &&
|
|
737
|
-
|
|
738
|
-
.declarationsOf(symbol)
|
|
739
|
-
.some((declaration) => (ts.isGetAccessorDeclaration(declaration) ||
|
|
833
|
+
symbol.declarations.some((declaration) => (ts.isGetAccessorDeclaration(declaration) ||
|
|
740
834
|
ts.isSetAccessorDeclaration(declaration)) &&
|
|
741
835
|
lowerer.checkedVirtualJsAccessors.has(declaration)))
|
|
742
836
|
return true;
|
|
@@ -755,7 +849,7 @@ function returnsWidenedJsField(lowerer, decl, member, fields, ret) {
|
|
|
755
849
|
return;
|
|
756
850
|
if (ts.isReturnStatement(node) && node.expression && widened(node.expression))
|
|
757
851
|
result = true;
|
|
758
|
-
|
|
852
|
+
ts.forEachChild(node, scan);
|
|
759
853
|
};
|
|
760
854
|
if (member.body)
|
|
761
855
|
scan(member.body);
|
|
@@ -768,13 +862,13 @@ function returnsWidenedJsField(lowerer, decl, member, fields, ret) {
|
|
|
768
862
|
* (genResultRecord's list, including scalar-backed Date values). */
|
|
769
863
|
function undefArmedFieldType(lowerer, p) {
|
|
770
864
|
const t = lowerer.checker.getTypeOfSymbol(p);
|
|
771
|
-
const site =
|
|
865
|
+
const site = p.declarations[0];
|
|
772
866
|
let mapped = lowerer.mapTypeOf(t) ?? (site ? dynFallbackType(lowerer, site, t) : null);
|
|
773
867
|
if (mapped && site)
|
|
774
868
|
mapped = jsOpenObjectType(site, mapped, lowerer.shapes, lowerer.unions);
|
|
775
869
|
if (!mapped || mapped.kind === "void")
|
|
776
870
|
return null;
|
|
777
|
-
for (const declaration of
|
|
871
|
+
for (const declaration of p.declarations) {
|
|
778
872
|
const assignment = ts.isBinaryExpression(declaration) ? declaration : declaration.parent;
|
|
779
873
|
if (assignment &&
|
|
780
874
|
ts.isBinaryExpression(assignment) &&
|
|
@@ -801,10 +895,15 @@ function undefArmedFieldType(lowerer, p) {
|
|
|
801
895
|
* `extends EventEmitter`, `x instanceof EventEmitter`) — any import
|
|
802
896
|
* spelling (named/default/namespace member, CJS require) resolves to
|
|
803
897
|
* the ambient class. Provenance-checked like the error classes: only a
|
|
804
|
-
* stdlib-file declaration inside the "events" ambient module counts.
|
|
898
|
+
* stdlib-file declaration inside the "events" ambient module counts. A
|
|
899
|
+
* const binding of it (`const E = EventEmitter`) names the same class
|
|
900
|
+
* (builtinClassAliasOf). */
|
|
805
901
|
export function builtinEmitterInfoOf(lowerer, symbol) {
|
|
806
902
|
if (!symbol)
|
|
807
903
|
return null;
|
|
904
|
+
const alias = builtinClassAliasOf(lowerer, symbol);
|
|
905
|
+
if (alias !== null)
|
|
906
|
+
return alias.kind === "emitter" ? alias.info : null;
|
|
808
907
|
if (!lowerer.isStdlibSymbol(symbol)) {
|
|
809
908
|
// A const ALIAS of the emitter class member (`const EventEmitter =
|
|
810
909
|
// require('node:events').EventEmitter` — commander's spelling; the
|
|
@@ -812,10 +911,11 @@ export function builtinEmitterInfoOf(lowerer, symbol) {
|
|
|
812
911
|
// follow the member off the module namespace. The declaration
|
|
813
912
|
// itself is alias plumbing (builtinMemberRequireDecl — both
|
|
814
913
|
// declaration walks skip it).
|
|
815
|
-
const decl =
|
|
914
|
+
const decl = symbol.valueDeclaration;
|
|
816
915
|
if (decl !== undefined &&
|
|
817
916
|
ts.isVariableDeclaration(decl) &&
|
|
818
|
-
(ts.getCombinedNodeFlags(decl) & ts.NodeFlags.Const) !== 0
|
|
917
|
+
((ts.getCombinedNodeFlags(decl) & ts.NodeFlags.Const) !== 0 ||
|
|
918
|
+
builtinMemberRequireDecl(decl.name, decl.initializer)) &&
|
|
819
919
|
decl.initializer !== undefined &&
|
|
820
920
|
ts.isPropertyAccessExpression(decl.initializer) &&
|
|
821
921
|
!decl.initializer.questionDotToken &&
|
|
@@ -825,9 +925,9 @@ export function builtinEmitterInfoOf(lowerer, symbol) {
|
|
|
825
925
|
}
|
|
826
926
|
return null;
|
|
827
927
|
}
|
|
828
|
-
if (symbol
|
|
928
|
+
if (ts.symbolName(symbol) !== "EventEmitter")
|
|
829
929
|
return null;
|
|
830
|
-
const declared =
|
|
930
|
+
const declared = symbol.declarations.some((d) => {
|
|
831
931
|
if (!ts.isClassDeclaration(d) && !ts.isInterfaceDeclaration(d))
|
|
832
932
|
return false;
|
|
833
933
|
let node = d.parent;
|
|
@@ -844,12 +944,19 @@ export function builtinEmitterInfoOf(lowerer, symbol) {
|
|
|
844
944
|
/** The builtin error ClassInfo a VALUE symbol refers to (`new Error`,
|
|
845
945
|
* `extends TypeError`, `x instanceof RangeError`), or null. Provenance-
|
|
846
946
|
* checked: only the standard library's declarations count — a user's own
|
|
847
|
-
* `class Error` resolves through classBySymbol instead.
|
|
947
|
+
* `class Error` resolves through classBySymbol instead. A const binding
|
|
948
|
+
* of one (`const E = TypeError`) names the same class
|
|
949
|
+
* (builtinClassAliasOf). */
|
|
848
950
|
export function builtinErrorInfoOf(lowerer, symbol) {
|
|
849
|
-
if (!symbol
|
|
951
|
+
if (!symbol)
|
|
952
|
+
return null;
|
|
953
|
+
const alias = builtinClassAliasOf(lowerer, symbol);
|
|
954
|
+
if (alias !== null)
|
|
955
|
+
return alias.kind === "error" ? alias.info : null;
|
|
956
|
+
if (!lowerer.isStdlibSymbol(symbol))
|
|
850
957
|
return null;
|
|
851
958
|
for (const [irName, rec] of RUNTIME_ERROR_CLASSES) {
|
|
852
|
-
if (rec.lib === symbol
|
|
959
|
+
if (rec.lib === ts.symbolName(symbol))
|
|
853
960
|
return lowerer.classes.get(irName) ?? null;
|
|
854
961
|
}
|
|
855
962
|
return null;
|
|
@@ -877,7 +984,7 @@ export const EMITTER_API_MEMBERS = new Set([
|
|
|
877
984
|
/** The decorators of a class-like or member node (they live in
|
|
878
985
|
* `modifiers` since TS 4.8). */
|
|
879
986
|
export function decoratorNodesOf(n) {
|
|
880
|
-
return (n.modifiers ?? []).filter((m) => m.kind === ts.SyntaxKind.Decorator);
|
|
987
|
+
return (n.modifiers?.nodes ?? []).filter((m) => m.kind === ts.SyntaxKind.Decorator);
|
|
881
988
|
}
|
|
882
989
|
/** The AMBIENT name a decorator expression's evaluation throws on, or
|
|
883
990
|
* null. Node erases ambient declarations (`declare let dec: any`,
|
|
@@ -936,14 +1043,14 @@ export function guaranteedDecorationThrow(lowerer, decl) {
|
|
|
936
1043
|
if (v !== "effectFree")
|
|
937
1044
|
return v;
|
|
938
1045
|
}
|
|
939
|
-
const heritage = decl.heritageClauses?.find((c) => c.token === ts.SyntaxKind.ExtendsKeyword)
|
|
940
|
-
?.types[0];
|
|
1046
|
+
const heritage = decl.heritageClauses?.nodes.find((c) => c.token === ts.SyntaxKind.ExtendsKeyword)
|
|
1047
|
+
?.types?.nodes[0];
|
|
941
1048
|
if (heritage) {
|
|
942
1049
|
const h = stripParens(heritage.expression);
|
|
943
1050
|
if (h.kind !== ts.SyntaxKind.NullKeyword && !ts.isIdentifier(h))
|
|
944
1051
|
return null;
|
|
945
1052
|
}
|
|
946
|
-
for (const member of decl.members) {
|
|
1053
|
+
for (const member of decl.members.nodes) {
|
|
947
1054
|
for (const d of decoratorNodesOf(member)) {
|
|
948
1055
|
const v = decoratorVerdict(d);
|
|
949
1056
|
if (v === "opaque")
|
|
@@ -978,17 +1085,17 @@ function collectClassShapeDeferring(lowerer, decl) {
|
|
|
978
1085
|
// A forward type reference can demand this class before collection
|
|
979
1086
|
// reaches its earlier base declaration. Collect that dependency first;
|
|
980
1087
|
// a later same-file base remains subject to the runtime order boundary.
|
|
981
|
-
const heritage = decl.heritageClauses?.find((clause) => clause.token === ts.SyntaxKind.ExtendsKeyword)?.types[0]?.expression;
|
|
1088
|
+
const heritage = decl.heritageClauses?.nodes.find((clause) => clause.token === ts.SyntaxKind.ExtendsKeyword)?.types?.nodes[0]?.expression;
|
|
982
1089
|
const reference = heritage && ts.isPropertyAccessExpression(heritage) ? heritage.name : heritage;
|
|
983
1090
|
const baseSymbol = reference && ts.isIdentifier(reference) ? lowerer.resolveValueSymbol(reference) : undefined;
|
|
984
1091
|
const baseDeclaration = baseSymbol
|
|
985
|
-
?
|
|
1092
|
+
? baseSymbol.declarations.find(ts.isClassDeclaration)
|
|
986
1093
|
: undefined;
|
|
987
1094
|
if (baseDeclaration &&
|
|
988
1095
|
!lowerer.isStdlibSymbol(baseSymbol ?? undefined) &&
|
|
989
|
-
!
|
|
990
|
-
(
|
|
991
|
-
|
|
1096
|
+
!ts.getSourceFileOfNode(baseDeclaration).isDeclarationFile &&
|
|
1097
|
+
(ts.getSourceFileOfNode(baseDeclaration) !== ts.getSourceFileOfNode(decl) ||
|
|
1098
|
+
ts.tokenStartOfNode(baseDeclaration) < ts.tokenStartOfNode(decl)))
|
|
992
1099
|
lowerer.collectClassShape(baseDeclaration);
|
|
993
1100
|
lowerer.collectClassShapeInner(decl);
|
|
994
1101
|
});
|
|
@@ -1003,8 +1110,8 @@ function collectClassShapeDeferring(lowerer, decl) {
|
|
|
1003
1110
|
// declaration without a diagnostic would drop observable side effects (the
|
|
1004
1111
|
// classStaticBlock13/28 miscompiles).
|
|
1005
1112
|
const hasDeclTimeCode = (n) => ts.isClassStaticBlockDeclaration(n) ||
|
|
1006
|
-
(n.modifiers ?? []).some((m) => m.kind === ts.SyntaxKind.Decorator);
|
|
1007
|
-
if (symbol && (hasDeclTimeCode(decl) || decl.members.some(hasDeclTimeCode))) {
|
|
1113
|
+
(n.modifiers?.nodes ?? []).some((m) => m.kind === ts.SyntaxKind.Decorator);
|
|
1114
|
+
if (symbol && (hasDeclTimeCode(decl) || decl.members.nodes.some(hasDeclTimeCode))) {
|
|
1008
1115
|
lowerer.reportDeferred(symbol);
|
|
1009
1116
|
}
|
|
1010
1117
|
// A poisoned BASE this class EXTENDS must report EAGERLY for the same
|
|
@@ -1018,9 +1125,9 @@ function collectClassShapeDeferring(lowerer, decl) {
|
|
|
1018
1125
|
// reports. Resolution runs under the collect pass's guard (this is
|
|
1019
1126
|
// collectProgram), so the lookup neither flushes nor fences.
|
|
1020
1127
|
{
|
|
1021
|
-
const baseIdent = decl.heritageClauses
|
|
1022
|
-
|
|
1023
|
-
?.types.map((t) => t.expression)
|
|
1128
|
+
const baseIdent = decl.heritageClauses?.nodes
|
|
1129
|
+
.find((h) => h.token === ts.SyntaxKind.ExtendsKeyword)
|
|
1130
|
+
?.types?.nodes.map((t) => t.expression)
|
|
1024
1131
|
.filter(ts.isIdentifier)[0];
|
|
1025
1132
|
const baseSym = baseIdent ? lowerer.resolveValueSymbol(baseIdent) : null;
|
|
1026
1133
|
if (baseSym)
|
|
@@ -1029,7 +1136,7 @@ function collectClassShapeDeferring(lowerer, decl) {
|
|
|
1029
1136
|
}
|
|
1030
1137
|
function inferredEmptyCollectionFieldType(lowerer, decl, field, initializer) {
|
|
1031
1138
|
if (!ts.isNewExpression(initializer) ||
|
|
1032
|
-
(initializer.arguments?.length ?? 0) !== 0 ||
|
|
1139
|
+
(initializer.arguments?.nodes.length ?? 0) !== 0 ||
|
|
1033
1140
|
!ts.isIdentifier(initializer.expression))
|
|
1034
1141
|
return null;
|
|
1035
1142
|
const collection = initializer.expression.text;
|
|
@@ -1044,7 +1151,12 @@ function inferredEmptyCollectionFieldType(lowerer, decl, field, initializer) {
|
|
|
1044
1151
|
const mappedArgument = (argument) => {
|
|
1045
1152
|
const type = lowerer.checker.getBaseTypeOfLiteralType(lowerer.typeOf(argument));
|
|
1046
1153
|
const mapped = lowerer.mapTypeOf(type);
|
|
1047
|
-
|
|
1154
|
+
// Inferred JS collection fields keep functions in checked slots.
|
|
1155
|
+
if (!mapped ||
|
|
1156
|
+
mapped.kind === "dyn" ||
|
|
1157
|
+
mapped.kind === "void" ||
|
|
1158
|
+
mapped.kind === "func" ||
|
|
1159
|
+
isUnitType(mapped))
|
|
1048
1160
|
return null;
|
|
1049
1161
|
return mapped;
|
|
1050
1162
|
};
|
|
@@ -1061,9 +1173,9 @@ function inferredEmptyCollectionFieldType(lowerer, decl, field, initializer) {
|
|
|
1061
1173
|
}
|
|
1062
1174
|
if (collection === "Map" &&
|
|
1063
1175
|
node.expression.name.text === "set" &&
|
|
1064
|
-
node.arguments.length === 2) {
|
|
1065
|
-
const key = mappedArgument(node.arguments[0]);
|
|
1066
|
-
const value = mappedArgument(node.arguments[1]);
|
|
1176
|
+
node.arguments.nodes.length === 2) {
|
|
1177
|
+
const key = mappedArgument(node.arguments.nodes[0]);
|
|
1178
|
+
const value = mappedArgument(node.arguments.nodes[1]);
|
|
1067
1179
|
if (key !== null &&
|
|
1068
1180
|
value !== null &&
|
|
1069
1181
|
isSupportedMapKey(key, key.kind === "union" ? lowerer.unions.get(key.unionId)?.arms : undefined) &&
|
|
@@ -1076,15 +1188,15 @@ function inferredEmptyCollectionFieldType(lowerer, decl, field, initializer) {
|
|
|
1076
1188
|
(node.expression.name.text === "add" ||
|
|
1077
1189
|
node.expression.name.text === "has" ||
|
|
1078
1190
|
node.expression.name.text === "delete") &&
|
|
1079
|
-
node.arguments.length === 1) {
|
|
1080
|
-
const element = mappedArgument(node.arguments[0]);
|
|
1191
|
+
node.arguments.nodes.length === 1) {
|
|
1192
|
+
const element = mappedArgument(node.arguments.nodes[0]);
|
|
1081
1193
|
if (element !== null &&
|
|
1082
1194
|
isSupportedSetElem(element, element.kind === "union" ? lowerer.unions.get(element.unionId)?.arms : undefined))
|
|
1083
1195
|
setElements.push(element);
|
|
1084
1196
|
}
|
|
1085
1197
|
return undefined;
|
|
1086
1198
|
};
|
|
1087
|
-
for (const member of decl.members) {
|
|
1199
|
+
for (const member of decl.members.nodes) {
|
|
1088
1200
|
const body = ts.isConstructorDeclaration(member) || ts.isMethodDeclaration(member) || ts.isAccessor(member)
|
|
1089
1201
|
? member.body
|
|
1090
1202
|
: undefined;
|
|
@@ -1136,13 +1248,13 @@ mixin) {
|
|
|
1136
1248
|
const classDecoratorNodes = [];
|
|
1137
1249
|
{
|
|
1138
1250
|
classDecoratorNodes.push(...decoratorNodesOf(decl));
|
|
1139
|
-
const decoratedMembers = decl.members.filter((m) => decoratorNodesOf(m).length > 0);
|
|
1251
|
+
const decoratedMembers = decl.members.nodes.filter((m) => decoratorNodesOf(m).length > 0);
|
|
1140
1252
|
if (classDecoratorNodes.length > 0 || decoratedMembers.length > 0) {
|
|
1141
1253
|
// Node itself cannot execute decorator syntax in a JavaScript
|
|
1142
1254
|
// source (V8 has not shipped the proposal; the type-stripping
|
|
1143
1255
|
// loaders leave `@dec` in place) — there is no runtime behavior
|
|
1144
1256
|
// to be exact against.
|
|
1145
|
-
if (isJsSourceFile(
|
|
1257
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(decl))) {
|
|
1146
1258
|
lowerer.unsupported("SC1090", (classDecoratorNodes[0] ?? decoratorNodesOf(decoratedMembers[0])[0]), "decorators in JavaScript sources (V8 has not shipped decorators — Node cannot execute this file)");
|
|
1147
1259
|
}
|
|
1148
1260
|
// The guaranteed-throw SHELL: declarations only (expressions
|
|
@@ -1197,7 +1309,7 @@ mixin) {
|
|
|
1197
1309
|
: ts.isGetAccessorDeclaration(member) || ts.isSetAccessorDeclaration(member)
|
|
1198
1310
|
? "accessor decorators"
|
|
1199
1311
|
: ts.isPropertyDeclaration(member)
|
|
1200
|
-
? member.modifiers?.some((m) => m.kind === ts.SyntaxKind.AccessorKeyword)
|
|
1312
|
+
? member.modifiers?.nodes.some((m) => m.kind === ts.SyntaxKind.AccessorKeyword)
|
|
1201
1313
|
? "auto-accessor decorators"
|
|
1202
1314
|
: "field decorators"
|
|
1203
1315
|
: "member decorators";
|
|
@@ -1259,9 +1371,9 @@ mixin) {
|
|
|
1259
1371
|
return true;
|
|
1260
1372
|
}
|
|
1261
1373
|
const signatures = lowerer.checker.getCallSignatures(lowerer.typeOf(expression));
|
|
1262
|
-
const source = signatures.length === 1 ?
|
|
1374
|
+
const source = signatures.length === 1 ? signatures[0].declaration : undefined;
|
|
1263
1375
|
if (!source ||
|
|
1264
|
-
!isJsSourceFile(
|
|
1376
|
+
!isJsSourceFile(ts.getSourceFileOfNode(source)) ||
|
|
1265
1377
|
!(ts.isFunctionDeclaration(source) || ts.isFunctionExpression(source)))
|
|
1266
1378
|
return false;
|
|
1267
1379
|
callableBase = {
|
|
@@ -1278,14 +1390,14 @@ mixin) {
|
|
|
1278
1390
|
if (!base || base.generic)
|
|
1279
1391
|
lowerer.unsupported("SC1090", ownGenericBase, "a generic base whose type arguments have no concrete layout");
|
|
1280
1392
|
}
|
|
1281
|
-
for (const clause of inst || mixin || computedBase ? [] : (decl.heritageClauses ?? [])) {
|
|
1393
|
+
for (const clause of inst || mixin || computedBase ? [] : (decl.heritageClauses?.nodes ?? [])) {
|
|
1282
1394
|
// `implements` is pure type-world: tsc checked the conformance and
|
|
1283
1395
|
// the clause erases — nothing about the runtime class changes.
|
|
1284
1396
|
// (Assigning an instance INTO an interface-typed slot is a separate
|
|
1285
1397
|
// question, owned by the shape-coercion fences at those sites.)
|
|
1286
1398
|
if (clause.token === ts.SyntaxKind.ImplementsKeyword)
|
|
1287
1399
|
continue;
|
|
1288
|
-
const t = clause.types[0];
|
|
1400
|
+
const t = clause.types.nodes[0];
|
|
1289
1401
|
if (familyMode && t) {
|
|
1290
1402
|
const reference = ts.isPropertyAccessExpression(t.expression)
|
|
1291
1403
|
? t.expression.name
|
|
@@ -1316,7 +1428,7 @@ mixin) {
|
|
|
1316
1428
|
if (globalError &&
|
|
1317
1429
|
globalError.def.name !== "%DOMException" &&
|
|
1318
1430
|
globalError.def.name !== "%AggregateError") {
|
|
1319
|
-
if (t.typeArguments)
|
|
1431
|
+
if (t.typeArguments?.nodes)
|
|
1320
1432
|
lowerer.unsupported("SC1090", t, "extending generic classes");
|
|
1321
1433
|
base = globalError;
|
|
1322
1434
|
continue;
|
|
@@ -1324,7 +1436,7 @@ mixin) {
|
|
|
1324
1436
|
const emitterBase = lowerer.builtinEmitterInfoOf(resolved);
|
|
1325
1437
|
const streamBaseNs = builtinStreamInfoOf(lowerer, resolved);
|
|
1326
1438
|
if (emitterBase || streamBaseNs) {
|
|
1327
|
-
if (t.typeArguments)
|
|
1439
|
+
if (t.typeArguments?.nodes)
|
|
1328
1440
|
lowerer.unsupported("SC1090", t, "extending generic classes");
|
|
1329
1441
|
base = (emitterBase ?? streamBaseNs);
|
|
1330
1442
|
continue;
|
|
@@ -1345,7 +1457,7 @@ mixin) {
|
|
|
1345
1457
|
continue;
|
|
1346
1458
|
lowerer.unsupported("SC1090", t, `extending the namespace member '${t.expression.name.text}' (no class lowering)`);
|
|
1347
1459
|
}
|
|
1348
|
-
if (t.typeArguments)
|
|
1460
|
+
if (t.typeArguments?.nodes)
|
|
1349
1461
|
lowerer.unsupported("SC1090", t, "extending generic classes");
|
|
1350
1462
|
base = nsBase;
|
|
1351
1463
|
continue;
|
|
@@ -1364,13 +1476,13 @@ mixin) {
|
|
|
1364
1476
|
if (!t.expression.questionDotToken) {
|
|
1365
1477
|
const propBase = propertyAssignedClassInfoOf(lowerer, memberSym);
|
|
1366
1478
|
if (propBase) {
|
|
1367
|
-
if (t.typeArguments)
|
|
1479
|
+
if (t.typeArguments?.nodes)
|
|
1368
1480
|
lowerer.unsupported("SC1090", t, "extending generic classes");
|
|
1369
1481
|
const baseDecl = propBase.decl;
|
|
1370
1482
|
if (baseDecl != null &&
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
lowerer.unsupported("SC1090", t, `extending '${t.expression
|
|
1483
|
+
ts.getSourceFileOfNode(baseDecl) === ts.getSourceFileOfNode(decl) &&
|
|
1484
|
+
ts.tokenStartOfNode(baseDecl) > ts.tokenStartOfNode(decl)) {
|
|
1485
|
+
lowerer.unsupported("SC1090", t, `extending '${ts.getTextOfNode(t.expression)}' above the statement that assigns it (the property is still undefined when this class evaluates — Node throws here; assign the base first)`);
|
|
1374
1486
|
}
|
|
1375
1487
|
base = propBase;
|
|
1376
1488
|
continue;
|
|
@@ -1379,11 +1491,9 @@ mixin) {
|
|
|
1379
1491
|
// fence (the generic computed-expression one below would hide
|
|
1380
1492
|
// what actually blocks it).
|
|
1381
1493
|
const rebinds = memberSym !== undefined &&
|
|
1382
|
-
|
|
1383
|
-
.declarationsOf(memberSym)
|
|
1384
|
-
.filter((d) => ts.isBinaryExpression(d) && d.operatorToken.kind === ts.SyntaxKind.EqualsToken).length > 1;
|
|
1494
|
+
memberSym.declarations.filter((d) => ts.isBinaryExpression(d) && d.operatorToken.kind === ts.SyntaxKind.EqualsToken).length > 1;
|
|
1385
1495
|
if (rebinds) {
|
|
1386
|
-
lowerer.unsupported("SC1090", t, `extending the reassigned property '${t.expression
|
|
1496
|
+
lowerer.unsupported("SC1090", t, `extending the reassigned property '${ts.getTextOfNode(t.expression)}' (the runtime base is whichever assignment ran last — bind the class exactly once)`);
|
|
1387
1497
|
}
|
|
1388
1498
|
}
|
|
1389
1499
|
}
|
|
@@ -1392,7 +1502,7 @@ mixin) {
|
|
|
1392
1502
|
// so its statics queue ahead of the derived class's — the
|
|
1393
1503
|
// recursion order delivers exactly that).
|
|
1394
1504
|
if (t && ts.isClassExpression(t.expression)) {
|
|
1395
|
-
if (t.typeArguments)
|
|
1505
|
+
if (t.typeArguments?.nodes)
|
|
1396
1506
|
lowerer.unsupported("SC1090", t, "extending generic classes");
|
|
1397
1507
|
const baseExpr = lowerer.lowerClassExpressionInfo(t.expression);
|
|
1398
1508
|
base = baseExpr;
|
|
@@ -1404,7 +1514,12 @@ mixin) {
|
|
|
1404
1514
|
// through the monomorphized chain (lower-mixins.ts). A call whose
|
|
1405
1515
|
// callee is NOT a mixin function keeps the computed-expression
|
|
1406
1516
|
// fence below.
|
|
1407
|
-
if (t && ts.isCallExpression(t.expression) && !t.typeArguments) {
|
|
1517
|
+
if (t && ts.isCallExpression(t.expression) && !t.typeArguments?.nodes) {
|
|
1518
|
+
const requiredBase = builtinRequireBaseOf(lowerer, t.expression);
|
|
1519
|
+
if (requiredBase) {
|
|
1520
|
+
base = requiredBase;
|
|
1521
|
+
continue;
|
|
1522
|
+
}
|
|
1408
1523
|
const mixinBase = lowerer.mixinCallClassInfoOf(t.expression);
|
|
1409
1524
|
if (mixinBase) {
|
|
1410
1525
|
base = mixinBase;
|
|
@@ -1492,7 +1607,7 @@ mixin) {
|
|
|
1492
1607
|
base = instBase;
|
|
1493
1608
|
continue;
|
|
1494
1609
|
}
|
|
1495
|
-
if (t.typeArguments)
|
|
1610
|
+
if (t.typeArguments?.nodes)
|
|
1496
1611
|
lowerer.unsupported("SC1090", t, "extending generic classes");
|
|
1497
1612
|
base = named;
|
|
1498
1613
|
if (!base) {
|
|
@@ -1502,7 +1617,7 @@ mixin) {
|
|
|
1502
1617
|
}
|
|
1503
1618
|
}
|
|
1504
1619
|
if (base?.localClass && !functionLocalClass(decl) && !computedBase && !factoryBaseExpression) {
|
|
1505
|
-
const heritage = decl.heritageClauses?.find((clause) => clause.token === ts.SyntaxKind.ExtendsKeyword)?.types[0];
|
|
1620
|
+
const heritage = decl.heritageClauses?.nodes.find((clause) => clause.token === ts.SyntaxKind.ExtendsKeyword)?.types?.nodes[0];
|
|
1506
1621
|
if (heritage)
|
|
1507
1622
|
factoryBaseExpression = heritage.expression;
|
|
1508
1623
|
else
|
|
@@ -1510,9 +1625,7 @@ mixin) {
|
|
|
1510
1625
|
}
|
|
1511
1626
|
if (lowerer.collectingExprClasses.has(decl)) {
|
|
1512
1627
|
for (let parent = base; parent; parent = parent.base) {
|
|
1513
|
-
if (parent.
|
|
1514
|
-
parent.builtinStream !== undefined ||
|
|
1515
|
-
parent.builtinEventTarget !== undefined) {
|
|
1628
|
+
if (parent.builtinEventTarget !== undefined) {
|
|
1516
1629
|
lowerer.unsupported("SC1090", decl, "classes extending builtin bases as values (the inherited runtime constructor has no class-value adapter)");
|
|
1517
1630
|
}
|
|
1518
1631
|
}
|
|
@@ -1535,6 +1648,7 @@ mixin) {
|
|
|
1535
1648
|
const fieldOrder = [];
|
|
1536
1649
|
const methods = new Map();
|
|
1537
1650
|
const methodEntryFences = new Map();
|
|
1651
|
+
const returnAdapters = new Map();
|
|
1538
1652
|
// Own accessor declarations ("get:x"/"set:x" → node), for the
|
|
1539
1653
|
// partial-override analysis below (diagnostics need the node).
|
|
1540
1654
|
const accessorNodes = new Map();
|
|
@@ -1563,12 +1677,12 @@ mixin) {
|
|
|
1563
1677
|
const runtimePrototypeMembers = [];
|
|
1564
1678
|
// Public JS accessors need live constructor descriptors, including
|
|
1565
1679
|
// receiver-sensitive getters and setters inherited by subclasses.
|
|
1566
|
-
const checkedStatics = isJsSourceFile(
|
|
1680
|
+
const checkedStatics = isJsSourceFile(ts.getSourceFileOfNode(decl)) &&
|
|
1567
1681
|
((base && hasRuntimeStatics(base)) ||
|
|
1568
|
-
decl.members.some((member) => ts.isAccessor(member) &&
|
|
1682
|
+
decl.members.nodes.some((member) => ts.isAccessor(member) &&
|
|
1569
1683
|
!ts.isPrivateIdentifier(member.name) &&
|
|
1570
|
-
member.modifiers?.some((modifier) => modifier.kind === ts.SyntaxKind.StaticKeyword))) &&
|
|
1571
|
-
!decl.members.some((member) => member.name &&
|
|
1684
|
+
member.modifiers?.nodes.some((modifier) => modifier.kind === ts.SyntaxKind.StaticKeyword))) &&
|
|
1685
|
+
!decl.members.nodes.some((member) => member.name &&
|
|
1572
1686
|
ts.isPrivateIdentifier(member.name) &&
|
|
1573
1687
|
ts
|
|
1574
1688
|
.getModifiers(member)
|
|
@@ -1601,13 +1715,13 @@ mixin) {
|
|
|
1601
1715
|
lowerer.unsupported("SC1071", member);
|
|
1602
1716
|
const mName = member.name.text;
|
|
1603
1717
|
const typeParams = [];
|
|
1604
|
-
for (const tp of fnNode.typeParameters) {
|
|
1718
|
+
for (const tp of fnNode.typeParameters.nodes) {
|
|
1605
1719
|
const sym = lowerer.checker.getSymbolAtLocation(tp.name);
|
|
1606
1720
|
if (!sym)
|
|
1607
1721
|
lowerer.unsupported("SC1090", member, "this method form");
|
|
1608
1722
|
typeParams.push(sym);
|
|
1609
1723
|
}
|
|
1610
|
-
for (const param of fnNode.parameters) {
|
|
1724
|
+
for (const param of fnNode.parameters.nodes) {
|
|
1611
1725
|
if (!ts.isIdentifier(param.name) &&
|
|
1612
1726
|
!ts.isObjectBindingPattern(param.name) &&
|
|
1613
1727
|
!ts.isArrayBindingPattern(param.name)) {
|
|
@@ -1622,9 +1736,9 @@ mixin) {
|
|
|
1622
1736
|
instances: new Map(),
|
|
1623
1737
|
});
|
|
1624
1738
|
};
|
|
1625
|
-
for (const member of decl.members) {
|
|
1739
|
+
for (const member of decl.members.nodes) {
|
|
1626
1740
|
if ((functionLocalClass(decl) || checkedStatics) &&
|
|
1627
|
-
isJsSourceFile(
|
|
1741
|
+
isJsSourceFile(ts.getSourceFileOfNode(decl)) &&
|
|
1628
1742
|
(ts.isClassStaticBlockDeclaration(member) ||
|
|
1629
1743
|
ts
|
|
1630
1744
|
.getModifiers(member)
|
|
@@ -1633,7 +1747,7 @@ mixin) {
|
|
|
1633
1747
|
continue;
|
|
1634
1748
|
}
|
|
1635
1749
|
if (functionLocalClass(decl) &&
|
|
1636
|
-
isJsSourceFile(
|
|
1750
|
+
isJsSourceFile(ts.getSourceFileOfNode(decl)) &&
|
|
1637
1751
|
(ts.isMethodDeclaration(member) || ts.isAccessor(member)) &&
|
|
1638
1752
|
member.body &&
|
|
1639
1753
|
!ts.isPrivateIdentifier(member.name)) {
|
|
@@ -1698,11 +1812,11 @@ mixin) {
|
|
|
1698
1812
|
if (type.kind === "void")
|
|
1699
1813
|
lowerer.badType(member.name, lowerer.typeOf(member.name));
|
|
1700
1814
|
if (type.kind === "dyn" &&
|
|
1701
|
-
!isJsSourceFile(
|
|
1815
|
+
!isJsSourceFile(ts.getSourceFileOfNode(member)) &&
|
|
1702
1816
|
!lowerer.classFieldStoresDyn(lowerer.typeOf(member.name)) &&
|
|
1703
1817
|
(member.type !== undefined ||
|
|
1704
1818
|
(lowerer.typeOf(member.name).flags & ts.TypeFlags.Any) === 0)) {
|
|
1705
|
-
lowerer.unsupported("SC1090", member.name,
|
|
1819
|
+
lowerer.unsupported("SC1090", member.name, `${dynFieldTypeSpelling(lowerer, member.name)}-typed static fields`);
|
|
1706
1820
|
}
|
|
1707
1821
|
staticFields.push({
|
|
1708
1822
|
name: member.name.text,
|
|
@@ -1724,7 +1838,7 @@ mixin) {
|
|
|
1724
1838
|
lowerer.badType(member.name, lowerer.typeOf(member.name));
|
|
1725
1839
|
}
|
|
1726
1840
|
staticMethods.set(member.name.text, { params: shapes, ret: ft.ret, member });
|
|
1727
|
-
if (implicitMonoFile(
|
|
1841
|
+
if (implicitMonoFile(ts.getSourceFileOfNode(decl)) &&
|
|
1728
1842
|
!functionLocalClass(decl) &&
|
|
1729
1843
|
inst === undefined &&
|
|
1730
1844
|
decl.typeParameters === undefined) {
|
|
@@ -1769,9 +1883,21 @@ mixin) {
|
|
|
1769
1883
|
const memberName = member.name;
|
|
1770
1884
|
if (errorRooted && memberName && classMemberNameOf(lowerer, memberName) === "cause") {
|
|
1771
1885
|
if (ts.isPropertyDeclaration(member) &&
|
|
1772
|
-
!member.modifiers?.some((m) => m.kind === ts.SyntaxKind.StaticKeyword)) {
|
|
1773
|
-
|
|
1774
|
-
|
|
1886
|
+
!member.modifiers?.nodes.some((m) => m.kind === ts.SyntaxKind.StaticKeyword)) {
|
|
1887
|
+
// A TypeScript redeclaration is the JavaScript field: Node
|
|
1888
|
+
// defines the Error's own `cause` (undefined without an
|
|
1889
|
+
// initializer) after super() returns. `declare` and `abstract`
|
|
1890
|
+
// declarations are erased and define nothing. Every `.cause`
|
|
1891
|
+
// read of an Error-rooted class is the checked-dynamic property
|
|
1892
|
+
// (fieldTarget's errorCause container), so only types that read
|
|
1893
|
+
// back unchanged from it are accepted.
|
|
1894
|
+
if (!isJsSourceFile(ts.getSourceFileOfNode(member))) {
|
|
1895
|
+
if (modifiers?.some((m) => m.kind === ts.SyntaxKind.DeclareKeyword ||
|
|
1896
|
+
m.kind === ts.SyntaxKind.AbstractKeyword))
|
|
1897
|
+
continue;
|
|
1898
|
+
if (!lowerer.classFieldStoresDyn(lowerer.typeOf(member.name)))
|
|
1899
|
+
lowerer.unsupported("SC1090", memberName, "redeclaring Error.cause with a type other than 'unknown' or 'object' (declare it 'cause?: unknown' and narrow at the read)");
|
|
1900
|
+
}
|
|
1775
1901
|
fieldOrder.push({
|
|
1776
1902
|
name: "cause",
|
|
1777
1903
|
type: DYN,
|
|
@@ -1837,11 +1963,11 @@ mixin) {
|
|
|
1837
1963
|
!inst &&
|
|
1838
1964
|
!mixin &&
|
|
1839
1965
|
ts.isMethodDeclaration(member) &&
|
|
1840
|
-
!member.modifiers?.some((m) => m.kind === ts.SyntaxKind.StaticKeyword)) {
|
|
1966
|
+
!member.modifiers?.nodes.some((m) => m.kind === ts.SyntaxKind.StaticKeyword)) {
|
|
1841
1967
|
const reason = emitOverrideShapeReason(lowerer, member);
|
|
1842
1968
|
if (reason === null) {
|
|
1843
|
-
const eventSym = lowerer.checker.getSymbolAtLocation(member.parameters[0].name);
|
|
1844
|
-
const restSym = lowerer.checker.getSymbolAtLocation(member.parameters[1].name);
|
|
1969
|
+
const eventSym = lowerer.checker.getSymbolAtLocation(member.parameters.nodes[0].name);
|
|
1970
|
+
const restSym = lowerer.checker.getSymbolAtLocation(member.parameters.nodes[1].name);
|
|
1845
1971
|
if (eventSym && restSym) {
|
|
1846
1972
|
emitOverride = { decl: member, eventSym, restSym };
|
|
1847
1973
|
continue;
|
|
@@ -1889,6 +2015,21 @@ mixin) {
|
|
|
1889
2015
|
lowerer.unsupported("SC1090", memberName, `declaring '${name}' on a ${streamBase.def.name.slice(1)} subclass (its constructor consumes ${accepted.map((a) => `'${UNDERSCORE_METHODS.get(a)}'`).join("/")})`);
|
|
1890
2016
|
}
|
|
1891
2017
|
}
|
|
2018
|
+
// A completion callback declared with the broad `Function` type
|
|
2019
|
+
// (`cb: Function`) takes the checked-dynamic callable the runtime
|
|
2020
|
+
// passes implicitly typed callbacks; calls through it are
|
|
2021
|
+
// dynamic calls of that callable.
|
|
2022
|
+
const callbackIndex = STREAM_COMPLETION_CALLBACK_INDEX.get(name);
|
|
2023
|
+
const callbackParam = ts.isMethodDeclaration(member) && callbackIndex !== undefined
|
|
2024
|
+
? member.parameters.nodes[callbackIndex]
|
|
2025
|
+
: undefined;
|
|
2026
|
+
if (callbackParam !== undefined &&
|
|
2027
|
+
ts.isIdentifier(callbackParam.name) &&
|
|
2028
|
+
!callbackParam.dotDotDotToken &&
|
|
2029
|
+
!callbackParam.questionToken &&
|
|
2030
|
+
!callbackParam.initializer &&
|
|
2031
|
+
lowerer.checker.typeToString(lowerer.typeOf(callbackParam.name)) === "Function")
|
|
2032
|
+
lowerer.checkedCallbackParams.add(callbackParam);
|
|
1892
2033
|
}
|
|
1893
2034
|
}
|
|
1894
2035
|
if (ts.isPropertyDeclaration(member)) {
|
|
@@ -1921,18 +2062,27 @@ mixin) {
|
|
|
1921
2062
|
? String(Number(member.name.text))
|
|
1922
2063
|
: member.name.text;
|
|
1923
2064
|
const fieldName = symbolKey?.fieldName ?? stringKey;
|
|
2065
|
+
// A TypeScript field without an initializer takes its declared
|
|
2066
|
+
// type and the identifier fields' definite-assignment rule (an
|
|
2067
|
+
// unconditional `this[key] = ...` at the constructor's top
|
|
2068
|
+
// level), checked with the unguarded fields below.
|
|
2069
|
+
const declaredOnly = !member.initializer && !isJsSourceFile(ts.getSourceFileOfNode(member)) && !!member.type;
|
|
1924
2070
|
if (fieldName === null ||
|
|
1925
|
-
(!member.initializer &&
|
|
2071
|
+
(!member.initializer &&
|
|
2072
|
+
!isJsSourceFile(ts.getSourceFileOfNode(member)) &&
|
|
2073
|
+
!declaredOnly)) {
|
|
1926
2074
|
lowerer.unsupported("SC1090", member, "computed class fields without an initializer and a stable string, number, or module-level literal Symbol()/Symbol.for() key");
|
|
1927
2075
|
}
|
|
1928
2076
|
const declared = lowerer.typeOf(member);
|
|
1929
2077
|
const inferred = member.type || !member.initializer
|
|
1930
2078
|
? declared
|
|
1931
2079
|
: lowerer.checker.getBaseTypeOfLiteralType(lowerer.typeOf(member.initializer));
|
|
1932
|
-
const mapped = member.initializer
|
|
2080
|
+
const mapped = member.initializer || declaredOnly
|
|
1933
2081
|
? (lowerer.mapTypeOf(inferred) ?? dynFallbackType(lowerer, member, inferred))
|
|
1934
2082
|
: DYN;
|
|
1935
|
-
let type = mapped?.kind === "record" &&
|
|
2083
|
+
let type = mapped?.kind === "record" &&
|
|
2084
|
+
isJsSourceFile(ts.getSourceFileOfNode(member)) &&
|
|
2085
|
+
!member.type
|
|
1936
2086
|
? DYN
|
|
1937
2087
|
: mapped
|
|
1938
2088
|
? jsOpenObjectType(member, mapped, lowerer.shapes, lowerer.unions)
|
|
@@ -1940,17 +2090,29 @@ mixin) {
|
|
|
1940
2090
|
if (!type ||
|
|
1941
2091
|
type.kind === "void" ||
|
|
1942
2092
|
(type.kind === "dyn" &&
|
|
1943
|
-
!isJsSourceFile(
|
|
1944
|
-
!lowerer.
|
|
2093
|
+
!isJsSourceFile(ts.getSourceFileOfNode(member)) &&
|
|
2094
|
+
!lowerer.classFieldStoresDyn(inferred)))
|
|
1945
2095
|
lowerer.badType(member, inferred);
|
|
1946
|
-
if (isJsSourceFile(
|
|
2096
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(member))) {
|
|
1947
2097
|
type = inheritedJsFieldType(lowerer, decl, fieldName, type);
|
|
1948
2098
|
if (base?.fields.get(fieldName)?.kind === "dyn")
|
|
1949
2099
|
type = DYN;
|
|
1950
2100
|
if (base && !fields.has(fieldName) && lowerer.dynConvertible(type))
|
|
1951
2101
|
type = DYN;
|
|
1952
2102
|
}
|
|
1953
|
-
const undefinedInitializer = !member.initializer
|
|
2103
|
+
const undefinedInitializer = !member.initializer && (!declaredOnly || type.kind === "dyn")
|
|
2104
|
+
? locOf(member)
|
|
2105
|
+
: undefined;
|
|
2106
|
+
if (declaredOnly &&
|
|
2107
|
+
type.kind !== "dyn" &&
|
|
2108
|
+
!(type.kind === "union" &&
|
|
2109
|
+
lowerer.unions.get(type.unionId)?.arms.some((a) => a.kind === "undefinedT"))) {
|
|
2110
|
+
unguardedFields.push({
|
|
2111
|
+
node: member.name,
|
|
2112
|
+
name: fieldName,
|
|
2113
|
+
why: `initializer-less computed fields not assigned at the constructor's top level (nothing guarantees '${symbolKey ? symbolFieldDisplayName(fieldName) : fieldName}' is assigned before a read — assign it unconditionally at the top of the constructor, give it an initializer, or include undefined in its type)`,
|
|
2114
|
+
});
|
|
2115
|
+
}
|
|
1954
2116
|
const previous = fields.get(fieldName);
|
|
1955
2117
|
if (previous) {
|
|
1956
2118
|
if (symbolKey && !symbolFields.has(symbolKey.identity)) {
|
|
@@ -2026,9 +2188,9 @@ mixin) {
|
|
|
2026
2188
|
// as undefined on construction, verified), and reads/writes ride
|
|
2027
2189
|
// the ordinary undefined-armed union machinery.
|
|
2028
2190
|
let type = lowerer.irTypeOf(member.name);
|
|
2029
|
-
if (isJsSourceFile(
|
|
2030
|
-
const constructor = decl.members.find((part) => ts.isConstructorDeclaration(part) && !!part.body);
|
|
2031
|
-
for (const statement of constructor?.body?.statements ?? []) {
|
|
2191
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(member)) && !member.initializer) {
|
|
2192
|
+
const constructor = decl.members.nodes.find((part) => ts.isConstructorDeclaration(part) && !!part.body);
|
|
2193
|
+
for (const statement of constructor?.body?.statements?.nodes ?? []) {
|
|
2032
2194
|
if (!ts.isExpressionStatement(statement) ||
|
|
2033
2195
|
!ts.isBinaryExpression(statement.expression) ||
|
|
2034
2196
|
statement.expression.operatorToken.kind !== ts.SyntaxKind.EqualsToken)
|
|
@@ -2046,18 +2208,20 @@ mixin) {
|
|
|
2046
2208
|
}
|
|
2047
2209
|
// Unannotated JavaScript callback slots retain the original
|
|
2048
2210
|
// callable and its receiver instead of adapting its signature.
|
|
2049
|
-
if (isJsSourceFile(
|
|
2211
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(member)) &&
|
|
2050
2212
|
!member.type &&
|
|
2051
|
-
!/@type\b/.test(
|
|
2213
|
+
!/@type\b/.test(ts.getSourceFileOfNode(member).text.slice(member.pos, ts.tokenStartOfNode(member))) &&
|
|
2052
2214
|
(type.kind === "func" || type.kind === "record") &&
|
|
2053
2215
|
lowerer.dynConvertible(type))
|
|
2054
2216
|
type = DYN;
|
|
2055
2217
|
// JS permits reads before a constructor's first assignment even
|
|
2056
2218
|
// when its inferred field type omits undefined.
|
|
2057
|
-
if (isJsSourceFile(
|
|
2219
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(member)) &&
|
|
2220
|
+
!member.initializer &&
|
|
2221
|
+
type.kind !== "dyn") {
|
|
2058
2222
|
type = lowerer.withUndefinedArmOf(type) ?? DYN;
|
|
2059
2223
|
}
|
|
2060
|
-
if (isJsSourceFile(
|
|
2224
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(member))) {
|
|
2061
2225
|
type = inheritedJsFieldType(lowerer, decl, member.name.text, type);
|
|
2062
2226
|
if (base?.fields.get(member.name.text)?.kind === "dyn")
|
|
2063
2227
|
type = DYN;
|
|
@@ -2070,9 +2234,9 @@ mixin) {
|
|
|
2070
2234
|
// them in the constructor. Use the same native checked-dynamic
|
|
2071
2235
|
// storage as implicit constructor-assigned JS fields.
|
|
2072
2236
|
if (type.kind === "dyn" &&
|
|
2073
|
-
!isJsSourceFile(
|
|
2237
|
+
!isJsSourceFile(ts.getSourceFileOfNode(member)) &&
|
|
2074
2238
|
!lowerer.classFieldStoresDyn(lowerer.typeOf(member.name))) {
|
|
2075
|
-
lowerer.unsupported("SC1090", member.name,
|
|
2239
|
+
lowerer.unsupported("SC1090", member.name, `${dynFieldTypeSpelling(lowerer, member.name)}-typed class fields`);
|
|
2076
2240
|
}
|
|
2077
2241
|
const undefinedInitializer = type.kind === "dyn" && !member.initializer ? locOf(member) : undefined;
|
|
2078
2242
|
if (fields.has(member.name.text)) {
|
|
@@ -2171,8 +2335,8 @@ mixin) {
|
|
|
2171
2335
|
// FIRST (before every declared field, as undefined), and the
|
|
2172
2336
|
// assignments run after super() and the field initializers, in
|
|
2173
2337
|
// parameter order (see paramPropInitStmts).
|
|
2174
|
-
for (const p of member.parameters) {
|
|
2175
|
-
const isParamProp = p.modifiers?.some((m) => m.kind === ts.SyntaxKind.PublicKeyword ||
|
|
2338
|
+
for (const p of member.parameters.nodes) {
|
|
2339
|
+
const isParamProp = p.modifiers?.nodes.some((m) => m.kind === ts.SyntaxKind.PublicKeyword ||
|
|
2176
2340
|
m.kind === ts.SyntaxKind.PrivateKeyword ||
|
|
2177
2341
|
m.kind === ts.SyntaxKind.ProtectedKeyword ||
|
|
2178
2342
|
m.kind === ts.SyntaxKind.ReadonlyKeyword ||
|
|
@@ -2180,7 +2344,7 @@ mixin) {
|
|
|
2180
2344
|
if (!isParamProp) {
|
|
2181
2345
|
// Non-keyword modifiers (parameter decorators) are rejected
|
|
2182
2346
|
// by tsc under standard decorators; defensive.
|
|
2183
|
-
if (p.modifiers?.length)
|
|
2347
|
+
if (p.modifiers?.nodes.length)
|
|
2184
2348
|
lowerer.unsupported("SC1090", p, "this parameter form");
|
|
2185
2349
|
continue;
|
|
2186
2350
|
}
|
|
@@ -2191,7 +2355,7 @@ mixin) {
|
|
|
2191
2355
|
}
|
|
2192
2356
|
const name = p.name.text;
|
|
2193
2357
|
if (errorRooted && name === "cause") {
|
|
2194
|
-
lowerer.unsupported("SC1090", p.name, "redeclaring Error.cause (
|
|
2358
|
+
lowerer.unsupported("SC1090", p.name, "redeclaring Error.cause as a parameter property (declare 'cause?: unknown' and assign it in the constructor)");
|
|
2195
2359
|
}
|
|
2196
2360
|
const shape = lowerer.paramShape(p);
|
|
2197
2361
|
const type = shape.bodyType ?? shape.type;
|
|
@@ -2199,7 +2363,7 @@ mixin) {
|
|
|
2199
2363
|
lowerer.badType(p.name, lowerer.typeOf(p.name));
|
|
2200
2364
|
// The class-field dyn rule verbatim (KEEP NARROW).
|
|
2201
2365
|
if (type.kind === "dyn" && !lowerer.classFieldStoresDyn(lowerer.typeOf(p))) {
|
|
2202
|
-
lowerer.unsupported("SC1090", p.name,
|
|
2366
|
+
lowerer.unsupported("SC1090", p.name, `${dynFieldTypeSpelling(lowerer, p)}-typed class fields`);
|
|
2203
2367
|
}
|
|
2204
2368
|
// `override x` (and any same-named inherited member) would
|
|
2205
2369
|
// redeclare a base slot — the declared-field rule verbatim.
|
|
@@ -2257,7 +2421,14 @@ mixin) {
|
|
|
2257
2421
|
!typeEquals(overridden.sig.ret, overrideReturnAbi(lowerer, ret, overridden.sig.ret, className, base)))) {
|
|
2258
2422
|
lowerer.unsupported("SC1090", member.name, "overriding a method with a different signature (parameter types must match the base declaration exactly; returns may narrow to a subclass)");
|
|
2259
2423
|
}
|
|
2260
|
-
|
|
2424
|
+
const unionReturn = overridden?.sig.ret.kind === "union" && !typeEquals(ret, overridden.sig.ret);
|
|
2425
|
+
if (unionReturn)
|
|
2426
|
+
lowerer.unionReturnOverrides.add(member);
|
|
2427
|
+
methods.set(mName, {
|
|
2428
|
+
params: shapes,
|
|
2429
|
+
ret: unionReturn ? overridden.sig.ret : ret,
|
|
2430
|
+
abstract: true,
|
|
2431
|
+
});
|
|
2261
2432
|
continue;
|
|
2262
2433
|
}
|
|
2263
2434
|
// A body-less method is an OVERLOAD SIGNATURE (abstract methods
|
|
@@ -2292,7 +2463,7 @@ mixin) {
|
|
|
2292
2463
|
// dispatch worlds could meet: an inherited declaration of the
|
|
2293
2464
|
// name (the override stays on the vtable), a shadowed field, or
|
|
2294
2465
|
// a generic-class instantiation's member.
|
|
2295
|
-
if (implicitMonoFile(
|
|
2466
|
+
if (implicitMonoFile(ts.getSourceFileOfNode(decl)) &&
|
|
2296
2467
|
!functionLocalClass(decl) &&
|
|
2297
2468
|
ts.isIdentifier(member.name) &&
|
|
2298
2469
|
!lowerer.virtualJsMethods.has(member) &&
|
|
@@ -2332,12 +2503,12 @@ mixin) {
|
|
|
2332
2503
|
}
|
|
2333
2504
|
// JS inference may retain only a symbol sentinel while a method
|
|
2334
2505
|
// also returns values from an untyped mutable field or local.
|
|
2335
|
-
if (isJsSourceFile(
|
|
2506
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(member)) &&
|
|
2336
2507
|
!member.type &&
|
|
2337
2508
|
!hasExplicitJsDocReturn(member) &&
|
|
2338
2509
|
ft.ret.kind === "symbol")
|
|
2339
2510
|
ft.ret = DYN;
|
|
2340
|
-
if (isJsSourceFile(
|
|
2511
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(member)) &&
|
|
2341
2512
|
lowerer.prototypeMethodAccesses.has(mName) &&
|
|
2342
2513
|
!lowerer.findMethodOn(base, mName)?.declarer.def.runtime &&
|
|
2343
2514
|
shapes.every((p) => p.mode === "required" || p.mode === "omittable")) {
|
|
@@ -2386,7 +2557,7 @@ mixin) {
|
|
|
2386
2557
|
// against the STATIC receiver's shape, so `m(x?: number)` and
|
|
2387
2558
|
// `m(x: number | undefined)` interchange soundly in overrides.
|
|
2388
2559
|
const overridden = lowerer.findMethodOn(base, mName);
|
|
2389
|
-
if (overridden && isJsSourceFile(
|
|
2560
|
+
if (overridden && isJsSourceFile(ts.getSourceFileOfNode(member))) {
|
|
2390
2561
|
// An unannotated JS override can return a checked value into
|
|
2391
2562
|
// the inherited native ABI, just as its untyped parameters do.
|
|
2392
2563
|
// Body lowering inserts the conversion at each return.
|
|
@@ -2408,7 +2579,7 @@ mixin) {
|
|
|
2408
2579
|
// Defaults stay local to each declaration, so only inherited
|
|
2409
2580
|
// required/optional slots participate in this refinement.
|
|
2410
2581
|
for (let i = 0; i < shapes.length; i++) {
|
|
2411
|
-
const parameter = member.parameters[i];
|
|
2582
|
+
const parameter = member.parameters.nodes[i];
|
|
2412
2583
|
const inherited = overridden.sig.params[i];
|
|
2413
2584
|
if (parameter &&
|
|
2414
2585
|
inherited &&
|
|
@@ -2427,7 +2598,7 @@ mixin) {
|
|
|
2427
2598
|
// calls fill them with undefined. Typed tails and rest/arguments
|
|
2428
2599
|
// readers keep the exact-signature fence.
|
|
2429
2600
|
if (overridden &&
|
|
2430
|
-
isJsSourceFile(
|
|
2601
|
+
isJsSourceFile(ts.getSourceFileOfNode(member)) &&
|
|
2431
2602
|
shapes.length < overridden.sig.params.length &&
|
|
2432
2603
|
!bodyReadsArguments(member) &&
|
|
2433
2604
|
shapes.every((p, i) => (p.mode === "required" || p.mode === "omittable") &&
|
|
@@ -2439,28 +2610,116 @@ mixin) {
|
|
|
2439
2610
|
.slice(shapes.length)
|
|
2440
2611
|
.map((p) => ({ type: p.type, mode: "omittable" })));
|
|
2441
2612
|
}
|
|
2613
|
+
// A TypeScript override of a JavaScript method (`class T extends
|
|
2614
|
+
// Agent` over an npm-static package) keeps the base's checked-value
|
|
2615
|
+
// ABI: each untyped base slot stays dyn, and the override's typed
|
|
2616
|
+
// parameter narrows from it at entry with a checked conversion. An
|
|
2617
|
+
// untyped base return takes the override's value boxed. Calls on
|
|
2618
|
+
// a statically typed receiver see the same ABI.
|
|
2619
|
+
if (overridden &&
|
|
2620
|
+
!isJsSourceFile(ts.getSourceFileOfNode(member)) &&
|
|
2621
|
+
overridden.declarer.decl !== null &&
|
|
2622
|
+
isJsSourceFile(ts.getSourceFileOfNode(overridden.declarer.decl)) &&
|
|
2623
|
+
member.asteriskToken === undefined &&
|
|
2624
|
+
!overridden.sig.async &&
|
|
2625
|
+
!overridden.sig.gen &&
|
|
2626
|
+
shapes.length <= overridden.sig.params.length &&
|
|
2627
|
+
shapes.every((p, i) => {
|
|
2628
|
+
const inherited = overridden.sig.params[i];
|
|
2629
|
+
return ((p.mode === "required" || p.mode === "omittable") &&
|
|
2630
|
+
p.bodyType === undefined &&
|
|
2631
|
+
(inherited.mode === "required" || inherited.mode === "omittable") &&
|
|
2632
|
+
(typeEquals(p.type, inherited.type) ||
|
|
2633
|
+
(inherited.type.kind === "dyn" && lowerer.dynConvertible(p.type))));
|
|
2634
|
+
}) &&
|
|
2635
|
+
overridden.sig.params
|
|
2636
|
+
.slice(shapes.length)
|
|
2637
|
+
.every((p) => p.type.kind === "dyn" && (p.mode === "required" || p.mode === "omittable"))) {
|
|
2638
|
+
for (let i = 0; i < shapes.length; i++) {
|
|
2639
|
+
const own = shapes[i];
|
|
2640
|
+
if (overridden.sig.params[i].type.kind === "dyn" && own.type.kind !== "dyn")
|
|
2641
|
+
shapes[i] = { type: DYN, mode: own.mode, entryNarrow: own.type };
|
|
2642
|
+
}
|
|
2643
|
+
shapes.push(...overridden.sig.params
|
|
2644
|
+
.slice(shapes.length)
|
|
2645
|
+
.map((p) => ({ type: p.type, mode: "omittable" })));
|
|
2646
|
+
if (overridden.sig.ret.kind === "dyn" &&
|
|
2647
|
+
ft.ret.kind !== "dyn" &&
|
|
2648
|
+
ft.ret.kind !== "void" &&
|
|
2649
|
+
lowerer.dynConvertible(ft.ret))
|
|
2650
|
+
ft.ret = DYN;
|
|
2651
|
+
ft.params = shapes.map((shape) => shape.type);
|
|
2652
|
+
}
|
|
2442
2653
|
if (overridden &&
|
|
2443
2654
|
member.asteriskToken === undefined &&
|
|
2444
2655
|
(overridden.sig.params.length !== shapes.length ||
|
|
2445
2656
|
!overridden.sig.params.every((p, i) => typeEquals(p.type, shapes[i].type)) ||
|
|
2446
2657
|
!typeEquals(overridden.sig.ret, overrideReturnAbi(lowerer, ft.ret, overridden.sig.ret, className, base)))) {
|
|
2447
|
-
const fencedJsOverride = isJsSourceFile(
|
|
2658
|
+
const fencedJsOverride = isJsSourceFile(ts.getSourceFileOfNode(member)) &&
|
|
2448
2659
|
overridden.declarer.decl !== null &&
|
|
2449
|
-
isJsSourceFile(overridden.declarer.decl
|
|
2660
|
+
isJsSourceFile(ts.getSourceFileOfNode(overridden.declarer.decl)) &&
|
|
2450
2661
|
overridden.sig.gen === undefined;
|
|
2451
|
-
|
|
2662
|
+
// A TypeScript override that only changes the result, into a
|
|
2663
|
+
// type that converts into the inherited one (`Promise<void>` over
|
|
2664
|
+
// an `any` base, `string | undefined` over `string`): the slot
|
|
2665
|
+
// keeps the inherited ABI and converts the body's result at the
|
|
2666
|
+
// boundary (lowerClassMethodMemberInner).
|
|
2667
|
+
const ownAsync = member.modifiers?.nodes.some((m) => m.kind === ts.SyntaxKind.AsyncKeyword) === true;
|
|
2668
|
+
if (!fencedJsOverride &&
|
|
2669
|
+
!functionLocalClass(decl) &&
|
|
2670
|
+
overridden.sig.gen === undefined &&
|
|
2671
|
+
// An async base's slot answers its promise: a Promise type, or
|
|
2672
|
+
// the checked-dynamic value of an untyped async method.
|
|
2673
|
+
(overridden.sig.async !== true ||
|
|
2674
|
+
overridden.sig.ret.kind === "promise" ||
|
|
2675
|
+
overridden.sig.ret.kind === "dyn") &&
|
|
2676
|
+
!overridden.sig.abstract &&
|
|
2677
|
+
overridden.sig.params.length === shapes.length &&
|
|
2678
|
+
overridden.sig.params.every((p, i) => p.mode === shapes[i].mode &&
|
|
2679
|
+
(p.mode === "required" || p.mode === "omittable") &&
|
|
2680
|
+
// Each inherited argument converts into the override's
|
|
2681
|
+
// parameter: equal, a checked extraction from an `any`
|
|
2682
|
+
// slot, or a widening (a contravariant parameter).
|
|
2683
|
+
(typeEquals(p.type, shapes[i].type) ||
|
|
2684
|
+
(p.type.kind === "dyn" &&
|
|
2685
|
+
canDynCheckTo(shapes[i].type, (id) => lowerer.shapes.get(id), (id) => lowerer.unions.get(id))) ||
|
|
2686
|
+
lowerer.coercibleValue(p.type, shapes[i].type))) &&
|
|
2687
|
+
(ownAsync ? ft.ret.kind === "promise" : true) &&
|
|
2688
|
+
(typeEquals(ft.ret, overridden.sig.ret) ||
|
|
2689
|
+
(overridden.sig.ret.kind === "dyn"
|
|
2690
|
+
? ft.ret.kind !== "void" && lowerer.dynConvertible(ft.ret)
|
|
2691
|
+
: lowerer.coercibleValue(ft.ret, overridden.sig.ret) ||
|
|
2692
|
+
// A promise whose payload widens into the inherited one
|
|
2693
|
+
// (`Promise<void>` over an untyped async `Promise<any>`).
|
|
2694
|
+
(ft.ret.kind === "promise" &&
|
|
2695
|
+
overridden.sig.ret.kind === "promise" &&
|
|
2696
|
+
lowerer.promisePayloadWidens(ft.ret, overridden.sig.ret)) ||
|
|
2697
|
+
// A JavaScript override's inferred `any` result checks
|
|
2698
|
+
// into the inherited type (`toString() { return
|
|
2699
|
+
// this.message }` over Error's).
|
|
2700
|
+
(ft.ret.kind === "dyn" &&
|
|
2701
|
+
isJsSourceFile(ts.getSourceFileOfNode(member)) &&
|
|
2702
|
+
overridden.sig.ret.kind !== "void" &&
|
|
2703
|
+
canDynCheckTo(overridden.sig.ret, (id) => lowerer.shapes.get(id), (id) => lowerer.unions.get(id)))))) {
|
|
2704
|
+
returnAdapters.set(mName, { params: [...shapes], ret: ft.ret, async: ownAsync });
|
|
2705
|
+
shapes.splice(0, shapes.length, ...overridden.sig.params);
|
|
2706
|
+
ft.ret = overridden.sig.ret;
|
|
2707
|
+
if (overridden.sig.async === true)
|
|
2708
|
+
thunkAsyncSlot(overridden, mName);
|
|
2709
|
+
}
|
|
2710
|
+
else if (fencedJsOverride) {
|
|
2452
2711
|
// A dormant JS method must not poison the whole class. Keep
|
|
2453
2712
|
// the inherited call/dispatch ABI and refuse at method entry;
|
|
2454
2713
|
// lowering this body with the base signature would change JS.
|
|
2455
2714
|
const returnOnly = overridden.sig.params.length === shapes.length &&
|
|
2456
2715
|
overridden.sig.params.every((p, i) => typeEquals(p.type, shapes[i].type)) &&
|
|
2457
|
-
!member.parameters.some((parameter, index) => {
|
|
2716
|
+
!member.parameters.nodes.some((parameter, index) => {
|
|
2458
2717
|
if (!parameter.initializer)
|
|
2459
2718
|
return false;
|
|
2460
|
-
const baseMember = overridden.declarer.decl?.members.find((candidate) => ts.isMethodDeclaration(candidate) &&
|
|
2719
|
+
const baseMember = overridden.declarer.decl?.members?.nodes.find((candidate) => ts.isMethodDeclaration(candidate) &&
|
|
2461
2720
|
classMemberNameOf(lowerer, candidate.name) === mName);
|
|
2462
2721
|
const inherited = baseMember && ts.isMethodDeclaration(baseMember)
|
|
2463
|
-
? baseMember.parameters[index]?.initializer
|
|
2722
|
+
? baseMember.parameters.nodes[index]?.initializer
|
|
2464
2723
|
: undefined;
|
|
2465
2724
|
if (!inherited)
|
|
2466
2725
|
return false;
|
|
@@ -2478,14 +2737,42 @@ mixin) {
|
|
|
2478
2737
|
lowerer.unsupported("SC1090", member.name, "overriding a method with a different signature (parameter types must match the base declaration exactly; returns may narrow to a subclass)");
|
|
2479
2738
|
}
|
|
2480
2739
|
}
|
|
2481
|
-
|
|
2740
|
+
// A return narrowed to part of an inherited union returns through
|
|
2741
|
+
// the union ABI; call sites narrow it back to the declared type.
|
|
2742
|
+
if (overridden?.sig.ret.kind === "union" && !typeEquals(ft.ret, overridden.sig.ret)) {
|
|
2743
|
+
ft.ret = overridden.sig.ret;
|
|
2744
|
+
lowerer.unionReturnOverrides.add(member);
|
|
2745
|
+
}
|
|
2746
|
+
const asyncMember = member.modifiers?.nodes.some((m) => m.kind === ts.SyntaxKind.AsyncKeyword) === true;
|
|
2482
2747
|
// Async methods dispatch STATICALLY (the body enters through its
|
|
2483
2748
|
// fiber spawn wrapper; vtable slots hold raw implementations) —
|
|
2484
2749
|
// an override chain touching an async method on either end would
|
|
2485
2750
|
// put a spawn wrapper behind a virtual slot, so it fences.
|
|
2486
|
-
|
|
2751
|
+
// An override chain touching async methods dispatches through
|
|
2752
|
+
// plain slot functions that return the body's promise: the async
|
|
2753
|
+
// bodies lower as `%C.m$own` behind them (thunkAsyncSlot).
|
|
2754
|
+
if (overridden &&
|
|
2755
|
+
!returnAdapters.has(mName) &&
|
|
2756
|
+
(asyncMember || overridden.sig.async === true) &&
|
|
2757
|
+
!isJsSourceFile(ts.getSourceFileOfNode(member)) &&
|
|
2758
|
+
!functionLocalClass(decl) &&
|
|
2759
|
+
member.asteriskToken === undefined &&
|
|
2760
|
+
overridden.sig.gen === undefined &&
|
|
2761
|
+
!overridden.sig.abstract &&
|
|
2762
|
+
ft.ret.kind === "promise" &&
|
|
2763
|
+
typeEquals(ft.ret, overridden.sig.ret) &&
|
|
2764
|
+
overridden.sig.params.length === shapes.length &&
|
|
2765
|
+
overridden.sig.params.every((p, i) => typeEquals(p.type, shapes[i].type) && p.mode === shapes[i].mode)) {
|
|
2766
|
+
if (overridden.sig.async === true)
|
|
2767
|
+
thunkAsyncSlot(overridden, mName);
|
|
2768
|
+
if (asyncMember)
|
|
2769
|
+
returnAdapters.set(mName, { params: [...shapes], ret: ft.ret, async: true });
|
|
2770
|
+
}
|
|
2771
|
+
if (overridden &&
|
|
2772
|
+
!returnAdapters.has(mName) &&
|
|
2773
|
+
(asyncMember || overridden.sig.async === true)) {
|
|
2487
2774
|
const message = `overriding ${overridden.sig.async === true ? "the async method" : "a method with an async method"} '${mName}' (async methods dispatch statically — the vtable slot machinery has no fiber-spawn story)`;
|
|
2488
|
-
if (isJsSourceFile(
|
|
2775
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(member)))
|
|
2489
2776
|
methodEntryFences.set(mName, unsupportedDiag("SC1090", locOf(member.name), message));
|
|
2490
2777
|
else
|
|
2491
2778
|
lowerer.unsupported("SC1090", member.name, message);
|
|
@@ -2493,7 +2780,7 @@ mixin) {
|
|
|
2493
2780
|
if (overridden &&
|
|
2494
2781
|
(member.asteriskToken !== undefined || overridden.sig.gen !== undefined)) {
|
|
2495
2782
|
const message = `overriding the generator method '${mName}' (generator methods dispatch statically — a virtual slot cannot enter their spawn wrapper)`;
|
|
2496
|
-
if (isJsSourceFile(
|
|
2783
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(member)))
|
|
2497
2784
|
methodEntryFences.set(mName, unsupportedDiag("SC1090", locOf(member.name), message));
|
|
2498
2785
|
else
|
|
2499
2786
|
lowerer.unsupported("SC1090", member.name, message);
|
|
@@ -2513,7 +2800,7 @@ mixin) {
|
|
|
2513
2800
|
});
|
|
2514
2801
|
}
|
|
2515
2802
|
else {
|
|
2516
|
-
methods.set(mName, asyncMember
|
|
2803
|
+
methods.set(mName, asyncMember && !returnAdapters.has(mName)
|
|
2517
2804
|
? { params: shapes, ret: ft.ret, async: true }
|
|
2518
2805
|
: { params: shapes, ret: ft.ret });
|
|
2519
2806
|
}
|
|
@@ -2555,7 +2842,7 @@ mixin) {
|
|
|
2555
2842
|
lowerer.unsupported("SC1090", member, "bodyless accessors");
|
|
2556
2843
|
const mName = `${isGet ? "get" : "set"}:${prop}`;
|
|
2557
2844
|
if (fields.has(prop) &&
|
|
2558
|
-
isJsSourceFile(
|
|
2845
|
+
isJsSourceFile(ts.getSourceFileOfNode(decl)) &&
|
|
2559
2846
|
base?.fields.has(prop) &&
|
|
2560
2847
|
!fieldOrder.some((field) => field.name === prop)) {
|
|
2561
2848
|
// JS may override an inherited data field with a prototype
|
|
@@ -2572,14 +2859,22 @@ mixin) {
|
|
|
2572
2859
|
}
|
|
2573
2860
|
let sig;
|
|
2574
2861
|
if (isGet) {
|
|
2575
|
-
|
|
2862
|
+
let ret = lowerer.declaredReturnType(member, member.name);
|
|
2863
|
+
// A getter that never returns a value: typed `never` (it only
|
|
2864
|
+
// throws, Next.js's removed `page`/`ua` getters) or, unannotated
|
|
2865
|
+
// with no return statement, inferred `void`. A read answers
|
|
2866
|
+
// undefined or throws, so the property takes the checked-dynamic
|
|
2867
|
+
// slot instead of VOID.
|
|
2868
|
+
if (ret.kind === "void" &&
|
|
2869
|
+
(lowerer.typeOf(member.name).flags & (ts.TypeFlags.Never | ts.TypeFlags.Void)) !== 0)
|
|
2870
|
+
ret = DYN;
|
|
2576
2871
|
if (ret.kind === "void")
|
|
2577
2872
|
lowerer.badType(member.name, lowerer.typeOf(member.name));
|
|
2578
2873
|
sig = { params: [], ret };
|
|
2579
2874
|
}
|
|
2580
2875
|
else {
|
|
2581
2876
|
// tsc rejects optional/default/rest setter params (TS1051-53).
|
|
2582
|
-
sig = { params: lowerer.paramShapes(member.parameters), ret: VOID };
|
|
2877
|
+
sig = { params: lowerer.paramShapes(member.parameters.nodes), ret: VOID };
|
|
2583
2878
|
}
|
|
2584
2879
|
if (lowerer.checkedVirtualJsAccessors.has(member)) {
|
|
2585
2880
|
if (isGet)
|
|
@@ -2643,7 +2938,7 @@ mixin) {
|
|
|
2643
2938
|
// undefined. Such fields take the deferred-init representation, whose
|
|
2644
2939
|
// slot (a nullable instance pointer) starts empty and whose reads check
|
|
2645
2940
|
// it. Fields assigned before any exposure keep their plain reads.
|
|
2646
|
-
const derived = decl.heritageClauses?.some((clause) => clause.token === ts.SyntaxKind.ExtendsKeyword) ??
|
|
2941
|
+
const derived = decl.heritageClauses?.nodes.some((clause) => clause.token === ts.SyntaxKind.ExtendsKeyword) ??
|
|
2647
2942
|
false;
|
|
2648
2943
|
// Generic instances and mixins share layouts across declarations, so
|
|
2649
2944
|
// they only report whether construction exposes the instance.
|
|
@@ -2668,7 +2963,7 @@ mixin) {
|
|
|
2668
2963
|
if (!ts.isPropertyAccessExpression(callee))
|
|
2669
2964
|
return null;
|
|
2670
2965
|
const name = callee.name.text;
|
|
2671
|
-
const declaration = decl.members.find((member) => ts.isMethodDeclaration(member) &&
|
|
2966
|
+
const declaration = decl.members.nodes.find((member) => ts.isMethodDeclaration(member) &&
|
|
2672
2967
|
member.body !== undefined &&
|
|
2673
2968
|
(ts.isIdentifier(member.name) || ts.isPrivateIdentifier(member.name)) &&
|
|
2674
2969
|
member.name.text === name);
|
|
@@ -2692,7 +2987,7 @@ mixin) {
|
|
|
2692
2987
|
const deferredInitFields = new Set(base?.deferredInitFields ?? []);
|
|
2693
2988
|
if (unguardedFields.length > 0) {
|
|
2694
2989
|
const topAssigned = new Set();
|
|
2695
|
-
for (const stmt of ctor?.body?.statements ?? []) {
|
|
2990
|
+
for (const stmt of ctor?.body?.statements?.nodes ?? []) {
|
|
2696
2991
|
if (ts.isExpressionStatement(stmt) &&
|
|
2697
2992
|
ts.isBinaryExpression(stmt.expression) &&
|
|
2698
2993
|
stmt.expression.operatorToken.kind === ts.SyntaxKind.EqualsToken &&
|
|
@@ -2700,6 +2995,16 @@ mixin) {
|
|
|
2700
2995
|
stmt.expression.left.expression.kind === ts.SyntaxKind.ThisKeyword) {
|
|
2701
2996
|
topAssigned.add(stmt.expression.left.name.text);
|
|
2702
2997
|
}
|
|
2998
|
+
else if (ts.isExpressionStatement(stmt) &&
|
|
2999
|
+
ts.isBinaryExpression(stmt.expression) &&
|
|
3000
|
+
stmt.expression.operatorToken.kind === ts.SyntaxKind.EqualsToken &&
|
|
3001
|
+
ts.isElementAccessExpression(stmt.expression.left) &&
|
|
3002
|
+
stmt.expression.left.expression.kind === ts.SyntaxKind.ThisKeyword) {
|
|
3003
|
+
const key = stmt.expression.left.argumentExpression;
|
|
3004
|
+
const name = classSymbolKeyOf(lowerer, key)?.fieldName ?? lowerer.foldedStringKeyOf(key);
|
|
3005
|
+
if (name !== null)
|
|
3006
|
+
topAssigned.add(name);
|
|
3007
|
+
}
|
|
2703
3008
|
}
|
|
2704
3009
|
for (const f of unguardedFields) {
|
|
2705
3010
|
if (topAssigned.has(f.name) || escape.assigned?.has(f.name))
|
|
@@ -2736,13 +3041,26 @@ mixin) {
|
|
|
2736
3041
|
}
|
|
2737
3042
|
}
|
|
2738
3043
|
if (escape.assigned && !inst) {
|
|
3044
|
+
let earlyReads = null;
|
|
2739
3045
|
for (const f of fieldOrder) {
|
|
2740
3046
|
if (f.redeclared || escape.assigned.has(f.name) || deferredInitFields.has(f.name))
|
|
2741
3047
|
continue;
|
|
2742
3048
|
if (paramProps.some((pp) => pp.name === f.name))
|
|
2743
3049
|
continue;
|
|
2744
3050
|
const declared = fields.get(f.name);
|
|
2745
|
-
|
|
3051
|
+
// Records, arrays and strings are pointer slots that start empty
|
|
3052
|
+
// too, but only take the checked slot when a method the
|
|
3053
|
+
// constructor calls actually reads them: their other early
|
|
3054
|
+
// exposures keep the plain slot.
|
|
3055
|
+
if (declared?.kind === "record" ||
|
|
3056
|
+
declared?.kind === "array" ||
|
|
3057
|
+
declared?.kind === "string") {
|
|
3058
|
+
earlyReads ??= constructorMethodReads(decl, base, ctor ?? undefined);
|
|
3059
|
+
if (!earlyReads.has(f.name))
|
|
3060
|
+
continue;
|
|
3061
|
+
}
|
|
3062
|
+
else if (declared?.kind !== "object" ||
|
|
3063
|
+
lowerer.classes.get(declared.className)?.def.runtime)
|
|
2746
3064
|
continue;
|
|
2747
3065
|
const armed = lowerer.withUndefinedArm(declared);
|
|
2748
3066
|
if (armed === null || armed.kind !== "union")
|
|
@@ -2803,7 +3121,7 @@ mixin) {
|
|
|
2803
3121
|
// assignment ran — the zeroed-memory trap a TS declaration order
|
|
2804
3122
|
// forbids via strictPropertyInitialization — so they keep a named
|
|
2805
3123
|
// fence instead of reading undefined without a diagnostic.
|
|
2806
|
-
if (isJsSourceFile(
|
|
3124
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(decl))) {
|
|
2807
3125
|
const hasAccessor = (name) => methods.has(`get:${name}`) ||
|
|
2808
3126
|
methods.has(`set:${name}`) ||
|
|
2809
3127
|
lowerer.findMethodOn(base, `get:${name}`) !== null ||
|
|
@@ -2826,14 +3144,22 @@ mixin) {
|
|
|
2826
3144
|
// goes through the key.
|
|
2827
3145
|
const lateBoundByKey = new Map();
|
|
2828
3146
|
for (const p of instType ? lowerer.checker.getPropertiesOfType(instType) : []) {
|
|
2829
|
-
if (!p.
|
|
3147
|
+
if (!ts.symbolName(p).startsWith("__@"))
|
|
2830
3148
|
continue;
|
|
2831
3149
|
const keySym = lateBoundKeySymOf(lowerer, p);
|
|
2832
3150
|
if (keySym)
|
|
2833
3151
|
lateBoundByKey.set(keySym, p);
|
|
2834
3152
|
}
|
|
3153
|
+
// A subclass field created before anything can observe the instance
|
|
3154
|
+
// keeps its type: super() cannot run code that reads it earlier.
|
|
3155
|
+
const baseConstruction = base && ![...methods.keys()].some((m) => m.startsWith("get:") || m.startsWith("set:"))
|
|
3156
|
+
? construction(base)
|
|
3157
|
+
: null;
|
|
3158
|
+
const sealedPrefix = baseConstruction
|
|
3159
|
+
? constructionPrefix(decl, baseConstruction, (name) => !hasAccessor(name) && !methods.has(name) && !lowerer.findMethodOn(base, name))
|
|
3160
|
+
: null;
|
|
2835
3161
|
if (ctor?.body) {
|
|
2836
|
-
for (const stmt of ctor.body.statements) {
|
|
3162
|
+
for (const stmt of ctor.body.statements.nodes) {
|
|
2837
3163
|
const lhs = ts.isExpressionStatement(stmt) &&
|
|
2838
3164
|
ts.isBinaryExpression(stmt.expression) &&
|
|
2839
3165
|
stmt.expression.operatorToken.kind === ts.SyntaxKind.EqualsToken
|
|
@@ -2869,7 +3195,7 @@ mixin) {
|
|
|
2869
3195
|
let type = t ? (lowerer.mapTypeOf(t) ?? dynFallbackType(lowerer, assign, t)) : null;
|
|
2870
3196
|
if (t &&
|
|
2871
3197
|
(t.flags & (ts.TypeFlags.Null | ts.TypeFlags.Undefined)) !== 0 &&
|
|
2872
|
-
isJsSourceFile(
|
|
3198
|
+
isJsSourceFile(ts.getSourceFileOfNode(decl)))
|
|
2873
3199
|
type = DYN;
|
|
2874
3200
|
if (type)
|
|
2875
3201
|
type = jsOpenObjectType(assign, type, lowerer.shapes, lowerer.unions);
|
|
@@ -2901,7 +3227,7 @@ mixin) {
|
|
|
2901
3227
|
type = inheritedJsFieldType(lowerer, decl, name, type);
|
|
2902
3228
|
// super() can invoke a subclass setter or method before its
|
|
2903
3229
|
// constructor assignments run. These slots start undefined.
|
|
2904
|
-
if (base && lowerer.dynConvertible(type))
|
|
3230
|
+
if (base && lowerer.dynConvertible(type) && !sealedPrefix?.created.has(name))
|
|
2905
3231
|
type = DYN;
|
|
2906
3232
|
fields.set(name, type);
|
|
2907
3233
|
fieldOrder.push({ name, type, initializer: undefined });
|
|
@@ -2983,17 +3309,16 @@ mixin) {
|
|
|
2983
3309
|
// static layouts cannot represent. Named fence, at the first
|
|
2984
3310
|
// assignment site.
|
|
2985
3311
|
for (const p of instType ? lowerer.checker.getPropertiesOfType(instType) : []) {
|
|
2986
|
-
if (errorRooted && p
|
|
3312
|
+
if (errorRooted && ts.symbolName(p) === "cause")
|
|
2987
3313
|
continue;
|
|
2988
|
-
if (fields.has(p
|
|
3314
|
+
if (fields.has(ts.symbolName(p)) || methods.has(ts.symbolName(p)))
|
|
2989
3315
|
continue;
|
|
2990
|
-
if (hasAccessor(p
|
|
3316
|
+
if (hasAccessor(ts.symbolName(p)))
|
|
2991
3317
|
continue;
|
|
2992
|
-
if (base &&
|
|
3318
|
+
if (base &&
|
|
3319
|
+
(base.fields.has(ts.symbolName(p)) || lowerer.findMethodOn(base, ts.symbolName(p))))
|
|
2993
3320
|
continue;
|
|
2994
|
-
const site =
|
|
2995
|
-
.declarationsOf(p)
|
|
2996
|
-
.find((d) => ts.isPropertyAccessExpression(d) ||
|
|
3321
|
+
const site = p.declarations.find((d) => ts.isPropertyAccessExpression(d) ||
|
|
2997
3322
|
ts.isBinaryExpression(d) ||
|
|
2998
3323
|
ts.isElementAccessExpression(d));
|
|
2999
3324
|
if (!site)
|
|
@@ -3004,7 +3329,7 @@ mixin) {
|
|
|
3004
3329
|
// identities (symbol parameters, mutable bindings, computed
|
|
3005
3330
|
// descriptions) or assignments outside the constructor's top
|
|
3006
3331
|
// level.
|
|
3007
|
-
if (p.
|
|
3332
|
+
if (ts.symbolName(p).startsWith("__@")) {
|
|
3008
3333
|
const keySym = lateBoundKeySymOf(lowerer, p);
|
|
3009
3334
|
const key = keySym ? classSymbolKeyOfSymbol(lowerer, keySym) : null;
|
|
3010
3335
|
if (key && symbolFields.has(key.identity))
|
|
@@ -3021,21 +3346,23 @@ mixin) {
|
|
|
3021
3346
|
// Unmappable inferences and arm-less kinds keep the fence.
|
|
3022
3347
|
// TypeScript classes keep the compile-time fence too: an annotated
|
|
3023
3348
|
// program can spell `T | undefined` itself.
|
|
3024
|
-
if (isJsSourceFile(
|
|
3349
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(decl))) {
|
|
3025
3350
|
const original = undefArmedFieldType(lowerer, p);
|
|
3026
|
-
const armed = original === null
|
|
3351
|
+
const armed = original === null
|
|
3352
|
+
? null
|
|
3353
|
+
: inheritedJsFieldType(lowerer, decl, ts.symbolName(p), original);
|
|
3027
3354
|
if (armed !== null) {
|
|
3028
3355
|
// Unknown JS properties use the instance bag: they do not
|
|
3029
3356
|
// exist until assigned, and a subclass may declare the same
|
|
3030
3357
|
// name as an ordinary layout field.
|
|
3031
3358
|
if (armed.kind === "dyn")
|
|
3032
3359
|
continue;
|
|
3033
|
-
fields.set(p
|
|
3034
|
-
fieldOrder.push({ name: p
|
|
3360
|
+
fields.set(ts.symbolName(p), armed);
|
|
3361
|
+
fieldOrder.push({ name: ts.symbolName(p), type: armed, initializer: undefined });
|
|
3035
3362
|
continue;
|
|
3036
3363
|
}
|
|
3037
3364
|
}
|
|
3038
|
-
lowerer.unsupported("SC1090", site, `fields assigned outside the constructor's top level ('this.${p
|
|
3365
|
+
lowerer.unsupported("SC1090", site, `fields assigned outside the constructor's top level ('this.${ts.symbolName(p)}' would be undefined until the first assignment runs — assign it unconditionally at the top of the constructor)`);
|
|
3039
3366
|
}
|
|
3040
3367
|
}
|
|
3041
3368
|
// Second refinement chance, OWN symbol slots: the member loop ran
|
|
@@ -3059,18 +3386,18 @@ mixin) {
|
|
|
3059
3386
|
// is NOT the pure forwarding shape has no static story — named
|
|
3060
3387
|
// fence, never a mis-typed array.
|
|
3061
3388
|
const mixinForwarding = mixin !== undefined && ctor !== null && mixinForwardingCtor(lowerer, ctor);
|
|
3062
|
-
if (mixin && ctor && !mixinForwarding && ctor.parameters.some((p) => p.dotDotDotToken)) {
|
|
3063
|
-
lowerer.unsupported("SC1090", ctor.parameters.find((p) => p.dotDotDotToken), "mixin constructors whose rest parameter does anything but forward (`super(...args)` as the first statement is the compiled shape)");
|
|
3389
|
+
if (mixin && ctor && !mixinForwarding && ctor.parameters.nodes.some((p) => p.dotDotDotToken)) {
|
|
3390
|
+
lowerer.unsupported("SC1090", ctor.parameters.nodes.find((p) => p.dotDotDotToken), "mixin constructors whose rest parameter does anything but forward (`super(...args)` as the first statement is the compiled shape)");
|
|
3064
3391
|
}
|
|
3065
3392
|
// Constructor omitted on a derived class: it inherits the base's
|
|
3066
3393
|
// (tsc types `new Derived(...)` against the inherited signature; the
|
|
3067
3394
|
// synthesized constructor forwards the same params to super).
|
|
3068
3395
|
const ctorParams = ctor && !mixinForwarding
|
|
3069
|
-
? lowerer.paramShapes(ctor.parameters)
|
|
3396
|
+
? lowerer.paramShapes(ctor.parameters.nodes)
|
|
3070
3397
|
: (base?.ctorParams ?? (callableBase ? [{ type: DYN, mode: "dynRest" }] : []));
|
|
3071
3398
|
if (ctor &&
|
|
3072
3399
|
!mixinForwarding &&
|
|
3073
|
-
isJsSourceFile(
|
|
3400
|
+
isJsSourceFile(ts.getSourceFileOfNode(ctor)) &&
|
|
3074
3401
|
!ctorParams.some((shape) => shape.mode === "rest" || shape.mode === "dynRest") &&
|
|
3075
3402
|
bodyReadsArguments(ctor)) {
|
|
3076
3403
|
ctorParams.push({ type: DYN, mode: "arguments" });
|
|
@@ -3086,9 +3413,9 @@ mixin) {
|
|
|
3086
3413
|
// INSTANTIATION prints its family's name — JS has one `Box`.
|
|
3087
3414
|
jsName: jsNameOverride ?? decl.name?.text ?? "",
|
|
3088
3415
|
...(base ? { base: base.def.name } : {}),
|
|
3089
|
-
jsLength: ctor?.parameters.findIndex((parameter) => parameter.initializer || parameter.dotDotDotToken) === -1
|
|
3090
|
-
? ctor.parameters.length
|
|
3091
|
-
: Math.max(0, ctor?.parameters.findIndex((parameter) => parameter.initializer || parameter.dotDotDotToken) ?? 0),
|
|
3416
|
+
jsLength: ctor?.parameters?.nodes.findIndex((parameter) => parameter.initializer || parameter.dotDotDotToken) === -1
|
|
3417
|
+
? ctor.parameters.nodes.length
|
|
3418
|
+
: Math.max(0, ctor?.parameters?.nodes.findIndex((parameter) => parameter.initializer || parameter.dotDotDotToken) ?? 0),
|
|
3092
3419
|
// Layout order: the base chain's fields as an IDENTICAL prefix,
|
|
3093
3420
|
// then this class's own — what makes an upcast a reinterpret.
|
|
3094
3421
|
// Redeclared INHERITED fields contribute no slot (their
|
|
@@ -3116,6 +3443,7 @@ mixin) {
|
|
|
3116
3443
|
fieldOrder,
|
|
3117
3444
|
methods,
|
|
3118
3445
|
...(methodEntryFences.size > 0 ? { methodEntryFences } : {}),
|
|
3446
|
+
...(returnAdapters.size > 0 ? { returnAdapters } : {}),
|
|
3119
3447
|
decl,
|
|
3120
3448
|
...(emitOverride !== undefined ? { emitOverride } : {}),
|
|
3121
3449
|
ctor,
|
|
@@ -3138,6 +3466,14 @@ mixin) {
|
|
|
3138
3466
|
...(deferredInitFields.size > 0 ? { deferredInitFields } : {}),
|
|
3139
3467
|
...(escape.escapes ? { constructionEscapes: true } : {}),
|
|
3140
3468
|
};
|
|
3469
|
+
let root = info;
|
|
3470
|
+
while (root?.base)
|
|
3471
|
+
root = root.base;
|
|
3472
|
+
if (root !== info && root?.def.name === "%Error") {
|
|
3473
|
+
const after = errorNameAfterField(info, errorViewFields(info.def.fields));
|
|
3474
|
+
if (after !== undefined)
|
|
3475
|
+
info.def.errorNameAfter = after;
|
|
3476
|
+
}
|
|
3141
3477
|
// GENERIC members get their declaring-class backlink now that the
|
|
3142
3478
|
// info exists (instance lowering reads it for `this` typing and the
|
|
3143
3479
|
// generic-class binding merge).
|
|
@@ -3171,7 +3507,7 @@ mixin) {
|
|
|
3171
3507
|
}
|
|
3172
3508
|
if (familyMode) {
|
|
3173
3509
|
const typeParams = [];
|
|
3174
|
-
for (const tp of decl.typeParameters) {
|
|
3510
|
+
for (const tp of decl.typeParameters.nodes) {
|
|
3175
3511
|
const sym = lowerer.checker.getSymbolAtLocation(tp.name);
|
|
3176
3512
|
if (!sym)
|
|
3177
3513
|
lowerer.unsupported("SC1090", tp, "this type parameter form");
|
|
@@ -3439,6 +3775,7 @@ export function lowerStaticFieldInits(lowerer, info) {
|
|
|
3439
3775
|
// instantiation's bindings/context (a no-op for everything else —
|
|
3440
3776
|
// generic FAMILIES own their statics and carry no genericInstance).
|
|
3441
3777
|
const diagsBefore = lowerer.diags.length;
|
|
3778
|
+
const sinkMark = lowerer.diagSinkMark();
|
|
3442
3779
|
try {
|
|
3443
3780
|
return withInstanceBindings(lowerer, info, () => lowerStaticFieldInitsInner(lowerer, info));
|
|
3444
3781
|
}
|
|
@@ -3448,8 +3785,10 @@ export function lowerStaticFieldInits(lowerer, info) {
|
|
|
3448
3785
|
// letting a poisoned initializer escape the module lowering pass.
|
|
3449
3786
|
if (!(error instanceof PoisonError))
|
|
3450
3787
|
throw error;
|
|
3451
|
-
if (info.decl && isJsSourceFile(info.decl
|
|
3452
|
-
const fence = lowerer.
|
|
3788
|
+
if (info.decl && isJsSourceFile(ts.getSourceFileOfNode(info.decl))) {
|
|
3789
|
+
const fence = lowerer.diagSink === null
|
|
3790
|
+
? lowerer.deferToRuntimeFence(diagsBefore, info.decl, { kind: "statement" })
|
|
3791
|
+
: lowerer.capturedRuntimeFence(sinkMark, info.decl);
|
|
3453
3792
|
if (fence)
|
|
3454
3793
|
return [fence];
|
|
3455
3794
|
}
|
|
@@ -3560,8 +3899,16 @@ function lowerStaticFieldInitsInner(lowerer, info) {
|
|
|
3560
3899
|
});
|
|
3561
3900
|
}
|
|
3562
3901
|
const items = [
|
|
3563
|
-
...info.staticFields.map((f) => ({
|
|
3564
|
-
|
|
3902
|
+
...info.staticFields.map((f) => ({
|
|
3903
|
+
pos: ts.tokenStartOfNode(f.initializer),
|
|
3904
|
+
kind: "field",
|
|
3905
|
+
f,
|
|
3906
|
+
})),
|
|
3907
|
+
...(info.staticBlocks ?? []).map((b) => ({
|
|
3908
|
+
pos: ts.tokenStartOfNode(b),
|
|
3909
|
+
kind: "block",
|
|
3910
|
+
b,
|
|
3911
|
+
})),
|
|
3565
3912
|
].sort((a, b) => a.pos - b.pos);
|
|
3566
3913
|
for (const item of items) {
|
|
3567
3914
|
if (item.kind === "block") {
|
|
@@ -3571,9 +3918,9 @@ function lowerStaticFieldInitsInner(lowerer, info) {
|
|
|
3571
3918
|
continue;
|
|
3572
3919
|
}
|
|
3573
3920
|
const f = item.f;
|
|
3574
|
-
lowerer.
|
|
3575
|
-
lowerer.bumpFileStat(locOf(f.initializer).file, "total");
|
|
3921
|
+
lowerer.countStatement(f.initializer, locOf(f.initializer).file);
|
|
3576
3922
|
const diagsBefore = lowerer.diags.length;
|
|
3923
|
+
const sinkMark = lowerer.diagSinkMark();
|
|
3577
3924
|
try {
|
|
3578
3925
|
const previousThis = lowerer.ctx.thisLocal;
|
|
3579
3926
|
const receiver = f.initializer.kind === ts.SyntaxKind.ThisKeyword || hasStaticThis(f.initializer)
|
|
@@ -3610,12 +3957,11 @@ function lowerStaticFieldInitsInner(lowerer, info) {
|
|
|
3610
3957
|
catch (e) {
|
|
3611
3958
|
if (!(e instanceof PoisonError))
|
|
3612
3959
|
throw e;
|
|
3613
|
-
lowerer.
|
|
3614
|
-
|
|
3615
|
-
|
|
3616
|
-
|
|
3617
|
-
|
|
3618
|
-
});
|
|
3960
|
+
lowerer.countStatementFailed(f.initializer, locOf(f.initializer).file);
|
|
3961
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(f.initializer))) {
|
|
3962
|
+
const fence = lowerer.diagSink === null
|
|
3963
|
+
? lowerer.deferToRuntimeFence(diagsBefore, f.initializer, { kind: "statement" })
|
|
3964
|
+
: lowerer.capturedRuntimeFence(sinkMark, f.initializer);
|
|
3619
3965
|
if (fence)
|
|
3620
3966
|
out.push(fence);
|
|
3621
3967
|
}
|
|
@@ -3664,12 +4010,12 @@ export function analyzeClassDecoration(lowerer, info) {
|
|
|
3664
4010
|
: null;
|
|
3665
4011
|
if (ambientCallee !== null) {
|
|
3666
4012
|
const sym = lowerer.resolveValueSymbol(ambientCallee);
|
|
3667
|
-
const vdecl = sym && !lowerer.isStdlibSymbol(sym) ?
|
|
4013
|
+
const vdecl = sym && !lowerer.isStdlibSymbol(sym) ? sym.declarations[0] : undefined;
|
|
3668
4014
|
const ambientVar = vdecl !== undefined &&
|
|
3669
4015
|
ts.isVariableDeclaration(vdecl) &&
|
|
3670
4016
|
vdecl.initializer === undefined &&
|
|
3671
4017
|
(ts.getCombinedModifierFlags(vdecl) & ts.ModifierFlags.Ambient) !== 0 &&
|
|
3672
|
-
!
|
|
4018
|
+
!ts.getSourceFileOfNode(vdecl).isDeclarationFile;
|
|
3673
4019
|
if (ambientVar || ambientUndefinedFnSymbolOf(lowerer, ambientCallee) !== null) {
|
|
3674
4020
|
shapes.push({ kind: "ambientThrow", name: ambientCallee.text });
|
|
3675
4021
|
continue;
|
|
@@ -3861,6 +4207,54 @@ export function staticShadowBelow(info, name) {
|
|
|
3861
4207
|
s.genericStatics?.has(name) === true ||
|
|
3862
4208
|
staticShadowBelow(s, name));
|
|
3863
4209
|
}
|
|
4210
|
+
/** The `this` members read by the methods and accessors a constructor
|
|
4211
|
+
* calls through `this` (transitively, over the class and its bases),
|
|
4212
|
+
* outside nested functions. The constructor's own reads are not included:
|
|
4213
|
+
* they run where the constructor's statements put them. */
|
|
4214
|
+
function constructorMethodReads(decl, base, ctor) {
|
|
4215
|
+
const reads = new Set();
|
|
4216
|
+
const visited = new Set();
|
|
4217
|
+
const bodies = (name) => {
|
|
4218
|
+
const out = [];
|
|
4219
|
+
let owner = decl;
|
|
4220
|
+
for (let next = base; owner; owner = next?.decl ?? undefined, next = next?.base ?? null) {
|
|
4221
|
+
for (const member of owner.members.nodes) {
|
|
4222
|
+
if ((ts.isMethodDeclaration(member) || ts.isAccessor(member)) &&
|
|
4223
|
+
member.body &&
|
|
4224
|
+
(ts.isIdentifier(member.name) || ts.isPrivateIdentifier(member.name)) &&
|
|
4225
|
+
member.name.text === name)
|
|
4226
|
+
out.push(member.body);
|
|
4227
|
+
}
|
|
4228
|
+
}
|
|
4229
|
+
return out;
|
|
4230
|
+
};
|
|
4231
|
+
const enter = (name) => {
|
|
4232
|
+
if (visited.has(name))
|
|
4233
|
+
return;
|
|
4234
|
+
visited.add(name);
|
|
4235
|
+
for (const body of bodies(name))
|
|
4236
|
+
scan(body, true);
|
|
4237
|
+
};
|
|
4238
|
+
// Nested functions (callbacks handed elsewhere) are not followed: only
|
|
4239
|
+
// the straight-line code of the constructor and the methods it calls.
|
|
4240
|
+
const scan = (node, inMethod) => {
|
|
4241
|
+
ts.walkPreorder(node, (n) => {
|
|
4242
|
+
if (n !== node && ts.isFunctionLike(n))
|
|
4243
|
+
return "skip";
|
|
4244
|
+
if (ts.isPropertyAccessExpression(n) &&
|
|
4245
|
+
n.expression.kind === ts.SyntaxKind.ThisKeyword &&
|
|
4246
|
+
(ts.isIdentifier(n.name) || ts.isPrivateIdentifier(n.name))) {
|
|
4247
|
+
if (inMethod)
|
|
4248
|
+
reads.add(n.name.text);
|
|
4249
|
+
enter(n.name.text);
|
|
4250
|
+
}
|
|
4251
|
+
return undefined;
|
|
4252
|
+
});
|
|
4253
|
+
};
|
|
4254
|
+
if (ctor?.body)
|
|
4255
|
+
scan(ctor.body, false);
|
|
4256
|
+
return reads;
|
|
4257
|
+
}
|
|
3864
4258
|
/** The nearest GENERIC static declaration of `name` at/above `info` —
|
|
3865
4259
|
* findStaticOn's twin over the genericStatics tables. */
|
|
3866
4260
|
export function findGenericStaticOn(lowerer, info, name) {
|
|
@@ -3915,17 +4309,22 @@ export function classValueRef(lowerer, info, blame) {
|
|
|
3915
4309
|
lowerer.unsupported("SC1090", blame, `generic classes as values ('typeof ${display}' keeps the type parameter — instantiation expressions ('${display}<number>') and concrete constructor-typed slots compile)`);
|
|
3916
4310
|
}
|
|
3917
4311
|
if (info.builtinError || info.builtinEmitter || info.builtinStream !== undefined) {
|
|
3918
|
-
|
|
3919
|
-
|
|
3920
|
-
|
|
3921
|
-
|
|
3922
|
-
|
|
3923
|
-
|
|
3924
|
-
|
|
3925
|
-
|
|
3926
|
-
|
|
3927
|
-
|
|
3928
|
-
|
|
4312
|
+
if (info.valueCtorParams === undefined) {
|
|
4313
|
+
lowerer.unsupported("SC1090", blame, `builtin classes as values ('${display}' is runtime-provided — reference program-declared classes instead)`);
|
|
4314
|
+
}
|
|
4315
|
+
defineClassValueConstruct(lowerer, info);
|
|
4316
|
+
return {
|
|
4317
|
+
kind: "classRef",
|
|
4318
|
+
className: info.def.name,
|
|
4319
|
+
type: { kind: "classval", className: info.def.name },
|
|
4320
|
+
loc: locOf(blame),
|
|
4321
|
+
};
|
|
4322
|
+
}
|
|
4323
|
+
// Classes extending EventEmitter or a stream class construct through
|
|
4324
|
+
// their own (or synthesized) `%C.constructor`, whose super call runs the
|
|
4325
|
+
// runtime initializer, so the class object's construct thunk serves them
|
|
4326
|
+
// like any program class. EventTarget subclasses keep the refusal.
|
|
4327
|
+
if (eventTargetRootOf(info) !== null) {
|
|
3929
4328
|
lowerer.unsupported("SC1090", blame, `classes extending builtin bases as values ('${display}' inherits a runtime-provided constructor)`);
|
|
3930
4329
|
}
|
|
3931
4330
|
lowerer.noteEdge(`%${info.def.name}.constructor`);
|
|
@@ -3936,14 +4335,94 @@ export function classValueRef(lowerer, info, blame) {
|
|
|
3936
4335
|
loc: locOf(blame),
|
|
3937
4336
|
};
|
|
3938
4337
|
}
|
|
4338
|
+
/** Notes a runtime-provided class whose value is named, widened to, or
|
|
4339
|
+
* constructed through (a no-op for program classes, whose constructor is
|
|
4340
|
+
* their own). runtimeClassConstructs defines `%C.construct` for the
|
|
4341
|
+
* noted classes the finished module still references. */
|
|
4342
|
+
export function defineClassValueConstruct(lowerer, info) {
|
|
4343
|
+
if (!info.def.runtime || info.valueCtorParams === undefined)
|
|
4344
|
+
return;
|
|
4345
|
+
lowerer.noteEdge(classValueConstructor(info.def).fn);
|
|
4346
|
+
lowerer.runtimeClassValues.set(info.def.name, info);
|
|
4347
|
+
}
|
|
4348
|
+
/** The `%C.construct` functions of the noted runtime classes that a
|
|
4349
|
+
* classRef, newValue or classval upcast in `functions` names. Lowering can
|
|
4350
|
+
* name a class speculatively and discard the expression, so the finished
|
|
4351
|
+
* functions decide. */
|
|
4352
|
+
export function runtimeClassConstructs(lowerer, functions) {
|
|
4353
|
+
if (lowerer.runtimeClassValues.size === 0)
|
|
4354
|
+
return [];
|
|
4355
|
+
const used = new Set();
|
|
4356
|
+
const note = (type) => {
|
|
4357
|
+
if (type.kind === "classval" && lowerer.runtimeClassValues.has(type.className))
|
|
4358
|
+
used.add(type.className);
|
|
4359
|
+
};
|
|
4360
|
+
const visitor = {
|
|
4361
|
+
expr: (e) => {
|
|
4362
|
+
if (e.kind === "classRef")
|
|
4363
|
+
note(e.type);
|
|
4364
|
+
else if (e.kind === "newValue")
|
|
4365
|
+
note(e.callee.type);
|
|
4366
|
+
else if (e.kind === "upcast") {
|
|
4367
|
+
note(e.type);
|
|
4368
|
+
note(e.value.type);
|
|
4369
|
+
}
|
|
4370
|
+
return true;
|
|
4371
|
+
},
|
|
4372
|
+
stmt: () => true,
|
|
4373
|
+
};
|
|
4374
|
+
for (const fn of functions)
|
|
4375
|
+
everyStmtList(fn.body, visitor);
|
|
4376
|
+
return [...used]
|
|
4377
|
+
.sort()
|
|
4378
|
+
.map((name) => runtimeClassConstruct(lowerer.runtimeClassValues.get(name)));
|
|
4379
|
+
}
|
|
4380
|
+
/** `%C.construct` for a runtime-provided class value: the thunk's target,
|
|
4381
|
+
* which builds the instance through the runtime constructor the direct
|
|
4382
|
+
* `new C(...)` uses (emitter.new, a stream's .newDyn without options,
|
|
4383
|
+
* error.newOptions). */
|
|
4384
|
+
function runtimeClassConstruct(info) {
|
|
4385
|
+
const params = info.valueCtorParams ?? [];
|
|
4386
|
+
const name = classValueConstructor(info.def).fn;
|
|
4387
|
+
const loc = info.def.loc;
|
|
4388
|
+
const type = { kind: "object", className: info.def.name };
|
|
4389
|
+
const ids = params.map((_, i) => `a${i}.0`);
|
|
4390
|
+
const args = ids.map((id) => varRef(id, DYN, loc));
|
|
4391
|
+
let fn = "error.newOptions";
|
|
4392
|
+
if (info.builtinEmitter)
|
|
4393
|
+
fn = "emitter.new";
|
|
4394
|
+
else if (info.builtinStream !== undefined) {
|
|
4395
|
+
fn = `${streamCtorShape(info.def.name).fn}.newDyn`;
|
|
4396
|
+
args.push(dynUndefinedExpr(loc));
|
|
4397
|
+
}
|
|
4398
|
+
return {
|
|
4399
|
+
name,
|
|
4400
|
+
params: params.map((shape, i) => ({ localId: ids[i], name: `a${i}`, type: shape.type })),
|
|
4401
|
+
returnType: type,
|
|
4402
|
+
locals: params.map((shape, i) => ({
|
|
4403
|
+
id: ids[i],
|
|
4404
|
+
name: `a${i}`,
|
|
4405
|
+
type: shape.type,
|
|
4406
|
+
mutable: false,
|
|
4407
|
+
})),
|
|
4408
|
+
body: [{ kind: "return", value: { kind: "libCall", fn, args, type, loc }, loc }],
|
|
4409
|
+
loc,
|
|
4410
|
+
};
|
|
4411
|
+
}
|
|
4412
|
+
/** The constructor parameters construction through a class value completes
|
|
4413
|
+
* against: a program class's constructor, or a runtime class's
|
|
4414
|
+
* `%C.construct`. */
|
|
4415
|
+
function classValueParams(info) {
|
|
4416
|
+
return info.def.runtime ? (info.valueCtorParams ?? info.ctorParams) : info.ctorParams;
|
|
4417
|
+
}
|
|
3939
4418
|
/** Constructor-ABI equality — the classval widening rule: a classval(D)
|
|
3940
4419
|
* value may flow into a classval(C) slot only when D's completed
|
|
3941
4420
|
* constructor signature equals C's (same count, modes, and ABI types),
|
|
3942
4421
|
* which is what keeps newValue completion against C's one signature
|
|
3943
4422
|
* sound for every value legally in the slot. */
|
|
3944
4423
|
export function ctorAbiEquals(lowerer, sub, sup) {
|
|
3945
|
-
const a = sub
|
|
3946
|
-
const b = sup
|
|
4424
|
+
const a = classValueParams(sub);
|
|
4425
|
+
const b = classValueParams(sup);
|
|
3947
4426
|
return (a.length === b.length &&
|
|
3948
4427
|
a.every((p, i) => p.mode === b[i].mode && typeEquals(p.type, b[i].type)));
|
|
3949
4428
|
}
|
|
@@ -4042,8 +4521,18 @@ export function lowerStaticFieldRead(lowerer, expr) {
|
|
|
4042
4521
|
}
|
|
4043
4522
|
// `C.name` — the JS-observable class name, a compile-time constant on
|
|
4044
4523
|
// the direct spelling (tsc rejects user statics named `name`, so the
|
|
4045
|
-
// chain above can never shadow it in TypeScript sources).
|
|
4524
|
+
// chain above can never shadow it in TypeScript sources). A class of an
|
|
4525
|
+
// import cycle reads it from its class object instead, whose reference
|
|
4526
|
+
// checks the class's initialization (checkCycleBindingAccesses).
|
|
4046
4527
|
if (expr.name.text === "name" && info.def.jsName !== undefined) {
|
|
4528
|
+
if (lowerer.classInitFlags.get(info.def.name)?.cycle === true)
|
|
4529
|
+
return {
|
|
4530
|
+
kind: "libCall",
|
|
4531
|
+
fn: "class.name",
|
|
4532
|
+
args: [classValueRef(lowerer, info, expr.expression)],
|
|
4533
|
+
type: STRING,
|
|
4534
|
+
loc,
|
|
4535
|
+
};
|
|
4047
4536
|
return { kind: "strLit", value: info.def.jsName, type: STRING, loc };
|
|
4048
4537
|
}
|
|
4049
4538
|
if (info.callableBase)
|
|
@@ -4066,7 +4555,7 @@ export function lowerStaticFieldRead(lowerer, expr) {
|
|
|
4066
4555
|
// JavaScript often assigns public statics after the class declaration.
|
|
4067
4556
|
// Their storage stays mutable and checked, while reads retain the
|
|
4068
4557
|
// checker's concrete type instead of losing the method receiver.
|
|
4069
|
-
const type = isJsSourceFile(
|
|
4558
|
+
const type = isJsSourceFile(ts.getSourceFileOfNode(expr))
|
|
4070
4559
|
? null
|
|
4071
4560
|
: lowerer.mapTypeOf(lowerer.typeOf(expr));
|
|
4072
4561
|
return type ? lowerer.coerceToExpected(value, type) : value;
|
|
@@ -4097,6 +4586,70 @@ function namedEvaluationName(expr) {
|
|
|
4097
4586
|
return p.name.text;
|
|
4098
4587
|
return "";
|
|
4099
4588
|
}
|
|
4589
|
+
/** Each evaluation of a function-local class creates fresh private names,
|
|
4590
|
+
* while the compiled class shares one layout across evaluations. A
|
|
4591
|
+
* JavaScript class's prototype methods are closures per evaluation, so the
|
|
4592
|
+
* names agree when every private member is an instance field and every use
|
|
4593
|
+
* is on `this` (privateNamesOnlyOnThis): native methods only run on their
|
|
4594
|
+
* own evaluation's instances, and the closures, which receive any `this`,
|
|
4595
|
+
* check the receiver's evaluation against the class's own binding
|
|
4596
|
+
* (private-brands.ts), so the class must be a named declaration (undici's
|
|
4597
|
+
* webidl FastIterableIterator). The checker rejects writes to that binding. */
|
|
4598
|
+
function localPrivateFieldsAgree(expr) {
|
|
4599
|
+
if (!isJsSourceFile(ts.getSourceFileOfNode(expr)) || !ts.isClassDeclaration(expr) || !expr.name)
|
|
4600
|
+
return false;
|
|
4601
|
+
if (expr.members.nodes.some((member) => member.name !== undefined &&
|
|
4602
|
+
ts.isPrivateIdentifier(member.name) &&
|
|
4603
|
+
!ts.isPropertyDeclaration(member)))
|
|
4604
|
+
return false;
|
|
4605
|
+
return privateNamesOnlyOnThis(expr);
|
|
4606
|
+
}
|
|
4607
|
+
/** Every private name is used only on `this` inside the class's own instance
|
|
4608
|
+
* members (`this.#x`, `#x in this`), outside nested classes and non-arrow
|
|
4609
|
+
* functions, and the class has no static members that could hand instances
|
|
4610
|
+
* across evaluations. */
|
|
4611
|
+
function privateNamesOnlyOnThis(expr) {
|
|
4612
|
+
let ok = true;
|
|
4613
|
+
for (const member of expr.members.nodes) {
|
|
4614
|
+
if (ts.getModifiers(member)?.some((m) => m.kind === ts.SyntaxKind.StaticKeyword))
|
|
4615
|
+
return false;
|
|
4616
|
+
ts.walkPreorder(member, (node) => {
|
|
4617
|
+
if (!ok)
|
|
4618
|
+
return "stop";
|
|
4619
|
+
// A nested class or non-arrow function rebinds `this`: any private
|
|
4620
|
+
// name inside it disqualifies.
|
|
4621
|
+
if (node !== member &&
|
|
4622
|
+
(ts.isClassDeclaration(node) ||
|
|
4623
|
+
ts.isClassExpression(node) ||
|
|
4624
|
+
ts.isFunctionExpression(node) ||
|
|
4625
|
+
ts.isFunctionDeclaration(node))) {
|
|
4626
|
+
ts.walkPreorder(node, (inner) => {
|
|
4627
|
+
if (ts.isPrivateIdentifier(inner))
|
|
4628
|
+
ok = false;
|
|
4629
|
+
return ok ? undefined : "stop";
|
|
4630
|
+
});
|
|
4631
|
+
return "skip";
|
|
4632
|
+
}
|
|
4633
|
+
if (ts.isPrivateIdentifier(node)) {
|
|
4634
|
+
const parent = node.parent;
|
|
4635
|
+
const onThis = parent === member ||
|
|
4636
|
+
(ts.isPropertyAccessExpression(parent) &&
|
|
4637
|
+
parent.name === node &&
|
|
4638
|
+
parent.expression.kind === ts.SyntaxKind.ThisKeyword) ||
|
|
4639
|
+
(ts.isBinaryExpression(parent) &&
|
|
4640
|
+
parent.left === node &&
|
|
4641
|
+
parent.operatorToken.kind === ts.SyntaxKind.InKeyword &&
|
|
4642
|
+
parent.right.kind === ts.SyntaxKind.ThisKeyword);
|
|
4643
|
+
if (!onThis)
|
|
4644
|
+
ok = false;
|
|
4645
|
+
}
|
|
4646
|
+
return undefined;
|
|
4647
|
+
});
|
|
4648
|
+
if (!ok)
|
|
4649
|
+
return false;
|
|
4650
|
+
}
|
|
4651
|
+
return true;
|
|
4652
|
+
}
|
|
4100
4653
|
/** Collect a class expression once per enclosing specialization. Function-local
|
|
4101
4654
|
* evaluations allocate fresh constructor objects; top-level expressions use
|
|
4102
4655
|
* immortal templates. Static initialization remains limited to whole top-level
|
|
@@ -4123,19 +4676,21 @@ export function lowerClassExpressionInfo(lowerer, expr) {
|
|
|
4123
4676
|
if (ts.isFunctionLike(p))
|
|
4124
4677
|
local = true;
|
|
4125
4678
|
}
|
|
4126
|
-
if (local &&
|
|
4679
|
+
if (local &&
|
|
4680
|
+
expr.members.nodes.some((member) => member.name && ts.isPrivateIdentifier(member.name)) &&
|
|
4681
|
+
!localPrivateFieldsAgree(expr)) {
|
|
4127
4682
|
lowerer.unsupported("SC1090", expr, "function-local classes with private brands");
|
|
4128
4683
|
}
|
|
4129
4684
|
if (local &&
|
|
4130
|
-
(expr.typeParameters?.length ||
|
|
4685
|
+
(expr.typeParameters?.nodes.length ||
|
|
4131
4686
|
decoratorNodesOf(expr).length ||
|
|
4132
|
-
expr.members.some((member) => decoratorNodesOf(member).length ||
|
|
4133
|
-
(!isJsSourceFile(
|
|
4687
|
+
expr.members.nodes.some((member) => decoratorNodesOf(member).length ||
|
|
4688
|
+
(!isJsSourceFile(ts.getSourceFileOfNode(expr)) &&
|
|
4134
4689
|
(ts.isClassStaticBlockDeclaration(member) ||
|
|
4135
4690
|
ts
|
|
4136
4691
|
.getModifiers(member)
|
|
4137
4692
|
?.some((modifier) => modifier.kind === ts.SyntaxKind.StaticKeyword))) ||
|
|
4138
|
-
(ts.isMethodDeclaration(member) && member.typeParameters?.length)))) {
|
|
4693
|
+
(ts.isMethodDeclaration(member) && member.typeParameters?.nodes.length)))) {
|
|
4139
4694
|
lowerer.unsupported("SC1090", expr, "function-local classes with statics, decorators, or generic members");
|
|
4140
4695
|
}
|
|
4141
4696
|
lowerer.collectingExprClasses.add(expr);
|
|
@@ -4143,9 +4698,9 @@ export function lowerClassExpressionInfo(lowerer, expr) {
|
|
|
4143
4698
|
if (local &&
|
|
4144
4699
|
lowerer.fnStack.length > 0 &&
|
|
4145
4700
|
!lowerer.computedClassBases.has(lowerer.classNamer(expr))) {
|
|
4146
|
-
const heritage = expr.heritageClauses?.find((clause) => clause.token === ts.SyntaxKind.ExtendsKeyword)?.types[0]?.expression;
|
|
4701
|
+
const heritage = expr.heritageClauses?.nodes.find((clause) => clause.token === ts.SyntaxKind.ExtendsKeyword)?.types?.nodes[0]?.expression;
|
|
4147
4702
|
if (heritage &&
|
|
4148
|
-
(ts.isCallExpression(heritage) ||
|
|
4703
|
+
((ts.isCallExpression(heritage) && !builtinRequireBaseOf(lowerer, heritage)) ||
|
|
4149
4704
|
(ts.isIdentifier(heritage) &&
|
|
4150
4705
|
(lowerer.peekLocal(heritage) ?? lowerer.globalOf(heritage)) != null))) {
|
|
4151
4706
|
let value = lowerer.lowerExpr(heritage);
|
|
@@ -4175,7 +4730,7 @@ export function lowerClassExpressionInfo(lowerer, expr) {
|
|
|
4175
4730
|
});
|
|
4176
4731
|
info.localClass = { context: null, bodies: new Map(), captureSources: [], ready: false };
|
|
4177
4732
|
if (info.base?.localClass) {
|
|
4178
|
-
const baseExpression = expr.heritageClauses?.find((clause) => clause.token === ts.SyntaxKind.ExtendsKeyword)?.types[0]?.expression;
|
|
4733
|
+
const baseExpression = expr.heritageClauses?.nodes.find((clause) => clause.token === ts.SyntaxKind.ExtendsKeyword)?.types?.nodes[0]?.expression;
|
|
4179
4734
|
if (baseExpression)
|
|
4180
4735
|
info.localClass.baseExpression = baseExpression;
|
|
4181
4736
|
}
|
|
@@ -4206,7 +4761,7 @@ export function lowerClassExpressionInfo(lowerer, expr) {
|
|
|
4206
4761
|
const wholeInit = (ts.isVariableDeclaration(holder) &&
|
|
4207
4762
|
holder.initializer !== undefined &&
|
|
4208
4763
|
ts.isVariableDeclarationList(holder.parent) &&
|
|
4209
|
-
holder.parent.declarations.length === 1 &&
|
|
4764
|
+
holder.parent.declarations.nodes.length === 1 &&
|
|
4210
4765
|
ts.isVariableStatement(holder.parent.parent) &&
|
|
4211
4766
|
ts.isSourceFile(holder.parent.parent.parent)) ||
|
|
4212
4767
|
(ts.isBinaryExpression(holder) &&
|
|
@@ -4230,8 +4785,8 @@ export function lowerClassExpressionInfo(lowerer, expr) {
|
|
|
4230
4785
|
* the member fences don't apply. */
|
|
4231
4786
|
export function lowerClassExpression(lowerer, expr) {
|
|
4232
4787
|
if (decoratorNodesOf(expr).length > 0 ||
|
|
4233
|
-
expr.members.some((m) => decoratorNodesOf(m).length > 0)) {
|
|
4234
|
-
if (!isJsSourceFile(
|
|
4788
|
+
expr.members.nodes.some((m) => decoratorNodesOf(m).length > 0)) {
|
|
4789
|
+
if (!isJsSourceFile(ts.getSourceFileOfNode(expr)) && expr.typeParameters === undefined) {
|
|
4235
4790
|
const thrown = guaranteedDecorationThrow(lowerer, expr);
|
|
4236
4791
|
if (thrown) {
|
|
4237
4792
|
// The expression's static type never materializes — the read
|
|
@@ -4413,7 +4968,7 @@ export function exactClassOfReceiver(lowerer, expr) {
|
|
|
4413
4968
|
// class-value write fence answers instead.
|
|
4414
4969
|
if (direct)
|
|
4415
4970
|
return direct.classDecorators?.valueGlobalId !== undefined ? null : direct;
|
|
4416
|
-
const decl =
|
|
4971
|
+
const decl = symbol.valueDeclaration;
|
|
4417
4972
|
if (!decl ||
|
|
4418
4973
|
!ts.isVariableDeclaration(decl) ||
|
|
4419
4974
|
decl.initializer === undefined ||
|
|
@@ -4457,7 +5012,7 @@ export function propertyAssignedClassInfoOf(lowerer, symbol) {
|
|
|
4457
5012
|
const registered = lowerer.classBySymbol.get(resolved);
|
|
4458
5013
|
if (registered)
|
|
4459
5014
|
return registered;
|
|
4460
|
-
const decls =
|
|
5015
|
+
const decls = resolved.declarations;
|
|
4461
5016
|
// The class expression's OWN symbol (tsgo's answer through CJS export
|
|
4462
5017
|
// aliases): the declaration is the expression itself. Its top-level
|
|
4463
5018
|
// assignment statement must be the binding's ONLY producer. The
|
|
@@ -4511,17 +5066,17 @@ function enclosingTopLevelClassAssignment(expr) {
|
|
|
4511
5066
|
* `Common.I`): a second assignment makes the binding dynamic, so
|
|
4512
5067
|
* callers refuse to pin the first one's class. */
|
|
4513
5068
|
function countAssignmentsTo(assign) {
|
|
4514
|
-
const sf =
|
|
5069
|
+
const sf = ts.getSourceFileOfNode(assign);
|
|
4515
5070
|
// `exports.I` and `module.exports.I` are the SAME binding in Node
|
|
4516
5071
|
// (exports aliases module.exports until a table replaces it) — fold
|
|
4517
5072
|
// the member spellings together before comparing.
|
|
4518
5073
|
const canon = (lhs) => {
|
|
4519
|
-
const text =
|
|
5074
|
+
const text = ts.getTextOfNode(lhs).replace(/\s+/g, "");
|
|
4520
5075
|
return text.startsWith("module.exports.") ? text.slice("module.".length) : text;
|
|
4521
5076
|
};
|
|
4522
5077
|
const target = canon(assign.left);
|
|
4523
5078
|
let n = 0;
|
|
4524
|
-
for (const stmt of sf.statements) {
|
|
5079
|
+
for (const stmt of sf.statements.nodes) {
|
|
4525
5080
|
if (!ts.isExpressionStatement(stmt))
|
|
4526
5081
|
continue;
|
|
4527
5082
|
const e = stmt.expression;
|
|
@@ -4569,9 +5124,9 @@ export function lowerStaticMethodCall(lowerer, call, access) {
|
|
|
4569
5124
|
// export assignment pins it) — the direct-name rules apply.
|
|
4570
5125
|
if (!ts.isIdentifier(access.expression)) {
|
|
4571
5126
|
if (!isModuleExportsAccess(access.expression) ||
|
|
4572
|
-
!isCjsJsFile(
|
|
5127
|
+
!isCjsJsFile(ts.getSourceFileOfNode(access), lowerer.program)) {
|
|
4573
5128
|
let receiverType = lowerer.mapTypeOf(lowerer.typeOf(access.expression));
|
|
4574
|
-
if (receiverType?.kind !== "classval" && isJsSourceFile(
|
|
5129
|
+
if (receiverType?.kind !== "classval" && isJsSourceFile(ts.getSourceFileOfNode(call))) {
|
|
4575
5130
|
const receiver = tryLowerExpression(lowerer, access.expression);
|
|
4576
5131
|
if (receiver?.type.kind === "classval")
|
|
4577
5132
|
receiverType = receiver.type;
|
|
@@ -4596,7 +5151,7 @@ export function lowerStaticMethodCall(lowerer, call, access) {
|
|
|
4596
5151
|
loc: locOf(call),
|
|
4597
5152
|
};
|
|
4598
5153
|
}
|
|
4599
|
-
const whole = cjsClassExprWholeExportOf(
|
|
5154
|
+
const whole = cjsClassExprWholeExportOf(ts.getSourceFileOfNode(access));
|
|
4600
5155
|
if (!whole)
|
|
4601
5156
|
return null;
|
|
4602
5157
|
return staticCallOn(lowerer, call, access, lowerer.lowerClassExpressionInfo(whole.classExpr), false);
|
|
@@ -4637,6 +5192,9 @@ function classValueIsExactlyOwn(lowerer, recv, info) {
|
|
|
4637
5192
|
}
|
|
4638
5193
|
function staticCallOn(lowerer, call, access, info, throughValue) {
|
|
4639
5194
|
const loc = locOf(call);
|
|
5195
|
+
const runtimeStatic = directRuntimeStaticCall(lowerer, call, access, info, throughValue);
|
|
5196
|
+
if (runtimeStatic)
|
|
5197
|
+
return runtimeStatic;
|
|
4640
5198
|
if ((hasRuntimeStatics(info) && !findStaticOn(lowerer, info, access.name.text)?.field) ||
|
|
4641
5199
|
(info.callableBase &&
|
|
4642
5200
|
!findStaticOn(lowerer, info, access.name.text) &&
|
|
@@ -4646,7 +5204,7 @@ function staticCallOn(lowerer, call, access, info, throughValue) {
|
|
|
4646
5204
|
recv: lowerer.lowerExprExpecting(access.expression, DYN),
|
|
4647
5205
|
method: access.name.text,
|
|
4648
5206
|
calleeName: access.name.text,
|
|
4649
|
-
args: call.arguments.map((argument) => lowerer.lowerExprExpecting(argument, DYN)),
|
|
5207
|
+
args: call.arguments.nodes.map((argument) => lowerer.lowerExprExpecting(argument, DYN)),
|
|
4650
5208
|
type: DYN,
|
|
4651
5209
|
loc,
|
|
4652
5210
|
};
|
|
@@ -4676,7 +5234,7 @@ function staticCallOn(lowerer, call, access, info, throughValue) {
|
|
|
4676
5234
|
lowerer.unsupported("SC1090", call, `calling the static member '${access.name.text}' through a class value (a subclass of '${info.def.name.replace(/^%|^%m\d+\./, "")}' redeclares it, so the runtime class decides which declaration answers)`);
|
|
4677
5235
|
}
|
|
4678
5236
|
const instance = genericCallInstance(lowerer, call, staticMethodForReceiver(lowerer, access, gfound.info, info, throughValue));
|
|
4679
|
-
const args = lowerer.completeArgs(call.arguments, instance.params, loc, call);
|
|
5237
|
+
const args = lowerer.completeArgs(call.arguments.nodes, instance.params, loc, call);
|
|
4680
5238
|
return { kind: "call", callee: instance.name, args, type: instance.returnType, loc };
|
|
4681
5239
|
}
|
|
4682
5240
|
if (throughValue && staticShadowBelow(info, access.name.text)) {
|
|
@@ -4685,7 +5243,7 @@ function staticCallOn(lowerer, call, access, info, throughValue) {
|
|
|
4685
5243
|
const specialized = findGenericStaticOn(lowerer, info, access.name.text);
|
|
4686
5244
|
if (specialized?.declarer === found.declarer && specialized.info.implicitParams) {
|
|
4687
5245
|
const instance = implicitCallInstance(lowerer, call, staticMethodForReceiver(lowerer, access, specialized.info, info, throughValue));
|
|
4688
|
-
const args = lowerer.completeArgs(call.arguments, instance.params, loc, call);
|
|
5246
|
+
const args = lowerer.completeArgs(call.arguments.nodes, instance.params, loc, call);
|
|
4689
5247
|
return { kind: "call", callee: instance.name, args, type: instance.returnType, loc };
|
|
4690
5248
|
}
|
|
4691
5249
|
if (found.field !== undefined) {
|
|
@@ -4700,7 +5258,7 @@ function staticCallOn(lowerer, call, access, info, throughValue) {
|
|
|
4700
5258
|
loc,
|
|
4701
5259
|
};
|
|
4702
5260
|
const params = found.field.type.params;
|
|
4703
|
-
const args = call.arguments.map((a, i) => lowerer.lowerExprExpecting(a, params[i]));
|
|
5261
|
+
const args = call.arguments.nodes.map((a, i) => lowerer.lowerExprExpecting(a, params[i]));
|
|
4704
5262
|
for (let i = args.length; i < params.length; i++) {
|
|
4705
5263
|
const absent = omittedArgFor(lowerer, params[i], loc);
|
|
4706
5264
|
if (!absent) {
|
|
@@ -4730,16 +5288,184 @@ function staticCallOn(lowerer, call, access, info, throughValue) {
|
|
|
4730
5288
|
return {
|
|
4731
5289
|
kind: "call",
|
|
4732
5290
|
callee: instance.name,
|
|
4733
|
-
args: lowerer.completeArgs(call.arguments, instance.params, loc, call),
|
|
5291
|
+
args: lowerer.completeArgs(call.arguments.nodes, instance.params, loc, call),
|
|
4734
5292
|
type: instance.returnType,
|
|
4735
5293
|
loc,
|
|
4736
5294
|
};
|
|
4737
5295
|
}
|
|
4738
5296
|
const fnName = `%${found.declarer.def.name}.static:${access.name.text}`;
|
|
4739
5297
|
lowerer.noteEdge(fnName);
|
|
4740
|
-
const args = lowerer.completeArgs(call.arguments, found.method.params, loc, call);
|
|
5298
|
+
const args = lowerer.completeArgs(call.arguments.nodes, found.method.params, loc, call);
|
|
4741
5299
|
return { kind: "call", callee: fnName, args, type: found.method.ret, loc };
|
|
4742
5300
|
}
|
|
5301
|
+
/** `C.m(...)` where `m` is a static method that a function-local
|
|
5302
|
+
* JavaScript class defines at runtime (a factory's `class extends base`),
|
|
5303
|
+
* inherited by `C` through its statically known base chain. When the body
|
|
5304
|
+
* captures nothing from the factory's scope, every evaluation of the class
|
|
5305
|
+
* defines the same method, so the call lowers directly with `this` bound
|
|
5306
|
+
* to `C`, as a free function given `C` would. A receiver-dependent result
|
|
5307
|
+
* (a class built from `this`) then keeps a static base. Null when another
|
|
5308
|
+
* declaration of `m` answers first, the program assigns that member, or
|
|
5309
|
+
* the method form has no direct lowering. */
|
|
5310
|
+
function directRuntimeStaticCall(lowerer, call, access, info, throughValue) {
|
|
5311
|
+
const name = access.name.text;
|
|
5312
|
+
if (throughValue || name.startsWith("#"))
|
|
5313
|
+
return null;
|
|
5314
|
+
let declarer = null;
|
|
5315
|
+
let member = null;
|
|
5316
|
+
for (let c = info; c; c = c.base) {
|
|
5317
|
+
if (c.staticFields.some((field) => field.name === name) ||
|
|
5318
|
+
c.staticMethods?.has(name) === true ||
|
|
5319
|
+
c.genericStatics?.has(name) === true)
|
|
5320
|
+
return null;
|
|
5321
|
+
const runtime = c.runtimeStatics?.find((element) => element.name !== undefined &&
|
|
5322
|
+
ts.isIdentifier(element.name) &&
|
|
5323
|
+
element.name.text === name);
|
|
5324
|
+
if (runtime) {
|
|
5325
|
+
if (!ts.isMethodDeclaration(runtime) || !runtime.body)
|
|
5326
|
+
return null;
|
|
5327
|
+
declarer = c;
|
|
5328
|
+
member = runtime;
|
|
5329
|
+
break;
|
|
5330
|
+
}
|
|
5331
|
+
}
|
|
5332
|
+
if (!declarer || !member || !declarer.decl)
|
|
5333
|
+
return null;
|
|
5334
|
+
if (member.asteriskToken || member.typeParameters?.nodes)
|
|
5335
|
+
return null;
|
|
5336
|
+
if (member.modifiers?.nodes.some((modifier) => modifier.kind === ts.SyntaxKind.AsyncKeyword))
|
|
5337
|
+
return null;
|
|
5338
|
+
if (hasLexicalSuper(member) || capturesEnclosingScope(lowerer, member, declarer.decl))
|
|
5339
|
+
return null;
|
|
5340
|
+
if (memberAssigned(lowerer, member, name) || bodyReadsArguments(member))
|
|
5341
|
+
return null;
|
|
5342
|
+
const implicit = member.parameters.nodes.length === 0 ? null : implicitAnyParamSymbolsOf(lowerer, member, true);
|
|
5343
|
+
if (member.parameters.nodes.length > 0 && !implicit)
|
|
5344
|
+
return null;
|
|
5345
|
+
let calls = declarer.runtimeStaticCalls;
|
|
5346
|
+
if (!calls) {
|
|
5347
|
+
calls = new Map();
|
|
5348
|
+
declarer.runtimeStaticCalls = calls;
|
|
5349
|
+
}
|
|
5350
|
+
const method = calls.get(name) ?? {
|
|
5351
|
+
decl: member,
|
|
5352
|
+
baseName: name,
|
|
5353
|
+
qualifiedName: `%${declarer.def.name}.runtimeStatic:${name}`,
|
|
5354
|
+
typeParams: [],
|
|
5355
|
+
instances: new Map(),
|
|
5356
|
+
member: { cls: declarer, kind: "static" },
|
|
5357
|
+
...(implicit ? { implicitParams: implicit } : {}),
|
|
5358
|
+
};
|
|
5359
|
+
calls.set(name, method);
|
|
5360
|
+
// A direct lowering the method form does not support keeps the dynamic
|
|
5361
|
+
// call: its refusal is not this program's error.
|
|
5362
|
+
const sink = [];
|
|
5363
|
+
const previousSink = lowerer.diagSink;
|
|
5364
|
+
lowerer.diagSink = sink;
|
|
5365
|
+
let lowered;
|
|
5366
|
+
try {
|
|
5367
|
+
const receiver = staticMethodForReceiver(lowerer, access, method, info, false);
|
|
5368
|
+
const instance = implicit
|
|
5369
|
+
? implicitCallInstance(lowerer, call, receiver)
|
|
5370
|
+
: genericCallInstance(lowerer, call, receiver);
|
|
5371
|
+
lowered = {
|
|
5372
|
+
kind: "call",
|
|
5373
|
+
callee: instance.name,
|
|
5374
|
+
args: lowerer.completeArgs(call.arguments.nodes, instance.params, locOf(call), call),
|
|
5375
|
+
type: instance.returnType,
|
|
5376
|
+
loc: locOf(call),
|
|
5377
|
+
};
|
|
5378
|
+
}
|
|
5379
|
+
catch (error) {
|
|
5380
|
+
if (error instanceof PoisonError)
|
|
5381
|
+
return null;
|
|
5382
|
+
throw error;
|
|
5383
|
+
}
|
|
5384
|
+
finally {
|
|
5385
|
+
lowerer.diagSink = previousSink;
|
|
5386
|
+
}
|
|
5387
|
+
return sink.length === 0 ? lowered : null;
|
|
5388
|
+
}
|
|
5389
|
+
/** `super` inside the method (arrows included) names the defining
|
|
5390
|
+
* class's base, which a receiver specialization does not track. */
|
|
5391
|
+
function hasLexicalSuper(root) {
|
|
5392
|
+
let found = false;
|
|
5393
|
+
const visit = (node) => {
|
|
5394
|
+
if (node.kind === ts.SyntaxKind.SuperKeyword)
|
|
5395
|
+
found = true;
|
|
5396
|
+
if ((ts.isFunctionLike(node) && !ts.isArrowFunction(node)) ||
|
|
5397
|
+
ts.isClassDeclaration(node) ||
|
|
5398
|
+
ts.isClassExpression(node))
|
|
5399
|
+
return;
|
|
5400
|
+
ts.forEachChild(node, visit);
|
|
5401
|
+
};
|
|
5402
|
+
ts.forEachChild(root, visit);
|
|
5403
|
+
return found;
|
|
5404
|
+
}
|
|
5405
|
+
/** The method reads a binding declared in a function that encloses its
|
|
5406
|
+
* class: each evaluation of the class can see a different value. */
|
|
5407
|
+
function capturesEnclosingScope(lowerer, member, classDecl) {
|
|
5408
|
+
let scope = classDecl.parent;
|
|
5409
|
+
while (scope && !ts.isFunctionLike(scope) && !ts.isSourceFile(scope))
|
|
5410
|
+
scope = scope.parent;
|
|
5411
|
+
if (!scope || ts.isSourceFile(scope))
|
|
5412
|
+
return false;
|
|
5413
|
+
const inside = (node, container) => {
|
|
5414
|
+
for (let n = node; n; n = n.parent)
|
|
5415
|
+
if (n === container)
|
|
5416
|
+
return true;
|
|
5417
|
+
return false;
|
|
5418
|
+
};
|
|
5419
|
+
let captured = false;
|
|
5420
|
+
const visit = (node) => {
|
|
5421
|
+
if (captured)
|
|
5422
|
+
return;
|
|
5423
|
+
if (ts.isIdentifier(node)) {
|
|
5424
|
+
const symbol = lowerer.checker.getSymbolAtLocation(node);
|
|
5425
|
+
const decl = symbol ? symbol.valueDeclaration : undefined;
|
|
5426
|
+
// The enclosing function's own name is the same binding for every
|
|
5427
|
+
// evaluation.
|
|
5428
|
+
if (decl && decl !== scope && inside(decl, scope) && !inside(decl, member))
|
|
5429
|
+
captured = true;
|
|
5430
|
+
return;
|
|
5431
|
+
}
|
|
5432
|
+
ts.forEachChild(node, visit);
|
|
5433
|
+
};
|
|
5434
|
+
ts.forEachChild(member, visit);
|
|
5435
|
+
return captured;
|
|
5436
|
+
}
|
|
5437
|
+
/** Some code assigns or deletes a member of this name, or defines it by
|
|
5438
|
+
* reflection: the member a runtime lookup finds can then differ. */
|
|
5439
|
+
function memberAssigned(lowerer, member, name) {
|
|
5440
|
+
let found = false;
|
|
5441
|
+
for (const sf of lowerer.program.getSourceFiles()) {
|
|
5442
|
+
if (sf.isDeclarationFile || found)
|
|
5443
|
+
continue;
|
|
5444
|
+
if (!sf.text.includes(name))
|
|
5445
|
+
continue;
|
|
5446
|
+
ts.walkPreorder(sf, (node) => {
|
|
5447
|
+
if (found)
|
|
5448
|
+
return "skip";
|
|
5449
|
+
if (ts.isPropertyAccessExpression(node) && node.name.text === name) {
|
|
5450
|
+
const parent = node.parent;
|
|
5451
|
+
if (parent &&
|
|
5452
|
+
((ts.isBinaryExpression(parent) &&
|
|
5453
|
+
parent.left === node &&
|
|
5454
|
+
parent.operatorToken.kind >= ts.SyntaxKind.FirstAssignment &&
|
|
5455
|
+
parent.operatorToken.kind <= ts.SyntaxKind.LastAssignment) ||
|
|
5456
|
+
ts.isDeleteExpression(parent)))
|
|
5457
|
+
found = true;
|
|
5458
|
+
}
|
|
5459
|
+
if (ts.isStringLiteral(node) && node.text === name && node !== member.name) {
|
|
5460
|
+
const parent = node.parent;
|
|
5461
|
+
if (parent && (ts.isCallExpression(parent) || ts.isElementAccessExpression(parent)))
|
|
5462
|
+
found = true;
|
|
5463
|
+
}
|
|
5464
|
+
return undefined;
|
|
5465
|
+
});
|
|
5466
|
+
}
|
|
5467
|
+
return found;
|
|
5468
|
+
}
|
|
4743
5469
|
function staticMethodForReceiver(lowerer, access, method, receiver, throughValue) {
|
|
4744
5470
|
if (!hasStaticThis(method.decl))
|
|
4745
5471
|
return method;
|
|
@@ -4782,6 +5508,10 @@ export function lowerClassValueProperty(lowerer, expr) {
|
|
|
4782
5508
|
const loc = locOf(expr);
|
|
4783
5509
|
const member = expr.name.text;
|
|
4784
5510
|
const info = lowerer.classes.get(recvT.className);
|
|
5511
|
+
// A runtime-provided class value answers `.name` from its class object;
|
|
5512
|
+
// its other statics (`Error.stackTraceLimit`) keep their own lowerings.
|
|
5513
|
+
if (info?.def.runtime && member !== "name")
|
|
5514
|
+
return null;
|
|
4785
5515
|
if (info &&
|
|
4786
5516
|
((hasRuntimeStatics(info) && !findStaticOn(lowerer, info, member)?.field) ||
|
|
4787
5517
|
(info.callableBase && !findStaticOn(lowerer, info, member))))
|
|
@@ -4808,7 +5538,8 @@ export function lowerClassValueProperty(lowerer, expr) {
|
|
|
4808
5538
|
// `module.exports.label` in a class-replaced CJS module: the
|
|
4809
5539
|
// receiver is the exact exported class, and the read is
|
|
4810
5540
|
// side-effect-free — as bindable as an identifier.
|
|
4811
|
-
!(isModuleExportsAccess(expr.expression) &&
|
|
5541
|
+
!(isModuleExportsAccess(expr.expression) &&
|
|
5542
|
+
isCjsJsFile(ts.getSourceFileOfNode(expr), lowerer.program))) {
|
|
4812
5543
|
// Devirtualized reads DISCARD the receiver value, so only
|
|
4813
5544
|
// side-effect-free receivers are claimed (the instanceOf fold
|
|
4814
5545
|
// rule); computed ones meet the pointed fence with a bindable fix.
|
|
@@ -4855,19 +5586,56 @@ export function lowerClassValueProperty(lowerer, expr) {
|
|
|
4855
5586
|
* async/generator/generic-with-body combinations before this runs, and
|
|
4856
5587
|
* the generic case fences at the caller). */
|
|
4857
5588
|
function abstractMemberSignature(lowerer, member) {
|
|
4858
|
-
for (const param of member.parameters) {
|
|
5589
|
+
for (const param of member.parameters.nodes) {
|
|
4859
5590
|
if (!ts.isIdentifier(param.name))
|
|
4860
5591
|
lowerer.unsupported("SC1031", param);
|
|
4861
5592
|
}
|
|
4862
5593
|
return {
|
|
4863
|
-
shapes: lowerer.paramShapes(member.parameters),
|
|
5594
|
+
shapes: lowerer.paramShapes(member.parameters.nodes),
|
|
4864
5595
|
ret: lowerer.declaredReturnType(member, member.name),
|
|
4865
5596
|
};
|
|
4866
5597
|
}
|
|
4867
5598
|
/** A nominal return subtype uses the same owned pointer as the inherited
|
|
4868
5599
|
* return slot. The current class is still being collected, so consult its
|
|
4869
5600
|
* already collected base chain before the complete class graph is available. */
|
|
5601
|
+
/** An inherited ASYNC method that an override now dispatches against: its
|
|
5602
|
+
* slot becomes a plain function returning the body's promise, and the
|
|
5603
|
+
* async body lowers behind it as `%C.m$own` (the adapter path with an
|
|
5604
|
+
* identity conversion), so a virtual call never enters an async body
|
|
5605
|
+
* without its spawn wrapper. */
|
|
5606
|
+
function thunkAsyncSlot(overridden, mName) {
|
|
5607
|
+
if (overridden.sig.async !== true)
|
|
5608
|
+
return;
|
|
5609
|
+
const declarer = overridden.declarer;
|
|
5610
|
+
// The slot answers the body's promise: an untyped async method's `dyn`
|
|
5611
|
+
// result is the promise's payload, so the slot's ABI is that promise. An
|
|
5612
|
+
// async generator method's slot keeps its generator object.
|
|
5613
|
+
const ret = overridden.sig.gen || overridden.sig.ret.kind === "promise"
|
|
5614
|
+
? overridden.sig.ret
|
|
5615
|
+
: { kind: "promise", inner: overridden.sig.ret };
|
|
5616
|
+
declarer.returnAdapters ??= new Map();
|
|
5617
|
+
if (!declarer.returnAdapters.has(mName)) {
|
|
5618
|
+
declarer.returnAdapters.set(mName, {
|
|
5619
|
+
params: [...overridden.sig.params],
|
|
5620
|
+
ret,
|
|
5621
|
+
async: true,
|
|
5622
|
+
});
|
|
5623
|
+
}
|
|
5624
|
+
overridden.sig.ret = ret;
|
|
5625
|
+
delete overridden.sig.async;
|
|
5626
|
+
}
|
|
4870
5627
|
function overrideReturnAbi(lowerer, declared, inherited, className, base) {
|
|
5628
|
+
// A return narrowed to part of an inherited union (`Meta` for
|
|
5629
|
+
// `Meta | undefined`) keeps the union ABI; returns convert into it.
|
|
5630
|
+
if (inherited.kind === "union" && !typeEquals(declared, inherited)) {
|
|
5631
|
+
const arms = lowerer.unions.get(inherited.unionId)?.arms ?? [];
|
|
5632
|
+
const fits = (type) => arms.some((arm) => typeEquals(arm, type) ||
|
|
5633
|
+
(arm.kind === "object" &&
|
|
5634
|
+
type.kind === "object" &&
|
|
5635
|
+
lowerer.isSubclassOf(type.className, arm.className)));
|
|
5636
|
+
const parts = declared.kind === "union" ? (lowerer.unions.get(declared.unionId)?.arms ?? []) : [declared];
|
|
5637
|
+
return parts.length > 0 && parts.every(fits) ? inherited : declared;
|
|
5638
|
+
}
|
|
4871
5639
|
if (declared.kind !== "object" || inherited.kind !== "object")
|
|
4872
5640
|
return declared;
|
|
4873
5641
|
if (lowerer.isSubclassOf(declared.className, inherited.className) ||
|
|
@@ -4947,7 +5715,7 @@ export function collectInheritedJsFieldWrites(lowerer, files) {
|
|
|
4947
5715
|
continue;
|
|
4948
5716
|
ts.walkPreorder(file, (node) => {
|
|
4949
5717
|
if ((!ts.isClassDeclaration(node) && !ts.isClassExpression(node)) ||
|
|
4950
|
-
!node.heritageClauses?.length)
|
|
5718
|
+
!node.heritageClauses?.nodes.length)
|
|
4951
5719
|
return;
|
|
4952
5720
|
const writes = new Map();
|
|
4953
5721
|
const addWrite = (name, expression) => {
|
|
@@ -4974,10 +5742,10 @@ export function collectInheritedJsFieldWrites(lowerer, files) {
|
|
|
4974
5742
|
addWrite(name, part.right);
|
|
4975
5743
|
}
|
|
4976
5744
|
}
|
|
4977
|
-
|
|
5745
|
+
ts.forEachChild(part, scan);
|
|
4978
5746
|
};
|
|
4979
|
-
for (const member of node.members) {
|
|
4980
|
-
if (member.modifiers?.some((modifier) => modifier.kind === ts.SyntaxKind.StaticKeyword))
|
|
5747
|
+
for (const member of node.members.nodes) {
|
|
5748
|
+
if (member.modifiers?.nodes.some((modifier) => modifier.kind === ts.SyntaxKind.StaticKeyword))
|
|
4981
5749
|
continue;
|
|
4982
5750
|
if (ts.isPropertyDeclaration(member) && member.initializer) {
|
|
4983
5751
|
const name = ts.isPrivateIdentifier(member.name)
|
|
@@ -5007,7 +5775,7 @@ export function collectInheritedJsFieldWrites(lowerer, files) {
|
|
|
5007
5775
|
for (const base of lowerer.checker.getBaseTypes(target)) {
|
|
5008
5776
|
for (const [name, expressions] of writes) {
|
|
5009
5777
|
const property = lowerer.checker.getPropertyOfType(base, name);
|
|
5010
|
-
for (const declaration of property ?
|
|
5778
|
+
for (const declaration of property ? property.declarations : []) {
|
|
5011
5779
|
if (ts.isMethodDeclaration(declaration) || ts.isAccessor(declaration))
|
|
5012
5780
|
continue;
|
|
5013
5781
|
let owner = declaration.parent;
|
|
@@ -5015,7 +5783,7 @@ export function collectInheritedJsFieldWrites(lowerer, files) {
|
|
|
5015
5783
|
owner = owner.parent;
|
|
5016
5784
|
if (!owner ||
|
|
5017
5785
|
(!ts.isClassDeclaration(owner) && !ts.isClassExpression(owner)) ||
|
|
5018
|
-
!isJsSourceFile(
|
|
5786
|
+
!isJsSourceFile(ts.getSourceFileOfNode(owner)))
|
|
5019
5787
|
continue;
|
|
5020
5788
|
let fields = lowerer.inheritedJsFieldWrites.get(owner);
|
|
5021
5789
|
if (!fields)
|
|
@@ -5041,15 +5809,15 @@ export function collectInheritedJsFieldWrites(lowerer, files) {
|
|
|
5041
5809
|
* hierarchy identifies the original declarations through aliases as well. */
|
|
5042
5810
|
export function collectVirtualJsMethods(lowerer, files) {
|
|
5043
5811
|
const families = [];
|
|
5044
|
-
collectClassMethodMutations(lowerer, files);
|
|
5812
|
+
lowerer.speculativeTypeQueries(() => collectClassMethodMutations(lowerer, files));
|
|
5045
5813
|
const visit = (node) => {
|
|
5046
5814
|
if (ts.isClassDeclaration(node) || ts.isClassExpression(node)) {
|
|
5047
|
-
const accessors = node.members.filter((member) => (ts.isGetAccessorDeclaration(member) || ts.isSetAccessorDeclaration(member)) &&
|
|
5815
|
+
const accessors = node.members.nodes.filter((member) => (ts.isGetAccessorDeclaration(member) || ts.isSetAccessorDeclaration(member)) &&
|
|
5048
5816
|
ts.isIdentifier(member.name) &&
|
|
5049
|
-
!member.modifiers?.some((modifier) => modifier.kind === ts.SyntaxKind.StaticKeyword));
|
|
5050
|
-
if (node.heritageClauses?.length &&
|
|
5817
|
+
!member.modifiers?.nodes.some((modifier) => modifier.kind === ts.SyntaxKind.StaticKeyword));
|
|
5818
|
+
if (node.heritageClauses?.nodes.length &&
|
|
5051
5819
|
accessors.length &&
|
|
5052
|
-
isJsSourceFile(
|
|
5820
|
+
isJsSourceFile(ts.getSourceFileOfNode(node))) {
|
|
5053
5821
|
const symbol = lowerer.typeOf(node).getSymbol();
|
|
5054
5822
|
const instance = symbol ? lowerer.checker.getDeclaredTypeOfSymbol(symbol) : null;
|
|
5055
5823
|
const seen = new Set();
|
|
@@ -5063,13 +5831,13 @@ export function collectVirtualJsMethods(lowerer, files) {
|
|
|
5063
5831
|
if (!ts.isIdentifier(member.name))
|
|
5064
5832
|
continue;
|
|
5065
5833
|
const property = lowerer.checker.getPropertyOfType(base, member.name.text);
|
|
5066
|
-
for (const declaration of property ?
|
|
5834
|
+
for (const declaration of property ? property.declarations : []) {
|
|
5067
5835
|
if ((ts.isGetAccessorDeclaration(declaration) ||
|
|
5068
5836
|
ts.isSetAccessorDeclaration(declaration)) &&
|
|
5069
|
-
isJsSourceFile(
|
|
5837
|
+
isJsSourceFile(ts.getSourceFileOfNode(declaration))) {
|
|
5070
5838
|
lowerer.checkedVirtualJsAccessors.add(declaration);
|
|
5071
5839
|
lowerer.checkedVirtualJsAccessors.add(member);
|
|
5072
|
-
for (const twin of node.members)
|
|
5840
|
+
for (const twin of node.members.nodes)
|
|
5073
5841
|
if ((ts.isGetAccessorDeclaration(twin) || ts.isSetAccessorDeclaration(twin)) &&
|
|
5074
5842
|
ts.isIdentifier(twin.name) &&
|
|
5075
5843
|
twin.name.text === member.name.text)
|
|
@@ -5083,10 +5851,10 @@ export function collectVirtualJsMethods(lowerer, files) {
|
|
|
5083
5851
|
if (instance)
|
|
5084
5852
|
markAccessors(instance);
|
|
5085
5853
|
}
|
|
5086
|
-
const members = node.members.filter((member) => ts.isMethodDeclaration(member) &&
|
|
5854
|
+
const members = node.members.nodes.filter((member) => ts.isMethodDeclaration(member) &&
|
|
5087
5855
|
ts.isIdentifier(member.name) &&
|
|
5088
|
-
!member.modifiers?.some((modifier) => modifier.kind === ts.SyntaxKind.StaticKeyword));
|
|
5089
|
-
if (node.heritageClauses?.length && members.length > 0) {
|
|
5856
|
+
!member.modifiers?.nodes.some((modifier) => modifier.kind === ts.SyntaxKind.StaticKeyword));
|
|
5857
|
+
if (node.heritageClauses?.nodes.length && members.length > 0) {
|
|
5090
5858
|
const symbol = lowerer.typeOf(node).getSymbol();
|
|
5091
5859
|
const instance = symbol ? lowerer.checker.getDeclaredTypeOfSymbol(symbol) : null;
|
|
5092
5860
|
const seen = new Set();
|
|
@@ -5100,22 +5868,23 @@ export function collectVirtualJsMethods(lowerer, files) {
|
|
|
5100
5868
|
if (!ts.isIdentifier(member.name))
|
|
5101
5869
|
continue;
|
|
5102
5870
|
const property = lowerer.checker.getPropertyOfType(base, member.name.text);
|
|
5103
|
-
for (const declaration of property ?
|
|
5871
|
+
for (const declaration of property ? property.declarations : []) {
|
|
5104
5872
|
if (ts.isMethodDeclaration(declaration) &&
|
|
5105
|
-
isJsSourceFile(
|
|
5873
|
+
isJsSourceFile(ts.getSourceFileOfNode(declaration)) &&
|
|
5874
|
+
!checkedJsOverride(lowerer, declaration, member)) {
|
|
5106
5875
|
lowerer.virtualJsMethods.add(declaration);
|
|
5107
|
-
if (isJsSourceFile(
|
|
5108
|
-
!member.typeParameters &&
|
|
5876
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(member)) &&
|
|
5877
|
+
!member.typeParameters?.nodes &&
|
|
5109
5878
|
!member.asteriskToken &&
|
|
5110
|
-
!member.modifiers?.some((m) => m.kind === ts.SyntaxKind.AsyncKeyword) &&
|
|
5879
|
+
!member.modifiers?.nodes.some((m) => m.kind === ts.SyntaxKind.AsyncKeyword) &&
|
|
5111
5880
|
!bodyReadsArguments(member) &&
|
|
5112
|
-
member.parameters.every((p) => !p.dotDotDotToken)) {
|
|
5113
|
-
lowerer.virtualJsMethodArity.set(declaration, Math.max(lowerer.virtualJsMethodArity.get(declaration) ?? 0, member.parameters.length));
|
|
5114
|
-
const checked = !declaration.typeParameters &&
|
|
5881
|
+
member.parameters.nodes.every((p) => !p.dotDotDotToken)) {
|
|
5882
|
+
lowerer.virtualJsMethodArity.set(declaration, Math.max(lowerer.virtualJsMethodArity.get(declaration) ?? 0, member.parameters.nodes.length));
|
|
5883
|
+
const checked = !declaration.typeParameters?.nodes &&
|
|
5115
5884
|
!declaration.asteriskToken &&
|
|
5116
|
-
!declaration.modifiers?.some((m) => m.kind === ts.SyntaxKind.AsyncKeyword) &&
|
|
5885
|
+
!declaration.modifiers?.nodes.some((m) => m.kind === ts.SyntaxKind.AsyncKeyword) &&
|
|
5117
5886
|
!bodyReadsArguments(declaration) &&
|
|
5118
|
-
[...member.parameters, ...declaration.parameters].every((p) => !p.dotDotDotToken);
|
|
5887
|
+
[...member.parameters.nodes, ...declaration.parameters.nodes].every((p) => !p.dotDotDotToken);
|
|
5119
5888
|
if (checked) {
|
|
5120
5889
|
lowerer.checkedVirtualJsMethods.add(declaration);
|
|
5121
5890
|
lowerer.checkedVirtualJsMethods.add(member);
|
|
@@ -5141,7 +5910,7 @@ export function collectVirtualJsMethods(lowerer, files) {
|
|
|
5141
5910
|
return;
|
|
5142
5911
|
if (ts.isReturnStatement(node) && node.expression)
|
|
5143
5912
|
lowerer.checkedVirtualJsValueReturns.add(member);
|
|
5144
|
-
|
|
5913
|
+
ts.forEachChild(node, scan);
|
|
5145
5914
|
};
|
|
5146
5915
|
scan(member);
|
|
5147
5916
|
}
|
|
@@ -5160,6 +5929,14 @@ export function collectVirtualJsMethods(lowerer, files) {
|
|
|
5160
5929
|
}
|
|
5161
5930
|
}
|
|
5162
5931
|
}
|
|
5932
|
+
/** An override whose base and overriding methods are in files TypeScript
|
|
5933
|
+
* checks and document every parameter: TypeScript checks the override
|
|
5934
|
+
* against its base, so both keep their declared signatures, as in
|
|
5935
|
+
* TypeScript classes. */
|
|
5936
|
+
function checkedJsOverride(lowerer, base, member) {
|
|
5937
|
+
return [base, member].every((method) => lowerer.checkedJsFile(ts.getSourceFileOfNode(method)) &&
|
|
5938
|
+
method.parameters.nodes.every(documentedParameter));
|
|
5939
|
+
}
|
|
5163
5940
|
/** The receiver's EXACT runtime class, when the expression proves it: a
|
|
5164
5941
|
* `new C(...)` expression directly, or a const binding initialized with
|
|
5165
5942
|
* one (the binding can never be reassigned to a subclass instance).
|
|
@@ -5182,7 +5959,7 @@ export function exactInstanceClassOf(lowerer, expr) {
|
|
|
5182
5959
|
if (!ts.isIdentifier(e))
|
|
5183
5960
|
return null;
|
|
5184
5961
|
const symbol = lowerer.resolveValueSymbol(e);
|
|
5185
|
-
const decl = symbol ?
|
|
5962
|
+
const decl = symbol ? symbol.valueDeclaration : undefined;
|
|
5186
5963
|
if (!decl ||
|
|
5187
5964
|
!ts.isVariableDeclaration(decl) ||
|
|
5188
5965
|
decl.initializer === undefined ||
|
|
@@ -5272,19 +6049,39 @@ export function lowerClassGenericMethodCall(lowerer, call, access, recvInfo, fou
|
|
|
5272
6049
|
loc,
|
|
5273
6050
|
}
|
|
5274
6051
|
: upcastTo(lowerer, receiver, declarer.def.name);
|
|
5275
|
-
const args = lowerer.completeArgs(call.arguments, instance.params, loc, call);
|
|
5276
|
-
|
|
6052
|
+
const args = lowerer.completeArgs(call.arguments.nodes, instance.params, loc, call);
|
|
6053
|
+
const result = {
|
|
5277
6054
|
kind: "call",
|
|
5278
6055
|
callee: instance.name,
|
|
5279
6056
|
args: [thisArg, ...args],
|
|
5280
6057
|
type: instance.returnType,
|
|
5281
6058
|
loc,
|
|
5282
6059
|
};
|
|
6060
|
+
// A fluent JavaScript method (every return ends in `this`, jose's claim
|
|
6061
|
+
// setters) answers the receiver: the instance returns the declarer's
|
|
6062
|
+
// class, a used result's checker type is the receiver's subclass.
|
|
6063
|
+
if (result.type.kind === "object" &&
|
|
6064
|
+
!ts.isExpressionStatement(call.parent) &&
|
|
6065
|
+
ts.isMethodDeclaration(info.decl) &&
|
|
6066
|
+
isJsSourceFile(ts.getSourceFileOfNode(info.decl)) &&
|
|
6067
|
+
returnsOnlyThisValue(info.decl)) {
|
|
6068
|
+
return lowerer.maybeNarrow(result, call);
|
|
6069
|
+
}
|
|
6070
|
+
return result;
|
|
5283
6071
|
}
|
|
5284
6072
|
/** Wraps a derived-class expression in an upcast when the target base
|
|
5285
6073
|
* class differs (a no-op reinterpret at runtime; keeps IR types exact). */
|
|
5286
6074
|
export function upcastTo(lowerer, expr, className) {
|
|
5287
6075
|
if (expr.type.kind === "object" && expr.type.className !== className) {
|
|
6076
|
+
// A value lowered at an ANCESTOR of the class the site needs (a
|
|
6077
|
+
// fluent `this` result whose lowering kept the method's declaring
|
|
6078
|
+
// class, the receiver of the next call in a chain): the checker
|
|
6079
|
+
// vouches for the subclass, so the bridge is the verified downcast,
|
|
6080
|
+
// never an upcast the validator rejects (an internal error before).
|
|
6081
|
+
if (!lowerer.isSubclassOf(expr.type.className, className) &&
|
|
6082
|
+
lowerer.isSubclassOf(className, expr.type.className)) {
|
|
6083
|
+
return { kind: "downcast", value: expr, type: { kind: "object", className }, loc: expr.loc };
|
|
6084
|
+
}
|
|
5288
6085
|
return { kind: "upcast", value: expr, type: { kind: "object", className }, loc: expr.loc };
|
|
5289
6086
|
}
|
|
5290
6087
|
return expr;
|
|
@@ -5302,24 +6099,24 @@ export function upcastTo(lowerer, expr, className) {
|
|
|
5302
6099
|
* form with an exact static story under monomorphization (the
|
|
5303
6100
|
* instantiation adopts the base's ABI; see collectClassShapeInner). */
|
|
5304
6101
|
function mixinForwardingCtor(lowerer, ctor) {
|
|
5305
|
-
if (ctor.parameters.length !== 1 || !ctor.body)
|
|
6102
|
+
if (ctor.parameters.nodes.length !== 1 || !ctor.body)
|
|
5306
6103
|
return false;
|
|
5307
|
-
const p = ctor.parameters[0];
|
|
6104
|
+
const p = ctor.parameters.nodes[0];
|
|
5308
6105
|
if (!p.dotDotDotToken || !ts.isIdentifier(p.name))
|
|
5309
6106
|
return false;
|
|
5310
6107
|
const paramName = p.name;
|
|
5311
6108
|
const paramSym = lowerer.checker.getSymbolAtLocation(paramName);
|
|
5312
6109
|
if (!paramSym)
|
|
5313
6110
|
return false;
|
|
5314
|
-
const first = ctor.body.statements[0];
|
|
6111
|
+
const first = ctor.body.statements.nodes[0];
|
|
5315
6112
|
if (!first || !ts.isExpressionStatement(first) || !ts.isCallExpression(first.expression))
|
|
5316
6113
|
return false;
|
|
5317
6114
|
const call = first.expression;
|
|
5318
6115
|
if (call.expression.kind !== ts.SyntaxKind.SuperKeyword)
|
|
5319
6116
|
return false;
|
|
5320
|
-
if (call.arguments.length !== 1)
|
|
6117
|
+
if (call.arguments.nodes.length !== 1)
|
|
5321
6118
|
return false;
|
|
5322
|
-
const a = call.arguments[0];
|
|
6119
|
+
const a = call.arguments.nodes[0];
|
|
5323
6120
|
if (!ts.isSpreadElement(a) || !ts.isIdentifier(a.expression))
|
|
5324
6121
|
return false;
|
|
5325
6122
|
const spreadIdent = a.expression;
|
|
@@ -5372,7 +6169,7 @@ export function lowerClassMembers(lowerer, info) {
|
|
|
5372
6169
|
catch (e) {
|
|
5373
6170
|
if (!(e instanceof PoisonError))
|
|
5374
6171
|
throw e;
|
|
5375
|
-
if (info.decl && isJsSourceFile(info.decl
|
|
6172
|
+
if (info.decl && isJsSourceFile(ts.getSourceFileOfNode(info.decl))) {
|
|
5376
6173
|
const types = [
|
|
5377
6174
|
{ kind: "object", className },
|
|
5378
6175
|
...info.ctorParams.map((param) => param.type),
|
|
@@ -5483,7 +6280,7 @@ function lowerClassCtorInner(lowerer, info) {
|
|
|
5483
6280
|
// The default-param prologue runs FIRST — before field initializers
|
|
5484
6281
|
// and (in a derived class) before super(): JS evaluates parameter
|
|
5485
6282
|
// defaults on entry, ahead of everything the body does.
|
|
5486
|
-
const declared = lowerer.declareParams(info.ctor.parameters, info.ctorParams);
|
|
6283
|
+
const declared = lowerer.declareParams(info.ctor.parameters.nodes, info.ctorParams);
|
|
5487
6284
|
params.push(...declared.params);
|
|
5488
6285
|
if (info.ctorParams.at(-1)?.mode === "arguments") {
|
|
5489
6286
|
const local = lowerer.declareHiddenLocal("%arguments", DYN);
|
|
@@ -5499,7 +6296,7 @@ function lowerClassCtorInner(lowerer, info) {
|
|
|
5499
6296
|
body.push(...lowerer.fieldInitStmts(info, thisLocal));
|
|
5500
6297
|
body.push(...paramPropInitStmts(lowerer, info, thisLocal));
|
|
5501
6298
|
if (info.ctor.body)
|
|
5502
|
-
body.push(...lowerer.lowerStmts(info.ctor.body.statements));
|
|
6299
|
+
body.push(...lowerer.lowerStmts(info.ctor.body.statements.nodes));
|
|
5503
6300
|
}
|
|
5504
6301
|
else if (info.ctor.body) {
|
|
5505
6302
|
body.push(...lowerer.lowerDerivedCtorBody(info, thisLocal));
|
|
@@ -5556,7 +6353,7 @@ function lowerClassCtorInner(lowerer, info) {
|
|
|
5556
6353
|
* private, static and abstract members are not prototype string keys. */
|
|
5557
6354
|
function classPrototypeNames(decl) {
|
|
5558
6355
|
const names = [];
|
|
5559
|
-
for (const member of decl.members) {
|
|
6356
|
+
for (const member of decl.members.nodes) {
|
|
5560
6357
|
if (!ts.isMethodDeclaration(member) &&
|
|
5561
6358
|
!ts.isGetAccessorDeclaration(member) &&
|
|
5562
6359
|
!ts.isSetAccessorDeclaration(member))
|
|
@@ -5608,7 +6405,8 @@ export function classMemberNameOf(lowerer, name) {
|
|
|
5608
6405
|
if (member === "iterator" ||
|
|
5609
6406
|
member === "asyncIterator" ||
|
|
5610
6407
|
member === "dispose" ||
|
|
5611
|
-
member === "asyncDispose"
|
|
6408
|
+
member === "asyncDispose" ||
|
|
6409
|
+
member === "toPrimitive") {
|
|
5612
6410
|
return `sym:${member}`;
|
|
5613
6411
|
}
|
|
5614
6412
|
}
|
|
@@ -5921,6 +6719,77 @@ function lowerClassMethodMemberInner(lowerer, info, fnLike) {
|
|
|
5921
6719
|
allowDiagSink: true,
|
|
5922
6720
|
});
|
|
5923
6721
|
}
|
|
6722
|
+
// An override converting its declared result into the inherited ABI:
|
|
6723
|
+
// the body lowers as `%C.m$own` under its declared result, and the slot
|
|
6724
|
+
// function forwards to it and converts what it returns.
|
|
6725
|
+
const adapter = info.returnAdapters?.get(mName);
|
|
6726
|
+
if (adapter) {
|
|
6727
|
+
const ownSig = { ...sig, params: adapter.params, ret: adapter.ret };
|
|
6728
|
+
if (adapter.async)
|
|
6729
|
+
ownSig.async = true;
|
|
6730
|
+
const own = lowerClassMethodBody(lowerer, info, fnLike, `%${className}.${mName}$own`, ownSig);
|
|
6731
|
+
if (!own)
|
|
6732
|
+
return null;
|
|
6733
|
+
lowerer.liftedFns.push(own);
|
|
6734
|
+
const loc = locOf(fnLike);
|
|
6735
|
+
const params = [
|
|
6736
|
+
{ localId: "this.0", name: "this", type: thisType },
|
|
6737
|
+
...sig.params.map((p, i) => ({ localId: `p.${i}`, name: `p${i}`, type: p.type })),
|
|
6738
|
+
];
|
|
6739
|
+
const fnCtx = newFnCtx(false, null, null, sig.ret);
|
|
6740
|
+
lowerer.fnStack.push(fnCtx);
|
|
6741
|
+
try {
|
|
6742
|
+
const call = {
|
|
6743
|
+
kind: "call",
|
|
6744
|
+
callee: own.name,
|
|
6745
|
+
args: params.map((p, i) => {
|
|
6746
|
+
const ref = { kind: "varRef", localId: p.localId, type: p.type, loc };
|
|
6747
|
+
// `this` passes through; each inherited argument converts into
|
|
6748
|
+
// the override's declared parameter (checked where it narrows).
|
|
6749
|
+
return i === 0 ? ref : lowerer.coerceInto(fnLike.name, ref, adapter.params[i - 1].type);
|
|
6750
|
+
}),
|
|
6751
|
+
type: adapter.ret,
|
|
6752
|
+
loc,
|
|
6753
|
+
};
|
|
6754
|
+
// A void slot discards the override's result after running it. A
|
|
6755
|
+
// toString slot hands on what every ToString consumer of the result
|
|
6756
|
+
// makes of it (`String(err)`, templates): undefined reads
|
|
6757
|
+
// "undefined", as in Node. Other slots check the result into the
|
|
6758
|
+
// inherited type.
|
|
6759
|
+
const result = () => mName === "toString" && sig.ret.kind === "string"
|
|
6760
|
+
? call.type.kind === "dyn"
|
|
6761
|
+
? { kind: "libCall", fn: "dyn.stringConstructor", args: [call], type: STRING, loc }
|
|
6762
|
+
: lowerer.ensureString(call, fnLike.name)
|
|
6763
|
+
: lowerer.coerceInto(fnLike.name, call, sig.ret);
|
|
6764
|
+
const body = sig.ret.kind === "void"
|
|
6765
|
+
? [
|
|
6766
|
+
{ kind: "exprStmt", expr: call, loc },
|
|
6767
|
+
{ kind: "return", value: null, loc },
|
|
6768
|
+
]
|
|
6769
|
+
: [{ kind: "return", value: result(), loc }];
|
|
6770
|
+
return {
|
|
6771
|
+
name: `%${className}.${mName}`,
|
|
6772
|
+
params,
|
|
6773
|
+
returnType: sig.ret,
|
|
6774
|
+
locals: [
|
|
6775
|
+
...params.map((p) => ({ id: p.localId, name: p.name, type: p.type, mutable: false })),
|
|
6776
|
+
...lowerer.ctx.locals,
|
|
6777
|
+
],
|
|
6778
|
+
body,
|
|
6779
|
+
loc,
|
|
6780
|
+
};
|
|
6781
|
+
}
|
|
6782
|
+
finally {
|
|
6783
|
+
lowerer.fnStack.pop();
|
|
6784
|
+
}
|
|
6785
|
+
}
|
|
6786
|
+
return lowerClassMethodBody(lowerer, info, fnLike, `%${className}.${mName}`, sig);
|
|
6787
|
+
}
|
|
6788
|
+
function lowerClassMethodBody(lowerer, info, fnLike, fnName, sig) {
|
|
6789
|
+
const className = info.def.name;
|
|
6790
|
+
const thisType = { kind: "object", className };
|
|
6791
|
+
if (!fnLike.body)
|
|
6792
|
+
return null;
|
|
5924
6793
|
const prevClass = lowerer.currentClass;
|
|
5925
6794
|
lowerer.currentClass = info;
|
|
5926
6795
|
// ASYNC methods: the module function is an async IrFunction — its
|
|
@@ -5949,7 +6818,7 @@ function lowerClassMethodMemberInner(lowerer, info, fnLike) {
|
|
|
5949
6818
|
const params = [{ localId: thisLocal.id, name: "this", type: thisType }];
|
|
5950
6819
|
// `this` is declared first, so method parameter DEFAULTS may use it
|
|
5951
6820
|
// (JS allows this in method defaults; it is param 0 here).
|
|
5952
|
-
const declared = lowerer.declareParams(fnLike.parameters, sig.params);
|
|
6821
|
+
const declared = lowerer.declareParams(fnLike.parameters.nodes, sig.params);
|
|
5953
6822
|
params.push(...declared.params);
|
|
5954
6823
|
// A shorter JS override still implements every inherited ABI slot.
|
|
5955
6824
|
// These tail parameters have no source binding or default prologue.
|
|
@@ -5960,10 +6829,10 @@ function lowerClassMethodMemberInner(lowerer, info, fnLike) {
|
|
|
5960
6829
|
if (shape.mode === "arguments")
|
|
5961
6830
|
fnCtx.argumentsLocal = local;
|
|
5962
6831
|
}
|
|
5963
|
-
const body = [...declared.prologue, ...lowerer.lowerStmts(fnLike.body.statements)];
|
|
6832
|
+
const body = [...declared.prologue, ...lowerer.lowerStmts(fnLike.body.statements.nodes)];
|
|
5964
6833
|
appendImplicitUndefinedReturn(lowerer, body, bodyReturn, locOf(fnLike));
|
|
5965
6834
|
const fn = {
|
|
5966
|
-
name:
|
|
6835
|
+
name: fnName,
|
|
5967
6836
|
params,
|
|
5968
6837
|
returnType: bodyReturn,
|
|
5969
6838
|
locals: lowerer.ctx.locals,
|
|
@@ -5993,7 +6862,7 @@ export function lowerStaticMethod(lowerer, info, name) {
|
|
|
5993
6862
|
const entry = info.staticMethods?.get(name);
|
|
5994
6863
|
if (!entry?.member.body)
|
|
5995
6864
|
return null;
|
|
5996
|
-
const isAsync = entry.member.modifiers?.some((m) => m.kind === ts.SyntaxKind.AsyncKeyword) === true;
|
|
6865
|
+
const isAsync = entry.member.modifiers?.nodes.some((m) => m.kind === ts.SyntaxKind.AsyncKeyword) === true;
|
|
5997
6866
|
const isGenerator = entry.member.asteriskToken !== undefined;
|
|
5998
6867
|
if (isGenerator && (entry.ret.kind !== "generator" || (entry.ret.async === true) !== isAsync)) {
|
|
5999
6868
|
lowerer.badType(entry.member.name, lowerer.typeOf(entry.member.name));
|
|
@@ -6014,13 +6883,13 @@ export function lowerStaticMethod(lowerer, info, name) {
|
|
|
6014
6883
|
lowerer.fnStack.push(fnCtx);
|
|
6015
6884
|
try {
|
|
6016
6885
|
rejectStaticThis(lowerer, entry.member.body, (keyword) => `'${keyword}' in static methods (it names the RECEIVER class — a dynamic value; reference the class by name instead)`);
|
|
6017
|
-
const declared = lowerer.declareParams(entry.member.parameters, entry.params);
|
|
6886
|
+
const declared = lowerer.declareParams(entry.member.parameters.nodes, entry.params);
|
|
6018
6887
|
if (entry.params.at(-1)?.mode === "arguments") {
|
|
6019
6888
|
const local = lowerer.declareHiddenLocal("%arguments", DYN);
|
|
6020
6889
|
declared.params.push({ localId: local.id, name: "%arguments", type: DYN });
|
|
6021
6890
|
fnCtx.argumentsLocal = local;
|
|
6022
6891
|
}
|
|
6023
|
-
const body = [...declared.prologue, ...lowerer.lowerStmts(entry.member.body.statements)];
|
|
6892
|
+
const body = [...declared.prologue, ...lowerer.lowerStmts(entry.member.body.statements.nodes)];
|
|
6024
6893
|
appendImplicitUndefinedReturn(lowerer, body, bodyReturn, locOf(entry.member));
|
|
6025
6894
|
const fn = {
|
|
6026
6895
|
name: `%${info.def.name}.static:${name}`,
|
|
@@ -6091,6 +6960,13 @@ export function throwingSetterFn(lowerer, info, prop) {
|
|
|
6091
6960
|
loc,
|
|
6092
6961
|
};
|
|
6093
6962
|
}
|
|
6963
|
+
/** The declared type a refused checked-dynamic class field names in its
|
|
6964
|
+
* diagnostic (`'any'`, `'WeakMap<object, string>'`): `unknown` and
|
|
6965
|
+
* `object` fields store checked-dynamic values, so the refusal is about
|
|
6966
|
+
* whatever else the declaration spells. */
|
|
6967
|
+
function dynFieldTypeSpelling(lowerer, node) {
|
|
6968
|
+
return `'${lowerer.checker.typeToString(lowerer.typeOf(node))}'`;
|
|
6969
|
+
}
|
|
6094
6970
|
/** The base a constructor chain actually CALLS into: generic FAMILIES are
|
|
6095
6971
|
* never constructed (no `%<family>.constructor` exists), so an
|
|
6096
6972
|
* instantiation's construction-relevant base is the family's own base —
|
|
@@ -6134,14 +7010,15 @@ export function fieldInitStmts(lowerer, info, thisLocal) {
|
|
|
6134
7010
|
className: info.def.name,
|
|
6135
7011
|
field: f.name,
|
|
6136
7012
|
value: dynUndefinedExpr(loc),
|
|
7013
|
+
define: true,
|
|
6137
7014
|
loc,
|
|
6138
7015
|
});
|
|
6139
7016
|
}
|
|
6140
7017
|
if (!f.initializer)
|
|
6141
7018
|
continue;
|
|
6142
|
-
lowerer.
|
|
6143
|
-
lowerer.bumpFileStat(locOf(f.initializer).file, "total");
|
|
7019
|
+
lowerer.countStatement(f.initializer, locOf(f.initializer).file);
|
|
6144
7020
|
const diagsBefore = lowerer.diags.length;
|
|
7021
|
+
const sinkMark = lowerer.diagSinkMark();
|
|
6145
7022
|
try {
|
|
6146
7023
|
const value = lowerer.lowerExprExpecting(f.initializer, f.type);
|
|
6147
7024
|
out.push({
|
|
@@ -6150,18 +7027,18 @@ export function fieldInitStmts(lowerer, info, thisLocal) {
|
|
|
6150
7027
|
className: info.def.name,
|
|
6151
7028
|
field: f.name,
|
|
6152
7029
|
value,
|
|
7030
|
+
define: true,
|
|
6153
7031
|
loc: locOf(f.initializer),
|
|
6154
7032
|
});
|
|
6155
7033
|
}
|
|
6156
7034
|
catch (e) {
|
|
6157
7035
|
if (!(e instanceof PoisonError))
|
|
6158
7036
|
throw e;
|
|
6159
|
-
lowerer.
|
|
6160
|
-
|
|
6161
|
-
|
|
6162
|
-
|
|
6163
|
-
|
|
6164
|
-
});
|
|
7037
|
+
lowerer.countStatementFailed(f.initializer, locOf(f.initializer).file);
|
|
7038
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(f.initializer))) {
|
|
7039
|
+
const fence = lowerer.diagSink === null
|
|
7040
|
+
? lowerer.deferToRuntimeFence(diagsBefore, f.initializer, { kind: "statement" })
|
|
7041
|
+
: lowerer.capturedRuntimeFence(sinkMark, f.initializer);
|
|
6165
7042
|
if (fence)
|
|
6166
7043
|
out.push(fence);
|
|
6167
7044
|
}
|
|
@@ -6200,6 +7077,24 @@ function paramPropInitStmts(lowerer, info, thisLocal) {
|
|
|
6200
7077
|
}
|
|
6201
7078
|
return out;
|
|
6202
7079
|
}
|
|
7080
|
+
/** Whether a super() call's value is discarded by its statement: the call
|
|
7081
|
+
* is the expression statement itself, or an operand of a comma chain that
|
|
7082
|
+
* is (`super(m, o), this.code = c;`, as minifiers join statements). The
|
|
7083
|
+
* statement lowering runs each comma operand as its own statement in
|
|
7084
|
+
* source order, so the chain lowers exactly like `super(m, o); this.code =
|
|
7085
|
+
* c;`. Parentheses are transparent to both. */
|
|
7086
|
+
function superCallInStatementPosition(call) {
|
|
7087
|
+
let node = call;
|
|
7088
|
+
for (;;) {
|
|
7089
|
+
const parent = node.parent;
|
|
7090
|
+
if (ts.isExpressionStatement(parent))
|
|
7091
|
+
return true;
|
|
7092
|
+
const comma = ts.isBinaryExpression(parent) && parent.operatorToken.kind === ts.SyntaxKind.CommaToken;
|
|
7093
|
+
if (!comma && !ts.isParenthesizedExpression(parent))
|
|
7094
|
+
return false;
|
|
7095
|
+
node = parent;
|
|
7096
|
+
}
|
|
7097
|
+
}
|
|
6203
7098
|
/** Super statements initialize the base and then the derived fields on
|
|
6204
7099
|
* whichever control-flow path executes. Repeated calls are explicitly
|
|
6205
7100
|
* refused until native layouts can allocate a second receiver. */
|
|
@@ -6212,7 +7107,7 @@ export function lowerDerivedCtorBody(lowerer, info, thisLocal, forward) {
|
|
|
6212
7107
|
const previousInitialized = context.superInitialized;
|
|
6213
7108
|
context.superInitialized = initialized;
|
|
6214
7109
|
context.superCall = (superCall) => {
|
|
6215
|
-
if (!
|
|
7110
|
+
if (!superCallInStatementPosition(superCall))
|
|
6216
7111
|
lowerer.unsupported("SC1090", superCall, "super() in an expression position");
|
|
6217
7112
|
superSeen = true;
|
|
6218
7113
|
const loc = locOf(superCall);
|
|
@@ -6232,11 +7127,11 @@ export function lowerDerivedCtorBody(lowerer, info, thisLocal, forward) {
|
|
|
6232
7127
|
},
|
|
6233
7128
|
];
|
|
6234
7129
|
if (info.callableBase) {
|
|
6235
|
-
if (superCall.arguments.some(ts.isSpreadElement))
|
|
7130
|
+
if (superCall.arguments.nodes.some(ts.isSpreadElement))
|
|
6236
7131
|
lowerer.unsupported("SC1090", superCall, "spreading explicit super arguments into an ordinary constructor");
|
|
6237
7132
|
const pack = {
|
|
6238
7133
|
kind: "dynArrLit",
|
|
6239
|
-
elems: superCall.arguments.map((arg) => lowerer.lowerExprExpecting(arg, DYN)),
|
|
7134
|
+
elems: superCall.arguments.nodes.map((arg) => lowerer.lowerExprExpecting(arg, DYN)),
|
|
6240
7135
|
type: DYN,
|
|
6241
7136
|
loc,
|
|
6242
7137
|
};
|
|
@@ -6244,19 +7139,19 @@ export function lowerDerivedCtorBody(lowerer, info, thisLocal, forward) {
|
|
|
6244
7139
|
}
|
|
6245
7140
|
else {
|
|
6246
7141
|
const base = superBaseOf(info);
|
|
6247
|
-
if (base.builtinEmitter && superCall.arguments.length > 0)
|
|
7142
|
+
if (base.builtinEmitter && superCall.arguments.nodes.length > 0)
|
|
6248
7143
|
lowerer.unsupported("SC1090", superCall, "EventEmitter constructor options ('captureRejections')");
|
|
6249
7144
|
if (base.builtinStream) {
|
|
6250
|
-
statements.push(...lowerStreamSuperCall(lowerer, info, base, superCall.arguments, thisLocal, loc, superCall));
|
|
7145
|
+
statements.push(...lowerStreamSuperCall(lowerer, info, base, superCall.arguments.nodes, thisLocal, loc, superCall));
|
|
6251
7146
|
}
|
|
6252
7147
|
else {
|
|
6253
7148
|
const surplusSpread = forward === undefined &&
|
|
6254
7149
|
!base.builtinError &&
|
|
6255
7150
|
!base.builtinEmitter &&
|
|
6256
7151
|
base.ctorParams.length === 0 &&
|
|
6257
|
-
superCall.arguments.some(ts.isSpreadElement);
|
|
7152
|
+
superCall.arguments.nodes.some(ts.isSpreadElement);
|
|
6258
7153
|
if (surplusSpread) {
|
|
6259
|
-
const evaluated = lowerer.completeArgs(superCall.arguments, [{ mode: "dynRest", type: DYN }], loc, superCall);
|
|
7154
|
+
const evaluated = lowerer.completeArgs(superCall.arguments.nodes, [{ mode: "dynRest", type: DYN }], loc, superCall);
|
|
6260
7155
|
for (const value of evaluated)
|
|
6261
7156
|
statements.push({ kind: "exprStmt", expr: value, loc });
|
|
6262
7157
|
}
|
|
@@ -6264,26 +7159,26 @@ export function lowerDerivedCtorBody(lowerer, info, thisLocal, forward) {
|
|
|
6264
7159
|
!base.builtinError &&
|
|
6265
7160
|
!base.builtinEmitter &&
|
|
6266
7161
|
!base.ctorParams.some((param) => param.mode === "rest" || param.mode === "dynRest") &&
|
|
6267
|
-
!superCall.arguments.some(ts.isSpreadElement) &&
|
|
6268
|
-
superCall.arguments.length > base.ctorParams.length;
|
|
7162
|
+
!superCall.arguments.nodes.some(ts.isSpreadElement) &&
|
|
7163
|
+
superCall.arguments.nodes.length > base.ctorParams.length;
|
|
6269
7164
|
let args = surplusSpread
|
|
6270
7165
|
? []
|
|
6271
7166
|
: forward !== undefined
|
|
6272
7167
|
? forward
|
|
6273
7168
|
: base.builtinError
|
|
6274
|
-
? lowerer.errorConstructorArgs(superCall.arguments, loc, superCall)
|
|
7169
|
+
? lowerer.errorConstructorArgs(superCall.arguments.nodes, loc, superCall)
|
|
6275
7170
|
: base.builtinEmitter
|
|
6276
7171
|
? []
|
|
6277
7172
|
: lowerer.completeArgs(surplus
|
|
6278
|
-
? superCall.arguments.slice(0, base.ctorParams.length)
|
|
6279
|
-
: superCall.arguments, base.ctorParams, loc, superCall);
|
|
7173
|
+
? superCall.arguments.nodes.slice(0, base.ctorParams.length)
|
|
7174
|
+
: superCall.arguments.nodes, base.ctorParams, loc, superCall);
|
|
6280
7175
|
if (surplus) {
|
|
6281
7176
|
args = args.map((arg) => {
|
|
6282
7177
|
const local = lowerer.declareHiddenLocal("%superArgument", arg.type);
|
|
6283
7178
|
statements.push({ kind: "varDecl", localId: local.id, init: arg, loc });
|
|
6284
7179
|
return { kind: "varRef", localId: local.id, type: arg.type, loc };
|
|
6285
7180
|
});
|
|
6286
|
-
for (const argument of superCall.arguments.slice(base.ctorParams.length)) {
|
|
7181
|
+
for (const argument of superCall.arguments.nodes.slice(base.ctorParams.length)) {
|
|
6287
7182
|
statements.push({
|
|
6288
7183
|
kind: "exprStmt",
|
|
6289
7184
|
expr: lowerer.lowerExpr(argument),
|
|
@@ -6323,7 +7218,7 @@ export function lowerDerivedCtorBody(lowerer, info, thisLocal, forward) {
|
|
|
6323
7218
|
};
|
|
6324
7219
|
};
|
|
6325
7220
|
try {
|
|
6326
|
-
const result = lowerer.lowerStmts(info.ctor.body.statements);
|
|
7221
|
+
const result = lowerer.lowerStmts(info.ctor.body.statements.nodes);
|
|
6327
7222
|
result.push({
|
|
6328
7223
|
kind: "if",
|
|
6329
7224
|
cond: {
|
|
@@ -6370,7 +7265,6 @@ export function lowerDerivedCtorBody(lowerer, info, thisLocal, forward) {
|
|
|
6370
7265
|
* `this` (upcast; retained by the varRef read — the callee owns and
|
|
6371
7266
|
* releases its param per the universal convention). */
|
|
6372
7267
|
export function superCallStmt(lowerer, info, thisLocal, args, loc) {
|
|
6373
|
-
const base = superBaseOf(info);
|
|
6374
7268
|
const thisRef = {
|
|
6375
7269
|
kind: "varRef",
|
|
6376
7270
|
localId: thisLocal.id,
|
|
@@ -6415,6 +7309,8 @@ export function superCallStmt(lowerer, info, thisLocal, args, loc) {
|
|
|
6415
7309
|
},
|
|
6416
7310
|
loc,
|
|
6417
7311
|
};
|
|
7312
|
+
// A callable base has no class info, so the base is read after that case.
|
|
7313
|
+
const base = superBaseOf(info);
|
|
6418
7314
|
if (base.builtinError) {
|
|
6419
7315
|
// super(message) into the runtime-provided Error constructor: stamps
|
|
6420
7316
|
// name/message on the (already-allocated) object. Receiver + message
|
|
@@ -6459,7 +7355,7 @@ export function superCallStmt(lowerer, info, thisLocal, args, loc) {
|
|
|
6459
7355
|
return lowerStreamSuperCall(lowerer, info, base, [], thisLocal, loc, info.decl ?? info.ctor)[0];
|
|
6460
7356
|
}
|
|
6461
7357
|
lowerer.noteSuperConstructorEdge(`%${base.def.name}.constructor`);
|
|
6462
|
-
|
|
7358
|
+
const call = {
|
|
6463
7359
|
kind: "exprStmt",
|
|
6464
7360
|
expr: {
|
|
6465
7361
|
kind: "call",
|
|
@@ -6470,6 +7366,7 @@ export function superCallStmt(lowerer, info, thisLocal, args, loc) {
|
|
|
6470
7366
|
},
|
|
6471
7367
|
loc,
|
|
6472
7368
|
};
|
|
7369
|
+
return superIntoResultSlot(lowerer, base, info, call, lowerer.upcastTo({ ...thisRef }, base.def.name), info.ctor ?? info.decl);
|
|
6473
7370
|
}
|
|
6474
7371
|
/** `super.method(args)`: the base chain's implementation, called
|
|
6475
7372
|
* DIRECTLY over this method's own `this` (upcast to the declarer) —
|
|
@@ -6500,7 +7397,7 @@ export function lowerSuperMethodCall(lowerer, call, access) {
|
|
|
6500
7397
|
const instance = genericCallInstance(lowerer, call, gfound.info);
|
|
6501
7398
|
const loc = locOf(call);
|
|
6502
7399
|
const thisRef = { kind: "varRef", localId: thisL.id, type: thisL.type, loc };
|
|
6503
|
-
const args = lowerer.completeArgs(call.arguments, instance.params, loc, call);
|
|
7400
|
+
const args = lowerer.completeArgs(call.arguments.nodes, instance.params, loc, call);
|
|
6504
7401
|
return {
|
|
6505
7402
|
kind: "call",
|
|
6506
7403
|
callee: instance.name,
|
|
@@ -6561,8 +7458,8 @@ export function lowerSuperMethodCall(lowerer, call, access) {
|
|
|
6561
7458
|
kind: "dynCall",
|
|
6562
7459
|
callee,
|
|
6563
7460
|
receiver: lowerer.coerceToExpected(thisRef, DYN),
|
|
6564
|
-
calleeName:
|
|
6565
|
-
args: call.arguments.map((arg) => lowerer.lowerExprExpecting(arg, DYN)),
|
|
7461
|
+
calleeName: ts.getTextOfNode(access),
|
|
7462
|
+
args: call.arguments.nodes.map((arg) => lowerer.lowerExprExpecting(arg, DYN)),
|
|
6566
7463
|
type: DYN,
|
|
6567
7464
|
loc,
|
|
6568
7465
|
};
|
|
@@ -6579,7 +7476,7 @@ export function lowerSuperMethodCall(lowerer, call, access) {
|
|
|
6579
7476
|
};
|
|
6580
7477
|
}
|
|
6581
7478
|
lowerer.noteEdge(`%${found.declarer.def.name}.${access.name.text}`);
|
|
6582
|
-
const args = lowerer.completeArgs(call.arguments, found.sig.params, loc, call);
|
|
7479
|
+
const args = lowerer.completeArgs(call.arguments.nodes, found.sig.params, loc, call);
|
|
6583
7480
|
return {
|
|
6584
7481
|
kind: "call",
|
|
6585
7482
|
callee: `%${found.declarer.def.name}.${access.name.text}`,
|
|
@@ -6696,6 +7593,47 @@ function inheritsBuiltinStreamCtor(lowerer, info) {
|
|
|
6696
7593
|
}
|
|
6697
7594
|
return false;
|
|
6698
7595
|
}
|
|
7596
|
+
/** The run-time form of refuseInheritedBuiltinCtorArgs, for construction
|
|
7597
|
+
* from checked-dynamic code (`new F(options)` with F an untyped value
|
|
7598
|
+
* holding C), whose argument count is known only to the caller: a
|
|
7599
|
+
* runtimeFence located at C, or null when C's constructor takes its
|
|
7600
|
+
* arguments. */
|
|
7601
|
+
export function inheritedBuiltinCtorFence(lowerer, info, loc) {
|
|
7602
|
+
let feature = null;
|
|
7603
|
+
if (inheritsBuiltinStreamCtor(lowerer, info))
|
|
7604
|
+
feature = `new ${info.def.name.replace(/^%/, "")} with arguments through an inherited stream constructor (declare a constructor that passes an inline options object to super(...))`;
|
|
7605
|
+
else if (lowerer.inheritsBuiltinEmitterCtor(info))
|
|
7606
|
+
feature = "EventEmitter constructor options ('captureRejections')";
|
|
7607
|
+
if (feature === null)
|
|
7608
|
+
return null;
|
|
7609
|
+
// Located at the class, whose constructor takes no arguments.
|
|
7610
|
+
const at = info.decl !== null ? locOf(info.decl) : loc;
|
|
7611
|
+
const diag = unsupportedDiag("SC1090", at, feature);
|
|
7612
|
+
lowerer.runtimeFences.push(diag);
|
|
7613
|
+
const line = info.decl !== null
|
|
7614
|
+
? ts.getLineAndCharacterOfPosition(ts.getSourceFileOfNode(info.decl), at.start).line + 1
|
|
7615
|
+
: null;
|
|
7616
|
+
const where = line !== null ? ` [${diag.code} at ${at.file}:${line}]` : "";
|
|
7617
|
+
return { kind: "runtimeFence", code: diag.code, message: `${diag.message}${where}`, loc };
|
|
7618
|
+
}
|
|
7619
|
+
/** `new C(args)` where C's constructor is the inherited runtime stream or
|
|
7620
|
+
* EventEmitter constructor (a ctor-less chain into the base): that
|
|
7621
|
+
* constructor takes zero arguments here (the options bag fences, like the
|
|
7622
|
+
* super() form), so arguments report at the first one. Applies to direct
|
|
7623
|
+
* construction and to construction through a class value of C. Stream
|
|
7624
|
+
* subclasses come first: their chain roots at the emitter too, but the
|
|
7625
|
+
* message should name the stream story. */
|
|
7626
|
+
function refuseInheritedBuiltinCtorArgs(lowerer, info, expr) {
|
|
7627
|
+
const first = expr.arguments?.nodes[0];
|
|
7628
|
+
if (first === undefined)
|
|
7629
|
+
return;
|
|
7630
|
+
if (inheritsBuiltinStreamCtor(lowerer, info)) {
|
|
7631
|
+
lowerer.noLowering(`new ${info.def.name.replace(/^%/, "")} with arguments through an inherited stream constructor`, first, "declare a constructor that passes an inline options object to super(...)");
|
|
7632
|
+
}
|
|
7633
|
+
if (lowerer.inheritsBuiltinEmitterCtor(info)) {
|
|
7634
|
+
lowerer.unsupported("SC1090", first, "EventEmitter constructor options ('captureRejections')");
|
|
7635
|
+
}
|
|
7636
|
+
}
|
|
6699
7637
|
/** Preserve argument evaluation order and option presence through builtin
|
|
6700
7638
|
* and inherited Error constructors. Checked-dynamic conversion retains
|
|
6701
7639
|
* Error identity and distinguishes a missing cause from undefined. */
|
|
@@ -6804,38 +7742,29 @@ function lowerProgramClassNew(lowerer, expr, declaredInfo, loc) {
|
|
|
6804
7742
|
if (info.localClass)
|
|
6805
7743
|
lowerer.unsupported("SC1090", expr, "construction through a function-local class's internal name");
|
|
6806
7744
|
lowerer.noteEdge(`%${info.def.name}.constructor`);
|
|
6807
|
-
|
|
6808
|
-
// zero arguments (the options bag fences, like the super() form).
|
|
6809
|
-
// Stream subclasses come first: their chain roots at the emitter
|
|
6810
|
-
// too, but the message should name the stream story.
|
|
6811
|
-
if (inheritsBuiltinStreamCtor(lowerer, info) && (expr.arguments ?? []).length > 0) {
|
|
6812
|
-
lowerer.noLowering(`new ${info.def.name.replace(/^%/, "")} with arguments through an inherited stream constructor`, expr.arguments[0], "declare a constructor that passes an inline options object to super(...)");
|
|
6813
|
-
}
|
|
6814
|
-
if (lowerer.inheritsBuiltinEmitterCtor(info) && (expr.arguments ?? []).length > 0) {
|
|
6815
|
-
lowerer.unsupported("SC1090", expr.arguments[0], "EventEmitter constructor options ('captureRejections')");
|
|
6816
|
-
}
|
|
7745
|
+
refuseInheritedBuiltinCtorArgs(lowerer, info, expr);
|
|
6817
7746
|
// A ctor-less chain into a builtin error base inherits both arguments;
|
|
6818
7747
|
// each synthesized constructor forwards the same pair to its base.
|
|
6819
7748
|
const args = lowerer.inheritsBuiltinErrorCtor(info)
|
|
6820
|
-
? lowerer.errorConstructorArgs(expr.arguments ?? [], loc, expr)
|
|
6821
|
-
: lowerer.completeArgs(expr.arguments ?? [], info.ctorParams, loc, expr);
|
|
7749
|
+
? lowerer.errorConstructorArgs(expr.arguments?.nodes ?? [], loc, expr)
|
|
7750
|
+
: lowerer.completeArgs(expr.arguments?.nodes ?? [], info.ctorParams, loc, expr);
|
|
6822
7751
|
for (let current = info; current; current = current.base) {
|
|
6823
7752
|
if (current.def.baseValueGlobal)
|
|
6824
|
-
return {
|
|
7753
|
+
return constructedValue(lowerer, info, {
|
|
6825
7754
|
kind: "newValue",
|
|
6826
7755
|
callee: classValueRef(lowerer, info, expr),
|
|
6827
7756
|
args,
|
|
6828
7757
|
type: { kind: "object", className: info.def.name },
|
|
6829
7758
|
loc,
|
|
6830
|
-
};
|
|
7759
|
+
});
|
|
6831
7760
|
}
|
|
6832
|
-
return {
|
|
7761
|
+
return constructedValue(lowerer, info, {
|
|
6833
7762
|
kind: "new",
|
|
6834
7763
|
className: info.def.name,
|
|
6835
7764
|
args,
|
|
6836
7765
|
type: { kind: "object", className: info.def.name },
|
|
6837
7766
|
loc,
|
|
6838
|
-
};
|
|
7767
|
+
});
|
|
6839
7768
|
}
|
|
6840
7769
|
function assignedThisFieldType(lowerer, expr) {
|
|
6841
7770
|
const parent = expr.parent;
|
|
@@ -6848,21 +7777,53 @@ function assignedThisFieldType(lowerer, expr) {
|
|
|
6848
7777
|
}
|
|
6849
7778
|
return lowerer.currentClass?.fields.get(parent.left.name.text) ?? null;
|
|
6850
7779
|
}
|
|
7780
|
+
/** Map, Set and the error classes construct in lowerNew's identifier
|
|
7781
|
+
* branch, which a module member alias of one (`new mod.M()`) also takes. */
|
|
7782
|
+
function isCollectionOrErrorClass(ref) {
|
|
7783
|
+
return ref?.kind === "collection" || ref?.kind === "error";
|
|
7784
|
+
}
|
|
6851
7785
|
export function lowerNew(lowerer, expr) {
|
|
6852
7786
|
const loc = locOf(expr);
|
|
7787
|
+
// A dependency's deprecated `new Buffer(...)` fallback (containers/bytes.ts).
|
|
7788
|
+
{
|
|
7789
|
+
const buffer = lowerNodeModulesBufferConstruct(lowerer, expr);
|
|
7790
|
+
if (buffer)
|
|
7791
|
+
return buffer;
|
|
7792
|
+
}
|
|
7793
|
+
// new Function(...): Node's EvalError under
|
|
7794
|
+
// --disallow-code-generation-from-strings (code-generation.ts).
|
|
7795
|
+
if (codeGenerationCalleeOf(lowerer, expr.expression) === "Function")
|
|
7796
|
+
return lowerCodeGenerationCall(lowerer, expr, "Function");
|
|
7797
|
+
// `new <temporal>.X(...)`: Node 24 has no such global, so the callee's
|
|
7798
|
+
// root read throws the ReferenceError before any argument evaluates.
|
|
7799
|
+
{
|
|
7800
|
+
const root = ambientUndefVarRootOf(lowerer, expr.expression);
|
|
7801
|
+
if (root !== null && root.text === TEMPORAL_GLOBAL) {
|
|
7802
|
+
const t = ambientUndefReadType(lowerer, expr) ?? contextualUndefReadType(lowerer, expr) ?? F64;
|
|
7803
|
+
return nsUndefRead(lowerer, root.text, expr, t);
|
|
7804
|
+
}
|
|
7805
|
+
}
|
|
7806
|
+
// `new (require("./x").C)()`: the module's %init at the require's
|
|
7807
|
+
// position, then construction through the member as for a binding.
|
|
7808
|
+
if (ts.isPropertyAccessExpression(expr.expression) && !expr.expression.questionDotToken) {
|
|
7809
|
+
const req = inlineNamespaceRequireOf(lowerer, expr.expression.expression);
|
|
7810
|
+
if (req !== null && !lowerer.inlineRequireInitDone.has(req.call)) {
|
|
7811
|
+
return lowerWithInlineRequireInit(lowerer, req, () => lowerNew(lowerer, expr));
|
|
7812
|
+
}
|
|
7813
|
+
}
|
|
6853
7814
|
const worker = lowerWorkerNew(lowerer, expr);
|
|
6854
7815
|
if (worker)
|
|
6855
7816
|
return worker;
|
|
6856
7817
|
const readlineUi = lowerReadlineUiNew(lowerer, expr);
|
|
6857
7818
|
if (readlineUi)
|
|
6858
7819
|
return readlineUi;
|
|
6859
|
-
const channel = lowerMessageChannelNew(lowerer, expr);
|
|
7820
|
+
const channel = lowerMessageChannelNew(lowerer, expr) ?? lowerBroadcastChannelNew(lowerer, expr);
|
|
6860
7821
|
if (channel)
|
|
6861
7822
|
return channel;
|
|
6862
7823
|
let intlConstructor = expr.expression;
|
|
6863
7824
|
if (ts.isIdentifier(intlConstructor)) {
|
|
6864
7825
|
const symbol = lowerer.resolveValueSymbol(intlConstructor);
|
|
6865
|
-
const declaration = symbol ?
|
|
7826
|
+
const declaration = symbol ? symbol.valueDeclaration : undefined;
|
|
6866
7827
|
if (declaration && ts.isVariableDeclaration(declaration) && declaration.initializer)
|
|
6867
7828
|
intlConstructor = declaration.initializer;
|
|
6868
7829
|
}
|
|
@@ -6871,6 +7832,9 @@ export function lowerNew(lowerer, expr) {
|
|
|
6871
7832
|
: null;
|
|
6872
7833
|
if (intl && intl !== "Segmenter")
|
|
6873
7834
|
lowerer.noLowering(`new Intl.${intl}`, expr, undefined, lowerer.checker.getSymbolAtLocation(expr.expression));
|
|
7835
|
+
const valueReturning = lowerValueReturningConstructorNew(lowerer, expr);
|
|
7836
|
+
if (valueReturning)
|
|
7837
|
+
return valueReturning;
|
|
6874
7838
|
const instanceConstructor = lowerInstanceConstructorNew(lowerer, expr);
|
|
6875
7839
|
if (instanceConstructor)
|
|
6876
7840
|
return instanceConstructor;
|
|
@@ -6880,11 +7844,9 @@ export function lowerNew(lowerer, expr) {
|
|
|
6880
7844
|
if (ts.isIdentifier(expr.expression)) {
|
|
6881
7845
|
const symbol = lowerer.resolveValueSymbol(expr.expression);
|
|
6882
7846
|
const declaration = symbol &&
|
|
6883
|
-
|
|
6884
|
-
.declarationsOf(symbol)
|
|
6885
|
-
.find((node) => ts.isFunctionDeclaration(node) && node.body !== undefined);
|
|
7847
|
+
symbol.declarations.find((node) => ts.isFunctionDeclaration(node) && node.body !== undefined);
|
|
6886
7848
|
if (declaration && ts.isFunctionDeclaration(declaration) && declaration.body) {
|
|
6887
|
-
const last = declaration.body.statements.at(-1);
|
|
7849
|
+
const last = declaration.body.statements.nodes.at(-1);
|
|
6888
7850
|
if (last &&
|
|
6889
7851
|
ts.isReturnStatement(last) &&
|
|
6890
7852
|
last.expression &&
|
|
@@ -6921,7 +7883,7 @@ export function lowerNew(lowerer, expr) {
|
|
|
6921
7883
|
if (ts.isPropertyAccessExpression(expr.expression) &&
|
|
6922
7884
|
expr.expression.name.text === "Segmenter" &&
|
|
6923
7885
|
lowerer.isStdlibGlobal(expr.expression.expression, "Intl")) {
|
|
6924
|
-
const args = expr.arguments ?? [];
|
|
7886
|
+
const args = expr.arguments?.nodes ?? [];
|
|
6925
7887
|
const undefinedArg = (arg) => (lowerer.typeOf(arg).flags & ts.TypeFlags.Undefined) !== 0;
|
|
6926
7888
|
if (args.length > 2 || (args[0] && !undefinedArg(args[0]))) {
|
|
6927
7889
|
lowerer.noLowering("Intl.Segmenter locale negotiation", expr, "omit the locale or pass undefined for default Unicode grapheme segmentation");
|
|
@@ -6930,7 +7892,7 @@ export function lowerNew(lowerer, expr) {
|
|
|
6930
7892
|
if (options &&
|
|
6931
7893
|
!undefinedArg(options) &&
|
|
6932
7894
|
!(ts.isObjectLiteralExpression(options) &&
|
|
6933
|
-
options.properties.every((property) => ts.isPropertyAssignment(property) &&
|
|
7895
|
+
options.properties.nodes.every((property) => ts.isPropertyAssignment(property) &&
|
|
6934
7896
|
(ts.isIdentifier(property.name) || ts.isStringLiteral(property.name)) &&
|
|
6935
7897
|
property.name.text === "granularity" &&
|
|
6936
7898
|
ts.isStringLiteral(property.initializer) &&
|
|
@@ -6970,8 +7932,8 @@ export function lowerNew(lowerer, expr) {
|
|
|
6970
7932
|
: memberSym;
|
|
6971
7933
|
const emitterInfo = lowerer.builtinEmitterInfoOf(resolved);
|
|
6972
7934
|
if (emitterInfo) {
|
|
6973
|
-
if ((expr.arguments ?? []).length > 0) {
|
|
6974
|
-
lowerer.unsupported("SC1090", expr.arguments[0], "EventEmitter constructor options ('captureRejections')");
|
|
7935
|
+
if ((expr.arguments?.nodes ?? []).length > 0) {
|
|
7936
|
+
lowerer.unsupported("SC1090", expr.arguments.nodes[0], "EventEmitter constructor options ('captureRejections')");
|
|
6975
7937
|
}
|
|
6976
7938
|
return {
|
|
6977
7939
|
kind: "libCall",
|
|
@@ -6992,8 +7954,8 @@ export function lowerNew(lowerer, expr) {
|
|
|
6992
7954
|
// `new zlib.Gzip(options?)` — the zlib stream classes.
|
|
6993
7955
|
const zlibModeNs = zlibStreamModeOf(lowerer, resolved);
|
|
6994
7956
|
if (zlibModeNs !== null) {
|
|
6995
|
-
const what = `new zlib.${
|
|
6996
|
-
return lowerZlibStreamNew(lowerer, expr.arguments ?? [], zlibModeNs, what, expr, loc);
|
|
7957
|
+
const what = `new zlib.${zlibClassName(zlibModeNs)}`;
|
|
7958
|
+
return lowerZlibStreamNew(lowerer, expr.arguments?.nodes ?? [], zlibModeNs, what, expr, loc);
|
|
6997
7959
|
}
|
|
6998
7960
|
// `new N.C(...)` / `new a.Point(...)` — construction through a
|
|
6999
7961
|
// USER namespace qualifier (import= alias chains included): the
|
|
@@ -7040,7 +8002,7 @@ export function lowerNew(lowerer, expr) {
|
|
|
7040
8002
|
// member-export symbol's; the class collects on demand (a body
|
|
7041
8003
|
// lowering ahead of the assignment statement).
|
|
7042
8004
|
if (!expr.expression.questionDotToken &&
|
|
7043
|
-
((isCjsJsFile(
|
|
8005
|
+
((isCjsJsFile(ts.getSourceFileOfNode(expr), lowerer.program) &&
|
|
7044
8006
|
(isModuleExportsAccess(expr.expression.expression) ||
|
|
7045
8007
|
(ts.isIdentifier(expr.expression.expression) &&
|
|
7046
8008
|
expr.expression.expression.text === "exports" &&
|
|
@@ -7055,7 +8017,7 @@ export function lowerNew(lowerer, expr) {
|
|
|
7055
8017
|
memberSym,
|
|
7056
8018
|
resolved,
|
|
7057
8019
|
lowerer.resolveValueSymbol(expr.expression.name) ?? undefined,
|
|
7058
|
-
lowerer.cjsModuleExportSymbol(
|
|
8020
|
+
lowerer.cjsModuleExportSymbol(ts.getSourceFileOfNode(expr), expr.expression.name.text),
|
|
7059
8021
|
];
|
|
7060
8022
|
const exportSym = candidates.find((s) => s !== undefined);
|
|
7061
8023
|
const g = candidates
|
|
@@ -7075,14 +8037,14 @@ export function lowerNew(lowerer, expr) {
|
|
|
7075
8037
|
};
|
|
7076
8038
|
below(info);
|
|
7077
8039
|
const callee = { kind: "varRef", localId: g.id, type: g.type, loc };
|
|
7078
|
-
const args = lowerer.completeArgs(expr.arguments ?? [], info.ctorParams, loc, expr);
|
|
7079
|
-
return {
|
|
8040
|
+
const args = lowerer.completeArgs(expr.arguments?.nodes ?? [], info.ctorParams, loc, expr);
|
|
8041
|
+
return constructedFromValue(lowerer, info, {
|
|
7080
8042
|
kind: "newValue",
|
|
7081
8043
|
callee,
|
|
7082
8044
|
args,
|
|
7083
8045
|
type: { kind: "object", className: info.def.name },
|
|
7084
8046
|
loc,
|
|
7085
|
-
};
|
|
8047
|
+
}, expr);
|
|
7086
8048
|
}
|
|
7087
8049
|
}
|
|
7088
8050
|
}
|
|
@@ -7106,7 +8068,10 @@ export function lowerNew(lowerer, expr) {
|
|
|
7106
8068
|
if (ts.isIdentifier(expr.expression) ||
|
|
7107
8069
|
(ts.isPropertyAccessExpression(expr.expression) &&
|
|
7108
8070
|
ts.isIdentifier(expr.expression.name) &&
|
|
7109
|
-
lowerer.isStdlibGlobal(expr.expression.expression, "globalThis")
|
|
8071
|
+
(lowerer.isStdlibGlobal(expr.expression.expression, "globalThis") ||
|
|
8072
|
+
// `new mod.M()` over an exported `const M = Map` or `const E =
|
|
8073
|
+
// TypeError`
|
|
8074
|
+
isCollectionOrErrorClass(builtinClassRefOf(lowerer, expr.expression))))) {
|
|
7110
8075
|
// `import C = N.C; new C()` — the alias's own source-order guards
|
|
7111
8076
|
// (a no-op for every non-import= binding).
|
|
7112
8077
|
if (ts.isIdentifier(expr.expression))
|
|
@@ -7114,7 +8079,7 @@ export function lowerNew(lowerer, expr) {
|
|
|
7114
8079
|
const identifier = ts.isIdentifier(expr.expression) ? expr.expression : expr.expression.name;
|
|
7115
8080
|
const symbol = ts.isIdentifier(identifier) ? lowerer.resolveValueSymbol(identifier) : null;
|
|
7116
8081
|
if (ts.isIdentifier(identifier) && lowerer.isStdlibGlobal(identifier, "Array")) {
|
|
7117
|
-
return lowerArrayConstructor(lowerer, expr, expr.arguments ?? []);
|
|
8082
|
+
return lowerArrayConstructor(lowerer, expr, expr.arguments?.nodes ?? []);
|
|
7118
8083
|
}
|
|
7119
8084
|
if (isNativeProxyInitializer(lowerer, expr))
|
|
7120
8085
|
return lowerNativeProxy(lowerer, expr);
|
|
@@ -7130,7 +8095,7 @@ export function lowerNew(lowerer, expr) {
|
|
|
7130
8095
|
// `cause` own-property record) / "Error" for absent, and the legacy
|
|
7131
8096
|
// numeric code from the name table.
|
|
7132
8097
|
if (errInfo && errInfo.def.name === "%DOMException") {
|
|
7133
|
-
const args = expr.arguments ?? [];
|
|
8098
|
+
const args = expr.arguments?.nodes ?? [];
|
|
7134
8099
|
if (args.length > 2) {
|
|
7135
8100
|
lowerer.noLowering(`new DOMException with ${args.length} arguments`, expr);
|
|
7136
8101
|
}
|
|
@@ -7163,7 +8128,7 @@ export function lowerNew(lowerer, expr) {
|
|
|
7163
8128
|
if (errInfo && errInfo.def.name === "%AssertionError") {
|
|
7164
8129
|
// new AssertionError(options): Node validates the options object and
|
|
7165
8130
|
// generates the message from operator, actual and expected.
|
|
7166
|
-
const args = expr.arguments ?? [];
|
|
8131
|
+
const args = expr.arguments?.nodes ?? [];
|
|
7167
8132
|
if (args.length > 1 || args.some(ts.isSpreadElement)) {
|
|
7168
8133
|
lowerer.noLowering(`new AssertionError with this argument list`, expr);
|
|
7169
8134
|
}
|
|
@@ -7176,7 +8141,7 @@ export function lowerNew(lowerer, expr) {
|
|
|
7176
8141
|
};
|
|
7177
8142
|
}
|
|
7178
8143
|
if (errInfo && errInfo.def.name === "%SuppressedError") {
|
|
7179
|
-
const args = expr.arguments ?? [];
|
|
8144
|
+
const args = expr.arguments?.nodes ?? [];
|
|
7180
8145
|
if (args.length > 3 || args.some(ts.isSpreadElement)) {
|
|
7181
8146
|
lowerer.noLowering(`new SuppressedError with this argument list`, expr);
|
|
7182
8147
|
}
|
|
@@ -7189,7 +8154,7 @@ export function lowerNew(lowerer, expr) {
|
|
|
7189
8154
|
};
|
|
7190
8155
|
}
|
|
7191
8156
|
if (errInfo && errInfo.def.name === "%AggregateError") {
|
|
7192
|
-
const args = expr.arguments ?? [];
|
|
8157
|
+
const args = expr.arguments?.nodes ?? [];
|
|
7193
8158
|
if (args.length > 3 || args.some(ts.isSpreadElement)) {
|
|
7194
8159
|
lowerer.noLowering(`new AggregateError with this argument list`, expr);
|
|
7195
8160
|
}
|
|
@@ -7203,7 +8168,7 @@ export function lowerNew(lowerer, expr) {
|
|
|
7203
8168
|
};
|
|
7204
8169
|
}
|
|
7205
8170
|
if (errInfo) {
|
|
7206
|
-
const args = lowerer.errorConstructorArgs(expr.arguments ?? [], loc, expr);
|
|
8171
|
+
const args = lowerer.errorConstructorArgs(expr.arguments?.nodes ?? [], loc, expr);
|
|
7207
8172
|
return {
|
|
7208
8173
|
kind: "libCall",
|
|
7209
8174
|
fn: "error.newOptions",
|
|
@@ -7217,8 +8182,8 @@ export function lowerNew(lowerer, expr) {
|
|
|
7217
8182
|
// (@types/node's captureRejections) has no lowering.
|
|
7218
8183
|
const emitterInfo = lowerer.builtinEmitterInfoOf(symbol);
|
|
7219
8184
|
if (emitterInfo) {
|
|
7220
|
-
if ((expr.arguments ?? []).length > 0) {
|
|
7221
|
-
lowerer.unsupported("SC1090", expr.arguments[0], "EventEmitter constructor options ('captureRejections')");
|
|
8185
|
+
if ((expr.arguments?.nodes ?? []).length > 0) {
|
|
8186
|
+
lowerer.unsupported("SC1090", expr.arguments.nodes[0], "EventEmitter constructor options ('captureRejections')");
|
|
7222
8187
|
}
|
|
7223
8188
|
return {
|
|
7224
8189
|
kind: "libCall",
|
|
@@ -7238,8 +8203,8 @@ export function lowerNew(lowerer, expr) {
|
|
|
7238
8203
|
return lowerStreamNew(lowerer, expr, streamInfo);
|
|
7239
8204
|
const zlibMode = zlibStreamModeOf(lowerer, symbol);
|
|
7240
8205
|
if (zlibMode !== null) {
|
|
7241
|
-
const what = `new zlib.${
|
|
7242
|
-
return lowerZlibStreamNew(lowerer, expr.arguments ?? [], zlibMode, what, expr, loc);
|
|
8206
|
+
const what = `new zlib.${zlibClassName(zlibMode)}`;
|
|
8207
|
+
return lowerZlibStreamNew(lowerer, expr.arguments?.nodes ?? [], zlibMode, what, expr, loc);
|
|
7243
8208
|
}
|
|
7244
8209
|
// `new URL(input)`: the WHATWG URL class (stdlib/@types provenance —
|
|
7245
8210
|
// a user's own `class URL` resolves through classBySymbol below).
|
|
@@ -7248,8 +8213,8 @@ export function lowerNew(lowerer, expr) {
|
|
|
7248
8213
|
// libregexp engine the literals ride. The pattern compiles EAGERLY,
|
|
7249
8214
|
// so bad input throws Node's catchable SyntaxError at construction.
|
|
7250
8215
|
// Checked arguments retain native regexes and perform runtime coercion.
|
|
7251
|
-
if (symbol && symbol
|
|
7252
|
-
const args = expr.arguments ?? [];
|
|
8216
|
+
if (symbol && ts.symbolName(symbol) === "RegExp" && lowerer.isStdlibSymbol(symbol)) {
|
|
8217
|
+
const args = expr.arguments?.nodes ?? [];
|
|
7253
8218
|
if (args.length > 2) {
|
|
7254
8219
|
lowerer.noLowering(`new RegExp with ${args.length} arguments`, expr);
|
|
7255
8220
|
}
|
|
@@ -7297,16 +8262,10 @@ export function lowerNew(lowerer, expr) {
|
|
|
7297
8262
|
};
|
|
7298
8263
|
const pattern = strArg(args[0], "pattern");
|
|
7299
8264
|
const flags = strArg(args[1], "flags argument");
|
|
7300
|
-
// Node accepts the 'd'
|
|
7301
|
-
//
|
|
7302
|
-
if (flags.kind === "strLit" && args[1] !== undefined) {
|
|
7303
|
-
|
|
7304
|
-
if (flags.value.includes(f)) {
|
|
7305
|
-
lowerer.unsupported("SC1120", args[1], f === "d"
|
|
7306
|
-
? "the regex 'd' flag (match indices)"
|
|
7307
|
-
: "the regex 'v' flag (unicode sets)");
|
|
7308
|
-
}
|
|
7309
|
-
}
|
|
8265
|
+
// Node accepts the 'd' flag the engine does not have; a literal
|
|
8266
|
+
// flags string refuses here like the literal regex form.
|
|
8267
|
+
if (flags.kind === "strLit" && args[1] !== undefined && flags.value.includes("d")) {
|
|
8268
|
+
lowerer.unsupported("SC1120", args[1], "the regex 'd' flag (match indices)");
|
|
7310
8269
|
}
|
|
7311
8270
|
return {
|
|
7312
8271
|
kind: "libCall",
|
|
@@ -7316,27 +8275,64 @@ export function lowerNew(lowerer, expr) {
|
|
|
7316
8275
|
loc,
|
|
7317
8276
|
};
|
|
7318
8277
|
}
|
|
7319
|
-
if (symbol && symbol
|
|
8278
|
+
if (symbol && ts.symbolName(symbol) === "URL" && lowerer.isStdlibSymbol(symbol)) {
|
|
7320
8279
|
return lowerUrlNew(lowerer, expr);
|
|
7321
8280
|
}
|
|
7322
8281
|
// `new URLSearchParams(init?)`: the WHATWG list (stdlib provenance —
|
|
7323
8282
|
// see lowerSearchParamsNew for the lowered init shapes).
|
|
7324
|
-
if (symbol && symbol
|
|
8283
|
+
if (symbol && ts.symbolName(symbol) === "URLSearchParams" && lowerer.isStdlibSymbol(symbol)) {
|
|
7325
8284
|
return lowerSearchParamsNew(lowerer, expr, loc);
|
|
7326
8285
|
}
|
|
7327
8286
|
// Date's read-only value slice: store the constructor's TimeClip'd
|
|
7328
8287
|
// epoch milliseconds as the scalar date kind. That is sufficient
|
|
7329
8288
|
// for every getter and toISOString; identity and setters stay
|
|
7330
8289
|
// fenced, so copying the scalar cannot create an observable lie.
|
|
7331
|
-
if (symbol && symbol
|
|
7332
|
-
const args = expr.arguments ?? [];
|
|
7333
|
-
if (args.some(ts.isSpreadElement)
|
|
7334
|
-
lowerer.noLowering(`new Date with
|
|
8290
|
+
if (symbol && ts.symbolName(symbol) === "Date" && lowerer.isStdlibSymbol(symbol)) {
|
|
8291
|
+
const args = expr.arguments?.nodes ?? [];
|
|
8292
|
+
if (args.some(ts.isSpreadElement)) {
|
|
8293
|
+
lowerer.noLowering(`new Date with spread arguments`, expr, "new Date(), new Date(milliseconds), new Date(dateString), and new Date(year, monthIndex, ...) with listed arguments are supported", symbol);
|
|
8294
|
+
}
|
|
8295
|
+
// new Date(year, monthIndex[, date[, hours[, minutes[, seconds[, ms]]]]]):
|
|
8296
|
+
// local-time fields, converted to UTC in the host zone at run time.
|
|
8297
|
+
// JavaScript callers pass their arguments to the runtime's ToNumber
|
|
8298
|
+
// (in order, exactly the constructor's coercions); typed callers
|
|
8299
|
+
// pass numbers, completed with the spec's defaults (date 1, time
|
|
8300
|
+
// parts 0) for the seven-f64 ABI.
|
|
8301
|
+
if (args.length > 1) {
|
|
8302
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(expr))) {
|
|
8303
|
+
return {
|
|
8304
|
+
kind: "libCall",
|
|
8305
|
+
fn: "date.nativeNewFields",
|
|
8306
|
+
args: [
|
|
8307
|
+
{
|
|
8308
|
+
kind: "dynArrLit",
|
|
8309
|
+
elems: args.map((arg) => lowerer.lowerExprExpecting(arg, DYN)),
|
|
8310
|
+
type: DYN,
|
|
8311
|
+
loc,
|
|
8312
|
+
},
|
|
8313
|
+
],
|
|
8314
|
+
type: DYN,
|
|
8315
|
+
loc,
|
|
8316
|
+
};
|
|
8317
|
+
}
|
|
8318
|
+
if (args.length > 7) {
|
|
8319
|
+
lowerer.noLowering(`new Date with ${args.length} arguments`, expr, undefined, symbol);
|
|
8320
|
+
}
|
|
8321
|
+
const defaults = [0, 0, 1, 0, 0, 0, 0];
|
|
8322
|
+
const fields = [];
|
|
8323
|
+
for (let i = 0; i < 7; i++) {
|
|
8324
|
+
const arg = args[i];
|
|
8325
|
+
fields.push(arg !== undefined
|
|
8326
|
+
? lowerer.lowerExprExpecting(arg, F64)
|
|
8327
|
+
: { kind: "numLit", value: defaults[i], type: F64, loc });
|
|
8328
|
+
}
|
|
8329
|
+
return { kind: "libCall", fn: "date.newLocal", args: fields, type: DATE_T, loc };
|
|
7335
8330
|
}
|
|
7336
|
-
if (isJsSourceFile(
|
|
8331
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(expr))) {
|
|
7337
8332
|
return {
|
|
7338
8333
|
kind: "libCall",
|
|
7339
|
-
|
|
8334
|
+
// One argument: a string parses with the full date parser.
|
|
8335
|
+
fn: args.length === 1 ? "date.nativeNewValue" : "date.nativeNew",
|
|
7340
8336
|
args: [
|
|
7341
8337
|
{
|
|
7342
8338
|
kind: "dynArrLit",
|
|
@@ -7365,34 +8361,52 @@ export function lowerNew(lowerer, expr) {
|
|
|
7365
8361
|
lowerer.noLowering(`new Date of '${lowerer.fmt(arg.type)}' values`, args[0], "pass milliseconds, a date string, or another Date value", symbol);
|
|
7366
8362
|
}
|
|
7367
8363
|
// `new StringDecoder(encoding?)` (node:string_decoder): the decoder
|
|
7368
|
-
// is a two-field record — the CANONICAL encoding name (
|
|
7369
|
-
//
|
|
7370
|
-
//
|
|
7371
|
-
//
|
|
7372
|
-
//
|
|
7373
|
-
|
|
7374
|
-
|
|
8364
|
+
// is a two-field record — the CANONICAL encoding name (exactly what
|
|
8365
|
+
// `.encoding` answers in Node) and the packed-f64 pending state
|
|
8366
|
+
// starting at 0 (nothing buffered). A literal Buffer encoding folds
|
|
8367
|
+
// its alias at compile time; any other encoding argument is
|
|
8368
|
+
// normalized at run time (Node's normalizeEncoding, which throws
|
|
8369
|
+
// ERR_UNKNOWN_ENCODING for an unknown name). Omitted means utf8,
|
|
8370
|
+
// Node's default.
|
|
8371
|
+
if (symbol && ts.symbolName(symbol) === "StringDecoder" && lowerer.isStdlibSymbol(symbol)) {
|
|
8372
|
+
const args = expr.arguments?.nodes ?? [];
|
|
7375
8373
|
if (args.length > 1) {
|
|
7376
8374
|
lowerer.noLowering("new StringDecoder with 2 arguments", expr, undefined, symbol);
|
|
7377
8375
|
}
|
|
7378
|
-
const
|
|
8376
|
+
const encNode = args[0];
|
|
8377
|
+
const encT = encNode ? lowerer.typeOf(encNode) : undefined;
|
|
8378
|
+
const encName = !encNode
|
|
8379
|
+
? "utf8"
|
|
8380
|
+
: encT.isStringLiteralType()
|
|
8381
|
+
? knownBufEncoding(encT.value)
|
|
8382
|
+
: undefined;
|
|
8383
|
+
const encoding = encName !== undefined
|
|
8384
|
+
? { kind: "strLit", value: encName, type: STRING, loc }
|
|
8385
|
+
: {
|
|
8386
|
+
kind: "libCall",
|
|
8387
|
+
fn: "strdec.encoding",
|
|
8388
|
+
args: [lowerer.lowerExprExpecting(encNode, DYN)],
|
|
8389
|
+
type: STRING,
|
|
8390
|
+
loc,
|
|
8391
|
+
};
|
|
7379
8392
|
const decT = lowerer.mapTypeOf(lowerer.typeOf(expr));
|
|
7380
8393
|
if (decT?.kind !== "record")
|
|
7381
8394
|
lowerer.badType(expr, lowerer.typeOf(expr));
|
|
7382
8395
|
return {
|
|
7383
8396
|
kind: "recordLit",
|
|
7384
8397
|
fields: [
|
|
7385
|
-
{ name: "%enc", value:
|
|
8398
|
+
{ name: "%enc", value: encoding },
|
|
7386
8399
|
{ name: "%pending", value: { kind: "numLit", value: 0, type: F64, loc } },
|
|
7387
8400
|
],
|
|
7388
8401
|
type: decT,
|
|
7389
8402
|
loc,
|
|
7390
8403
|
};
|
|
7391
8404
|
}
|
|
8405
|
+
const codec = symbol ? ts.symbolName(symbol) : undefined;
|
|
7392
8406
|
if (symbol &&
|
|
7393
|
-
(
|
|
8407
|
+
(codec === "TextDecoder" || codec === "TextEncoder") &&
|
|
7394
8408
|
lowerer.isStdlibSymbol(symbol)) {
|
|
7395
|
-
return lowerTextCodecNew(lowerer, expr,
|
|
8409
|
+
return lowerTextCodecNew(lowerer, expr, codec);
|
|
7396
8410
|
}
|
|
7397
8411
|
// `new Uint8Array(...)` / `new Uint32Array(...)` / `new
|
|
7398
8412
|
// Float32Array(...)` / `new Float64Array(...)`: the typed-array
|
|
@@ -7426,25 +8440,26 @@ export function lowerNew(lowerer, expr) {
|
|
|
7426
8440
|
// types get their half named specifically instead of the component
|
|
7427
8441
|
// fence (SC2009, which names Map slots at value positions elsewhere).
|
|
7428
8442
|
// Both Array() and new Array() share the elements/count lowering.
|
|
7429
|
-
if (symbol
|
|
7430
|
-
const object = lowerObjectConstructor(lowerer, expr.arguments ?? [], loc);
|
|
8443
|
+
if (symbol !== null && ts.symbolName(symbol) === "Object" && lowerer.isStdlibSymbol(symbol)) {
|
|
8444
|
+
const object = lowerObjectConstructor(lowerer, expr.arguments?.nodes ?? [], loc);
|
|
7431
8445
|
if (object)
|
|
7432
8446
|
return object;
|
|
7433
8447
|
}
|
|
7434
|
-
if (symbol
|
|
7435
|
-
return lowerArrayConstructor(lowerer, expr, expr.arguments ?? []);
|
|
8448
|
+
if (symbol !== null && ts.symbolName(symbol) === "Array" && lowerer.isStdlibSymbol(symbol)) {
|
|
8449
|
+
return lowerArrayConstructor(lowerer, expr, expr.arguments?.nodes ?? []);
|
|
7436
8450
|
}
|
|
7437
|
-
|
|
7438
|
-
|
|
8451
|
+
// A const alias (`const M = Map`) constructs the same Map.
|
|
8452
|
+
if (ts.isIdentifier(identifier) && lowerer.isStdlibGlobal(identifier, "Map")) {
|
|
8453
|
+
const seedArg = (expr.arguments?.nodes.length ?? 0) === 1 ? expr.arguments.nodes[0] : null;
|
|
7439
8454
|
const isPairLit = (el) => ts.isArrayLiteralExpression(el) &&
|
|
7440
|
-
el.elements.length === 2 &&
|
|
7441
|
-
!el.elements.some(ts.isSpreadElement);
|
|
7442
|
-
const entriesLit = seedArg && ts.isArrayLiteralExpression(seedArg) && seedArg.elements.every(isPairLit)
|
|
7443
|
-
? seedArg.elements.filter(isPairLit)
|
|
8455
|
+
el.elements.nodes.length === 2 &&
|
|
8456
|
+
!el.elements.nodes.some(ts.isSpreadElement);
|
|
8457
|
+
const entriesLit = seedArg && ts.isArrayLiteralExpression(seedArg) && seedArg.elements.nodes.every(isPairLit)
|
|
8458
|
+
? seedArg.elements.nodes.filter(isPairLit)
|
|
7444
8459
|
: null;
|
|
7445
8460
|
let tsType = lowerer.typeOf(expr);
|
|
7446
8461
|
let mapped = lowerer.mapTypeOf(tsType);
|
|
7447
|
-
if (mapped === null && isJsSourceFile(
|
|
8462
|
+
if (mapped === null && isJsSourceFile(ts.getSourceFileOfNode(expr)))
|
|
7448
8463
|
mapped = lowerer.irTypeOf(expr);
|
|
7449
8464
|
const fieldType = assignedThisFieldType(lowerer, expr);
|
|
7450
8465
|
if (mapped?.kind !== "map" && fieldType?.kind === "map")
|
|
@@ -7459,8 +8474,8 @@ export function lowerNew(lowerer, expr) {
|
|
|
7459
8474
|
parent = parent.parent;
|
|
7460
8475
|
// `satisfies` checks a view but retains the expression's own type.
|
|
7461
8476
|
const contextualSeed = !ts.isSatisfiesExpression(parent) &&
|
|
7462
|
-
(expr.typeArguments?.length ?? 0) === 0 &&
|
|
7463
|
-
(entriesLit !== null || (expr.arguments?.length ?? 0) === 0);
|
|
8477
|
+
(expr.typeArguments?.nodes.length ?? 0) === 0 &&
|
|
8478
|
+
(entriesLit !== null || (expr.arguments?.nodes.length ?? 0) === 0);
|
|
7464
8479
|
// JavaScript's `new Map()` has no type-argument syntax: the no-arg
|
|
7465
8480
|
// constructor overload pins Map<any, any> whatever the JSDoc says
|
|
7466
8481
|
// (`@type` on the declaration types the VARIABLE, not this
|
|
@@ -7480,7 +8495,7 @@ export function lowerNew(lowerer, expr) {
|
|
|
7480
8495
|
if (seeded)
|
|
7481
8496
|
return seeded;
|
|
7482
8497
|
}
|
|
7483
|
-
if ((expr.arguments?.length ?? 0) > 0 && !entriesLit) {
|
|
8498
|
+
if ((expr.arguments?.nodes.length ?? 0) > 0 && !entriesLit) {
|
|
7484
8499
|
lowerer.noLowering("new Map(entries)", expr, "supported seeds: an array literal of [key, value] pair literals, or a " +
|
|
7485
8500
|
"[K, V][]-typed tuple-array value, a matching collection or collection iterator, or null/undefined");
|
|
7486
8501
|
}
|
|
@@ -7488,10 +8503,10 @@ export function lowerNew(lowerer, expr) {
|
|
|
7488
8503
|
if (!entriesLit)
|
|
7489
8504
|
return { kind: "mapNew", type: mapped, loc };
|
|
7490
8505
|
const seed = entriesLit.map((pair) => ({
|
|
7491
|
-
key: lowerer.lowerCollectionKey(pair.elements[0], mapped.key),
|
|
8506
|
+
key: lowerer.lowerCollectionKey(pair.elements.nodes[0], mapped.key),
|
|
7492
8507
|
value: mapped.value.kind === "dyn"
|
|
7493
|
-
? lowerer.lowerCollectionKey(pair.elements[1], mapped.value)
|
|
7494
|
-
: lowerer.lowerExprExpecting(pair.elements[1], mapped.value),
|
|
8508
|
+
? lowerer.lowerCollectionKey(pair.elements.nodes[1], mapped.value)
|
|
8509
|
+
: lowerer.lowerExprExpecting(pair.elements.nodes[1], mapped.value),
|
|
7495
8510
|
}));
|
|
7496
8511
|
return { kind: "mapNew", seed, type: mapped, loc };
|
|
7497
8512
|
}
|
|
@@ -7504,8 +8519,8 @@ export function lowerNew(lowerer, expr) {
|
|
|
7504
8519
|
// config-cache shape: module init constructs the caches
|
|
7505
8520
|
// unconditionally; the format path never touches them. TypeScript
|
|
7506
8521
|
// keeps the compile fence.
|
|
7507
|
-
if (isJsSourceFile(
|
|
7508
|
-
(expr.arguments?.length ?? 0) === 0 &&
|
|
8522
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(expr)) &&
|
|
8523
|
+
(expr.arguments?.nodes.length ?? 0) === 0 &&
|
|
7509
8524
|
targs.length > 0 &&
|
|
7510
8525
|
targs.every((t) => (t.flags & ts.TypeFlags.Any) !== 0)) {
|
|
7511
8526
|
return { kind: "dynObjLit", type: DYN, loc };
|
|
@@ -7519,21 +8534,22 @@ export function lowerNew(lowerer, expr) {
|
|
|
7519
8534
|
}
|
|
7520
8535
|
if (targs[1]) {
|
|
7521
8536
|
lowerer.unsupported("SC1090", expr, `Map values of type '${lowerer.checker.typeToString(targs[1])}' ` +
|
|
7522
|
-
`(Map values must be number, string, boolean, records, class instances, ` +
|
|
8537
|
+
`(Map values must be number, string, boolean, records, class instances, functions, ` +
|
|
7523
8538
|
`typed arrays, arrays, promises, Maps, Sets, or supported unions and checked values)`);
|
|
7524
8539
|
}
|
|
7525
8540
|
lowerer.badType(expr, tsType);
|
|
7526
8541
|
}
|
|
7527
8542
|
// Weak containers share checked native key identities and lifetime hooks.
|
|
7528
|
-
if ((symbol
|
|
8543
|
+
if (((symbol !== null && ts.symbolName(symbol) === "WeakMap") ||
|
|
8544
|
+
(symbol !== null && ts.symbolName(symbol) === "WeakSet")) &&
|
|
7529
8545
|
lowerer.isStdlibSymbol(symbol)) {
|
|
7530
|
-
const args = expr.arguments ?? [];
|
|
8546
|
+
const args = expr.arguments?.nodes ?? [];
|
|
7531
8547
|
if (args.length > 1 || args.some(ts.isSpreadElement)) {
|
|
7532
|
-
lowerer.unsupported("SC1090", expr, `${symbol
|
|
8548
|
+
lowerer.unsupported("SC1090", expr, `${ts.symbolName(symbol)} construction with surplus or spread arguments`);
|
|
7533
8549
|
}
|
|
7534
8550
|
return {
|
|
7535
8551
|
kind: "libCall",
|
|
7536
|
-
fn: symbol
|
|
8552
|
+
fn: ts.symbolName(symbol) === "WeakMap" ? "weakMap.new" : "weakSet.new",
|
|
7537
8553
|
args: [args[0] ? lowerer.lowerExprExpecting(args[0], DYN) : dynUndefinedExpr(loc)],
|
|
7538
8554
|
type: DYN,
|
|
7539
8555
|
loc,
|
|
@@ -7541,27 +8557,27 @@ export function lowerNew(lowerer, expr) {
|
|
|
7541
8557
|
}
|
|
7542
8558
|
// `new Set<T>()`: construct + bulk add from supported values,
|
|
7543
8559
|
// including live collection cursors. Duplicates collapse in insertion order.
|
|
7544
|
-
if (
|
|
8560
|
+
if (ts.isIdentifier(identifier) && lowerer.isStdlibGlobal(identifier, "Set")) {
|
|
7545
8561
|
const tsType = lowerer.typeOf(expr);
|
|
7546
8562
|
let mapped = lowerer.mapTypeOf(tsType);
|
|
7547
8563
|
const fieldType = assignedThisFieldType(lowerer, expr);
|
|
7548
8564
|
if (mapped?.kind !== "set" && fieldType?.kind === "set")
|
|
7549
8565
|
mapped = fieldType;
|
|
7550
|
-
if (mapped?.kind === "set" && (expr.arguments?.length ?? 0) === 1) {
|
|
7551
|
-
const seeded = lowerSetSeedNew(lowerer, expr.arguments[0], mapped);
|
|
8566
|
+
if (mapped?.kind === "set" && (expr.arguments?.nodes.length ?? 0) === 1) {
|
|
8567
|
+
const seeded = lowerSetSeedNew(lowerer, expr.arguments.nodes[0], mapped);
|
|
7552
8568
|
if (seeded)
|
|
7553
8569
|
return seeded;
|
|
7554
8570
|
}
|
|
7555
8571
|
if (!mapped &&
|
|
7556
|
-
isJsSourceFile(
|
|
7557
|
-
(expr.arguments?.length ?? 0) <= 1 &&
|
|
7558
|
-
!expr.arguments?.some(ts.isSpreadElement)) {
|
|
8572
|
+
isJsSourceFile(ts.getSourceFileOfNode(expr)) &&
|
|
8573
|
+
(expr.arguments?.nodes.length ?? 0) <= 1 &&
|
|
8574
|
+
!expr.arguments?.nodes.some(ts.isSpreadElement)) {
|
|
7559
8575
|
return {
|
|
7560
8576
|
kind: "libCall",
|
|
7561
8577
|
fn: "dyn.nativeSetNew",
|
|
7562
8578
|
args: [
|
|
7563
|
-
expr.arguments?.[0]
|
|
7564
|
-
? lowerer.lowerExprExpecting(expr.arguments[0], DYN)
|
|
8579
|
+
expr.arguments?.nodes[0]
|
|
8580
|
+
? lowerer.lowerExprExpecting(expr.arguments.nodes[0], DYN)
|
|
7565
8581
|
: dynUndefinedExpr(loc),
|
|
7566
8582
|
],
|
|
7567
8583
|
type: DYN,
|
|
@@ -7574,12 +8590,12 @@ export function lowerNew(lowerer, expr) {
|
|
|
7574
8590
|
// (interned strings — see the JS token stance in lower-exprs), so
|
|
7575
8591
|
// the honest construction is a Set of those scalars.
|
|
7576
8592
|
if (!mapped &&
|
|
7577
|
-
isJsSourceFile(
|
|
7578
|
-
(expr.arguments?.length ?? 0) === 1 &&
|
|
7579
|
-
ts.isArrayLiteralExpression(expr.arguments[0]) &&
|
|
7580
|
-
!expr.arguments[0].elements.some(ts.isSpreadElement)) {
|
|
7581
|
-
const lit = expr.arguments[0];
|
|
7582
|
-
const elems = lit.elements.map((el) => lowerer.lowerExpr(el));
|
|
8593
|
+
isJsSourceFile(ts.getSourceFileOfNode(expr)) &&
|
|
8594
|
+
(expr.arguments?.nodes.length ?? 0) === 1 &&
|
|
8595
|
+
ts.isArrayLiteralExpression(expr.arguments.nodes[0]) &&
|
|
8596
|
+
!expr.arguments.nodes[0].elements.nodes.some(ts.isSpreadElement)) {
|
|
8597
|
+
const lit = expr.arguments.nodes[0];
|
|
8598
|
+
const elems = lit.elements.nodes.map((el) => lowerer.lowerExpr(el));
|
|
7583
8599
|
const first = elems[0];
|
|
7584
8600
|
if (first !== undefined &&
|
|
7585
8601
|
(first.type.kind === "string" || first.type.kind === "f64") &&
|
|
@@ -7589,7 +8605,7 @@ export function lowerNew(lowerer, expr) {
|
|
|
7589
8605
|
return { kind: "setNew", seed, type: setT, loc };
|
|
7590
8606
|
}
|
|
7591
8607
|
}
|
|
7592
|
-
if ((expr.arguments?.length ?? 0) > 0) {
|
|
8608
|
+
if ((expr.arguments?.nodes.length ?? 0) > 0) {
|
|
7593
8609
|
lowerer.noLowering("new Set(values)", expr, "construct the Set empty and add() each value — only nullish values or a matching Set, collection iterator, string, array, or fixed tuple of " +
|
|
7594
8610
|
"supported key values seeds a Set");
|
|
7595
8611
|
}
|
|
@@ -7605,18 +8621,20 @@ export function lowerNew(lowerer, expr) {
|
|
|
7605
8621
|
// `new AsyncLocalStorage()` (node:async_hooks): a fresh store id —
|
|
7606
8622
|
// an f64 handle (type-mapper.ts), the Channel story. Construction options
|
|
7607
8623
|
// ({ defaultValue, name }) have no lowering yet.
|
|
7608
|
-
if (symbol
|
|
7609
|
-
|
|
8624
|
+
if (symbol !== null &&
|
|
8625
|
+
ts.symbolName(symbol) === "AsyncLocalStorage" &&
|
|
8626
|
+
lowerer.isStdlibSymbol(symbol)) {
|
|
8627
|
+
if ((expr.arguments?.nodes.length ?? 0) > 0) {
|
|
7610
8628
|
lowerer.noLowering("new AsyncLocalStorage(options)", expr, "the zero-argument constructor is the supported form (defaultValue/name options have no lowering yet)");
|
|
7611
8629
|
}
|
|
7612
8630
|
return { kind: "libCall", fn: "als.new", args: [], type: F64, loc };
|
|
7613
8631
|
}
|
|
7614
8632
|
// `new Promise<T>((resolve) => ...)`: the ambient Promise constructor.
|
|
7615
|
-
if (symbol
|
|
8633
|
+
if (symbol !== null && ts.symbolName(symbol) === "Promise" && lowerer.isStdlibSymbol(symbol)) {
|
|
7616
8634
|
const type = lowerer.irTypeOf(expr);
|
|
7617
8635
|
if (type.kind !== "promise")
|
|
7618
8636
|
lowerer.badType(expr, lowerer.typeOf(expr));
|
|
7619
|
-
const args = expr.arguments ?? [];
|
|
8637
|
+
const args = expr.arguments?.nodes ?? [];
|
|
7620
8638
|
if (args.length !== 1) {
|
|
7621
8639
|
lowerer.unsupported("SC1090", expr, "Promise construction without an executor");
|
|
7622
8640
|
}
|
|
@@ -7628,8 +8646,9 @@ export function lowerNew(lowerer, expr) {
|
|
|
7628
8646
|
const a0 = args[0];
|
|
7629
8647
|
if (ts.isIdentifier(a0) && a0.text === "setImmediate") {
|
|
7630
8648
|
const sym = lowerer.checker.getSymbolAtLocation(a0);
|
|
7631
|
-
const decls = sym ?
|
|
7632
|
-
if (decls.length > 0 &&
|
|
8649
|
+
const decls = sym ? sym.declarations : [];
|
|
8650
|
+
if (decls.length > 0 &&
|
|
8651
|
+
decls.every((d) => lowerer.isStdlibFile(ts.getSourceFileOfNode(d)))) {
|
|
7633
8652
|
// The settled value is the undefined dyn value — the result
|
|
7634
8653
|
// is promise<dyn> whatever T the checker inferred for the
|
|
7635
8654
|
// unusual executor (Promise<unknown> in the suite's shape).
|
|
@@ -7650,7 +8669,10 @@ export function lowerNew(lowerer, expr) {
|
|
|
7650
8669
|
// catch-side instanceof and the uncaught printer working). First
|
|
7651
8670
|
// settle wins, exactly JS: reject-after-resolve and double-reject
|
|
7652
8671
|
// are no-ops, and an executor throw after any settle is swallowed.
|
|
7653
|
-
|
|
8672
|
+
let executor = lowerer.lowerExpr(args[0]);
|
|
8673
|
+
if (executor.type.kind !== "func")
|
|
8674
|
+
lowerer.badType(args[0], lowerer.typeOf(args[0]));
|
|
8675
|
+
executor = adaptPromiseExecutor(lowerer, executor, type.inner, loc) ?? executor;
|
|
7654
8676
|
if (executor.type.kind !== "func")
|
|
7655
8677
|
lowerer.badType(args[0], lowerer.typeOf(args[0]));
|
|
7656
8678
|
if (executor.type.params.length > 1) {
|
|
@@ -7682,11 +8704,11 @@ export function lowerNew(lowerer, expr) {
|
|
|
7682
8704
|
// Every other new Buffer form keeps the fence below — the
|
|
7683
8705
|
// constructing forms would owe the deprecation warning.
|
|
7684
8706
|
if (expr.expression.text === "Buffer" &&
|
|
7685
|
-
expr.arguments?.length === 2 &&
|
|
7686
|
-
!expr.arguments.some(ts.isSpreadElement) &&
|
|
7687
|
-
lowerer.mapTypeOf(lowerer.typeOf(expr.arguments[0]))?.kind !== "string" &&
|
|
7688
|
-
lowerer.mapTypeOf(lowerer.typeOf(expr.arguments[1]))?.kind === "string") {
|
|
7689
|
-
const first = lowerer.lowerExpr(expr.arguments[0]);
|
|
8707
|
+
expr.arguments?.nodes.length === 2 &&
|
|
8708
|
+
!expr.arguments.nodes.some(ts.isSpreadElement) &&
|
|
8709
|
+
lowerer.mapTypeOf(lowerer.typeOf(expr.arguments.nodes[0]))?.kind !== "string" &&
|
|
8710
|
+
lowerer.mapTypeOf(lowerer.typeOf(expr.arguments.nodes[1]))?.kind === "string") {
|
|
8711
|
+
const first = lowerer.lowerExpr(expr.arguments.nodes[0]);
|
|
7690
8712
|
if (first.kind === "unitLit" ||
|
|
7691
8713
|
first.type.kind === "dyn" ||
|
|
7692
8714
|
lowerer.dynConvertible(first.type)) {
|
|
@@ -7695,7 +8717,7 @@ export function lowerNew(lowerer, expr) {
|
|
|
7695
8717
|
// throw only via the ctor body's later reads — it does NOT
|
|
7696
8718
|
// observe it before throwing, so dropping it is exact for
|
|
7697
8719
|
// effect-free operands; effectful ones keep the fence.
|
|
7698
|
-
const enc = lowerer.lowerExpr(expr.arguments[1]);
|
|
8720
|
+
const enc = lowerer.lowerExpr(expr.arguments.nodes[1]);
|
|
7699
8721
|
if (enc.kind === "strLit" || isSafeToRepeat(enc)) {
|
|
7700
8722
|
return {
|
|
7701
8723
|
kind: "libCall",
|
|
@@ -7745,7 +8767,7 @@ export function lowerNew(lowerer, expr) {
|
|
|
7745
8767
|
return bi?.module === "crypto" && bi.member === "X509Certificate";
|
|
7746
8768
|
})());
|
|
7747
8769
|
if (isX509) {
|
|
7748
|
-
const args = expr.arguments ?? [];
|
|
8770
|
+
const args = expr.arguments?.nodes ?? [];
|
|
7749
8771
|
if (args.length !== 1) {
|
|
7750
8772
|
lowerer.noLowering("X509Certificate with this argument shape", expr, "the supported form is new X509Certificate(readFileSync(path))");
|
|
7751
8773
|
}
|
|
@@ -7838,29 +8860,55 @@ export function lowerNew(lowerer, expr) {
|
|
|
7838
8860
|
return lowerCheckedConstructor(lowerer, expr, callee);
|
|
7839
8861
|
if (callee.type.kind !== "classval")
|
|
7840
8862
|
lowerer.badType(expr.expression, lowerer.typeOf(expr.expression));
|
|
7841
|
-
lowerer.noteEdge(
|
|
8863
|
+
lowerer.noteEdge(classValueConstructor(info.def).fn);
|
|
7842
8864
|
// Every constructor a value in this slot can dispatch to is a
|
|
7843
8865
|
// descendant's — mark them reachable like a virtual edge.
|
|
7844
8866
|
const below = (c) => {
|
|
7845
8867
|
for (const s of c.subclasses) {
|
|
7846
|
-
lowerer.noteEdge(
|
|
8868
|
+
lowerer.noteEdge(classValueConstructor(s.def).fn);
|
|
7847
8869
|
below(s);
|
|
7848
8870
|
}
|
|
7849
8871
|
};
|
|
7850
8872
|
below(info);
|
|
7851
|
-
|
|
7852
|
-
|
|
8873
|
+
// EventEmitter and stream class values construct without options
|
|
8874
|
+
// only: a slot of either may hold any of those classes, and the
|
|
8875
|
+
// direct `new Readable({...})` lowering reads its options at compile
|
|
8876
|
+
// time (EventEmitter's options have no lowering at all).
|
|
8877
|
+
if ((info.builtinStream !== undefined || info.builtinEmitter) &&
|
|
8878
|
+
(expr.arguments?.nodes.length ?? 0) > 0) {
|
|
8879
|
+
lowerer.unsupported("SC1090", expr, `EventEmitter and stream class values constructed with options (construct with 'new ${info.def.name.slice(1)}({ ... })' directly)`);
|
|
8880
|
+
}
|
|
8881
|
+
// A program class whose constructor is the inherited runtime one
|
|
8882
|
+
// takes no arguments through its class value either.
|
|
8883
|
+
refuseInheritedBuiltinCtorArgs(lowerer, info, expr);
|
|
8884
|
+
defineClassValueConstruct(lowerer, info);
|
|
8885
|
+
const args = lowerer.completeArgs(expr.arguments?.nodes ?? [], classValueParams(info), loc, expr);
|
|
8886
|
+
const built = constructedFromValue(lowerer, info, {
|
|
7853
8887
|
kind: "newValue",
|
|
7854
8888
|
callee,
|
|
7855
8889
|
args,
|
|
7856
8890
|
type: { kind: "object", className: info.def.name },
|
|
7857
8891
|
loc,
|
|
7858
|
-
};
|
|
8892
|
+
}, expr);
|
|
8893
|
+
// A runtime class slot widened from a union (`[Readable, Writable]`'s
|
|
8894
|
+
// elements hold EventEmitter values): the checker types the result as
|
|
8895
|
+
// the union of the arms' instances, which the checked class view
|
|
8896
|
+
// answers from the instance's class.
|
|
8897
|
+
if (info.def.runtime) {
|
|
8898
|
+
const resultT = lowerer.mapTypeOf(lowerer.typeOf(expr));
|
|
8899
|
+
if (resultT?.kind === "union") {
|
|
8900
|
+
const asserted = checkedClassUnionAssertion(lowerer, built, resultT, loc);
|
|
8901
|
+
if (asserted)
|
|
8902
|
+
return asserted;
|
|
8903
|
+
}
|
|
8904
|
+
}
|
|
8905
|
+
return built;
|
|
7859
8906
|
}
|
|
7860
8907
|
if (calleeT?.kind === "union") {
|
|
7861
8908
|
const def = lowerer.unions.get(calleeT.unionId);
|
|
7862
8909
|
if (def?.arms.some((a) => a.kind === "classval")) {
|
|
7863
|
-
if (def.arms.every((arm) => arm.kind === "classval" ||
|
|
8910
|
+
if (def.arms.every((arm) => arm.kind === "classval" ||
|
|
8911
|
+
(isJsSourceFile(ts.getSourceFileOfNode(expr)) && isUnitType(arm))) &&
|
|
7864
8912
|
lowerer.dynConvertible(calleeT)) {
|
|
7865
8913
|
const callee = lowerer.lowerExprExpecting(expr.expression, DYN);
|
|
7866
8914
|
return lowerCheckedConstructor(lowerer, expr, callee);
|
|
@@ -7884,7 +8932,7 @@ export function lowerNew(lowerer, expr) {
|
|
|
7884
8932
|
if (ctorName !== null) {
|
|
7885
8933
|
const raw = lowerer.checker.getSymbolAtLocation(ctorName);
|
|
7886
8934
|
const sym = raw && raw.flags & ts.SymbolFlags.Alias ? lowerer.checker.getAliasedSymbol(raw) : raw;
|
|
7887
|
-
const hint = sym && lowerer.isStdlibSymbol(sym) ? own(STDLIB_CTOR_HINTS, sym
|
|
8935
|
+
const hint = sym && lowerer.isStdlibSymbol(sym) ? own(STDLIB_CTOR_HINTS, ts.symbolName(sym)) : undefined;
|
|
7888
8936
|
if (hint !== undefined) {
|
|
7889
8937
|
lowerer.unsupported("SC1090", expr, hint);
|
|
7890
8938
|
}
|
|
@@ -7896,13 +8944,22 @@ export function lowerNew(lowerer, expr) {
|
|
|
7896
8944
|
(callee.type.kind === "dyn" ||
|
|
7897
8945
|
((callee.type.kind === "func" || callee.type.kind === "classval") &&
|
|
7898
8946
|
lowerer.dynConvertible(callee.type)))) {
|
|
7899
|
-
|
|
8947
|
+
let boxed = lowerer.coerceToExpected(callee, DYN);
|
|
8948
|
+
// A plain function's box carries its name: the construction's
|
|
8949
|
+
// prototype records it as `constructor`, which util.inspect prints
|
|
8950
|
+
// (`F { a: 2 }`).
|
|
8951
|
+
if (boxed.kind === "dynFrom" && boxed.fnName === undefined && callee.type.kind === "func") {
|
|
8952
|
+
const name = jsFuncNameOf(expr.expression, lowerer);
|
|
8953
|
+
if (name !== null)
|
|
8954
|
+
boxed = { ...boxed, fnName: name };
|
|
8955
|
+
}
|
|
8956
|
+
return lowerCheckedConstructor(lowerer, expr, boxed);
|
|
7900
8957
|
}
|
|
7901
8958
|
lowerer.unsupported("SC1090", expr, "constructing values other than classes declared in the program");
|
|
7902
8959
|
}
|
|
7903
8960
|
function lowerCheckedConstructor(lowerer, expr, callee) {
|
|
7904
8961
|
const loc = locOf(expr);
|
|
7905
|
-
const args = expr.arguments ?? [];
|
|
8962
|
+
const args = expr.arguments?.nodes ?? [];
|
|
7906
8963
|
if (args.some(ts.isSpreadElement)) {
|
|
7907
8964
|
const packed = lowerer.completeArgs(args, [{ type: DYN, mode: "dynRest" }], loc, expr)[0];
|
|
7908
8965
|
return checkedClassConstructionPacked(lowerer, callee, packed, loc);
|