@scriptc/compiler 0.3.6 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ambient/scriptc-node-fallback.d.ts +682 -50
- package/ambient/scriptc.d.ts +134 -0
- package/dist/backend/cycle-analysis.d.ts +1 -1
- package/dist/backend/cycle-analysis.js +1 -0
- package/dist/backend/cycle-analysis.js.map +1 -1
- package/dist/backend/cycle-analysis.test.js +13 -1
- package/dist/backend/cycle-analysis.test.js.map +1 -1
- package/dist/backend/cycle-mutability.js +16 -5
- package/dist/backend/cycle-mutability.js.map +1 -1
- package/dist/backend/executable-features.js +13 -0
- package/dist/backend/executable-features.js.map +1 -1
- package/dist/backend/immutability.test.js +1 -1
- package/dist/backend/library-pack.js +6 -0
- package/dist/backend/library-pack.js.map +1 -1
- package/dist/backend/llvm/alloc.d.ts +41 -4
- package/dist/backend/llvm/alloc.js +138 -7
- package/dist/backend/llvm/alloc.js.map +1 -1
- package/dist/backend/llvm/alloc.test.js +30 -1
- package/dist/backend/llvm/alloc.test.js.map +1 -1
- package/dist/backend/llvm/appended-array-literals.test.js +1 -1
- package/dist/backend/llvm/array-search.test.js +1 -1
- package/dist/backend/llvm/blocks.d.ts +8 -0
- package/dist/backend/llvm/blocks.js +43 -1
- package/dist/backend/llvm/blocks.js.map +1 -1
- package/dist/backend/llvm/blocks.test.js +22 -1
- package/dist/backend/llvm/blocks.test.js.map +1 -1
- package/dist/backend/llvm/byte-numbers.js +15 -5
- package/dist/backend/llvm/byte-numbers.js.map +1 -1
- package/dist/backend/llvm/bytes-alias.d.ts +14 -0
- package/dist/backend/llvm/bytes-alias.js +20 -0
- package/dist/backend/llvm/bytes-alias.js.map +1 -0
- package/dist/backend/llvm/bytes-loop-versions.d.ts +86 -0
- package/dist/backend/llvm/bytes-loop-versions.js +506 -0
- package/dist/backend/llvm/bytes-loop-versions.js.map +1 -0
- package/dist/backend/llvm/bytes-loop-versions.test.d.ts +1 -0
- package/dist/backend/llvm/bytes-loop-versions.test.js +244 -0
- package/dist/backend/llvm/bytes-loop-versions.test.js.map +1 -0
- package/dist/backend/llvm/call-lifetimes.js +50 -1
- package/dist/backend/llvm/call-lifetimes.js.map +1 -1
- package/dist/backend/llvm/call-lifetimes.test.js +34 -0
- package/dist/backend/llvm/call-lifetimes.test.js.map +1 -1
- package/dist/backend/llvm/checked-narrows.test.js +1 -1
- package/dist/backend/llvm/checked-value-lifetimes.js +4 -1
- package/dist/backend/llvm/checked-value-lifetimes.js.map +1 -1
- package/dist/backend/llvm/classes.d.ts +11 -0
- package/dist/backend/llvm/classes.js +71 -14
- package/dist/backend/llvm/classes.js.map +1 -1
- package/dist/backend/llvm/classes.test.js +58 -8
- package/dist/backend/llvm/classes.test.js.map +1 -1
- package/dist/backend/llvm/common.js +1 -0
- package/dist/backend/llvm/common.js.map +1 -1
- package/dist/backend/llvm/constant-callbacks.d.ts +5 -1
- package/dist/backend/llvm/constant-callbacks.js +55 -12
- package/dist/backend/llvm/constant-callbacks.js.map +1 -1
- package/dist/backend/llvm/constant-callbacks.test.js +88 -1
- package/dist/backend/llvm/constant-callbacks.test.js.map +1 -1
- package/dist/backend/llvm/counted-loops.d.ts +4 -0
- package/dist/backend/llvm/counted-loops.js +37 -0
- package/dist/backend/llvm/counted-loops.js.map +1 -1
- package/dist/backend/llvm/dense-array-access.d.ts +12 -3
- package/dist/backend/llvm/dense-array-access.js +72 -14
- package/dist/backend/llvm/dense-array-access.js.map +1 -1
- package/dist/backend/llvm/dense-array-access.test.js +59 -3
- package/dist/backend/llvm/dense-array-access.test.js.map +1 -1
- package/dist/backend/llvm/dense-array-loops.d.ts +51 -0
- package/dist/backend/llvm/dense-array-loops.js +162 -0
- package/dist/backend/llvm/dense-array-loops.js.map +1 -0
- package/dist/backend/llvm/dense-array-loops.test.d.ts +1 -0
- package/dist/backend/llvm/dense-array-loops.test.js +128 -0
- package/dist/backend/llvm/dense-array-loops.test.js.map +1 -0
- package/dist/backend/llvm/dyn-handle-tags.test.d.ts +1 -0
- package/dist/backend/llvm/dyn-handle-tags.test.js +38 -0
- package/dist/backend/llvm/dyn-handle-tags.test.js.map +1 -0
- package/dist/backend/llvm/dyn.d.ts +28 -4
- package/dist/backend/llvm/dyn.js +293 -178
- package/dist/backend/llvm/dyn.js.map +1 -1
- package/dist/backend/llvm/emit-function.d.ts +64 -0
- package/dist/backend/llvm/emit-function.js +1190 -0
- package/dist/backend/llvm/emit-function.js.map +1 -0
- package/dist/backend/llvm/emit-module.d.ts +24 -0
- package/dist/backend/llvm/emit-module.js +1535 -0
- package/dist/backend/llvm/emit-module.js.map +1 -0
- package/dist/backend/llvm/emit-statements.d.ts +58 -0
- package/dist/backend/llvm/emit-statements.js +1964 -0
- package/dist/backend/llvm/emit-statements.js.map +1 -0
- package/dist/backend/llvm/emitter.d.ts +547 -283
- package/dist/backend/llvm/emitter.js +689 -4643
- package/dist/backend/llvm/emitter.js.map +1 -1
- package/dist/backend/llvm/emitter.test.js +57 -3
- package/dist/backend/llvm/emitter.test.js.map +1 -1
- package/dist/backend/llvm/expr-async.js +73 -46
- package/dist/backend/llvm/expr-async.js.map +1 -1
- package/dist/backend/llvm/expr-async.test.js +1 -1
- package/dist/backend/llvm/expr-bytes.d.ts +2 -0
- package/dist/backend/llvm/expr-bytes.js +76 -29
- package/dist/backend/llvm/expr-bytes.js.map +1 -1
- package/dist/backend/llvm/expr-callbacks.d.ts +6 -2
- package/dist/backend/llvm/expr-callbacks.js +48 -11
- package/dist/backend/llvm/expr-callbacks.js.map +1 -1
- package/dist/backend/llvm/expr-calls.d.ts +1 -1
- package/dist/backend/llvm/expr-calls.js +71 -53
- package/dist/backend/llvm/expr-calls.js.map +1 -1
- package/dist/backend/llvm/expr-calls.test.js +1 -1
- package/dist/backend/llvm/expr-containers.js +39 -15
- package/dist/backend/llvm/expr-containers.js.map +1 -1
- package/dist/backend/llvm/expr-control.js +16 -16
- package/dist/backend/llvm/expr-control.js.map +1 -1
- package/dist/backend/llvm/expr-dynamic.d.ts +3 -0
- package/dist/backend/llvm/expr-dynamic.js +67 -62
- package/dist/backend/llvm/expr-dynamic.js.map +1 -1
- package/dist/backend/llvm/expr-primitives.js +121 -25
- package/dist/backend/llvm/expr-primitives.js.map +1 -1
- package/dist/backend/llvm/expr-primitives.test.js +2 -2
- package/dist/backend/llvm/expr-records.d.ts +1 -1
- package/dist/backend/llvm/expr-records.js +32 -11
- package/dist/backend/llvm/expr-records.js.map +1 -1
- package/dist/backend/llvm/expr-stream-bridges.js +54 -12
- package/dist/backend/llvm/expr-stream-bridges.js.map +1 -1
- package/dist/backend/llvm/expr-stream-bridges.test.js +2 -2
- package/dist/backend/llvm/expr-stream-callbacks.js +22 -1
- package/dist/backend/llvm/expr-stream-callbacks.js.map +1 -1
- package/dist/backend/llvm/int32-abi.test.js +2 -2
- package/dist/backend/llvm/integer-clones.test.js +3 -3
- package/dist/backend/llvm/integer-remainder.d.ts +34 -13
- package/dist/backend/llvm/integer-remainder.js +156 -22
- package/dist/backend/llvm/integer-remainder.js.map +1 -1
- package/dist/backend/llvm/intern-tables.test.js +1 -1
- package/dist/backend/llvm/jsval-encoding.d.ts +21 -0
- package/dist/backend/llvm/jsval-encoding.js +20 -0
- package/dist/backend/llvm/jsval-encoding.js.map +1 -0
- package/dist/backend/llvm/jsval.d.ts +12 -0
- package/dist/backend/llvm/jsval.js +488 -0
- package/dist/backend/llvm/jsval.js.map +1 -0
- package/dist/backend/llvm/lazy-captures.d.ts +12 -2
- package/dist/backend/llvm/lazy-captures.js +39 -17
- package/dist/backend/llvm/lazy-captures.js.map +1 -1
- package/dist/backend/llvm/lib-abi.js +1 -1
- package/dist/backend/llvm/lib-abi.js.map +1 -1
- package/dist/backend/llvm/lib-connect.js +1 -1
- package/dist/backend/llvm/lib-connect.js.map +1 -1
- package/dist/backend/llvm/lib-datagram.js +14 -8
- package/dist/backend/llvm/lib-datagram.js.map +1 -1
- package/dist/backend/llvm/lib-dispatch.js +189 -23
- package/dist/backend/llvm/lib-dispatch.js.map +1 -1
- package/dist/backend/llvm/lib-filesystem.js +42 -13
- package/dist/backend/llvm/lib-filesystem.js.map +1 -1
- package/dist/backend/llvm/lib-http2.js +3 -3
- package/dist/backend/llvm/lib-http2.js.map +1 -1
- package/dist/backend/llvm/lib-lookup.js +2 -2
- package/dist/backend/llvm/lib-lookup.js.map +1 -1
- package/dist/backend/llvm/lib-network.js +56 -22
- package/dist/backend/llvm/lib-network.js.map +1 -1
- package/dist/backend/llvm/lib-process.js +90 -50
- package/dist/backend/llvm/lib-process.js.map +1 -1
- package/dist/backend/llvm/lib-shared.d.ts +12 -0
- package/dist/backend/llvm/lib-shared.js +187 -6
- package/dist/backend/llvm/lib-shared.js.map +1 -1
- package/dist/backend/llvm/lib-stream.js +46 -16
- package/dist/backend/llvm/lib-stream.js.map +1 -1
- package/dist/backend/llvm/lib-test.js +43 -7
- package/dist/backend/llvm/lib-test.js.map +1 -1
- package/dist/backend/llvm/lib-tls.js +4 -9
- package/dist/backend/llvm/lib-tls.js.map +1 -1
- package/dist/backend/llvm/local-array-reads.js +2 -2
- package/dist/backend/llvm/local-array-reads.test.js +1 -1
- package/dist/backend/llvm/local-extents.d.ts +19 -0
- package/dist/backend/llvm/local-extents.js +169 -0
- package/dist/backend/llvm/local-extents.js.map +1 -0
- package/dist/backend/llvm/local-extents.test.d.ts +1 -0
- package/dist/backend/llvm/local-extents.test.js +92 -0
- package/dist/backend/llvm/local-extents.test.js.map +1 -0
- package/dist/backend/llvm/local-union-storage.js +7 -7
- package/dist/backend/llvm/local-union-storage.js.map +1 -1
- package/dist/backend/llvm/local-union-storage.test.js +2 -2
- package/dist/backend/llvm/map-entry-fusion.test.js +1 -1
- package/dist/backend/llvm/map-number-lookup.js +2 -2
- package/dist/backend/llvm/map-number-lookup.test.js +2 -2
- package/dist/backend/llvm/map-read-lifetimes.test.js +2 -2
- package/dist/backend/llvm/narrow-guards.d.ts +38 -0
- package/dist/backend/llvm/narrow-guards.js +151 -0
- package/dist/backend/llvm/narrow-guards.js.map +1 -0
- package/dist/backend/llvm/nullable-unions.d.ts +64 -6
- package/dist/backend/llvm/nullable-unions.js +103 -6
- package/dist/backend/llvm/nullable-unions.js.map +1 -1
- package/dist/backend/llvm/nullable-unions.test.d.ts +1 -0
- package/dist/backend/llvm/nullable-unions.test.js +65 -0
- package/dist/backend/llvm/nullable-unions.test.js.map +1 -0
- package/dist/backend/llvm/publish.d.ts +4 -0
- package/dist/backend/llvm/publish.js +14 -2
- package/dist/backend/llvm/publish.js.map +1 -1
- package/dist/backend/llvm/publish.test.js +1 -1
- package/dist/backend/llvm/receivers.d.ts +31 -0
- package/dist/backend/llvm/receivers.js +395 -0
- package/dist/backend/llvm/receivers.js.map +1 -0
- package/dist/backend/llvm/record-results.d.ts +12 -1
- package/dist/backend/llvm/record-results.js +64 -4
- package/dist/backend/llvm/record-results.js.map +1 -1
- package/dist/backend/llvm/reference-effects.js +9 -0
- package/dist/backend/llvm/reference-effects.js.map +1 -1
- package/dist/backend/llvm/reference-writes.d.ts +4 -0
- package/dist/backend/llvm/reference-writes.js +142 -6
- package/dist/backend/llvm/reference-writes.js.map +1 -1
- package/dist/backend/llvm/reference-writes.test.d.ts +1 -0
- package/dist/backend/llvm/reference-writes.test.js +88 -0
- package/dist/backend/llvm/reference-writes.test.js.map +1 -0
- package/dist/backend/llvm/regex-matchers.d.ts +8 -0
- package/dist/backend/llvm/regex-matchers.js +33 -0
- package/dist/backend/llvm/regex-matchers.js.map +1 -1
- package/dist/backend/llvm/regex-matchers.test.js +23 -1
- package/dist/backend/llvm/regex-matchers.test.js.map +1 -1
- package/dist/backend/llvm/regions.d.ts +1 -1
- package/dist/backend/llvm/regions.js +9 -6
- package/dist/backend/llvm/regions.js.map +1 -1
- package/dist/backend/llvm/regions.test.js +1 -1
- package/dist/backend/llvm/shapes.d.ts +66 -43
- package/dist/backend/llvm/shapes.js +280 -21
- package/dist/backend/llvm/shapes.js.map +1 -1
- package/dist/backend/llvm/shapes.test.js +37 -3
- package/dist/backend/llvm/shapes.test.js.map +1 -1
- package/dist/backend/llvm/split-loops.js +2 -2
- package/dist/backend/llvm/split-loops.js.map +1 -1
- package/dist/backend/llvm/stack-objects.d.ts +26 -6
- package/dist/backend/llvm/stack-objects.js +133 -10
- package/dist/backend/llvm/stack-objects.js.map +1 -1
- package/dist/backend/llvm/stack-objects.test.js +55 -1
- package/dist/backend/llvm/stack-objects.test.js.map +1 -1
- package/dist/backend/llvm/stack-unions.test.js +1 -1
- package/dist/backend/llvm/string-construction.test.js +1 -1
- package/dist/backend/llvm/string-lifetimes.test.js +15 -14
- package/dist/backend/llvm/string-lifetimes.test.js.map +1 -1
- package/dist/backend/llvm/string-slices.d.ts +25 -0
- package/dist/backend/llvm/string-slices.js +207 -1
- package/dist/backend/llvm/string-slices.js.map +1 -1
- package/dist/backend/llvm/string-slices.test.js +139 -2
- package/dist/backend/llvm/string-slices.test.js.map +1 -1
- package/dist/backend/llvm/switch-dispatch.test.js +2 -2
- package/dist/backend/llvm/thread-slots.d.ts +5 -0
- package/dist/backend/llvm/thread-slots.js +142 -0
- package/dist/backend/llvm/thread-slots.js.map +1 -0
- package/dist/backend/llvm/thread-slots.test.d.ts +1 -0
- package/dist/backend/llvm/thread-slots.test.js +110 -0
- package/dist/backend/llvm/thread-slots.test.js.map +1 -0
- package/dist/backend/llvm/union-repr.d.ts +7 -7
- package/dist/backend/llvm/union-repr.js +18 -2
- package/dist/backend/llvm/union-repr.js.map +1 -1
- package/dist/backend/llvm/union-retype.test.js +17 -3
- package/dist/backend/llvm/union-retype.test.js.map +1 -1
- package/dist/backend/llvm/walkers.d.ts +2 -2
- package/dist/backend/llvm/walkers.js +51 -26
- package/dist/backend/llvm/walkers.js.map +1 -1
- package/dist/backend/llvm/wasm-modules.d.ts +16 -0
- package/dist/backend/llvm/wasm-modules.js +66 -0
- package/dist/backend/llvm/wasm-modules.js.map +1 -0
- package/dist/backend/llvm/wrapping-sums.d.ts +7 -0
- package/dist/backend/llvm/wrapping-sums.js +11 -3
- package/dist/backend/llvm/wrapping-sums.js.map +1 -1
- package/dist/backend/mangle.d.ts +7 -0
- package/dist/backend/mangle.js +11 -0
- package/dist/backend/mangle.js.map +1 -1
- package/dist/backend/may-throw.d.ts +3 -0
- package/dist/backend/may-throw.js +4 -2
- package/dist/backend/may-throw.js.map +1 -1
- package/dist/backend/may-throw.test.js +1 -1
- package/dist/backend/native/contracts.d.ts +37 -0
- package/dist/backend/native/executable.js +192 -137
- package/dist/backend/native/executable.js.map +1 -1
- package/dist/backend/native/library.js +1 -0
- package/dist/backend/native/library.js.map +1 -1
- package/dist/backend/native/runtime-inputs.d.ts +1 -1
- package/dist/backend/native/runtime-inputs.js +1 -0
- package/dist/backend/native/runtime-inputs.js.map +1 -1
- package/dist/backend/native-link-info-core.d.ts +30 -0
- package/dist/backend/native-link-info-core.js.map +1 -1
- package/dist/backend/publication.test.js +1 -1
- package/dist/backend/runtime-pack-core.d.ts +9 -1
- package/dist/backend/runtime-pack-core.js +10 -1
- package/dist/backend/runtime-pack-core.js.map +1 -1
- package/dist/backend/runtime-pack-native.js +1 -1
- package/dist/backend/runtime-pack-native.js.map +1 -1
- package/dist/backend/runtime-pack-native.test.d.ts +1 -0
- package/dist/backend/runtime-pack-native.test.js +31 -0
- package/dist/backend/runtime-pack-native.test.js.map +1 -0
- package/dist/backend/runtime-pack-targets.test.js +5 -0
- package/dist/backend/runtime-pack-targets.test.js.map +1 -1
- package/dist/backend/runtime-pack.test.js +5 -0
- package/dist/backend/runtime-pack.test.js.map +1 -1
- package/dist/backend/stack-observations.d.ts +22 -0
- package/dist/backend/stack-observations.js +382 -0
- package/dist/backend/stack-observations.js.map +1 -0
- package/dist/backend/stack-observations.test.d.ts +1 -0
- package/dist/backend/stack-observations.test.js +233 -0
- package/dist/backend/stack-observations.test.js.map +1 -0
- package/dist/backend/target-diagnostics.js +8 -0
- package/dist/backend/target-diagnostics.js.map +1 -1
- package/dist/backend/target-diagnostics.test.js +1 -1
- package/dist/backend/warm-cache.js +5 -0
- package/dist/backend/warm-cache.js.map +1 -1
- package/dist/backend/young-nursery.d.ts +7 -0
- package/dist/backend/young-nursery.js +10 -0
- package/dist/backend/young-nursery.js.map +1 -0
- package/dist/cli/command.js +44 -4
- package/dist/cli/command.js.map +1 -1
- package/dist/cli/usage.d.ts +11 -1
- package/dist/cli/usage.js +20 -1
- package/dist/cli/usage.js.map +1 -1
- package/dist/compat/fetch-profile.js +10 -1
- package/dist/compat/fetch-profile.js.map +1 -1
- package/dist/compile-types.d.ts +13 -0
- package/dist/contracts/check.js +24 -6
- package/dist/contracts/check.js.map +1 -1
- package/dist/contracts/int32-elements.d.ts +115 -0
- package/dist/contracts/int32-elements.js +1179 -0
- package/dist/contracts/int32-elements.js.map +1 -0
- package/dist/coverage/report.d.ts +16 -0
- package/dist/coverage/report.js +182 -1
- package/dist/coverage/report.js.map +1 -1
- package/dist/coverage/surface-manifest.js +16 -3
- package/dist/coverage/surface-manifest.js.map +1 -1
- package/dist/coverage/verdict-cache.d.ts +2 -0
- package/dist/coverage/verdict-cache.js +12 -0
- package/dist/coverage/verdict-cache.js.map +1 -1
- package/dist/coverage/verdict-cache.test.js +2 -1
- package/dist/coverage/verdict-cache.test.js.map +1 -1
- package/dist/diagnostics/diagnostic.d.ts +10 -6
- package/dist/diagnostics/diagnostic.js +29 -21
- package/dist/diagnostics/diagnostic.js.map +1 -1
- package/dist/diagnostics/envelope.d.ts +39 -2
- package/dist/diagnostics/envelope.js.map +1 -1
- package/dist/diagnostics/render.d.ts +7 -0
- package/dist/diagnostics/render.js +50 -13
- package/dist/diagnostics/render.js.map +1 -1
- package/dist/diagnostics/render.test.d.ts +1 -0
- package/dist/diagnostics/render.test.js +49 -0
- package/dist/diagnostics/render.test.js.map +1 -0
- package/dist/executable/executable-cache.d.ts +17 -0
- package/dist/executable/executable-cache.js +13 -1
- package/dist/executable/executable-cache.js.map +1 -1
- package/dist/executable/executable-cache.test.js +7 -1
- package/dist/executable/executable-cache.test.js.map +1 -1
- package/dist/executable/prepare.js +2 -1
- package/dist/executable/prepare.js.map +1 -1
- package/dist/frontend/analysis.js +6 -1
- package/dist/frontend/analysis.js.map +1 -1
- package/dist/frontend/builtin-modules.d.ts +16 -2
- package/dist/frontend/builtin-modules.js +40 -7
- package/dist/frontend/builtin-modules.js.map +1 -1
- package/dist/frontend/cjs-syntax.js +52 -51
- package/dist/frontend/cjs-syntax.js.map +1 -1
- package/dist/frontend/contract-types.d.ts +3 -0
- package/dist/frontend/contract-types.js +36 -7
- package/dist/frontend/contract-types.js.map +1 -1
- package/dist/frontend/experimental-import.d.ts +5 -1
- package/dist/frontend/experimental-import.js +26 -7
- package/dist/frontend/experimental-import.js.map +1 -1
- package/dist/frontend/fork-target.js +20 -22
- package/dist/frontend/fork-target.js.map +1 -1
- package/dist/frontend/fork-target.test.js +2 -1
- package/dist/frontend/fork-target.test.js.map +1 -1
- package/dist/frontend/function-completion.js +6 -6
- package/dist/frontend/function-completion.js.map +1 -1
- package/dist/frontend/helper-tokens.js +15 -3
- package/dist/frontend/helper-tokens.js.map +1 -1
- package/dist/frontend/helper-tokens.test.js +7 -1
- package/dist/frontend/helper-tokens.test.js.map +1 -1
- package/dist/frontend/inferred-js-diagnostics.js +14 -17
- package/dist/frontend/inferred-js-diagnostics.js.map +1 -1
- package/dist/frontend/input-tracker.d.ts +3 -0
- package/dist/frontend/input-tracker.js +32 -3
- package/dist/frontend/input-tracker.js.map +1 -1
- package/dist/frontend/lib-contract.js +36 -32
- package/dist/frontend/lib-contract.js.map +1 -1
- package/dist/frontend/lib-exports.js +3 -3
- package/dist/frontend/lib-exports.js.map +1 -1
- package/dist/frontend/lowering/array-values.d.ts +8 -3
- package/dist/frontend/lowering/array-values.js +60 -11
- package/dist/frontend/lowering/array-values.js.map +1 -1
- package/dist/frontend/lowering/assert-instances.js +4 -4
- package/dist/frontend/lowering/assert-instances.js.map +1 -1
- package/dist/frontend/lowering/assertion-identity.d.ts +12 -0
- package/dist/frontend/lowering/assertion-identity.js +70 -0
- package/dist/frontend/lowering/assertion-identity.js.map +1 -0
- package/dist/frontend/lowering/assertion-members.d.ts +28 -0
- package/dist/frontend/lowering/assertion-members.js +185 -0
- package/dist/frontend/lowering/assertion-members.js.map +1 -0
- package/dist/frontend/lowering/binding-analysis.js +27 -20
- package/dist/frontend/lowering/binding-analysis.js.map +1 -1
- package/dist/frontend/lowering/builtin-calls.js +63 -5
- package/dist/frontend/lowering/builtin-calls.js.map +1 -1
- package/dist/frontend/lowering/builtin-function-fences.d.ts +14 -0
- package/dist/frontend/lowering/builtin-function-fences.js +42 -0
- package/dist/frontend/lowering/builtin-function-fences.js.map +1 -0
- package/dist/frontend/lowering/builtins/arguments.js +1 -1
- package/dist/frontend/lowering/builtins/arguments.js.map +1 -1
- package/dist/frontend/lowering/builtins/async-context.js +53 -52
- package/dist/frontend/lowering/builtins/async-context.js.map +1 -1
- package/dist/frontend/lowering/builtins/atomics.js +6 -6
- package/dist/frontend/lowering/builtins/atomics.js.map +1 -1
- package/dist/frontend/lowering/builtins/blob.js +8 -6
- package/dist/frontend/lowering/builtins/blob.js.map +1 -1
- package/dist/frontend/lowering/builtins/builtin-class-dyn.d.ts +23 -0
- package/dist/frontend/lowering/builtins/builtin-class-dyn.js +156 -0
- package/dist/frontend/lowering/builtins/builtin-class-dyn.js.map +1 -0
- package/dist/frontend/lowering/builtins/callable-aliases.js +16 -5
- package/dist/frontend/lowering/builtins/callable-aliases.js.map +1 -1
- package/dist/frontend/lowering/builtins/child-process-async.js +7 -7
- package/dist/frontend/lowering/builtins/child-process-async.js.map +1 -1
- package/dist/frontend/lowering/builtins/child-process-methods.d.ts +6 -4
- package/dist/frontend/lowering/builtins/child-process-methods.js +310 -57
- package/dist/frontend/lowering/builtins/child-process-methods.js.map +1 -1
- package/dist/frontend/lowering/builtins/child-process-sync.js +16 -10
- package/dist/frontend/lowering/builtins/child-process-sync.js.map +1 -1
- package/dist/frontend/lowering/builtins/child-process.d.ts +6 -4
- package/dist/frontend/lowering/builtins/child-process.js +85 -61
- package/dist/frontend/lowering/builtins/child-process.js.map +1 -1
- package/dist/frontend/lowering/builtins/class-values.d.ts +60 -0
- package/dist/frontend/lowering/builtins/class-values.js +226 -0
- package/dist/frontend/lowering/builtins/class-values.js.map +1 -0
- package/dist/frontend/lowering/builtins/compression.d.ts +9 -0
- package/dist/frontend/lowering/builtins/compression.js +107 -44
- package/dist/frontend/lowering/builtins/compression.js.map +1 -1
- package/dist/frontend/lowering/builtins/constants.d.ts +9 -1
- package/dist/frontend/lowering/builtins/constants.js +28 -7
- package/dist/frontend/lowering/builtins/constants.js.map +1 -1
- package/dist/frontend/lowering/builtins/crypto.d.ts +19 -0
- package/dist/frontend/lowering/builtins/crypto.js +211 -37
- package/dist/frontend/lowering/builtins/crypto.js.map +1 -1
- package/dist/frontend/lowering/builtins/dates.d.ts +7 -1
- package/dist/frontend/lowering/builtins/dates.js +92 -16
- package/dist/frontend/lowering/builtins/dates.js.map +1 -1
- package/dist/frontend/lowering/builtins/disposable-stack.d.ts +18 -0
- package/dist/frontend/lowering/builtins/disposable-stack.js +137 -0
- package/dist/frontend/lowering/builtins/disposable-stack.js.map +1 -0
- package/dist/frontend/lowering/builtins/environment.js +3 -3
- package/dist/frontend/lowering/builtins/environment.js.map +1 -1
- package/dist/frontend/lowering/builtins/errors.d.ts +14 -10
- package/dist/frontend/lowering/builtins/errors.js +169 -3
- package/dist/frontend/lowering/builtins/errors.js.map +1 -1
- package/dist/frontend/lowering/builtins/filesystem-calls.js +128 -116
- package/dist/frontend/lowering/builtins/filesystem-calls.js.map +1 -1
- package/dist/frontend/lowering/builtins/filesystem.js +77 -77
- package/dist/frontend/lowering/builtins/filesystem.js.map +1 -1
- package/dist/frontend/lowering/builtins/fs-glob.js +3 -3
- package/dist/frontend/lowering/builtins/fs-glob.js.map +1 -1
- package/dist/frontend/lowering/builtins/fs-streams.js +10 -11
- package/dist/frontend/lowering/builtins/fs-streams.js.map +1 -1
- package/dist/frontend/lowering/builtins/ipc.js +45 -8
- package/dist/frontend/lowering/builtins/ipc.js.map +1 -1
- package/dist/frontend/lowering/builtins/json.js +232 -24
- package/dist/frontend/lowering/builtins/json.js.map +1 -1
- package/dist/frontend/lowering/builtins/key-object.js +4 -4
- package/dist/frontend/lowering/builtins/key-object.js.map +1 -1
- package/dist/frontend/lowering/builtins/module-bindings.d.ts +8 -0
- package/dist/frontend/lowering/builtins/module-bindings.js +71 -22
- package/dist/frontend/lowering/builtins/module-bindings.js.map +1 -1
- package/dist/frontend/lowering/builtins/module-calls.js +55 -44
- package/dist/frontend/lowering/builtins/module-calls.js.map +1 -1
- package/dist/frontend/lowering/builtins/module-resolution.d.ts +4 -3
- package/dist/frontend/lowering/builtins/module-resolution.js +24 -23
- package/dist/frontend/lowering/builtins/module-resolution.js.map +1 -1
- package/dist/frontend/lowering/builtins/navigator.d.ts +13 -0
- package/dist/frontend/lowering/builtins/navigator.js +40 -0
- package/dist/frontend/lowering/builtins/navigator.js.map +1 -0
- package/dist/frontend/lowering/builtins/net-address.d.ts +19 -0
- package/dist/frontend/lowering/builtins/net-address.js +156 -0
- package/dist/frontend/lowering/builtins/net-address.js.map +1 -0
- package/dist/frontend/lowering/builtins/numbers.js +25 -9
- package/dist/frontend/lowering/builtins/numbers.js.map +1 -1
- package/dist/frontend/lowering/builtins/operating-system.d.ts +4 -0
- package/dist/frontend/lowering/builtins/operating-system.js +25 -12
- package/dist/frontend/lowering/builtins/operating-system.js.map +1 -1
- package/dist/frontend/lowering/builtins/performance.d.ts +12 -0
- package/dist/frontend/lowering/builtins/performance.js +259 -8
- package/dist/frontend/lowering/builtins/performance.js.map +1 -1
- package/dist/frontend/lowering/builtins/process.d.ts +32 -1
- package/dist/frontend/lowering/builtins/process.js +461 -99
- package/dist/frontend/lowering/builtins/process.js.map +1 -1
- package/dist/frontend/lowering/builtins/promises.d.ts +5 -1
- package/dist/frontend/lowering/builtins/promises.js +326 -43
- package/dist/frontend/lowering/builtins/promises.js.map +1 -1
- package/dist/frontend/lowering/builtins/promisify-callback.d.ts +37 -0
- package/dist/frontend/lowering/builtins/promisify-callback.js +320 -0
- package/dist/frontend/lowering/builtins/promisify-callback.js.map +1 -0
- package/dist/frontend/lowering/builtins/properties.js +37 -1
- package/dist/frontend/lowering/builtins/properties.js.map +1 -1
- package/dist/frontend/lowering/builtins/querystring.js +14 -14
- package/dist/frontend/lowering/builtins/querystring.js.map +1 -1
- package/dist/frontend/lowering/builtins/readline.d.ts +12 -2
- package/dist/frontend/lowering/builtins/readline.js +136 -39
- package/dist/frontend/lowering/builtins/readline.js.map +1 -1
- package/dist/frontend/lowering/builtins/receiver-types.js +3 -5
- package/dist/frontend/lowering/builtins/receiver-types.js.map +1 -1
- package/dist/frontend/lowering/builtins/reflection.js +16 -14
- package/dist/frontend/lowering/builtins/reflection.js.map +1 -1
- package/dist/frontend/lowering/builtins/runtime-constructor.d.ts +26 -0
- package/dist/frontend/lowering/builtins/runtime-constructor.js +165 -0
- package/dist/frontend/lowering/builtins/runtime-constructor.js.map +1 -0
- package/dist/frontend/lowering/builtins/strings.js +101 -12
- package/dist/frontend/lowering/builtins/strings.js.map +1 -1
- package/dist/frontend/lowering/builtins/text-codecs.js +41 -38
- package/dist/frontend/lowering/builtins/text-codecs.js.map +1 -1
- package/dist/frontend/lowering/builtins/timers.js +75 -30
- package/dist/frontend/lowering/builtins/timers.js.map +1 -1
- package/dist/frontend/lowering/builtins/url.d.ts +3 -0
- package/dist/frontend/lowering/builtins/url.js +120 -17
- package/dist/frontend/lowering/builtins/url.js.map +1 -1
- package/dist/frontend/lowering/builtins/util-types.js +20 -4
- package/dist/frontend/lowering/builtins/util-types.js.map +1 -1
- package/dist/frontend/lowering/builtins/v8.d.ts +11 -0
- package/dist/frontend/lowering/builtins/v8.js +105 -0
- package/dist/frontend/lowering/builtins/v8.js.map +1 -0
- package/dist/frontend/lowering/builtins/webassembly.d.ts +33 -0
- package/dist/frontend/lowering/builtins/webassembly.js +388 -0
- package/dist/frontend/lowering/builtins/webassembly.js.map +1 -0
- package/dist/frontend/lowering/builtins/webcrypto.d.ts +20 -0
- package/dist/frontend/lowering/builtins/webcrypto.js +112 -0
- package/dist/frontend/lowering/builtins/webcrypto.js.map +1 -0
- package/dist/frontend/lowering/builtins/workers.d.ts +12 -0
- package/dist/frontend/lowering/builtins/workers.js +193 -8
- package/dist/frontend/lowering/builtins/workers.js.map +1 -1
- package/dist/frontend/lowering/call-arguments.js +69 -14
- package/dist/frontend/lowering/call-arguments.js.map +1 -1
- package/dist/frontend/lowering/call-signatures.d.ts +19 -1
- package/dist/frontend/lowering/call-signatures.js +254 -47
- package/dist/frontend/lowering/call-signatures.js.map +1 -1
- package/dist/frontend/lowering/checked-promise-all.d.ts +3 -0
- package/dist/frontend/lowering/checked-promise-all.js +1 -1
- package/dist/frontend/lowering/checked-promise-all.js.map +1 -1
- package/dist/frontend/lowering/cjs-exports-object.d.ts +53 -0
- package/dist/frontend/lowering/cjs-exports-object.js +528 -0
- package/dist/frontend/lowering/cjs-exports-object.js.map +1 -0
- package/dist/frontend/lowering/cjs-inline-require.d.ts +86 -0
- package/dist/frontend/lowering/cjs-inline-require.js +314 -0
- package/dist/frontend/lowering/cjs-inline-require.js.map +1 -0
- package/dist/frontend/lowering/cjs-tsc-interop.d.ts +28 -0
- package/dist/frontend/lowering/cjs-tsc-interop.js +208 -0
- package/dist/frontend/lowering/cjs-tsc-interop.js.map +1 -0
- package/dist/frontend/lowering/class-attributes.d.ts +19 -0
- package/dist/frontend/lowering/class-attributes.js +378 -0
- package/dist/frontend/lowering/class-attributes.js.map +1 -0
- package/dist/frontend/lowering/class-callbacks.d.ts +3 -1
- package/dist/frontend/lowering/class-callbacks.js +21 -10
- package/dist/frontend/lowering/class-callbacks.js.map +1 -1
- package/dist/frontend/lowering/class-construction.js +49 -4
- package/dist/frontend/lowering/class-construction.js.map +1 -1
- package/dist/frontend/lowering/class-descriptors.d.ts +2 -0
- package/dist/frontend/lowering/class-descriptors.js +8 -8
- package/dist/frontend/lowering/class-descriptors.js.map +1 -1
- package/dist/frontend/lowering/class-dynamic-dispatch.d.ts +64 -0
- package/dist/frontend/lowering/class-dynamic-dispatch.js +1115 -89
- package/dist/frontend/lowering/class-dynamic-dispatch.js.map +1 -1
- package/dist/frontend/lowering/class-instance-constructor.js +1 -1
- package/dist/frontend/lowering/class-instance-constructor.js.map +1 -1
- package/dist/frontend/lowering/class-iterables.d.ts +11 -0
- package/dist/frontend/lowering/class-iterables.js +31 -0
- package/dist/frontend/lowering/class-iterables.js.map +1 -0
- package/dist/frontend/lowering/class-method-mutations.js +73 -35
- package/dist/frontend/lowering/class-method-mutations.js.map +1 -1
- package/dist/frontend/lowering/class-method-values.js +56 -10
- package/dist/frontend/lowering/class-method-values.js.map +1 -1
- package/dist/frontend/lowering/class-protocol-dispatch.js +24 -22
- package/dist/frontend/lowering/class-protocol-dispatch.js.map +1 -1
- package/dist/frontend/lowering/class-protocols.js +25 -44
- package/dist/frontend/lowering/class-protocols.js.map +1 -1
- package/dist/frontend/lowering/class-prototypes.d.ts +6 -0
- package/dist/frontend/lowering/class-prototypes.js +80 -18
- package/dist/frontend/lowering/class-prototypes.js.map +1 -1
- package/dist/frontend/lowering/class-runtime-statics.js +1 -1
- package/dist/frontend/lowering/class-runtime-statics.js.map +1 -1
- package/dist/frontend/lowering/class-static-data.js +2 -2
- package/dist/frontend/lowering/class-static-data.js.map +1 -1
- package/dist/frontend/lowering/class-to-primitive.d.ts +25 -0
- package/dist/frontend/lowering/class-to-primitive.js +261 -0
- package/dist/frontend/lowering/class-to-primitive.js.map +1 -0
- package/dist/frontend/lowering/class-unions.d.ts +25 -0
- package/dist/frontend/lowering/class-unions.js +102 -1
- package/dist/frontend/lowering/class-unions.js.map +1 -1
- package/dist/frontend/lowering/code-generation.d.ts +14 -0
- package/dist/frontend/lowering/code-generation.js +127 -0
- package/dist/frontend/lowering/code-generation.js.map +1 -0
- package/dist/frontend/lowering/coercions/function-adapters.d.ts +16 -2
- package/dist/frontend/lowering/coercions/function-adapters.js +145 -3
- package/dist/frontend/lowering/coercions/function-adapters.js.map +1 -1
- package/dist/frontend/lowering/coercions/structural-plans.js +25 -3
- package/dist/frontend/lowering/coercions/structural-plans.js.map +1 -1
- package/dist/frontend/lowering/coercions/structural.js +35 -3
- package/dist/frontend/lowering/coercions/structural.js.map +1 -1
- package/dist/frontend/lowering/coercions/unions.d.ts +15 -0
- package/dist/frontend/lowering/coercions/unions.js +57 -1
- package/dist/frontend/lowering/coercions/unions.js.map +1 -1
- package/dist/frontend/lowering/collection-ingestion.js +2 -2
- package/dist/frontend/lowering/collection-ingestion.js.map +1 -1
- package/dist/frontend/lowering/collection-narrowing.js +2 -4
- package/dist/frontend/lowering/collection-narrowing.js.map +1 -1
- package/dist/frontend/lowering/construction-escapes.js +8 -8
- package/dist/frontend/lowering/construction-escapes.js.map +1 -1
- package/dist/frontend/lowering/construction-escapes.test.js +4 -4
- package/dist/frontend/lowering/construction-escapes.test.js.map +1 -1
- package/dist/frontend/lowering/constructor-returns.d.ts +61 -0
- package/dist/frontend/lowering/constructor-returns.js +477 -0
- package/dist/frontend/lowering/constructor-returns.js.map +1 -0
- package/dist/frontend/lowering/containers/array-callback-call.js +1 -1
- package/dist/frontend/lowering/containers/array-callback-call.js.map +1 -1
- package/dist/frontend/lowering/containers/array-callbacks.d.ts +9 -0
- package/dist/frontend/lowering/containers/array-callbacks.js +266 -100
- package/dist/frontend/lowering/containers/array-callbacks.js.map +1 -1
- package/dist/frontend/lowering/containers/array-concat.js +1 -1
- package/dist/frontend/lowering/containers/array-concat.js.map +1 -1
- package/dist/frontend/lowering/containers/array-construction.d.ts +0 -1
- package/dist/frontend/lowering/containers/array-construction.js +51 -13
- package/dist/frontend/lowering/containers/array-construction.js.map +1 -1
- package/dist/frontend/lowering/containers/array-from-async.d.ts +6 -5
- package/dist/frontend/lowering/containers/array-from-async.js +159 -14
- package/dist/frontend/lowering/containers/array-from-async.js.map +1 -1
- package/dist/frontend/lowering/containers/array-methods.js +89 -77
- package/dist/frontend/lowering/containers/array-methods.js.map +1 -1
- package/dist/frontend/lowering/containers/array-pipelines.js +1 -0
- package/dist/frontend/lowering/containers/array-pipelines.js.map +1 -1
- package/dist/frontend/lowering/containers/bytes.js +161 -101
- package/dist/frontend/lowering/containers/bytes.js.map +1 -1
- package/dist/frontend/lowering/containers/callback-arguments.d.ts +9 -1
- package/dist/frontend/lowering/containers/callback-arguments.js +55 -5
- package/dist/frontend/lowering/containers/callback-arguments.js.map +1 -1
- package/dist/frontend/lowering/containers/collection-grouping.d.ts +7 -8
- package/dist/frontend/lowering/containers/collection-grouping.js +217 -26
- package/dist/frontend/lowering/containers/collection-grouping.js.map +1 -1
- package/dist/frontend/lowering/containers/collection-methods.js +54 -25
- package/dist/frontend/lowering/containers/collection-methods.js.map +1 -1
- package/dist/frontend/lowering/containers/dynamic-receivers.js +1 -1
- package/dist/frontend/lowering/containers/dynamic-receivers.js.map +1 -1
- package/dist/frontend/lowering/containers/exec-result-uses.js +2 -2
- package/dist/frontend/lowering/containers/exec-result-uses.js.map +1 -1
- package/dist/frontend/lowering/containers/for-of.d.ts +6 -0
- package/dist/frontend/lowering/containers/for-of.js +19 -19
- package/dist/frontend/lowering/containers/for-of.js.map +1 -1
- package/dist/frontend/lowering/containers/indexed-objects.js +142 -57
- package/dist/frontend/lowering/containers/indexed-objects.js.map +1 -1
- package/dist/frontend/lowering/containers/iterator-helpers.d.ts +53 -4
- package/dist/frontend/lowering/containers/iterator-helpers.js +1581 -462
- package/dist/frontend/lowering/containers/iterator-helpers.js.map +1 -1
- package/dist/frontend/lowering/containers/match-row-uses.d.ts +17 -0
- package/dist/frontend/lowering/containers/match-row-uses.js +264 -0
- package/dist/frontend/lowering/containers/match-row-uses.js.map +1 -0
- package/dist/frontend/lowering/containers/string-and-regexp.d.ts +14 -0
- package/dist/frontend/lowering/containers/string-and-regexp.js +419 -30
- package/dist/frontend/lowering/containers/string-and-regexp.js.map +1 -1
- package/dist/frontend/lowering/containers/string-replacement.js +1 -1
- package/dist/frontend/lowering/containers/string-replacement.js.map +1 -1
- package/dist/frontend/lowering/cycle-initialization.d.ts +4 -0
- package/dist/frontend/lowering/cycle-initialization.js +39 -0
- package/dist/frontend/lowering/cycle-initialization.js.map +1 -1
- package/dist/frontend/lowering/deferred-module-initializers.js +47 -43
- package/dist/frontend/lowering/deferred-module-initializers.js.map +1 -1
- package/dist/frontend/lowering/devirtualize.d.ts +1 -1
- package/dist/frontend/lowering/devirtualize.js +27 -7
- package/dist/frontend/lowering/devirtualize.js.map +1 -1
- package/dist/frontend/lowering/divergences.d.ts +0 -5
- package/dist/frontend/lowering/divergences.js +62 -125
- package/dist/frontend/lowering/divergences.js.map +1 -1
- package/dist/frontend/lowering/dyn-streams.d.ts +25 -0
- package/dist/frontend/lowering/dyn-streams.js +257 -0
- package/dist/frontend/lowering/dyn-streams.js.map +1 -0
- package/dist/frontend/lowering/error-methods.js +4 -1
- package/dist/frontend/lowering/error-methods.js.map +1 -1
- package/dist/frontend/lowering/error-name-order.d.ts +19 -0
- package/dist/frontend/lowering/error-name-order.js +93 -0
- package/dist/frontend/lowering/error-name-order.js.map +1 -0
- package/dist/frontend/lowering/expressions/array-literals.d.ts +21 -0
- package/dist/frontend/lowering/expressions/array-literals.js +703 -0
- package/dist/frontend/lowering/expressions/array-literals.js.map +1 -0
- package/dist/frontend/lowering/expressions/binary.d.ts +35 -0
- package/dist/frontend/lowering/expressions/binary.js +2483 -0
- package/dist/frontend/lowering/expressions/binary.js.map +1 -0
- package/dist/frontend/lowering/expressions/element-access.d.ts +31 -0
- package/dist/frontend/lowering/expressions/element-access.js +1797 -0
- package/dist/frontend/lowering/expressions/element-access.js.map +1 -0
- package/dist/frontend/lowering/expressions/evaluation-safety.js +4 -3
- package/dist/frontend/lowering/expressions/evaluation-safety.js.map +1 -1
- package/dist/frontend/lowering/expressions/hosted-narrowing.d.ts +38 -0
- package/dist/frontend/lowering/expressions/hosted-narrowing.js +160 -0
- package/dist/frontend/lowering/expressions/hosted-narrowing.js.map +1 -0
- package/dist/frontend/lowering/expressions/identifiers.d.ts +4 -0
- package/dist/frontend/lowering/expressions/identifiers.js +830 -0
- package/dist/frontend/lowering/expressions/identifiers.js.map +1 -0
- package/dist/frontend/lowering/expressions/keyed-field-targets.d.ts +40 -0
- package/dist/frontend/lowering/expressions/keyed-field-targets.js +226 -0
- package/dist/frontend/lowering/expressions/keyed-field-targets.js.map +1 -0
- package/dist/frontend/lowering/expressions/narrowing.d.ts +37 -0
- package/dist/frontend/lowering/expressions/narrowing.js +1322 -0
- package/dist/frontend/lowering/expressions/narrowing.js.map +1 -0
- package/dist/frontend/lowering/expressions/native-proxy.js +4 -4
- package/dist/frontend/lowering/expressions/native-proxy.js.map +1 -1
- package/dist/frontend/lowering/expressions/nullish-assignment.js +45 -0
- package/dist/frontend/lowering/expressions/nullish-assignment.js.map +1 -1
- package/dist/frontend/lowering/expressions/object-literals.d.ts +10 -0
- package/dist/frontend/lowering/expressions/object-literals.js +253 -85
- package/dist/frontend/lowering/expressions/object-literals.js.map +1 -1
- package/dist/frontend/lowering/expressions/optional-chains.d.ts +2 -1
- package/dist/frontend/lowering/expressions/optional-chains.js +91 -14
- package/dist/frontend/lowering/expressions/optional-chains.js.map +1 -1
- package/dist/frontend/lowering/expressions/property-access.d.ts +110 -0
- package/dist/frontend/lowering/expressions/property-access.js +3544 -0
- package/dist/frontend/lowering/expressions/property-access.js.map +1 -0
- package/dist/frontend/lowering/expressions/relational.d.ts +28 -0
- package/dist/frontend/lowering/expressions/relational.js +1679 -0
- package/dist/frontend/lowering/expressions/relational.js.map +1 -0
- package/dist/frontend/lowering/expressions/typeof.d.ts +22 -0
- package/dist/frontend/lowering/expressions/typeof.js +538 -0
- package/dist/frontend/lowering/expressions/typeof.js.map +1 -0
- package/dist/frontend/lowering/expressions/union-fields.js +1 -1
- package/dist/frontend/lowering/expressions/union-fields.js.map +1 -1
- package/dist/frontend/lowering/expressions/updates.d.ts +21 -0
- package/dist/frontend/lowering/expressions/updates.js +780 -0
- package/dist/frontend/lowering/expressions/updates.js.map +1 -0
- package/dist/frontend/lowering/function-context.d.ts +10 -0
- package/dist/frontend/lowering/function-context.js +11 -1
- package/dist/frontend/lowering/function-context.js.map +1 -1
- package/dist/frontend/lowering/function-returns.js +52 -28
- package/dist/frontend/lowering/function-returns.js.map +1 -1
- package/dist/frontend/lowering/general-streams.d.ts +25 -0
- package/dist/frontend/lowering/general-streams.js +108 -0
- package/dist/frontend/lowering/general-streams.js.map +1 -0
- package/dist/frontend/lowering/generator-dynamic-dispatch.d.ts +7 -0
- package/dist/frontend/lowering/generator-dynamic-dispatch.js +172 -69
- package/dist/frontend/lowering/generator-dynamic-dispatch.js.map +1 -1
- package/dist/frontend/lowering/generic-functions.d.ts +39 -0
- package/dist/frontend/lowering/generic-functions.js +393 -75
- package/dist/frontend/lowering/generic-functions.js.map +1 -1
- package/dist/frontend/lowering/import-meta.js +2 -2
- package/dist/frontend/lowering/import-meta.js.map +1 -1
- package/dist/frontend/lowering/intern-tables.js +10 -9
- package/dist/frontend/lowering/intern-tables.js.map +1 -1
- package/dist/frontend/lowering/iterator-adapters.d.ts +19 -0
- package/dist/frontend/lowering/iterator-adapters.js +331 -3
- package/dist/frontend/lowering/iterator-adapters.js.map +1 -1
- package/dist/frontend/lowering/js-class-fields.d.ts +28 -0
- package/dist/frontend/lowering/js-class-fields.js +170 -0
- package/dist/frontend/lowering/js-class-fields.js.map +1 -0
- package/dist/frontend/lowering/js-dynamic-objects.d.ts +15 -0
- package/dist/frontend/lowering/js-dynamic-objects.js +299 -0
- package/dist/frontend/lowering/js-dynamic-objects.js.map +1 -0
- package/dist/frontend/lowering/js-dynamic-objects.test.d.ts +1 -0
- package/dist/frontend/lowering/js-dynamic-objects.test.js +35 -0
- package/dist/frontend/lowering/js-dynamic-objects.test.js.map +1 -0
- package/dist/frontend/lowering/json-require.d.ts +22 -0
- package/dist/frontend/lowering/json-require.js +131 -0
- package/dist/frontend/lowering/json-require.js.map +1 -0
- package/dist/frontend/lowering/key-order-witness.d.ts +44 -0
- package/dist/frontend/lowering/key-order-witness.js +641 -0
- package/dist/frontend/lowering/key-order-witness.js.map +1 -0
- package/dist/frontend/lowering/key-order-witness.test.d.ts +1 -0
- package/dist/frontend/lowering/key-order-witness.test.js +239 -0
- package/dist/frontend/lowering/key-order-witness.test.js.map +1 -0
- package/dist/frontend/lowering/lifetime-regions.js +7 -7
- package/dist/frontend/lowering/lifetime-regions.js.map +1 -1
- package/dist/frontend/lowering/lower-assert.js +61 -60
- package/dist/frontend/lowering/lower-assert.js.map +1 -1
- package/dist/frontend/lowering/lower-async-iteration.d.ts +10 -1
- package/dist/frontend/lowering/lower-async-iteration.js +34 -6
- package/dist/frontend/lowering/lower-async-iteration.js.map +1 -1
- package/dist/frontend/lowering/lower-builtin-values.d.ts +5 -0
- package/dist/frontend/lowering/lower-builtin-values.js +32 -3
- package/dist/frontend/lowering/lower-builtin-values.js.map +1 -1
- package/dist/frontend/lowering/lower-calls.js +1239 -442
- package/dist/frontend/lowering/lower-calls.js.map +1 -1
- package/dist/frontend/lowering/lower-classes.d.ts +50 -3
- package/dist/frontend/lowering/lower-classes.js +1473 -468
- package/dist/frontend/lowering/lower-classes.js.map +1 -1
- package/dist/frontend/lowering/lower-comptime.d.ts +4 -2
- package/dist/frontend/lowering/lower-comptime.js +111 -13
- package/dist/frontend/lowering/lower-comptime.js.map +1 -1
- package/dist/frontend/lowering/lower-console.js +13 -11
- package/dist/frontend/lowering/lower-console.js.map +1 -1
- package/dist/frontend/lowering/lower-dgram.d.ts +10 -0
- package/dist/frontend/lowering/lower-dgram.js +179 -8
- package/dist/frontend/lowering/lower-dgram.js.map +1 -1
- package/dist/frontend/lowering/lower-enums.js +113 -14
- package/dist/frontend/lowering/lower-enums.js.map +1 -1
- package/dist/frontend/lowering/lower-event-emitter.d.ts +16 -7
- package/dist/frontend/lowering/lower-event-emitter.js +258 -70
- package/dist/frontend/lowering/lower-event-emitter.js.map +1 -1
- package/dist/frontend/lowering/lower-event-target.js +2 -2
- package/dist/frontend/lowering/lower-event-target.js.map +1 -1
- package/dist/frontend/lowering/lower-expando.js +17 -13
- package/dist/frontend/lowering/lower-expando.js.map +1 -1
- package/dist/frontend/lowering/lower-exprs.d.ts +188 -186
- package/dist/frontend/lowering/lower-exprs.js +1481 -12489
- package/dist/frontend/lowering/lower-exprs.js.map +1 -1
- package/dist/frontend/lowering/lower-functions.js +68 -22
- package/dist/frontend/lowering/lower-functions.js.map +1 -1
- package/dist/frontend/lowering/lower-generators.d.ts +6 -0
- package/dist/frontend/lowering/lower-generators.js +29 -16
- package/dist/frontend/lowering/lower-generators.js.map +1 -1
- package/dist/frontend/lowering/lower-global-value.js +5 -1
- package/dist/frontend/lowering/lower-global-value.js.map +1 -1
- package/dist/frontend/lowering/lower-inspect.js +331 -96
- package/dist/frontend/lowering/lower-inspect.js.map +1 -1
- package/dist/frontend/lowering/lower-mixins.js +23 -20
- package/dist/frontend/lowering/lower-mixins.js.map +1 -1
- package/dist/frontend/lowering/lower-mock.d.ts +8 -1
- package/dist/frontend/lowering/lower-mock.js +185 -18
- package/dist/frontend/lowering/lower-mock.js.map +1 -1
- package/dist/frontend/lowering/lower-modules.js +267 -61
- package/dist/frontend/lowering/lower-modules.js.map +1 -1
- package/dist/frontend/lowering/lower-namespaces.d.ts +6 -0
- package/dist/frontend/lowering/lower-namespaces.js +45 -33
- package/dist/frontend/lowering/lower-namespaces.js.map +1 -1
- package/dist/frontend/lowering/lower-node-module.d.ts +16 -0
- package/dist/frontend/lowering/lower-node-module.js +147 -14
- package/dist/frontend/lowering/lower-node-module.js.map +1 -1
- package/dist/frontend/lowering/lower-server.d.ts +6 -6
- package/dist/frontend/lowering/lower-server.js +488 -100
- package/dist/frontend/lowering/lower-server.js.map +1 -1
- package/dist/frontend/lowering/lower-stdlib.d.ts +4 -0
- package/dist/frontend/lowering/lower-stdlib.js +151 -109
- package/dist/frontend/lowering/lower-stdlib.js.map +1 -1
- package/dist/frontend/lowering/lower-stmts.d.ts +28 -2
- package/dist/frontend/lowering/lower-stmts.js +1541 -391
- package/dist/frontend/lowering/lower-stmts.js.map +1 -1
- package/dist/frontend/lowering/lower-stream.d.ts +3 -0
- package/dist/frontend/lowering/lower-stream.js +398 -56
- package/dist/frontend/lowering/lower-stream.js.map +1 -1
- package/dist/frontend/lowering/lower-test.d.ts +3 -0
- package/dist/frontend/lowering/lower-test.js +437 -62
- package/dist/frontend/lowering/lower-test.js.map +1 -1
- package/dist/frontend/lowering/lower-timers.js +80 -32
- package/dist/frontend/lowering/lower-timers.js.map +1 -1
- package/dist/frontend/lowering/lower-url.js +1 -1
- package/dist/frontend/lowering/lower-url.js.map +1 -1
- package/dist/frontend/lowering/lowerer.d.ts +399 -26
- package/dist/frontend/lowering/lowerer.js +1910 -305
- package/dist/frontend/lowering/lowerer.js.map +1 -1
- package/dist/frontend/lowering/lowerer.test.js +10 -4
- package/dist/frontend/lowering/lowerer.test.js.map +1 -1
- package/dist/frontend/lowering/maybe-promise.d.ts +46 -0
- package/dist/frontend/lowering/maybe-promise.js +249 -0
- package/dist/frontend/lowering/maybe-promise.js.map +1 -0
- package/dist/frontend/lowering/module-member-this.d.ts +3 -0
- package/dist/frontend/lowering/module-member-this.js +262 -0
- package/dist/frontend/lowering/module-member-this.js.map +1 -0
- package/dist/frontend/lowering/module-namespace-elements.js +1 -1
- package/dist/frontend/lowering/module-namespace-elements.js.map +1 -1
- package/dist/frontend/lowering/nan-coded-reads.d.ts +3 -0
- package/dist/frontend/lowering/nan-coded-reads.js +45 -32
- package/dist/frontend/lowering/nan-coded-reads.js.map +1 -1
- package/dist/frontend/lowering/narrowing-stability.d.ts +18 -3
- package/dist/frontend/lowering/narrowing-stability.js +104 -32
- package/dist/frontend/lowering/narrowing-stability.js.map +1 -1
- package/dist/frontend/lowering/native-ffi.js +11 -11
- package/dist/frontend/lowering/native-ffi.js.map +1 -1
- package/dist/frontend/lowering/object-factory-new.js +6 -8
- package/dist/frontend/lowering/object-factory-new.js.map +1 -1
- package/dist/frontend/lowering/private-brands.d.ts +46 -0
- package/dist/frontend/lowering/private-brands.js +265 -0
- package/dist/frontend/lowering/private-brands.js.map +1 -0
- package/dist/frontend/lowering/promise-executor-adapter.d.ts +11 -0
- package/dist/frontend/lowering/promise-executor-adapter.js +87 -0
- package/dist/frontend/lowering/promise-executor-adapter.js.map +1 -0
- package/dist/frontend/lowering/require-initialization.d.ts +32 -0
- package/dist/frontend/lowering/require-initialization.js +246 -0
- package/dist/frontend/lowering/require-initialization.js.map +1 -0
- package/dist/frontend/lowering/runtime-optional-bounds.js +7 -7
- package/dist/frontend/lowering/runtime-optional-bounds.js.map +1 -1
- package/dist/frontend/lowering/runtime-optional-elements.js +12 -12
- package/dist/frontend/lowering/runtime-optional-elements.js.map +1 -1
- package/dist/frontend/lowering/runtime-optional-guards.js +10 -10
- package/dist/frontend/lowering/runtime-optional-guards.js.map +1 -1
- package/dist/frontend/lowering/runtime-optional-guards.test.js +1 -1
- package/dist/frontend/lowering/runtime-optional-guards.test.js.map +1 -1
- package/dist/frontend/lowering/runtime-optional-ownership.js +10 -9
- package/dist/frontend/lowering/runtime-optional-ownership.js.map +1 -1
- package/dist/frontend/lowering/runtime-optional-provenance.js +2 -2
- package/dist/frontend/lowering/runtime-optional-provenance.js.map +1 -1
- package/dist/frontend/lowering/runtime-optional-records.d.ts +35 -0
- package/dist/frontend/lowering/runtime-optional-records.js +205 -32
- package/dist/frontend/lowering/runtime-optional-records.js.map +1 -1
- package/dist/frontend/lowering/runtime-optional-records.test.js +19 -1
- package/dist/frontend/lowering/runtime-optional-records.test.js.map +1 -1
- package/dist/frontend/lowering/sanitize-class-types.test.js +2 -2
- package/dist/frontend/lowering/split-consumers.js +4 -4
- package/dist/frontend/lowering/split-consumers.js.map +1 -1
- package/dist/frontend/lowering/static-function-names.d.ts +28 -0
- package/dist/frontend/lowering/static-function-names.js +212 -0
- package/dist/frontend/lowering/static-function-names.js.map +1 -0
- package/dist/frontend/lowering/static-this.js +6 -6
- package/dist/frontend/lowering/static-this.js.map +1 -1
- package/dist/frontend/lowering/strict-mode.d.ts +5 -0
- package/dist/frontend/lowering/strict-mode.js +31 -0
- package/dist/frontend/lowering/strict-mode.js.map +1 -0
- package/dist/frontend/lowering/string-index-bounds.js +10 -10
- package/dist/frontend/lowering/string-index-bounds.js.map +1 -1
- package/dist/frontend/lowering/string-index.d.ts +12 -0
- package/dist/frontend/lowering/string-index.js +72 -1
- package/dist/frontend/lowering/string-index.js.map +1 -1
- package/dist/frontend/lowering/surfaces.d.ts +12 -3
- package/dist/frontend/lowering/surfaces.js +252 -41
- package/dist/frontend/lowering/surfaces.js.map +1 -1
- package/dist/frontend/lowering/symbol-fields.d.ts +7 -0
- package/dist/frontend/lowering/symbol-fields.js +204 -36
- package/dist/frontend/lowering/symbol-fields.js.map +1 -1
- package/dist/frontend/lowering/symbol-methods.d.ts +2 -1
- package/dist/frontend/lowering/symbol-methods.js +24 -6
- package/dist/frontend/lowering/symbol-methods.js.map +1 -1
- package/dist/frontend/lowering/thread-slots.d.ts +13 -0
- package/dist/frontend/lowering/thread-slots.js +208 -0
- package/dist/frontend/lowering/thread-slots.js.map +1 -0
- package/dist/frontend/lowering/typed-arguments.d.ts +74 -0
- package/dist/frontend/lowering/typed-arguments.js +472 -0
- package/dist/frontend/lowering/typed-arguments.js.map +1 -0
- package/dist/frontend/lowering/union-retag.d.ts +8 -0
- package/dist/frontend/lowering/union-retag.js +27 -0
- package/dist/frontend/lowering/union-retag.js.map +1 -1
- package/dist/frontend/lowering/union-retag.test.js +24 -1
- package/dist/frontend/lowering/union-retag.test.js.map +1 -1
- package/dist/frontend/lowering/var-hoisting.js +6 -6
- package/dist/frontend/lowering/var-hoisting.js.map +1 -1
- package/dist/frontend/lowering/width-lift.d.ts +4 -0
- package/dist/frontend/mock-shapes.js +13 -6
- package/dist/frontend/mock-shapes.js.map +1 -1
- package/dist/frontend/module-source-candidates.js +1 -1
- package/dist/frontend/module-source-candidates.js.map +1 -1
- package/dist/frontend/module-source-candidates.test.js +2 -1
- package/dist/frontend/module-source-candidates.test.js.map +1 -1
- package/dist/frontend/module-syntax.js +8 -8
- package/dist/frontend/module-syntax.js.map +1 -1
- package/dist/frontend/npm-static-bundled-chunks.d.ts +51 -0
- package/dist/frontend/npm-static-bundled-chunks.js +810 -0
- package/dist/frontend/npm-static-bundled-chunks.js.map +1 -0
- package/dist/frontend/npm-static-bundled-chunks.test.d.ts +1 -0
- package/dist/frontend/npm-static-bundled-chunks.test.js +287 -0
- package/dist/frontend/npm-static-bundled-chunks.test.js.map +1 -0
- package/dist/frontend/npm-static-bundled-cjs.js +24 -23
- package/dist/frontend/npm-static-bundled-cjs.js.map +1 -1
- package/dist/frontend/npm-static-bundled-esm.d.ts +9 -0
- package/dist/frontend/npm-static-bundled-esm.js +768 -0
- package/dist/frontend/npm-static-bundled-esm.js.map +1 -0
- package/dist/frontend/npm-static-bundled-esm.test.d.ts +1 -0
- package/dist/frontend/npm-static-bundled-esm.test.js +207 -0
- package/dist/frontend/npm-static-bundled-esm.test.js.map +1 -0
- package/dist/frontend/npm-static-cjs-exports-alias.d.ts +2 -0
- package/dist/frontend/npm-static-cjs-exports-alias.js +186 -0
- package/dist/frontend/npm-static-cjs-exports-alias.js.map +1 -0
- package/dist/frontend/npm-static-cjs-exports-alias.test.d.ts +1 -0
- package/dist/frontend/npm-static-cjs-exports-alias.test.js +73 -0
- package/dist/frontend/npm-static-cjs-exports-alias.test.js.map +1 -0
- package/dist/frontend/npm-static-cjs-exports-var.d.ts +2 -0
- package/dist/frontend/npm-static-cjs-exports-var.js +236 -0
- package/dist/frontend/npm-static-cjs-exports-var.js.map +1 -0
- package/dist/frontend/npm-static-declaration-syntax.js +102 -101
- package/dist/frontend/npm-static-declaration-syntax.js.map +1 -1
- package/dist/frontend/npm-static-prune.js +36 -24
- package/dist/frontend/npm-static-prune.js.map +1 -1
- package/dist/frontend/npm-static-rewrite-host.d.ts +4 -1
- package/dist/frontend/npm-static-rewrite-host.js +14 -3
- package/dist/frontend/npm-static-rewrite-host.js.map +1 -1
- package/dist/frontend/npm-static-rewrite-syntax.d.ts +19 -0
- package/dist/frontend/npm-static-rewrite-syntax.js +274 -101
- package/dist/frontend/npm-static-rewrite-syntax.js.map +1 -1
- package/dist/frontend/npm-static-subtyping.js +7 -9
- package/dist/frontend/npm-static-subtyping.js.map +1 -1
- package/dist/frontend/npm-static.d.ts +17 -1
- package/dist/frontend/npm-static.js +167 -16
- package/dist/frontend/npm-static.js.map +1 -1
- package/dist/frontend/npm-static.test.js +22 -1
- package/dist/frontend/npm-static.test.js.map +1 -1
- package/dist/frontend/pipeline.js +164 -26
- package/dist/frontend/pipeline.js.map +1 -1
- package/dist/frontend/pipeline.test.js +22 -1
- package/dist/frontend/pipeline.test.js.map +1 -1
- package/dist/frontend/program-analysis.d.ts +6 -1
- package/dist/frontend/program-analysis.js +7 -0
- package/dist/frontend/program-analysis.js.map +1 -1
- package/dist/frontend/program.d.ts +92 -2
- package/dist/frontend/program.js +1557 -255
- package/dist/frontend/program.js.map +1 -1
- package/dist/frontend/program.test.js +76 -6
- package/dist/frontend/program.test.js.map +1 -1
- package/dist/frontend/resolve.js +36 -2
- package/dist/frontend/resolve.js.map +1 -1
- package/dist/frontend/resolve.test.js +49 -0
- package/dist/frontend/resolve.test.js.map +1 -1
- package/dist/frontend/services.d.ts +20 -1
- package/dist/frontend/services.js +40 -3
- package/dist/frontend/services.js.map +1 -1
- package/dist/frontend/services.test.js +2 -1
- package/dist/frontend/services.test.js.map +1 -1
- package/dist/frontend/threads-import.js +1 -1
- package/dist/frontend/threads-import.js.map +1 -1
- package/dist/frontend/tier-analysis.d.ts +71 -0
- package/dist/frontend/tier-analysis.js +522 -0
- package/dist/frontend/tier-analysis.js.map +1 -0
- package/dist/frontend/ts7/api-conformance.d.ts +234 -0
- package/dist/frontend/ts7/api-conformance.js +7 -0
- package/dist/frontend/ts7/api-conformance.js.map +1 -0
- package/dist/frontend/ts7/ast-guards.generated.js +2 -1
- package/dist/frontend/ts7/ast-guards.generated.js.map +1 -1
- package/dist/frontend/ts7/ast-node.d.ts +47 -25
- package/dist/frontend/ts7/ast-node.js +64 -18
- package/dist/frontend/ts7/ast-node.js.map +1 -1
- package/dist/frontend/ts7/ast-node.test.js +36 -12
- package/dist/frontend/ts7/ast-node.test.js.map +1 -1
- package/dist/frontend/ts7/ast-types.d.ts +10 -3
- package/dist/frontend/ts7/ast-types.generated.d.ts +39 -39
- package/dist/frontend/ts7/ast.d.ts +1 -0
- package/dist/frontend/ts7/ast.js +3 -2
- package/dist/frontend/ts7/ast.js.map +1 -1
- package/dist/frontend/ts7/checker-backend.d.ts +23 -0
- package/dist/frontend/ts7/checker-backend.js +88 -0
- package/dist/frontend/ts7/checker-backend.js.map +1 -0
- package/dist/frontend/ts7/checker-backend.test.d.ts +1 -0
- package/dist/frontend/ts7/checker-backend.test.js +63 -0
- package/dist/frontend/ts7/checker-backend.test.js.map +1 -0
- package/dist/frontend/ts7/checker-cache.d.ts +0 -3
- package/dist/frontend/ts7/checker-cache.js +0 -6
- package/dist/frontend/ts7/checker-cache.js.map +1 -1
- package/dist/frontend/ts7/checker.d.ts +18 -11
- package/dist/frontend/ts7/checker.js +42 -55
- package/dist/frontend/ts7/checker.js.map +1 -1
- package/dist/frontend/ts7/checker.test.js +10 -7
- package/dist/frontend/ts7/checker.test.js.map +1 -1
- package/dist/frontend/ts7/diagnostic.d.ts +19 -0
- package/dist/frontend/ts7/diagnostic.js +22 -0
- package/dist/frontend/ts7/diagnostic.js.map +1 -0
- package/dist/frontend/ts7/node-functions.d.ts +8 -0
- package/dist/frontend/ts7/node-functions.js +18 -0
- package/dist/frontend/ts7/node-functions.js.map +1 -0
- package/dist/frontend/ts7/program-host.d.ts +5 -1
- package/dist/frontend/ts7/program-host.js +12 -0
- package/dist/frontend/ts7/program-host.js.map +1 -1
- package/dist/frontend/ts7/rpc-api.d.ts +5 -1
- package/dist/frontend/ts7/rpc-api.js +8 -1
- package/dist/frontend/ts7/rpc-api.js.map +1 -1
- package/dist/frontend/ts7/semantic-checker.d.ts +13 -6
- package/dist/frontend/ts7/semantic-checker.js +26 -8
- package/dist/frontend/ts7/semantic-checker.js.map +1 -1
- package/dist/frontend/ts7/semantic-checker.test.js +12 -9
- package/dist/frontend/ts7/semantic-checker.test.js.map +1 -1
- package/dist/frontend/ts7/semantic-model.d.ts +54 -24
- package/dist/frontend/ts7/semantic-model.js +88 -16
- package/dist/frontend/ts7/semantic-model.js.map +1 -1
- package/dist/frontend/ts7/semantic-model.test.js +4 -4
- package/dist/frontend/ts7/semantic-model.test.js.map +1 -1
- package/dist/frontend/ts7/semantic-types.d.ts +7 -3
- package/dist/frontend/ts7/semantic-types.js +1 -1
- package/dist/frontend/ts7/semantic-types.js.map +1 -1
- package/dist/frontend/ts7/session.d.ts +11 -11
- package/dist/frontend/ts7/session.js +8 -5
- package/dist/frontend/ts7/session.js.map +1 -1
- package/dist/frontend/ts7/session.test.js +9 -5
- package/dist/frontend/ts7/session.test.js.map +1 -1
- package/dist/frontend/ts7/source-parser.d.ts +6 -2
- package/dist/frontend/ts7/source-parser.js +24 -3
- package/dist/frontend/ts7/source-parser.js.map +1 -1
- package/dist/frontend/ts7/source-parser.test.js +38 -17
- package/dist/frontend/ts7/source-parser.test.js.map +1 -1
- package/dist/frontend/type-mapper.d.ts +122 -2
- package/dist/frontend/type-mapper.js +2545 -719
- package/dist/frontend/type-mapper.js.map +1 -1
- package/dist/frontend/type-only-imports.d.ts +28 -0
- package/dist/frontend/type-only-imports.js +122 -0
- package/dist/frontend/type-only-imports.js.map +1 -0
- package/dist/frontend/worker-target.js +8 -8
- package/dist/frontend/worker-target.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +29 -2
- package/dist/index.js.map +1 -1
- package/dist/ir/analysis.js +4 -2
- package/dist/ir/analysis.js.map +1 -1
- package/dist/ir/api.d.ts +1 -1
- package/dist/ir/api.js +1 -1
- package/dist/ir/api.js.map +1 -1
- package/dist/ir/array-length-stability.d.ts +30 -0
- package/dist/ir/array-length-stability.js +236 -0
- package/dist/ir/array-length-stability.js.map +1 -0
- package/dist/ir/array-length-stability.test.d.ts +1 -0
- package/dist/ir/array-length-stability.test.js +113 -0
- package/dist/ir/array-length-stability.test.js.map +1 -0
- package/dist/ir/build.d.ts +2 -2
- package/dist/ir/build.js +1 -1
- package/dist/ir/build.js.map +1 -1
- package/dist/ir/builtin-effects.js +103 -0
- package/dist/ir/builtin-effects.js.map +1 -1
- package/dist/ir/builtin-signatures.d.ts +1 -1
- package/dist/ir/builtin-signatures.js +494 -25
- package/dist/ir/builtin-signatures.js.map +1 -1
- package/dist/ir/byte-numbers.js +3 -0
- package/dist/ir/byte-numbers.js.map +1 -1
- package/dist/ir/callback-specialization.d.ts +37 -0
- package/dist/ir/callback-specialization.js +459 -0
- package/dist/ir/callback-specialization.js.map +1 -0
- package/dist/ir/callback-specialization.test.d.ts +1 -0
- package/dist/ir/callback-specialization.test.js +208 -0
- package/dist/ir/callback-specialization.test.js.map +1 -0
- package/dist/ir/capture-values.d.ts +0 -1
- package/dist/ir/capture-values.js +51 -40
- package/dist/ir/capture-values.js.map +1 -1
- package/dist/ir/constant-globals.test.js +1 -1
- package/dist/ir/constant-tables.test.js +1 -1
- package/dist/ir/field-values.test.js +1 -1
- package/dist/ir/final-fields.test.js +1 -1
- package/dist/ir/function-references.test.js +9 -1
- package/dist/ir/function-references.test.js.map +1 -1
- package/dist/ir/init-only-globals.test.js +1 -1
- package/dist/ir/initializer-bindings.test.js +1 -1
- package/dist/ir/int32-slots.d.ts +14 -0
- package/dist/ir/int32-slots.js +97 -14
- package/dist/ir/int32-slots.js.map +1 -1
- package/dist/ir/int32-slots.test.js +1 -1
- package/dist/ir/integer-loop-facts.d.ts +2 -0
- package/dist/ir/integer-loop-facts.js +24 -3
- package/dist/ir/integer-loop-facts.js.map +1 -1
- package/dist/ir/integer-loops.d.ts +1 -1
- package/dist/ir/integer-loops.js +39 -9
- package/dist/ir/integer-loops.js.map +1 -1
- package/dist/ir/integer-loops.test.js +104 -0
- package/dist/ir/integer-loops.test.js.map +1 -1
- package/dist/ir/integer-ranges.d.ts +3 -0
- package/dist/ir/integer-ranges.js +3 -1
- package/dist/ir/integer-ranges.js.map +1 -1
- package/dist/ir/integer-ranges.test.js +82 -1
- package/dist/ir/integer-ranges.test.js.map +1 -1
- package/dist/ir/intrinsic-signatures.js +6 -0
- package/dist/ir/intrinsic-signatures.js.map +1 -1
- package/dist/ir/ir.d.ts +221 -58
- package/dist/ir/ir.js +119 -12
- package/dist/ir/ir.js.map +1 -1
- package/dist/ir/ir.test.js +10 -0
- package/dist/ir/ir.test.js.map +1 -1
- package/dist/ir/jsval.d.ts +8 -0
- package/dist/ir/jsval.js +365 -0
- package/dist/ir/jsval.js.map +1 -0
- package/dist/ir/jsval.test.d.ts +1 -0
- package/dist/ir/jsval.test.js +239 -0
- package/dist/ir/jsval.test.js.map +1 -0
- package/dist/ir/runtime-features.d.ts +148 -33
- package/dist/ir/runtime-features.js +629 -386
- package/dist/ir/runtime-features.js.map +1 -1
- package/dist/ir/scalar-records.test.js +1 -1
- package/dist/ir/self-captures.d.ts +33 -0
- package/dist/ir/self-captures.js +245 -0
- package/dist/ir/self-captures.js.map +1 -0
- package/dist/ir/self-captures.test.d.ts +1 -0
- package/dist/ir/self-captures.test.js +135 -0
- package/dist/ir/self-captures.test.js.map +1 -0
- package/dist/ir/serialize.d.ts +1 -1
- package/dist/ir/serialize.js +7 -4
- package/dist/ir/serialize.js.map +1 -1
- package/dist/ir/tiers.d.ts +26 -0
- package/dist/ir/tiers.js +101 -0
- package/dist/ir/tiers.js.map +1 -0
- package/dist/ir/tiers.test.d.ts +1 -0
- package/dist/ir/tiers.test.js +140 -0
- package/dist/ir/tiers.test.js.map +1 -0
- package/dist/ir/traverse.js +103 -94
- package/dist/ir/traverse.js.map +1 -1
- package/dist/ir/traverse.test.js +33 -30
- package/dist/ir/traverse.test.js.map +1 -1
- package/dist/ir/unshare.js +65 -3
- package/dist/ir/unshare.js.map +1 -1
- package/dist/ir/unshare.test.js +1 -1
- package/dist/ir/validate.js +175 -68
- package/dist/ir/validate.js.map +1 -1
- package/dist/ir/validate.test.js +26 -9
- package/dist/ir/validate.test.js.map +1 -1
- package/dist/library/fence-eval.test.js +1 -1
- package/dist/library/int-infer.test.js +4 -4
- package/dist/library/ir-policy.js +13 -0
- package/dist/library/ir-policy.js.map +1 -1
- package/dist/library/library-cache.d.ts +1 -0
- package/dist/library/library-cache.js.map +1 -1
- package/dist/library/library-cache.test.js +5 -5
- package/dist/library/library-profile.d.ts +4 -4
- package/dist/library/library-profile.js +35 -7
- package/dist/library/library-profile.js.map +1 -1
- package/dist/library/prepare.js +13 -1
- package/dist/library/prepare.js.map +1 -1
- package/dist/native/cli.js +5 -0
- package/dist/native/cli.js.map +1 -1
- package/dist/native/compiler.js +2 -2
- package/dist/native/compiler.js.map +1 -1
- package/dist/native/compiler.test.js +2 -2
- package/dist/native/prepare.js +7 -0
- package/dist/native/prepare.js.map +1 -1
- package/dist/native/sanitizer.test.js +12 -0
- package/dist/native/sanitizer.test.js.map +1 -1
- package/dist/native/toolchain.d.ts +2 -0
- package/dist/native/toolchain.js +10 -1
- package/dist/native/toolchain.js.map +1 -1
- package/dist/native/toolchain.test.js +39 -1
- package/dist/native/toolchain.test.js.map +1 -1
- package/dist/startup-cache.d.ts +1 -0
- package/dist/startup-cache.js +1 -0
- package/dist/startup-cache.js.map +1 -1
- package/dist/wasm/base64.d.ts +5 -0
- package/dist/wasm/base64.js +62 -0
- package/dist/wasm/base64.js.map +1 -0
- package/dist/wasm/binary.d.ts +36 -0
- package/dist/wasm/binary.js +1976 -0
- package/dist/wasm/binary.js.map +1 -0
- package/dist/wasm/binary.test.d.ts +1 -0
- package/dist/wasm/binary.test.js +190 -0
- package/dist/wasm/binary.test.js.map +1 -0
- package/dist/wasm/discover.d.ts +38 -0
- package/dist/wasm/discover.js +377 -0
- package/dist/wasm/discover.js.map +1 -0
- package/dist/wasm/discover.test.d.ts +1 -0
- package/dist/wasm/discover.test.js +24 -0
- package/dist/wasm/discover.test.js.map +1 -0
- package/dist/wasm/module.d.ts +151 -0
- package/dist/wasm/module.js +575 -0
- package/dist/wasm/module.js.map +1 -0
- package/dist/wasm/translate.d.ts +48 -0
- package/dist/wasm/translate.js +2129 -0
- package/dist/wasm/translate.js.map +1 -0
- package/dist/wasm/translate.test.d.ts +1 -0
- package/dist/wasm/translate.test.js +207 -0
- package/dist/wasm/translate.test.js.map +1 -0
- package/package.json +21 -20
- package/surface-manifest.json +303 -19
|
@@ -1,6 +1,10 @@
|
|
|
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 { checkedClassUnionAssertion } from "./class-assertions.js";
|
|
4
8
|
import { collectClassMethodMutations } from "./class-method-mutations.js";
|
|
5
9
|
import { InternalCompilerError } from "../../errors.js";
|
|
6
10
|
/* Class lowering: shape collection over the single-inheritance graph
|
|
@@ -9,40 +13,47 @@ import { InternalCompilerError } from "../../errors.js";
|
|
|
9
13
|
* accessor access, upcasts, `new` expressions, and the builtin Error
|
|
10
14
|
* hierarchy registration. */
|
|
11
15
|
import { fsStreamClassOf, lowerFsStreamNew } from "./builtins/fs-streams.js";
|
|
16
|
+
import { codeGenerationCalleeOf, lowerCodeGenerationCall } from "./code-generation.js";
|
|
17
|
+
import { TEMPORAL_GLOBAL } from "../builtin-modules.js";
|
|
12
18
|
import * as ts from "../ts7/adapter.js";
|
|
13
|
-
import { lowerZlibStreamNew, zlibStreamModeOf } from "./builtins/compression.js";
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
19
|
+
import { lowerZlibStreamNew, zlibClassName, zlibStreamModeOf } from "./builtins/compression.js";
|
|
20
|
+
import { everyStmtList } from "../../ir/traverse.js";
|
|
21
|
+
import { builtinClassAliasOf, builtinClassRefOf, } from "./builtins/class-values.js";
|
|
22
|
+
import { inlineNamespaceRequireOf, lowerWithInlineRequireInit } from "./cjs-inline-require.js";
|
|
23
|
+
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";
|
|
24
|
+
import { genericCallInstance, implicitAnyParamSymbolsOf, implicitCallInstance, implicitMonoFile, genericLocalClassResult, } from "./generic-functions.js";
|
|
16
25
|
import { extendInstantiationPath, MAX_INSTANTIATION_RECURSION, } from "./instantiation-path.js";
|
|
17
26
|
import { appendImplicitUndefinedReturn, hasExplicitJsDocReturn } from "./function-returns.js";
|
|
18
27
|
import { bodyReadsArguments } from "../arguments-usage.js";
|
|
19
|
-
import {
|
|
28
|
+
import { errorNameAfterField, errorViewFields } from "./error-name-order.js";
|
|
29
|
+
import { checkedJsDocumentedParameter, documentedParameter, generatorMeta, } from "./call-signatures.js";
|
|
20
30
|
import { omittedArgFor } from "./call-arguments.js";
|
|
21
31
|
import { isGenericCallableMemberType, jsOpenObjectType, typeKey, withUnitArm, } from "../type-mapper.js";
|
|
22
|
-
import { cjsClassExprWholeExportOf, isCjsJsFile, isJsSourceFile, isModuleExportsAccess,
|
|
23
|
-
import { PoisonError, dynFallbackType, newFnCtx, own } from "./lowerer.js";
|
|
32
|
+
import { cjsClassExprWholeExportOf, isCjsJsFile, isJsSourceFile, isModuleExportsAccess, locOf, } from "../program.js";
|
|
33
|
+
import { PoisonError, dynFallbackType, jsFuncNameOf, newFnCtx, own } from "./lowerer.js";
|
|
24
34
|
import { isAssertClassNew } from "./assert-instances.js";
|
|
25
35
|
import { lowerArrayConstructor } from "./containers/array-construction.js";
|
|
26
36
|
import { lowerMapSeedNew, lowerSetSeedNew } from "./containers/collection-methods.js";
|
|
27
37
|
import { lowerObjectConstructor } from "./containers/indexed-objects.js";
|
|
28
|
-
import {
|
|
38
|
+
import { knownBufEncoding } from "./containers/bytes.js";
|
|
29
39
|
import { isSafeToRepeat } from "./expressions/evaluation-safety.js";
|
|
30
40
|
import { lowerSearchParamsNew } from "./builtins/url.js";
|
|
31
41
|
import { lowerTextCodecNew } from "./builtins/text-codecs.js";
|
|
32
|
-
import { lowerMessageChannelNew, lowerWorkerNew } from "./builtins/workers.js";
|
|
42
|
+
import { lowerBroadcastChannelNew, lowerMessageChannelNew, lowerWorkerNew, } from "./builtins/workers.js";
|
|
33
43
|
import { unsupportedPackageValueDiag, unsupportedDiag, } from "../../diagnostics/diagnostic.js";
|
|
34
|
-
import { STREAM_API_MEMBERS, STREAM_PROP_MEMBERS, UNDERSCORE_METHODS, lowerStreamNew, lowerStreamSuperCall, streamCtorShape, } from "./lower-stream.js";
|
|
44
|
+
import { STREAM_API_MEMBERS, STREAM_PROP_MEMBERS, STREAM_COMPLETION_CALLBACK_INDEX, UNDERSCORE_METHODS, lowerStreamNew, lowerStreamSuperCall, streamCtorShape, } from "./lower-stream.js";
|
|
35
45
|
import { builtinEventTargetBaseOf, eventTargetApiMembers, eventTargetApiMethod, eventTargetRootOf, eventTargetSuperCall, lowerEventTargetMethodCall, } from "./lower-event-target.js";
|
|
36
46
|
import { emitOverrideShapeReason, emitSpecSuperForward, emitterRooted, lowerEmitterSuperCall, } from "./lower-event-emitter.js";
|
|
37
47
|
import { declSymbolOf } from "./lower-modules.js";
|
|
38
48
|
import { classSymbolKeyOf, classSymbolKeyOfSymbol, symbolFieldDisplayName, } from "./symbol-fields.js";
|
|
39
49
|
import { lowerHttpAgentNew, lowerHttpServerNew } from "./lower-server.js";
|
|
40
|
-
import { ambientNsRootOf, ambientUndefReadType, ambientUndefVarRootOf, ambientUndefinedFnSymbolOf, fenceEarlyAliasUse, fenceEarlyNsMemberRef, nsMemberIdentOf, nsUndefRead, } from "./lower-namespaces.js";
|
|
50
|
+
import { ambientNsRootOf, ambientUndefReadType, ambientUndefVarRootOf, ambientUndefinedFnSymbolOf, contextualUndefReadType, fenceEarlyAliasUse, fenceEarlyNsMemberRef, nsMemberIdentOf, nsUndefRead, } from "./lower-namespaces.js";
|
|
41
51
|
import { mixinResultBindingClassOf } from "./lower-mixins.js";
|
|
42
52
|
import { hasLexicalPrivateReference, hasStaticThis, rejectStaticThis } from "./static-this.js";
|
|
43
53
|
import { lowerUrlNew } from "./lower-url.js";
|
|
44
54
|
import { isNativeProxyInitializer, lowerNativeProxy } from "./expressions/native-proxy.js";
|
|
45
55
|
import { classStaticDataFor } from "./class-static-data.js";
|
|
56
|
+
import { construction, constructionPrefix } from "./js-class-fields.js";
|
|
46
57
|
import { lowerObjectFactoryNew } from "./object-factory-new.js";
|
|
47
58
|
import { tryLowerExpression } from "./expressions/try-lower-expression.js";
|
|
48
59
|
import { lowerInstanceConstructorNew } from "./class-instance-constructor.js";
|
|
@@ -53,7 +64,7 @@ import { initializeRuntimeStatics, hasRuntimeStatics } from "./class-runtime-sta
|
|
|
53
64
|
import { reflectedClassStaticMethodValue } from "./class-method-values.js";
|
|
54
65
|
export function returnsOnlyThis(member) {
|
|
55
66
|
const body = member.body;
|
|
56
|
-
const last = body?.statements.at(-1);
|
|
67
|
+
const last = body?.statements?.nodes.at(-1);
|
|
57
68
|
if (!body || !last || !ts.isReturnStatement(last))
|
|
58
69
|
return false;
|
|
59
70
|
let valid = true;
|
|
@@ -67,9 +78,43 @@ export function returnsOnlyThis(member) {
|
|
|
67
78
|
if (!value || value.kind !== ts.SyntaxKind.ThisKeyword)
|
|
68
79
|
valid = false;
|
|
69
80
|
}
|
|
70
|
-
|
|
81
|
+
ts.forEachChild(node, visit);
|
|
71
82
|
};
|
|
72
|
-
|
|
83
|
+
ts.forEachChild(body, visit);
|
|
84
|
+
return valid;
|
|
85
|
+
}
|
|
86
|
+
/** returnsOnlyThis, also accepting a comma expression whose last operand
|
|
87
|
+
* is `this` (the minifier's `return a(), this.x = v, this`, jose's fluent
|
|
88
|
+
* claim setters). Used only to narrow a call's result back to the
|
|
89
|
+
* receiver's class. */
|
|
90
|
+
export function returnsOnlyThisValue(member) {
|
|
91
|
+
const body = member.body;
|
|
92
|
+
const last = body?.statements?.nodes.at(-1);
|
|
93
|
+
if (!body || !last || !ts.isReturnStatement(last))
|
|
94
|
+
return false;
|
|
95
|
+
let valid = true;
|
|
96
|
+
const visit = (node) => {
|
|
97
|
+
if (ts.isFunctionLike(node))
|
|
98
|
+
return;
|
|
99
|
+
if (ts.isReturnStatement(node)) {
|
|
100
|
+
let value = node.expression;
|
|
101
|
+
for (;;) {
|
|
102
|
+
while (value && ts.isParenthesizedExpression(value))
|
|
103
|
+
value = value.expression;
|
|
104
|
+
if (value &&
|
|
105
|
+
ts.isBinaryExpression(value) &&
|
|
106
|
+
value.operatorToken.kind === ts.SyntaxKind.CommaToken) {
|
|
107
|
+
value = value.right;
|
|
108
|
+
continue;
|
|
109
|
+
}
|
|
110
|
+
break;
|
|
111
|
+
}
|
|
112
|
+
if (!value || value.kind !== ts.SyntaxKind.ThisKeyword)
|
|
113
|
+
valid = false;
|
|
114
|
+
}
|
|
115
|
+
ts.forEachChild(node, visit);
|
|
116
|
+
};
|
|
117
|
+
ts.forEachChild(body, visit);
|
|
73
118
|
return valid;
|
|
74
119
|
}
|
|
75
120
|
function functionLocalClass(decl) {
|
|
@@ -107,9 +152,7 @@ export function storedClassValueType(lowerer, expression, visiting = new Set())
|
|
|
107
152
|
return stored.type;
|
|
108
153
|
const symbol = lowerer.resolveValueSymbol(expression);
|
|
109
154
|
const declaration = symbol &&
|
|
110
|
-
|
|
111
|
-
.declarationsOf(symbol)
|
|
112
|
-
.find((decl) => ts.isVariableDeclaration(decl) &&
|
|
155
|
+
symbol.declarations.find((decl) => ts.isVariableDeclaration(decl) &&
|
|
113
156
|
decl.initializer &&
|
|
114
157
|
(ts.getCombinedNodeFlags(decl) & ts.NodeFlags.Const) !== 0);
|
|
115
158
|
if (declaration && ts.isVariableDeclaration(declaration) && declaration.initializer) {
|
|
@@ -118,11 +161,17 @@ export function storedClassValueType(lowerer, expression, visiting = new Set())
|
|
|
118
161
|
return value;
|
|
119
162
|
}
|
|
120
163
|
}
|
|
164
|
+
// A generic factory's own local class has one class per instance.
|
|
165
|
+
if (ts.isCallExpression(expression)) {
|
|
166
|
+
const local = genericLocalClassResult(lowerer, expression);
|
|
167
|
+
if (local?.kind === "classval")
|
|
168
|
+
return local;
|
|
169
|
+
}
|
|
121
170
|
const type = lowerer.typeOf(expression);
|
|
122
171
|
const mapped = lowerer.mapTypeOf(type);
|
|
123
172
|
if (mapped?.kind === "classval" && !lowerer.classes.has(mapped.className)) {
|
|
124
173
|
for (const signature of lowerer.checker.getConstructSignatures(type)) {
|
|
125
|
-
const constructor =
|
|
174
|
+
const constructor = signature.declaration;
|
|
126
175
|
const declaration = constructor && ts.isConstructorDeclaration(constructor) ? constructor.parent : undefined;
|
|
127
176
|
if (declaration &&
|
|
128
177
|
ts.isClassExpression(declaration) &&
|
|
@@ -161,9 +210,7 @@ export function storedClassValueType(lowerer, expression, visiting = new Set())
|
|
|
161
210
|
if (ts.isIdentifier(callee)) {
|
|
162
211
|
const symbol = lowerer.resolveValueSymbol(callee);
|
|
163
212
|
const declaration = symbol &&
|
|
164
|
-
|
|
165
|
-
.declarationsOf(symbol)
|
|
166
|
-
.find((decl) => ts.isVariableDeclaration(decl) &&
|
|
213
|
+
symbol.declarations.find((decl) => ts.isVariableDeclaration(decl) &&
|
|
167
214
|
decl.initializer &&
|
|
168
215
|
(ts.getCombinedNodeFlags(decl) & ts.NodeFlags.Const) !== 0);
|
|
169
216
|
if (declaration && ts.isVariableDeclaration(declaration) && declaration.initializer) {
|
|
@@ -174,8 +221,8 @@ export function storedClassValueType(lowerer, expression, visiting = new Set())
|
|
|
174
221
|
break;
|
|
175
222
|
}
|
|
176
223
|
if ((ts.isArrowFunction(callee) || ts.isFunctionExpression(callee)) &&
|
|
177
|
-
isJsSourceFile(
|
|
178
|
-
!callee.typeParameters?.length &&
|
|
224
|
+
isJsSourceFile(ts.getSourceFileOfNode(callee)) &&
|
|
225
|
+
!callee.typeParameters?.nodes.length &&
|
|
179
226
|
!lowerer.preparingClassFactories.has(callee)) {
|
|
180
227
|
const signature = lowerer.checker.getSignatureFromDeclaration(callee);
|
|
181
228
|
let result = signature && lowerer.checker.getReturnTypeOfSignature(signature);
|
|
@@ -227,7 +274,7 @@ export function storedClassValueType(lowerer, expression, visiting = new Set())
|
|
|
227
274
|
// Cache the module-level closure so its captures and lifted bodies are
|
|
228
275
|
// exactly the ones used when the declaration executes.
|
|
229
276
|
for (const signature of lowerer.checker.getConstructSignatures(type)) {
|
|
230
|
-
const declaration =
|
|
277
|
+
const declaration = signature.declaration;
|
|
231
278
|
const cls = declaration && ts.isConstructorDeclaration(declaration) ? declaration.parent : null;
|
|
232
279
|
if (!cls || (!ts.isClassExpression(cls) && !ts.isClassDeclaration(cls)))
|
|
233
280
|
continue;
|
|
@@ -241,8 +288,8 @@ export function storedClassValueType(lowerer, expression, visiting = new Set())
|
|
|
241
288
|
}
|
|
242
289
|
}
|
|
243
290
|
if (!factory ||
|
|
244
|
-
!isJsSourceFile(
|
|
245
|
-
factory.typeParameters?.length ||
|
|
291
|
+
!isJsSourceFile(ts.getSourceFileOfNode(factory)) ||
|
|
292
|
+
factory.typeParameters?.nodes.length ||
|
|
246
293
|
!ts.isVariableDeclaration(factory.parent) ||
|
|
247
294
|
factory.parent.initializer !== factory ||
|
|
248
295
|
!ts.isVariableDeclarationList(factory.parent.parent) ||
|
|
@@ -277,7 +324,7 @@ export function storedClassValueType(lowerer, expression, visiting = new Set())
|
|
|
277
324
|
* or the ElementAccessExpression itself). Null when no declaration has
|
|
278
325
|
* that shape (well-known-symbol members like `[Symbol.iterator]`). */
|
|
279
326
|
function lateBoundKeySymOf(lowerer, p) {
|
|
280
|
-
for (const d of
|
|
327
|
+
for (const d of p.declarations) {
|
|
281
328
|
const access = ts.isBinaryExpression(d) && ts.isElementAccessExpression(d.left)
|
|
282
329
|
? d.left
|
|
283
330
|
: ts.isElementAccessExpression(d)
|
|
@@ -311,13 +358,13 @@ function symbolSlotReturnType(lowerer, fnLike, symbolFields, fields) {
|
|
|
311
358
|
return null;
|
|
312
359
|
if (fnLike.type !== undefined || !fnLike.body)
|
|
313
360
|
return null;
|
|
314
|
-
if (!isJsSourceFile(
|
|
361
|
+
if (!isJsSourceFile(ts.getSourceFileOfNode(fnLike)))
|
|
315
362
|
return null;
|
|
316
363
|
if (fnLike.asteriskToken !== undefined)
|
|
317
364
|
return null;
|
|
318
|
-
if (fnLike.modifiers?.some((m) => m.kind === ts.SyntaxKind.AsyncKeyword))
|
|
365
|
+
if (fnLike.modifiers?.nodes.some((m) => m.kind === ts.SyntaxKind.AsyncKeyword))
|
|
319
366
|
return null;
|
|
320
|
-
const stmts = fnLike.body.statements;
|
|
367
|
+
const stmts = fnLike.body.statements.nodes;
|
|
321
368
|
const last = stmts[stmts.length - 1];
|
|
322
369
|
if (!last || !ts.isReturnStatement(last))
|
|
323
370
|
return null;
|
|
@@ -327,9 +374,9 @@ function symbolSlotReturnType(lowerer, fnLike, symbolFields, fields) {
|
|
|
327
374
|
return;
|
|
328
375
|
if (ts.isReturnStatement(n))
|
|
329
376
|
returns.push(n);
|
|
330
|
-
|
|
377
|
+
ts.forEachChild(n, visit);
|
|
331
378
|
};
|
|
332
|
-
fnLike.body
|
|
379
|
+
ts.forEachChild(fnLike.body, visit);
|
|
333
380
|
let out = null;
|
|
334
381
|
for (const r of returns) {
|
|
335
382
|
let e = r.expression;
|
|
@@ -350,6 +397,16 @@ function symbolSlotReturnType(lowerer, fnLike, symbolFields, fields) {
|
|
|
350
397
|
}
|
|
351
398
|
return out;
|
|
352
399
|
}
|
|
400
|
+
/** The error classes whose values construct through error.newOptions. */
|
|
401
|
+
const ERROR_CLASS_VALUES = new Set([
|
|
402
|
+
"%Error",
|
|
403
|
+
"%TypeError",
|
|
404
|
+
"%RangeError",
|
|
405
|
+
"%SyntaxError",
|
|
406
|
+
"%ReferenceError",
|
|
407
|
+
"%EvalError",
|
|
408
|
+
"%URIError",
|
|
409
|
+
]);
|
|
353
410
|
/** The builtin Error hierarchy
|
|
354
411
|
* as eagerly-registered ClassInfos: mapType names them the moment a lib
|
|
355
412
|
* Error type appears, so the infos must exist before any lowering. They
|
|
@@ -418,6 +475,17 @@ export function registerBuiltinErrorClasses(lowerer) {
|
|
|
418
475
|
{ type: DYN, mode: "omittable" },
|
|
419
476
|
{ type: DYN, mode: "omittable" },
|
|
420
477
|
],
|
|
478
|
+
// The ECMAScript error constructors take (message?, options?);
|
|
479
|
+
// DOMException, AggregateError, AssertionError and SuppressedError
|
|
480
|
+
// have their own construction and are not values.
|
|
481
|
+
...(ERROR_CLASS_VALUES.has(irName)
|
|
482
|
+
? {
|
|
483
|
+
valueCtorParams: [
|
|
484
|
+
{ type: DYN, mode: "omittable" },
|
|
485
|
+
{ type: DYN, mode: "omittable" },
|
|
486
|
+
],
|
|
487
|
+
}
|
|
488
|
+
: {}),
|
|
421
489
|
base,
|
|
422
490
|
subclasses: [],
|
|
423
491
|
throwingSetters: [],
|
|
@@ -450,6 +518,7 @@ export function registerBuiltinEmitterClass(lowerer) {
|
|
|
450
518
|
// `new EventEmitter()` — zero-argument (the options bag fences at
|
|
451
519
|
// construction sites; the checker may admit it via @types/node).
|
|
452
520
|
ctorParams: [],
|
|
521
|
+
valueCtorParams: [],
|
|
453
522
|
base: null,
|
|
454
523
|
subclasses: [],
|
|
455
524
|
throwingSetters: [],
|
|
@@ -480,6 +549,9 @@ export function registerBuiltinStreamClasses(lowerer) {
|
|
|
480
549
|
// `new Readable(opts?)` — the options bag is parsed structurally
|
|
481
550
|
// by the stream spoke (lowerNew never completes against this).
|
|
482
551
|
ctorParams: [],
|
|
552
|
+
// Construction through a class value builds the stream without
|
|
553
|
+
// options (lowerNew reports options passed through a value).
|
|
554
|
+
valueCtorParams: [],
|
|
483
555
|
base,
|
|
484
556
|
subclasses: [],
|
|
485
557
|
throwingSetters: [],
|
|
@@ -496,10 +568,14 @@ export function registerBuiltinStreamClasses(lowerer) {
|
|
|
496
568
|
* "stream" ambient module, EXCLUDING @types/node's (whose stream.Readable
|
|
497
569
|
* also types child stdio — under @types/node the childStream mapping
|
|
498
570
|
* keeps priority and the static stream classes stand down; the shipped
|
|
499
|
-
* fallback declarations are the supported surface).
|
|
571
|
+
* fallback declarations are the supported surface). A const binding of
|
|
572
|
+
* one (`const R = Readable`) names the same class (builtinClassAliasOf). */
|
|
500
573
|
export function builtinStreamInfoOf(lowerer, symbol) {
|
|
501
574
|
if (!symbol)
|
|
502
575
|
return null;
|
|
576
|
+
const alias = builtinClassAliasOf(lowerer, symbol);
|
|
577
|
+
if (alias !== null)
|
|
578
|
+
return alias.kind === "stream" ? alias.info : null;
|
|
503
579
|
if (!lowerer.isStdlibSymbol(symbol)) {
|
|
504
580
|
// A const ALIAS of a namespace member (`const Writable =
|
|
505
581
|
// stream.Writable` — the two-step spelling; the one-step
|
|
@@ -507,7 +583,7 @@ export function builtinStreamInfoOf(lowerer, symbol) {
|
|
|
507
583
|
// member to the stdlib class symbol. The declaration itself is
|
|
508
584
|
// alias plumbing (streamClassAliasDecl — both declaration walks
|
|
509
585
|
// skip it).
|
|
510
|
-
const decl =
|
|
586
|
+
const decl = symbol.valueDeclaration;
|
|
511
587
|
if (decl &&
|
|
512
588
|
ts.isVariableDeclaration(decl) &&
|
|
513
589
|
(ts.getCombinedNodeFlags(decl) & ts.NodeFlags.Const) !== 0 &&
|
|
@@ -524,16 +600,17 @@ export function builtinStreamInfoOf(lowerer, symbol) {
|
|
|
524
600
|
}
|
|
525
601
|
let irName = null;
|
|
526
602
|
for (const [name, rec] of RUNTIME_STREAM_CLASSES) {
|
|
527
|
-
if (rec.lib === symbol
|
|
603
|
+
if (rec.lib === ts.symbolName(symbol))
|
|
528
604
|
irName = name;
|
|
529
605
|
}
|
|
530
606
|
if (!irName)
|
|
531
607
|
return null;
|
|
532
|
-
|
|
608
|
+
// Both the bundled declarations and @types/node declare the classes
|
|
609
|
+
// inside `declare module "stream"` (@types/node nests them in the module's
|
|
610
|
+
// `internal` namespace).
|
|
611
|
+
const declared = symbol.declarations.some((d) => {
|
|
533
612
|
if (!ts.isClassDeclaration(d))
|
|
534
613
|
return false;
|
|
535
|
-
if (isNodeTypesPath(d.getSourceFile().fileName))
|
|
536
|
-
return false;
|
|
537
614
|
let node = d.parent;
|
|
538
615
|
while (node) {
|
|
539
616
|
if (ts.isModuleDeclaration(node) && ts.isStringLiteral(node.name)) {
|
|
@@ -551,10 +628,9 @@ function jsFieldInitializerType(lowerer, type, expression) {
|
|
|
551
628
|
if (ts.isIdentifier(expression)) {
|
|
552
629
|
const symbol = lowerer.checker.getSymbolAtLocation(expression);
|
|
553
630
|
if (symbol &&
|
|
554
|
-
|
|
555
|
-
.
|
|
556
|
-
|
|
557
|
-
(ts.isConstructorDeclaration(decl.parent) ||
|
|
631
|
+
symbol.declarations.some((decl) => ts.isParameter(decl) &&
|
|
632
|
+
((ts.isConstructorDeclaration(decl.parent) &&
|
|
633
|
+
!checkedJsDocumentedParameter(lowerer, decl)) ||
|
|
558
634
|
(lowerer.typeOf(expression).flags & (ts.TypeFlags.Any | ts.TypeFlags.Unknown)) !== 0)))
|
|
559
635
|
return DYN;
|
|
560
636
|
}
|
|
@@ -563,7 +639,7 @@ function jsFieldInitializerType(lowerer, type, expression) {
|
|
|
563
639
|
// JavaScript documentation cannot guarantee that a call or an indexed
|
|
564
640
|
// read returns a present number. Numeric fields receiving those values
|
|
565
641
|
// must retain undefined, so later arithmetic performs JS coercion (NaN).
|
|
566
|
-
if (type.kind === "f64" && isJsSourceFile(
|
|
642
|
+
if (type.kind === "f64" && isJsSourceFile(ts.getSourceFileOfNode(expression))) {
|
|
567
643
|
const assignment = expression.parent;
|
|
568
644
|
const left = ts.isBinaryExpression(assignment) ? assignment.left : null;
|
|
569
645
|
const field = left &&
|
|
@@ -591,7 +667,7 @@ function jsFieldInitializerType(lowerer, type, expression) {
|
|
|
591
667
|
if (ts.isCallExpression(rhs) || ts.isElementAccessExpression(rhs))
|
|
592
668
|
acceptsUnchecked = true;
|
|
593
669
|
}
|
|
594
|
-
|
|
670
|
+
ts.forEachChild(node, scan);
|
|
595
671
|
};
|
|
596
672
|
scan(owner);
|
|
597
673
|
if (acceptsUnchecked)
|
|
@@ -603,14 +679,14 @@ function jsFieldInitializerType(lowerer, type, expression) {
|
|
|
603
679
|
node = node.expression;
|
|
604
680
|
if (ts.isCallExpression(node) && type.kind === "bytes") {
|
|
605
681
|
let prototypeArgument = false;
|
|
606
|
-
for (const argument of node.arguments)
|
|
682
|
+
for (const argument of node.arguments.nodes)
|
|
607
683
|
ts.walkPreorder(argument, (part) => {
|
|
608
684
|
if (!ts.isPropertyAccessExpression(part) ||
|
|
609
685
|
part.expression.kind !== ts.SyntaxKind.ThisKeyword)
|
|
610
686
|
return;
|
|
611
687
|
const symbol = lowerer.checker.getSymbolAtLocation(part.name);
|
|
612
688
|
if (symbol &&
|
|
613
|
-
|
|
689
|
+
symbol.declarations.some((decl) => {
|
|
614
690
|
const member = ts.isBinaryExpression(decl) ? decl.left : decl;
|
|
615
691
|
return (ts.isPropertyAccessExpression(member) &&
|
|
616
692
|
ts.isPropertyAccessExpression(member.expression) &&
|
|
@@ -624,7 +700,7 @@ function jsFieldInitializerType(lowerer, type, expression) {
|
|
|
624
700
|
owner = owner.parent;
|
|
625
701
|
if (owner && (ts.isClassDeclaration(owner) || ts.isClassExpression(owner)) && owner.name) {
|
|
626
702
|
const className = owner.name.text;
|
|
627
|
-
for (const statement of
|
|
703
|
+
for (const statement of ts.getSourceFileOfNode(owner).statements.nodes) {
|
|
628
704
|
if (!ts.isExpressionStatement(statement) ||
|
|
629
705
|
!ts.isBinaryExpression(statement.expression))
|
|
630
706
|
continue;
|
|
@@ -702,7 +778,7 @@ function inheritedJsFieldType(lowerer, decl, name, type) {
|
|
|
702
778
|
return type;
|
|
703
779
|
}
|
|
704
780
|
function returnsWidenedJsField(lowerer, decl, member, fields, ret) {
|
|
705
|
-
if (!isJsSourceFile(
|
|
781
|
+
if (!isJsSourceFile(ts.getSourceFileOfNode(member)) ||
|
|
706
782
|
member.type ||
|
|
707
783
|
member.asteriskToken ||
|
|
708
784
|
hasExplicitJsDocReturn(member))
|
|
@@ -720,10 +796,7 @@ function returnsWidenedJsField(lowerer, decl, member, fields, ret) {
|
|
|
720
796
|
? lowerer.checker.getPropertyOfType(lowerer.typeOf(callee.expression), lowerer.foldedStringKeyOf(callee.argumentExpression) ?? "")
|
|
721
797
|
: undefined;
|
|
722
798
|
if (symbol &&
|
|
723
|
-
lowerer.
|
|
724
|
-
.declarationsOf(symbol)
|
|
725
|
-
.some((declaration) => ts.isMethodDeclaration(declaration) &&
|
|
726
|
-
lowerer.checkedVirtualJsMethods.has(declaration)))
|
|
799
|
+
symbol.declarations.some((declaration) => ts.isMethodDeclaration(declaration) && lowerer.checkedVirtualJsMethods.has(declaration)))
|
|
727
800
|
return true;
|
|
728
801
|
}
|
|
729
802
|
const name = ts.isPropertyAccessExpression(expression)
|
|
@@ -734,9 +807,7 @@ function returnsWidenedJsField(lowerer, decl, member, fields, ret) {
|
|
|
734
807
|
if (ts.isPropertyAccessExpression(expression)) {
|
|
735
808
|
const symbol = lowerer.checker.getSymbolAtLocation(expression.name);
|
|
736
809
|
if (symbol &&
|
|
737
|
-
|
|
738
|
-
.declarationsOf(symbol)
|
|
739
|
-
.some((declaration) => (ts.isGetAccessorDeclaration(declaration) ||
|
|
810
|
+
symbol.declarations.some((declaration) => (ts.isGetAccessorDeclaration(declaration) ||
|
|
740
811
|
ts.isSetAccessorDeclaration(declaration)) &&
|
|
741
812
|
lowerer.checkedVirtualJsAccessors.has(declaration)))
|
|
742
813
|
return true;
|
|
@@ -755,7 +826,7 @@ function returnsWidenedJsField(lowerer, decl, member, fields, ret) {
|
|
|
755
826
|
return;
|
|
756
827
|
if (ts.isReturnStatement(node) && node.expression && widened(node.expression))
|
|
757
828
|
result = true;
|
|
758
|
-
|
|
829
|
+
ts.forEachChild(node, scan);
|
|
759
830
|
};
|
|
760
831
|
if (member.body)
|
|
761
832
|
scan(member.body);
|
|
@@ -768,13 +839,13 @@ function returnsWidenedJsField(lowerer, decl, member, fields, ret) {
|
|
|
768
839
|
* (genResultRecord's list, including scalar-backed Date values). */
|
|
769
840
|
function undefArmedFieldType(lowerer, p) {
|
|
770
841
|
const t = lowerer.checker.getTypeOfSymbol(p);
|
|
771
|
-
const site =
|
|
842
|
+
const site = p.declarations[0];
|
|
772
843
|
let mapped = lowerer.mapTypeOf(t) ?? (site ? dynFallbackType(lowerer, site, t) : null);
|
|
773
844
|
if (mapped && site)
|
|
774
845
|
mapped = jsOpenObjectType(site, mapped, lowerer.shapes, lowerer.unions);
|
|
775
846
|
if (!mapped || mapped.kind === "void")
|
|
776
847
|
return null;
|
|
777
|
-
for (const declaration of
|
|
848
|
+
for (const declaration of p.declarations) {
|
|
778
849
|
const assignment = ts.isBinaryExpression(declaration) ? declaration : declaration.parent;
|
|
779
850
|
if (assignment &&
|
|
780
851
|
ts.isBinaryExpression(assignment) &&
|
|
@@ -801,10 +872,15 @@ function undefArmedFieldType(lowerer, p) {
|
|
|
801
872
|
* `extends EventEmitter`, `x instanceof EventEmitter`) — any import
|
|
802
873
|
* spelling (named/default/namespace member, CJS require) resolves to
|
|
803
874
|
* the ambient class. Provenance-checked like the error classes: only a
|
|
804
|
-
* stdlib-file declaration inside the "events" ambient module counts.
|
|
875
|
+
* stdlib-file declaration inside the "events" ambient module counts. A
|
|
876
|
+
* const binding of it (`const E = EventEmitter`) names the same class
|
|
877
|
+
* (builtinClassAliasOf). */
|
|
805
878
|
export function builtinEmitterInfoOf(lowerer, symbol) {
|
|
806
879
|
if (!symbol)
|
|
807
880
|
return null;
|
|
881
|
+
const alias = builtinClassAliasOf(lowerer, symbol);
|
|
882
|
+
if (alias !== null)
|
|
883
|
+
return alias.kind === "emitter" ? alias.info : null;
|
|
808
884
|
if (!lowerer.isStdlibSymbol(symbol)) {
|
|
809
885
|
// A const ALIAS of the emitter class member (`const EventEmitter =
|
|
810
886
|
// require('node:events').EventEmitter` — commander's spelling; the
|
|
@@ -812,7 +888,7 @@ export function builtinEmitterInfoOf(lowerer, symbol) {
|
|
|
812
888
|
// follow the member off the module namespace. The declaration
|
|
813
889
|
// itself is alias plumbing (builtinMemberRequireDecl — both
|
|
814
890
|
// declaration walks skip it).
|
|
815
|
-
const decl =
|
|
891
|
+
const decl = symbol.valueDeclaration;
|
|
816
892
|
if (decl !== undefined &&
|
|
817
893
|
ts.isVariableDeclaration(decl) &&
|
|
818
894
|
(ts.getCombinedNodeFlags(decl) & ts.NodeFlags.Const) !== 0 &&
|
|
@@ -825,9 +901,9 @@ export function builtinEmitterInfoOf(lowerer, symbol) {
|
|
|
825
901
|
}
|
|
826
902
|
return null;
|
|
827
903
|
}
|
|
828
|
-
if (symbol
|
|
904
|
+
if (ts.symbolName(symbol) !== "EventEmitter")
|
|
829
905
|
return null;
|
|
830
|
-
const declared =
|
|
906
|
+
const declared = symbol.declarations.some((d) => {
|
|
831
907
|
if (!ts.isClassDeclaration(d) && !ts.isInterfaceDeclaration(d))
|
|
832
908
|
return false;
|
|
833
909
|
let node = d.parent;
|
|
@@ -844,12 +920,19 @@ export function builtinEmitterInfoOf(lowerer, symbol) {
|
|
|
844
920
|
/** The builtin error ClassInfo a VALUE symbol refers to (`new Error`,
|
|
845
921
|
* `extends TypeError`, `x instanceof RangeError`), or null. Provenance-
|
|
846
922
|
* checked: only the standard library's declarations count — a user's own
|
|
847
|
-
* `class Error` resolves through classBySymbol instead.
|
|
923
|
+
* `class Error` resolves through classBySymbol instead. A const binding
|
|
924
|
+
* of one (`const E = TypeError`) names the same class
|
|
925
|
+
* (builtinClassAliasOf). */
|
|
848
926
|
export function builtinErrorInfoOf(lowerer, symbol) {
|
|
849
|
-
if (!symbol
|
|
927
|
+
if (!symbol)
|
|
928
|
+
return null;
|
|
929
|
+
const alias = builtinClassAliasOf(lowerer, symbol);
|
|
930
|
+
if (alias !== null)
|
|
931
|
+
return alias.kind === "error" ? alias.info : null;
|
|
932
|
+
if (!lowerer.isStdlibSymbol(symbol))
|
|
850
933
|
return null;
|
|
851
934
|
for (const [irName, rec] of RUNTIME_ERROR_CLASSES) {
|
|
852
|
-
if (rec.lib === symbol
|
|
935
|
+
if (rec.lib === ts.symbolName(symbol))
|
|
853
936
|
return lowerer.classes.get(irName) ?? null;
|
|
854
937
|
}
|
|
855
938
|
return null;
|
|
@@ -877,7 +960,7 @@ export const EMITTER_API_MEMBERS = new Set([
|
|
|
877
960
|
/** The decorators of a class-like or member node (they live in
|
|
878
961
|
* `modifiers` since TS 4.8). */
|
|
879
962
|
export function decoratorNodesOf(n) {
|
|
880
|
-
return (n.modifiers ?? []).filter((m) => m.kind === ts.SyntaxKind.Decorator);
|
|
963
|
+
return (n.modifiers?.nodes ?? []).filter((m) => m.kind === ts.SyntaxKind.Decorator);
|
|
881
964
|
}
|
|
882
965
|
/** The AMBIENT name a decorator expression's evaluation throws on, or
|
|
883
966
|
* null. Node erases ambient declarations (`declare let dec: any`,
|
|
@@ -936,14 +1019,14 @@ export function guaranteedDecorationThrow(lowerer, decl) {
|
|
|
936
1019
|
if (v !== "effectFree")
|
|
937
1020
|
return v;
|
|
938
1021
|
}
|
|
939
|
-
const heritage = decl.heritageClauses?.find((c) => c.token === ts.SyntaxKind.ExtendsKeyword)
|
|
940
|
-
?.types[0];
|
|
1022
|
+
const heritage = decl.heritageClauses?.nodes.find((c) => c.token === ts.SyntaxKind.ExtendsKeyword)
|
|
1023
|
+
?.types?.nodes[0];
|
|
941
1024
|
if (heritage) {
|
|
942
1025
|
const h = stripParens(heritage.expression);
|
|
943
1026
|
if (h.kind !== ts.SyntaxKind.NullKeyword && !ts.isIdentifier(h))
|
|
944
1027
|
return null;
|
|
945
1028
|
}
|
|
946
|
-
for (const member of decl.members) {
|
|
1029
|
+
for (const member of decl.members.nodes) {
|
|
947
1030
|
for (const d of decoratorNodesOf(member)) {
|
|
948
1031
|
const v = decoratorVerdict(d);
|
|
949
1032
|
if (v === "opaque")
|
|
@@ -978,17 +1061,17 @@ function collectClassShapeDeferring(lowerer, decl) {
|
|
|
978
1061
|
// A forward type reference can demand this class before collection
|
|
979
1062
|
// reaches its earlier base declaration. Collect that dependency first;
|
|
980
1063
|
// 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;
|
|
1064
|
+
const heritage = decl.heritageClauses?.nodes.find((clause) => clause.token === ts.SyntaxKind.ExtendsKeyword)?.types?.nodes[0]?.expression;
|
|
982
1065
|
const reference = heritage && ts.isPropertyAccessExpression(heritage) ? heritage.name : heritage;
|
|
983
1066
|
const baseSymbol = reference && ts.isIdentifier(reference) ? lowerer.resolveValueSymbol(reference) : undefined;
|
|
984
1067
|
const baseDeclaration = baseSymbol
|
|
985
|
-
?
|
|
1068
|
+
? baseSymbol.declarations.find(ts.isClassDeclaration)
|
|
986
1069
|
: undefined;
|
|
987
1070
|
if (baseDeclaration &&
|
|
988
1071
|
!lowerer.isStdlibSymbol(baseSymbol ?? undefined) &&
|
|
989
|
-
!
|
|
990
|
-
(
|
|
991
|
-
|
|
1072
|
+
!ts.getSourceFileOfNode(baseDeclaration).isDeclarationFile &&
|
|
1073
|
+
(ts.getSourceFileOfNode(baseDeclaration) !== ts.getSourceFileOfNode(decl) ||
|
|
1074
|
+
ts.tokenStartOfNode(baseDeclaration) < ts.tokenStartOfNode(decl)))
|
|
992
1075
|
lowerer.collectClassShape(baseDeclaration);
|
|
993
1076
|
lowerer.collectClassShapeInner(decl);
|
|
994
1077
|
});
|
|
@@ -1003,8 +1086,8 @@ function collectClassShapeDeferring(lowerer, decl) {
|
|
|
1003
1086
|
// declaration without a diagnostic would drop observable side effects (the
|
|
1004
1087
|
// classStaticBlock13/28 miscompiles).
|
|
1005
1088
|
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))) {
|
|
1089
|
+
(n.modifiers?.nodes ?? []).some((m) => m.kind === ts.SyntaxKind.Decorator);
|
|
1090
|
+
if (symbol && (hasDeclTimeCode(decl) || decl.members.nodes.some(hasDeclTimeCode))) {
|
|
1008
1091
|
lowerer.reportDeferred(symbol);
|
|
1009
1092
|
}
|
|
1010
1093
|
// A poisoned BASE this class EXTENDS must report EAGERLY for the same
|
|
@@ -1018,9 +1101,9 @@ function collectClassShapeDeferring(lowerer, decl) {
|
|
|
1018
1101
|
// reports. Resolution runs under the collect pass's guard (this is
|
|
1019
1102
|
// collectProgram), so the lookup neither flushes nor fences.
|
|
1020
1103
|
{
|
|
1021
|
-
const baseIdent = decl.heritageClauses
|
|
1022
|
-
|
|
1023
|
-
?.types.map((t) => t.expression)
|
|
1104
|
+
const baseIdent = decl.heritageClauses?.nodes
|
|
1105
|
+
.find((h) => h.token === ts.SyntaxKind.ExtendsKeyword)
|
|
1106
|
+
?.types?.nodes.map((t) => t.expression)
|
|
1024
1107
|
.filter(ts.isIdentifier)[0];
|
|
1025
1108
|
const baseSym = baseIdent ? lowerer.resolveValueSymbol(baseIdent) : null;
|
|
1026
1109
|
if (baseSym)
|
|
@@ -1029,7 +1112,7 @@ function collectClassShapeDeferring(lowerer, decl) {
|
|
|
1029
1112
|
}
|
|
1030
1113
|
function inferredEmptyCollectionFieldType(lowerer, decl, field, initializer) {
|
|
1031
1114
|
if (!ts.isNewExpression(initializer) ||
|
|
1032
|
-
(initializer.arguments?.length ?? 0) !== 0 ||
|
|
1115
|
+
(initializer.arguments?.nodes.length ?? 0) !== 0 ||
|
|
1033
1116
|
!ts.isIdentifier(initializer.expression))
|
|
1034
1117
|
return null;
|
|
1035
1118
|
const collection = initializer.expression.text;
|
|
@@ -1044,7 +1127,12 @@ function inferredEmptyCollectionFieldType(lowerer, decl, field, initializer) {
|
|
|
1044
1127
|
const mappedArgument = (argument) => {
|
|
1045
1128
|
const type = lowerer.checker.getBaseTypeOfLiteralType(lowerer.typeOf(argument));
|
|
1046
1129
|
const mapped = lowerer.mapTypeOf(type);
|
|
1047
|
-
|
|
1130
|
+
// Inferred JS collection fields keep functions in checked slots.
|
|
1131
|
+
if (!mapped ||
|
|
1132
|
+
mapped.kind === "dyn" ||
|
|
1133
|
+
mapped.kind === "void" ||
|
|
1134
|
+
mapped.kind === "func" ||
|
|
1135
|
+
isUnitType(mapped))
|
|
1048
1136
|
return null;
|
|
1049
1137
|
return mapped;
|
|
1050
1138
|
};
|
|
@@ -1061,9 +1149,9 @@ function inferredEmptyCollectionFieldType(lowerer, decl, field, initializer) {
|
|
|
1061
1149
|
}
|
|
1062
1150
|
if (collection === "Map" &&
|
|
1063
1151
|
node.expression.name.text === "set" &&
|
|
1064
|
-
node.arguments.length === 2) {
|
|
1065
|
-
const key = mappedArgument(node.arguments[0]);
|
|
1066
|
-
const value = mappedArgument(node.arguments[1]);
|
|
1152
|
+
node.arguments.nodes.length === 2) {
|
|
1153
|
+
const key = mappedArgument(node.arguments.nodes[0]);
|
|
1154
|
+
const value = mappedArgument(node.arguments.nodes[1]);
|
|
1067
1155
|
if (key !== null &&
|
|
1068
1156
|
value !== null &&
|
|
1069
1157
|
isSupportedMapKey(key, key.kind === "union" ? lowerer.unions.get(key.unionId)?.arms : undefined) &&
|
|
@@ -1076,15 +1164,15 @@ function inferredEmptyCollectionFieldType(lowerer, decl, field, initializer) {
|
|
|
1076
1164
|
(node.expression.name.text === "add" ||
|
|
1077
1165
|
node.expression.name.text === "has" ||
|
|
1078
1166
|
node.expression.name.text === "delete") &&
|
|
1079
|
-
node.arguments.length === 1) {
|
|
1080
|
-
const element = mappedArgument(node.arguments[0]);
|
|
1167
|
+
node.arguments.nodes.length === 1) {
|
|
1168
|
+
const element = mappedArgument(node.arguments.nodes[0]);
|
|
1081
1169
|
if (element !== null &&
|
|
1082
1170
|
isSupportedSetElem(element, element.kind === "union" ? lowerer.unions.get(element.unionId)?.arms : undefined))
|
|
1083
1171
|
setElements.push(element);
|
|
1084
1172
|
}
|
|
1085
1173
|
return undefined;
|
|
1086
1174
|
};
|
|
1087
|
-
for (const member of decl.members) {
|
|
1175
|
+
for (const member of decl.members.nodes) {
|
|
1088
1176
|
const body = ts.isConstructorDeclaration(member) || ts.isMethodDeclaration(member) || ts.isAccessor(member)
|
|
1089
1177
|
? member.body
|
|
1090
1178
|
: undefined;
|
|
@@ -1136,13 +1224,13 @@ mixin) {
|
|
|
1136
1224
|
const classDecoratorNodes = [];
|
|
1137
1225
|
{
|
|
1138
1226
|
classDecoratorNodes.push(...decoratorNodesOf(decl));
|
|
1139
|
-
const decoratedMembers = decl.members.filter((m) => decoratorNodesOf(m).length > 0);
|
|
1227
|
+
const decoratedMembers = decl.members.nodes.filter((m) => decoratorNodesOf(m).length > 0);
|
|
1140
1228
|
if (classDecoratorNodes.length > 0 || decoratedMembers.length > 0) {
|
|
1141
1229
|
// Node itself cannot execute decorator syntax in a JavaScript
|
|
1142
1230
|
// source (V8 has not shipped the proposal; the type-stripping
|
|
1143
1231
|
// loaders leave `@dec` in place) — there is no runtime behavior
|
|
1144
1232
|
// to be exact against.
|
|
1145
|
-
if (isJsSourceFile(
|
|
1233
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(decl))) {
|
|
1146
1234
|
lowerer.unsupported("SC1090", (classDecoratorNodes[0] ?? decoratorNodesOf(decoratedMembers[0])[0]), "decorators in JavaScript sources (V8 has not shipped decorators — Node cannot execute this file)");
|
|
1147
1235
|
}
|
|
1148
1236
|
// The guaranteed-throw SHELL: declarations only (expressions
|
|
@@ -1197,7 +1285,7 @@ mixin) {
|
|
|
1197
1285
|
: ts.isGetAccessorDeclaration(member) || ts.isSetAccessorDeclaration(member)
|
|
1198
1286
|
? "accessor decorators"
|
|
1199
1287
|
: ts.isPropertyDeclaration(member)
|
|
1200
|
-
? member.modifiers?.some((m) => m.kind === ts.SyntaxKind.AccessorKeyword)
|
|
1288
|
+
? member.modifiers?.nodes.some((m) => m.kind === ts.SyntaxKind.AccessorKeyword)
|
|
1201
1289
|
? "auto-accessor decorators"
|
|
1202
1290
|
: "field decorators"
|
|
1203
1291
|
: "member decorators";
|
|
@@ -1259,9 +1347,9 @@ mixin) {
|
|
|
1259
1347
|
return true;
|
|
1260
1348
|
}
|
|
1261
1349
|
const signatures = lowerer.checker.getCallSignatures(lowerer.typeOf(expression));
|
|
1262
|
-
const source = signatures.length === 1 ?
|
|
1350
|
+
const source = signatures.length === 1 ? signatures[0].declaration : undefined;
|
|
1263
1351
|
if (!source ||
|
|
1264
|
-
!isJsSourceFile(
|
|
1352
|
+
!isJsSourceFile(ts.getSourceFileOfNode(source)) ||
|
|
1265
1353
|
!(ts.isFunctionDeclaration(source) || ts.isFunctionExpression(source)))
|
|
1266
1354
|
return false;
|
|
1267
1355
|
callableBase = {
|
|
@@ -1278,14 +1366,14 @@ mixin) {
|
|
|
1278
1366
|
if (!base || base.generic)
|
|
1279
1367
|
lowerer.unsupported("SC1090", ownGenericBase, "a generic base whose type arguments have no concrete layout");
|
|
1280
1368
|
}
|
|
1281
|
-
for (const clause of inst || mixin || computedBase ? [] : (decl.heritageClauses ?? [])) {
|
|
1369
|
+
for (const clause of inst || mixin || computedBase ? [] : (decl.heritageClauses?.nodes ?? [])) {
|
|
1282
1370
|
// `implements` is pure type-world: tsc checked the conformance and
|
|
1283
1371
|
// the clause erases — nothing about the runtime class changes.
|
|
1284
1372
|
// (Assigning an instance INTO an interface-typed slot is a separate
|
|
1285
1373
|
// question, owned by the shape-coercion fences at those sites.)
|
|
1286
1374
|
if (clause.token === ts.SyntaxKind.ImplementsKeyword)
|
|
1287
1375
|
continue;
|
|
1288
|
-
const t = clause.types[0];
|
|
1376
|
+
const t = clause.types.nodes[0];
|
|
1289
1377
|
if (familyMode && t) {
|
|
1290
1378
|
const reference = ts.isPropertyAccessExpression(t.expression)
|
|
1291
1379
|
? t.expression.name
|
|
@@ -1316,7 +1404,7 @@ mixin) {
|
|
|
1316
1404
|
if (globalError &&
|
|
1317
1405
|
globalError.def.name !== "%DOMException" &&
|
|
1318
1406
|
globalError.def.name !== "%AggregateError") {
|
|
1319
|
-
if (t.typeArguments)
|
|
1407
|
+
if (t.typeArguments?.nodes)
|
|
1320
1408
|
lowerer.unsupported("SC1090", t, "extending generic classes");
|
|
1321
1409
|
base = globalError;
|
|
1322
1410
|
continue;
|
|
@@ -1324,7 +1412,7 @@ mixin) {
|
|
|
1324
1412
|
const emitterBase = lowerer.builtinEmitterInfoOf(resolved);
|
|
1325
1413
|
const streamBaseNs = builtinStreamInfoOf(lowerer, resolved);
|
|
1326
1414
|
if (emitterBase || streamBaseNs) {
|
|
1327
|
-
if (t.typeArguments)
|
|
1415
|
+
if (t.typeArguments?.nodes)
|
|
1328
1416
|
lowerer.unsupported("SC1090", t, "extending generic classes");
|
|
1329
1417
|
base = (emitterBase ?? streamBaseNs);
|
|
1330
1418
|
continue;
|
|
@@ -1345,7 +1433,7 @@ mixin) {
|
|
|
1345
1433
|
continue;
|
|
1346
1434
|
lowerer.unsupported("SC1090", t, `extending the namespace member '${t.expression.name.text}' (no class lowering)`);
|
|
1347
1435
|
}
|
|
1348
|
-
if (t.typeArguments)
|
|
1436
|
+
if (t.typeArguments?.nodes)
|
|
1349
1437
|
lowerer.unsupported("SC1090", t, "extending generic classes");
|
|
1350
1438
|
base = nsBase;
|
|
1351
1439
|
continue;
|
|
@@ -1364,13 +1452,13 @@ mixin) {
|
|
|
1364
1452
|
if (!t.expression.questionDotToken) {
|
|
1365
1453
|
const propBase = propertyAssignedClassInfoOf(lowerer, memberSym);
|
|
1366
1454
|
if (propBase) {
|
|
1367
|
-
if (t.typeArguments)
|
|
1455
|
+
if (t.typeArguments?.nodes)
|
|
1368
1456
|
lowerer.unsupported("SC1090", t, "extending generic classes");
|
|
1369
1457
|
const baseDecl = propBase.decl;
|
|
1370
1458
|
if (baseDecl != null &&
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
lowerer.unsupported("SC1090", t, `extending '${t.expression
|
|
1459
|
+
ts.getSourceFileOfNode(baseDecl) === ts.getSourceFileOfNode(decl) &&
|
|
1460
|
+
ts.tokenStartOfNode(baseDecl) > ts.tokenStartOfNode(decl)) {
|
|
1461
|
+
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
1462
|
}
|
|
1375
1463
|
base = propBase;
|
|
1376
1464
|
continue;
|
|
@@ -1379,11 +1467,9 @@ mixin) {
|
|
|
1379
1467
|
// fence (the generic computed-expression one below would hide
|
|
1380
1468
|
// what actually blocks it).
|
|
1381
1469
|
const rebinds = memberSym !== undefined &&
|
|
1382
|
-
|
|
1383
|
-
.declarationsOf(memberSym)
|
|
1384
|
-
.filter((d) => ts.isBinaryExpression(d) && d.operatorToken.kind === ts.SyntaxKind.EqualsToken).length > 1;
|
|
1470
|
+
memberSym.declarations.filter((d) => ts.isBinaryExpression(d) && d.operatorToken.kind === ts.SyntaxKind.EqualsToken).length > 1;
|
|
1385
1471
|
if (rebinds) {
|
|
1386
|
-
lowerer.unsupported("SC1090", t, `extending the reassigned property '${t.expression
|
|
1472
|
+
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
1473
|
}
|
|
1388
1474
|
}
|
|
1389
1475
|
}
|
|
@@ -1392,7 +1478,7 @@ mixin) {
|
|
|
1392
1478
|
// so its statics queue ahead of the derived class's — the
|
|
1393
1479
|
// recursion order delivers exactly that).
|
|
1394
1480
|
if (t && ts.isClassExpression(t.expression)) {
|
|
1395
|
-
if (t.typeArguments)
|
|
1481
|
+
if (t.typeArguments?.nodes)
|
|
1396
1482
|
lowerer.unsupported("SC1090", t, "extending generic classes");
|
|
1397
1483
|
const baseExpr = lowerer.lowerClassExpressionInfo(t.expression);
|
|
1398
1484
|
base = baseExpr;
|
|
@@ -1404,7 +1490,7 @@ mixin) {
|
|
|
1404
1490
|
// through the monomorphized chain (lower-mixins.ts). A call whose
|
|
1405
1491
|
// callee is NOT a mixin function keeps the computed-expression
|
|
1406
1492
|
// fence below.
|
|
1407
|
-
if (t && ts.isCallExpression(t.expression) && !t.typeArguments) {
|
|
1493
|
+
if (t && ts.isCallExpression(t.expression) && !t.typeArguments?.nodes) {
|
|
1408
1494
|
const mixinBase = lowerer.mixinCallClassInfoOf(t.expression);
|
|
1409
1495
|
if (mixinBase) {
|
|
1410
1496
|
base = mixinBase;
|
|
@@ -1492,7 +1578,7 @@ mixin) {
|
|
|
1492
1578
|
base = instBase;
|
|
1493
1579
|
continue;
|
|
1494
1580
|
}
|
|
1495
|
-
if (t.typeArguments)
|
|
1581
|
+
if (t.typeArguments?.nodes)
|
|
1496
1582
|
lowerer.unsupported("SC1090", t, "extending generic classes");
|
|
1497
1583
|
base = named;
|
|
1498
1584
|
if (!base) {
|
|
@@ -1502,7 +1588,7 @@ mixin) {
|
|
|
1502
1588
|
}
|
|
1503
1589
|
}
|
|
1504
1590
|
if (base?.localClass && !functionLocalClass(decl) && !computedBase && !factoryBaseExpression) {
|
|
1505
|
-
const heritage = decl.heritageClauses?.find((clause) => clause.token === ts.SyntaxKind.ExtendsKeyword)?.types[0];
|
|
1591
|
+
const heritage = decl.heritageClauses?.nodes.find((clause) => clause.token === ts.SyntaxKind.ExtendsKeyword)?.types?.nodes[0];
|
|
1506
1592
|
if (heritage)
|
|
1507
1593
|
factoryBaseExpression = heritage.expression;
|
|
1508
1594
|
else
|
|
@@ -1510,9 +1596,7 @@ mixin) {
|
|
|
1510
1596
|
}
|
|
1511
1597
|
if (lowerer.collectingExprClasses.has(decl)) {
|
|
1512
1598
|
for (let parent = base; parent; parent = parent.base) {
|
|
1513
|
-
if (parent.
|
|
1514
|
-
parent.builtinStream !== undefined ||
|
|
1515
|
-
parent.builtinEventTarget !== undefined) {
|
|
1599
|
+
if (parent.builtinEventTarget !== undefined) {
|
|
1516
1600
|
lowerer.unsupported("SC1090", decl, "classes extending builtin bases as values (the inherited runtime constructor has no class-value adapter)");
|
|
1517
1601
|
}
|
|
1518
1602
|
}
|
|
@@ -1535,6 +1619,7 @@ mixin) {
|
|
|
1535
1619
|
const fieldOrder = [];
|
|
1536
1620
|
const methods = new Map();
|
|
1537
1621
|
const methodEntryFences = new Map();
|
|
1622
|
+
const returnAdapters = new Map();
|
|
1538
1623
|
// Own accessor declarations ("get:x"/"set:x" → node), for the
|
|
1539
1624
|
// partial-override analysis below (diagnostics need the node).
|
|
1540
1625
|
const accessorNodes = new Map();
|
|
@@ -1563,12 +1648,12 @@ mixin) {
|
|
|
1563
1648
|
const runtimePrototypeMembers = [];
|
|
1564
1649
|
// Public JS accessors need live constructor descriptors, including
|
|
1565
1650
|
// receiver-sensitive getters and setters inherited by subclasses.
|
|
1566
|
-
const checkedStatics = isJsSourceFile(
|
|
1651
|
+
const checkedStatics = isJsSourceFile(ts.getSourceFileOfNode(decl)) &&
|
|
1567
1652
|
((base && hasRuntimeStatics(base)) ||
|
|
1568
|
-
decl.members.some((member) => ts.isAccessor(member) &&
|
|
1653
|
+
decl.members.nodes.some((member) => ts.isAccessor(member) &&
|
|
1569
1654
|
!ts.isPrivateIdentifier(member.name) &&
|
|
1570
|
-
member.modifiers?.some((modifier) => modifier.kind === ts.SyntaxKind.StaticKeyword))) &&
|
|
1571
|
-
!decl.members.some((member) => member.name &&
|
|
1655
|
+
member.modifiers?.nodes.some((modifier) => modifier.kind === ts.SyntaxKind.StaticKeyword))) &&
|
|
1656
|
+
!decl.members.nodes.some((member) => member.name &&
|
|
1572
1657
|
ts.isPrivateIdentifier(member.name) &&
|
|
1573
1658
|
ts
|
|
1574
1659
|
.getModifiers(member)
|
|
@@ -1601,13 +1686,13 @@ mixin) {
|
|
|
1601
1686
|
lowerer.unsupported("SC1071", member);
|
|
1602
1687
|
const mName = member.name.text;
|
|
1603
1688
|
const typeParams = [];
|
|
1604
|
-
for (const tp of fnNode.typeParameters) {
|
|
1689
|
+
for (const tp of fnNode.typeParameters.nodes) {
|
|
1605
1690
|
const sym = lowerer.checker.getSymbolAtLocation(tp.name);
|
|
1606
1691
|
if (!sym)
|
|
1607
1692
|
lowerer.unsupported("SC1090", member, "this method form");
|
|
1608
1693
|
typeParams.push(sym);
|
|
1609
1694
|
}
|
|
1610
|
-
for (const param of fnNode.parameters) {
|
|
1695
|
+
for (const param of fnNode.parameters.nodes) {
|
|
1611
1696
|
if (!ts.isIdentifier(param.name) &&
|
|
1612
1697
|
!ts.isObjectBindingPattern(param.name) &&
|
|
1613
1698
|
!ts.isArrayBindingPattern(param.name)) {
|
|
@@ -1622,9 +1707,9 @@ mixin) {
|
|
|
1622
1707
|
instances: new Map(),
|
|
1623
1708
|
});
|
|
1624
1709
|
};
|
|
1625
|
-
for (const member of decl.members) {
|
|
1710
|
+
for (const member of decl.members.nodes) {
|
|
1626
1711
|
if ((functionLocalClass(decl) || checkedStatics) &&
|
|
1627
|
-
isJsSourceFile(
|
|
1712
|
+
isJsSourceFile(ts.getSourceFileOfNode(decl)) &&
|
|
1628
1713
|
(ts.isClassStaticBlockDeclaration(member) ||
|
|
1629
1714
|
ts
|
|
1630
1715
|
.getModifiers(member)
|
|
@@ -1633,7 +1718,7 @@ mixin) {
|
|
|
1633
1718
|
continue;
|
|
1634
1719
|
}
|
|
1635
1720
|
if (functionLocalClass(decl) &&
|
|
1636
|
-
isJsSourceFile(
|
|
1721
|
+
isJsSourceFile(ts.getSourceFileOfNode(decl)) &&
|
|
1637
1722
|
(ts.isMethodDeclaration(member) || ts.isAccessor(member)) &&
|
|
1638
1723
|
member.body &&
|
|
1639
1724
|
!ts.isPrivateIdentifier(member.name)) {
|
|
@@ -1698,11 +1783,11 @@ mixin) {
|
|
|
1698
1783
|
if (type.kind === "void")
|
|
1699
1784
|
lowerer.badType(member.name, lowerer.typeOf(member.name));
|
|
1700
1785
|
if (type.kind === "dyn" &&
|
|
1701
|
-
!isJsSourceFile(
|
|
1786
|
+
!isJsSourceFile(ts.getSourceFileOfNode(member)) &&
|
|
1702
1787
|
!lowerer.classFieldStoresDyn(lowerer.typeOf(member.name)) &&
|
|
1703
1788
|
(member.type !== undefined ||
|
|
1704
1789
|
(lowerer.typeOf(member.name).flags & ts.TypeFlags.Any) === 0)) {
|
|
1705
|
-
lowerer.unsupported("SC1090", member.name,
|
|
1790
|
+
lowerer.unsupported("SC1090", member.name, `${dynFieldTypeSpelling(lowerer, member.name)}-typed static fields`);
|
|
1706
1791
|
}
|
|
1707
1792
|
staticFields.push({
|
|
1708
1793
|
name: member.name.text,
|
|
@@ -1724,7 +1809,7 @@ mixin) {
|
|
|
1724
1809
|
lowerer.badType(member.name, lowerer.typeOf(member.name));
|
|
1725
1810
|
}
|
|
1726
1811
|
staticMethods.set(member.name.text, { params: shapes, ret: ft.ret, member });
|
|
1727
|
-
if (implicitMonoFile(
|
|
1812
|
+
if (implicitMonoFile(ts.getSourceFileOfNode(decl)) &&
|
|
1728
1813
|
!functionLocalClass(decl) &&
|
|
1729
1814
|
inst === undefined &&
|
|
1730
1815
|
decl.typeParameters === undefined) {
|
|
@@ -1769,9 +1854,21 @@ mixin) {
|
|
|
1769
1854
|
const memberName = member.name;
|
|
1770
1855
|
if (errorRooted && memberName && classMemberNameOf(lowerer, memberName) === "cause") {
|
|
1771
1856
|
if (ts.isPropertyDeclaration(member) &&
|
|
1772
|
-
!member.modifiers?.some((m) => m.kind === ts.SyntaxKind.StaticKeyword)) {
|
|
1773
|
-
|
|
1774
|
-
|
|
1857
|
+
!member.modifiers?.nodes.some((m) => m.kind === ts.SyntaxKind.StaticKeyword)) {
|
|
1858
|
+
// A TypeScript redeclaration is the JavaScript field: Node
|
|
1859
|
+
// defines the Error's own `cause` (undefined without an
|
|
1860
|
+
// initializer) after super() returns. `declare` and `abstract`
|
|
1861
|
+
// declarations are erased and define nothing. Every `.cause`
|
|
1862
|
+
// read of an Error-rooted class is the checked-dynamic property
|
|
1863
|
+
// (fieldTarget's errorCause container), so only types that read
|
|
1864
|
+
// back unchanged from it are accepted.
|
|
1865
|
+
if (!isJsSourceFile(ts.getSourceFileOfNode(member))) {
|
|
1866
|
+
if (modifiers?.some((m) => m.kind === ts.SyntaxKind.DeclareKeyword ||
|
|
1867
|
+
m.kind === ts.SyntaxKind.AbstractKeyword))
|
|
1868
|
+
continue;
|
|
1869
|
+
if (!lowerer.classFieldStoresDyn(lowerer.typeOf(member.name)))
|
|
1870
|
+
lowerer.unsupported("SC1090", memberName, "redeclaring Error.cause with a type other than 'unknown' or 'object' (declare it 'cause?: unknown' and narrow at the read)");
|
|
1871
|
+
}
|
|
1775
1872
|
fieldOrder.push({
|
|
1776
1873
|
name: "cause",
|
|
1777
1874
|
type: DYN,
|
|
@@ -1837,11 +1934,11 @@ mixin) {
|
|
|
1837
1934
|
!inst &&
|
|
1838
1935
|
!mixin &&
|
|
1839
1936
|
ts.isMethodDeclaration(member) &&
|
|
1840
|
-
!member.modifiers?.some((m) => m.kind === ts.SyntaxKind.StaticKeyword)) {
|
|
1937
|
+
!member.modifiers?.nodes.some((m) => m.kind === ts.SyntaxKind.StaticKeyword)) {
|
|
1841
1938
|
const reason = emitOverrideShapeReason(lowerer, member);
|
|
1842
1939
|
if (reason === null) {
|
|
1843
|
-
const eventSym = lowerer.checker.getSymbolAtLocation(member.parameters[0].name);
|
|
1844
|
-
const restSym = lowerer.checker.getSymbolAtLocation(member.parameters[1].name);
|
|
1940
|
+
const eventSym = lowerer.checker.getSymbolAtLocation(member.parameters.nodes[0].name);
|
|
1941
|
+
const restSym = lowerer.checker.getSymbolAtLocation(member.parameters.nodes[1].name);
|
|
1845
1942
|
if (eventSym && restSym) {
|
|
1846
1943
|
emitOverride = { decl: member, eventSym, restSym };
|
|
1847
1944
|
continue;
|
|
@@ -1889,6 +1986,21 @@ mixin) {
|
|
|
1889
1986
|
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
1987
|
}
|
|
1891
1988
|
}
|
|
1989
|
+
// A completion callback declared with the broad `Function` type
|
|
1990
|
+
// (`cb: Function`) takes the checked-dynamic callable the runtime
|
|
1991
|
+
// passes implicitly typed callbacks; calls through it are
|
|
1992
|
+
// dynamic calls of that callable.
|
|
1993
|
+
const callbackIndex = STREAM_COMPLETION_CALLBACK_INDEX.get(name);
|
|
1994
|
+
const callbackParam = ts.isMethodDeclaration(member) && callbackIndex !== undefined
|
|
1995
|
+
? member.parameters.nodes[callbackIndex]
|
|
1996
|
+
: undefined;
|
|
1997
|
+
if (callbackParam !== undefined &&
|
|
1998
|
+
ts.isIdentifier(callbackParam.name) &&
|
|
1999
|
+
!callbackParam.dotDotDotToken &&
|
|
2000
|
+
!callbackParam.questionToken &&
|
|
2001
|
+
!callbackParam.initializer &&
|
|
2002
|
+
lowerer.checker.typeToString(lowerer.typeOf(callbackParam.name)) === "Function")
|
|
2003
|
+
lowerer.checkedCallbackParams.add(callbackParam);
|
|
1892
2004
|
}
|
|
1893
2005
|
}
|
|
1894
2006
|
if (ts.isPropertyDeclaration(member)) {
|
|
@@ -1921,18 +2033,27 @@ mixin) {
|
|
|
1921
2033
|
? String(Number(member.name.text))
|
|
1922
2034
|
: member.name.text;
|
|
1923
2035
|
const fieldName = symbolKey?.fieldName ?? stringKey;
|
|
2036
|
+
// A TypeScript field without an initializer takes its declared
|
|
2037
|
+
// type and the identifier fields' definite-assignment rule (an
|
|
2038
|
+
// unconditional `this[key] = ...` at the constructor's top
|
|
2039
|
+
// level), checked with the unguarded fields below.
|
|
2040
|
+
const declaredOnly = !member.initializer && !isJsSourceFile(ts.getSourceFileOfNode(member)) && !!member.type;
|
|
1924
2041
|
if (fieldName === null ||
|
|
1925
|
-
(!member.initializer &&
|
|
2042
|
+
(!member.initializer &&
|
|
2043
|
+
!isJsSourceFile(ts.getSourceFileOfNode(member)) &&
|
|
2044
|
+
!declaredOnly)) {
|
|
1926
2045
|
lowerer.unsupported("SC1090", member, "computed class fields without an initializer and a stable string, number, or module-level literal Symbol()/Symbol.for() key");
|
|
1927
2046
|
}
|
|
1928
2047
|
const declared = lowerer.typeOf(member);
|
|
1929
2048
|
const inferred = member.type || !member.initializer
|
|
1930
2049
|
? declared
|
|
1931
2050
|
: lowerer.checker.getBaseTypeOfLiteralType(lowerer.typeOf(member.initializer));
|
|
1932
|
-
const mapped = member.initializer
|
|
2051
|
+
const mapped = member.initializer || declaredOnly
|
|
1933
2052
|
? (lowerer.mapTypeOf(inferred) ?? dynFallbackType(lowerer, member, inferred))
|
|
1934
2053
|
: DYN;
|
|
1935
|
-
let type = mapped?.kind === "record" &&
|
|
2054
|
+
let type = mapped?.kind === "record" &&
|
|
2055
|
+
isJsSourceFile(ts.getSourceFileOfNode(member)) &&
|
|
2056
|
+
!member.type
|
|
1936
2057
|
? DYN
|
|
1937
2058
|
: mapped
|
|
1938
2059
|
? jsOpenObjectType(member, mapped, lowerer.shapes, lowerer.unions)
|
|
@@ -1940,17 +2061,29 @@ mixin) {
|
|
|
1940
2061
|
if (!type ||
|
|
1941
2062
|
type.kind === "void" ||
|
|
1942
2063
|
(type.kind === "dyn" &&
|
|
1943
|
-
!isJsSourceFile(
|
|
1944
|
-
!lowerer.
|
|
2064
|
+
!isJsSourceFile(ts.getSourceFileOfNode(member)) &&
|
|
2065
|
+
!lowerer.classFieldStoresDyn(inferred)))
|
|
1945
2066
|
lowerer.badType(member, inferred);
|
|
1946
|
-
if (isJsSourceFile(
|
|
2067
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(member))) {
|
|
1947
2068
|
type = inheritedJsFieldType(lowerer, decl, fieldName, type);
|
|
1948
2069
|
if (base?.fields.get(fieldName)?.kind === "dyn")
|
|
1949
2070
|
type = DYN;
|
|
1950
2071
|
if (base && !fields.has(fieldName) && lowerer.dynConvertible(type))
|
|
1951
2072
|
type = DYN;
|
|
1952
2073
|
}
|
|
1953
|
-
const undefinedInitializer = !member.initializer
|
|
2074
|
+
const undefinedInitializer = !member.initializer && (!declaredOnly || type.kind === "dyn")
|
|
2075
|
+
? locOf(member)
|
|
2076
|
+
: undefined;
|
|
2077
|
+
if (declaredOnly &&
|
|
2078
|
+
type.kind !== "dyn" &&
|
|
2079
|
+
!(type.kind === "union" &&
|
|
2080
|
+
lowerer.unions.get(type.unionId)?.arms.some((a) => a.kind === "undefinedT"))) {
|
|
2081
|
+
unguardedFields.push({
|
|
2082
|
+
node: member.name,
|
|
2083
|
+
name: fieldName,
|
|
2084
|
+
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)`,
|
|
2085
|
+
});
|
|
2086
|
+
}
|
|
1954
2087
|
const previous = fields.get(fieldName);
|
|
1955
2088
|
if (previous) {
|
|
1956
2089
|
if (symbolKey && !symbolFields.has(symbolKey.identity)) {
|
|
@@ -2026,9 +2159,9 @@ mixin) {
|
|
|
2026
2159
|
// as undefined on construction, verified), and reads/writes ride
|
|
2027
2160
|
// the ordinary undefined-armed union machinery.
|
|
2028
2161
|
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 ?? []) {
|
|
2162
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(member)) && !member.initializer) {
|
|
2163
|
+
const constructor = decl.members.nodes.find((part) => ts.isConstructorDeclaration(part) && !!part.body);
|
|
2164
|
+
for (const statement of constructor?.body?.statements?.nodes ?? []) {
|
|
2032
2165
|
if (!ts.isExpressionStatement(statement) ||
|
|
2033
2166
|
!ts.isBinaryExpression(statement.expression) ||
|
|
2034
2167
|
statement.expression.operatorToken.kind !== ts.SyntaxKind.EqualsToken)
|
|
@@ -2046,18 +2179,20 @@ mixin) {
|
|
|
2046
2179
|
}
|
|
2047
2180
|
// Unannotated JavaScript callback slots retain the original
|
|
2048
2181
|
// callable and its receiver instead of adapting its signature.
|
|
2049
|
-
if (isJsSourceFile(
|
|
2182
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(member)) &&
|
|
2050
2183
|
!member.type &&
|
|
2051
|
-
!/@type\b/.test(
|
|
2184
|
+
!/@type\b/.test(ts.getSourceFileOfNode(member).text.slice(member.pos, ts.tokenStartOfNode(member))) &&
|
|
2052
2185
|
(type.kind === "func" || type.kind === "record") &&
|
|
2053
2186
|
lowerer.dynConvertible(type))
|
|
2054
2187
|
type = DYN;
|
|
2055
2188
|
// JS permits reads before a constructor's first assignment even
|
|
2056
2189
|
// when its inferred field type omits undefined.
|
|
2057
|
-
if (isJsSourceFile(
|
|
2190
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(member)) &&
|
|
2191
|
+
!member.initializer &&
|
|
2192
|
+
type.kind !== "dyn") {
|
|
2058
2193
|
type = lowerer.withUndefinedArmOf(type) ?? DYN;
|
|
2059
2194
|
}
|
|
2060
|
-
if (isJsSourceFile(
|
|
2195
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(member))) {
|
|
2061
2196
|
type = inheritedJsFieldType(lowerer, decl, member.name.text, type);
|
|
2062
2197
|
if (base?.fields.get(member.name.text)?.kind === "dyn")
|
|
2063
2198
|
type = DYN;
|
|
@@ -2070,9 +2205,9 @@ mixin) {
|
|
|
2070
2205
|
// them in the constructor. Use the same native checked-dynamic
|
|
2071
2206
|
// storage as implicit constructor-assigned JS fields.
|
|
2072
2207
|
if (type.kind === "dyn" &&
|
|
2073
|
-
!isJsSourceFile(
|
|
2208
|
+
!isJsSourceFile(ts.getSourceFileOfNode(member)) &&
|
|
2074
2209
|
!lowerer.classFieldStoresDyn(lowerer.typeOf(member.name))) {
|
|
2075
|
-
lowerer.unsupported("SC1090", member.name,
|
|
2210
|
+
lowerer.unsupported("SC1090", member.name, `${dynFieldTypeSpelling(lowerer, member.name)}-typed class fields`);
|
|
2076
2211
|
}
|
|
2077
2212
|
const undefinedInitializer = type.kind === "dyn" && !member.initializer ? locOf(member) : undefined;
|
|
2078
2213
|
if (fields.has(member.name.text)) {
|
|
@@ -2171,8 +2306,8 @@ mixin) {
|
|
|
2171
2306
|
// FIRST (before every declared field, as undefined), and the
|
|
2172
2307
|
// assignments run after super() and the field initializers, in
|
|
2173
2308
|
// parameter order (see paramPropInitStmts).
|
|
2174
|
-
for (const p of member.parameters) {
|
|
2175
|
-
const isParamProp = p.modifiers?.some((m) => m.kind === ts.SyntaxKind.PublicKeyword ||
|
|
2309
|
+
for (const p of member.parameters.nodes) {
|
|
2310
|
+
const isParamProp = p.modifiers?.nodes.some((m) => m.kind === ts.SyntaxKind.PublicKeyword ||
|
|
2176
2311
|
m.kind === ts.SyntaxKind.PrivateKeyword ||
|
|
2177
2312
|
m.kind === ts.SyntaxKind.ProtectedKeyword ||
|
|
2178
2313
|
m.kind === ts.SyntaxKind.ReadonlyKeyword ||
|
|
@@ -2180,7 +2315,7 @@ mixin) {
|
|
|
2180
2315
|
if (!isParamProp) {
|
|
2181
2316
|
// Non-keyword modifiers (parameter decorators) are rejected
|
|
2182
2317
|
// by tsc under standard decorators; defensive.
|
|
2183
|
-
if (p.modifiers?.length)
|
|
2318
|
+
if (p.modifiers?.nodes.length)
|
|
2184
2319
|
lowerer.unsupported("SC1090", p, "this parameter form");
|
|
2185
2320
|
continue;
|
|
2186
2321
|
}
|
|
@@ -2191,7 +2326,7 @@ mixin) {
|
|
|
2191
2326
|
}
|
|
2192
2327
|
const name = p.name.text;
|
|
2193
2328
|
if (errorRooted && name === "cause") {
|
|
2194
|
-
lowerer.unsupported("SC1090", p.name, "redeclaring Error.cause (
|
|
2329
|
+
lowerer.unsupported("SC1090", p.name, "redeclaring Error.cause as a parameter property (declare 'cause?: unknown' and assign it in the constructor)");
|
|
2195
2330
|
}
|
|
2196
2331
|
const shape = lowerer.paramShape(p);
|
|
2197
2332
|
const type = shape.bodyType ?? shape.type;
|
|
@@ -2199,7 +2334,7 @@ mixin) {
|
|
|
2199
2334
|
lowerer.badType(p.name, lowerer.typeOf(p.name));
|
|
2200
2335
|
// The class-field dyn rule verbatim (KEEP NARROW).
|
|
2201
2336
|
if (type.kind === "dyn" && !lowerer.classFieldStoresDyn(lowerer.typeOf(p))) {
|
|
2202
|
-
lowerer.unsupported("SC1090", p.name,
|
|
2337
|
+
lowerer.unsupported("SC1090", p.name, `${dynFieldTypeSpelling(lowerer, p)}-typed class fields`);
|
|
2203
2338
|
}
|
|
2204
2339
|
// `override x` (and any same-named inherited member) would
|
|
2205
2340
|
// redeclare a base slot — the declared-field rule verbatim.
|
|
@@ -2257,7 +2392,14 @@ mixin) {
|
|
|
2257
2392
|
!typeEquals(overridden.sig.ret, overrideReturnAbi(lowerer, ret, overridden.sig.ret, className, base)))) {
|
|
2258
2393
|
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
2394
|
}
|
|
2260
|
-
|
|
2395
|
+
const unionReturn = overridden?.sig.ret.kind === "union" && !typeEquals(ret, overridden.sig.ret);
|
|
2396
|
+
if (unionReturn)
|
|
2397
|
+
lowerer.unionReturnOverrides.add(member);
|
|
2398
|
+
methods.set(mName, {
|
|
2399
|
+
params: shapes,
|
|
2400
|
+
ret: unionReturn ? overridden.sig.ret : ret,
|
|
2401
|
+
abstract: true,
|
|
2402
|
+
});
|
|
2261
2403
|
continue;
|
|
2262
2404
|
}
|
|
2263
2405
|
// A body-less method is an OVERLOAD SIGNATURE (abstract methods
|
|
@@ -2292,7 +2434,7 @@ mixin) {
|
|
|
2292
2434
|
// dispatch worlds could meet: an inherited declaration of the
|
|
2293
2435
|
// name (the override stays on the vtable), a shadowed field, or
|
|
2294
2436
|
// a generic-class instantiation's member.
|
|
2295
|
-
if (implicitMonoFile(
|
|
2437
|
+
if (implicitMonoFile(ts.getSourceFileOfNode(decl)) &&
|
|
2296
2438
|
!functionLocalClass(decl) &&
|
|
2297
2439
|
ts.isIdentifier(member.name) &&
|
|
2298
2440
|
!lowerer.virtualJsMethods.has(member) &&
|
|
@@ -2332,12 +2474,12 @@ mixin) {
|
|
|
2332
2474
|
}
|
|
2333
2475
|
// JS inference may retain only a symbol sentinel while a method
|
|
2334
2476
|
// also returns values from an untyped mutable field or local.
|
|
2335
|
-
if (isJsSourceFile(
|
|
2477
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(member)) &&
|
|
2336
2478
|
!member.type &&
|
|
2337
2479
|
!hasExplicitJsDocReturn(member) &&
|
|
2338
2480
|
ft.ret.kind === "symbol")
|
|
2339
2481
|
ft.ret = DYN;
|
|
2340
|
-
if (isJsSourceFile(
|
|
2482
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(member)) &&
|
|
2341
2483
|
lowerer.prototypeMethodAccesses.has(mName) &&
|
|
2342
2484
|
!lowerer.findMethodOn(base, mName)?.declarer.def.runtime &&
|
|
2343
2485
|
shapes.every((p) => p.mode === "required" || p.mode === "omittable")) {
|
|
@@ -2386,7 +2528,7 @@ mixin) {
|
|
|
2386
2528
|
// against the STATIC receiver's shape, so `m(x?: number)` and
|
|
2387
2529
|
// `m(x: number | undefined)` interchange soundly in overrides.
|
|
2388
2530
|
const overridden = lowerer.findMethodOn(base, mName);
|
|
2389
|
-
if (overridden && isJsSourceFile(
|
|
2531
|
+
if (overridden && isJsSourceFile(ts.getSourceFileOfNode(member))) {
|
|
2390
2532
|
// An unannotated JS override can return a checked value into
|
|
2391
2533
|
// the inherited native ABI, just as its untyped parameters do.
|
|
2392
2534
|
// Body lowering inserts the conversion at each return.
|
|
@@ -2408,7 +2550,7 @@ mixin) {
|
|
|
2408
2550
|
// Defaults stay local to each declaration, so only inherited
|
|
2409
2551
|
// required/optional slots participate in this refinement.
|
|
2410
2552
|
for (let i = 0; i < shapes.length; i++) {
|
|
2411
|
-
const parameter = member.parameters[i];
|
|
2553
|
+
const parameter = member.parameters.nodes[i];
|
|
2412
2554
|
const inherited = overridden.sig.params[i];
|
|
2413
2555
|
if (parameter &&
|
|
2414
2556
|
inherited &&
|
|
@@ -2427,7 +2569,7 @@ mixin) {
|
|
|
2427
2569
|
// calls fill them with undefined. Typed tails and rest/arguments
|
|
2428
2570
|
// readers keep the exact-signature fence.
|
|
2429
2571
|
if (overridden &&
|
|
2430
|
-
isJsSourceFile(
|
|
2572
|
+
isJsSourceFile(ts.getSourceFileOfNode(member)) &&
|
|
2431
2573
|
shapes.length < overridden.sig.params.length &&
|
|
2432
2574
|
!bodyReadsArguments(member) &&
|
|
2433
2575
|
shapes.every((p, i) => (p.mode === "required" || p.mode === "omittable") &&
|
|
@@ -2439,28 +2581,116 @@ mixin) {
|
|
|
2439
2581
|
.slice(shapes.length)
|
|
2440
2582
|
.map((p) => ({ type: p.type, mode: "omittable" })));
|
|
2441
2583
|
}
|
|
2584
|
+
// A TypeScript override of a JavaScript method (`class T extends
|
|
2585
|
+
// Agent` over an npm-static package) keeps the base's checked-value
|
|
2586
|
+
// ABI: each untyped base slot stays dyn, and the override's typed
|
|
2587
|
+
// parameter narrows from it at entry with a checked conversion. An
|
|
2588
|
+
// untyped base return takes the override's value boxed. Calls on
|
|
2589
|
+
// a statically typed receiver see the same ABI.
|
|
2590
|
+
if (overridden &&
|
|
2591
|
+
!isJsSourceFile(ts.getSourceFileOfNode(member)) &&
|
|
2592
|
+
overridden.declarer.decl !== null &&
|
|
2593
|
+
isJsSourceFile(ts.getSourceFileOfNode(overridden.declarer.decl)) &&
|
|
2594
|
+
member.asteriskToken === undefined &&
|
|
2595
|
+
!overridden.sig.async &&
|
|
2596
|
+
!overridden.sig.gen &&
|
|
2597
|
+
shapes.length <= overridden.sig.params.length &&
|
|
2598
|
+
shapes.every((p, i) => {
|
|
2599
|
+
const inherited = overridden.sig.params[i];
|
|
2600
|
+
return ((p.mode === "required" || p.mode === "omittable") &&
|
|
2601
|
+
p.bodyType === undefined &&
|
|
2602
|
+
(inherited.mode === "required" || inherited.mode === "omittable") &&
|
|
2603
|
+
(typeEquals(p.type, inherited.type) ||
|
|
2604
|
+
(inherited.type.kind === "dyn" && lowerer.dynConvertible(p.type))));
|
|
2605
|
+
}) &&
|
|
2606
|
+
overridden.sig.params
|
|
2607
|
+
.slice(shapes.length)
|
|
2608
|
+
.every((p) => p.type.kind === "dyn" && (p.mode === "required" || p.mode === "omittable"))) {
|
|
2609
|
+
for (let i = 0; i < shapes.length; i++) {
|
|
2610
|
+
const own = shapes[i];
|
|
2611
|
+
if (overridden.sig.params[i].type.kind === "dyn" && own.type.kind !== "dyn")
|
|
2612
|
+
shapes[i] = { type: DYN, mode: own.mode, entryNarrow: own.type };
|
|
2613
|
+
}
|
|
2614
|
+
shapes.push(...overridden.sig.params
|
|
2615
|
+
.slice(shapes.length)
|
|
2616
|
+
.map((p) => ({ type: p.type, mode: "omittable" })));
|
|
2617
|
+
if (overridden.sig.ret.kind === "dyn" &&
|
|
2618
|
+
ft.ret.kind !== "dyn" &&
|
|
2619
|
+
ft.ret.kind !== "void" &&
|
|
2620
|
+
lowerer.dynConvertible(ft.ret))
|
|
2621
|
+
ft.ret = DYN;
|
|
2622
|
+
ft.params = shapes.map((shape) => shape.type);
|
|
2623
|
+
}
|
|
2442
2624
|
if (overridden &&
|
|
2443
2625
|
member.asteriskToken === undefined &&
|
|
2444
2626
|
(overridden.sig.params.length !== shapes.length ||
|
|
2445
2627
|
!overridden.sig.params.every((p, i) => typeEquals(p.type, shapes[i].type)) ||
|
|
2446
2628
|
!typeEquals(overridden.sig.ret, overrideReturnAbi(lowerer, ft.ret, overridden.sig.ret, className, base)))) {
|
|
2447
|
-
const fencedJsOverride = isJsSourceFile(
|
|
2629
|
+
const fencedJsOverride = isJsSourceFile(ts.getSourceFileOfNode(member)) &&
|
|
2448
2630
|
overridden.declarer.decl !== null &&
|
|
2449
|
-
isJsSourceFile(overridden.declarer.decl
|
|
2631
|
+
isJsSourceFile(ts.getSourceFileOfNode(overridden.declarer.decl)) &&
|
|
2450
2632
|
overridden.sig.gen === undefined;
|
|
2451
|
-
|
|
2633
|
+
// A TypeScript override that only changes the result, into a
|
|
2634
|
+
// type that converts into the inherited one (`Promise<void>` over
|
|
2635
|
+
// an `any` base, `string | undefined` over `string`): the slot
|
|
2636
|
+
// keeps the inherited ABI and converts the body's result at the
|
|
2637
|
+
// boundary (lowerClassMethodMemberInner).
|
|
2638
|
+
const ownAsync = member.modifiers?.nodes.some((m) => m.kind === ts.SyntaxKind.AsyncKeyword) === true;
|
|
2639
|
+
if (!fencedJsOverride &&
|
|
2640
|
+
!functionLocalClass(decl) &&
|
|
2641
|
+
overridden.sig.gen === undefined &&
|
|
2642
|
+
// An async base's slot answers its promise: a Promise type, or
|
|
2643
|
+
// the checked-dynamic value of an untyped async method.
|
|
2644
|
+
(overridden.sig.async !== true ||
|
|
2645
|
+
overridden.sig.ret.kind === "promise" ||
|
|
2646
|
+
overridden.sig.ret.kind === "dyn") &&
|
|
2647
|
+
!overridden.sig.abstract &&
|
|
2648
|
+
overridden.sig.params.length === shapes.length &&
|
|
2649
|
+
overridden.sig.params.every((p, i) => p.mode === shapes[i].mode &&
|
|
2650
|
+
(p.mode === "required" || p.mode === "omittable") &&
|
|
2651
|
+
// Each inherited argument converts into the override's
|
|
2652
|
+
// parameter: equal, a checked extraction from an `any`
|
|
2653
|
+
// slot, or a widening (a contravariant parameter).
|
|
2654
|
+
(typeEquals(p.type, shapes[i].type) ||
|
|
2655
|
+
(p.type.kind === "dyn" &&
|
|
2656
|
+
canDynCheckTo(shapes[i].type, (id) => lowerer.shapes.get(id), (id) => lowerer.unions.get(id))) ||
|
|
2657
|
+
lowerer.coercibleValue(p.type, shapes[i].type))) &&
|
|
2658
|
+
(ownAsync ? ft.ret.kind === "promise" : true) &&
|
|
2659
|
+
(typeEquals(ft.ret, overridden.sig.ret) ||
|
|
2660
|
+
(overridden.sig.ret.kind === "dyn"
|
|
2661
|
+
? ft.ret.kind !== "void" && lowerer.dynConvertible(ft.ret)
|
|
2662
|
+
: lowerer.coercibleValue(ft.ret, overridden.sig.ret) ||
|
|
2663
|
+
// A promise whose payload widens into the inherited one
|
|
2664
|
+
// (`Promise<void>` over an untyped async `Promise<any>`).
|
|
2665
|
+
(ft.ret.kind === "promise" &&
|
|
2666
|
+
overridden.sig.ret.kind === "promise" &&
|
|
2667
|
+
lowerer.promisePayloadWidens(ft.ret, overridden.sig.ret)) ||
|
|
2668
|
+
// A JavaScript override's inferred `any` result checks
|
|
2669
|
+
// into the inherited type (`toString() { return
|
|
2670
|
+
// this.message }` over Error's).
|
|
2671
|
+
(ft.ret.kind === "dyn" &&
|
|
2672
|
+
isJsSourceFile(ts.getSourceFileOfNode(member)) &&
|
|
2673
|
+
overridden.sig.ret.kind !== "void" &&
|
|
2674
|
+
canDynCheckTo(overridden.sig.ret, (id) => lowerer.shapes.get(id), (id) => lowerer.unions.get(id)))))) {
|
|
2675
|
+
returnAdapters.set(mName, { params: [...shapes], ret: ft.ret, async: ownAsync });
|
|
2676
|
+
shapes.splice(0, shapes.length, ...overridden.sig.params);
|
|
2677
|
+
ft.ret = overridden.sig.ret;
|
|
2678
|
+
if (overridden.sig.async === true)
|
|
2679
|
+
thunkAsyncSlot(overridden, mName);
|
|
2680
|
+
}
|
|
2681
|
+
else if (fencedJsOverride) {
|
|
2452
2682
|
// A dormant JS method must not poison the whole class. Keep
|
|
2453
2683
|
// the inherited call/dispatch ABI and refuse at method entry;
|
|
2454
2684
|
// lowering this body with the base signature would change JS.
|
|
2455
2685
|
const returnOnly = overridden.sig.params.length === shapes.length &&
|
|
2456
2686
|
overridden.sig.params.every((p, i) => typeEquals(p.type, shapes[i].type)) &&
|
|
2457
|
-
!member.parameters.some((parameter, index) => {
|
|
2687
|
+
!member.parameters.nodes.some((parameter, index) => {
|
|
2458
2688
|
if (!parameter.initializer)
|
|
2459
2689
|
return false;
|
|
2460
|
-
const baseMember = overridden.declarer.decl?.members.find((candidate) => ts.isMethodDeclaration(candidate) &&
|
|
2690
|
+
const baseMember = overridden.declarer.decl?.members?.nodes.find((candidate) => ts.isMethodDeclaration(candidate) &&
|
|
2461
2691
|
classMemberNameOf(lowerer, candidate.name) === mName);
|
|
2462
2692
|
const inherited = baseMember && ts.isMethodDeclaration(baseMember)
|
|
2463
|
-
? baseMember.parameters[index]?.initializer
|
|
2693
|
+
? baseMember.parameters.nodes[index]?.initializer
|
|
2464
2694
|
: undefined;
|
|
2465
2695
|
if (!inherited)
|
|
2466
2696
|
return false;
|
|
@@ -2478,14 +2708,42 @@ mixin) {
|
|
|
2478
2708
|
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
2709
|
}
|
|
2480
2710
|
}
|
|
2481
|
-
|
|
2711
|
+
// A return narrowed to part of an inherited union returns through
|
|
2712
|
+
// the union ABI; call sites narrow it back to the declared type.
|
|
2713
|
+
if (overridden?.sig.ret.kind === "union" && !typeEquals(ft.ret, overridden.sig.ret)) {
|
|
2714
|
+
ft.ret = overridden.sig.ret;
|
|
2715
|
+
lowerer.unionReturnOverrides.add(member);
|
|
2716
|
+
}
|
|
2717
|
+
const asyncMember = member.modifiers?.nodes.some((m) => m.kind === ts.SyntaxKind.AsyncKeyword) === true;
|
|
2482
2718
|
// Async methods dispatch STATICALLY (the body enters through its
|
|
2483
2719
|
// fiber spawn wrapper; vtable slots hold raw implementations) —
|
|
2484
2720
|
// an override chain touching an async method on either end would
|
|
2485
2721
|
// put a spawn wrapper behind a virtual slot, so it fences.
|
|
2486
|
-
|
|
2722
|
+
// An override chain touching async methods dispatches through
|
|
2723
|
+
// plain slot functions that return the body's promise: the async
|
|
2724
|
+
// bodies lower as `%C.m$own` behind them (thunkAsyncSlot).
|
|
2725
|
+
if (overridden &&
|
|
2726
|
+
!returnAdapters.has(mName) &&
|
|
2727
|
+
(asyncMember || overridden.sig.async === true) &&
|
|
2728
|
+
!isJsSourceFile(ts.getSourceFileOfNode(member)) &&
|
|
2729
|
+
!functionLocalClass(decl) &&
|
|
2730
|
+
member.asteriskToken === undefined &&
|
|
2731
|
+
overridden.sig.gen === undefined &&
|
|
2732
|
+
!overridden.sig.abstract &&
|
|
2733
|
+
ft.ret.kind === "promise" &&
|
|
2734
|
+
typeEquals(ft.ret, overridden.sig.ret) &&
|
|
2735
|
+
overridden.sig.params.length === shapes.length &&
|
|
2736
|
+
overridden.sig.params.every((p, i) => typeEquals(p.type, shapes[i].type) && p.mode === shapes[i].mode)) {
|
|
2737
|
+
if (overridden.sig.async === true)
|
|
2738
|
+
thunkAsyncSlot(overridden, mName);
|
|
2739
|
+
if (asyncMember)
|
|
2740
|
+
returnAdapters.set(mName, { params: [...shapes], ret: ft.ret, async: true });
|
|
2741
|
+
}
|
|
2742
|
+
if (overridden &&
|
|
2743
|
+
!returnAdapters.has(mName) &&
|
|
2744
|
+
(asyncMember || overridden.sig.async === true)) {
|
|
2487
2745
|
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(
|
|
2746
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(member)))
|
|
2489
2747
|
methodEntryFences.set(mName, unsupportedDiag("SC1090", locOf(member.name), message));
|
|
2490
2748
|
else
|
|
2491
2749
|
lowerer.unsupported("SC1090", member.name, message);
|
|
@@ -2493,7 +2751,7 @@ mixin) {
|
|
|
2493
2751
|
if (overridden &&
|
|
2494
2752
|
(member.asteriskToken !== undefined || overridden.sig.gen !== undefined)) {
|
|
2495
2753
|
const message = `overriding the generator method '${mName}' (generator methods dispatch statically — a virtual slot cannot enter their spawn wrapper)`;
|
|
2496
|
-
if (isJsSourceFile(
|
|
2754
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(member)))
|
|
2497
2755
|
methodEntryFences.set(mName, unsupportedDiag("SC1090", locOf(member.name), message));
|
|
2498
2756
|
else
|
|
2499
2757
|
lowerer.unsupported("SC1090", member.name, message);
|
|
@@ -2513,7 +2771,7 @@ mixin) {
|
|
|
2513
2771
|
});
|
|
2514
2772
|
}
|
|
2515
2773
|
else {
|
|
2516
|
-
methods.set(mName, asyncMember
|
|
2774
|
+
methods.set(mName, asyncMember && !returnAdapters.has(mName)
|
|
2517
2775
|
? { params: shapes, ret: ft.ret, async: true }
|
|
2518
2776
|
: { params: shapes, ret: ft.ret });
|
|
2519
2777
|
}
|
|
@@ -2555,7 +2813,7 @@ mixin) {
|
|
|
2555
2813
|
lowerer.unsupported("SC1090", member, "bodyless accessors");
|
|
2556
2814
|
const mName = `${isGet ? "get" : "set"}:${prop}`;
|
|
2557
2815
|
if (fields.has(prop) &&
|
|
2558
|
-
isJsSourceFile(
|
|
2816
|
+
isJsSourceFile(ts.getSourceFileOfNode(decl)) &&
|
|
2559
2817
|
base?.fields.has(prop) &&
|
|
2560
2818
|
!fieldOrder.some((field) => field.name === prop)) {
|
|
2561
2819
|
// JS may override an inherited data field with a prototype
|
|
@@ -2572,14 +2830,22 @@ mixin) {
|
|
|
2572
2830
|
}
|
|
2573
2831
|
let sig;
|
|
2574
2832
|
if (isGet) {
|
|
2575
|
-
|
|
2833
|
+
let ret = lowerer.declaredReturnType(member, member.name);
|
|
2834
|
+
// A getter that never returns a value: typed `never` (it only
|
|
2835
|
+
// throws, Next.js's removed `page`/`ua` getters) or, unannotated
|
|
2836
|
+
// with no return statement, inferred `void`. A read answers
|
|
2837
|
+
// undefined or throws, so the property takes the checked-dynamic
|
|
2838
|
+
// slot instead of VOID.
|
|
2839
|
+
if (ret.kind === "void" &&
|
|
2840
|
+
(lowerer.typeOf(member.name).flags & (ts.TypeFlags.Never | ts.TypeFlags.Void)) !== 0)
|
|
2841
|
+
ret = DYN;
|
|
2576
2842
|
if (ret.kind === "void")
|
|
2577
2843
|
lowerer.badType(member.name, lowerer.typeOf(member.name));
|
|
2578
2844
|
sig = { params: [], ret };
|
|
2579
2845
|
}
|
|
2580
2846
|
else {
|
|
2581
2847
|
// tsc rejects optional/default/rest setter params (TS1051-53).
|
|
2582
|
-
sig = { params: lowerer.paramShapes(member.parameters), ret: VOID };
|
|
2848
|
+
sig = { params: lowerer.paramShapes(member.parameters.nodes), ret: VOID };
|
|
2583
2849
|
}
|
|
2584
2850
|
if (lowerer.checkedVirtualJsAccessors.has(member)) {
|
|
2585
2851
|
if (isGet)
|
|
@@ -2643,7 +2909,7 @@ mixin) {
|
|
|
2643
2909
|
// undefined. Such fields take the deferred-init representation, whose
|
|
2644
2910
|
// slot (a nullable instance pointer) starts empty and whose reads check
|
|
2645
2911
|
// it. Fields assigned before any exposure keep their plain reads.
|
|
2646
|
-
const derived = decl.heritageClauses?.some((clause) => clause.token === ts.SyntaxKind.ExtendsKeyword) ??
|
|
2912
|
+
const derived = decl.heritageClauses?.nodes.some((clause) => clause.token === ts.SyntaxKind.ExtendsKeyword) ??
|
|
2647
2913
|
false;
|
|
2648
2914
|
// Generic instances and mixins share layouts across declarations, so
|
|
2649
2915
|
// they only report whether construction exposes the instance.
|
|
@@ -2668,7 +2934,7 @@ mixin) {
|
|
|
2668
2934
|
if (!ts.isPropertyAccessExpression(callee))
|
|
2669
2935
|
return null;
|
|
2670
2936
|
const name = callee.name.text;
|
|
2671
|
-
const declaration = decl.members.find((member) => ts.isMethodDeclaration(member) &&
|
|
2937
|
+
const declaration = decl.members.nodes.find((member) => ts.isMethodDeclaration(member) &&
|
|
2672
2938
|
member.body !== undefined &&
|
|
2673
2939
|
(ts.isIdentifier(member.name) || ts.isPrivateIdentifier(member.name)) &&
|
|
2674
2940
|
member.name.text === name);
|
|
@@ -2692,7 +2958,7 @@ mixin) {
|
|
|
2692
2958
|
const deferredInitFields = new Set(base?.deferredInitFields ?? []);
|
|
2693
2959
|
if (unguardedFields.length > 0) {
|
|
2694
2960
|
const topAssigned = new Set();
|
|
2695
|
-
for (const stmt of ctor?.body?.statements ?? []) {
|
|
2961
|
+
for (const stmt of ctor?.body?.statements?.nodes ?? []) {
|
|
2696
2962
|
if (ts.isExpressionStatement(stmt) &&
|
|
2697
2963
|
ts.isBinaryExpression(stmt.expression) &&
|
|
2698
2964
|
stmt.expression.operatorToken.kind === ts.SyntaxKind.EqualsToken &&
|
|
@@ -2700,6 +2966,16 @@ mixin) {
|
|
|
2700
2966
|
stmt.expression.left.expression.kind === ts.SyntaxKind.ThisKeyword) {
|
|
2701
2967
|
topAssigned.add(stmt.expression.left.name.text);
|
|
2702
2968
|
}
|
|
2969
|
+
else if (ts.isExpressionStatement(stmt) &&
|
|
2970
|
+
ts.isBinaryExpression(stmt.expression) &&
|
|
2971
|
+
stmt.expression.operatorToken.kind === ts.SyntaxKind.EqualsToken &&
|
|
2972
|
+
ts.isElementAccessExpression(stmt.expression.left) &&
|
|
2973
|
+
stmt.expression.left.expression.kind === ts.SyntaxKind.ThisKeyword) {
|
|
2974
|
+
const key = stmt.expression.left.argumentExpression;
|
|
2975
|
+
const name = classSymbolKeyOf(lowerer, key)?.fieldName ?? lowerer.foldedStringKeyOf(key);
|
|
2976
|
+
if (name !== null)
|
|
2977
|
+
topAssigned.add(name);
|
|
2978
|
+
}
|
|
2703
2979
|
}
|
|
2704
2980
|
for (const f of unguardedFields) {
|
|
2705
2981
|
if (topAssigned.has(f.name) || escape.assigned?.has(f.name))
|
|
@@ -2736,13 +3012,26 @@ mixin) {
|
|
|
2736
3012
|
}
|
|
2737
3013
|
}
|
|
2738
3014
|
if (escape.assigned && !inst) {
|
|
3015
|
+
let earlyReads = null;
|
|
2739
3016
|
for (const f of fieldOrder) {
|
|
2740
3017
|
if (f.redeclared || escape.assigned.has(f.name) || deferredInitFields.has(f.name))
|
|
2741
3018
|
continue;
|
|
2742
3019
|
if (paramProps.some((pp) => pp.name === f.name))
|
|
2743
3020
|
continue;
|
|
2744
3021
|
const declared = fields.get(f.name);
|
|
2745
|
-
|
|
3022
|
+
// Records, arrays and strings are pointer slots that start empty
|
|
3023
|
+
// too, but only take the checked slot when a method the
|
|
3024
|
+
// constructor calls actually reads them: their other early
|
|
3025
|
+
// exposures keep the plain slot.
|
|
3026
|
+
if (declared?.kind === "record" ||
|
|
3027
|
+
declared?.kind === "array" ||
|
|
3028
|
+
declared?.kind === "string") {
|
|
3029
|
+
earlyReads ??= constructorMethodReads(decl, base, ctor ?? undefined);
|
|
3030
|
+
if (!earlyReads.has(f.name))
|
|
3031
|
+
continue;
|
|
3032
|
+
}
|
|
3033
|
+
else if (declared?.kind !== "object" ||
|
|
3034
|
+
lowerer.classes.get(declared.className)?.def.runtime)
|
|
2746
3035
|
continue;
|
|
2747
3036
|
const armed = lowerer.withUndefinedArm(declared);
|
|
2748
3037
|
if (armed === null || armed.kind !== "union")
|
|
@@ -2803,7 +3092,7 @@ mixin) {
|
|
|
2803
3092
|
// assignment ran — the zeroed-memory trap a TS declaration order
|
|
2804
3093
|
// forbids via strictPropertyInitialization — so they keep a named
|
|
2805
3094
|
// fence instead of reading undefined without a diagnostic.
|
|
2806
|
-
if (isJsSourceFile(
|
|
3095
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(decl))) {
|
|
2807
3096
|
const hasAccessor = (name) => methods.has(`get:${name}`) ||
|
|
2808
3097
|
methods.has(`set:${name}`) ||
|
|
2809
3098
|
lowerer.findMethodOn(base, `get:${name}`) !== null ||
|
|
@@ -2826,14 +3115,22 @@ mixin) {
|
|
|
2826
3115
|
// goes through the key.
|
|
2827
3116
|
const lateBoundByKey = new Map();
|
|
2828
3117
|
for (const p of instType ? lowerer.checker.getPropertiesOfType(instType) : []) {
|
|
2829
|
-
if (!p.
|
|
3118
|
+
if (!ts.symbolName(p).startsWith("__@"))
|
|
2830
3119
|
continue;
|
|
2831
3120
|
const keySym = lateBoundKeySymOf(lowerer, p);
|
|
2832
3121
|
if (keySym)
|
|
2833
3122
|
lateBoundByKey.set(keySym, p);
|
|
2834
3123
|
}
|
|
3124
|
+
// A subclass field created before anything can observe the instance
|
|
3125
|
+
// keeps its type: super() cannot run code that reads it earlier.
|
|
3126
|
+
const baseConstruction = base && ![...methods.keys()].some((m) => m.startsWith("get:") || m.startsWith("set:"))
|
|
3127
|
+
? construction(base)
|
|
3128
|
+
: null;
|
|
3129
|
+
const sealedPrefix = baseConstruction
|
|
3130
|
+
? constructionPrefix(decl, baseConstruction, (name) => !hasAccessor(name) && !methods.has(name) && !lowerer.findMethodOn(base, name))
|
|
3131
|
+
: null;
|
|
2835
3132
|
if (ctor?.body) {
|
|
2836
|
-
for (const stmt of ctor.body.statements) {
|
|
3133
|
+
for (const stmt of ctor.body.statements.nodes) {
|
|
2837
3134
|
const lhs = ts.isExpressionStatement(stmt) &&
|
|
2838
3135
|
ts.isBinaryExpression(stmt.expression) &&
|
|
2839
3136
|
stmt.expression.operatorToken.kind === ts.SyntaxKind.EqualsToken
|
|
@@ -2869,7 +3166,7 @@ mixin) {
|
|
|
2869
3166
|
let type = t ? (lowerer.mapTypeOf(t) ?? dynFallbackType(lowerer, assign, t)) : null;
|
|
2870
3167
|
if (t &&
|
|
2871
3168
|
(t.flags & (ts.TypeFlags.Null | ts.TypeFlags.Undefined)) !== 0 &&
|
|
2872
|
-
isJsSourceFile(
|
|
3169
|
+
isJsSourceFile(ts.getSourceFileOfNode(decl)))
|
|
2873
3170
|
type = DYN;
|
|
2874
3171
|
if (type)
|
|
2875
3172
|
type = jsOpenObjectType(assign, type, lowerer.shapes, lowerer.unions);
|
|
@@ -2901,7 +3198,7 @@ mixin) {
|
|
|
2901
3198
|
type = inheritedJsFieldType(lowerer, decl, name, type);
|
|
2902
3199
|
// super() can invoke a subclass setter or method before its
|
|
2903
3200
|
// constructor assignments run. These slots start undefined.
|
|
2904
|
-
if (base && lowerer.dynConvertible(type))
|
|
3201
|
+
if (base && lowerer.dynConvertible(type) && !sealedPrefix?.created.has(name))
|
|
2905
3202
|
type = DYN;
|
|
2906
3203
|
fields.set(name, type);
|
|
2907
3204
|
fieldOrder.push({ name, type, initializer: undefined });
|
|
@@ -2983,17 +3280,16 @@ mixin) {
|
|
|
2983
3280
|
// static layouts cannot represent. Named fence, at the first
|
|
2984
3281
|
// assignment site.
|
|
2985
3282
|
for (const p of instType ? lowerer.checker.getPropertiesOfType(instType) : []) {
|
|
2986
|
-
if (errorRooted && p
|
|
3283
|
+
if (errorRooted && ts.symbolName(p) === "cause")
|
|
2987
3284
|
continue;
|
|
2988
|
-
if (fields.has(p
|
|
3285
|
+
if (fields.has(ts.symbolName(p)) || methods.has(ts.symbolName(p)))
|
|
2989
3286
|
continue;
|
|
2990
|
-
if (hasAccessor(p
|
|
3287
|
+
if (hasAccessor(ts.symbolName(p)))
|
|
2991
3288
|
continue;
|
|
2992
|
-
if (base &&
|
|
3289
|
+
if (base &&
|
|
3290
|
+
(base.fields.has(ts.symbolName(p)) || lowerer.findMethodOn(base, ts.symbolName(p))))
|
|
2993
3291
|
continue;
|
|
2994
|
-
const site =
|
|
2995
|
-
.declarationsOf(p)
|
|
2996
|
-
.find((d) => ts.isPropertyAccessExpression(d) ||
|
|
3292
|
+
const site = p.declarations.find((d) => ts.isPropertyAccessExpression(d) ||
|
|
2997
3293
|
ts.isBinaryExpression(d) ||
|
|
2998
3294
|
ts.isElementAccessExpression(d));
|
|
2999
3295
|
if (!site)
|
|
@@ -3004,7 +3300,7 @@ mixin) {
|
|
|
3004
3300
|
// identities (symbol parameters, mutable bindings, computed
|
|
3005
3301
|
// descriptions) or assignments outside the constructor's top
|
|
3006
3302
|
// level.
|
|
3007
|
-
if (p.
|
|
3303
|
+
if (ts.symbolName(p).startsWith("__@")) {
|
|
3008
3304
|
const keySym = lateBoundKeySymOf(lowerer, p);
|
|
3009
3305
|
const key = keySym ? classSymbolKeyOfSymbol(lowerer, keySym) : null;
|
|
3010
3306
|
if (key && symbolFields.has(key.identity))
|
|
@@ -3021,21 +3317,23 @@ mixin) {
|
|
|
3021
3317
|
// Unmappable inferences and arm-less kinds keep the fence.
|
|
3022
3318
|
// TypeScript classes keep the compile-time fence too: an annotated
|
|
3023
3319
|
// program can spell `T | undefined` itself.
|
|
3024
|
-
if (isJsSourceFile(
|
|
3320
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(decl))) {
|
|
3025
3321
|
const original = undefArmedFieldType(lowerer, p);
|
|
3026
|
-
const armed = original === null
|
|
3322
|
+
const armed = original === null
|
|
3323
|
+
? null
|
|
3324
|
+
: inheritedJsFieldType(lowerer, decl, ts.symbolName(p), original);
|
|
3027
3325
|
if (armed !== null) {
|
|
3028
3326
|
// Unknown JS properties use the instance bag: they do not
|
|
3029
3327
|
// exist until assigned, and a subclass may declare the same
|
|
3030
3328
|
// name as an ordinary layout field.
|
|
3031
3329
|
if (armed.kind === "dyn")
|
|
3032
3330
|
continue;
|
|
3033
|
-
fields.set(p
|
|
3034
|
-
fieldOrder.push({ name: p
|
|
3331
|
+
fields.set(ts.symbolName(p), armed);
|
|
3332
|
+
fieldOrder.push({ name: ts.symbolName(p), type: armed, initializer: undefined });
|
|
3035
3333
|
continue;
|
|
3036
3334
|
}
|
|
3037
3335
|
}
|
|
3038
|
-
lowerer.unsupported("SC1090", site, `fields assigned outside the constructor's top level ('this.${p
|
|
3336
|
+
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
3337
|
}
|
|
3040
3338
|
}
|
|
3041
3339
|
// Second refinement chance, OWN symbol slots: the member loop ran
|
|
@@ -3059,18 +3357,18 @@ mixin) {
|
|
|
3059
3357
|
// is NOT the pure forwarding shape has no static story — named
|
|
3060
3358
|
// fence, never a mis-typed array.
|
|
3061
3359
|
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)");
|
|
3360
|
+
if (mixin && ctor && !mixinForwarding && ctor.parameters.nodes.some((p) => p.dotDotDotToken)) {
|
|
3361
|
+
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
3362
|
}
|
|
3065
3363
|
// Constructor omitted on a derived class: it inherits the base's
|
|
3066
3364
|
// (tsc types `new Derived(...)` against the inherited signature; the
|
|
3067
3365
|
// synthesized constructor forwards the same params to super).
|
|
3068
3366
|
const ctorParams = ctor && !mixinForwarding
|
|
3069
|
-
? lowerer.paramShapes(ctor.parameters)
|
|
3367
|
+
? lowerer.paramShapes(ctor.parameters.nodes)
|
|
3070
3368
|
: (base?.ctorParams ?? (callableBase ? [{ type: DYN, mode: "dynRest" }] : []));
|
|
3071
3369
|
if (ctor &&
|
|
3072
3370
|
!mixinForwarding &&
|
|
3073
|
-
isJsSourceFile(
|
|
3371
|
+
isJsSourceFile(ts.getSourceFileOfNode(ctor)) &&
|
|
3074
3372
|
!ctorParams.some((shape) => shape.mode === "rest" || shape.mode === "dynRest") &&
|
|
3075
3373
|
bodyReadsArguments(ctor)) {
|
|
3076
3374
|
ctorParams.push({ type: DYN, mode: "arguments" });
|
|
@@ -3086,9 +3384,9 @@ mixin) {
|
|
|
3086
3384
|
// INSTANTIATION prints its family's name — JS has one `Box`.
|
|
3087
3385
|
jsName: jsNameOverride ?? decl.name?.text ?? "",
|
|
3088
3386
|
...(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),
|
|
3387
|
+
jsLength: ctor?.parameters?.nodes.findIndex((parameter) => parameter.initializer || parameter.dotDotDotToken) === -1
|
|
3388
|
+
? ctor.parameters.nodes.length
|
|
3389
|
+
: Math.max(0, ctor?.parameters?.nodes.findIndex((parameter) => parameter.initializer || parameter.dotDotDotToken) ?? 0),
|
|
3092
3390
|
// Layout order: the base chain's fields as an IDENTICAL prefix,
|
|
3093
3391
|
// then this class's own — what makes an upcast a reinterpret.
|
|
3094
3392
|
// Redeclared INHERITED fields contribute no slot (their
|
|
@@ -3116,6 +3414,7 @@ mixin) {
|
|
|
3116
3414
|
fieldOrder,
|
|
3117
3415
|
methods,
|
|
3118
3416
|
...(methodEntryFences.size > 0 ? { methodEntryFences } : {}),
|
|
3417
|
+
...(returnAdapters.size > 0 ? { returnAdapters } : {}),
|
|
3119
3418
|
decl,
|
|
3120
3419
|
...(emitOverride !== undefined ? { emitOverride } : {}),
|
|
3121
3420
|
ctor,
|
|
@@ -3138,6 +3437,14 @@ mixin) {
|
|
|
3138
3437
|
...(deferredInitFields.size > 0 ? { deferredInitFields } : {}),
|
|
3139
3438
|
...(escape.escapes ? { constructionEscapes: true } : {}),
|
|
3140
3439
|
};
|
|
3440
|
+
let root = info;
|
|
3441
|
+
while (root?.base)
|
|
3442
|
+
root = root.base;
|
|
3443
|
+
if (root !== info && root?.def.name === "%Error") {
|
|
3444
|
+
const after = errorNameAfterField(info, errorViewFields(info.def.fields));
|
|
3445
|
+
if (after !== undefined)
|
|
3446
|
+
info.def.errorNameAfter = after;
|
|
3447
|
+
}
|
|
3141
3448
|
// GENERIC members get their declaring-class backlink now that the
|
|
3142
3449
|
// info exists (instance lowering reads it for `this` typing and the
|
|
3143
3450
|
// generic-class binding merge).
|
|
@@ -3171,7 +3478,7 @@ mixin) {
|
|
|
3171
3478
|
}
|
|
3172
3479
|
if (familyMode) {
|
|
3173
3480
|
const typeParams = [];
|
|
3174
|
-
for (const tp of decl.typeParameters) {
|
|
3481
|
+
for (const tp of decl.typeParameters.nodes) {
|
|
3175
3482
|
const sym = lowerer.checker.getSymbolAtLocation(tp.name);
|
|
3176
3483
|
if (!sym)
|
|
3177
3484
|
lowerer.unsupported("SC1090", tp, "this type parameter form");
|
|
@@ -3439,6 +3746,7 @@ export function lowerStaticFieldInits(lowerer, info) {
|
|
|
3439
3746
|
// instantiation's bindings/context (a no-op for everything else —
|
|
3440
3747
|
// generic FAMILIES own their statics and carry no genericInstance).
|
|
3441
3748
|
const diagsBefore = lowerer.diags.length;
|
|
3749
|
+
const sinkMark = lowerer.diagSinkMark();
|
|
3442
3750
|
try {
|
|
3443
3751
|
return withInstanceBindings(lowerer, info, () => lowerStaticFieldInitsInner(lowerer, info));
|
|
3444
3752
|
}
|
|
@@ -3448,8 +3756,10 @@ export function lowerStaticFieldInits(lowerer, info) {
|
|
|
3448
3756
|
// letting a poisoned initializer escape the module lowering pass.
|
|
3449
3757
|
if (!(error instanceof PoisonError))
|
|
3450
3758
|
throw error;
|
|
3451
|
-
if (info.decl && isJsSourceFile(info.decl
|
|
3452
|
-
const fence = lowerer.
|
|
3759
|
+
if (info.decl && isJsSourceFile(ts.getSourceFileOfNode(info.decl))) {
|
|
3760
|
+
const fence = lowerer.diagSink === null
|
|
3761
|
+
? lowerer.deferToRuntimeFence(diagsBefore, info.decl, { kind: "statement" })
|
|
3762
|
+
: lowerer.capturedRuntimeFence(sinkMark, info.decl);
|
|
3453
3763
|
if (fence)
|
|
3454
3764
|
return [fence];
|
|
3455
3765
|
}
|
|
@@ -3560,8 +3870,16 @@ function lowerStaticFieldInitsInner(lowerer, info) {
|
|
|
3560
3870
|
});
|
|
3561
3871
|
}
|
|
3562
3872
|
const items = [
|
|
3563
|
-
...info.staticFields.map((f) => ({
|
|
3564
|
-
|
|
3873
|
+
...info.staticFields.map((f) => ({
|
|
3874
|
+
pos: ts.tokenStartOfNode(f.initializer),
|
|
3875
|
+
kind: "field",
|
|
3876
|
+
f,
|
|
3877
|
+
})),
|
|
3878
|
+
...(info.staticBlocks ?? []).map((b) => ({
|
|
3879
|
+
pos: ts.tokenStartOfNode(b),
|
|
3880
|
+
kind: "block",
|
|
3881
|
+
b,
|
|
3882
|
+
})),
|
|
3565
3883
|
].sort((a, b) => a.pos - b.pos);
|
|
3566
3884
|
for (const item of items) {
|
|
3567
3885
|
if (item.kind === "block") {
|
|
@@ -3571,9 +3889,9 @@ function lowerStaticFieldInitsInner(lowerer, info) {
|
|
|
3571
3889
|
continue;
|
|
3572
3890
|
}
|
|
3573
3891
|
const f = item.f;
|
|
3574
|
-
lowerer.
|
|
3575
|
-
lowerer.bumpFileStat(locOf(f.initializer).file, "total");
|
|
3892
|
+
lowerer.countStatement(f.initializer, locOf(f.initializer).file);
|
|
3576
3893
|
const diagsBefore = lowerer.diags.length;
|
|
3894
|
+
const sinkMark = lowerer.diagSinkMark();
|
|
3577
3895
|
try {
|
|
3578
3896
|
const previousThis = lowerer.ctx.thisLocal;
|
|
3579
3897
|
const receiver = f.initializer.kind === ts.SyntaxKind.ThisKeyword || hasStaticThis(f.initializer)
|
|
@@ -3610,12 +3928,11 @@ function lowerStaticFieldInitsInner(lowerer, info) {
|
|
|
3610
3928
|
catch (e) {
|
|
3611
3929
|
if (!(e instanceof PoisonError))
|
|
3612
3930
|
throw e;
|
|
3613
|
-
lowerer.
|
|
3614
|
-
|
|
3615
|
-
|
|
3616
|
-
|
|
3617
|
-
|
|
3618
|
-
});
|
|
3931
|
+
lowerer.countStatementFailed(f.initializer, locOf(f.initializer).file);
|
|
3932
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(f.initializer))) {
|
|
3933
|
+
const fence = lowerer.diagSink === null
|
|
3934
|
+
? lowerer.deferToRuntimeFence(diagsBefore, f.initializer, { kind: "statement" })
|
|
3935
|
+
: lowerer.capturedRuntimeFence(sinkMark, f.initializer);
|
|
3619
3936
|
if (fence)
|
|
3620
3937
|
out.push(fence);
|
|
3621
3938
|
}
|
|
@@ -3664,12 +3981,12 @@ export function analyzeClassDecoration(lowerer, info) {
|
|
|
3664
3981
|
: null;
|
|
3665
3982
|
if (ambientCallee !== null) {
|
|
3666
3983
|
const sym = lowerer.resolveValueSymbol(ambientCallee);
|
|
3667
|
-
const vdecl = sym && !lowerer.isStdlibSymbol(sym) ?
|
|
3984
|
+
const vdecl = sym && !lowerer.isStdlibSymbol(sym) ? sym.declarations[0] : undefined;
|
|
3668
3985
|
const ambientVar = vdecl !== undefined &&
|
|
3669
3986
|
ts.isVariableDeclaration(vdecl) &&
|
|
3670
3987
|
vdecl.initializer === undefined &&
|
|
3671
3988
|
(ts.getCombinedModifierFlags(vdecl) & ts.ModifierFlags.Ambient) !== 0 &&
|
|
3672
|
-
!
|
|
3989
|
+
!ts.getSourceFileOfNode(vdecl).isDeclarationFile;
|
|
3673
3990
|
if (ambientVar || ambientUndefinedFnSymbolOf(lowerer, ambientCallee) !== null) {
|
|
3674
3991
|
shapes.push({ kind: "ambientThrow", name: ambientCallee.text });
|
|
3675
3992
|
continue;
|
|
@@ -3861,6 +4178,54 @@ export function staticShadowBelow(info, name) {
|
|
|
3861
4178
|
s.genericStatics?.has(name) === true ||
|
|
3862
4179
|
staticShadowBelow(s, name));
|
|
3863
4180
|
}
|
|
4181
|
+
/** The `this` members read by the methods and accessors a constructor
|
|
4182
|
+
* calls through `this` (transitively, over the class and its bases),
|
|
4183
|
+
* outside nested functions. The constructor's own reads are not included:
|
|
4184
|
+
* they run where the constructor's statements put them. */
|
|
4185
|
+
function constructorMethodReads(decl, base, ctor) {
|
|
4186
|
+
const reads = new Set();
|
|
4187
|
+
const visited = new Set();
|
|
4188
|
+
const bodies = (name) => {
|
|
4189
|
+
const out = [];
|
|
4190
|
+
let owner = decl;
|
|
4191
|
+
for (let next = base; owner; owner = next?.decl ?? undefined, next = next?.base ?? null) {
|
|
4192
|
+
for (const member of owner.members.nodes) {
|
|
4193
|
+
if ((ts.isMethodDeclaration(member) || ts.isAccessor(member)) &&
|
|
4194
|
+
member.body &&
|
|
4195
|
+
(ts.isIdentifier(member.name) || ts.isPrivateIdentifier(member.name)) &&
|
|
4196
|
+
member.name.text === name)
|
|
4197
|
+
out.push(member.body);
|
|
4198
|
+
}
|
|
4199
|
+
}
|
|
4200
|
+
return out;
|
|
4201
|
+
};
|
|
4202
|
+
const enter = (name) => {
|
|
4203
|
+
if (visited.has(name))
|
|
4204
|
+
return;
|
|
4205
|
+
visited.add(name);
|
|
4206
|
+
for (const body of bodies(name))
|
|
4207
|
+
scan(body, true);
|
|
4208
|
+
};
|
|
4209
|
+
// Nested functions (callbacks handed elsewhere) are not followed: only
|
|
4210
|
+
// the straight-line code of the constructor and the methods it calls.
|
|
4211
|
+
const scan = (node, inMethod) => {
|
|
4212
|
+
ts.walkPreorder(node, (n) => {
|
|
4213
|
+
if (n !== node && ts.isFunctionLike(n))
|
|
4214
|
+
return "skip";
|
|
4215
|
+
if (ts.isPropertyAccessExpression(n) &&
|
|
4216
|
+
n.expression.kind === ts.SyntaxKind.ThisKeyword &&
|
|
4217
|
+
(ts.isIdentifier(n.name) || ts.isPrivateIdentifier(n.name))) {
|
|
4218
|
+
if (inMethod)
|
|
4219
|
+
reads.add(n.name.text);
|
|
4220
|
+
enter(n.name.text);
|
|
4221
|
+
}
|
|
4222
|
+
return undefined;
|
|
4223
|
+
});
|
|
4224
|
+
};
|
|
4225
|
+
if (ctor?.body)
|
|
4226
|
+
scan(ctor.body, false);
|
|
4227
|
+
return reads;
|
|
4228
|
+
}
|
|
3864
4229
|
/** The nearest GENERIC static declaration of `name` at/above `info` —
|
|
3865
4230
|
* findStaticOn's twin over the genericStatics tables. */
|
|
3866
4231
|
export function findGenericStaticOn(lowerer, info, name) {
|
|
@@ -3915,17 +4280,22 @@ export function classValueRef(lowerer, info, blame) {
|
|
|
3915
4280
|
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
4281
|
}
|
|
3917
4282
|
if (info.builtinError || info.builtinEmitter || info.builtinStream !== undefined) {
|
|
3918
|
-
|
|
3919
|
-
|
|
3920
|
-
|
|
3921
|
-
|
|
3922
|
-
|
|
3923
|
-
|
|
3924
|
-
|
|
3925
|
-
|
|
3926
|
-
|
|
3927
|
-
|
|
3928
|
-
|
|
4283
|
+
if (info.valueCtorParams === undefined) {
|
|
4284
|
+
lowerer.unsupported("SC1090", blame, `builtin classes as values ('${display}' is runtime-provided — reference program-declared classes instead)`);
|
|
4285
|
+
}
|
|
4286
|
+
defineClassValueConstruct(lowerer, info);
|
|
4287
|
+
return {
|
|
4288
|
+
kind: "classRef",
|
|
4289
|
+
className: info.def.name,
|
|
4290
|
+
type: { kind: "classval", className: info.def.name },
|
|
4291
|
+
loc: locOf(blame),
|
|
4292
|
+
};
|
|
4293
|
+
}
|
|
4294
|
+
// Classes extending EventEmitter or a stream class construct through
|
|
4295
|
+
// their own (or synthesized) `%C.constructor`, whose super call runs the
|
|
4296
|
+
// runtime initializer, so the class object's construct thunk serves them
|
|
4297
|
+
// like any program class. EventTarget subclasses keep the refusal.
|
|
4298
|
+
if (eventTargetRootOf(info) !== null) {
|
|
3929
4299
|
lowerer.unsupported("SC1090", blame, `classes extending builtin bases as values ('${display}' inherits a runtime-provided constructor)`);
|
|
3930
4300
|
}
|
|
3931
4301
|
lowerer.noteEdge(`%${info.def.name}.constructor`);
|
|
@@ -3936,14 +4306,94 @@ export function classValueRef(lowerer, info, blame) {
|
|
|
3936
4306
|
loc: locOf(blame),
|
|
3937
4307
|
};
|
|
3938
4308
|
}
|
|
4309
|
+
/** Notes a runtime-provided class whose value is named, widened to, or
|
|
4310
|
+
* constructed through (a no-op for program classes, whose constructor is
|
|
4311
|
+
* their own). runtimeClassConstructs defines `%C.construct` for the
|
|
4312
|
+
* noted classes the finished module still references. */
|
|
4313
|
+
export function defineClassValueConstruct(lowerer, info) {
|
|
4314
|
+
if (!info.def.runtime || info.valueCtorParams === undefined)
|
|
4315
|
+
return;
|
|
4316
|
+
lowerer.noteEdge(classValueConstructor(info.def).fn);
|
|
4317
|
+
lowerer.runtimeClassValues.set(info.def.name, info);
|
|
4318
|
+
}
|
|
4319
|
+
/** The `%C.construct` functions of the noted runtime classes that a
|
|
4320
|
+
* classRef, newValue or classval upcast in `functions` names. Lowering can
|
|
4321
|
+
* name a class speculatively and discard the expression, so the finished
|
|
4322
|
+
* functions decide. */
|
|
4323
|
+
export function runtimeClassConstructs(lowerer, functions) {
|
|
4324
|
+
if (lowerer.runtimeClassValues.size === 0)
|
|
4325
|
+
return [];
|
|
4326
|
+
const used = new Set();
|
|
4327
|
+
const note = (type) => {
|
|
4328
|
+
if (type.kind === "classval" && lowerer.runtimeClassValues.has(type.className))
|
|
4329
|
+
used.add(type.className);
|
|
4330
|
+
};
|
|
4331
|
+
const visitor = {
|
|
4332
|
+
expr: (e) => {
|
|
4333
|
+
if (e.kind === "classRef")
|
|
4334
|
+
note(e.type);
|
|
4335
|
+
else if (e.kind === "newValue")
|
|
4336
|
+
note(e.callee.type);
|
|
4337
|
+
else if (e.kind === "upcast") {
|
|
4338
|
+
note(e.type);
|
|
4339
|
+
note(e.value.type);
|
|
4340
|
+
}
|
|
4341
|
+
return true;
|
|
4342
|
+
},
|
|
4343
|
+
stmt: () => true,
|
|
4344
|
+
};
|
|
4345
|
+
for (const fn of functions)
|
|
4346
|
+
everyStmtList(fn.body, visitor);
|
|
4347
|
+
return [...used]
|
|
4348
|
+
.sort()
|
|
4349
|
+
.map((name) => runtimeClassConstruct(lowerer.runtimeClassValues.get(name)));
|
|
4350
|
+
}
|
|
4351
|
+
/** `%C.construct` for a runtime-provided class value: the thunk's target,
|
|
4352
|
+
* which builds the instance through the runtime constructor the direct
|
|
4353
|
+
* `new C(...)` uses (emitter.new, a stream's .newDyn without options,
|
|
4354
|
+
* error.newOptions). */
|
|
4355
|
+
function runtimeClassConstruct(info) {
|
|
4356
|
+
const params = info.valueCtorParams ?? [];
|
|
4357
|
+
const name = classValueConstructor(info.def).fn;
|
|
4358
|
+
const loc = info.def.loc;
|
|
4359
|
+
const type = { kind: "object", className: info.def.name };
|
|
4360
|
+
const ids = params.map((_, i) => `a${i}.0`);
|
|
4361
|
+
const args = ids.map((id) => varRef(id, DYN, loc));
|
|
4362
|
+
let fn = "error.newOptions";
|
|
4363
|
+
if (info.builtinEmitter)
|
|
4364
|
+
fn = "emitter.new";
|
|
4365
|
+
else if (info.builtinStream !== undefined) {
|
|
4366
|
+
fn = `${streamCtorShape(info.def.name).fn}.newDyn`;
|
|
4367
|
+
args.push(dynUndefinedExpr(loc));
|
|
4368
|
+
}
|
|
4369
|
+
return {
|
|
4370
|
+
name,
|
|
4371
|
+
params: params.map((shape, i) => ({ localId: ids[i], name: `a${i}`, type: shape.type })),
|
|
4372
|
+
returnType: type,
|
|
4373
|
+
locals: params.map((shape, i) => ({
|
|
4374
|
+
id: ids[i],
|
|
4375
|
+
name: `a${i}`,
|
|
4376
|
+
type: shape.type,
|
|
4377
|
+
mutable: false,
|
|
4378
|
+
})),
|
|
4379
|
+
body: [{ kind: "return", value: { kind: "libCall", fn, args, type, loc }, loc }],
|
|
4380
|
+
loc,
|
|
4381
|
+
};
|
|
4382
|
+
}
|
|
4383
|
+
/** The constructor parameters construction through a class value completes
|
|
4384
|
+
* against: a program class's constructor, or a runtime class's
|
|
4385
|
+
* `%C.construct`. */
|
|
4386
|
+
function classValueParams(info) {
|
|
4387
|
+
return info.def.runtime ? (info.valueCtorParams ?? info.ctorParams) : info.ctorParams;
|
|
4388
|
+
}
|
|
3939
4389
|
/** Constructor-ABI equality — the classval widening rule: a classval(D)
|
|
3940
4390
|
* value may flow into a classval(C) slot only when D's completed
|
|
3941
4391
|
* constructor signature equals C's (same count, modes, and ABI types),
|
|
3942
4392
|
* which is what keeps newValue completion against C's one signature
|
|
3943
4393
|
* sound for every value legally in the slot. */
|
|
3944
4394
|
export function ctorAbiEquals(lowerer, sub, sup) {
|
|
3945
|
-
const a = sub
|
|
3946
|
-
const b = sup
|
|
4395
|
+
const a = classValueParams(sub);
|
|
4396
|
+
const b = classValueParams(sup);
|
|
3947
4397
|
return (a.length === b.length &&
|
|
3948
4398
|
a.every((p, i) => p.mode === b[i].mode && typeEquals(p.type, b[i].type)));
|
|
3949
4399
|
}
|
|
@@ -4066,7 +4516,7 @@ export function lowerStaticFieldRead(lowerer, expr) {
|
|
|
4066
4516
|
// JavaScript often assigns public statics after the class declaration.
|
|
4067
4517
|
// Their storage stays mutable and checked, while reads retain the
|
|
4068
4518
|
// checker's concrete type instead of losing the method receiver.
|
|
4069
|
-
const type = isJsSourceFile(
|
|
4519
|
+
const type = isJsSourceFile(ts.getSourceFileOfNode(expr))
|
|
4070
4520
|
? null
|
|
4071
4521
|
: lowerer.mapTypeOf(lowerer.typeOf(expr));
|
|
4072
4522
|
return type ? lowerer.coerceToExpected(value, type) : value;
|
|
@@ -4097,6 +4547,70 @@ function namedEvaluationName(expr) {
|
|
|
4097
4547
|
return p.name.text;
|
|
4098
4548
|
return "";
|
|
4099
4549
|
}
|
|
4550
|
+
/** Each evaluation of a function-local class creates fresh private names,
|
|
4551
|
+
* while the compiled class shares one layout across evaluations. A
|
|
4552
|
+
* JavaScript class's prototype methods are closures per evaluation, so the
|
|
4553
|
+
* names agree when every private member is an instance field and every use
|
|
4554
|
+
* is on `this` (privateNamesOnlyOnThis): native methods only run on their
|
|
4555
|
+
* own evaluation's instances, and the closures, which receive any `this`,
|
|
4556
|
+
* check the receiver's evaluation against the class's own binding
|
|
4557
|
+
* (private-brands.ts), so the class must be a named declaration (undici's
|
|
4558
|
+
* webidl FastIterableIterator). The checker rejects writes to that binding. */
|
|
4559
|
+
function localPrivateFieldsAgree(expr) {
|
|
4560
|
+
if (!isJsSourceFile(ts.getSourceFileOfNode(expr)) || !ts.isClassDeclaration(expr) || !expr.name)
|
|
4561
|
+
return false;
|
|
4562
|
+
if (expr.members.nodes.some((member) => member.name !== undefined &&
|
|
4563
|
+
ts.isPrivateIdentifier(member.name) &&
|
|
4564
|
+
!ts.isPropertyDeclaration(member)))
|
|
4565
|
+
return false;
|
|
4566
|
+
return privateNamesOnlyOnThis(expr);
|
|
4567
|
+
}
|
|
4568
|
+
/** Every private name is used only on `this` inside the class's own instance
|
|
4569
|
+
* members (`this.#x`, `#x in this`), outside nested classes and non-arrow
|
|
4570
|
+
* functions, and the class has no static members that could hand instances
|
|
4571
|
+
* across evaluations. */
|
|
4572
|
+
function privateNamesOnlyOnThis(expr) {
|
|
4573
|
+
let ok = true;
|
|
4574
|
+
for (const member of expr.members.nodes) {
|
|
4575
|
+
if (ts.getModifiers(member)?.some((m) => m.kind === ts.SyntaxKind.StaticKeyword))
|
|
4576
|
+
return false;
|
|
4577
|
+
ts.walkPreorder(member, (node) => {
|
|
4578
|
+
if (!ok)
|
|
4579
|
+
return "stop";
|
|
4580
|
+
// A nested class or non-arrow function rebinds `this`: any private
|
|
4581
|
+
// name inside it disqualifies.
|
|
4582
|
+
if (node !== member &&
|
|
4583
|
+
(ts.isClassDeclaration(node) ||
|
|
4584
|
+
ts.isClassExpression(node) ||
|
|
4585
|
+
ts.isFunctionExpression(node) ||
|
|
4586
|
+
ts.isFunctionDeclaration(node))) {
|
|
4587
|
+
ts.walkPreorder(node, (inner) => {
|
|
4588
|
+
if (ts.isPrivateIdentifier(inner))
|
|
4589
|
+
ok = false;
|
|
4590
|
+
return ok ? undefined : "stop";
|
|
4591
|
+
});
|
|
4592
|
+
return "skip";
|
|
4593
|
+
}
|
|
4594
|
+
if (ts.isPrivateIdentifier(node)) {
|
|
4595
|
+
const parent = node.parent;
|
|
4596
|
+
const onThis = parent === member ||
|
|
4597
|
+
(ts.isPropertyAccessExpression(parent) &&
|
|
4598
|
+
parent.name === node &&
|
|
4599
|
+
parent.expression.kind === ts.SyntaxKind.ThisKeyword) ||
|
|
4600
|
+
(ts.isBinaryExpression(parent) &&
|
|
4601
|
+
parent.left === node &&
|
|
4602
|
+
parent.operatorToken.kind === ts.SyntaxKind.InKeyword &&
|
|
4603
|
+
parent.right.kind === ts.SyntaxKind.ThisKeyword);
|
|
4604
|
+
if (!onThis)
|
|
4605
|
+
ok = false;
|
|
4606
|
+
}
|
|
4607
|
+
return undefined;
|
|
4608
|
+
});
|
|
4609
|
+
if (!ok)
|
|
4610
|
+
return false;
|
|
4611
|
+
}
|
|
4612
|
+
return true;
|
|
4613
|
+
}
|
|
4100
4614
|
/** Collect a class expression once per enclosing specialization. Function-local
|
|
4101
4615
|
* evaluations allocate fresh constructor objects; top-level expressions use
|
|
4102
4616
|
* immortal templates. Static initialization remains limited to whole top-level
|
|
@@ -4123,19 +4637,21 @@ export function lowerClassExpressionInfo(lowerer, expr) {
|
|
|
4123
4637
|
if (ts.isFunctionLike(p))
|
|
4124
4638
|
local = true;
|
|
4125
4639
|
}
|
|
4126
|
-
if (local &&
|
|
4640
|
+
if (local &&
|
|
4641
|
+
expr.members.nodes.some((member) => member.name && ts.isPrivateIdentifier(member.name)) &&
|
|
4642
|
+
!localPrivateFieldsAgree(expr)) {
|
|
4127
4643
|
lowerer.unsupported("SC1090", expr, "function-local classes with private brands");
|
|
4128
4644
|
}
|
|
4129
4645
|
if (local &&
|
|
4130
|
-
(expr.typeParameters?.length ||
|
|
4646
|
+
(expr.typeParameters?.nodes.length ||
|
|
4131
4647
|
decoratorNodesOf(expr).length ||
|
|
4132
|
-
expr.members.some((member) => decoratorNodesOf(member).length ||
|
|
4133
|
-
(!isJsSourceFile(
|
|
4648
|
+
expr.members.nodes.some((member) => decoratorNodesOf(member).length ||
|
|
4649
|
+
(!isJsSourceFile(ts.getSourceFileOfNode(expr)) &&
|
|
4134
4650
|
(ts.isClassStaticBlockDeclaration(member) ||
|
|
4135
4651
|
ts
|
|
4136
4652
|
.getModifiers(member)
|
|
4137
4653
|
?.some((modifier) => modifier.kind === ts.SyntaxKind.StaticKeyword))) ||
|
|
4138
|
-
(ts.isMethodDeclaration(member) && member.typeParameters?.length)))) {
|
|
4654
|
+
(ts.isMethodDeclaration(member) && member.typeParameters?.nodes.length)))) {
|
|
4139
4655
|
lowerer.unsupported("SC1090", expr, "function-local classes with statics, decorators, or generic members");
|
|
4140
4656
|
}
|
|
4141
4657
|
lowerer.collectingExprClasses.add(expr);
|
|
@@ -4143,7 +4659,7 @@ export function lowerClassExpressionInfo(lowerer, expr) {
|
|
|
4143
4659
|
if (local &&
|
|
4144
4660
|
lowerer.fnStack.length > 0 &&
|
|
4145
4661
|
!lowerer.computedClassBases.has(lowerer.classNamer(expr))) {
|
|
4146
|
-
const heritage = expr.heritageClauses?.find((clause) => clause.token === ts.SyntaxKind.ExtendsKeyword)?.types[0]?.expression;
|
|
4662
|
+
const heritage = expr.heritageClauses?.nodes.find((clause) => clause.token === ts.SyntaxKind.ExtendsKeyword)?.types?.nodes[0]?.expression;
|
|
4147
4663
|
if (heritage &&
|
|
4148
4664
|
(ts.isCallExpression(heritage) ||
|
|
4149
4665
|
(ts.isIdentifier(heritage) &&
|
|
@@ -4175,7 +4691,7 @@ export function lowerClassExpressionInfo(lowerer, expr) {
|
|
|
4175
4691
|
});
|
|
4176
4692
|
info.localClass = { context: null, bodies: new Map(), captureSources: [], ready: false };
|
|
4177
4693
|
if (info.base?.localClass) {
|
|
4178
|
-
const baseExpression = expr.heritageClauses?.find((clause) => clause.token === ts.SyntaxKind.ExtendsKeyword)?.types[0]?.expression;
|
|
4694
|
+
const baseExpression = expr.heritageClauses?.nodes.find((clause) => clause.token === ts.SyntaxKind.ExtendsKeyword)?.types?.nodes[0]?.expression;
|
|
4179
4695
|
if (baseExpression)
|
|
4180
4696
|
info.localClass.baseExpression = baseExpression;
|
|
4181
4697
|
}
|
|
@@ -4206,7 +4722,7 @@ export function lowerClassExpressionInfo(lowerer, expr) {
|
|
|
4206
4722
|
const wholeInit = (ts.isVariableDeclaration(holder) &&
|
|
4207
4723
|
holder.initializer !== undefined &&
|
|
4208
4724
|
ts.isVariableDeclarationList(holder.parent) &&
|
|
4209
|
-
holder.parent.declarations.length === 1 &&
|
|
4725
|
+
holder.parent.declarations.nodes.length === 1 &&
|
|
4210
4726
|
ts.isVariableStatement(holder.parent.parent) &&
|
|
4211
4727
|
ts.isSourceFile(holder.parent.parent.parent)) ||
|
|
4212
4728
|
(ts.isBinaryExpression(holder) &&
|
|
@@ -4230,8 +4746,8 @@ export function lowerClassExpressionInfo(lowerer, expr) {
|
|
|
4230
4746
|
* the member fences don't apply. */
|
|
4231
4747
|
export function lowerClassExpression(lowerer, expr) {
|
|
4232
4748
|
if (decoratorNodesOf(expr).length > 0 ||
|
|
4233
|
-
expr.members.some((m) => decoratorNodesOf(m).length > 0)) {
|
|
4234
|
-
if (!isJsSourceFile(
|
|
4749
|
+
expr.members.nodes.some((m) => decoratorNodesOf(m).length > 0)) {
|
|
4750
|
+
if (!isJsSourceFile(ts.getSourceFileOfNode(expr)) && expr.typeParameters === undefined) {
|
|
4235
4751
|
const thrown = guaranteedDecorationThrow(lowerer, expr);
|
|
4236
4752
|
if (thrown) {
|
|
4237
4753
|
// The expression's static type never materializes — the read
|
|
@@ -4413,7 +4929,7 @@ export function exactClassOfReceiver(lowerer, expr) {
|
|
|
4413
4929
|
// class-value write fence answers instead.
|
|
4414
4930
|
if (direct)
|
|
4415
4931
|
return direct.classDecorators?.valueGlobalId !== undefined ? null : direct;
|
|
4416
|
-
const decl =
|
|
4932
|
+
const decl = symbol.valueDeclaration;
|
|
4417
4933
|
if (!decl ||
|
|
4418
4934
|
!ts.isVariableDeclaration(decl) ||
|
|
4419
4935
|
decl.initializer === undefined ||
|
|
@@ -4457,7 +4973,7 @@ export function propertyAssignedClassInfoOf(lowerer, symbol) {
|
|
|
4457
4973
|
const registered = lowerer.classBySymbol.get(resolved);
|
|
4458
4974
|
if (registered)
|
|
4459
4975
|
return registered;
|
|
4460
|
-
const decls =
|
|
4976
|
+
const decls = resolved.declarations;
|
|
4461
4977
|
// The class expression's OWN symbol (tsgo's answer through CJS export
|
|
4462
4978
|
// aliases): the declaration is the expression itself. Its top-level
|
|
4463
4979
|
// assignment statement must be the binding's ONLY producer. The
|
|
@@ -4511,17 +5027,17 @@ function enclosingTopLevelClassAssignment(expr) {
|
|
|
4511
5027
|
* `Common.I`): a second assignment makes the binding dynamic, so
|
|
4512
5028
|
* callers refuse to pin the first one's class. */
|
|
4513
5029
|
function countAssignmentsTo(assign) {
|
|
4514
|
-
const sf =
|
|
5030
|
+
const sf = ts.getSourceFileOfNode(assign);
|
|
4515
5031
|
// `exports.I` and `module.exports.I` are the SAME binding in Node
|
|
4516
5032
|
// (exports aliases module.exports until a table replaces it) — fold
|
|
4517
5033
|
// the member spellings together before comparing.
|
|
4518
5034
|
const canon = (lhs) => {
|
|
4519
|
-
const text =
|
|
5035
|
+
const text = ts.getTextOfNode(lhs).replace(/\s+/g, "");
|
|
4520
5036
|
return text.startsWith("module.exports.") ? text.slice("module.".length) : text;
|
|
4521
5037
|
};
|
|
4522
5038
|
const target = canon(assign.left);
|
|
4523
5039
|
let n = 0;
|
|
4524
|
-
for (const stmt of sf.statements) {
|
|
5040
|
+
for (const stmt of sf.statements.nodes) {
|
|
4525
5041
|
if (!ts.isExpressionStatement(stmt))
|
|
4526
5042
|
continue;
|
|
4527
5043
|
const e = stmt.expression;
|
|
@@ -4569,9 +5085,9 @@ export function lowerStaticMethodCall(lowerer, call, access) {
|
|
|
4569
5085
|
// export assignment pins it) — the direct-name rules apply.
|
|
4570
5086
|
if (!ts.isIdentifier(access.expression)) {
|
|
4571
5087
|
if (!isModuleExportsAccess(access.expression) ||
|
|
4572
|
-
!isCjsJsFile(
|
|
5088
|
+
!isCjsJsFile(ts.getSourceFileOfNode(access), lowerer.program)) {
|
|
4573
5089
|
let receiverType = lowerer.mapTypeOf(lowerer.typeOf(access.expression));
|
|
4574
|
-
if (receiverType?.kind !== "classval" && isJsSourceFile(
|
|
5090
|
+
if (receiverType?.kind !== "classval" && isJsSourceFile(ts.getSourceFileOfNode(call))) {
|
|
4575
5091
|
const receiver = tryLowerExpression(lowerer, access.expression);
|
|
4576
5092
|
if (receiver?.type.kind === "classval")
|
|
4577
5093
|
receiverType = receiver.type;
|
|
@@ -4596,7 +5112,7 @@ export function lowerStaticMethodCall(lowerer, call, access) {
|
|
|
4596
5112
|
loc: locOf(call),
|
|
4597
5113
|
};
|
|
4598
5114
|
}
|
|
4599
|
-
const whole = cjsClassExprWholeExportOf(
|
|
5115
|
+
const whole = cjsClassExprWholeExportOf(ts.getSourceFileOfNode(access));
|
|
4600
5116
|
if (!whole)
|
|
4601
5117
|
return null;
|
|
4602
5118
|
return staticCallOn(lowerer, call, access, lowerer.lowerClassExpressionInfo(whole.classExpr), false);
|
|
@@ -4637,6 +5153,9 @@ function classValueIsExactlyOwn(lowerer, recv, info) {
|
|
|
4637
5153
|
}
|
|
4638
5154
|
function staticCallOn(lowerer, call, access, info, throughValue) {
|
|
4639
5155
|
const loc = locOf(call);
|
|
5156
|
+
const runtimeStatic = directRuntimeStaticCall(lowerer, call, access, info, throughValue);
|
|
5157
|
+
if (runtimeStatic)
|
|
5158
|
+
return runtimeStatic;
|
|
4640
5159
|
if ((hasRuntimeStatics(info) && !findStaticOn(lowerer, info, access.name.text)?.field) ||
|
|
4641
5160
|
(info.callableBase &&
|
|
4642
5161
|
!findStaticOn(lowerer, info, access.name.text) &&
|
|
@@ -4646,7 +5165,7 @@ function staticCallOn(lowerer, call, access, info, throughValue) {
|
|
|
4646
5165
|
recv: lowerer.lowerExprExpecting(access.expression, DYN),
|
|
4647
5166
|
method: access.name.text,
|
|
4648
5167
|
calleeName: access.name.text,
|
|
4649
|
-
args: call.arguments.map((argument) => lowerer.lowerExprExpecting(argument, DYN)),
|
|
5168
|
+
args: call.arguments.nodes.map((argument) => lowerer.lowerExprExpecting(argument, DYN)),
|
|
4650
5169
|
type: DYN,
|
|
4651
5170
|
loc,
|
|
4652
5171
|
};
|
|
@@ -4676,7 +5195,7 @@ function staticCallOn(lowerer, call, access, info, throughValue) {
|
|
|
4676
5195
|
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
5196
|
}
|
|
4678
5197
|
const instance = genericCallInstance(lowerer, call, staticMethodForReceiver(lowerer, access, gfound.info, info, throughValue));
|
|
4679
|
-
const args = lowerer.completeArgs(call.arguments, instance.params, loc, call);
|
|
5198
|
+
const args = lowerer.completeArgs(call.arguments.nodes, instance.params, loc, call);
|
|
4680
5199
|
return { kind: "call", callee: instance.name, args, type: instance.returnType, loc };
|
|
4681
5200
|
}
|
|
4682
5201
|
if (throughValue && staticShadowBelow(info, access.name.text)) {
|
|
@@ -4685,7 +5204,7 @@ function staticCallOn(lowerer, call, access, info, throughValue) {
|
|
|
4685
5204
|
const specialized = findGenericStaticOn(lowerer, info, access.name.text);
|
|
4686
5205
|
if (specialized?.declarer === found.declarer && specialized.info.implicitParams) {
|
|
4687
5206
|
const instance = implicitCallInstance(lowerer, call, staticMethodForReceiver(lowerer, access, specialized.info, info, throughValue));
|
|
4688
|
-
const args = lowerer.completeArgs(call.arguments, instance.params, loc, call);
|
|
5207
|
+
const args = lowerer.completeArgs(call.arguments.nodes, instance.params, loc, call);
|
|
4689
5208
|
return { kind: "call", callee: instance.name, args, type: instance.returnType, loc };
|
|
4690
5209
|
}
|
|
4691
5210
|
if (found.field !== undefined) {
|
|
@@ -4700,7 +5219,7 @@ function staticCallOn(lowerer, call, access, info, throughValue) {
|
|
|
4700
5219
|
loc,
|
|
4701
5220
|
};
|
|
4702
5221
|
const params = found.field.type.params;
|
|
4703
|
-
const args = call.arguments.map((a, i) => lowerer.lowerExprExpecting(a, params[i]));
|
|
5222
|
+
const args = call.arguments.nodes.map((a, i) => lowerer.lowerExprExpecting(a, params[i]));
|
|
4704
5223
|
for (let i = args.length; i < params.length; i++) {
|
|
4705
5224
|
const absent = omittedArgFor(lowerer, params[i], loc);
|
|
4706
5225
|
if (!absent) {
|
|
@@ -4730,16 +5249,184 @@ function staticCallOn(lowerer, call, access, info, throughValue) {
|
|
|
4730
5249
|
return {
|
|
4731
5250
|
kind: "call",
|
|
4732
5251
|
callee: instance.name,
|
|
4733
|
-
args: lowerer.completeArgs(call.arguments, instance.params, loc, call),
|
|
5252
|
+
args: lowerer.completeArgs(call.arguments.nodes, instance.params, loc, call),
|
|
4734
5253
|
type: instance.returnType,
|
|
4735
5254
|
loc,
|
|
4736
5255
|
};
|
|
4737
5256
|
}
|
|
4738
5257
|
const fnName = `%${found.declarer.def.name}.static:${access.name.text}`;
|
|
4739
5258
|
lowerer.noteEdge(fnName);
|
|
4740
|
-
const args = lowerer.completeArgs(call.arguments, found.method.params, loc, call);
|
|
5259
|
+
const args = lowerer.completeArgs(call.arguments.nodes, found.method.params, loc, call);
|
|
4741
5260
|
return { kind: "call", callee: fnName, args, type: found.method.ret, loc };
|
|
4742
5261
|
}
|
|
5262
|
+
/** `C.m(...)` where `m` is a static method that a function-local
|
|
5263
|
+
* JavaScript class defines at runtime (a factory's `class extends base`),
|
|
5264
|
+
* inherited by `C` through its statically known base chain. When the body
|
|
5265
|
+
* captures nothing from the factory's scope, every evaluation of the class
|
|
5266
|
+
* defines the same method, so the call lowers directly with `this` bound
|
|
5267
|
+
* to `C`, as a free function given `C` would. A receiver-dependent result
|
|
5268
|
+
* (a class built from `this`) then keeps a static base. Null when another
|
|
5269
|
+
* declaration of `m` answers first, the program assigns that member, or
|
|
5270
|
+
* the method form has no direct lowering. */
|
|
5271
|
+
function directRuntimeStaticCall(lowerer, call, access, info, throughValue) {
|
|
5272
|
+
const name = access.name.text;
|
|
5273
|
+
if (throughValue || name.startsWith("#"))
|
|
5274
|
+
return null;
|
|
5275
|
+
let declarer = null;
|
|
5276
|
+
let member = null;
|
|
5277
|
+
for (let c = info; c; c = c.base) {
|
|
5278
|
+
if (c.staticFields.some((field) => field.name === name) ||
|
|
5279
|
+
c.staticMethods?.has(name) === true ||
|
|
5280
|
+
c.genericStatics?.has(name) === true)
|
|
5281
|
+
return null;
|
|
5282
|
+
const runtime = c.runtimeStatics?.find((element) => element.name !== undefined &&
|
|
5283
|
+
ts.isIdentifier(element.name) &&
|
|
5284
|
+
element.name.text === name);
|
|
5285
|
+
if (runtime) {
|
|
5286
|
+
if (!ts.isMethodDeclaration(runtime) || !runtime.body)
|
|
5287
|
+
return null;
|
|
5288
|
+
declarer = c;
|
|
5289
|
+
member = runtime;
|
|
5290
|
+
break;
|
|
5291
|
+
}
|
|
5292
|
+
}
|
|
5293
|
+
if (!declarer || !member || !declarer.decl)
|
|
5294
|
+
return null;
|
|
5295
|
+
if (member.asteriskToken || member.typeParameters?.nodes)
|
|
5296
|
+
return null;
|
|
5297
|
+
if (member.modifiers?.nodes.some((modifier) => modifier.kind === ts.SyntaxKind.AsyncKeyword))
|
|
5298
|
+
return null;
|
|
5299
|
+
if (hasLexicalSuper(member) || capturesEnclosingScope(lowerer, member, declarer.decl))
|
|
5300
|
+
return null;
|
|
5301
|
+
if (memberAssigned(lowerer, member, name) || bodyReadsArguments(member))
|
|
5302
|
+
return null;
|
|
5303
|
+
const implicit = member.parameters.nodes.length === 0 ? null : implicitAnyParamSymbolsOf(lowerer, member, true);
|
|
5304
|
+
if (member.parameters.nodes.length > 0 && !implicit)
|
|
5305
|
+
return null;
|
|
5306
|
+
let calls = declarer.runtimeStaticCalls;
|
|
5307
|
+
if (!calls) {
|
|
5308
|
+
calls = new Map();
|
|
5309
|
+
declarer.runtimeStaticCalls = calls;
|
|
5310
|
+
}
|
|
5311
|
+
const method = calls.get(name) ?? {
|
|
5312
|
+
decl: member,
|
|
5313
|
+
baseName: name,
|
|
5314
|
+
qualifiedName: `%${declarer.def.name}.runtimeStatic:${name}`,
|
|
5315
|
+
typeParams: [],
|
|
5316
|
+
instances: new Map(),
|
|
5317
|
+
member: { cls: declarer, kind: "static" },
|
|
5318
|
+
...(implicit ? { implicitParams: implicit } : {}),
|
|
5319
|
+
};
|
|
5320
|
+
calls.set(name, method);
|
|
5321
|
+
// A direct lowering the method form does not support keeps the dynamic
|
|
5322
|
+
// call: its refusal is not this program's error.
|
|
5323
|
+
const sink = [];
|
|
5324
|
+
const previousSink = lowerer.diagSink;
|
|
5325
|
+
lowerer.diagSink = sink;
|
|
5326
|
+
let lowered;
|
|
5327
|
+
try {
|
|
5328
|
+
const receiver = staticMethodForReceiver(lowerer, access, method, info, false);
|
|
5329
|
+
const instance = implicit
|
|
5330
|
+
? implicitCallInstance(lowerer, call, receiver)
|
|
5331
|
+
: genericCallInstance(lowerer, call, receiver);
|
|
5332
|
+
lowered = {
|
|
5333
|
+
kind: "call",
|
|
5334
|
+
callee: instance.name,
|
|
5335
|
+
args: lowerer.completeArgs(call.arguments.nodes, instance.params, locOf(call), call),
|
|
5336
|
+
type: instance.returnType,
|
|
5337
|
+
loc: locOf(call),
|
|
5338
|
+
};
|
|
5339
|
+
}
|
|
5340
|
+
catch (error) {
|
|
5341
|
+
if (error instanceof PoisonError)
|
|
5342
|
+
return null;
|
|
5343
|
+
throw error;
|
|
5344
|
+
}
|
|
5345
|
+
finally {
|
|
5346
|
+
lowerer.diagSink = previousSink;
|
|
5347
|
+
}
|
|
5348
|
+
return sink.length === 0 ? lowered : null;
|
|
5349
|
+
}
|
|
5350
|
+
/** `super` inside the method (arrows included) names the defining
|
|
5351
|
+
* class's base, which a receiver specialization does not track. */
|
|
5352
|
+
function hasLexicalSuper(root) {
|
|
5353
|
+
let found = false;
|
|
5354
|
+
const visit = (node) => {
|
|
5355
|
+
if (node.kind === ts.SyntaxKind.SuperKeyword)
|
|
5356
|
+
found = true;
|
|
5357
|
+
if ((ts.isFunctionLike(node) && !ts.isArrowFunction(node)) ||
|
|
5358
|
+
ts.isClassDeclaration(node) ||
|
|
5359
|
+
ts.isClassExpression(node))
|
|
5360
|
+
return;
|
|
5361
|
+
ts.forEachChild(node, visit);
|
|
5362
|
+
};
|
|
5363
|
+
ts.forEachChild(root, visit);
|
|
5364
|
+
return found;
|
|
5365
|
+
}
|
|
5366
|
+
/** The method reads a binding declared in a function that encloses its
|
|
5367
|
+
* class: each evaluation of the class can see a different value. */
|
|
5368
|
+
function capturesEnclosingScope(lowerer, member, classDecl) {
|
|
5369
|
+
let scope = classDecl.parent;
|
|
5370
|
+
while (scope && !ts.isFunctionLike(scope) && !ts.isSourceFile(scope))
|
|
5371
|
+
scope = scope.parent;
|
|
5372
|
+
if (!scope || ts.isSourceFile(scope))
|
|
5373
|
+
return false;
|
|
5374
|
+
const inside = (node, container) => {
|
|
5375
|
+
for (let n = node; n; n = n.parent)
|
|
5376
|
+
if (n === container)
|
|
5377
|
+
return true;
|
|
5378
|
+
return false;
|
|
5379
|
+
};
|
|
5380
|
+
let captured = false;
|
|
5381
|
+
const visit = (node) => {
|
|
5382
|
+
if (captured)
|
|
5383
|
+
return;
|
|
5384
|
+
if (ts.isIdentifier(node)) {
|
|
5385
|
+
const symbol = lowerer.checker.getSymbolAtLocation(node);
|
|
5386
|
+
const decl = symbol ? symbol.valueDeclaration : undefined;
|
|
5387
|
+
// The enclosing function's own name is the same binding for every
|
|
5388
|
+
// evaluation.
|
|
5389
|
+
if (decl && decl !== scope && inside(decl, scope) && !inside(decl, member))
|
|
5390
|
+
captured = true;
|
|
5391
|
+
return;
|
|
5392
|
+
}
|
|
5393
|
+
ts.forEachChild(node, visit);
|
|
5394
|
+
};
|
|
5395
|
+
ts.forEachChild(member, visit);
|
|
5396
|
+
return captured;
|
|
5397
|
+
}
|
|
5398
|
+
/** Some code assigns or deletes a member of this name, or defines it by
|
|
5399
|
+
* reflection: the member a runtime lookup finds can then differ. */
|
|
5400
|
+
function memberAssigned(lowerer, member, name) {
|
|
5401
|
+
let found = false;
|
|
5402
|
+
for (const sf of lowerer.program.getSourceFiles()) {
|
|
5403
|
+
if (sf.isDeclarationFile || found)
|
|
5404
|
+
continue;
|
|
5405
|
+
if (!sf.text.includes(name))
|
|
5406
|
+
continue;
|
|
5407
|
+
ts.walkPreorder(sf, (node) => {
|
|
5408
|
+
if (found)
|
|
5409
|
+
return "skip";
|
|
5410
|
+
if (ts.isPropertyAccessExpression(node) && node.name.text === name) {
|
|
5411
|
+
const parent = node.parent;
|
|
5412
|
+
if (parent &&
|
|
5413
|
+
((ts.isBinaryExpression(parent) &&
|
|
5414
|
+
parent.left === node &&
|
|
5415
|
+
parent.operatorToken.kind >= ts.SyntaxKind.FirstAssignment &&
|
|
5416
|
+
parent.operatorToken.kind <= ts.SyntaxKind.LastAssignment) ||
|
|
5417
|
+
ts.isDeleteExpression(parent)))
|
|
5418
|
+
found = true;
|
|
5419
|
+
}
|
|
5420
|
+
if (ts.isStringLiteral(node) && node.text === name && node !== member.name) {
|
|
5421
|
+
const parent = node.parent;
|
|
5422
|
+
if (parent && (ts.isCallExpression(parent) || ts.isElementAccessExpression(parent)))
|
|
5423
|
+
found = true;
|
|
5424
|
+
}
|
|
5425
|
+
return undefined;
|
|
5426
|
+
});
|
|
5427
|
+
}
|
|
5428
|
+
return found;
|
|
5429
|
+
}
|
|
4743
5430
|
function staticMethodForReceiver(lowerer, access, method, receiver, throughValue) {
|
|
4744
5431
|
if (!hasStaticThis(method.decl))
|
|
4745
5432
|
return method;
|
|
@@ -4782,6 +5469,10 @@ export function lowerClassValueProperty(lowerer, expr) {
|
|
|
4782
5469
|
const loc = locOf(expr);
|
|
4783
5470
|
const member = expr.name.text;
|
|
4784
5471
|
const info = lowerer.classes.get(recvT.className);
|
|
5472
|
+
// A runtime-provided class value answers `.name` from its class object;
|
|
5473
|
+
// its other statics (`Error.stackTraceLimit`) keep their own lowerings.
|
|
5474
|
+
if (info?.def.runtime && member !== "name")
|
|
5475
|
+
return null;
|
|
4785
5476
|
if (info &&
|
|
4786
5477
|
((hasRuntimeStatics(info) && !findStaticOn(lowerer, info, member)?.field) ||
|
|
4787
5478
|
(info.callableBase && !findStaticOn(lowerer, info, member))))
|
|
@@ -4808,7 +5499,8 @@ export function lowerClassValueProperty(lowerer, expr) {
|
|
|
4808
5499
|
// `module.exports.label` in a class-replaced CJS module: the
|
|
4809
5500
|
// receiver is the exact exported class, and the read is
|
|
4810
5501
|
// side-effect-free — as bindable as an identifier.
|
|
4811
|
-
!(isModuleExportsAccess(expr.expression) &&
|
|
5502
|
+
!(isModuleExportsAccess(expr.expression) &&
|
|
5503
|
+
isCjsJsFile(ts.getSourceFileOfNode(expr), lowerer.program))) {
|
|
4812
5504
|
// Devirtualized reads DISCARD the receiver value, so only
|
|
4813
5505
|
// side-effect-free receivers are claimed (the instanceOf fold
|
|
4814
5506
|
// rule); computed ones meet the pointed fence with a bindable fix.
|
|
@@ -4855,19 +5547,49 @@ export function lowerClassValueProperty(lowerer, expr) {
|
|
|
4855
5547
|
* async/generator/generic-with-body combinations before this runs, and
|
|
4856
5548
|
* the generic case fences at the caller). */
|
|
4857
5549
|
function abstractMemberSignature(lowerer, member) {
|
|
4858
|
-
for (const param of member.parameters) {
|
|
5550
|
+
for (const param of member.parameters.nodes) {
|
|
4859
5551
|
if (!ts.isIdentifier(param.name))
|
|
4860
5552
|
lowerer.unsupported("SC1031", param);
|
|
4861
5553
|
}
|
|
4862
5554
|
return {
|
|
4863
|
-
shapes: lowerer.paramShapes(member.parameters),
|
|
5555
|
+
shapes: lowerer.paramShapes(member.parameters.nodes),
|
|
4864
5556
|
ret: lowerer.declaredReturnType(member, member.name),
|
|
4865
5557
|
};
|
|
4866
5558
|
}
|
|
4867
5559
|
/** A nominal return subtype uses the same owned pointer as the inherited
|
|
4868
5560
|
* return slot. The current class is still being collected, so consult its
|
|
4869
5561
|
* already collected base chain before the complete class graph is available. */
|
|
5562
|
+
/** An inherited ASYNC method that an override now dispatches against: its
|
|
5563
|
+
* slot becomes a plain function returning the body's promise, and the
|
|
5564
|
+
* async body lowers behind it as `%C.m$own` (the adapter path with an
|
|
5565
|
+
* identity conversion), so a virtual call never enters an async body
|
|
5566
|
+
* without its spawn wrapper. */
|
|
5567
|
+
function thunkAsyncSlot(overridden, mName) {
|
|
5568
|
+
if (overridden.sig.async !== true)
|
|
5569
|
+
return;
|
|
5570
|
+
const declarer = overridden.declarer;
|
|
5571
|
+
declarer.returnAdapters ??= new Map();
|
|
5572
|
+
if (!declarer.returnAdapters.has(mName)) {
|
|
5573
|
+
declarer.returnAdapters.set(mName, {
|
|
5574
|
+
params: [...overridden.sig.params],
|
|
5575
|
+
ret: overridden.sig.ret,
|
|
5576
|
+
async: true,
|
|
5577
|
+
});
|
|
5578
|
+
}
|
|
5579
|
+
delete overridden.sig.async;
|
|
5580
|
+
}
|
|
4870
5581
|
function overrideReturnAbi(lowerer, declared, inherited, className, base) {
|
|
5582
|
+
// A return narrowed to part of an inherited union (`Meta` for
|
|
5583
|
+
// `Meta | undefined`) keeps the union ABI; returns convert into it.
|
|
5584
|
+
if (inherited.kind === "union" && !typeEquals(declared, inherited)) {
|
|
5585
|
+
const arms = lowerer.unions.get(inherited.unionId)?.arms ?? [];
|
|
5586
|
+
const fits = (type) => arms.some((arm) => typeEquals(arm, type) ||
|
|
5587
|
+
(arm.kind === "object" &&
|
|
5588
|
+
type.kind === "object" &&
|
|
5589
|
+
lowerer.isSubclassOf(type.className, arm.className)));
|
|
5590
|
+
const parts = declared.kind === "union" ? (lowerer.unions.get(declared.unionId)?.arms ?? []) : [declared];
|
|
5591
|
+
return parts.length > 0 && parts.every(fits) ? inherited : declared;
|
|
5592
|
+
}
|
|
4871
5593
|
if (declared.kind !== "object" || inherited.kind !== "object")
|
|
4872
5594
|
return declared;
|
|
4873
5595
|
if (lowerer.isSubclassOf(declared.className, inherited.className) ||
|
|
@@ -4947,7 +5669,7 @@ export function collectInheritedJsFieldWrites(lowerer, files) {
|
|
|
4947
5669
|
continue;
|
|
4948
5670
|
ts.walkPreorder(file, (node) => {
|
|
4949
5671
|
if ((!ts.isClassDeclaration(node) && !ts.isClassExpression(node)) ||
|
|
4950
|
-
!node.heritageClauses?.length)
|
|
5672
|
+
!node.heritageClauses?.nodes.length)
|
|
4951
5673
|
return;
|
|
4952
5674
|
const writes = new Map();
|
|
4953
5675
|
const addWrite = (name, expression) => {
|
|
@@ -4974,10 +5696,10 @@ export function collectInheritedJsFieldWrites(lowerer, files) {
|
|
|
4974
5696
|
addWrite(name, part.right);
|
|
4975
5697
|
}
|
|
4976
5698
|
}
|
|
4977
|
-
|
|
5699
|
+
ts.forEachChild(part, scan);
|
|
4978
5700
|
};
|
|
4979
|
-
for (const member of node.members) {
|
|
4980
|
-
if (member.modifiers?.some((modifier) => modifier.kind === ts.SyntaxKind.StaticKeyword))
|
|
5701
|
+
for (const member of node.members.nodes) {
|
|
5702
|
+
if (member.modifiers?.nodes.some((modifier) => modifier.kind === ts.SyntaxKind.StaticKeyword))
|
|
4981
5703
|
continue;
|
|
4982
5704
|
if (ts.isPropertyDeclaration(member) && member.initializer) {
|
|
4983
5705
|
const name = ts.isPrivateIdentifier(member.name)
|
|
@@ -5007,7 +5729,7 @@ export function collectInheritedJsFieldWrites(lowerer, files) {
|
|
|
5007
5729
|
for (const base of lowerer.checker.getBaseTypes(target)) {
|
|
5008
5730
|
for (const [name, expressions] of writes) {
|
|
5009
5731
|
const property = lowerer.checker.getPropertyOfType(base, name);
|
|
5010
|
-
for (const declaration of property ?
|
|
5732
|
+
for (const declaration of property ? property.declarations : []) {
|
|
5011
5733
|
if (ts.isMethodDeclaration(declaration) || ts.isAccessor(declaration))
|
|
5012
5734
|
continue;
|
|
5013
5735
|
let owner = declaration.parent;
|
|
@@ -5015,7 +5737,7 @@ export function collectInheritedJsFieldWrites(lowerer, files) {
|
|
|
5015
5737
|
owner = owner.parent;
|
|
5016
5738
|
if (!owner ||
|
|
5017
5739
|
(!ts.isClassDeclaration(owner) && !ts.isClassExpression(owner)) ||
|
|
5018
|
-
!isJsSourceFile(
|
|
5740
|
+
!isJsSourceFile(ts.getSourceFileOfNode(owner)))
|
|
5019
5741
|
continue;
|
|
5020
5742
|
let fields = lowerer.inheritedJsFieldWrites.get(owner);
|
|
5021
5743
|
if (!fields)
|
|
@@ -5041,15 +5763,15 @@ export function collectInheritedJsFieldWrites(lowerer, files) {
|
|
|
5041
5763
|
* hierarchy identifies the original declarations through aliases as well. */
|
|
5042
5764
|
export function collectVirtualJsMethods(lowerer, files) {
|
|
5043
5765
|
const families = [];
|
|
5044
|
-
collectClassMethodMutations(lowerer, files);
|
|
5766
|
+
lowerer.speculativeTypeQueries(() => collectClassMethodMutations(lowerer, files));
|
|
5045
5767
|
const visit = (node) => {
|
|
5046
5768
|
if (ts.isClassDeclaration(node) || ts.isClassExpression(node)) {
|
|
5047
|
-
const accessors = node.members.filter((member) => (ts.isGetAccessorDeclaration(member) || ts.isSetAccessorDeclaration(member)) &&
|
|
5769
|
+
const accessors = node.members.nodes.filter((member) => (ts.isGetAccessorDeclaration(member) || ts.isSetAccessorDeclaration(member)) &&
|
|
5048
5770
|
ts.isIdentifier(member.name) &&
|
|
5049
|
-
!member.modifiers?.some((modifier) => modifier.kind === ts.SyntaxKind.StaticKeyword));
|
|
5050
|
-
if (node.heritageClauses?.length &&
|
|
5771
|
+
!member.modifiers?.nodes.some((modifier) => modifier.kind === ts.SyntaxKind.StaticKeyword));
|
|
5772
|
+
if (node.heritageClauses?.nodes.length &&
|
|
5051
5773
|
accessors.length &&
|
|
5052
|
-
isJsSourceFile(
|
|
5774
|
+
isJsSourceFile(ts.getSourceFileOfNode(node))) {
|
|
5053
5775
|
const symbol = lowerer.typeOf(node).getSymbol();
|
|
5054
5776
|
const instance = symbol ? lowerer.checker.getDeclaredTypeOfSymbol(symbol) : null;
|
|
5055
5777
|
const seen = new Set();
|
|
@@ -5063,13 +5785,13 @@ export function collectVirtualJsMethods(lowerer, files) {
|
|
|
5063
5785
|
if (!ts.isIdentifier(member.name))
|
|
5064
5786
|
continue;
|
|
5065
5787
|
const property = lowerer.checker.getPropertyOfType(base, member.name.text);
|
|
5066
|
-
for (const declaration of property ?
|
|
5788
|
+
for (const declaration of property ? property.declarations : []) {
|
|
5067
5789
|
if ((ts.isGetAccessorDeclaration(declaration) ||
|
|
5068
5790
|
ts.isSetAccessorDeclaration(declaration)) &&
|
|
5069
|
-
isJsSourceFile(
|
|
5791
|
+
isJsSourceFile(ts.getSourceFileOfNode(declaration))) {
|
|
5070
5792
|
lowerer.checkedVirtualJsAccessors.add(declaration);
|
|
5071
5793
|
lowerer.checkedVirtualJsAccessors.add(member);
|
|
5072
|
-
for (const twin of node.members)
|
|
5794
|
+
for (const twin of node.members.nodes)
|
|
5073
5795
|
if ((ts.isGetAccessorDeclaration(twin) || ts.isSetAccessorDeclaration(twin)) &&
|
|
5074
5796
|
ts.isIdentifier(twin.name) &&
|
|
5075
5797
|
twin.name.text === member.name.text)
|
|
@@ -5083,10 +5805,10 @@ export function collectVirtualJsMethods(lowerer, files) {
|
|
|
5083
5805
|
if (instance)
|
|
5084
5806
|
markAccessors(instance);
|
|
5085
5807
|
}
|
|
5086
|
-
const members = node.members.filter((member) => ts.isMethodDeclaration(member) &&
|
|
5808
|
+
const members = node.members.nodes.filter((member) => ts.isMethodDeclaration(member) &&
|
|
5087
5809
|
ts.isIdentifier(member.name) &&
|
|
5088
|
-
!member.modifiers?.some((modifier) => modifier.kind === ts.SyntaxKind.StaticKeyword));
|
|
5089
|
-
if (node.heritageClauses?.length && members.length > 0) {
|
|
5810
|
+
!member.modifiers?.nodes.some((modifier) => modifier.kind === ts.SyntaxKind.StaticKeyword));
|
|
5811
|
+
if (node.heritageClauses?.nodes.length && members.length > 0) {
|
|
5090
5812
|
const symbol = lowerer.typeOf(node).getSymbol();
|
|
5091
5813
|
const instance = symbol ? lowerer.checker.getDeclaredTypeOfSymbol(symbol) : null;
|
|
5092
5814
|
const seen = new Set();
|
|
@@ -5100,22 +5822,23 @@ export function collectVirtualJsMethods(lowerer, files) {
|
|
|
5100
5822
|
if (!ts.isIdentifier(member.name))
|
|
5101
5823
|
continue;
|
|
5102
5824
|
const property = lowerer.checker.getPropertyOfType(base, member.name.text);
|
|
5103
|
-
for (const declaration of property ?
|
|
5825
|
+
for (const declaration of property ? property.declarations : []) {
|
|
5104
5826
|
if (ts.isMethodDeclaration(declaration) &&
|
|
5105
|
-
isJsSourceFile(
|
|
5827
|
+
isJsSourceFile(ts.getSourceFileOfNode(declaration)) &&
|
|
5828
|
+
!checkedJsOverride(lowerer, declaration, member)) {
|
|
5106
5829
|
lowerer.virtualJsMethods.add(declaration);
|
|
5107
|
-
if (isJsSourceFile(
|
|
5108
|
-
!member.typeParameters &&
|
|
5830
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(member)) &&
|
|
5831
|
+
!member.typeParameters?.nodes &&
|
|
5109
5832
|
!member.asteriskToken &&
|
|
5110
|
-
!member.modifiers?.some((m) => m.kind === ts.SyntaxKind.AsyncKeyword) &&
|
|
5833
|
+
!member.modifiers?.nodes.some((m) => m.kind === ts.SyntaxKind.AsyncKeyword) &&
|
|
5111
5834
|
!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 &&
|
|
5835
|
+
member.parameters.nodes.every((p) => !p.dotDotDotToken)) {
|
|
5836
|
+
lowerer.virtualJsMethodArity.set(declaration, Math.max(lowerer.virtualJsMethodArity.get(declaration) ?? 0, member.parameters.nodes.length));
|
|
5837
|
+
const checked = !declaration.typeParameters?.nodes &&
|
|
5115
5838
|
!declaration.asteriskToken &&
|
|
5116
|
-
!declaration.modifiers?.some((m) => m.kind === ts.SyntaxKind.AsyncKeyword) &&
|
|
5839
|
+
!declaration.modifiers?.nodes.some((m) => m.kind === ts.SyntaxKind.AsyncKeyword) &&
|
|
5117
5840
|
!bodyReadsArguments(declaration) &&
|
|
5118
|
-
[...member.parameters, ...declaration.parameters].every((p) => !p.dotDotDotToken);
|
|
5841
|
+
[...member.parameters.nodes, ...declaration.parameters.nodes].every((p) => !p.dotDotDotToken);
|
|
5119
5842
|
if (checked) {
|
|
5120
5843
|
lowerer.checkedVirtualJsMethods.add(declaration);
|
|
5121
5844
|
lowerer.checkedVirtualJsMethods.add(member);
|
|
@@ -5141,7 +5864,7 @@ export function collectVirtualJsMethods(lowerer, files) {
|
|
|
5141
5864
|
return;
|
|
5142
5865
|
if (ts.isReturnStatement(node) && node.expression)
|
|
5143
5866
|
lowerer.checkedVirtualJsValueReturns.add(member);
|
|
5144
|
-
|
|
5867
|
+
ts.forEachChild(node, scan);
|
|
5145
5868
|
};
|
|
5146
5869
|
scan(member);
|
|
5147
5870
|
}
|
|
@@ -5160,6 +5883,14 @@ export function collectVirtualJsMethods(lowerer, files) {
|
|
|
5160
5883
|
}
|
|
5161
5884
|
}
|
|
5162
5885
|
}
|
|
5886
|
+
/** An override whose base and overriding methods are in files TypeScript
|
|
5887
|
+
* checks and document every parameter: TypeScript checks the override
|
|
5888
|
+
* against its base, so both keep their declared signatures, as in
|
|
5889
|
+
* TypeScript classes. */
|
|
5890
|
+
function checkedJsOverride(lowerer, base, member) {
|
|
5891
|
+
return [base, member].every((method) => lowerer.checkedJsFile(ts.getSourceFileOfNode(method)) &&
|
|
5892
|
+
method.parameters.nodes.every(documentedParameter));
|
|
5893
|
+
}
|
|
5163
5894
|
/** The receiver's EXACT runtime class, when the expression proves it: a
|
|
5164
5895
|
* `new C(...)` expression directly, or a const binding initialized with
|
|
5165
5896
|
* one (the binding can never be reassigned to a subclass instance).
|
|
@@ -5182,7 +5913,7 @@ export function exactInstanceClassOf(lowerer, expr) {
|
|
|
5182
5913
|
if (!ts.isIdentifier(e))
|
|
5183
5914
|
return null;
|
|
5184
5915
|
const symbol = lowerer.resolveValueSymbol(e);
|
|
5185
|
-
const decl = symbol ?
|
|
5916
|
+
const decl = symbol ? symbol.valueDeclaration : undefined;
|
|
5186
5917
|
if (!decl ||
|
|
5187
5918
|
!ts.isVariableDeclaration(decl) ||
|
|
5188
5919
|
decl.initializer === undefined ||
|
|
@@ -5272,19 +6003,39 @@ export function lowerClassGenericMethodCall(lowerer, call, access, recvInfo, fou
|
|
|
5272
6003
|
loc,
|
|
5273
6004
|
}
|
|
5274
6005
|
: upcastTo(lowerer, receiver, declarer.def.name);
|
|
5275
|
-
const args = lowerer.completeArgs(call.arguments, instance.params, loc, call);
|
|
5276
|
-
|
|
6006
|
+
const args = lowerer.completeArgs(call.arguments.nodes, instance.params, loc, call);
|
|
6007
|
+
const result = {
|
|
5277
6008
|
kind: "call",
|
|
5278
6009
|
callee: instance.name,
|
|
5279
6010
|
args: [thisArg, ...args],
|
|
5280
6011
|
type: instance.returnType,
|
|
5281
6012
|
loc,
|
|
5282
6013
|
};
|
|
6014
|
+
// A fluent JavaScript method (every return ends in `this`, jose's claim
|
|
6015
|
+
// setters) answers the receiver: the instance returns the declarer's
|
|
6016
|
+
// class, a used result's checker type is the receiver's subclass.
|
|
6017
|
+
if (result.type.kind === "object" &&
|
|
6018
|
+
!ts.isExpressionStatement(call.parent) &&
|
|
6019
|
+
ts.isMethodDeclaration(info.decl) &&
|
|
6020
|
+
isJsSourceFile(ts.getSourceFileOfNode(info.decl)) &&
|
|
6021
|
+
returnsOnlyThisValue(info.decl)) {
|
|
6022
|
+
return lowerer.maybeNarrow(result, call);
|
|
6023
|
+
}
|
|
6024
|
+
return result;
|
|
5283
6025
|
}
|
|
5284
6026
|
/** Wraps a derived-class expression in an upcast when the target base
|
|
5285
6027
|
* class differs (a no-op reinterpret at runtime; keeps IR types exact). */
|
|
5286
6028
|
export function upcastTo(lowerer, expr, className) {
|
|
5287
6029
|
if (expr.type.kind === "object" && expr.type.className !== className) {
|
|
6030
|
+
// A value lowered at an ANCESTOR of the class the site needs (a
|
|
6031
|
+
// fluent `this` result whose lowering kept the method's declaring
|
|
6032
|
+
// class, the receiver of the next call in a chain): the checker
|
|
6033
|
+
// vouches for the subclass, so the bridge is the verified downcast,
|
|
6034
|
+
// never an upcast the validator rejects (an internal error before).
|
|
6035
|
+
if (!lowerer.isSubclassOf(expr.type.className, className) &&
|
|
6036
|
+
lowerer.isSubclassOf(className, expr.type.className)) {
|
|
6037
|
+
return { kind: "downcast", value: expr, type: { kind: "object", className }, loc: expr.loc };
|
|
6038
|
+
}
|
|
5288
6039
|
return { kind: "upcast", value: expr, type: { kind: "object", className }, loc: expr.loc };
|
|
5289
6040
|
}
|
|
5290
6041
|
return expr;
|
|
@@ -5302,24 +6053,24 @@ export function upcastTo(lowerer, expr, className) {
|
|
|
5302
6053
|
* form with an exact static story under monomorphization (the
|
|
5303
6054
|
* instantiation adopts the base's ABI; see collectClassShapeInner). */
|
|
5304
6055
|
function mixinForwardingCtor(lowerer, ctor) {
|
|
5305
|
-
if (ctor.parameters.length !== 1 || !ctor.body)
|
|
6056
|
+
if (ctor.parameters.nodes.length !== 1 || !ctor.body)
|
|
5306
6057
|
return false;
|
|
5307
|
-
const p = ctor.parameters[0];
|
|
6058
|
+
const p = ctor.parameters.nodes[0];
|
|
5308
6059
|
if (!p.dotDotDotToken || !ts.isIdentifier(p.name))
|
|
5309
6060
|
return false;
|
|
5310
6061
|
const paramName = p.name;
|
|
5311
6062
|
const paramSym = lowerer.checker.getSymbolAtLocation(paramName);
|
|
5312
6063
|
if (!paramSym)
|
|
5313
6064
|
return false;
|
|
5314
|
-
const first = ctor.body.statements[0];
|
|
6065
|
+
const first = ctor.body.statements.nodes[0];
|
|
5315
6066
|
if (!first || !ts.isExpressionStatement(first) || !ts.isCallExpression(first.expression))
|
|
5316
6067
|
return false;
|
|
5317
6068
|
const call = first.expression;
|
|
5318
6069
|
if (call.expression.kind !== ts.SyntaxKind.SuperKeyword)
|
|
5319
6070
|
return false;
|
|
5320
|
-
if (call.arguments.length !== 1)
|
|
6071
|
+
if (call.arguments.nodes.length !== 1)
|
|
5321
6072
|
return false;
|
|
5322
|
-
const a = call.arguments[0];
|
|
6073
|
+
const a = call.arguments.nodes[0];
|
|
5323
6074
|
if (!ts.isSpreadElement(a) || !ts.isIdentifier(a.expression))
|
|
5324
6075
|
return false;
|
|
5325
6076
|
const spreadIdent = a.expression;
|
|
@@ -5372,7 +6123,7 @@ export function lowerClassMembers(lowerer, info) {
|
|
|
5372
6123
|
catch (e) {
|
|
5373
6124
|
if (!(e instanceof PoisonError))
|
|
5374
6125
|
throw e;
|
|
5375
|
-
if (info.decl && isJsSourceFile(info.decl
|
|
6126
|
+
if (info.decl && isJsSourceFile(ts.getSourceFileOfNode(info.decl))) {
|
|
5376
6127
|
const types = [
|
|
5377
6128
|
{ kind: "object", className },
|
|
5378
6129
|
...info.ctorParams.map((param) => param.type),
|
|
@@ -5483,7 +6234,7 @@ function lowerClassCtorInner(lowerer, info) {
|
|
|
5483
6234
|
// The default-param prologue runs FIRST — before field initializers
|
|
5484
6235
|
// and (in a derived class) before super(): JS evaluates parameter
|
|
5485
6236
|
// defaults on entry, ahead of everything the body does.
|
|
5486
|
-
const declared = lowerer.declareParams(info.ctor.parameters, info.ctorParams);
|
|
6237
|
+
const declared = lowerer.declareParams(info.ctor.parameters.nodes, info.ctorParams);
|
|
5487
6238
|
params.push(...declared.params);
|
|
5488
6239
|
if (info.ctorParams.at(-1)?.mode === "arguments") {
|
|
5489
6240
|
const local = lowerer.declareHiddenLocal("%arguments", DYN);
|
|
@@ -5499,7 +6250,7 @@ function lowerClassCtorInner(lowerer, info) {
|
|
|
5499
6250
|
body.push(...lowerer.fieldInitStmts(info, thisLocal));
|
|
5500
6251
|
body.push(...paramPropInitStmts(lowerer, info, thisLocal));
|
|
5501
6252
|
if (info.ctor.body)
|
|
5502
|
-
body.push(...lowerer.lowerStmts(info.ctor.body.statements));
|
|
6253
|
+
body.push(...lowerer.lowerStmts(info.ctor.body.statements.nodes));
|
|
5503
6254
|
}
|
|
5504
6255
|
else if (info.ctor.body) {
|
|
5505
6256
|
body.push(...lowerer.lowerDerivedCtorBody(info, thisLocal));
|
|
@@ -5556,7 +6307,7 @@ function lowerClassCtorInner(lowerer, info) {
|
|
|
5556
6307
|
* private, static and abstract members are not prototype string keys. */
|
|
5557
6308
|
function classPrototypeNames(decl) {
|
|
5558
6309
|
const names = [];
|
|
5559
|
-
for (const member of decl.members) {
|
|
6310
|
+
for (const member of decl.members.nodes) {
|
|
5560
6311
|
if (!ts.isMethodDeclaration(member) &&
|
|
5561
6312
|
!ts.isGetAccessorDeclaration(member) &&
|
|
5562
6313
|
!ts.isSetAccessorDeclaration(member))
|
|
@@ -5608,7 +6359,8 @@ export function classMemberNameOf(lowerer, name) {
|
|
|
5608
6359
|
if (member === "iterator" ||
|
|
5609
6360
|
member === "asyncIterator" ||
|
|
5610
6361
|
member === "dispose" ||
|
|
5611
|
-
member === "asyncDispose"
|
|
6362
|
+
member === "asyncDispose" ||
|
|
6363
|
+
member === "toPrimitive") {
|
|
5612
6364
|
return `sym:${member}`;
|
|
5613
6365
|
}
|
|
5614
6366
|
}
|
|
@@ -5921,6 +6673,77 @@ function lowerClassMethodMemberInner(lowerer, info, fnLike) {
|
|
|
5921
6673
|
allowDiagSink: true,
|
|
5922
6674
|
});
|
|
5923
6675
|
}
|
|
6676
|
+
// An override converting its declared result into the inherited ABI:
|
|
6677
|
+
// the body lowers as `%C.m$own` under its declared result, and the slot
|
|
6678
|
+
// function forwards to it and converts what it returns.
|
|
6679
|
+
const adapter = info.returnAdapters?.get(mName);
|
|
6680
|
+
if (adapter) {
|
|
6681
|
+
const ownSig = { ...sig, params: adapter.params, ret: adapter.ret };
|
|
6682
|
+
if (adapter.async)
|
|
6683
|
+
ownSig.async = true;
|
|
6684
|
+
const own = lowerClassMethodBody(lowerer, info, fnLike, `%${className}.${mName}$own`, ownSig);
|
|
6685
|
+
if (!own)
|
|
6686
|
+
return null;
|
|
6687
|
+
lowerer.liftedFns.push(own);
|
|
6688
|
+
const loc = locOf(fnLike);
|
|
6689
|
+
const params = [
|
|
6690
|
+
{ localId: "this.0", name: "this", type: thisType },
|
|
6691
|
+
...sig.params.map((p, i) => ({ localId: `p.${i}`, name: `p${i}`, type: p.type })),
|
|
6692
|
+
];
|
|
6693
|
+
const fnCtx = newFnCtx(false, null, null, sig.ret);
|
|
6694
|
+
lowerer.fnStack.push(fnCtx);
|
|
6695
|
+
try {
|
|
6696
|
+
const call = {
|
|
6697
|
+
kind: "call",
|
|
6698
|
+
callee: own.name,
|
|
6699
|
+
args: params.map((p, i) => {
|
|
6700
|
+
const ref = { kind: "varRef", localId: p.localId, type: p.type, loc };
|
|
6701
|
+
// `this` passes through; each inherited argument converts into
|
|
6702
|
+
// the override's declared parameter (checked where it narrows).
|
|
6703
|
+
return i === 0 ? ref : lowerer.coerceInto(fnLike.name, ref, adapter.params[i - 1].type);
|
|
6704
|
+
}),
|
|
6705
|
+
type: adapter.ret,
|
|
6706
|
+
loc,
|
|
6707
|
+
};
|
|
6708
|
+
// A void slot discards the override's result after running it. A
|
|
6709
|
+
// toString slot hands on what every ToString consumer of the result
|
|
6710
|
+
// makes of it (`String(err)`, templates): undefined reads
|
|
6711
|
+
// "undefined", as in Node. Other slots check the result into the
|
|
6712
|
+
// inherited type.
|
|
6713
|
+
const result = () => mName === "toString" && sig.ret.kind === "string"
|
|
6714
|
+
? call.type.kind === "dyn"
|
|
6715
|
+
? { kind: "libCall", fn: "dyn.stringConstructor", args: [call], type: STRING, loc }
|
|
6716
|
+
: lowerer.ensureString(call, fnLike.name)
|
|
6717
|
+
: lowerer.coerceInto(fnLike.name, call, sig.ret);
|
|
6718
|
+
const body = sig.ret.kind === "void"
|
|
6719
|
+
? [
|
|
6720
|
+
{ kind: "exprStmt", expr: call, loc },
|
|
6721
|
+
{ kind: "return", value: null, loc },
|
|
6722
|
+
]
|
|
6723
|
+
: [{ kind: "return", value: result(), loc }];
|
|
6724
|
+
return {
|
|
6725
|
+
name: `%${className}.${mName}`,
|
|
6726
|
+
params,
|
|
6727
|
+
returnType: sig.ret,
|
|
6728
|
+
locals: [
|
|
6729
|
+
...params.map((p) => ({ id: p.localId, name: p.name, type: p.type, mutable: false })),
|
|
6730
|
+
...lowerer.ctx.locals,
|
|
6731
|
+
],
|
|
6732
|
+
body,
|
|
6733
|
+
loc,
|
|
6734
|
+
};
|
|
6735
|
+
}
|
|
6736
|
+
finally {
|
|
6737
|
+
lowerer.fnStack.pop();
|
|
6738
|
+
}
|
|
6739
|
+
}
|
|
6740
|
+
return lowerClassMethodBody(lowerer, info, fnLike, `%${className}.${mName}`, sig);
|
|
6741
|
+
}
|
|
6742
|
+
function lowerClassMethodBody(lowerer, info, fnLike, fnName, sig) {
|
|
6743
|
+
const className = info.def.name;
|
|
6744
|
+
const thisType = { kind: "object", className };
|
|
6745
|
+
if (!fnLike.body)
|
|
6746
|
+
return null;
|
|
5924
6747
|
const prevClass = lowerer.currentClass;
|
|
5925
6748
|
lowerer.currentClass = info;
|
|
5926
6749
|
// ASYNC methods: the module function is an async IrFunction — its
|
|
@@ -5949,7 +6772,7 @@ function lowerClassMethodMemberInner(lowerer, info, fnLike) {
|
|
|
5949
6772
|
const params = [{ localId: thisLocal.id, name: "this", type: thisType }];
|
|
5950
6773
|
// `this` is declared first, so method parameter DEFAULTS may use it
|
|
5951
6774
|
// (JS allows this in method defaults; it is param 0 here).
|
|
5952
|
-
const declared = lowerer.declareParams(fnLike.parameters, sig.params);
|
|
6775
|
+
const declared = lowerer.declareParams(fnLike.parameters.nodes, sig.params);
|
|
5953
6776
|
params.push(...declared.params);
|
|
5954
6777
|
// A shorter JS override still implements every inherited ABI slot.
|
|
5955
6778
|
// These tail parameters have no source binding or default prologue.
|
|
@@ -5960,10 +6783,10 @@ function lowerClassMethodMemberInner(lowerer, info, fnLike) {
|
|
|
5960
6783
|
if (shape.mode === "arguments")
|
|
5961
6784
|
fnCtx.argumentsLocal = local;
|
|
5962
6785
|
}
|
|
5963
|
-
const body = [...declared.prologue, ...lowerer.lowerStmts(fnLike.body.statements)];
|
|
6786
|
+
const body = [...declared.prologue, ...lowerer.lowerStmts(fnLike.body.statements.nodes)];
|
|
5964
6787
|
appendImplicitUndefinedReturn(lowerer, body, bodyReturn, locOf(fnLike));
|
|
5965
6788
|
const fn = {
|
|
5966
|
-
name:
|
|
6789
|
+
name: fnName,
|
|
5967
6790
|
params,
|
|
5968
6791
|
returnType: bodyReturn,
|
|
5969
6792
|
locals: lowerer.ctx.locals,
|
|
@@ -5993,7 +6816,7 @@ export function lowerStaticMethod(lowerer, info, name) {
|
|
|
5993
6816
|
const entry = info.staticMethods?.get(name);
|
|
5994
6817
|
if (!entry?.member.body)
|
|
5995
6818
|
return null;
|
|
5996
|
-
const isAsync = entry.member.modifiers?.some((m) => m.kind === ts.SyntaxKind.AsyncKeyword) === true;
|
|
6819
|
+
const isAsync = entry.member.modifiers?.nodes.some((m) => m.kind === ts.SyntaxKind.AsyncKeyword) === true;
|
|
5997
6820
|
const isGenerator = entry.member.asteriskToken !== undefined;
|
|
5998
6821
|
if (isGenerator && (entry.ret.kind !== "generator" || (entry.ret.async === true) !== isAsync)) {
|
|
5999
6822
|
lowerer.badType(entry.member.name, lowerer.typeOf(entry.member.name));
|
|
@@ -6014,13 +6837,13 @@ export function lowerStaticMethod(lowerer, info, name) {
|
|
|
6014
6837
|
lowerer.fnStack.push(fnCtx);
|
|
6015
6838
|
try {
|
|
6016
6839
|
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);
|
|
6840
|
+
const declared = lowerer.declareParams(entry.member.parameters.nodes, entry.params);
|
|
6018
6841
|
if (entry.params.at(-1)?.mode === "arguments") {
|
|
6019
6842
|
const local = lowerer.declareHiddenLocal("%arguments", DYN);
|
|
6020
6843
|
declared.params.push({ localId: local.id, name: "%arguments", type: DYN });
|
|
6021
6844
|
fnCtx.argumentsLocal = local;
|
|
6022
6845
|
}
|
|
6023
|
-
const body = [...declared.prologue, ...lowerer.lowerStmts(entry.member.body.statements)];
|
|
6846
|
+
const body = [...declared.prologue, ...lowerer.lowerStmts(entry.member.body.statements.nodes)];
|
|
6024
6847
|
appendImplicitUndefinedReturn(lowerer, body, bodyReturn, locOf(entry.member));
|
|
6025
6848
|
const fn = {
|
|
6026
6849
|
name: `%${info.def.name}.static:${name}`,
|
|
@@ -6091,6 +6914,13 @@ export function throwingSetterFn(lowerer, info, prop) {
|
|
|
6091
6914
|
loc,
|
|
6092
6915
|
};
|
|
6093
6916
|
}
|
|
6917
|
+
/** The declared type a refused checked-dynamic class field names in its
|
|
6918
|
+
* diagnostic (`'any'`, `'WeakMap<object, string>'`): `unknown` and
|
|
6919
|
+
* `object` fields store checked-dynamic values, so the refusal is about
|
|
6920
|
+
* whatever else the declaration spells. */
|
|
6921
|
+
function dynFieldTypeSpelling(lowerer, node) {
|
|
6922
|
+
return `'${lowerer.checker.typeToString(lowerer.typeOf(node))}'`;
|
|
6923
|
+
}
|
|
6094
6924
|
/** The base a constructor chain actually CALLS into: generic FAMILIES are
|
|
6095
6925
|
* never constructed (no `%<family>.constructor` exists), so an
|
|
6096
6926
|
* instantiation's construction-relevant base is the family's own base —
|
|
@@ -6134,14 +6964,15 @@ export function fieldInitStmts(lowerer, info, thisLocal) {
|
|
|
6134
6964
|
className: info.def.name,
|
|
6135
6965
|
field: f.name,
|
|
6136
6966
|
value: dynUndefinedExpr(loc),
|
|
6967
|
+
define: true,
|
|
6137
6968
|
loc,
|
|
6138
6969
|
});
|
|
6139
6970
|
}
|
|
6140
6971
|
if (!f.initializer)
|
|
6141
6972
|
continue;
|
|
6142
|
-
lowerer.
|
|
6143
|
-
lowerer.bumpFileStat(locOf(f.initializer).file, "total");
|
|
6973
|
+
lowerer.countStatement(f.initializer, locOf(f.initializer).file);
|
|
6144
6974
|
const diagsBefore = lowerer.diags.length;
|
|
6975
|
+
const sinkMark = lowerer.diagSinkMark();
|
|
6145
6976
|
try {
|
|
6146
6977
|
const value = lowerer.lowerExprExpecting(f.initializer, f.type);
|
|
6147
6978
|
out.push({
|
|
@@ -6150,18 +6981,18 @@ export function fieldInitStmts(lowerer, info, thisLocal) {
|
|
|
6150
6981
|
className: info.def.name,
|
|
6151
6982
|
field: f.name,
|
|
6152
6983
|
value,
|
|
6984
|
+
define: true,
|
|
6153
6985
|
loc: locOf(f.initializer),
|
|
6154
6986
|
});
|
|
6155
6987
|
}
|
|
6156
6988
|
catch (e) {
|
|
6157
6989
|
if (!(e instanceof PoisonError))
|
|
6158
6990
|
throw e;
|
|
6159
|
-
lowerer.
|
|
6160
|
-
|
|
6161
|
-
|
|
6162
|
-
|
|
6163
|
-
|
|
6164
|
-
});
|
|
6991
|
+
lowerer.countStatementFailed(f.initializer, locOf(f.initializer).file);
|
|
6992
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(f.initializer))) {
|
|
6993
|
+
const fence = lowerer.diagSink === null
|
|
6994
|
+
? lowerer.deferToRuntimeFence(diagsBefore, f.initializer, { kind: "statement" })
|
|
6995
|
+
: lowerer.capturedRuntimeFence(sinkMark, f.initializer);
|
|
6165
6996
|
if (fence)
|
|
6166
6997
|
out.push(fence);
|
|
6167
6998
|
}
|
|
@@ -6200,6 +7031,24 @@ function paramPropInitStmts(lowerer, info, thisLocal) {
|
|
|
6200
7031
|
}
|
|
6201
7032
|
return out;
|
|
6202
7033
|
}
|
|
7034
|
+
/** Whether a super() call's value is discarded by its statement: the call
|
|
7035
|
+
* is the expression statement itself, or an operand of a comma chain that
|
|
7036
|
+
* is (`super(m, o), this.code = c;`, as minifiers join statements). The
|
|
7037
|
+
* statement lowering runs each comma operand as its own statement in
|
|
7038
|
+
* source order, so the chain lowers exactly like `super(m, o); this.code =
|
|
7039
|
+
* c;`. Parentheses are transparent to both. */
|
|
7040
|
+
function superCallInStatementPosition(call) {
|
|
7041
|
+
let node = call;
|
|
7042
|
+
for (;;) {
|
|
7043
|
+
const parent = node.parent;
|
|
7044
|
+
if (ts.isExpressionStatement(parent))
|
|
7045
|
+
return true;
|
|
7046
|
+
const comma = ts.isBinaryExpression(parent) && parent.operatorToken.kind === ts.SyntaxKind.CommaToken;
|
|
7047
|
+
if (!comma && !ts.isParenthesizedExpression(parent))
|
|
7048
|
+
return false;
|
|
7049
|
+
node = parent;
|
|
7050
|
+
}
|
|
7051
|
+
}
|
|
6203
7052
|
/** Super statements initialize the base and then the derived fields on
|
|
6204
7053
|
* whichever control-flow path executes. Repeated calls are explicitly
|
|
6205
7054
|
* refused until native layouts can allocate a second receiver. */
|
|
@@ -6212,7 +7061,7 @@ export function lowerDerivedCtorBody(lowerer, info, thisLocal, forward) {
|
|
|
6212
7061
|
const previousInitialized = context.superInitialized;
|
|
6213
7062
|
context.superInitialized = initialized;
|
|
6214
7063
|
context.superCall = (superCall) => {
|
|
6215
|
-
if (!
|
|
7064
|
+
if (!superCallInStatementPosition(superCall))
|
|
6216
7065
|
lowerer.unsupported("SC1090", superCall, "super() in an expression position");
|
|
6217
7066
|
superSeen = true;
|
|
6218
7067
|
const loc = locOf(superCall);
|
|
@@ -6232,11 +7081,11 @@ export function lowerDerivedCtorBody(lowerer, info, thisLocal, forward) {
|
|
|
6232
7081
|
},
|
|
6233
7082
|
];
|
|
6234
7083
|
if (info.callableBase) {
|
|
6235
|
-
if (superCall.arguments.some(ts.isSpreadElement))
|
|
7084
|
+
if (superCall.arguments.nodes.some(ts.isSpreadElement))
|
|
6236
7085
|
lowerer.unsupported("SC1090", superCall, "spreading explicit super arguments into an ordinary constructor");
|
|
6237
7086
|
const pack = {
|
|
6238
7087
|
kind: "dynArrLit",
|
|
6239
|
-
elems: superCall.arguments.map((arg) => lowerer.lowerExprExpecting(arg, DYN)),
|
|
7088
|
+
elems: superCall.arguments.nodes.map((arg) => lowerer.lowerExprExpecting(arg, DYN)),
|
|
6240
7089
|
type: DYN,
|
|
6241
7090
|
loc,
|
|
6242
7091
|
};
|
|
@@ -6244,19 +7093,19 @@ export function lowerDerivedCtorBody(lowerer, info, thisLocal, forward) {
|
|
|
6244
7093
|
}
|
|
6245
7094
|
else {
|
|
6246
7095
|
const base = superBaseOf(info);
|
|
6247
|
-
if (base.builtinEmitter && superCall.arguments.length > 0)
|
|
7096
|
+
if (base.builtinEmitter && superCall.arguments.nodes.length > 0)
|
|
6248
7097
|
lowerer.unsupported("SC1090", superCall, "EventEmitter constructor options ('captureRejections')");
|
|
6249
7098
|
if (base.builtinStream) {
|
|
6250
|
-
statements.push(...lowerStreamSuperCall(lowerer, info, base, superCall.arguments, thisLocal, loc, superCall));
|
|
7099
|
+
statements.push(...lowerStreamSuperCall(lowerer, info, base, superCall.arguments.nodes, thisLocal, loc, superCall));
|
|
6251
7100
|
}
|
|
6252
7101
|
else {
|
|
6253
7102
|
const surplusSpread = forward === undefined &&
|
|
6254
7103
|
!base.builtinError &&
|
|
6255
7104
|
!base.builtinEmitter &&
|
|
6256
7105
|
base.ctorParams.length === 0 &&
|
|
6257
|
-
superCall.arguments.some(ts.isSpreadElement);
|
|
7106
|
+
superCall.arguments.nodes.some(ts.isSpreadElement);
|
|
6258
7107
|
if (surplusSpread) {
|
|
6259
|
-
const evaluated = lowerer.completeArgs(superCall.arguments, [{ mode: "dynRest", type: DYN }], loc, superCall);
|
|
7108
|
+
const evaluated = lowerer.completeArgs(superCall.arguments.nodes, [{ mode: "dynRest", type: DYN }], loc, superCall);
|
|
6260
7109
|
for (const value of evaluated)
|
|
6261
7110
|
statements.push({ kind: "exprStmt", expr: value, loc });
|
|
6262
7111
|
}
|
|
@@ -6264,26 +7113,26 @@ export function lowerDerivedCtorBody(lowerer, info, thisLocal, forward) {
|
|
|
6264
7113
|
!base.builtinError &&
|
|
6265
7114
|
!base.builtinEmitter &&
|
|
6266
7115
|
!base.ctorParams.some((param) => param.mode === "rest" || param.mode === "dynRest") &&
|
|
6267
|
-
!superCall.arguments.some(ts.isSpreadElement) &&
|
|
6268
|
-
superCall.arguments.length > base.ctorParams.length;
|
|
7116
|
+
!superCall.arguments.nodes.some(ts.isSpreadElement) &&
|
|
7117
|
+
superCall.arguments.nodes.length > base.ctorParams.length;
|
|
6269
7118
|
let args = surplusSpread
|
|
6270
7119
|
? []
|
|
6271
7120
|
: forward !== undefined
|
|
6272
7121
|
? forward
|
|
6273
7122
|
: base.builtinError
|
|
6274
|
-
? lowerer.errorConstructorArgs(superCall.arguments, loc, superCall)
|
|
7123
|
+
? lowerer.errorConstructorArgs(superCall.arguments.nodes, loc, superCall)
|
|
6275
7124
|
: base.builtinEmitter
|
|
6276
7125
|
? []
|
|
6277
7126
|
: lowerer.completeArgs(surplus
|
|
6278
|
-
? superCall.arguments.slice(0, base.ctorParams.length)
|
|
6279
|
-
: superCall.arguments, base.ctorParams, loc, superCall);
|
|
7127
|
+
? superCall.arguments.nodes.slice(0, base.ctorParams.length)
|
|
7128
|
+
: superCall.arguments.nodes, base.ctorParams, loc, superCall);
|
|
6280
7129
|
if (surplus) {
|
|
6281
7130
|
args = args.map((arg) => {
|
|
6282
7131
|
const local = lowerer.declareHiddenLocal("%superArgument", arg.type);
|
|
6283
7132
|
statements.push({ kind: "varDecl", localId: local.id, init: arg, loc });
|
|
6284
7133
|
return { kind: "varRef", localId: local.id, type: arg.type, loc };
|
|
6285
7134
|
});
|
|
6286
|
-
for (const argument of superCall.arguments.slice(base.ctorParams.length)) {
|
|
7135
|
+
for (const argument of superCall.arguments.nodes.slice(base.ctorParams.length)) {
|
|
6287
7136
|
statements.push({
|
|
6288
7137
|
kind: "exprStmt",
|
|
6289
7138
|
expr: lowerer.lowerExpr(argument),
|
|
@@ -6323,7 +7172,7 @@ export function lowerDerivedCtorBody(lowerer, info, thisLocal, forward) {
|
|
|
6323
7172
|
};
|
|
6324
7173
|
};
|
|
6325
7174
|
try {
|
|
6326
|
-
const result = lowerer.lowerStmts(info.ctor.body.statements);
|
|
7175
|
+
const result = lowerer.lowerStmts(info.ctor.body.statements.nodes);
|
|
6327
7176
|
result.push({
|
|
6328
7177
|
kind: "if",
|
|
6329
7178
|
cond: {
|
|
@@ -6370,7 +7219,6 @@ export function lowerDerivedCtorBody(lowerer, info, thisLocal, forward) {
|
|
|
6370
7219
|
* `this` (upcast; retained by the varRef read — the callee owns and
|
|
6371
7220
|
* releases its param per the universal convention). */
|
|
6372
7221
|
export function superCallStmt(lowerer, info, thisLocal, args, loc) {
|
|
6373
|
-
const base = superBaseOf(info);
|
|
6374
7222
|
const thisRef = {
|
|
6375
7223
|
kind: "varRef",
|
|
6376
7224
|
localId: thisLocal.id,
|
|
@@ -6415,6 +7263,8 @@ export function superCallStmt(lowerer, info, thisLocal, args, loc) {
|
|
|
6415
7263
|
},
|
|
6416
7264
|
loc,
|
|
6417
7265
|
};
|
|
7266
|
+
// A callable base has no class info, so the base is read after that case.
|
|
7267
|
+
const base = superBaseOf(info);
|
|
6418
7268
|
if (base.builtinError) {
|
|
6419
7269
|
// super(message) into the runtime-provided Error constructor: stamps
|
|
6420
7270
|
// name/message on the (already-allocated) object. Receiver + message
|
|
@@ -6459,7 +7309,7 @@ export function superCallStmt(lowerer, info, thisLocal, args, loc) {
|
|
|
6459
7309
|
return lowerStreamSuperCall(lowerer, info, base, [], thisLocal, loc, info.decl ?? info.ctor)[0];
|
|
6460
7310
|
}
|
|
6461
7311
|
lowerer.noteSuperConstructorEdge(`%${base.def.name}.constructor`);
|
|
6462
|
-
|
|
7312
|
+
const call = {
|
|
6463
7313
|
kind: "exprStmt",
|
|
6464
7314
|
expr: {
|
|
6465
7315
|
kind: "call",
|
|
@@ -6470,6 +7320,7 @@ export function superCallStmt(lowerer, info, thisLocal, args, loc) {
|
|
|
6470
7320
|
},
|
|
6471
7321
|
loc,
|
|
6472
7322
|
};
|
|
7323
|
+
return superIntoResultSlot(lowerer, base, info, call, lowerer.upcastTo({ ...thisRef }, base.def.name), info.ctor ?? info.decl);
|
|
6473
7324
|
}
|
|
6474
7325
|
/** `super.method(args)`: the base chain's implementation, called
|
|
6475
7326
|
* DIRECTLY over this method's own `this` (upcast to the declarer) —
|
|
@@ -6500,7 +7351,7 @@ export function lowerSuperMethodCall(lowerer, call, access) {
|
|
|
6500
7351
|
const instance = genericCallInstance(lowerer, call, gfound.info);
|
|
6501
7352
|
const loc = locOf(call);
|
|
6502
7353
|
const thisRef = { kind: "varRef", localId: thisL.id, type: thisL.type, loc };
|
|
6503
|
-
const args = lowerer.completeArgs(call.arguments, instance.params, loc, call);
|
|
7354
|
+
const args = lowerer.completeArgs(call.arguments.nodes, instance.params, loc, call);
|
|
6504
7355
|
return {
|
|
6505
7356
|
kind: "call",
|
|
6506
7357
|
callee: instance.name,
|
|
@@ -6561,8 +7412,8 @@ export function lowerSuperMethodCall(lowerer, call, access) {
|
|
|
6561
7412
|
kind: "dynCall",
|
|
6562
7413
|
callee,
|
|
6563
7414
|
receiver: lowerer.coerceToExpected(thisRef, DYN),
|
|
6564
|
-
calleeName:
|
|
6565
|
-
args: call.arguments.map((arg) => lowerer.lowerExprExpecting(arg, DYN)),
|
|
7415
|
+
calleeName: ts.getTextOfNode(access),
|
|
7416
|
+
args: call.arguments.nodes.map((arg) => lowerer.lowerExprExpecting(arg, DYN)),
|
|
6566
7417
|
type: DYN,
|
|
6567
7418
|
loc,
|
|
6568
7419
|
};
|
|
@@ -6579,7 +7430,7 @@ export function lowerSuperMethodCall(lowerer, call, access) {
|
|
|
6579
7430
|
};
|
|
6580
7431
|
}
|
|
6581
7432
|
lowerer.noteEdge(`%${found.declarer.def.name}.${access.name.text}`);
|
|
6582
|
-
const args = lowerer.completeArgs(call.arguments, found.sig.params, loc, call);
|
|
7433
|
+
const args = lowerer.completeArgs(call.arguments.nodes, found.sig.params, loc, call);
|
|
6583
7434
|
return {
|
|
6584
7435
|
kind: "call",
|
|
6585
7436
|
callee: `%${found.declarer.def.name}.${access.name.text}`,
|
|
@@ -6696,6 +7547,47 @@ function inheritsBuiltinStreamCtor(lowerer, info) {
|
|
|
6696
7547
|
}
|
|
6697
7548
|
return false;
|
|
6698
7549
|
}
|
|
7550
|
+
/** The run-time form of refuseInheritedBuiltinCtorArgs, for construction
|
|
7551
|
+
* from checked-dynamic code (`new F(options)` with F an untyped value
|
|
7552
|
+
* holding C), whose argument count is known only to the caller: a
|
|
7553
|
+
* runtimeFence located at C, or null when C's constructor takes its
|
|
7554
|
+
* arguments. */
|
|
7555
|
+
export function inheritedBuiltinCtorFence(lowerer, info, loc) {
|
|
7556
|
+
let feature = null;
|
|
7557
|
+
if (inheritsBuiltinStreamCtor(lowerer, info))
|
|
7558
|
+
feature = `new ${info.def.name.replace(/^%/, "")} with arguments through an inherited stream constructor (declare a constructor that passes an inline options object to super(...))`;
|
|
7559
|
+
else if (lowerer.inheritsBuiltinEmitterCtor(info))
|
|
7560
|
+
feature = "EventEmitter constructor options ('captureRejections')";
|
|
7561
|
+
if (feature === null)
|
|
7562
|
+
return null;
|
|
7563
|
+
// Located at the class, whose constructor takes no arguments.
|
|
7564
|
+
const at = info.decl !== null ? locOf(info.decl) : loc;
|
|
7565
|
+
const diag = unsupportedDiag("SC1090", at, feature);
|
|
7566
|
+
lowerer.runtimeFences.push(diag);
|
|
7567
|
+
const line = info.decl !== null
|
|
7568
|
+
? ts.getLineAndCharacterOfPosition(ts.getSourceFileOfNode(info.decl), at.start).line + 1
|
|
7569
|
+
: null;
|
|
7570
|
+
const where = line !== null ? ` [${diag.code} at ${at.file}:${line}]` : "";
|
|
7571
|
+
return { kind: "runtimeFence", code: diag.code, message: `${diag.message}${where}`, loc };
|
|
7572
|
+
}
|
|
7573
|
+
/** `new C(args)` where C's constructor is the inherited runtime stream or
|
|
7574
|
+
* EventEmitter constructor (a ctor-less chain into the base): that
|
|
7575
|
+
* constructor takes zero arguments here (the options bag fences, like the
|
|
7576
|
+
* super() form), so arguments report at the first one. Applies to direct
|
|
7577
|
+
* construction and to construction through a class value of C. Stream
|
|
7578
|
+
* subclasses come first: their chain roots at the emitter too, but the
|
|
7579
|
+
* message should name the stream story. */
|
|
7580
|
+
function refuseInheritedBuiltinCtorArgs(lowerer, info, expr) {
|
|
7581
|
+
const first = expr.arguments?.nodes[0];
|
|
7582
|
+
if (first === undefined)
|
|
7583
|
+
return;
|
|
7584
|
+
if (inheritsBuiltinStreamCtor(lowerer, info)) {
|
|
7585
|
+
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(...)");
|
|
7586
|
+
}
|
|
7587
|
+
if (lowerer.inheritsBuiltinEmitterCtor(info)) {
|
|
7588
|
+
lowerer.unsupported("SC1090", first, "EventEmitter constructor options ('captureRejections')");
|
|
7589
|
+
}
|
|
7590
|
+
}
|
|
6699
7591
|
/** Preserve argument evaluation order and option presence through builtin
|
|
6700
7592
|
* and inherited Error constructors. Checked-dynamic conversion retains
|
|
6701
7593
|
* Error identity and distinguishes a missing cause from undefined. */
|
|
@@ -6804,38 +7696,29 @@ function lowerProgramClassNew(lowerer, expr, declaredInfo, loc) {
|
|
|
6804
7696
|
if (info.localClass)
|
|
6805
7697
|
lowerer.unsupported("SC1090", expr, "construction through a function-local class's internal name");
|
|
6806
7698
|
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
|
-
}
|
|
7699
|
+
refuseInheritedBuiltinCtorArgs(lowerer, info, expr);
|
|
6817
7700
|
// A ctor-less chain into a builtin error base inherits both arguments;
|
|
6818
7701
|
// each synthesized constructor forwards the same pair to its base.
|
|
6819
7702
|
const args = lowerer.inheritsBuiltinErrorCtor(info)
|
|
6820
|
-
? lowerer.errorConstructorArgs(expr.arguments ?? [], loc, expr)
|
|
6821
|
-
: lowerer.completeArgs(expr.arguments ?? [], info.ctorParams, loc, expr);
|
|
7703
|
+
? lowerer.errorConstructorArgs(expr.arguments?.nodes ?? [], loc, expr)
|
|
7704
|
+
: lowerer.completeArgs(expr.arguments?.nodes ?? [], info.ctorParams, loc, expr);
|
|
6822
7705
|
for (let current = info; current; current = current.base) {
|
|
6823
7706
|
if (current.def.baseValueGlobal)
|
|
6824
|
-
return {
|
|
7707
|
+
return constructedValue(lowerer, info, {
|
|
6825
7708
|
kind: "newValue",
|
|
6826
7709
|
callee: classValueRef(lowerer, info, expr),
|
|
6827
7710
|
args,
|
|
6828
7711
|
type: { kind: "object", className: info.def.name },
|
|
6829
7712
|
loc,
|
|
6830
|
-
};
|
|
7713
|
+
});
|
|
6831
7714
|
}
|
|
6832
|
-
return {
|
|
7715
|
+
return constructedValue(lowerer, info, {
|
|
6833
7716
|
kind: "new",
|
|
6834
7717
|
className: info.def.name,
|
|
6835
7718
|
args,
|
|
6836
7719
|
type: { kind: "object", className: info.def.name },
|
|
6837
7720
|
loc,
|
|
6838
|
-
};
|
|
7721
|
+
});
|
|
6839
7722
|
}
|
|
6840
7723
|
function assignedThisFieldType(lowerer, expr) {
|
|
6841
7724
|
const parent = expr.parent;
|
|
@@ -6848,21 +7731,47 @@ function assignedThisFieldType(lowerer, expr) {
|
|
|
6848
7731
|
}
|
|
6849
7732
|
return lowerer.currentClass?.fields.get(parent.left.name.text) ?? null;
|
|
6850
7733
|
}
|
|
7734
|
+
/** Map, Set and the error classes construct in lowerNew's identifier
|
|
7735
|
+
* branch, which a module member alias of one (`new mod.M()`) also takes. */
|
|
7736
|
+
function isCollectionOrErrorClass(ref) {
|
|
7737
|
+
return ref?.kind === "collection" || ref?.kind === "error";
|
|
7738
|
+
}
|
|
6851
7739
|
export function lowerNew(lowerer, expr) {
|
|
6852
7740
|
const loc = locOf(expr);
|
|
7741
|
+
// new Function(...): Node's EvalError under
|
|
7742
|
+
// --disallow-code-generation-from-strings (code-generation.ts).
|
|
7743
|
+
if (codeGenerationCalleeOf(lowerer, expr.expression) === "Function")
|
|
7744
|
+
return lowerCodeGenerationCall(lowerer, expr, "Function");
|
|
7745
|
+
// `new <temporal>.X(...)`: Node 24 has no such global, so the callee's
|
|
7746
|
+
// root read throws the ReferenceError before any argument evaluates.
|
|
7747
|
+
{
|
|
7748
|
+
const root = ambientUndefVarRootOf(lowerer, expr.expression);
|
|
7749
|
+
if (root !== null && root.text === TEMPORAL_GLOBAL) {
|
|
7750
|
+
const t = ambientUndefReadType(lowerer, expr) ?? contextualUndefReadType(lowerer, expr) ?? F64;
|
|
7751
|
+
return nsUndefRead(lowerer, root.text, expr, t);
|
|
7752
|
+
}
|
|
7753
|
+
}
|
|
7754
|
+
// `new (require("./x").C)()`: the module's %init at the require's
|
|
7755
|
+
// position, then construction through the member as for a binding.
|
|
7756
|
+
if (ts.isPropertyAccessExpression(expr.expression) && !expr.expression.questionDotToken) {
|
|
7757
|
+
const req = inlineNamespaceRequireOf(lowerer, expr.expression.expression);
|
|
7758
|
+
if (req !== null && !lowerer.inlineRequireInitDone.has(req.call)) {
|
|
7759
|
+
return lowerWithInlineRequireInit(lowerer, req, () => lowerNew(lowerer, expr));
|
|
7760
|
+
}
|
|
7761
|
+
}
|
|
6853
7762
|
const worker = lowerWorkerNew(lowerer, expr);
|
|
6854
7763
|
if (worker)
|
|
6855
7764
|
return worker;
|
|
6856
7765
|
const readlineUi = lowerReadlineUiNew(lowerer, expr);
|
|
6857
7766
|
if (readlineUi)
|
|
6858
7767
|
return readlineUi;
|
|
6859
|
-
const channel = lowerMessageChannelNew(lowerer, expr);
|
|
7768
|
+
const channel = lowerMessageChannelNew(lowerer, expr) ?? lowerBroadcastChannelNew(lowerer, expr);
|
|
6860
7769
|
if (channel)
|
|
6861
7770
|
return channel;
|
|
6862
7771
|
let intlConstructor = expr.expression;
|
|
6863
7772
|
if (ts.isIdentifier(intlConstructor)) {
|
|
6864
7773
|
const symbol = lowerer.resolveValueSymbol(intlConstructor);
|
|
6865
|
-
const declaration = symbol ?
|
|
7774
|
+
const declaration = symbol ? symbol.valueDeclaration : undefined;
|
|
6866
7775
|
if (declaration && ts.isVariableDeclaration(declaration) && declaration.initializer)
|
|
6867
7776
|
intlConstructor = declaration.initializer;
|
|
6868
7777
|
}
|
|
@@ -6871,6 +7780,9 @@ export function lowerNew(lowerer, expr) {
|
|
|
6871
7780
|
: null;
|
|
6872
7781
|
if (intl && intl !== "Segmenter")
|
|
6873
7782
|
lowerer.noLowering(`new Intl.${intl}`, expr, undefined, lowerer.checker.getSymbolAtLocation(expr.expression));
|
|
7783
|
+
const valueReturning = lowerValueReturningConstructorNew(lowerer, expr);
|
|
7784
|
+
if (valueReturning)
|
|
7785
|
+
return valueReturning;
|
|
6874
7786
|
const instanceConstructor = lowerInstanceConstructorNew(lowerer, expr);
|
|
6875
7787
|
if (instanceConstructor)
|
|
6876
7788
|
return instanceConstructor;
|
|
@@ -6880,11 +7792,9 @@ export function lowerNew(lowerer, expr) {
|
|
|
6880
7792
|
if (ts.isIdentifier(expr.expression)) {
|
|
6881
7793
|
const symbol = lowerer.resolveValueSymbol(expr.expression);
|
|
6882
7794
|
const declaration = symbol &&
|
|
6883
|
-
|
|
6884
|
-
.declarationsOf(symbol)
|
|
6885
|
-
.find((node) => ts.isFunctionDeclaration(node) && node.body !== undefined);
|
|
7795
|
+
symbol.declarations.find((node) => ts.isFunctionDeclaration(node) && node.body !== undefined);
|
|
6886
7796
|
if (declaration && ts.isFunctionDeclaration(declaration) && declaration.body) {
|
|
6887
|
-
const last = declaration.body.statements.at(-1);
|
|
7797
|
+
const last = declaration.body.statements.nodes.at(-1);
|
|
6888
7798
|
if (last &&
|
|
6889
7799
|
ts.isReturnStatement(last) &&
|
|
6890
7800
|
last.expression &&
|
|
@@ -6921,7 +7831,7 @@ export function lowerNew(lowerer, expr) {
|
|
|
6921
7831
|
if (ts.isPropertyAccessExpression(expr.expression) &&
|
|
6922
7832
|
expr.expression.name.text === "Segmenter" &&
|
|
6923
7833
|
lowerer.isStdlibGlobal(expr.expression.expression, "Intl")) {
|
|
6924
|
-
const args = expr.arguments ?? [];
|
|
7834
|
+
const args = expr.arguments?.nodes ?? [];
|
|
6925
7835
|
const undefinedArg = (arg) => (lowerer.typeOf(arg).flags & ts.TypeFlags.Undefined) !== 0;
|
|
6926
7836
|
if (args.length > 2 || (args[0] && !undefinedArg(args[0]))) {
|
|
6927
7837
|
lowerer.noLowering("Intl.Segmenter locale negotiation", expr, "omit the locale or pass undefined for default Unicode grapheme segmentation");
|
|
@@ -6930,7 +7840,7 @@ export function lowerNew(lowerer, expr) {
|
|
|
6930
7840
|
if (options &&
|
|
6931
7841
|
!undefinedArg(options) &&
|
|
6932
7842
|
!(ts.isObjectLiteralExpression(options) &&
|
|
6933
|
-
options.properties.every((property) => ts.isPropertyAssignment(property) &&
|
|
7843
|
+
options.properties.nodes.every((property) => ts.isPropertyAssignment(property) &&
|
|
6934
7844
|
(ts.isIdentifier(property.name) || ts.isStringLiteral(property.name)) &&
|
|
6935
7845
|
property.name.text === "granularity" &&
|
|
6936
7846
|
ts.isStringLiteral(property.initializer) &&
|
|
@@ -6970,8 +7880,8 @@ export function lowerNew(lowerer, expr) {
|
|
|
6970
7880
|
: memberSym;
|
|
6971
7881
|
const emitterInfo = lowerer.builtinEmitterInfoOf(resolved);
|
|
6972
7882
|
if (emitterInfo) {
|
|
6973
|
-
if ((expr.arguments ?? []).length > 0) {
|
|
6974
|
-
lowerer.unsupported("SC1090", expr.arguments[0], "EventEmitter constructor options ('captureRejections')");
|
|
7883
|
+
if ((expr.arguments?.nodes ?? []).length > 0) {
|
|
7884
|
+
lowerer.unsupported("SC1090", expr.arguments.nodes[0], "EventEmitter constructor options ('captureRejections')");
|
|
6975
7885
|
}
|
|
6976
7886
|
return {
|
|
6977
7887
|
kind: "libCall",
|
|
@@ -6992,8 +7902,8 @@ export function lowerNew(lowerer, expr) {
|
|
|
6992
7902
|
// `new zlib.Gzip(options?)` — the zlib stream classes.
|
|
6993
7903
|
const zlibModeNs = zlibStreamModeOf(lowerer, resolved);
|
|
6994
7904
|
if (zlibModeNs !== null) {
|
|
6995
|
-
const what = `new zlib.${
|
|
6996
|
-
return lowerZlibStreamNew(lowerer, expr.arguments ?? [], zlibModeNs, what, expr, loc);
|
|
7905
|
+
const what = `new zlib.${zlibClassName(zlibModeNs)}`;
|
|
7906
|
+
return lowerZlibStreamNew(lowerer, expr.arguments?.nodes ?? [], zlibModeNs, what, expr, loc);
|
|
6997
7907
|
}
|
|
6998
7908
|
// `new N.C(...)` / `new a.Point(...)` — construction through a
|
|
6999
7909
|
// USER namespace qualifier (import= alias chains included): the
|
|
@@ -7040,7 +7950,7 @@ export function lowerNew(lowerer, expr) {
|
|
|
7040
7950
|
// member-export symbol's; the class collects on demand (a body
|
|
7041
7951
|
// lowering ahead of the assignment statement).
|
|
7042
7952
|
if (!expr.expression.questionDotToken &&
|
|
7043
|
-
((isCjsJsFile(
|
|
7953
|
+
((isCjsJsFile(ts.getSourceFileOfNode(expr), lowerer.program) &&
|
|
7044
7954
|
(isModuleExportsAccess(expr.expression.expression) ||
|
|
7045
7955
|
(ts.isIdentifier(expr.expression.expression) &&
|
|
7046
7956
|
expr.expression.expression.text === "exports" &&
|
|
@@ -7055,7 +7965,7 @@ export function lowerNew(lowerer, expr) {
|
|
|
7055
7965
|
memberSym,
|
|
7056
7966
|
resolved,
|
|
7057
7967
|
lowerer.resolveValueSymbol(expr.expression.name) ?? undefined,
|
|
7058
|
-
lowerer.cjsModuleExportSymbol(
|
|
7968
|
+
lowerer.cjsModuleExportSymbol(ts.getSourceFileOfNode(expr), expr.expression.name.text),
|
|
7059
7969
|
];
|
|
7060
7970
|
const exportSym = candidates.find((s) => s !== undefined);
|
|
7061
7971
|
const g = candidates
|
|
@@ -7075,14 +7985,14 @@ export function lowerNew(lowerer, expr) {
|
|
|
7075
7985
|
};
|
|
7076
7986
|
below(info);
|
|
7077
7987
|
const callee = { kind: "varRef", localId: g.id, type: g.type, loc };
|
|
7078
|
-
const args = lowerer.completeArgs(expr.arguments ?? [], info.ctorParams, loc, expr);
|
|
7079
|
-
return {
|
|
7988
|
+
const args = lowerer.completeArgs(expr.arguments?.nodes ?? [], info.ctorParams, loc, expr);
|
|
7989
|
+
return constructedFromValue(lowerer, info, {
|
|
7080
7990
|
kind: "newValue",
|
|
7081
7991
|
callee,
|
|
7082
7992
|
args,
|
|
7083
7993
|
type: { kind: "object", className: info.def.name },
|
|
7084
7994
|
loc,
|
|
7085
|
-
};
|
|
7995
|
+
}, expr);
|
|
7086
7996
|
}
|
|
7087
7997
|
}
|
|
7088
7998
|
}
|
|
@@ -7106,7 +8016,10 @@ export function lowerNew(lowerer, expr) {
|
|
|
7106
8016
|
if (ts.isIdentifier(expr.expression) ||
|
|
7107
8017
|
(ts.isPropertyAccessExpression(expr.expression) &&
|
|
7108
8018
|
ts.isIdentifier(expr.expression.name) &&
|
|
7109
|
-
lowerer.isStdlibGlobal(expr.expression.expression, "globalThis")
|
|
8019
|
+
(lowerer.isStdlibGlobal(expr.expression.expression, "globalThis") ||
|
|
8020
|
+
// `new mod.M()` over an exported `const M = Map` or `const E =
|
|
8021
|
+
// TypeError`
|
|
8022
|
+
isCollectionOrErrorClass(builtinClassRefOf(lowerer, expr.expression))))) {
|
|
7110
8023
|
// `import C = N.C; new C()` — the alias's own source-order guards
|
|
7111
8024
|
// (a no-op for every non-import= binding).
|
|
7112
8025
|
if (ts.isIdentifier(expr.expression))
|
|
@@ -7114,7 +8027,7 @@ export function lowerNew(lowerer, expr) {
|
|
|
7114
8027
|
const identifier = ts.isIdentifier(expr.expression) ? expr.expression : expr.expression.name;
|
|
7115
8028
|
const symbol = ts.isIdentifier(identifier) ? lowerer.resolveValueSymbol(identifier) : null;
|
|
7116
8029
|
if (ts.isIdentifier(identifier) && lowerer.isStdlibGlobal(identifier, "Array")) {
|
|
7117
|
-
return lowerArrayConstructor(lowerer, expr, expr.arguments ?? []);
|
|
8030
|
+
return lowerArrayConstructor(lowerer, expr, expr.arguments?.nodes ?? []);
|
|
7118
8031
|
}
|
|
7119
8032
|
if (isNativeProxyInitializer(lowerer, expr))
|
|
7120
8033
|
return lowerNativeProxy(lowerer, expr);
|
|
@@ -7130,7 +8043,7 @@ export function lowerNew(lowerer, expr) {
|
|
|
7130
8043
|
// `cause` own-property record) / "Error" for absent, and the legacy
|
|
7131
8044
|
// numeric code from the name table.
|
|
7132
8045
|
if (errInfo && errInfo.def.name === "%DOMException") {
|
|
7133
|
-
const args = expr.arguments ?? [];
|
|
8046
|
+
const args = expr.arguments?.nodes ?? [];
|
|
7134
8047
|
if (args.length > 2) {
|
|
7135
8048
|
lowerer.noLowering(`new DOMException with ${args.length} arguments`, expr);
|
|
7136
8049
|
}
|
|
@@ -7163,7 +8076,7 @@ export function lowerNew(lowerer, expr) {
|
|
|
7163
8076
|
if (errInfo && errInfo.def.name === "%AssertionError") {
|
|
7164
8077
|
// new AssertionError(options): Node validates the options object and
|
|
7165
8078
|
// generates the message from operator, actual and expected.
|
|
7166
|
-
const args = expr.arguments ?? [];
|
|
8079
|
+
const args = expr.arguments?.nodes ?? [];
|
|
7167
8080
|
if (args.length > 1 || args.some(ts.isSpreadElement)) {
|
|
7168
8081
|
lowerer.noLowering(`new AssertionError with this argument list`, expr);
|
|
7169
8082
|
}
|
|
@@ -7176,7 +8089,7 @@ export function lowerNew(lowerer, expr) {
|
|
|
7176
8089
|
};
|
|
7177
8090
|
}
|
|
7178
8091
|
if (errInfo && errInfo.def.name === "%SuppressedError") {
|
|
7179
|
-
const args = expr.arguments ?? [];
|
|
8092
|
+
const args = expr.arguments?.nodes ?? [];
|
|
7180
8093
|
if (args.length > 3 || args.some(ts.isSpreadElement)) {
|
|
7181
8094
|
lowerer.noLowering(`new SuppressedError with this argument list`, expr);
|
|
7182
8095
|
}
|
|
@@ -7189,7 +8102,7 @@ export function lowerNew(lowerer, expr) {
|
|
|
7189
8102
|
};
|
|
7190
8103
|
}
|
|
7191
8104
|
if (errInfo && errInfo.def.name === "%AggregateError") {
|
|
7192
|
-
const args = expr.arguments ?? [];
|
|
8105
|
+
const args = expr.arguments?.nodes ?? [];
|
|
7193
8106
|
if (args.length > 3 || args.some(ts.isSpreadElement)) {
|
|
7194
8107
|
lowerer.noLowering(`new AggregateError with this argument list`, expr);
|
|
7195
8108
|
}
|
|
@@ -7203,7 +8116,7 @@ export function lowerNew(lowerer, expr) {
|
|
|
7203
8116
|
};
|
|
7204
8117
|
}
|
|
7205
8118
|
if (errInfo) {
|
|
7206
|
-
const args = lowerer.errorConstructorArgs(expr.arguments ?? [], loc, expr);
|
|
8119
|
+
const args = lowerer.errorConstructorArgs(expr.arguments?.nodes ?? [], loc, expr);
|
|
7207
8120
|
return {
|
|
7208
8121
|
kind: "libCall",
|
|
7209
8122
|
fn: "error.newOptions",
|
|
@@ -7217,8 +8130,8 @@ export function lowerNew(lowerer, expr) {
|
|
|
7217
8130
|
// (@types/node's captureRejections) has no lowering.
|
|
7218
8131
|
const emitterInfo = lowerer.builtinEmitterInfoOf(symbol);
|
|
7219
8132
|
if (emitterInfo) {
|
|
7220
|
-
if ((expr.arguments ?? []).length > 0) {
|
|
7221
|
-
lowerer.unsupported("SC1090", expr.arguments[0], "EventEmitter constructor options ('captureRejections')");
|
|
8133
|
+
if ((expr.arguments?.nodes ?? []).length > 0) {
|
|
8134
|
+
lowerer.unsupported("SC1090", expr.arguments.nodes[0], "EventEmitter constructor options ('captureRejections')");
|
|
7222
8135
|
}
|
|
7223
8136
|
return {
|
|
7224
8137
|
kind: "libCall",
|
|
@@ -7238,8 +8151,8 @@ export function lowerNew(lowerer, expr) {
|
|
|
7238
8151
|
return lowerStreamNew(lowerer, expr, streamInfo);
|
|
7239
8152
|
const zlibMode = zlibStreamModeOf(lowerer, symbol);
|
|
7240
8153
|
if (zlibMode !== null) {
|
|
7241
|
-
const what = `new zlib.${
|
|
7242
|
-
return lowerZlibStreamNew(lowerer, expr.arguments ?? [], zlibMode, what, expr, loc);
|
|
8154
|
+
const what = `new zlib.${zlibClassName(zlibMode)}`;
|
|
8155
|
+
return lowerZlibStreamNew(lowerer, expr.arguments?.nodes ?? [], zlibMode, what, expr, loc);
|
|
7243
8156
|
}
|
|
7244
8157
|
// `new URL(input)`: the WHATWG URL class (stdlib/@types provenance —
|
|
7245
8158
|
// a user's own `class URL` resolves through classBySymbol below).
|
|
@@ -7248,8 +8161,8 @@ export function lowerNew(lowerer, expr) {
|
|
|
7248
8161
|
// libregexp engine the literals ride. The pattern compiles EAGERLY,
|
|
7249
8162
|
// so bad input throws Node's catchable SyntaxError at construction.
|
|
7250
8163
|
// Checked arguments retain native regexes and perform runtime coercion.
|
|
7251
|
-
if (symbol && symbol
|
|
7252
|
-
const args = expr.arguments ?? [];
|
|
8164
|
+
if (symbol && ts.symbolName(symbol) === "RegExp" && lowerer.isStdlibSymbol(symbol)) {
|
|
8165
|
+
const args = expr.arguments?.nodes ?? [];
|
|
7253
8166
|
if (args.length > 2) {
|
|
7254
8167
|
lowerer.noLowering(`new RegExp with ${args.length} arguments`, expr);
|
|
7255
8168
|
}
|
|
@@ -7297,16 +8210,10 @@ export function lowerNew(lowerer, expr) {
|
|
|
7297
8210
|
};
|
|
7298
8211
|
const pattern = strArg(args[0], "pattern");
|
|
7299
8212
|
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
|
-
}
|
|
8213
|
+
// Node accepts the 'd' flag the engine does not have; a literal
|
|
8214
|
+
// flags string refuses here like the literal regex form.
|
|
8215
|
+
if (flags.kind === "strLit" && args[1] !== undefined && flags.value.includes("d")) {
|
|
8216
|
+
lowerer.unsupported("SC1120", args[1], "the regex 'd' flag (match indices)");
|
|
7310
8217
|
}
|
|
7311
8218
|
return {
|
|
7312
8219
|
kind: "libCall",
|
|
@@ -7316,27 +8223,64 @@ export function lowerNew(lowerer, expr) {
|
|
|
7316
8223
|
loc,
|
|
7317
8224
|
};
|
|
7318
8225
|
}
|
|
7319
|
-
if (symbol && symbol
|
|
8226
|
+
if (symbol && ts.symbolName(symbol) === "URL" && lowerer.isStdlibSymbol(symbol)) {
|
|
7320
8227
|
return lowerUrlNew(lowerer, expr);
|
|
7321
8228
|
}
|
|
7322
8229
|
// `new URLSearchParams(init?)`: the WHATWG list (stdlib provenance —
|
|
7323
8230
|
// see lowerSearchParamsNew for the lowered init shapes).
|
|
7324
|
-
if (symbol && symbol
|
|
8231
|
+
if (symbol && ts.symbolName(symbol) === "URLSearchParams" && lowerer.isStdlibSymbol(symbol)) {
|
|
7325
8232
|
return lowerSearchParamsNew(lowerer, expr, loc);
|
|
7326
8233
|
}
|
|
7327
8234
|
// Date's read-only value slice: store the constructor's TimeClip'd
|
|
7328
8235
|
// epoch milliseconds as the scalar date kind. That is sufficient
|
|
7329
8236
|
// for every getter and toISOString; identity and setters stay
|
|
7330
8237
|
// 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
|
|
8238
|
+
if (symbol && ts.symbolName(symbol) === "Date" && lowerer.isStdlibSymbol(symbol)) {
|
|
8239
|
+
const args = expr.arguments?.nodes ?? [];
|
|
8240
|
+
if (args.some(ts.isSpreadElement)) {
|
|
8241
|
+
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);
|
|
8242
|
+
}
|
|
8243
|
+
// new Date(year, monthIndex[, date[, hours[, minutes[, seconds[, ms]]]]]):
|
|
8244
|
+
// local-time fields, converted to UTC in the host zone at run time.
|
|
8245
|
+
// JavaScript callers pass their arguments to the runtime's ToNumber
|
|
8246
|
+
// (in order, exactly the constructor's coercions); typed callers
|
|
8247
|
+
// pass numbers, completed with the spec's defaults (date 1, time
|
|
8248
|
+
// parts 0) for the seven-f64 ABI.
|
|
8249
|
+
if (args.length > 1) {
|
|
8250
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(expr))) {
|
|
8251
|
+
return {
|
|
8252
|
+
kind: "libCall",
|
|
8253
|
+
fn: "date.nativeNewFields",
|
|
8254
|
+
args: [
|
|
8255
|
+
{
|
|
8256
|
+
kind: "dynArrLit",
|
|
8257
|
+
elems: args.map((arg) => lowerer.lowerExprExpecting(arg, DYN)),
|
|
8258
|
+
type: DYN,
|
|
8259
|
+
loc,
|
|
8260
|
+
},
|
|
8261
|
+
],
|
|
8262
|
+
type: DYN,
|
|
8263
|
+
loc,
|
|
8264
|
+
};
|
|
8265
|
+
}
|
|
8266
|
+
if (args.length > 7) {
|
|
8267
|
+
lowerer.noLowering(`new Date with ${args.length} arguments`, expr, undefined, symbol);
|
|
8268
|
+
}
|
|
8269
|
+
const defaults = [0, 0, 1, 0, 0, 0, 0];
|
|
8270
|
+
const fields = [];
|
|
8271
|
+
for (let i = 0; i < 7; i++) {
|
|
8272
|
+
const arg = args[i];
|
|
8273
|
+
fields.push(arg !== undefined
|
|
8274
|
+
? lowerer.lowerExprExpecting(arg, F64)
|
|
8275
|
+
: { kind: "numLit", value: defaults[i], type: F64, loc });
|
|
8276
|
+
}
|
|
8277
|
+
return { kind: "libCall", fn: "date.newLocal", args: fields, type: DATE_T, loc };
|
|
7335
8278
|
}
|
|
7336
|
-
if (isJsSourceFile(
|
|
8279
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(expr))) {
|
|
7337
8280
|
return {
|
|
7338
8281
|
kind: "libCall",
|
|
7339
|
-
|
|
8282
|
+
// One argument: a string parses with the full date parser.
|
|
8283
|
+
fn: args.length === 1 ? "date.nativeNewValue" : "date.nativeNew",
|
|
7340
8284
|
args: [
|
|
7341
8285
|
{
|
|
7342
8286
|
kind: "dynArrLit",
|
|
@@ -7365,34 +8309,52 @@ export function lowerNew(lowerer, expr) {
|
|
|
7365
8309
|
lowerer.noLowering(`new Date of '${lowerer.fmt(arg.type)}' values`, args[0], "pass milliseconds, a date string, or another Date value", symbol);
|
|
7366
8310
|
}
|
|
7367
8311
|
// `new StringDecoder(encoding?)` (node:string_decoder): the decoder
|
|
7368
|
-
// is a two-field record — the CANONICAL encoding name (
|
|
7369
|
-
//
|
|
7370
|
-
//
|
|
7371
|
-
//
|
|
7372
|
-
//
|
|
7373
|
-
|
|
7374
|
-
|
|
8312
|
+
// is a two-field record — the CANONICAL encoding name (exactly what
|
|
8313
|
+
// `.encoding` answers in Node) and the packed-f64 pending state
|
|
8314
|
+
// starting at 0 (nothing buffered). A literal Buffer encoding folds
|
|
8315
|
+
// its alias at compile time; any other encoding argument is
|
|
8316
|
+
// normalized at run time (Node's normalizeEncoding, which throws
|
|
8317
|
+
// ERR_UNKNOWN_ENCODING for an unknown name). Omitted means utf8,
|
|
8318
|
+
// Node's default.
|
|
8319
|
+
if (symbol && ts.symbolName(symbol) === "StringDecoder" && lowerer.isStdlibSymbol(symbol)) {
|
|
8320
|
+
const args = expr.arguments?.nodes ?? [];
|
|
7375
8321
|
if (args.length > 1) {
|
|
7376
8322
|
lowerer.noLowering("new StringDecoder with 2 arguments", expr, undefined, symbol);
|
|
7377
8323
|
}
|
|
7378
|
-
const
|
|
8324
|
+
const encNode = args[0];
|
|
8325
|
+
const encT = encNode ? lowerer.typeOf(encNode) : undefined;
|
|
8326
|
+
const encName = !encNode
|
|
8327
|
+
? "utf8"
|
|
8328
|
+
: encT.isStringLiteralType()
|
|
8329
|
+
? knownBufEncoding(encT.value)
|
|
8330
|
+
: undefined;
|
|
8331
|
+
const encoding = encName !== undefined
|
|
8332
|
+
? { kind: "strLit", value: encName, type: STRING, loc }
|
|
8333
|
+
: {
|
|
8334
|
+
kind: "libCall",
|
|
8335
|
+
fn: "strdec.encoding",
|
|
8336
|
+
args: [lowerer.lowerExprExpecting(encNode, DYN)],
|
|
8337
|
+
type: STRING,
|
|
8338
|
+
loc,
|
|
8339
|
+
};
|
|
7379
8340
|
const decT = lowerer.mapTypeOf(lowerer.typeOf(expr));
|
|
7380
8341
|
if (decT?.kind !== "record")
|
|
7381
8342
|
lowerer.badType(expr, lowerer.typeOf(expr));
|
|
7382
8343
|
return {
|
|
7383
8344
|
kind: "recordLit",
|
|
7384
8345
|
fields: [
|
|
7385
|
-
{ name: "%enc", value:
|
|
8346
|
+
{ name: "%enc", value: encoding },
|
|
7386
8347
|
{ name: "%pending", value: { kind: "numLit", value: 0, type: F64, loc } },
|
|
7387
8348
|
],
|
|
7388
8349
|
type: decT,
|
|
7389
8350
|
loc,
|
|
7390
8351
|
};
|
|
7391
8352
|
}
|
|
8353
|
+
const codec = symbol ? ts.symbolName(symbol) : undefined;
|
|
7392
8354
|
if (symbol &&
|
|
7393
|
-
(
|
|
8355
|
+
(codec === "TextDecoder" || codec === "TextEncoder") &&
|
|
7394
8356
|
lowerer.isStdlibSymbol(symbol)) {
|
|
7395
|
-
return lowerTextCodecNew(lowerer, expr,
|
|
8357
|
+
return lowerTextCodecNew(lowerer, expr, codec);
|
|
7396
8358
|
}
|
|
7397
8359
|
// `new Uint8Array(...)` / `new Uint32Array(...)` / `new
|
|
7398
8360
|
// Float32Array(...)` / `new Float64Array(...)`: the typed-array
|
|
@@ -7426,25 +8388,26 @@ export function lowerNew(lowerer, expr) {
|
|
|
7426
8388
|
// types get their half named specifically instead of the component
|
|
7427
8389
|
// fence (SC2009, which names Map slots at value positions elsewhere).
|
|
7428
8390
|
// Both Array() and new Array() share the elements/count lowering.
|
|
7429
|
-
if (symbol
|
|
7430
|
-
const object = lowerObjectConstructor(lowerer, expr.arguments ?? [], loc);
|
|
8391
|
+
if (symbol !== null && ts.symbolName(symbol) === "Object" && lowerer.isStdlibSymbol(symbol)) {
|
|
8392
|
+
const object = lowerObjectConstructor(lowerer, expr.arguments?.nodes ?? [], loc);
|
|
7431
8393
|
if (object)
|
|
7432
8394
|
return object;
|
|
7433
8395
|
}
|
|
7434
|
-
if (symbol
|
|
7435
|
-
return lowerArrayConstructor(lowerer, expr, expr.arguments ?? []);
|
|
8396
|
+
if (symbol !== null && ts.symbolName(symbol) === "Array" && lowerer.isStdlibSymbol(symbol)) {
|
|
8397
|
+
return lowerArrayConstructor(lowerer, expr, expr.arguments?.nodes ?? []);
|
|
7436
8398
|
}
|
|
7437
|
-
|
|
7438
|
-
|
|
8399
|
+
// A const alias (`const M = Map`) constructs the same Map.
|
|
8400
|
+
if (ts.isIdentifier(identifier) && lowerer.isStdlibGlobal(identifier, "Map")) {
|
|
8401
|
+
const seedArg = (expr.arguments?.nodes.length ?? 0) === 1 ? expr.arguments.nodes[0] : null;
|
|
7439
8402
|
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)
|
|
8403
|
+
el.elements.nodes.length === 2 &&
|
|
8404
|
+
!el.elements.nodes.some(ts.isSpreadElement);
|
|
8405
|
+
const entriesLit = seedArg && ts.isArrayLiteralExpression(seedArg) && seedArg.elements.nodes.every(isPairLit)
|
|
8406
|
+
? seedArg.elements.nodes.filter(isPairLit)
|
|
7444
8407
|
: null;
|
|
7445
8408
|
let tsType = lowerer.typeOf(expr);
|
|
7446
8409
|
let mapped = lowerer.mapTypeOf(tsType);
|
|
7447
|
-
if (mapped === null && isJsSourceFile(
|
|
8410
|
+
if (mapped === null && isJsSourceFile(ts.getSourceFileOfNode(expr)))
|
|
7448
8411
|
mapped = lowerer.irTypeOf(expr);
|
|
7449
8412
|
const fieldType = assignedThisFieldType(lowerer, expr);
|
|
7450
8413
|
if (mapped?.kind !== "map" && fieldType?.kind === "map")
|
|
@@ -7459,8 +8422,8 @@ export function lowerNew(lowerer, expr) {
|
|
|
7459
8422
|
parent = parent.parent;
|
|
7460
8423
|
// `satisfies` checks a view but retains the expression's own type.
|
|
7461
8424
|
const contextualSeed = !ts.isSatisfiesExpression(parent) &&
|
|
7462
|
-
(expr.typeArguments?.length ?? 0) === 0 &&
|
|
7463
|
-
(entriesLit !== null || (expr.arguments?.length ?? 0) === 0);
|
|
8425
|
+
(expr.typeArguments?.nodes.length ?? 0) === 0 &&
|
|
8426
|
+
(entriesLit !== null || (expr.arguments?.nodes.length ?? 0) === 0);
|
|
7464
8427
|
// JavaScript's `new Map()` has no type-argument syntax: the no-arg
|
|
7465
8428
|
// constructor overload pins Map<any, any> whatever the JSDoc says
|
|
7466
8429
|
// (`@type` on the declaration types the VARIABLE, not this
|
|
@@ -7480,7 +8443,7 @@ export function lowerNew(lowerer, expr) {
|
|
|
7480
8443
|
if (seeded)
|
|
7481
8444
|
return seeded;
|
|
7482
8445
|
}
|
|
7483
|
-
if ((expr.arguments?.length ?? 0) > 0 && !entriesLit) {
|
|
8446
|
+
if ((expr.arguments?.nodes.length ?? 0) > 0 && !entriesLit) {
|
|
7484
8447
|
lowerer.noLowering("new Map(entries)", expr, "supported seeds: an array literal of [key, value] pair literals, or a " +
|
|
7485
8448
|
"[K, V][]-typed tuple-array value, a matching collection or collection iterator, or null/undefined");
|
|
7486
8449
|
}
|
|
@@ -7488,10 +8451,10 @@ export function lowerNew(lowerer, expr) {
|
|
|
7488
8451
|
if (!entriesLit)
|
|
7489
8452
|
return { kind: "mapNew", type: mapped, loc };
|
|
7490
8453
|
const seed = entriesLit.map((pair) => ({
|
|
7491
|
-
key: lowerer.lowerCollectionKey(pair.elements[0], mapped.key),
|
|
8454
|
+
key: lowerer.lowerCollectionKey(pair.elements.nodes[0], mapped.key),
|
|
7492
8455
|
value: mapped.value.kind === "dyn"
|
|
7493
|
-
? lowerer.lowerCollectionKey(pair.elements[1], mapped.value)
|
|
7494
|
-
: lowerer.lowerExprExpecting(pair.elements[1], mapped.value),
|
|
8456
|
+
? lowerer.lowerCollectionKey(pair.elements.nodes[1], mapped.value)
|
|
8457
|
+
: lowerer.lowerExprExpecting(pair.elements.nodes[1], mapped.value),
|
|
7495
8458
|
}));
|
|
7496
8459
|
return { kind: "mapNew", seed, type: mapped, loc };
|
|
7497
8460
|
}
|
|
@@ -7504,8 +8467,8 @@ export function lowerNew(lowerer, expr) {
|
|
|
7504
8467
|
// config-cache shape: module init constructs the caches
|
|
7505
8468
|
// unconditionally; the format path never touches them. TypeScript
|
|
7506
8469
|
// keeps the compile fence.
|
|
7507
|
-
if (isJsSourceFile(
|
|
7508
|
-
(expr.arguments?.length ?? 0) === 0 &&
|
|
8470
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(expr)) &&
|
|
8471
|
+
(expr.arguments?.nodes.length ?? 0) === 0 &&
|
|
7509
8472
|
targs.length > 0 &&
|
|
7510
8473
|
targs.every((t) => (t.flags & ts.TypeFlags.Any) !== 0)) {
|
|
7511
8474
|
return { kind: "dynObjLit", type: DYN, loc };
|
|
@@ -7519,21 +8482,22 @@ export function lowerNew(lowerer, expr) {
|
|
|
7519
8482
|
}
|
|
7520
8483
|
if (targs[1]) {
|
|
7521
8484
|
lowerer.unsupported("SC1090", expr, `Map values of type '${lowerer.checker.typeToString(targs[1])}' ` +
|
|
7522
|
-
`(Map values must be number, string, boolean, records, class instances, ` +
|
|
8485
|
+
`(Map values must be number, string, boolean, records, class instances, functions, ` +
|
|
7523
8486
|
`typed arrays, arrays, promises, Maps, Sets, or supported unions and checked values)`);
|
|
7524
8487
|
}
|
|
7525
8488
|
lowerer.badType(expr, tsType);
|
|
7526
8489
|
}
|
|
7527
8490
|
// Weak containers share checked native key identities and lifetime hooks.
|
|
7528
|
-
if ((symbol
|
|
8491
|
+
if (((symbol !== null && ts.symbolName(symbol) === "WeakMap") ||
|
|
8492
|
+
(symbol !== null && ts.symbolName(symbol) === "WeakSet")) &&
|
|
7529
8493
|
lowerer.isStdlibSymbol(symbol)) {
|
|
7530
|
-
const args = expr.arguments ?? [];
|
|
8494
|
+
const args = expr.arguments?.nodes ?? [];
|
|
7531
8495
|
if (args.length > 1 || args.some(ts.isSpreadElement)) {
|
|
7532
|
-
lowerer.unsupported("SC1090", expr, `${symbol
|
|
8496
|
+
lowerer.unsupported("SC1090", expr, `${ts.symbolName(symbol)} construction with surplus or spread arguments`);
|
|
7533
8497
|
}
|
|
7534
8498
|
return {
|
|
7535
8499
|
kind: "libCall",
|
|
7536
|
-
fn: symbol
|
|
8500
|
+
fn: ts.symbolName(symbol) === "WeakMap" ? "weakMap.new" : "weakSet.new",
|
|
7537
8501
|
args: [args[0] ? lowerer.lowerExprExpecting(args[0], DYN) : dynUndefinedExpr(loc)],
|
|
7538
8502
|
type: DYN,
|
|
7539
8503
|
loc,
|
|
@@ -7541,27 +8505,27 @@ export function lowerNew(lowerer, expr) {
|
|
|
7541
8505
|
}
|
|
7542
8506
|
// `new Set<T>()`: construct + bulk add from supported values,
|
|
7543
8507
|
// including live collection cursors. Duplicates collapse in insertion order.
|
|
7544
|
-
if (
|
|
8508
|
+
if (ts.isIdentifier(identifier) && lowerer.isStdlibGlobal(identifier, "Set")) {
|
|
7545
8509
|
const tsType = lowerer.typeOf(expr);
|
|
7546
8510
|
let mapped = lowerer.mapTypeOf(tsType);
|
|
7547
8511
|
const fieldType = assignedThisFieldType(lowerer, expr);
|
|
7548
8512
|
if (mapped?.kind !== "set" && fieldType?.kind === "set")
|
|
7549
8513
|
mapped = fieldType;
|
|
7550
|
-
if (mapped?.kind === "set" && (expr.arguments?.length ?? 0) === 1) {
|
|
7551
|
-
const seeded = lowerSetSeedNew(lowerer, expr.arguments[0], mapped);
|
|
8514
|
+
if (mapped?.kind === "set" && (expr.arguments?.nodes.length ?? 0) === 1) {
|
|
8515
|
+
const seeded = lowerSetSeedNew(lowerer, expr.arguments.nodes[0], mapped);
|
|
7552
8516
|
if (seeded)
|
|
7553
8517
|
return seeded;
|
|
7554
8518
|
}
|
|
7555
8519
|
if (!mapped &&
|
|
7556
|
-
isJsSourceFile(
|
|
7557
|
-
(expr.arguments?.length ?? 0) <= 1 &&
|
|
7558
|
-
!expr.arguments?.some(ts.isSpreadElement)) {
|
|
8520
|
+
isJsSourceFile(ts.getSourceFileOfNode(expr)) &&
|
|
8521
|
+
(expr.arguments?.nodes.length ?? 0) <= 1 &&
|
|
8522
|
+
!expr.arguments?.nodes.some(ts.isSpreadElement)) {
|
|
7559
8523
|
return {
|
|
7560
8524
|
kind: "libCall",
|
|
7561
8525
|
fn: "dyn.nativeSetNew",
|
|
7562
8526
|
args: [
|
|
7563
|
-
expr.arguments?.[0]
|
|
7564
|
-
? lowerer.lowerExprExpecting(expr.arguments[0], DYN)
|
|
8527
|
+
expr.arguments?.nodes[0]
|
|
8528
|
+
? lowerer.lowerExprExpecting(expr.arguments.nodes[0], DYN)
|
|
7565
8529
|
: dynUndefinedExpr(loc),
|
|
7566
8530
|
],
|
|
7567
8531
|
type: DYN,
|
|
@@ -7574,12 +8538,12 @@ export function lowerNew(lowerer, expr) {
|
|
|
7574
8538
|
// (interned strings — see the JS token stance in lower-exprs), so
|
|
7575
8539
|
// the honest construction is a Set of those scalars.
|
|
7576
8540
|
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));
|
|
8541
|
+
isJsSourceFile(ts.getSourceFileOfNode(expr)) &&
|
|
8542
|
+
(expr.arguments?.nodes.length ?? 0) === 1 &&
|
|
8543
|
+
ts.isArrayLiteralExpression(expr.arguments.nodes[0]) &&
|
|
8544
|
+
!expr.arguments.nodes[0].elements.nodes.some(ts.isSpreadElement)) {
|
|
8545
|
+
const lit = expr.arguments.nodes[0];
|
|
8546
|
+
const elems = lit.elements.nodes.map((el) => lowerer.lowerExpr(el));
|
|
7583
8547
|
const first = elems[0];
|
|
7584
8548
|
if (first !== undefined &&
|
|
7585
8549
|
(first.type.kind === "string" || first.type.kind === "f64") &&
|
|
@@ -7589,7 +8553,7 @@ export function lowerNew(lowerer, expr) {
|
|
|
7589
8553
|
return { kind: "setNew", seed, type: setT, loc };
|
|
7590
8554
|
}
|
|
7591
8555
|
}
|
|
7592
|
-
if ((expr.arguments?.length ?? 0) > 0) {
|
|
8556
|
+
if ((expr.arguments?.nodes.length ?? 0) > 0) {
|
|
7593
8557
|
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
8558
|
"supported key values seeds a Set");
|
|
7595
8559
|
}
|
|
@@ -7605,18 +8569,20 @@ export function lowerNew(lowerer, expr) {
|
|
|
7605
8569
|
// `new AsyncLocalStorage()` (node:async_hooks): a fresh store id —
|
|
7606
8570
|
// an f64 handle (type-mapper.ts), the Channel story. Construction options
|
|
7607
8571
|
// ({ defaultValue, name }) have no lowering yet.
|
|
7608
|
-
if (symbol
|
|
7609
|
-
|
|
8572
|
+
if (symbol !== null &&
|
|
8573
|
+
ts.symbolName(symbol) === "AsyncLocalStorage" &&
|
|
8574
|
+
lowerer.isStdlibSymbol(symbol)) {
|
|
8575
|
+
if ((expr.arguments?.nodes.length ?? 0) > 0) {
|
|
7610
8576
|
lowerer.noLowering("new AsyncLocalStorage(options)", expr, "the zero-argument constructor is the supported form (defaultValue/name options have no lowering yet)");
|
|
7611
8577
|
}
|
|
7612
8578
|
return { kind: "libCall", fn: "als.new", args: [], type: F64, loc };
|
|
7613
8579
|
}
|
|
7614
8580
|
// `new Promise<T>((resolve) => ...)`: the ambient Promise constructor.
|
|
7615
|
-
if (symbol
|
|
8581
|
+
if (symbol !== null && ts.symbolName(symbol) === "Promise" && lowerer.isStdlibSymbol(symbol)) {
|
|
7616
8582
|
const type = lowerer.irTypeOf(expr);
|
|
7617
8583
|
if (type.kind !== "promise")
|
|
7618
8584
|
lowerer.badType(expr, lowerer.typeOf(expr));
|
|
7619
|
-
const args = expr.arguments ?? [];
|
|
8585
|
+
const args = expr.arguments?.nodes ?? [];
|
|
7620
8586
|
if (args.length !== 1) {
|
|
7621
8587
|
lowerer.unsupported("SC1090", expr, "Promise construction without an executor");
|
|
7622
8588
|
}
|
|
@@ -7628,8 +8594,9 @@ export function lowerNew(lowerer, expr) {
|
|
|
7628
8594
|
const a0 = args[0];
|
|
7629
8595
|
if (ts.isIdentifier(a0) && a0.text === "setImmediate") {
|
|
7630
8596
|
const sym = lowerer.checker.getSymbolAtLocation(a0);
|
|
7631
|
-
const decls = sym ?
|
|
7632
|
-
if (decls.length > 0 &&
|
|
8597
|
+
const decls = sym ? sym.declarations : [];
|
|
8598
|
+
if (decls.length > 0 &&
|
|
8599
|
+
decls.every((d) => lowerer.isStdlibFile(ts.getSourceFileOfNode(d)))) {
|
|
7633
8600
|
// The settled value is the undefined dyn value — the result
|
|
7634
8601
|
// is promise<dyn> whatever T the checker inferred for the
|
|
7635
8602
|
// unusual executor (Promise<unknown> in the suite's shape).
|
|
@@ -7650,7 +8617,10 @@ export function lowerNew(lowerer, expr) {
|
|
|
7650
8617
|
// catch-side instanceof and the uncaught printer working). First
|
|
7651
8618
|
// settle wins, exactly JS: reject-after-resolve and double-reject
|
|
7652
8619
|
// are no-ops, and an executor throw after any settle is swallowed.
|
|
7653
|
-
|
|
8620
|
+
let executor = lowerer.lowerExpr(args[0]);
|
|
8621
|
+
if (executor.type.kind !== "func")
|
|
8622
|
+
lowerer.badType(args[0], lowerer.typeOf(args[0]));
|
|
8623
|
+
executor = adaptPromiseExecutor(lowerer, executor, type.inner, loc) ?? executor;
|
|
7654
8624
|
if (executor.type.kind !== "func")
|
|
7655
8625
|
lowerer.badType(args[0], lowerer.typeOf(args[0]));
|
|
7656
8626
|
if (executor.type.params.length > 1) {
|
|
@@ -7682,11 +8652,11 @@ export function lowerNew(lowerer, expr) {
|
|
|
7682
8652
|
// Every other new Buffer form keeps the fence below — the
|
|
7683
8653
|
// constructing forms would owe the deprecation warning.
|
|
7684
8654
|
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]);
|
|
8655
|
+
expr.arguments?.nodes.length === 2 &&
|
|
8656
|
+
!expr.arguments.nodes.some(ts.isSpreadElement) &&
|
|
8657
|
+
lowerer.mapTypeOf(lowerer.typeOf(expr.arguments.nodes[0]))?.kind !== "string" &&
|
|
8658
|
+
lowerer.mapTypeOf(lowerer.typeOf(expr.arguments.nodes[1]))?.kind === "string") {
|
|
8659
|
+
const first = lowerer.lowerExpr(expr.arguments.nodes[0]);
|
|
7690
8660
|
if (first.kind === "unitLit" ||
|
|
7691
8661
|
first.type.kind === "dyn" ||
|
|
7692
8662
|
lowerer.dynConvertible(first.type)) {
|
|
@@ -7695,7 +8665,7 @@ export function lowerNew(lowerer, expr) {
|
|
|
7695
8665
|
// throw only via the ctor body's later reads — it does NOT
|
|
7696
8666
|
// observe it before throwing, so dropping it is exact for
|
|
7697
8667
|
// effect-free operands; effectful ones keep the fence.
|
|
7698
|
-
const enc = lowerer.lowerExpr(expr.arguments[1]);
|
|
8668
|
+
const enc = lowerer.lowerExpr(expr.arguments.nodes[1]);
|
|
7699
8669
|
if (enc.kind === "strLit" || isSafeToRepeat(enc)) {
|
|
7700
8670
|
return {
|
|
7701
8671
|
kind: "libCall",
|
|
@@ -7745,7 +8715,7 @@ export function lowerNew(lowerer, expr) {
|
|
|
7745
8715
|
return bi?.module === "crypto" && bi.member === "X509Certificate";
|
|
7746
8716
|
})());
|
|
7747
8717
|
if (isX509) {
|
|
7748
|
-
const args = expr.arguments ?? [];
|
|
8718
|
+
const args = expr.arguments?.nodes ?? [];
|
|
7749
8719
|
if (args.length !== 1) {
|
|
7750
8720
|
lowerer.noLowering("X509Certificate with this argument shape", expr, "the supported form is new X509Certificate(readFileSync(path))");
|
|
7751
8721
|
}
|
|
@@ -7838,29 +8808,55 @@ export function lowerNew(lowerer, expr) {
|
|
|
7838
8808
|
return lowerCheckedConstructor(lowerer, expr, callee);
|
|
7839
8809
|
if (callee.type.kind !== "classval")
|
|
7840
8810
|
lowerer.badType(expr.expression, lowerer.typeOf(expr.expression));
|
|
7841
|
-
lowerer.noteEdge(
|
|
8811
|
+
lowerer.noteEdge(classValueConstructor(info.def).fn);
|
|
7842
8812
|
// Every constructor a value in this slot can dispatch to is a
|
|
7843
8813
|
// descendant's — mark them reachable like a virtual edge.
|
|
7844
8814
|
const below = (c) => {
|
|
7845
8815
|
for (const s of c.subclasses) {
|
|
7846
|
-
lowerer.noteEdge(
|
|
8816
|
+
lowerer.noteEdge(classValueConstructor(s.def).fn);
|
|
7847
8817
|
below(s);
|
|
7848
8818
|
}
|
|
7849
8819
|
};
|
|
7850
8820
|
below(info);
|
|
7851
|
-
|
|
7852
|
-
|
|
8821
|
+
// EventEmitter and stream class values construct without options
|
|
8822
|
+
// only: a slot of either may hold any of those classes, and the
|
|
8823
|
+
// direct `new Readable({...})` lowering reads its options at compile
|
|
8824
|
+
// time (EventEmitter's options have no lowering at all).
|
|
8825
|
+
if ((info.builtinStream !== undefined || info.builtinEmitter) &&
|
|
8826
|
+
(expr.arguments?.nodes.length ?? 0) > 0) {
|
|
8827
|
+
lowerer.unsupported("SC1090", expr, `EventEmitter and stream class values constructed with options (construct with 'new ${info.def.name.slice(1)}({ ... })' directly)`);
|
|
8828
|
+
}
|
|
8829
|
+
// A program class whose constructor is the inherited runtime one
|
|
8830
|
+
// takes no arguments through its class value either.
|
|
8831
|
+
refuseInheritedBuiltinCtorArgs(lowerer, info, expr);
|
|
8832
|
+
defineClassValueConstruct(lowerer, info);
|
|
8833
|
+
const args = lowerer.completeArgs(expr.arguments?.nodes ?? [], classValueParams(info), loc, expr);
|
|
8834
|
+
const built = constructedFromValue(lowerer, info, {
|
|
7853
8835
|
kind: "newValue",
|
|
7854
8836
|
callee,
|
|
7855
8837
|
args,
|
|
7856
8838
|
type: { kind: "object", className: info.def.name },
|
|
7857
8839
|
loc,
|
|
7858
|
-
};
|
|
8840
|
+
}, expr);
|
|
8841
|
+
// A runtime class slot widened from a union (`[Readable, Writable]`'s
|
|
8842
|
+
// elements hold EventEmitter values): the checker types the result as
|
|
8843
|
+
// the union of the arms' instances, which the checked class view
|
|
8844
|
+
// answers from the instance's class.
|
|
8845
|
+
if (info.def.runtime) {
|
|
8846
|
+
const resultT = lowerer.mapTypeOf(lowerer.typeOf(expr));
|
|
8847
|
+
if (resultT?.kind === "union") {
|
|
8848
|
+
const asserted = checkedClassUnionAssertion(lowerer, built, resultT, loc);
|
|
8849
|
+
if (asserted)
|
|
8850
|
+
return asserted;
|
|
8851
|
+
}
|
|
8852
|
+
}
|
|
8853
|
+
return built;
|
|
7859
8854
|
}
|
|
7860
8855
|
if (calleeT?.kind === "union") {
|
|
7861
8856
|
const def = lowerer.unions.get(calleeT.unionId);
|
|
7862
8857
|
if (def?.arms.some((a) => a.kind === "classval")) {
|
|
7863
|
-
if (def.arms.every((arm) => arm.kind === "classval" ||
|
|
8858
|
+
if (def.arms.every((arm) => arm.kind === "classval" ||
|
|
8859
|
+
(isJsSourceFile(ts.getSourceFileOfNode(expr)) && isUnitType(arm))) &&
|
|
7864
8860
|
lowerer.dynConvertible(calleeT)) {
|
|
7865
8861
|
const callee = lowerer.lowerExprExpecting(expr.expression, DYN);
|
|
7866
8862
|
return lowerCheckedConstructor(lowerer, expr, callee);
|
|
@@ -7884,7 +8880,7 @@ export function lowerNew(lowerer, expr) {
|
|
|
7884
8880
|
if (ctorName !== null) {
|
|
7885
8881
|
const raw = lowerer.checker.getSymbolAtLocation(ctorName);
|
|
7886
8882
|
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
|
|
8883
|
+
const hint = sym && lowerer.isStdlibSymbol(sym) ? own(STDLIB_CTOR_HINTS, ts.symbolName(sym)) : undefined;
|
|
7888
8884
|
if (hint !== undefined) {
|
|
7889
8885
|
lowerer.unsupported("SC1090", expr, hint);
|
|
7890
8886
|
}
|
|
@@ -7896,13 +8892,22 @@ export function lowerNew(lowerer, expr) {
|
|
|
7896
8892
|
(callee.type.kind === "dyn" ||
|
|
7897
8893
|
((callee.type.kind === "func" || callee.type.kind === "classval") &&
|
|
7898
8894
|
lowerer.dynConvertible(callee.type)))) {
|
|
7899
|
-
|
|
8895
|
+
let boxed = lowerer.coerceToExpected(callee, DYN);
|
|
8896
|
+
// A plain function's box carries its name: the construction's
|
|
8897
|
+
// prototype records it as `constructor`, which util.inspect prints
|
|
8898
|
+
// (`F { a: 2 }`).
|
|
8899
|
+
if (boxed.kind === "dynFrom" && boxed.fnName === undefined && callee.type.kind === "func") {
|
|
8900
|
+
const name = jsFuncNameOf(expr.expression, lowerer);
|
|
8901
|
+
if (name !== null)
|
|
8902
|
+
boxed = { ...boxed, fnName: name };
|
|
8903
|
+
}
|
|
8904
|
+
return lowerCheckedConstructor(lowerer, expr, boxed);
|
|
7900
8905
|
}
|
|
7901
8906
|
lowerer.unsupported("SC1090", expr, "constructing values other than classes declared in the program");
|
|
7902
8907
|
}
|
|
7903
8908
|
function lowerCheckedConstructor(lowerer, expr, callee) {
|
|
7904
8909
|
const loc = locOf(expr);
|
|
7905
|
-
const args = expr.arguments ?? [];
|
|
8910
|
+
const args = expr.arguments?.nodes ?? [];
|
|
7906
8911
|
if (args.some(ts.isSpreadElement)) {
|
|
7907
8912
|
const packed = lowerer.completeArgs(args, [{ type: DYN, mode: "dynRest" }], loc, expr)[0];
|
|
7908
8913
|
return checkedClassConstructionPacked(lowerer, callee, packed, loc);
|