@scriptc/compiler 0.3.5 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ambient/scriptc-node-fallback.d.ts +960 -82
- package/ambient/scriptc.d.ts +134 -0
- package/dist/backend/cycle-analysis.d.ts +1 -1
- package/dist/backend/cycle-analysis.js +1 -0
- package/dist/backend/cycle-analysis.js.map +1 -1
- package/dist/backend/cycle-analysis.test.js +13 -1
- package/dist/backend/cycle-analysis.test.js.map +1 -1
- package/dist/backend/cycle-mutability.js +16 -5
- package/dist/backend/cycle-mutability.js.map +1 -1
- package/dist/backend/executable-features.js +13 -0
- package/dist/backend/executable-features.js.map +1 -1
- package/dist/backend/immutability.test.js +1 -1
- package/dist/backend/library-pack.js +6 -0
- package/dist/backend/library-pack.js.map +1 -1
- package/dist/backend/llvm/alloc.d.ts +41 -4
- package/dist/backend/llvm/alloc.js +138 -7
- package/dist/backend/llvm/alloc.js.map +1 -1
- package/dist/backend/llvm/alloc.test.js +30 -1
- package/dist/backend/llvm/alloc.test.js.map +1 -1
- package/dist/backend/llvm/appended-array-literals.test.js +1 -1
- package/dist/backend/llvm/array-search.test.js +1 -1
- package/dist/backend/llvm/blocks.d.ts +8 -0
- package/dist/backend/llvm/blocks.js +43 -1
- package/dist/backend/llvm/blocks.js.map +1 -1
- package/dist/backend/llvm/blocks.test.js +22 -1
- package/dist/backend/llvm/blocks.test.js.map +1 -1
- package/dist/backend/llvm/byte-numbers.js +15 -5
- package/dist/backend/llvm/byte-numbers.js.map +1 -1
- package/dist/backend/llvm/bytes-alias.d.ts +14 -0
- package/dist/backend/llvm/bytes-alias.js +20 -0
- package/dist/backend/llvm/bytes-alias.js.map +1 -0
- package/dist/backend/llvm/bytes-loop-versions.d.ts +86 -0
- package/dist/backend/llvm/bytes-loop-versions.js +506 -0
- package/dist/backend/llvm/bytes-loop-versions.js.map +1 -0
- package/dist/backend/llvm/bytes-loop-versions.test.d.ts +1 -0
- package/dist/backend/llvm/bytes-loop-versions.test.js +244 -0
- package/dist/backend/llvm/bytes-loop-versions.test.js.map +1 -0
- package/dist/backend/llvm/call-lifetimes.js +50 -1
- package/dist/backend/llvm/call-lifetimes.js.map +1 -1
- package/dist/backend/llvm/call-lifetimes.test.js +34 -0
- package/dist/backend/llvm/call-lifetimes.test.js.map +1 -1
- package/dist/backend/llvm/checked-narrows.test.js +1 -1
- package/dist/backend/llvm/checked-value-lifetimes.js +4 -1
- package/dist/backend/llvm/checked-value-lifetimes.js.map +1 -1
- package/dist/backend/llvm/classes.d.ts +11 -0
- package/dist/backend/llvm/classes.js +71 -14
- package/dist/backend/llvm/classes.js.map +1 -1
- package/dist/backend/llvm/classes.test.js +58 -8
- package/dist/backend/llvm/classes.test.js.map +1 -1
- package/dist/backend/llvm/common.js +1 -0
- package/dist/backend/llvm/common.js.map +1 -1
- package/dist/backend/llvm/constant-callbacks.d.ts +5 -1
- package/dist/backend/llvm/constant-callbacks.js +55 -12
- package/dist/backend/llvm/constant-callbacks.js.map +1 -1
- package/dist/backend/llvm/constant-callbacks.test.js +88 -1
- package/dist/backend/llvm/constant-callbacks.test.js.map +1 -1
- package/dist/backend/llvm/counted-loops.d.ts +4 -0
- package/dist/backend/llvm/counted-loops.js +37 -0
- package/dist/backend/llvm/counted-loops.js.map +1 -1
- package/dist/backend/llvm/dense-array-access.d.ts +12 -3
- package/dist/backend/llvm/dense-array-access.js +72 -14
- package/dist/backend/llvm/dense-array-access.js.map +1 -1
- package/dist/backend/llvm/dense-array-access.test.js +59 -3
- package/dist/backend/llvm/dense-array-access.test.js.map +1 -1
- package/dist/backend/llvm/dense-array-loops.d.ts +51 -0
- package/dist/backend/llvm/dense-array-loops.js +162 -0
- package/dist/backend/llvm/dense-array-loops.js.map +1 -0
- package/dist/backend/llvm/dense-array-loops.test.d.ts +1 -0
- package/dist/backend/llvm/dense-array-loops.test.js +128 -0
- package/dist/backend/llvm/dense-array-loops.test.js.map +1 -0
- package/dist/backend/llvm/dyn-handle-tags.test.d.ts +1 -0
- package/dist/backend/llvm/dyn-handle-tags.test.js +38 -0
- package/dist/backend/llvm/dyn-handle-tags.test.js.map +1 -0
- package/dist/backend/llvm/dyn.d.ts +28 -4
- package/dist/backend/llvm/dyn.js +324 -179
- package/dist/backend/llvm/dyn.js.map +1 -1
- package/dist/backend/llvm/emit-function.d.ts +64 -0
- package/dist/backend/llvm/emit-function.js +1190 -0
- package/dist/backend/llvm/emit-function.js.map +1 -0
- package/dist/backend/llvm/emit-module.d.ts +24 -0
- package/dist/backend/llvm/emit-module.js +1535 -0
- package/dist/backend/llvm/emit-module.js.map +1 -0
- package/dist/backend/llvm/emit-statements.d.ts +58 -0
- package/dist/backend/llvm/emit-statements.js +1964 -0
- package/dist/backend/llvm/emit-statements.js.map +1 -0
- package/dist/backend/llvm/emitter.d.ts +576 -268
- package/dist/backend/llvm/emitter.js +801 -4447
- package/dist/backend/llvm/emitter.js.map +1 -1
- package/dist/backend/llvm/emitter.test.js +57 -3
- package/dist/backend/llvm/emitter.test.js.map +1 -1
- package/dist/backend/llvm/expr-async.js +73 -46
- package/dist/backend/llvm/expr-async.js.map +1 -1
- package/dist/backend/llvm/expr-async.test.js +1 -1
- package/dist/backend/llvm/expr-bytes.d.ts +2 -0
- package/dist/backend/llvm/expr-bytes.js +76 -29
- package/dist/backend/llvm/expr-bytes.js.map +1 -1
- package/dist/backend/llvm/expr-callbacks.d.ts +6 -2
- package/dist/backend/llvm/expr-callbacks.js +48 -11
- package/dist/backend/llvm/expr-callbacks.js.map +1 -1
- package/dist/backend/llvm/expr-calls.d.ts +1 -1
- package/dist/backend/llvm/expr-calls.js +71 -53
- package/dist/backend/llvm/expr-calls.js.map +1 -1
- package/dist/backend/llvm/expr-calls.test.js +1 -1
- package/dist/backend/llvm/expr-containers.js +39 -15
- package/dist/backend/llvm/expr-containers.js.map +1 -1
- package/dist/backend/llvm/expr-control.js +16 -16
- package/dist/backend/llvm/expr-control.js.map +1 -1
- package/dist/backend/llvm/expr-dispatch.js +1 -0
- package/dist/backend/llvm/expr-dispatch.js.map +1 -1
- package/dist/backend/llvm/expr-dynamic.d.ts +3 -0
- package/dist/backend/llvm/expr-dynamic.js +92 -63
- package/dist/backend/llvm/expr-dynamic.js.map +1 -1
- package/dist/backend/llvm/expr-primitives.d.ts +1 -1
- package/dist/backend/llvm/expr-primitives.js +132 -25
- package/dist/backend/llvm/expr-primitives.js.map +1 -1
- package/dist/backend/llvm/expr-primitives.test.js +2 -2
- package/dist/backend/llvm/expr-records.d.ts +1 -1
- package/dist/backend/llvm/expr-records.js +32 -11
- package/dist/backend/llvm/expr-records.js.map +1 -1
- package/dist/backend/llvm/expr-stream-bridges.js +54 -12
- package/dist/backend/llvm/expr-stream-bridges.js.map +1 -1
- package/dist/backend/llvm/expr-stream-bridges.test.js +2 -2
- package/dist/backend/llvm/expr-stream-callbacks.js +22 -1
- package/dist/backend/llvm/expr-stream-callbacks.js.map +1 -1
- package/dist/backend/llvm/int32-abi.test.js +2 -2
- package/dist/backend/llvm/integer-clones.test.js +3 -3
- package/dist/backend/llvm/integer-remainder.d.ts +34 -13
- package/dist/backend/llvm/integer-remainder.js +156 -22
- package/dist/backend/llvm/integer-remainder.js.map +1 -1
- package/dist/backend/llvm/intern-tables.test.js +1 -1
- package/dist/backend/llvm/jsval-encoding.d.ts +21 -0
- package/dist/backend/llvm/jsval-encoding.js +20 -0
- package/dist/backend/llvm/jsval-encoding.js.map +1 -0
- package/dist/backend/llvm/jsval.d.ts +12 -0
- package/dist/backend/llvm/jsval.js +488 -0
- package/dist/backend/llvm/jsval.js.map +1 -0
- package/dist/backend/llvm/lazy-captures.d.ts +12 -2
- package/dist/backend/llvm/lazy-captures.js +39 -17
- package/dist/backend/llvm/lazy-captures.js.map +1 -1
- package/dist/backend/llvm/lib-abi.js +1 -1
- package/dist/backend/llvm/lib-abi.js.map +1 -1
- package/dist/backend/llvm/lib-connect.js +1 -1
- package/dist/backend/llvm/lib-connect.js.map +1 -1
- package/dist/backend/llvm/lib-datagram.js +14 -8
- package/dist/backend/llvm/lib-datagram.js.map +1 -1
- package/dist/backend/llvm/lib-dispatch.js +217 -24
- package/dist/backend/llvm/lib-dispatch.js.map +1 -1
- package/dist/backend/llvm/lib-filesystem.js +102 -13
- package/dist/backend/llvm/lib-filesystem.js.map +1 -1
- package/dist/backend/llvm/lib-http2.js +3 -3
- package/dist/backend/llvm/lib-http2.js.map +1 -1
- package/dist/backend/llvm/lib-lookup.js +2 -2
- package/dist/backend/llvm/lib-lookup.js.map +1 -1
- package/dist/backend/llvm/lib-network.js +77 -25
- package/dist/backend/llvm/lib-network.js.map +1 -1
- package/dist/backend/llvm/lib-process.js +100 -50
- package/dist/backend/llvm/lib-process.js.map +1 -1
- package/dist/backend/llvm/lib-shared.d.ts +12 -0
- package/dist/backend/llvm/lib-shared.js +229 -5
- package/dist/backend/llvm/lib-shared.js.map +1 -1
- package/dist/backend/llvm/lib-stream.js +46 -16
- package/dist/backend/llvm/lib-stream.js.map +1 -1
- package/dist/backend/llvm/lib-test.js +57 -8
- package/dist/backend/llvm/lib-test.js.map +1 -1
- package/dist/backend/llvm/lib-tls.js +4 -9
- package/dist/backend/llvm/lib-tls.js.map +1 -1
- package/dist/backend/llvm/local-array-reads.js +2 -2
- package/dist/backend/llvm/local-array-reads.test.js +1 -1
- package/dist/backend/llvm/local-extents.d.ts +19 -0
- package/dist/backend/llvm/local-extents.js +169 -0
- package/dist/backend/llvm/local-extents.js.map +1 -0
- package/dist/backend/llvm/local-extents.test.d.ts +1 -0
- package/dist/backend/llvm/local-extents.test.js +92 -0
- package/dist/backend/llvm/local-extents.test.js.map +1 -0
- package/dist/backend/llvm/local-union-storage.js +7 -7
- package/dist/backend/llvm/local-union-storage.js.map +1 -1
- package/dist/backend/llvm/local-union-storage.test.js +2 -2
- package/dist/backend/llvm/map-entry-fusion.test.js +1 -1
- package/dist/backend/llvm/map-number-lookup.js +2 -2
- package/dist/backend/llvm/map-number-lookup.test.js +2 -2
- package/dist/backend/llvm/map-read-lifetimes.test.js +2 -2
- package/dist/backend/llvm/narrow-guards.d.ts +38 -0
- package/dist/backend/llvm/narrow-guards.js +151 -0
- package/dist/backend/llvm/narrow-guards.js.map +1 -0
- package/dist/backend/llvm/nullable-unions.d.ts +70 -9
- package/dist/backend/llvm/nullable-unions.js +105 -6
- package/dist/backend/llvm/nullable-unions.js.map +1 -1
- package/dist/backend/llvm/nullable-unions.test.d.ts +1 -0
- package/dist/backend/llvm/nullable-unions.test.js +65 -0
- package/dist/backend/llvm/nullable-unions.test.js.map +1 -0
- package/dist/backend/llvm/publish.d.ts +4 -0
- package/dist/backend/llvm/publish.js +14 -2
- package/dist/backend/llvm/publish.js.map +1 -1
- package/dist/backend/llvm/publish.test.js +1 -1
- package/dist/backend/llvm/receivers.d.ts +31 -0
- package/dist/backend/llvm/receivers.js +395 -0
- package/dist/backend/llvm/receivers.js.map +1 -0
- package/dist/backend/llvm/record-results.d.ts +13 -2
- package/dist/backend/llvm/record-results.js +66 -6
- package/dist/backend/llvm/record-results.js.map +1 -1
- package/dist/backend/llvm/reference-effects.js +9 -0
- package/dist/backend/llvm/reference-effects.js.map +1 -1
- package/dist/backend/llvm/reference-writes.d.ts +4 -0
- package/dist/backend/llvm/reference-writes.js +143 -6
- package/dist/backend/llvm/reference-writes.js.map +1 -1
- package/dist/backend/llvm/reference-writes.test.d.ts +1 -0
- package/dist/backend/llvm/reference-writes.test.js +88 -0
- package/dist/backend/llvm/reference-writes.test.js.map +1 -0
- package/dist/backend/llvm/regex-matchers.d.ts +8 -0
- package/dist/backend/llvm/regex-matchers.js +33 -0
- package/dist/backend/llvm/regex-matchers.js.map +1 -1
- package/dist/backend/llvm/regex-matchers.test.js +23 -1
- package/dist/backend/llvm/regex-matchers.test.js.map +1 -1
- package/dist/backend/llvm/regions.d.ts +1 -1
- package/dist/backend/llvm/regions.js +9 -6
- package/dist/backend/llvm/regions.js.map +1 -1
- package/dist/backend/llvm/regions.test.js +1 -1
- package/dist/backend/llvm/shapes.d.ts +69 -43
- package/dist/backend/llvm/shapes.js +285 -21
- package/dist/backend/llvm/shapes.js.map +1 -1
- package/dist/backend/llvm/shapes.test.js +37 -3
- package/dist/backend/llvm/shapes.test.js.map +1 -1
- package/dist/backend/llvm/speculative-integers.d.ts +74 -0
- package/dist/backend/llvm/speculative-integers.js +571 -0
- package/dist/backend/llvm/speculative-integers.js.map +1 -0
- package/dist/backend/llvm/speculative-integers.test.d.ts +1 -0
- package/dist/backend/llvm/speculative-integers.test.js +148 -0
- package/dist/backend/llvm/speculative-integers.test.js.map +1 -0
- package/dist/backend/llvm/split-loops.js +2 -2
- package/dist/backend/llvm/split-loops.js.map +1 -1
- package/dist/backend/llvm/stack-objects.d.ts +26 -6
- package/dist/backend/llvm/stack-objects.js +133 -10
- package/dist/backend/llvm/stack-objects.js.map +1 -1
- package/dist/backend/llvm/stack-objects.test.js +55 -1
- package/dist/backend/llvm/stack-objects.test.js.map +1 -1
- package/dist/backend/llvm/stack-unions.test.js +1 -1
- package/dist/backend/llvm/string-construction.test.js +1 -1
- package/dist/backend/llvm/string-lifetimes.test.js +15 -14
- package/dist/backend/llvm/string-lifetimes.test.js.map +1 -1
- package/dist/backend/llvm/string-slices.d.ts +25 -0
- package/dist/backend/llvm/string-slices.js +207 -1
- package/dist/backend/llvm/string-slices.js.map +1 -1
- package/dist/backend/llvm/string-slices.test.js +139 -2
- package/dist/backend/llvm/string-slices.test.js.map +1 -1
- package/dist/backend/llvm/switch-dispatch.test.js +2 -2
- package/dist/backend/llvm/thread-slots.d.ts +5 -0
- package/dist/backend/llvm/thread-slots.js +142 -0
- package/dist/backend/llvm/thread-slots.js.map +1 -0
- package/dist/backend/llvm/thread-slots.test.d.ts +1 -0
- package/dist/backend/llvm/thread-slots.test.js +110 -0
- package/dist/backend/llvm/thread-slots.test.js.map +1 -0
- package/dist/backend/llvm/union-repr.d.ts +7 -7
- package/dist/backend/llvm/union-repr.js +18 -2
- package/dist/backend/llvm/union-repr.js.map +1 -1
- package/dist/backend/llvm/union-retype.test.js +17 -3
- package/dist/backend/llvm/union-retype.test.js.map +1 -1
- package/dist/backend/llvm/walkers.d.ts +2 -2
- package/dist/backend/llvm/walkers.js +51 -26
- package/dist/backend/llvm/walkers.js.map +1 -1
- package/dist/backend/llvm/wasm-modules.d.ts +16 -0
- package/dist/backend/llvm/wasm-modules.js +66 -0
- package/dist/backend/llvm/wasm-modules.js.map +1 -0
- package/dist/backend/llvm/wrapping-sums.d.ts +7 -0
- package/dist/backend/llvm/wrapping-sums.js +11 -3
- package/dist/backend/llvm/wrapping-sums.js.map +1 -1
- package/dist/backend/mangle.d.ts +7 -0
- package/dist/backend/mangle.js +11 -0
- package/dist/backend/mangle.js.map +1 -1
- package/dist/backend/may-throw.d.ts +3 -0
- package/dist/backend/may-throw.js +6 -2
- package/dist/backend/may-throw.js.map +1 -1
- package/dist/backend/may-throw.test.js +1 -1
- package/dist/backend/native/contracts.d.ts +37 -0
- package/dist/backend/native/executable.js +192 -134
- package/dist/backend/native/executable.js.map +1 -1
- package/dist/backend/native/library.js +1 -0
- package/dist/backend/native/library.js.map +1 -1
- package/dist/backend/native/runtime-inputs.d.ts +1 -1
- package/dist/backend/native/runtime-inputs.js +2 -0
- package/dist/backend/native/runtime-inputs.js.map +1 -1
- package/dist/backend/native-link-info-core.d.ts +30 -0
- package/dist/backend/native-link-info-core.js.map +1 -1
- package/dist/backend/publication.test.js +1 -1
- package/dist/backend/runtime-pack-core.d.ts +9 -1
- package/dist/backend/runtime-pack-core.js +10 -1
- package/dist/backend/runtime-pack-core.js.map +1 -1
- package/dist/backend/runtime-pack-native.js +1 -1
- package/dist/backend/runtime-pack-native.js.map +1 -1
- package/dist/backend/runtime-pack-native.test.d.ts +1 -0
- package/dist/backend/runtime-pack-native.test.js +31 -0
- package/dist/backend/runtime-pack-native.test.js.map +1 -0
- package/dist/backend/runtime-pack-targets.test.js +5 -0
- package/dist/backend/runtime-pack-targets.test.js.map +1 -1
- package/dist/backend/runtime-pack.d.ts +7 -3
- package/dist/backend/runtime-pack.js +12 -6
- package/dist/backend/runtime-pack.js.map +1 -1
- package/dist/backend/runtime-pack.test.js +20 -6
- package/dist/backend/runtime-pack.test.js.map +1 -1
- package/dist/backend/stack-observations.d.ts +22 -0
- package/dist/backend/stack-observations.js +382 -0
- package/dist/backend/stack-observations.js.map +1 -0
- package/dist/backend/stack-observations.test.d.ts +1 -0
- package/dist/backend/stack-observations.test.js +233 -0
- package/dist/backend/stack-observations.test.js.map +1 -0
- package/dist/backend/target-diagnostics.js +8 -0
- package/dist/backend/target-diagnostics.js.map +1 -1
- package/dist/backend/target-diagnostics.test.js +1 -1
- package/dist/backend/warm-cache.js +5 -0
- package/dist/backend/warm-cache.js.map +1 -1
- package/dist/backend/young-nursery.d.ts +7 -0
- package/dist/backend/young-nursery.js +10 -0
- package/dist/backend/young-nursery.js.map +1 -0
- package/dist/cli/command.js +44 -4
- package/dist/cli/command.js.map +1 -1
- package/dist/cli/usage.d.ts +11 -1
- package/dist/cli/usage.js +20 -1
- package/dist/cli/usage.js.map +1 -1
- package/dist/compat/fetch-profile.js +10 -1
- package/dist/compat/fetch-profile.js.map +1 -1
- package/dist/compile-types.d.ts +13 -0
- package/dist/contracts/check.js +25 -6
- package/dist/contracts/check.js.map +1 -1
- package/dist/contracts/int32-elements.d.ts +115 -0
- package/dist/contracts/int32-elements.js +1179 -0
- package/dist/contracts/int32-elements.js.map +1 -0
- package/dist/coverage/report.d.ts +16 -0
- package/dist/coverage/report.js +182 -1
- package/dist/coverage/report.js.map +1 -1
- package/dist/coverage/surface-manifest.js +19 -6
- package/dist/coverage/surface-manifest.js.map +1 -1
- package/dist/coverage/verdict-cache.d.ts +2 -0
- package/dist/coverage/verdict-cache.js +12 -0
- package/dist/coverage/verdict-cache.js.map +1 -1
- package/dist/coverage/verdict-cache.test.js +2 -1
- package/dist/coverage/verdict-cache.test.js.map +1 -1
- package/dist/diagnostics/diagnostic.d.ts +11 -7
- package/dist/diagnostics/diagnostic.js +35 -23
- package/dist/diagnostics/diagnostic.js.map +1 -1
- package/dist/diagnostics/envelope.d.ts +39 -2
- package/dist/diagnostics/envelope.js.map +1 -1
- package/dist/diagnostics/render.d.ts +7 -0
- package/dist/diagnostics/render.js +50 -13
- package/dist/diagnostics/render.js.map +1 -1
- package/dist/diagnostics/render.test.d.ts +1 -0
- package/dist/diagnostics/render.test.js +49 -0
- package/dist/diagnostics/render.test.js.map +1 -0
- package/dist/executable/executable-cache.d.ts +17 -0
- package/dist/executable/executable-cache.js +13 -1
- package/dist/executable/executable-cache.js.map +1 -1
- package/dist/executable/executable-cache.test.js +7 -1
- package/dist/executable/executable-cache.test.js.map +1 -1
- package/dist/executable/prepare.js +2 -1
- package/dist/executable/prepare.js.map +1 -1
- package/dist/frontend/analysis.js +6 -1
- package/dist/frontend/analysis.js.map +1 -1
- package/dist/frontend/builtin-modules.d.ts +16 -2
- package/dist/frontend/builtin-modules.js +40 -7
- package/dist/frontend/builtin-modules.js.map +1 -1
- package/dist/frontend/cjs-syntax.js +52 -51
- package/dist/frontend/cjs-syntax.js.map +1 -1
- package/dist/frontend/contract-types.d.ts +3 -0
- package/dist/frontend/contract-types.js +36 -7
- package/dist/frontend/contract-types.js.map +1 -1
- package/dist/frontend/experimental-import.d.ts +5 -1
- package/dist/frontend/experimental-import.js +26 -7
- package/dist/frontend/experimental-import.js.map +1 -1
- package/dist/frontend/fork-target.js +20 -22
- package/dist/frontend/fork-target.js.map +1 -1
- package/dist/frontend/fork-target.test.js +2 -1
- package/dist/frontend/fork-target.test.js.map +1 -1
- package/dist/frontend/function-completion.js +6 -6
- package/dist/frontend/function-completion.js.map +1 -1
- package/dist/frontend/helper-tokens.js +15 -3
- package/dist/frontend/helper-tokens.js.map +1 -1
- package/dist/frontend/helper-tokens.test.js +7 -1
- package/dist/frontend/helper-tokens.test.js.map +1 -1
- package/dist/frontend/inferred-js-diagnostics.js +14 -17
- package/dist/frontend/inferred-js-diagnostics.js.map +1 -1
- package/dist/frontend/input-tracker.d.ts +3 -0
- package/dist/frontend/input-tracker.js +32 -3
- package/dist/frontend/input-tracker.js.map +1 -1
- package/dist/frontend/lib-contract.js +36 -32
- package/dist/frontend/lib-contract.js.map +1 -1
- package/dist/frontend/lib-exports.js +3 -3
- package/dist/frontend/lib-exports.js.map +1 -1
- package/dist/frontend/lowering/array-values.d.ts +8 -3
- package/dist/frontend/lowering/array-values.js +60 -11
- package/dist/frontend/lowering/array-values.js.map +1 -1
- package/dist/frontend/lowering/assert-instances.js +4 -4
- package/dist/frontend/lowering/assert-instances.js.map +1 -1
- package/dist/frontend/lowering/assertion-identity.d.ts +12 -0
- package/dist/frontend/lowering/assertion-identity.js +70 -0
- package/dist/frontend/lowering/assertion-identity.js.map +1 -0
- package/dist/frontend/lowering/assertion-members.d.ts +28 -0
- package/dist/frontend/lowering/assertion-members.js +185 -0
- package/dist/frontend/lowering/assertion-members.js.map +1 -0
- package/dist/frontend/lowering/binding-analysis.js +27 -20
- package/dist/frontend/lowering/binding-analysis.js.map +1 -1
- package/dist/frontend/lowering/builtin-calls.js +72 -4
- package/dist/frontend/lowering/builtin-calls.js.map +1 -1
- package/dist/frontend/lowering/builtin-function-fences.d.ts +14 -0
- package/dist/frontend/lowering/builtin-function-fences.js +42 -0
- package/dist/frontend/lowering/builtin-function-fences.js.map +1 -0
- package/dist/frontend/lowering/builtins/arguments.js +1 -1
- package/dist/frontend/lowering/builtins/arguments.js.map +1 -1
- package/dist/frontend/lowering/builtins/async-context.js +53 -52
- package/dist/frontend/lowering/builtins/async-context.js.map +1 -1
- package/dist/frontend/lowering/builtins/atomics.js +6 -6
- package/dist/frontend/lowering/builtins/atomics.js.map +1 -1
- package/dist/frontend/lowering/builtins/blob.js +8 -6
- package/dist/frontend/lowering/builtins/blob.js.map +1 -1
- package/dist/frontend/lowering/builtins/builtin-class-dyn.d.ts +23 -0
- package/dist/frontend/lowering/builtins/builtin-class-dyn.js +156 -0
- package/dist/frontend/lowering/builtins/builtin-class-dyn.js.map +1 -0
- package/dist/frontend/lowering/builtins/callable-aliases.js +45 -6
- package/dist/frontend/lowering/builtins/callable-aliases.js.map +1 -1
- package/dist/frontend/lowering/builtins/child-process-async.js +7 -7
- package/dist/frontend/lowering/builtins/child-process-async.js.map +1 -1
- package/dist/frontend/lowering/builtins/child-process-methods.d.ts +6 -4
- package/dist/frontend/lowering/builtins/child-process-methods.js +310 -57
- package/dist/frontend/lowering/builtins/child-process-methods.js.map +1 -1
- package/dist/frontend/lowering/builtins/child-process-sync.js +16 -10
- package/dist/frontend/lowering/builtins/child-process-sync.js.map +1 -1
- package/dist/frontend/lowering/builtins/child-process.d.ts +6 -4
- package/dist/frontend/lowering/builtins/child-process.js +85 -61
- package/dist/frontend/lowering/builtins/child-process.js.map +1 -1
- package/dist/frontend/lowering/builtins/class-values.d.ts +60 -0
- package/dist/frontend/lowering/builtins/class-values.js +226 -0
- package/dist/frontend/lowering/builtins/class-values.js.map +1 -0
- package/dist/frontend/lowering/builtins/compression.d.ts +18 -0
- package/dist/frontend/lowering/builtins/compression.js +230 -52
- package/dist/frontend/lowering/builtins/compression.js.map +1 -1
- package/dist/frontend/lowering/builtins/constants.d.ts +9 -1
- package/dist/frontend/lowering/builtins/constants.js +28 -7
- package/dist/frontend/lowering/builtins/constants.js.map +1 -1
- package/dist/frontend/lowering/builtins/crypto.d.ts +19 -0
- package/dist/frontend/lowering/builtins/crypto.js +223 -38
- package/dist/frontend/lowering/builtins/crypto.js.map +1 -1
- package/dist/frontend/lowering/builtins/dates.d.ts +7 -1
- package/dist/frontend/lowering/builtins/dates.js +92 -16
- package/dist/frontend/lowering/builtins/dates.js.map +1 -1
- package/dist/frontend/lowering/builtins/disposable-stack.d.ts +18 -0
- package/dist/frontend/lowering/builtins/disposable-stack.js +137 -0
- package/dist/frontend/lowering/builtins/disposable-stack.js.map +1 -0
- package/dist/frontend/lowering/builtins/environment.js +3 -3
- package/dist/frontend/lowering/builtins/environment.js.map +1 -1
- package/dist/frontend/lowering/builtins/errors.d.ts +14 -10
- package/dist/frontend/lowering/builtins/errors.js +174 -6
- package/dist/frontend/lowering/builtins/errors.js.map +1 -1
- package/dist/frontend/lowering/builtins/filesystem-calls.d.ts +4 -0
- package/dist/frontend/lowering/builtins/filesystem-calls.js +136 -113
- package/dist/frontend/lowering/builtins/filesystem-calls.js.map +1 -1
- package/dist/frontend/lowering/builtins/filesystem.d.ts +8 -0
- package/dist/frontend/lowering/builtins/filesystem.js +213 -76
- package/dist/frontend/lowering/builtins/filesystem.js.map +1 -1
- package/dist/frontend/lowering/builtins/fs-glob.js +3 -3
- package/dist/frontend/lowering/builtins/fs-glob.js.map +1 -1
- package/dist/frontend/lowering/builtins/fs-streams.js +10 -11
- package/dist/frontend/lowering/builtins/fs-streams.js.map +1 -1
- package/dist/frontend/lowering/builtins/hash-stream.d.ts +12 -0
- package/dist/frontend/lowering/builtins/hash-stream.js +80 -0
- package/dist/frontend/lowering/builtins/hash-stream.js.map +1 -0
- package/dist/frontend/lowering/builtins/ipc.js +45 -8
- package/dist/frontend/lowering/builtins/ipc.js.map +1 -1
- package/dist/frontend/lowering/builtins/json.js +232 -24
- package/dist/frontend/lowering/builtins/json.js.map +1 -1
- package/dist/frontend/lowering/builtins/key-object.js +4 -4
- package/dist/frontend/lowering/builtins/key-object.js.map +1 -1
- package/dist/frontend/lowering/builtins/module-bindings.d.ts +8 -0
- package/dist/frontend/lowering/builtins/module-bindings.js +71 -22
- package/dist/frontend/lowering/builtins/module-bindings.js.map +1 -1
- package/dist/frontend/lowering/builtins/module-calls.js +67 -46
- package/dist/frontend/lowering/builtins/module-calls.js.map +1 -1
- package/dist/frontend/lowering/builtins/module-resolution.d.ts +4 -3
- package/dist/frontend/lowering/builtins/module-resolution.js +24 -23
- package/dist/frontend/lowering/builtins/module-resolution.js.map +1 -1
- package/dist/frontend/lowering/builtins/navigator.d.ts +13 -0
- package/dist/frontend/lowering/builtins/navigator.js +40 -0
- package/dist/frontend/lowering/builtins/navigator.js.map +1 -0
- package/dist/frontend/lowering/builtins/net-address.d.ts +19 -0
- package/dist/frontend/lowering/builtins/net-address.js +156 -0
- package/dist/frontend/lowering/builtins/net-address.js.map +1 -0
- package/dist/frontend/lowering/builtins/numbers.js +25 -9
- package/dist/frontend/lowering/builtins/numbers.js.map +1 -1
- package/dist/frontend/lowering/builtins/operating-system.d.ts +4 -0
- package/dist/frontend/lowering/builtins/operating-system.js +25 -12
- package/dist/frontend/lowering/builtins/operating-system.js.map +1 -1
- package/dist/frontend/lowering/builtins/performance.d.ts +12 -0
- package/dist/frontend/lowering/builtins/performance.js +259 -8
- package/dist/frontend/lowering/builtins/performance.js.map +1 -1
- package/dist/frontend/lowering/builtins/process.d.ts +32 -1
- package/dist/frontend/lowering/builtins/process.js +468 -99
- package/dist/frontend/lowering/builtins/process.js.map +1 -1
- package/dist/frontend/lowering/builtins/promises.d.ts +5 -1
- package/dist/frontend/lowering/builtins/promises.js +326 -43
- package/dist/frontend/lowering/builtins/promises.js.map +1 -1
- package/dist/frontend/lowering/builtins/promisify-callback.d.ts +37 -0
- package/dist/frontend/lowering/builtins/promisify-callback.js +320 -0
- package/dist/frontend/lowering/builtins/promisify-callback.js.map +1 -0
- package/dist/frontend/lowering/builtins/properties.js +37 -1
- package/dist/frontend/lowering/builtins/properties.js.map +1 -1
- package/dist/frontend/lowering/builtins/querystring.js +14 -14
- package/dist/frontend/lowering/builtins/querystring.js.map +1 -1
- package/dist/frontend/lowering/builtins/readline.d.ts +55 -13
- package/dist/frontend/lowering/builtins/readline.js +931 -69
- package/dist/frontend/lowering/builtins/readline.js.map +1 -1
- package/dist/frontend/lowering/builtins/receiver-types.js +3 -5
- package/dist/frontend/lowering/builtins/receiver-types.js.map +1 -1
- package/dist/frontend/lowering/builtins/reflection.js +16 -14
- package/dist/frontend/lowering/builtins/reflection.js.map +1 -1
- package/dist/frontend/lowering/builtins/runtime-constructor.d.ts +26 -0
- package/dist/frontend/lowering/builtins/runtime-constructor.js +165 -0
- package/dist/frontend/lowering/builtins/runtime-constructor.js.map +1 -0
- package/dist/frontend/lowering/builtins/strings.js +101 -12
- package/dist/frontend/lowering/builtins/strings.js.map +1 -1
- package/dist/frontend/lowering/builtins/text-codecs.js +41 -38
- package/dist/frontend/lowering/builtins/text-codecs.js.map +1 -1
- package/dist/frontend/lowering/builtins/timers.js +75 -30
- package/dist/frontend/lowering/builtins/timers.js.map +1 -1
- package/dist/frontend/lowering/builtins/url.d.ts +3 -0
- package/dist/frontend/lowering/builtins/url.js +120 -17
- package/dist/frontend/lowering/builtins/url.js.map +1 -1
- package/dist/frontend/lowering/builtins/util-types.js +20 -4
- package/dist/frontend/lowering/builtins/util-types.js.map +1 -1
- package/dist/frontend/lowering/builtins/v8.d.ts +11 -0
- package/dist/frontend/lowering/builtins/v8.js +105 -0
- package/dist/frontend/lowering/builtins/v8.js.map +1 -0
- package/dist/frontend/lowering/builtins/webassembly.d.ts +33 -0
- package/dist/frontend/lowering/builtins/webassembly.js +388 -0
- package/dist/frontend/lowering/builtins/webassembly.js.map +1 -0
- package/dist/frontend/lowering/builtins/webcrypto.d.ts +20 -0
- package/dist/frontend/lowering/builtins/webcrypto.js +112 -0
- package/dist/frontend/lowering/builtins/webcrypto.js.map +1 -0
- package/dist/frontend/lowering/builtins/workers.d.ts +16 -0
- package/dist/frontend/lowering/builtins/workers.js +246 -3
- package/dist/frontend/lowering/builtins/workers.js.map +1 -1
- package/dist/frontend/lowering/call-arguments.js +69 -14
- package/dist/frontend/lowering/call-arguments.js.map +1 -1
- package/dist/frontend/lowering/call-signatures.d.ts +19 -1
- package/dist/frontend/lowering/call-signatures.js +254 -47
- package/dist/frontend/lowering/call-signatures.js.map +1 -1
- package/dist/frontend/lowering/checked-promise-all.d.ts +3 -0
- package/dist/frontend/lowering/checked-promise-all.js +1 -1
- package/dist/frontend/lowering/checked-promise-all.js.map +1 -1
- package/dist/frontend/lowering/cjs-exports-object.d.ts +53 -0
- package/dist/frontend/lowering/cjs-exports-object.js +528 -0
- package/dist/frontend/lowering/cjs-exports-object.js.map +1 -0
- package/dist/frontend/lowering/cjs-inline-require.d.ts +86 -0
- package/dist/frontend/lowering/cjs-inline-require.js +314 -0
- package/dist/frontend/lowering/cjs-inline-require.js.map +1 -0
- package/dist/frontend/lowering/cjs-tsc-interop.d.ts +28 -0
- package/dist/frontend/lowering/cjs-tsc-interop.js +208 -0
- package/dist/frontend/lowering/cjs-tsc-interop.js.map +1 -0
- package/dist/frontend/lowering/class-attributes.d.ts +19 -0
- package/dist/frontend/lowering/class-attributes.js +378 -0
- package/dist/frontend/lowering/class-attributes.js.map +1 -0
- package/dist/frontend/lowering/class-callbacks.d.ts +3 -1
- package/dist/frontend/lowering/class-callbacks.js +21 -10
- package/dist/frontend/lowering/class-callbacks.js.map +1 -1
- package/dist/frontend/lowering/class-construction.js +49 -4
- package/dist/frontend/lowering/class-construction.js.map +1 -1
- package/dist/frontend/lowering/class-descriptors.d.ts +2 -0
- package/dist/frontend/lowering/class-descriptors.js +8 -8
- package/dist/frontend/lowering/class-descriptors.js.map +1 -1
- package/dist/frontend/lowering/class-dynamic-dispatch.d.ts +64 -0
- package/dist/frontend/lowering/class-dynamic-dispatch.js +1115 -89
- package/dist/frontend/lowering/class-dynamic-dispatch.js.map +1 -1
- package/dist/frontend/lowering/class-instance-constructor.js +1 -1
- package/dist/frontend/lowering/class-instance-constructor.js.map +1 -1
- package/dist/frontend/lowering/class-iterables.d.ts +11 -0
- package/dist/frontend/lowering/class-iterables.js +31 -0
- package/dist/frontend/lowering/class-iterables.js.map +1 -0
- package/dist/frontend/lowering/class-method-mutations.js +73 -35
- package/dist/frontend/lowering/class-method-mutations.js.map +1 -1
- package/dist/frontend/lowering/class-method-values.js +56 -10
- package/dist/frontend/lowering/class-method-values.js.map +1 -1
- package/dist/frontend/lowering/class-protocol-dispatch.js +24 -22
- package/dist/frontend/lowering/class-protocol-dispatch.js.map +1 -1
- package/dist/frontend/lowering/class-protocols.d.ts +55 -0
- package/dist/frontend/lowering/class-protocols.js +738 -22
- package/dist/frontend/lowering/class-protocols.js.map +1 -1
- package/dist/frontend/lowering/class-prototypes.d.ts +6 -0
- package/dist/frontend/lowering/class-prototypes.js +80 -18
- package/dist/frontend/lowering/class-prototypes.js.map +1 -1
- package/dist/frontend/lowering/class-runtime-statics.js +1 -1
- package/dist/frontend/lowering/class-runtime-statics.js.map +1 -1
- package/dist/frontend/lowering/class-static-data.js +2 -2
- package/dist/frontend/lowering/class-static-data.js.map +1 -1
- package/dist/frontend/lowering/class-to-primitive.d.ts +25 -0
- package/dist/frontend/lowering/class-to-primitive.js +261 -0
- package/dist/frontend/lowering/class-to-primitive.js.map +1 -0
- package/dist/frontend/lowering/class-unions.d.ts +25 -0
- package/dist/frontend/lowering/class-unions.js +102 -1
- package/dist/frontend/lowering/class-unions.js.map +1 -1
- package/dist/frontend/lowering/code-generation.d.ts +14 -0
- package/dist/frontend/lowering/code-generation.js +127 -0
- package/dist/frontend/lowering/code-generation.js.map +1 -0
- package/dist/frontend/lowering/coercions/function-adapters.d.ts +16 -2
- package/dist/frontend/lowering/coercions/function-adapters.js +145 -3
- package/dist/frontend/lowering/coercions/function-adapters.js.map +1 -1
- package/dist/frontend/lowering/coercions/structural-plans.js +25 -3
- package/dist/frontend/lowering/coercions/structural-plans.js.map +1 -1
- package/dist/frontend/lowering/coercions/structural.js +35 -3
- package/dist/frontend/lowering/coercions/structural.js.map +1 -1
- package/dist/frontend/lowering/coercions/unions.d.ts +15 -0
- package/dist/frontend/lowering/coercions/unions.js +57 -1
- package/dist/frontend/lowering/coercions/unions.js.map +1 -1
- package/dist/frontend/lowering/collection-ingestion.js +2 -2
- package/dist/frontend/lowering/collection-ingestion.js.map +1 -1
- package/dist/frontend/lowering/collection-narrowing.js +2 -4
- package/dist/frontend/lowering/collection-narrowing.js.map +1 -1
- package/dist/frontend/lowering/construction-escapes.js +8 -8
- package/dist/frontend/lowering/construction-escapes.js.map +1 -1
- package/dist/frontend/lowering/construction-escapes.test.js +4 -4
- package/dist/frontend/lowering/construction-escapes.test.js.map +1 -1
- package/dist/frontend/lowering/constructor-returns.d.ts +61 -0
- package/dist/frontend/lowering/constructor-returns.js +477 -0
- package/dist/frontend/lowering/constructor-returns.js.map +1 -0
- package/dist/frontend/lowering/containers/array-callback-call.js +1 -1
- package/dist/frontend/lowering/containers/array-callback-call.js.map +1 -1
- package/dist/frontend/lowering/containers/array-callbacks.d.ts +9 -0
- package/dist/frontend/lowering/containers/array-callbacks.js +266 -100
- package/dist/frontend/lowering/containers/array-callbacks.js.map +1 -1
- package/dist/frontend/lowering/containers/array-concat.js +1 -1
- package/dist/frontend/lowering/containers/array-concat.js.map +1 -1
- package/dist/frontend/lowering/containers/array-construction.d.ts +0 -1
- package/dist/frontend/lowering/containers/array-construction.js +51 -13
- package/dist/frontend/lowering/containers/array-construction.js.map +1 -1
- package/dist/frontend/lowering/containers/array-from-async.d.ts +19 -0
- package/dist/frontend/lowering/containers/array-from-async.js +427 -0
- package/dist/frontend/lowering/containers/array-from-async.js.map +1 -0
- package/dist/frontend/lowering/containers/array-methods.js +89 -77
- package/dist/frontend/lowering/containers/array-methods.js.map +1 -1
- package/dist/frontend/lowering/containers/array-pipelines.js +1 -0
- package/dist/frontend/lowering/containers/array-pipelines.js.map +1 -1
- package/dist/frontend/lowering/containers/bytes.js +161 -101
- package/dist/frontend/lowering/containers/bytes.js.map +1 -1
- package/dist/frontend/lowering/containers/callback-arguments.d.ts +9 -1
- package/dist/frontend/lowering/containers/callback-arguments.js +55 -5
- package/dist/frontend/lowering/containers/callback-arguments.js.map +1 -1
- package/dist/frontend/lowering/containers/collection-grouping.d.ts +7 -8
- package/dist/frontend/lowering/containers/collection-grouping.js +219 -27
- package/dist/frontend/lowering/containers/collection-grouping.js.map +1 -1
- package/dist/frontend/lowering/containers/collection-methods.js +81 -48
- package/dist/frontend/lowering/containers/collection-methods.js.map +1 -1
- package/dist/frontend/lowering/containers/dynamic-receivers.js +1 -1
- package/dist/frontend/lowering/containers/dynamic-receivers.js.map +1 -1
- package/dist/frontend/lowering/containers/exec-result-uses.js +2 -2
- package/dist/frontend/lowering/containers/exec-result-uses.js.map +1 -1
- package/dist/frontend/lowering/containers/for-of.d.ts +6 -0
- package/dist/frontend/lowering/containers/for-of.js +19 -19
- package/dist/frontend/lowering/containers/for-of.js.map +1 -1
- package/dist/frontend/lowering/containers/indexed-objects.js +142 -57
- package/dist/frontend/lowering/containers/indexed-objects.js.map +1 -1
- package/dist/frontend/lowering/containers/iterator-helpers.d.ts +53 -4
- package/dist/frontend/lowering/containers/iterator-helpers.js +1581 -462
- package/dist/frontend/lowering/containers/iterator-helpers.js.map +1 -1
- package/dist/frontend/lowering/containers/match-row-uses.d.ts +17 -0
- package/dist/frontend/lowering/containers/match-row-uses.js +264 -0
- package/dist/frontend/lowering/containers/match-row-uses.js.map +1 -0
- package/dist/frontend/lowering/containers/string-and-regexp.d.ts +14 -0
- package/dist/frontend/lowering/containers/string-and-regexp.js +419 -30
- package/dist/frontend/lowering/containers/string-and-regexp.js.map +1 -1
- package/dist/frontend/lowering/containers/string-replacement.js +1 -1
- package/dist/frontend/lowering/containers/string-replacement.js.map +1 -1
- package/dist/frontend/lowering/cycle-initialization.d.ts +4 -0
- package/dist/frontend/lowering/cycle-initialization.js +39 -0
- package/dist/frontend/lowering/cycle-initialization.js.map +1 -1
- package/dist/frontend/lowering/deferred-module-initializers.js +47 -43
- package/dist/frontend/lowering/deferred-module-initializers.js.map +1 -1
- package/dist/frontend/lowering/devirtualize.d.ts +1 -1
- package/dist/frontend/lowering/devirtualize.js +27 -7
- package/dist/frontend/lowering/devirtualize.js.map +1 -1
- package/dist/frontend/lowering/divergences.d.ts +0 -5
- package/dist/frontend/lowering/divergences.js +238 -128
- package/dist/frontend/lowering/divergences.js.map +1 -1
- package/dist/frontend/lowering/dyn-streams.d.ts +25 -0
- package/dist/frontend/lowering/dyn-streams.js +257 -0
- package/dist/frontend/lowering/dyn-streams.js.map +1 -0
- package/dist/frontend/lowering/error-methods.js +4 -1
- package/dist/frontend/lowering/error-methods.js.map +1 -1
- package/dist/frontend/lowering/error-name-order.d.ts +19 -0
- package/dist/frontend/lowering/error-name-order.js +93 -0
- package/dist/frontend/lowering/error-name-order.js.map +1 -0
- package/dist/frontend/lowering/expressions/array-literals.d.ts +21 -0
- package/dist/frontend/lowering/expressions/array-literals.js +703 -0
- package/dist/frontend/lowering/expressions/array-literals.js.map +1 -0
- package/dist/frontend/lowering/expressions/binary.d.ts +35 -0
- package/dist/frontend/lowering/expressions/binary.js +2483 -0
- package/dist/frontend/lowering/expressions/binary.js.map +1 -0
- package/dist/frontend/lowering/expressions/element-access.d.ts +31 -0
- package/dist/frontend/lowering/expressions/element-access.js +1797 -0
- package/dist/frontend/lowering/expressions/element-access.js.map +1 -0
- package/dist/frontend/lowering/expressions/evaluation-safety.js +4 -3
- package/dist/frontend/lowering/expressions/evaluation-safety.js.map +1 -1
- package/dist/frontend/lowering/expressions/hosted-narrowing.d.ts +38 -0
- package/dist/frontend/lowering/expressions/hosted-narrowing.js +160 -0
- package/dist/frontend/lowering/expressions/hosted-narrowing.js.map +1 -0
- package/dist/frontend/lowering/expressions/identifiers.d.ts +4 -0
- package/dist/frontend/lowering/expressions/identifiers.js +830 -0
- package/dist/frontend/lowering/expressions/identifiers.js.map +1 -0
- package/dist/frontend/lowering/expressions/keyed-field-targets.d.ts +40 -0
- package/dist/frontend/lowering/expressions/keyed-field-targets.js +226 -0
- package/dist/frontend/lowering/expressions/keyed-field-targets.js.map +1 -0
- package/dist/frontend/lowering/expressions/narrowing.d.ts +37 -0
- package/dist/frontend/lowering/expressions/narrowing.js +1322 -0
- package/dist/frontend/lowering/expressions/narrowing.js.map +1 -0
- package/dist/frontend/lowering/expressions/native-proxy.js +4 -4
- package/dist/frontend/lowering/expressions/native-proxy.js.map +1 -1
- package/dist/frontend/lowering/expressions/nullish-assignment.js +45 -0
- package/dist/frontend/lowering/expressions/nullish-assignment.js.map +1 -1
- package/dist/frontend/lowering/expressions/object-literals.d.ts +10 -0
- package/dist/frontend/lowering/expressions/object-literals.js +253 -85
- package/dist/frontend/lowering/expressions/object-literals.js.map +1 -1
- package/dist/frontend/lowering/expressions/optional-chains.d.ts +2 -1
- package/dist/frontend/lowering/expressions/optional-chains.js +91 -14
- package/dist/frontend/lowering/expressions/optional-chains.js.map +1 -1
- package/dist/frontend/lowering/expressions/property-access.d.ts +110 -0
- package/dist/frontend/lowering/expressions/property-access.js +3544 -0
- package/dist/frontend/lowering/expressions/property-access.js.map +1 -0
- package/dist/frontend/lowering/expressions/relational.d.ts +28 -0
- package/dist/frontend/lowering/expressions/relational.js +1679 -0
- package/dist/frontend/lowering/expressions/relational.js.map +1 -0
- package/dist/frontend/lowering/expressions/typeof.d.ts +22 -0
- package/dist/frontend/lowering/expressions/typeof.js +538 -0
- package/dist/frontend/lowering/expressions/typeof.js.map +1 -0
- package/dist/frontend/lowering/expressions/union-fields.js +1 -1
- package/dist/frontend/lowering/expressions/union-fields.js.map +1 -1
- package/dist/frontend/lowering/expressions/updates.d.ts +21 -0
- package/dist/frontend/lowering/expressions/updates.js +780 -0
- package/dist/frontend/lowering/expressions/updates.js.map +1 -0
- package/dist/frontend/lowering/function-context.d.ts +10 -0
- package/dist/frontend/lowering/function-context.js +11 -1
- package/dist/frontend/lowering/function-context.js.map +1 -1
- package/dist/frontend/lowering/function-returns.js +52 -28
- package/dist/frontend/lowering/function-returns.js.map +1 -1
- package/dist/frontend/lowering/general-streams.d.ts +25 -0
- package/dist/frontend/lowering/general-streams.js +108 -0
- package/dist/frontend/lowering/general-streams.js.map +1 -0
- package/dist/frontend/lowering/generator-dynamic-dispatch.d.ts +7 -0
- package/dist/frontend/lowering/generator-dynamic-dispatch.js +172 -69
- package/dist/frontend/lowering/generator-dynamic-dispatch.js.map +1 -1
- package/dist/frontend/lowering/generic-functions.d.ts +39 -0
- package/dist/frontend/lowering/generic-functions.js +393 -75
- package/dist/frontend/lowering/generic-functions.js.map +1 -1
- package/dist/frontend/lowering/import-meta.js +2 -2
- package/dist/frontend/lowering/import-meta.js.map +1 -1
- package/dist/frontend/lowering/intern-tables.js +10 -9
- package/dist/frontend/lowering/intern-tables.js.map +1 -1
- package/dist/frontend/lowering/iterator-adapters.d.ts +19 -0
- package/dist/frontend/lowering/iterator-adapters.js +331 -3
- package/dist/frontend/lowering/iterator-adapters.js.map +1 -1
- package/dist/frontend/lowering/js-class-fields.d.ts +28 -0
- package/dist/frontend/lowering/js-class-fields.js +170 -0
- package/dist/frontend/lowering/js-class-fields.js.map +1 -0
- package/dist/frontend/lowering/js-dynamic-objects.d.ts +15 -0
- package/dist/frontend/lowering/js-dynamic-objects.js +299 -0
- package/dist/frontend/lowering/js-dynamic-objects.js.map +1 -0
- package/dist/frontend/lowering/js-dynamic-objects.test.d.ts +1 -0
- package/dist/frontend/lowering/js-dynamic-objects.test.js +35 -0
- package/dist/frontend/lowering/js-dynamic-objects.test.js.map +1 -0
- package/dist/frontend/lowering/json-require.d.ts +22 -0
- package/dist/frontend/lowering/json-require.js +131 -0
- package/dist/frontend/lowering/json-require.js.map +1 -0
- package/dist/frontend/lowering/key-order-witness.d.ts +44 -0
- package/dist/frontend/lowering/key-order-witness.js +641 -0
- package/dist/frontend/lowering/key-order-witness.js.map +1 -0
- package/dist/frontend/lowering/key-order-witness.test.d.ts +1 -0
- package/dist/frontend/lowering/key-order-witness.test.js +239 -0
- package/dist/frontend/lowering/key-order-witness.test.js.map +1 -0
- package/dist/frontend/lowering/lifetime-regions.js +7 -7
- package/dist/frontend/lowering/lifetime-regions.js.map +1 -1
- package/dist/frontend/lowering/lower-assert.js +61 -60
- package/dist/frontend/lowering/lower-assert.js.map +1 -1
- package/dist/frontend/lowering/lower-async-iteration.d.ts +10 -1
- package/dist/frontend/lowering/lower-async-iteration.js +34 -6
- package/dist/frontend/lowering/lower-async-iteration.js.map +1 -1
- package/dist/frontend/lowering/lower-builtin-values.d.ts +5 -0
- package/dist/frontend/lowering/lower-builtin-values.js +32 -3
- package/dist/frontend/lowering/lower-builtin-values.js.map +1 -1
- package/dist/frontend/lowering/lower-calls.js +1298 -452
- package/dist/frontend/lowering/lower-calls.js.map +1 -1
- package/dist/frontend/lowering/lower-classes.d.ts +50 -3
- package/dist/frontend/lowering/lower-classes.js +1499 -456
- package/dist/frontend/lowering/lower-classes.js.map +1 -1
- package/dist/frontend/lowering/lower-comptime.d.ts +4 -2
- package/dist/frontend/lowering/lower-comptime.js +111 -13
- package/dist/frontend/lowering/lower-comptime.js.map +1 -1
- package/dist/frontend/lowering/lower-console.js +13 -11
- package/dist/frontend/lowering/lower-console.js.map +1 -1
- package/dist/frontend/lowering/lower-dgram.d.ts +10 -0
- package/dist/frontend/lowering/lower-dgram.js +179 -8
- package/dist/frontend/lowering/lower-dgram.js.map +1 -1
- package/dist/frontend/lowering/lower-enums.js +113 -14
- package/dist/frontend/lowering/lower-enums.js.map +1 -1
- package/dist/frontend/lowering/lower-event-emitter.d.ts +16 -7
- package/dist/frontend/lowering/lower-event-emitter.js +268 -71
- package/dist/frontend/lowering/lower-event-emitter.js.map +1 -1
- package/dist/frontend/lowering/lower-event-target.js +2 -2
- package/dist/frontend/lowering/lower-event-target.js.map +1 -1
- package/dist/frontend/lowering/lower-expando.js +17 -13
- package/dist/frontend/lowering/lower-expando.js.map +1 -1
- package/dist/frontend/lowering/lower-exprs.d.ts +188 -186
- package/dist/frontend/lowering/lower-exprs.js +1493 -12407
- package/dist/frontend/lowering/lower-exprs.js.map +1 -1
- package/dist/frontend/lowering/lower-functions.js +68 -22
- package/dist/frontend/lowering/lower-functions.js.map +1 -1
- package/dist/frontend/lowering/lower-generators.d.ts +6 -0
- package/dist/frontend/lowering/lower-generators.js +29 -16
- package/dist/frontend/lowering/lower-generators.js.map +1 -1
- package/dist/frontend/lowering/lower-global-value.js +5 -1
- package/dist/frontend/lowering/lower-global-value.js.map +1 -1
- package/dist/frontend/lowering/lower-inspect.js +354 -99
- package/dist/frontend/lowering/lower-inspect.js.map +1 -1
- package/dist/frontend/lowering/lower-mixins.js +23 -20
- package/dist/frontend/lowering/lower-mixins.js.map +1 -1
- package/dist/frontend/lowering/lower-mock.d.ts +19 -2
- package/dist/frontend/lowering/lower-mock.js +557 -74
- package/dist/frontend/lowering/lower-mock.js.map +1 -1
- package/dist/frontend/lowering/lower-modules.js +268 -61
- package/dist/frontend/lowering/lower-modules.js.map +1 -1
- package/dist/frontend/lowering/lower-namespaces.d.ts +6 -0
- package/dist/frontend/lowering/lower-namespaces.js +45 -33
- package/dist/frontend/lowering/lower-namespaces.js.map +1 -1
- package/dist/frontend/lowering/lower-node-module.d.ts +16 -0
- package/dist/frontend/lowering/lower-node-module.js +147 -14
- package/dist/frontend/lowering/lower-node-module.js.map +1 -1
- package/dist/frontend/lowering/lower-server.d.ts +6 -6
- package/dist/frontend/lowering/lower-server.js +638 -105
- package/dist/frontend/lowering/lower-server.js.map +1 -1
- package/dist/frontend/lowering/lower-stdlib.d.ts +4 -0
- package/dist/frontend/lowering/lower-stdlib.js +151 -109
- package/dist/frontend/lowering/lower-stdlib.js.map +1 -1
- package/dist/frontend/lowering/lower-stmts.d.ts +28 -2
- package/dist/frontend/lowering/lower-stmts.js +1589 -398
- package/dist/frontend/lowering/lower-stmts.js.map +1 -1
- package/dist/frontend/lowering/lower-stream.d.ts +4 -3
- package/dist/frontend/lowering/lower-stream.js +714 -75
- package/dist/frontend/lowering/lower-stream.js.map +1 -1
- package/dist/frontend/lowering/lower-test.d.ts +3 -0
- package/dist/frontend/lowering/lower-test.js +574 -100
- package/dist/frontend/lowering/lower-test.js.map +1 -1
- package/dist/frontend/lowering/lower-timers.js +80 -32
- package/dist/frontend/lowering/lower-timers.js.map +1 -1
- package/dist/frontend/lowering/lower-url.js +1 -1
- package/dist/frontend/lowering/lower-url.js.map +1 -1
- package/dist/frontend/lowering/lowerer.d.ts +409 -26
- package/dist/frontend/lowering/lowerer.js +1918 -305
- package/dist/frontend/lowering/lowerer.js.map +1 -1
- package/dist/frontend/lowering/lowerer.test.js +10 -4
- package/dist/frontend/lowering/lowerer.test.js.map +1 -1
- package/dist/frontend/lowering/maybe-promise.d.ts +46 -0
- package/dist/frontend/lowering/maybe-promise.js +249 -0
- package/dist/frontend/lowering/maybe-promise.js.map +1 -0
- package/dist/frontend/lowering/module-member-this.d.ts +3 -0
- package/dist/frontend/lowering/module-member-this.js +262 -0
- package/dist/frontend/lowering/module-member-this.js.map +1 -0
- package/dist/frontend/lowering/module-namespace-elements.js +1 -1
- package/dist/frontend/lowering/module-namespace-elements.js.map +1 -1
- package/dist/frontend/lowering/nan-coded-reads.d.ts +3 -0
- package/dist/frontend/lowering/nan-coded-reads.js +45 -32
- package/dist/frontend/lowering/nan-coded-reads.js.map +1 -1
- package/dist/frontend/lowering/narrowing-stability.d.ts +18 -3
- package/dist/frontend/lowering/narrowing-stability.js +104 -32
- package/dist/frontend/lowering/narrowing-stability.js.map +1 -1
- package/dist/frontend/lowering/native-ffi.js +11 -11
- package/dist/frontend/lowering/native-ffi.js.map +1 -1
- package/dist/frontend/lowering/null-prototype.d.ts +13 -0
- package/dist/frontend/lowering/null-prototype.js +33 -0
- package/dist/frontend/lowering/null-prototype.js.map +1 -0
- package/dist/frontend/lowering/object-factory-new.js +6 -8
- package/dist/frontend/lowering/object-factory-new.js.map +1 -1
- package/dist/frontend/lowering/private-brands.d.ts +46 -0
- package/dist/frontend/lowering/private-brands.js +265 -0
- package/dist/frontend/lowering/private-brands.js.map +1 -0
- package/dist/frontend/lowering/promise-executor-adapter.d.ts +11 -0
- package/dist/frontend/lowering/promise-executor-adapter.js +87 -0
- package/dist/frontend/lowering/promise-executor-adapter.js.map +1 -0
- package/dist/frontend/lowering/require-initialization.d.ts +32 -0
- package/dist/frontend/lowering/require-initialization.js +246 -0
- package/dist/frontend/lowering/require-initialization.js.map +1 -0
- package/dist/frontend/lowering/runtime-optional-bounds.js +7 -7
- package/dist/frontend/lowering/runtime-optional-bounds.js.map +1 -1
- package/dist/frontend/lowering/runtime-optional-elements.js +12 -12
- package/dist/frontend/lowering/runtime-optional-elements.js.map +1 -1
- package/dist/frontend/lowering/runtime-optional-guards.js +10 -10
- package/dist/frontend/lowering/runtime-optional-guards.js.map +1 -1
- package/dist/frontend/lowering/runtime-optional-guards.test.js +1 -1
- package/dist/frontend/lowering/runtime-optional-guards.test.js.map +1 -1
- package/dist/frontend/lowering/runtime-optional-ownership.js +10 -9
- package/dist/frontend/lowering/runtime-optional-ownership.js.map +1 -1
- package/dist/frontend/lowering/runtime-optional-provenance.js +2 -2
- package/dist/frontend/lowering/runtime-optional-provenance.js.map +1 -1
- package/dist/frontend/lowering/runtime-optional-records.d.ts +35 -0
- package/dist/frontend/lowering/runtime-optional-records.js +205 -32
- package/dist/frontend/lowering/runtime-optional-records.js.map +1 -1
- package/dist/frontend/lowering/runtime-optional-records.test.js +19 -1
- package/dist/frontend/lowering/runtime-optional-records.test.js.map +1 -1
- package/dist/frontend/lowering/sanitize-class-types.test.js +2 -2
- package/dist/frontend/lowering/split-consumers.js +4 -4
- package/dist/frontend/lowering/split-consumers.js.map +1 -1
- package/dist/frontend/lowering/static-function-names.d.ts +28 -0
- package/dist/frontend/lowering/static-function-names.js +212 -0
- package/dist/frontend/lowering/static-function-names.js.map +1 -0
- package/dist/frontend/lowering/static-this.js +6 -6
- package/dist/frontend/lowering/static-this.js.map +1 -1
- package/dist/frontend/lowering/strict-mode.d.ts +5 -0
- package/dist/frontend/lowering/strict-mode.js +31 -0
- package/dist/frontend/lowering/strict-mode.js.map +1 -0
- package/dist/frontend/lowering/string-index-bounds.js +10 -10
- package/dist/frontend/lowering/string-index-bounds.js.map +1 -1
- package/dist/frontend/lowering/string-index.d.ts +12 -0
- package/dist/frontend/lowering/string-index.js +72 -1
- package/dist/frontend/lowering/string-index.js.map +1 -1
- package/dist/frontend/lowering/surfaces.d.ts +15 -6
- package/dist/frontend/lowering/surfaces.js +278 -45
- package/dist/frontend/lowering/surfaces.js.map +1 -1
- package/dist/frontend/lowering/symbol-fields.d.ts +7 -0
- package/dist/frontend/lowering/symbol-fields.js +204 -36
- package/dist/frontend/lowering/symbol-fields.js.map +1 -1
- package/dist/frontend/lowering/symbol-methods.d.ts +2 -1
- package/dist/frontend/lowering/symbol-methods.js +24 -6
- package/dist/frontend/lowering/symbol-methods.js.map +1 -1
- package/dist/frontend/lowering/thread-slots.d.ts +13 -0
- package/dist/frontend/lowering/thread-slots.js +208 -0
- package/dist/frontend/lowering/thread-slots.js.map +1 -0
- package/dist/frontend/lowering/typed-arguments.d.ts +74 -0
- package/dist/frontend/lowering/typed-arguments.js +472 -0
- package/dist/frontend/lowering/typed-arguments.js.map +1 -0
- package/dist/frontend/lowering/union-retag.d.ts +8 -0
- package/dist/frontend/lowering/union-retag.js +27 -0
- package/dist/frontend/lowering/union-retag.js.map +1 -1
- package/dist/frontend/lowering/union-retag.test.js +24 -1
- package/dist/frontend/lowering/union-retag.test.js.map +1 -1
- package/dist/frontend/lowering/var-hoisting.js +6 -6
- package/dist/frontend/lowering/var-hoisting.js.map +1 -1
- package/dist/frontend/lowering/width-lift.d.ts +4 -0
- package/dist/frontend/mock-shapes.d.ts +5 -0
- package/dist/frontend/mock-shapes.js +39 -7
- package/dist/frontend/mock-shapes.js.map +1 -1
- package/dist/frontend/module-source-candidates.js +1 -1
- package/dist/frontend/module-source-candidates.js.map +1 -1
- package/dist/frontend/module-source-candidates.test.js +2 -1
- package/dist/frontend/module-source-candidates.test.js.map +1 -1
- package/dist/frontend/module-syntax.js +8 -8
- package/dist/frontend/module-syntax.js.map +1 -1
- package/dist/frontend/npm-static-bundled-chunks.d.ts +51 -0
- package/dist/frontend/npm-static-bundled-chunks.js +810 -0
- package/dist/frontend/npm-static-bundled-chunks.js.map +1 -0
- package/dist/frontend/npm-static-bundled-chunks.test.d.ts +1 -0
- package/dist/frontend/npm-static-bundled-chunks.test.js +287 -0
- package/dist/frontend/npm-static-bundled-chunks.test.js.map +1 -0
- package/dist/frontend/npm-static-bundled-cjs.js +24 -23
- package/dist/frontend/npm-static-bundled-cjs.js.map +1 -1
- package/dist/frontend/npm-static-bundled-esm.d.ts +9 -0
- package/dist/frontend/npm-static-bundled-esm.js +768 -0
- package/dist/frontend/npm-static-bundled-esm.js.map +1 -0
- package/dist/frontend/npm-static-bundled-esm.test.d.ts +1 -0
- package/dist/frontend/npm-static-bundled-esm.test.js +207 -0
- package/dist/frontend/npm-static-bundled-esm.test.js.map +1 -0
- package/dist/frontend/npm-static-cjs-exports-alias.d.ts +2 -0
- package/dist/frontend/npm-static-cjs-exports-alias.js +186 -0
- package/dist/frontend/npm-static-cjs-exports-alias.js.map +1 -0
- package/dist/frontend/npm-static-cjs-exports-alias.test.d.ts +1 -0
- package/dist/frontend/npm-static-cjs-exports-alias.test.js +73 -0
- package/dist/frontend/npm-static-cjs-exports-alias.test.js.map +1 -0
- package/dist/frontend/npm-static-cjs-exports-var.d.ts +2 -0
- package/dist/frontend/npm-static-cjs-exports-var.js +236 -0
- package/dist/frontend/npm-static-cjs-exports-var.js.map +1 -0
- package/dist/frontend/npm-static-declaration-syntax.js +102 -101
- package/dist/frontend/npm-static-declaration-syntax.js.map +1 -1
- package/dist/frontend/npm-static-prune.js +36 -24
- package/dist/frontend/npm-static-prune.js.map +1 -1
- package/dist/frontend/npm-static-rewrite-host.d.ts +4 -1
- package/dist/frontend/npm-static-rewrite-host.js +14 -3
- package/dist/frontend/npm-static-rewrite-host.js.map +1 -1
- package/dist/frontend/npm-static-rewrite-syntax.d.ts +19 -0
- package/dist/frontend/npm-static-rewrite-syntax.js +274 -101
- package/dist/frontend/npm-static-rewrite-syntax.js.map +1 -1
- package/dist/frontend/npm-static-subtyping.js +7 -9
- package/dist/frontend/npm-static-subtyping.js.map +1 -1
- package/dist/frontend/npm-static.d.ts +17 -1
- package/dist/frontend/npm-static.js +167 -16
- package/dist/frontend/npm-static.js.map +1 -1
- package/dist/frontend/npm-static.test.js +22 -1
- package/dist/frontend/npm-static.test.js.map +1 -1
- package/dist/frontend/pipeline.js +164 -26
- package/dist/frontend/pipeline.js.map +1 -1
- package/dist/frontend/pipeline.test.js +22 -1
- package/dist/frontend/pipeline.test.js.map +1 -1
- package/dist/frontend/program-analysis.d.ts +6 -1
- package/dist/frontend/program-analysis.js +7 -0
- package/dist/frontend/program-analysis.js.map +1 -1
- package/dist/frontend/program.d.ts +92 -2
- package/dist/frontend/program.js +1557 -254
- package/dist/frontend/program.js.map +1 -1
- package/dist/frontend/program.test.js +76 -6
- package/dist/frontend/program.test.js.map +1 -1
- package/dist/frontend/resolve.js +36 -2
- package/dist/frontend/resolve.js.map +1 -1
- package/dist/frontend/resolve.test.js +49 -0
- package/dist/frontend/resolve.test.js.map +1 -1
- package/dist/frontend/services.d.ts +20 -1
- package/dist/frontend/services.js +40 -3
- package/dist/frontend/services.js.map +1 -1
- package/dist/frontend/services.test.js +2 -1
- package/dist/frontend/services.test.js.map +1 -1
- package/dist/frontend/threads-import.js +1 -1
- package/dist/frontend/threads-import.js.map +1 -1
- package/dist/frontend/tier-analysis.d.ts +71 -0
- package/dist/frontend/tier-analysis.js +522 -0
- package/dist/frontend/tier-analysis.js.map +1 -0
- package/dist/frontend/ts7/api-conformance.d.ts +234 -0
- package/dist/frontend/ts7/api-conformance.js +7 -0
- package/dist/frontend/ts7/api-conformance.js.map +1 -0
- package/dist/frontend/ts7/ast-guards.generated.js +2 -1
- package/dist/frontend/ts7/ast-guards.generated.js.map +1 -1
- package/dist/frontend/ts7/ast-node.d.ts +47 -25
- package/dist/frontend/ts7/ast-node.js +64 -18
- package/dist/frontend/ts7/ast-node.js.map +1 -1
- package/dist/frontend/ts7/ast-node.test.js +36 -12
- package/dist/frontend/ts7/ast-node.test.js.map +1 -1
- package/dist/frontend/ts7/ast-types.d.ts +10 -3
- package/dist/frontend/ts7/ast-types.generated.d.ts +39 -39
- package/dist/frontend/ts7/ast.d.ts +1 -0
- package/dist/frontend/ts7/ast.js +3 -2
- package/dist/frontend/ts7/ast.js.map +1 -1
- package/dist/frontend/ts7/checker-backend.d.ts +23 -0
- package/dist/frontend/ts7/checker-backend.js +88 -0
- package/dist/frontend/ts7/checker-backend.js.map +1 -0
- package/dist/frontend/ts7/checker-backend.test.d.ts +1 -0
- package/dist/frontend/ts7/checker-backend.test.js +63 -0
- package/dist/frontend/ts7/checker-backend.test.js.map +1 -0
- package/dist/frontend/ts7/checker-cache.d.ts +0 -3
- package/dist/frontend/ts7/checker-cache.js +0 -6
- package/dist/frontend/ts7/checker-cache.js.map +1 -1
- package/dist/frontend/ts7/checker.d.ts +18 -11
- package/dist/frontend/ts7/checker.js +42 -55
- package/dist/frontend/ts7/checker.js.map +1 -1
- package/dist/frontend/ts7/checker.test.js +10 -7
- package/dist/frontend/ts7/checker.test.js.map +1 -1
- package/dist/frontend/ts7/diagnostic.d.ts +19 -0
- package/dist/frontend/ts7/diagnostic.js +22 -0
- package/dist/frontend/ts7/diagnostic.js.map +1 -0
- package/dist/frontend/ts7/node-functions.d.ts +8 -0
- package/dist/frontend/ts7/node-functions.js +18 -0
- package/dist/frontend/ts7/node-functions.js.map +1 -0
- package/dist/frontend/ts7/program-host.d.ts +5 -1
- package/dist/frontend/ts7/program-host.js +12 -0
- package/dist/frontend/ts7/program-host.js.map +1 -1
- package/dist/frontend/ts7/rpc-api.d.ts +5 -1
- package/dist/frontend/ts7/rpc-api.js +8 -1
- package/dist/frontend/ts7/rpc-api.js.map +1 -1
- package/dist/frontend/ts7/semantic-checker.d.ts +13 -6
- package/dist/frontend/ts7/semantic-checker.js +26 -8
- package/dist/frontend/ts7/semantic-checker.js.map +1 -1
- package/dist/frontend/ts7/semantic-checker.test.js +12 -9
- package/dist/frontend/ts7/semantic-checker.test.js.map +1 -1
- package/dist/frontend/ts7/semantic-model.d.ts +54 -24
- package/dist/frontend/ts7/semantic-model.js +88 -16
- package/dist/frontend/ts7/semantic-model.js.map +1 -1
- package/dist/frontend/ts7/semantic-model.test.js +4 -4
- package/dist/frontend/ts7/semantic-model.test.js.map +1 -1
- package/dist/frontend/ts7/semantic-types.d.ts +7 -3
- package/dist/frontend/ts7/semantic-types.js +1 -1
- package/dist/frontend/ts7/semantic-types.js.map +1 -1
- package/dist/frontend/ts7/session.d.ts +11 -11
- package/dist/frontend/ts7/session.js +8 -5
- package/dist/frontend/ts7/session.js.map +1 -1
- package/dist/frontend/ts7/session.test.js +9 -5
- package/dist/frontend/ts7/session.test.js.map +1 -1
- package/dist/frontend/ts7/source-parser.d.ts +6 -2
- package/dist/frontend/ts7/source-parser.js +24 -3
- package/dist/frontend/ts7/source-parser.js.map +1 -1
- package/dist/frontend/ts7/source-parser.test.js +38 -17
- package/dist/frontend/ts7/source-parser.test.js.map +1 -1
- package/dist/frontend/type-mapper.d.ts +122 -2
- package/dist/frontend/type-mapper.js +2612 -695
- package/dist/frontend/type-mapper.js.map +1 -1
- package/dist/frontend/type-only-imports.d.ts +28 -0
- package/dist/frontend/type-only-imports.js +122 -0
- package/dist/frontend/type-only-imports.js.map +1 -0
- package/dist/frontend/worker-target.js +8 -8
- package/dist/frontend/worker-target.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +47 -10
- package/dist/index.js.map +1 -1
- package/dist/ir/analysis.js +4 -2
- package/dist/ir/analysis.js.map +1 -1
- package/dist/ir/api.d.ts +1 -1
- package/dist/ir/api.js +1 -1
- package/dist/ir/api.js.map +1 -1
- package/dist/ir/array-length-stability.d.ts +30 -0
- package/dist/ir/array-length-stability.js +236 -0
- package/dist/ir/array-length-stability.js.map +1 -0
- package/dist/ir/array-length-stability.test.d.ts +1 -0
- package/dist/ir/array-length-stability.test.js +113 -0
- package/dist/ir/array-length-stability.test.js.map +1 -0
- package/dist/ir/build.d.ts +2 -2
- package/dist/ir/build.js +1 -1
- package/dist/ir/build.js.map +1 -1
- package/dist/ir/builtin-effects.js +139 -0
- package/dist/ir/builtin-effects.js.map +1 -1
- package/dist/ir/builtin-signatures.d.ts +1 -1
- package/dist/ir/builtin-signatures.js +655 -25
- package/dist/ir/builtin-signatures.js.map +1 -1
- package/dist/ir/byte-numbers.js +3 -0
- package/dist/ir/byte-numbers.js.map +1 -1
- package/dist/ir/callback-specialization.d.ts +37 -0
- package/dist/ir/callback-specialization.js +459 -0
- package/dist/ir/callback-specialization.js.map +1 -0
- package/dist/ir/callback-specialization.test.d.ts +1 -0
- package/dist/ir/callback-specialization.test.js +208 -0
- package/dist/ir/callback-specialization.test.js.map +1 -0
- package/dist/ir/capture-values.d.ts +0 -1
- package/dist/ir/capture-values.js +51 -40
- package/dist/ir/capture-values.js.map +1 -1
- package/dist/ir/constant-globals.test.js +1 -1
- package/dist/ir/constant-tables.test.js +1 -1
- package/dist/ir/field-values.test.js +1 -1
- package/dist/ir/final-fields.test.js +1 -1
- package/dist/ir/function-references.test.js +10 -1
- package/dist/ir/function-references.test.js.map +1 -1
- package/dist/ir/init-only-globals.test.js +1 -1
- package/dist/ir/initializer-bindings.test.js +1 -1
- package/dist/ir/int32-slots.d.ts +14 -0
- package/dist/ir/int32-slots.js +119 -14
- package/dist/ir/int32-slots.js.map +1 -1
- package/dist/ir/int32-slots.test.js +29 -1
- package/dist/ir/int32-slots.test.js.map +1 -1
- package/dist/ir/integer-loop-facts.d.ts +16 -6
- package/dist/ir/integer-loop-facts.js +143 -38
- package/dist/ir/integer-loop-facts.js.map +1 -1
- package/dist/ir/integer-loops.d.ts +1 -1
- package/dist/ir/integer-loops.js +39 -9
- package/dist/ir/integer-loops.js.map +1 -1
- package/dist/ir/integer-loops.test.js +104 -0
- package/dist/ir/integer-loops.test.js.map +1 -1
- package/dist/ir/integer-ranges.d.ts +3 -0
- package/dist/ir/integer-ranges.js +4 -6
- package/dist/ir/integer-ranges.js.map +1 -1
- package/dist/ir/integer-ranges.test.js +142 -1
- package/dist/ir/integer-ranges.test.js.map +1 -1
- package/dist/ir/intrinsic-signatures.js +6 -0
- package/dist/ir/intrinsic-signatures.js.map +1 -1
- package/dist/ir/ir.d.ts +234 -58
- package/dist/ir/ir.js +123 -12
- package/dist/ir/ir.js.map +1 -1
- package/dist/ir/ir.test.js +10 -0
- package/dist/ir/ir.test.js.map +1 -1
- package/dist/ir/jsval.d.ts +8 -0
- package/dist/ir/jsval.js +365 -0
- package/dist/ir/jsval.js.map +1 -0
- package/dist/ir/jsval.test.d.ts +1 -0
- package/dist/ir/jsval.test.js +239 -0
- package/dist/ir/jsval.test.js.map +1 -0
- package/dist/ir/runtime-features.d.ts +150 -33
- package/dist/ir/runtime-features.js +672 -339
- package/dist/ir/runtime-features.js.map +1 -1
- package/dist/ir/runtime-features.test.js +62 -0
- package/dist/ir/runtime-features.test.js.map +1 -1
- package/dist/ir/scalar-records.test.js +1 -1
- package/dist/ir/self-captures.d.ts +33 -0
- package/dist/ir/self-captures.js +245 -0
- package/dist/ir/self-captures.js.map +1 -0
- package/dist/ir/self-captures.test.d.ts +1 -0
- package/dist/ir/self-captures.test.js +135 -0
- package/dist/ir/self-captures.test.js.map +1 -0
- package/dist/ir/serialize.d.ts +1 -1
- package/dist/ir/serialize.js +7 -4
- package/dist/ir/serialize.js.map +1 -1
- package/dist/ir/tiers.d.ts +26 -0
- package/dist/ir/tiers.js +101 -0
- package/dist/ir/tiers.js.map +1 -0
- package/dist/ir/tiers.test.d.ts +1 -0
- package/dist/ir/tiers.test.js +140 -0
- package/dist/ir/tiers.test.js.map +1 -0
- package/dist/ir/traverse.js +107 -94
- package/dist/ir/traverse.js.map +1 -1
- package/dist/ir/traverse.test.js +33 -30
- package/dist/ir/traverse.test.js.map +1 -1
- package/dist/ir/unshare.js +65 -3
- package/dist/ir/unshare.js.map +1 -1
- package/dist/ir/unshare.test.js +1 -1
- package/dist/ir/validate.js +220 -71
- package/dist/ir/validate.js.map +1 -1
- package/dist/ir/validate.test.js +64 -9
- package/dist/ir/validate.test.js.map +1 -1
- package/dist/library/fence-eval.test.js +1 -1
- package/dist/library/int-infer.test.js +4 -4
- package/dist/library/ir-policy.js +18 -0
- package/dist/library/ir-policy.js.map +1 -1
- package/dist/library/library-cache.d.ts +1 -0
- package/dist/library/library-cache.js.map +1 -1
- package/dist/library/library-cache.test.js +5 -5
- package/dist/library/library-profile.d.ts +4 -4
- package/dist/library/library-profile.js +35 -7
- package/dist/library/library-profile.js.map +1 -1
- package/dist/library/prepare.js +13 -1
- package/dist/library/prepare.js.map +1 -1
- package/dist/native/cli.js +5 -0
- package/dist/native/cli.js.map +1 -1
- package/dist/native/compiler.js +2 -2
- package/dist/native/compiler.js.map +1 -1
- package/dist/native/compiler.test.js +2 -2
- package/dist/native/prepare.js +7 -0
- package/dist/native/prepare.js.map +1 -1
- package/dist/native/sanitizer.test.js +12 -0
- package/dist/native/sanitizer.test.js.map +1 -1
- package/dist/native/toolchain.d.ts +2 -0
- package/dist/native/toolchain.js +10 -1
- package/dist/native/toolchain.js.map +1 -1
- package/dist/native/toolchain.test.js +39 -1
- package/dist/native/toolchain.test.js.map +1 -1
- package/dist/startup-cache.d.ts +1 -0
- package/dist/startup-cache.js +1 -0
- package/dist/startup-cache.js.map +1 -1
- package/dist/wasm/base64.d.ts +5 -0
- package/dist/wasm/base64.js +62 -0
- package/dist/wasm/base64.js.map +1 -0
- package/dist/wasm/binary.d.ts +36 -0
- package/dist/wasm/binary.js +1976 -0
- package/dist/wasm/binary.js.map +1 -0
- package/dist/wasm/binary.test.d.ts +1 -0
- package/dist/wasm/binary.test.js +190 -0
- package/dist/wasm/binary.test.js.map +1 -0
- package/dist/wasm/discover.d.ts +38 -0
- package/dist/wasm/discover.js +377 -0
- package/dist/wasm/discover.js.map +1 -0
- package/dist/wasm/discover.test.d.ts +1 -0
- package/dist/wasm/discover.test.js +24 -0
- package/dist/wasm/discover.test.js.map +1 -0
- package/dist/wasm/module.d.ts +151 -0
- package/dist/wasm/module.js +575 -0
- package/dist/wasm/module.js.map +1 -0
- package/dist/wasm/translate.d.ts +48 -0
- package/dist/wasm/translate.js +2129 -0
- package/dist/wasm/translate.js.map +1 -0
- package/dist/wasm/translate.test.d.ts +1 -0
- package/dist/wasm/translate.test.js +207 -0
- package/dist/wasm/translate.test.js.map +1 -0
- package/package.json +21 -20
- package/surface-manifest.json +332 -36
|
@@ -1,5 +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";
|
|
6
|
+
import { lowerReadlineUiNew } from "./builtins/readline.js";
|
|
7
|
+
import { checkedClassUnionAssertion } from "./class-assertions.js";
|
|
3
8
|
import { collectClassMethodMutations } from "./class-method-mutations.js";
|
|
4
9
|
import { InternalCompilerError } from "../../errors.js";
|
|
5
10
|
/* Class lowering: shape collection over the single-inheritance graph
|
|
@@ -8,40 +13,47 @@ import { InternalCompilerError } from "../../errors.js";
|
|
|
8
13
|
* accessor access, upcasts, `new` expressions, and the builtin Error
|
|
9
14
|
* hierarchy registration. */
|
|
10
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";
|
|
11
18
|
import * as ts from "../ts7/adapter.js";
|
|
12
|
-
import { lowerZlibStreamNew, zlibStreamModeOf } from "./builtins/compression.js";
|
|
13
|
-
import {
|
|
14
|
-
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";
|
|
15
25
|
import { extendInstantiationPath, MAX_INSTANTIATION_RECURSION, } from "./instantiation-path.js";
|
|
16
26
|
import { appendImplicitUndefinedReturn, hasExplicitJsDocReturn } from "./function-returns.js";
|
|
17
27
|
import { bodyReadsArguments } from "../arguments-usage.js";
|
|
18
|
-
import {
|
|
28
|
+
import { errorNameAfterField, errorViewFields } from "./error-name-order.js";
|
|
29
|
+
import { checkedJsDocumentedParameter, documentedParameter, generatorMeta, } from "./call-signatures.js";
|
|
19
30
|
import { omittedArgFor } from "./call-arguments.js";
|
|
20
31
|
import { isGenericCallableMemberType, jsOpenObjectType, typeKey, withUnitArm, } from "../type-mapper.js";
|
|
21
|
-
import { cjsClassExprWholeExportOf, isCjsJsFile, isJsSourceFile, isModuleExportsAccess,
|
|
22
|
-
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";
|
|
23
34
|
import { isAssertClassNew } from "./assert-instances.js";
|
|
24
35
|
import { lowerArrayConstructor } from "./containers/array-construction.js";
|
|
25
36
|
import { lowerMapSeedNew, lowerSetSeedNew } from "./containers/collection-methods.js";
|
|
26
37
|
import { lowerObjectConstructor } from "./containers/indexed-objects.js";
|
|
27
|
-
import {
|
|
38
|
+
import { knownBufEncoding } from "./containers/bytes.js";
|
|
28
39
|
import { isSafeToRepeat } from "./expressions/evaluation-safety.js";
|
|
29
40
|
import { lowerSearchParamsNew } from "./builtins/url.js";
|
|
30
41
|
import { lowerTextCodecNew } from "./builtins/text-codecs.js";
|
|
31
|
-
import { lowerWorkerNew } from "./builtins/workers.js";
|
|
42
|
+
import { lowerBroadcastChannelNew, lowerMessageChannelNew, lowerWorkerNew, } from "./builtins/workers.js";
|
|
32
43
|
import { unsupportedPackageValueDiag, unsupportedDiag, } from "../../diagnostics/diagnostic.js";
|
|
33
|
-
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";
|
|
34
45
|
import { builtinEventTargetBaseOf, eventTargetApiMembers, eventTargetApiMethod, eventTargetRootOf, eventTargetSuperCall, lowerEventTargetMethodCall, } from "./lower-event-target.js";
|
|
35
46
|
import { emitOverrideShapeReason, emitSpecSuperForward, emitterRooted, lowerEmitterSuperCall, } from "./lower-event-emitter.js";
|
|
36
47
|
import { declSymbolOf } from "./lower-modules.js";
|
|
37
48
|
import { classSymbolKeyOf, classSymbolKeyOfSymbol, symbolFieldDisplayName, } from "./symbol-fields.js";
|
|
38
49
|
import { lowerHttpAgentNew, lowerHttpServerNew } from "./lower-server.js";
|
|
39
|
-
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";
|
|
40
51
|
import { mixinResultBindingClassOf } from "./lower-mixins.js";
|
|
41
52
|
import { hasLexicalPrivateReference, hasStaticThis, rejectStaticThis } from "./static-this.js";
|
|
42
53
|
import { lowerUrlNew } from "./lower-url.js";
|
|
43
54
|
import { isNativeProxyInitializer, lowerNativeProxy } from "./expressions/native-proxy.js";
|
|
44
55
|
import { classStaticDataFor } from "./class-static-data.js";
|
|
56
|
+
import { construction, constructionPrefix } from "./js-class-fields.js";
|
|
45
57
|
import { lowerObjectFactoryNew } from "./object-factory-new.js";
|
|
46
58
|
import { tryLowerExpression } from "./expressions/try-lower-expression.js";
|
|
47
59
|
import { lowerInstanceConstructorNew } from "./class-instance-constructor.js";
|
|
@@ -52,7 +64,7 @@ import { initializeRuntimeStatics, hasRuntimeStatics } from "./class-runtime-sta
|
|
|
52
64
|
import { reflectedClassStaticMethodValue } from "./class-method-values.js";
|
|
53
65
|
export function returnsOnlyThis(member) {
|
|
54
66
|
const body = member.body;
|
|
55
|
-
const last = body?.statements.at(-1);
|
|
67
|
+
const last = body?.statements?.nodes.at(-1);
|
|
56
68
|
if (!body || !last || !ts.isReturnStatement(last))
|
|
57
69
|
return false;
|
|
58
70
|
let valid = true;
|
|
@@ -66,9 +78,43 @@ export function returnsOnlyThis(member) {
|
|
|
66
78
|
if (!value || value.kind !== ts.SyntaxKind.ThisKeyword)
|
|
67
79
|
valid = false;
|
|
68
80
|
}
|
|
69
|
-
|
|
81
|
+
ts.forEachChild(node, visit);
|
|
70
82
|
};
|
|
71
|
-
|
|
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);
|
|
72
118
|
return valid;
|
|
73
119
|
}
|
|
74
120
|
function functionLocalClass(decl) {
|
|
@@ -106,9 +152,7 @@ export function storedClassValueType(lowerer, expression, visiting = new Set())
|
|
|
106
152
|
return stored.type;
|
|
107
153
|
const symbol = lowerer.resolveValueSymbol(expression);
|
|
108
154
|
const declaration = symbol &&
|
|
109
|
-
|
|
110
|
-
.declarationsOf(symbol)
|
|
111
|
-
.find((decl) => ts.isVariableDeclaration(decl) &&
|
|
155
|
+
symbol.declarations.find((decl) => ts.isVariableDeclaration(decl) &&
|
|
112
156
|
decl.initializer &&
|
|
113
157
|
(ts.getCombinedNodeFlags(decl) & ts.NodeFlags.Const) !== 0);
|
|
114
158
|
if (declaration && ts.isVariableDeclaration(declaration) && declaration.initializer) {
|
|
@@ -117,11 +161,17 @@ export function storedClassValueType(lowerer, expression, visiting = new Set())
|
|
|
117
161
|
return value;
|
|
118
162
|
}
|
|
119
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
|
+
}
|
|
120
170
|
const type = lowerer.typeOf(expression);
|
|
121
171
|
const mapped = lowerer.mapTypeOf(type);
|
|
122
172
|
if (mapped?.kind === "classval" && !lowerer.classes.has(mapped.className)) {
|
|
123
173
|
for (const signature of lowerer.checker.getConstructSignatures(type)) {
|
|
124
|
-
const constructor =
|
|
174
|
+
const constructor = signature.declaration;
|
|
125
175
|
const declaration = constructor && ts.isConstructorDeclaration(constructor) ? constructor.parent : undefined;
|
|
126
176
|
if (declaration &&
|
|
127
177
|
ts.isClassExpression(declaration) &&
|
|
@@ -160,9 +210,7 @@ export function storedClassValueType(lowerer, expression, visiting = new Set())
|
|
|
160
210
|
if (ts.isIdentifier(callee)) {
|
|
161
211
|
const symbol = lowerer.resolveValueSymbol(callee);
|
|
162
212
|
const declaration = symbol &&
|
|
163
|
-
|
|
164
|
-
.declarationsOf(symbol)
|
|
165
|
-
.find((decl) => ts.isVariableDeclaration(decl) &&
|
|
213
|
+
symbol.declarations.find((decl) => ts.isVariableDeclaration(decl) &&
|
|
166
214
|
decl.initializer &&
|
|
167
215
|
(ts.getCombinedNodeFlags(decl) & ts.NodeFlags.Const) !== 0);
|
|
168
216
|
if (declaration && ts.isVariableDeclaration(declaration) && declaration.initializer) {
|
|
@@ -173,8 +221,8 @@ export function storedClassValueType(lowerer, expression, visiting = new Set())
|
|
|
173
221
|
break;
|
|
174
222
|
}
|
|
175
223
|
if ((ts.isArrowFunction(callee) || ts.isFunctionExpression(callee)) &&
|
|
176
|
-
isJsSourceFile(
|
|
177
|
-
!callee.typeParameters?.length &&
|
|
224
|
+
isJsSourceFile(ts.getSourceFileOfNode(callee)) &&
|
|
225
|
+
!callee.typeParameters?.nodes.length &&
|
|
178
226
|
!lowerer.preparingClassFactories.has(callee)) {
|
|
179
227
|
const signature = lowerer.checker.getSignatureFromDeclaration(callee);
|
|
180
228
|
let result = signature && lowerer.checker.getReturnTypeOfSignature(signature);
|
|
@@ -226,7 +274,7 @@ export function storedClassValueType(lowerer, expression, visiting = new Set())
|
|
|
226
274
|
// Cache the module-level closure so its captures and lifted bodies are
|
|
227
275
|
// exactly the ones used when the declaration executes.
|
|
228
276
|
for (const signature of lowerer.checker.getConstructSignatures(type)) {
|
|
229
|
-
const declaration =
|
|
277
|
+
const declaration = signature.declaration;
|
|
230
278
|
const cls = declaration && ts.isConstructorDeclaration(declaration) ? declaration.parent : null;
|
|
231
279
|
if (!cls || (!ts.isClassExpression(cls) && !ts.isClassDeclaration(cls)))
|
|
232
280
|
continue;
|
|
@@ -240,8 +288,8 @@ export function storedClassValueType(lowerer, expression, visiting = new Set())
|
|
|
240
288
|
}
|
|
241
289
|
}
|
|
242
290
|
if (!factory ||
|
|
243
|
-
!isJsSourceFile(
|
|
244
|
-
factory.typeParameters?.length ||
|
|
291
|
+
!isJsSourceFile(ts.getSourceFileOfNode(factory)) ||
|
|
292
|
+
factory.typeParameters?.nodes.length ||
|
|
245
293
|
!ts.isVariableDeclaration(factory.parent) ||
|
|
246
294
|
factory.parent.initializer !== factory ||
|
|
247
295
|
!ts.isVariableDeclarationList(factory.parent.parent) ||
|
|
@@ -276,7 +324,7 @@ export function storedClassValueType(lowerer, expression, visiting = new Set())
|
|
|
276
324
|
* or the ElementAccessExpression itself). Null when no declaration has
|
|
277
325
|
* that shape (well-known-symbol members like `[Symbol.iterator]`). */
|
|
278
326
|
function lateBoundKeySymOf(lowerer, p) {
|
|
279
|
-
for (const d of
|
|
327
|
+
for (const d of p.declarations) {
|
|
280
328
|
const access = ts.isBinaryExpression(d) && ts.isElementAccessExpression(d.left)
|
|
281
329
|
? d.left
|
|
282
330
|
: ts.isElementAccessExpression(d)
|
|
@@ -310,13 +358,13 @@ function symbolSlotReturnType(lowerer, fnLike, symbolFields, fields) {
|
|
|
310
358
|
return null;
|
|
311
359
|
if (fnLike.type !== undefined || !fnLike.body)
|
|
312
360
|
return null;
|
|
313
|
-
if (!isJsSourceFile(
|
|
361
|
+
if (!isJsSourceFile(ts.getSourceFileOfNode(fnLike)))
|
|
314
362
|
return null;
|
|
315
363
|
if (fnLike.asteriskToken !== undefined)
|
|
316
364
|
return null;
|
|
317
|
-
if (fnLike.modifiers?.some((m) => m.kind === ts.SyntaxKind.AsyncKeyword))
|
|
365
|
+
if (fnLike.modifiers?.nodes.some((m) => m.kind === ts.SyntaxKind.AsyncKeyword))
|
|
318
366
|
return null;
|
|
319
|
-
const stmts = fnLike.body.statements;
|
|
367
|
+
const stmts = fnLike.body.statements.nodes;
|
|
320
368
|
const last = stmts[stmts.length - 1];
|
|
321
369
|
if (!last || !ts.isReturnStatement(last))
|
|
322
370
|
return null;
|
|
@@ -326,9 +374,9 @@ function symbolSlotReturnType(lowerer, fnLike, symbolFields, fields) {
|
|
|
326
374
|
return;
|
|
327
375
|
if (ts.isReturnStatement(n))
|
|
328
376
|
returns.push(n);
|
|
329
|
-
|
|
377
|
+
ts.forEachChild(n, visit);
|
|
330
378
|
};
|
|
331
|
-
fnLike.body
|
|
379
|
+
ts.forEachChild(fnLike.body, visit);
|
|
332
380
|
let out = null;
|
|
333
381
|
for (const r of returns) {
|
|
334
382
|
let e = r.expression;
|
|
@@ -349,6 +397,16 @@ function symbolSlotReturnType(lowerer, fnLike, symbolFields, fields) {
|
|
|
349
397
|
}
|
|
350
398
|
return out;
|
|
351
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
|
+
]);
|
|
352
410
|
/** The builtin Error hierarchy
|
|
353
411
|
* as eagerly-registered ClassInfos: mapType names them the moment a lib
|
|
354
412
|
* Error type appears, so the infos must exist before any lowering. They
|
|
@@ -390,6 +448,10 @@ export function registerBuiltinErrorClasses(lowerer) {
|
|
|
390
448
|
{ name: "%systemCall", type: STRING },
|
|
391
449
|
{ name: "%systemPath", type: STRING },
|
|
392
450
|
{ name: "%systemDest", type: STRING },
|
|
451
|
+
{ name: "%systemMessage", type: STRING },
|
|
452
|
+
{ name: "%systemCode", type: STRING },
|
|
453
|
+
{ name: "%nativePlain", type: BOOL },
|
|
454
|
+
{ name: "%errnoOrder", type: BOOL },
|
|
393
455
|
],
|
|
394
456
|
loc,
|
|
395
457
|
},
|
|
@@ -413,6 +475,17 @@ export function registerBuiltinErrorClasses(lowerer) {
|
|
|
413
475
|
{ type: DYN, mode: "omittable" },
|
|
414
476
|
{ type: DYN, mode: "omittable" },
|
|
415
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
|
+
: {}),
|
|
416
489
|
base,
|
|
417
490
|
subclasses: [],
|
|
418
491
|
throwingSetters: [],
|
|
@@ -445,6 +518,7 @@ export function registerBuiltinEmitterClass(lowerer) {
|
|
|
445
518
|
// `new EventEmitter()` — zero-argument (the options bag fences at
|
|
446
519
|
// construction sites; the checker may admit it via @types/node).
|
|
447
520
|
ctorParams: [],
|
|
521
|
+
valueCtorParams: [],
|
|
448
522
|
base: null,
|
|
449
523
|
subclasses: [],
|
|
450
524
|
throwingSetters: [],
|
|
@@ -475,6 +549,9 @@ export function registerBuiltinStreamClasses(lowerer) {
|
|
|
475
549
|
// `new Readable(opts?)` — the options bag is parsed structurally
|
|
476
550
|
// by the stream spoke (lowerNew never completes against this).
|
|
477
551
|
ctorParams: [],
|
|
552
|
+
// Construction through a class value builds the stream without
|
|
553
|
+
// options (lowerNew reports options passed through a value).
|
|
554
|
+
valueCtorParams: [],
|
|
478
555
|
base,
|
|
479
556
|
subclasses: [],
|
|
480
557
|
throwingSetters: [],
|
|
@@ -491,10 +568,14 @@ export function registerBuiltinStreamClasses(lowerer) {
|
|
|
491
568
|
* "stream" ambient module, EXCLUDING @types/node's (whose stream.Readable
|
|
492
569
|
* also types child stdio — under @types/node the childStream mapping
|
|
493
570
|
* keeps priority and the static stream classes stand down; the shipped
|
|
494
|
-
* 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). */
|
|
495
573
|
export function builtinStreamInfoOf(lowerer, symbol) {
|
|
496
574
|
if (!symbol)
|
|
497
575
|
return null;
|
|
576
|
+
const alias = builtinClassAliasOf(lowerer, symbol);
|
|
577
|
+
if (alias !== null)
|
|
578
|
+
return alias.kind === "stream" ? alias.info : null;
|
|
498
579
|
if (!lowerer.isStdlibSymbol(symbol)) {
|
|
499
580
|
// A const ALIAS of a namespace member (`const Writable =
|
|
500
581
|
// stream.Writable` — the two-step spelling; the one-step
|
|
@@ -502,7 +583,7 @@ export function builtinStreamInfoOf(lowerer, symbol) {
|
|
|
502
583
|
// member to the stdlib class symbol. The declaration itself is
|
|
503
584
|
// alias plumbing (streamClassAliasDecl — both declaration walks
|
|
504
585
|
// skip it).
|
|
505
|
-
const decl =
|
|
586
|
+
const decl = symbol.valueDeclaration;
|
|
506
587
|
if (decl &&
|
|
507
588
|
ts.isVariableDeclaration(decl) &&
|
|
508
589
|
(ts.getCombinedNodeFlags(decl) & ts.NodeFlags.Const) !== 0 &&
|
|
@@ -519,16 +600,17 @@ export function builtinStreamInfoOf(lowerer, symbol) {
|
|
|
519
600
|
}
|
|
520
601
|
let irName = null;
|
|
521
602
|
for (const [name, rec] of RUNTIME_STREAM_CLASSES) {
|
|
522
|
-
if (rec.lib === symbol
|
|
603
|
+
if (rec.lib === ts.symbolName(symbol))
|
|
523
604
|
irName = name;
|
|
524
605
|
}
|
|
525
606
|
if (!irName)
|
|
526
607
|
return null;
|
|
527
|
-
|
|
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) => {
|
|
528
612
|
if (!ts.isClassDeclaration(d))
|
|
529
613
|
return false;
|
|
530
|
-
if (isNodeTypesPath(d.getSourceFile().fileName))
|
|
531
|
-
return false;
|
|
532
614
|
let node = d.parent;
|
|
533
615
|
while (node) {
|
|
534
616
|
if (ts.isModuleDeclaration(node) && ts.isStringLiteral(node.name)) {
|
|
@@ -546,10 +628,9 @@ function jsFieldInitializerType(lowerer, type, expression) {
|
|
|
546
628
|
if (ts.isIdentifier(expression)) {
|
|
547
629
|
const symbol = lowerer.checker.getSymbolAtLocation(expression);
|
|
548
630
|
if (symbol &&
|
|
549
|
-
|
|
550
|
-
.
|
|
551
|
-
|
|
552
|
-
(ts.isConstructorDeclaration(decl.parent) ||
|
|
631
|
+
symbol.declarations.some((decl) => ts.isParameter(decl) &&
|
|
632
|
+
((ts.isConstructorDeclaration(decl.parent) &&
|
|
633
|
+
!checkedJsDocumentedParameter(lowerer, decl)) ||
|
|
553
634
|
(lowerer.typeOf(expression).flags & (ts.TypeFlags.Any | ts.TypeFlags.Unknown)) !== 0)))
|
|
554
635
|
return DYN;
|
|
555
636
|
}
|
|
@@ -558,7 +639,7 @@ function jsFieldInitializerType(lowerer, type, expression) {
|
|
|
558
639
|
// JavaScript documentation cannot guarantee that a call or an indexed
|
|
559
640
|
// read returns a present number. Numeric fields receiving those values
|
|
560
641
|
// must retain undefined, so later arithmetic performs JS coercion (NaN).
|
|
561
|
-
if (type.kind === "f64" && isJsSourceFile(
|
|
642
|
+
if (type.kind === "f64" && isJsSourceFile(ts.getSourceFileOfNode(expression))) {
|
|
562
643
|
const assignment = expression.parent;
|
|
563
644
|
const left = ts.isBinaryExpression(assignment) ? assignment.left : null;
|
|
564
645
|
const field = left &&
|
|
@@ -586,7 +667,7 @@ function jsFieldInitializerType(lowerer, type, expression) {
|
|
|
586
667
|
if (ts.isCallExpression(rhs) || ts.isElementAccessExpression(rhs))
|
|
587
668
|
acceptsUnchecked = true;
|
|
588
669
|
}
|
|
589
|
-
|
|
670
|
+
ts.forEachChild(node, scan);
|
|
590
671
|
};
|
|
591
672
|
scan(owner);
|
|
592
673
|
if (acceptsUnchecked)
|
|
@@ -598,14 +679,14 @@ function jsFieldInitializerType(lowerer, type, expression) {
|
|
|
598
679
|
node = node.expression;
|
|
599
680
|
if (ts.isCallExpression(node) && type.kind === "bytes") {
|
|
600
681
|
let prototypeArgument = false;
|
|
601
|
-
for (const argument of node.arguments)
|
|
682
|
+
for (const argument of node.arguments.nodes)
|
|
602
683
|
ts.walkPreorder(argument, (part) => {
|
|
603
684
|
if (!ts.isPropertyAccessExpression(part) ||
|
|
604
685
|
part.expression.kind !== ts.SyntaxKind.ThisKeyword)
|
|
605
686
|
return;
|
|
606
687
|
const symbol = lowerer.checker.getSymbolAtLocation(part.name);
|
|
607
688
|
if (symbol &&
|
|
608
|
-
|
|
689
|
+
symbol.declarations.some((decl) => {
|
|
609
690
|
const member = ts.isBinaryExpression(decl) ? decl.left : decl;
|
|
610
691
|
return (ts.isPropertyAccessExpression(member) &&
|
|
611
692
|
ts.isPropertyAccessExpression(member.expression) &&
|
|
@@ -619,7 +700,7 @@ function jsFieldInitializerType(lowerer, type, expression) {
|
|
|
619
700
|
owner = owner.parent;
|
|
620
701
|
if (owner && (ts.isClassDeclaration(owner) || ts.isClassExpression(owner)) && owner.name) {
|
|
621
702
|
const className = owner.name.text;
|
|
622
|
-
for (const statement of
|
|
703
|
+
for (const statement of ts.getSourceFileOfNode(owner).statements.nodes) {
|
|
623
704
|
if (!ts.isExpressionStatement(statement) ||
|
|
624
705
|
!ts.isBinaryExpression(statement.expression))
|
|
625
706
|
continue;
|
|
@@ -697,7 +778,7 @@ function inheritedJsFieldType(lowerer, decl, name, type) {
|
|
|
697
778
|
return type;
|
|
698
779
|
}
|
|
699
780
|
function returnsWidenedJsField(lowerer, decl, member, fields, ret) {
|
|
700
|
-
if (!isJsSourceFile(
|
|
781
|
+
if (!isJsSourceFile(ts.getSourceFileOfNode(member)) ||
|
|
701
782
|
member.type ||
|
|
702
783
|
member.asteriskToken ||
|
|
703
784
|
hasExplicitJsDocReturn(member))
|
|
@@ -715,10 +796,7 @@ function returnsWidenedJsField(lowerer, decl, member, fields, ret) {
|
|
|
715
796
|
? lowerer.checker.getPropertyOfType(lowerer.typeOf(callee.expression), lowerer.foldedStringKeyOf(callee.argumentExpression) ?? "")
|
|
716
797
|
: undefined;
|
|
717
798
|
if (symbol &&
|
|
718
|
-
lowerer.
|
|
719
|
-
.declarationsOf(symbol)
|
|
720
|
-
.some((declaration) => ts.isMethodDeclaration(declaration) &&
|
|
721
|
-
lowerer.checkedVirtualJsMethods.has(declaration)))
|
|
799
|
+
symbol.declarations.some((declaration) => ts.isMethodDeclaration(declaration) && lowerer.checkedVirtualJsMethods.has(declaration)))
|
|
722
800
|
return true;
|
|
723
801
|
}
|
|
724
802
|
const name = ts.isPropertyAccessExpression(expression)
|
|
@@ -729,9 +807,7 @@ function returnsWidenedJsField(lowerer, decl, member, fields, ret) {
|
|
|
729
807
|
if (ts.isPropertyAccessExpression(expression)) {
|
|
730
808
|
const symbol = lowerer.checker.getSymbolAtLocation(expression.name);
|
|
731
809
|
if (symbol &&
|
|
732
|
-
|
|
733
|
-
.declarationsOf(symbol)
|
|
734
|
-
.some((declaration) => (ts.isGetAccessorDeclaration(declaration) ||
|
|
810
|
+
symbol.declarations.some((declaration) => (ts.isGetAccessorDeclaration(declaration) ||
|
|
735
811
|
ts.isSetAccessorDeclaration(declaration)) &&
|
|
736
812
|
lowerer.checkedVirtualJsAccessors.has(declaration)))
|
|
737
813
|
return true;
|
|
@@ -750,7 +826,7 @@ function returnsWidenedJsField(lowerer, decl, member, fields, ret) {
|
|
|
750
826
|
return;
|
|
751
827
|
if (ts.isReturnStatement(node) && node.expression && widened(node.expression))
|
|
752
828
|
result = true;
|
|
753
|
-
|
|
829
|
+
ts.forEachChild(node, scan);
|
|
754
830
|
};
|
|
755
831
|
if (member.body)
|
|
756
832
|
scan(member.body);
|
|
@@ -763,13 +839,13 @@ function returnsWidenedJsField(lowerer, decl, member, fields, ret) {
|
|
|
763
839
|
* (genResultRecord's list, including scalar-backed Date values). */
|
|
764
840
|
function undefArmedFieldType(lowerer, p) {
|
|
765
841
|
const t = lowerer.checker.getTypeOfSymbol(p);
|
|
766
|
-
const site =
|
|
842
|
+
const site = p.declarations[0];
|
|
767
843
|
let mapped = lowerer.mapTypeOf(t) ?? (site ? dynFallbackType(lowerer, site, t) : null);
|
|
768
844
|
if (mapped && site)
|
|
769
845
|
mapped = jsOpenObjectType(site, mapped, lowerer.shapes, lowerer.unions);
|
|
770
846
|
if (!mapped || mapped.kind === "void")
|
|
771
847
|
return null;
|
|
772
|
-
for (const declaration of
|
|
848
|
+
for (const declaration of p.declarations) {
|
|
773
849
|
const assignment = ts.isBinaryExpression(declaration) ? declaration : declaration.parent;
|
|
774
850
|
if (assignment &&
|
|
775
851
|
ts.isBinaryExpression(assignment) &&
|
|
@@ -796,10 +872,15 @@ function undefArmedFieldType(lowerer, p) {
|
|
|
796
872
|
* `extends EventEmitter`, `x instanceof EventEmitter`) — any import
|
|
797
873
|
* spelling (named/default/namespace member, CJS require) resolves to
|
|
798
874
|
* the ambient class. Provenance-checked like the error classes: only a
|
|
799
|
-
* 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). */
|
|
800
878
|
export function builtinEmitterInfoOf(lowerer, symbol) {
|
|
801
879
|
if (!symbol)
|
|
802
880
|
return null;
|
|
881
|
+
const alias = builtinClassAliasOf(lowerer, symbol);
|
|
882
|
+
if (alias !== null)
|
|
883
|
+
return alias.kind === "emitter" ? alias.info : null;
|
|
803
884
|
if (!lowerer.isStdlibSymbol(symbol)) {
|
|
804
885
|
// A const ALIAS of the emitter class member (`const EventEmitter =
|
|
805
886
|
// require('node:events').EventEmitter` — commander's spelling; the
|
|
@@ -807,7 +888,7 @@ export function builtinEmitterInfoOf(lowerer, symbol) {
|
|
|
807
888
|
// follow the member off the module namespace. The declaration
|
|
808
889
|
// itself is alias plumbing (builtinMemberRequireDecl — both
|
|
809
890
|
// declaration walks skip it).
|
|
810
|
-
const decl =
|
|
891
|
+
const decl = symbol.valueDeclaration;
|
|
811
892
|
if (decl !== undefined &&
|
|
812
893
|
ts.isVariableDeclaration(decl) &&
|
|
813
894
|
(ts.getCombinedNodeFlags(decl) & ts.NodeFlags.Const) !== 0 &&
|
|
@@ -820,9 +901,9 @@ export function builtinEmitterInfoOf(lowerer, symbol) {
|
|
|
820
901
|
}
|
|
821
902
|
return null;
|
|
822
903
|
}
|
|
823
|
-
if (symbol
|
|
904
|
+
if (ts.symbolName(symbol) !== "EventEmitter")
|
|
824
905
|
return null;
|
|
825
|
-
const declared =
|
|
906
|
+
const declared = symbol.declarations.some((d) => {
|
|
826
907
|
if (!ts.isClassDeclaration(d) && !ts.isInterfaceDeclaration(d))
|
|
827
908
|
return false;
|
|
828
909
|
let node = d.parent;
|
|
@@ -839,12 +920,19 @@ export function builtinEmitterInfoOf(lowerer, symbol) {
|
|
|
839
920
|
/** The builtin error ClassInfo a VALUE symbol refers to (`new Error`,
|
|
840
921
|
* `extends TypeError`, `x instanceof RangeError`), or null. Provenance-
|
|
841
922
|
* checked: only the standard library's declarations count — a user's own
|
|
842
|
-
* `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). */
|
|
843
926
|
export function builtinErrorInfoOf(lowerer, symbol) {
|
|
844
|
-
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))
|
|
845
933
|
return null;
|
|
846
934
|
for (const [irName, rec] of RUNTIME_ERROR_CLASSES) {
|
|
847
|
-
if (rec.lib === symbol
|
|
935
|
+
if (rec.lib === ts.symbolName(symbol))
|
|
848
936
|
return lowerer.classes.get(irName) ?? null;
|
|
849
937
|
}
|
|
850
938
|
return null;
|
|
@@ -872,7 +960,7 @@ export const EMITTER_API_MEMBERS = new Set([
|
|
|
872
960
|
/** The decorators of a class-like or member node (they live in
|
|
873
961
|
* `modifiers` since TS 4.8). */
|
|
874
962
|
export function decoratorNodesOf(n) {
|
|
875
|
-
return (n.modifiers ?? []).filter((m) => m.kind === ts.SyntaxKind.Decorator);
|
|
963
|
+
return (n.modifiers?.nodes ?? []).filter((m) => m.kind === ts.SyntaxKind.Decorator);
|
|
876
964
|
}
|
|
877
965
|
/** The AMBIENT name a decorator expression's evaluation throws on, or
|
|
878
966
|
* null. Node erases ambient declarations (`declare let dec: any`,
|
|
@@ -931,14 +1019,14 @@ export function guaranteedDecorationThrow(lowerer, decl) {
|
|
|
931
1019
|
if (v !== "effectFree")
|
|
932
1020
|
return v;
|
|
933
1021
|
}
|
|
934
|
-
const heritage = decl.heritageClauses?.find((c) => c.token === ts.SyntaxKind.ExtendsKeyword)
|
|
935
|
-
?.types[0];
|
|
1022
|
+
const heritage = decl.heritageClauses?.nodes.find((c) => c.token === ts.SyntaxKind.ExtendsKeyword)
|
|
1023
|
+
?.types?.nodes[0];
|
|
936
1024
|
if (heritage) {
|
|
937
1025
|
const h = stripParens(heritage.expression);
|
|
938
1026
|
if (h.kind !== ts.SyntaxKind.NullKeyword && !ts.isIdentifier(h))
|
|
939
1027
|
return null;
|
|
940
1028
|
}
|
|
941
|
-
for (const member of decl.members) {
|
|
1029
|
+
for (const member of decl.members.nodes) {
|
|
942
1030
|
for (const d of decoratorNodesOf(member)) {
|
|
943
1031
|
const v = decoratorVerdict(d);
|
|
944
1032
|
if (v === "opaque")
|
|
@@ -973,17 +1061,17 @@ function collectClassShapeDeferring(lowerer, decl) {
|
|
|
973
1061
|
// A forward type reference can demand this class before collection
|
|
974
1062
|
// reaches its earlier base declaration. Collect that dependency first;
|
|
975
1063
|
// a later same-file base remains subject to the runtime order boundary.
|
|
976
|
-
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;
|
|
977
1065
|
const reference = heritage && ts.isPropertyAccessExpression(heritage) ? heritage.name : heritage;
|
|
978
1066
|
const baseSymbol = reference && ts.isIdentifier(reference) ? lowerer.resolveValueSymbol(reference) : undefined;
|
|
979
1067
|
const baseDeclaration = baseSymbol
|
|
980
|
-
?
|
|
1068
|
+
? baseSymbol.declarations.find(ts.isClassDeclaration)
|
|
981
1069
|
: undefined;
|
|
982
1070
|
if (baseDeclaration &&
|
|
983
1071
|
!lowerer.isStdlibSymbol(baseSymbol ?? undefined) &&
|
|
984
|
-
!
|
|
985
|
-
(
|
|
986
|
-
|
|
1072
|
+
!ts.getSourceFileOfNode(baseDeclaration).isDeclarationFile &&
|
|
1073
|
+
(ts.getSourceFileOfNode(baseDeclaration) !== ts.getSourceFileOfNode(decl) ||
|
|
1074
|
+
ts.tokenStartOfNode(baseDeclaration) < ts.tokenStartOfNode(decl)))
|
|
987
1075
|
lowerer.collectClassShape(baseDeclaration);
|
|
988
1076
|
lowerer.collectClassShapeInner(decl);
|
|
989
1077
|
});
|
|
@@ -998,8 +1086,8 @@ function collectClassShapeDeferring(lowerer, decl) {
|
|
|
998
1086
|
// declaration without a diagnostic would drop observable side effects (the
|
|
999
1087
|
// classStaticBlock13/28 miscompiles).
|
|
1000
1088
|
const hasDeclTimeCode = (n) => ts.isClassStaticBlockDeclaration(n) ||
|
|
1001
|
-
(n.modifiers ?? []).some((m) => m.kind === ts.SyntaxKind.Decorator);
|
|
1002
|
-
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))) {
|
|
1003
1091
|
lowerer.reportDeferred(symbol);
|
|
1004
1092
|
}
|
|
1005
1093
|
// A poisoned BASE this class EXTENDS must report EAGERLY for the same
|
|
@@ -1013,9 +1101,9 @@ function collectClassShapeDeferring(lowerer, decl) {
|
|
|
1013
1101
|
// reports. Resolution runs under the collect pass's guard (this is
|
|
1014
1102
|
// collectProgram), so the lookup neither flushes nor fences.
|
|
1015
1103
|
{
|
|
1016
|
-
const baseIdent = decl.heritageClauses
|
|
1017
|
-
|
|
1018
|
-
?.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)
|
|
1019
1107
|
.filter(ts.isIdentifier)[0];
|
|
1020
1108
|
const baseSym = baseIdent ? lowerer.resolveValueSymbol(baseIdent) : null;
|
|
1021
1109
|
if (baseSym)
|
|
@@ -1024,7 +1112,7 @@ function collectClassShapeDeferring(lowerer, decl) {
|
|
|
1024
1112
|
}
|
|
1025
1113
|
function inferredEmptyCollectionFieldType(lowerer, decl, field, initializer) {
|
|
1026
1114
|
if (!ts.isNewExpression(initializer) ||
|
|
1027
|
-
(initializer.arguments?.length ?? 0) !== 0 ||
|
|
1115
|
+
(initializer.arguments?.nodes.length ?? 0) !== 0 ||
|
|
1028
1116
|
!ts.isIdentifier(initializer.expression))
|
|
1029
1117
|
return null;
|
|
1030
1118
|
const collection = initializer.expression.text;
|
|
@@ -1039,7 +1127,12 @@ function inferredEmptyCollectionFieldType(lowerer, decl, field, initializer) {
|
|
|
1039
1127
|
const mappedArgument = (argument) => {
|
|
1040
1128
|
const type = lowerer.checker.getBaseTypeOfLiteralType(lowerer.typeOf(argument));
|
|
1041
1129
|
const mapped = lowerer.mapTypeOf(type);
|
|
1042
|
-
|
|
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))
|
|
1043
1136
|
return null;
|
|
1044
1137
|
return mapped;
|
|
1045
1138
|
};
|
|
@@ -1056,9 +1149,9 @@ function inferredEmptyCollectionFieldType(lowerer, decl, field, initializer) {
|
|
|
1056
1149
|
}
|
|
1057
1150
|
if (collection === "Map" &&
|
|
1058
1151
|
node.expression.name.text === "set" &&
|
|
1059
|
-
node.arguments.length === 2) {
|
|
1060
|
-
const key = mappedArgument(node.arguments[0]);
|
|
1061
|
-
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]);
|
|
1062
1155
|
if (key !== null &&
|
|
1063
1156
|
value !== null &&
|
|
1064
1157
|
isSupportedMapKey(key, key.kind === "union" ? lowerer.unions.get(key.unionId)?.arms : undefined) &&
|
|
@@ -1071,15 +1164,15 @@ function inferredEmptyCollectionFieldType(lowerer, decl, field, initializer) {
|
|
|
1071
1164
|
(node.expression.name.text === "add" ||
|
|
1072
1165
|
node.expression.name.text === "has" ||
|
|
1073
1166
|
node.expression.name.text === "delete") &&
|
|
1074
|
-
node.arguments.length === 1) {
|
|
1075
|
-
const element = mappedArgument(node.arguments[0]);
|
|
1167
|
+
node.arguments.nodes.length === 1) {
|
|
1168
|
+
const element = mappedArgument(node.arguments.nodes[0]);
|
|
1076
1169
|
if (element !== null &&
|
|
1077
1170
|
isSupportedSetElem(element, element.kind === "union" ? lowerer.unions.get(element.unionId)?.arms : undefined))
|
|
1078
1171
|
setElements.push(element);
|
|
1079
1172
|
}
|
|
1080
1173
|
return undefined;
|
|
1081
1174
|
};
|
|
1082
|
-
for (const member of decl.members) {
|
|
1175
|
+
for (const member of decl.members.nodes) {
|
|
1083
1176
|
const body = ts.isConstructorDeclaration(member) || ts.isMethodDeclaration(member) || ts.isAccessor(member)
|
|
1084
1177
|
? member.body
|
|
1085
1178
|
: undefined;
|
|
@@ -1131,13 +1224,13 @@ mixin) {
|
|
|
1131
1224
|
const classDecoratorNodes = [];
|
|
1132
1225
|
{
|
|
1133
1226
|
classDecoratorNodes.push(...decoratorNodesOf(decl));
|
|
1134
|
-
const decoratedMembers = decl.members.filter((m) => decoratorNodesOf(m).length > 0);
|
|
1227
|
+
const decoratedMembers = decl.members.nodes.filter((m) => decoratorNodesOf(m).length > 0);
|
|
1135
1228
|
if (classDecoratorNodes.length > 0 || decoratedMembers.length > 0) {
|
|
1136
1229
|
// Node itself cannot execute decorator syntax in a JavaScript
|
|
1137
1230
|
// source (V8 has not shipped the proposal; the type-stripping
|
|
1138
1231
|
// loaders leave `@dec` in place) — there is no runtime behavior
|
|
1139
1232
|
// to be exact against.
|
|
1140
|
-
if (isJsSourceFile(
|
|
1233
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(decl))) {
|
|
1141
1234
|
lowerer.unsupported("SC1090", (classDecoratorNodes[0] ?? decoratorNodesOf(decoratedMembers[0])[0]), "decorators in JavaScript sources (V8 has not shipped decorators — Node cannot execute this file)");
|
|
1142
1235
|
}
|
|
1143
1236
|
// The guaranteed-throw SHELL: declarations only (expressions
|
|
@@ -1192,7 +1285,7 @@ mixin) {
|
|
|
1192
1285
|
: ts.isGetAccessorDeclaration(member) || ts.isSetAccessorDeclaration(member)
|
|
1193
1286
|
? "accessor decorators"
|
|
1194
1287
|
: ts.isPropertyDeclaration(member)
|
|
1195
|
-
? member.modifiers?.some((m) => m.kind === ts.SyntaxKind.AccessorKeyword)
|
|
1288
|
+
? member.modifiers?.nodes.some((m) => m.kind === ts.SyntaxKind.AccessorKeyword)
|
|
1196
1289
|
? "auto-accessor decorators"
|
|
1197
1290
|
: "field decorators"
|
|
1198
1291
|
: "member decorators";
|
|
@@ -1254,9 +1347,9 @@ mixin) {
|
|
|
1254
1347
|
return true;
|
|
1255
1348
|
}
|
|
1256
1349
|
const signatures = lowerer.checker.getCallSignatures(lowerer.typeOf(expression));
|
|
1257
|
-
const source = signatures.length === 1 ?
|
|
1350
|
+
const source = signatures.length === 1 ? signatures[0].declaration : undefined;
|
|
1258
1351
|
if (!source ||
|
|
1259
|
-
!isJsSourceFile(
|
|
1352
|
+
!isJsSourceFile(ts.getSourceFileOfNode(source)) ||
|
|
1260
1353
|
!(ts.isFunctionDeclaration(source) || ts.isFunctionExpression(source)))
|
|
1261
1354
|
return false;
|
|
1262
1355
|
callableBase = {
|
|
@@ -1273,14 +1366,14 @@ mixin) {
|
|
|
1273
1366
|
if (!base || base.generic)
|
|
1274
1367
|
lowerer.unsupported("SC1090", ownGenericBase, "a generic base whose type arguments have no concrete layout");
|
|
1275
1368
|
}
|
|
1276
|
-
for (const clause of inst || mixin || computedBase ? [] : (decl.heritageClauses ?? [])) {
|
|
1369
|
+
for (const clause of inst || mixin || computedBase ? [] : (decl.heritageClauses?.nodes ?? [])) {
|
|
1277
1370
|
// `implements` is pure type-world: tsc checked the conformance and
|
|
1278
1371
|
// the clause erases — nothing about the runtime class changes.
|
|
1279
1372
|
// (Assigning an instance INTO an interface-typed slot is a separate
|
|
1280
1373
|
// question, owned by the shape-coercion fences at those sites.)
|
|
1281
1374
|
if (clause.token === ts.SyntaxKind.ImplementsKeyword)
|
|
1282
1375
|
continue;
|
|
1283
|
-
const t = clause.types[0];
|
|
1376
|
+
const t = clause.types.nodes[0];
|
|
1284
1377
|
if (familyMode && t) {
|
|
1285
1378
|
const reference = ts.isPropertyAccessExpression(t.expression)
|
|
1286
1379
|
? t.expression.name
|
|
@@ -1311,7 +1404,7 @@ mixin) {
|
|
|
1311
1404
|
if (globalError &&
|
|
1312
1405
|
globalError.def.name !== "%DOMException" &&
|
|
1313
1406
|
globalError.def.name !== "%AggregateError") {
|
|
1314
|
-
if (t.typeArguments)
|
|
1407
|
+
if (t.typeArguments?.nodes)
|
|
1315
1408
|
lowerer.unsupported("SC1090", t, "extending generic classes");
|
|
1316
1409
|
base = globalError;
|
|
1317
1410
|
continue;
|
|
@@ -1319,7 +1412,7 @@ mixin) {
|
|
|
1319
1412
|
const emitterBase = lowerer.builtinEmitterInfoOf(resolved);
|
|
1320
1413
|
const streamBaseNs = builtinStreamInfoOf(lowerer, resolved);
|
|
1321
1414
|
if (emitterBase || streamBaseNs) {
|
|
1322
|
-
if (t.typeArguments)
|
|
1415
|
+
if (t.typeArguments?.nodes)
|
|
1323
1416
|
lowerer.unsupported("SC1090", t, "extending generic classes");
|
|
1324
1417
|
base = (emitterBase ?? streamBaseNs);
|
|
1325
1418
|
continue;
|
|
@@ -1340,7 +1433,7 @@ mixin) {
|
|
|
1340
1433
|
continue;
|
|
1341
1434
|
lowerer.unsupported("SC1090", t, `extending the namespace member '${t.expression.name.text}' (no class lowering)`);
|
|
1342
1435
|
}
|
|
1343
|
-
if (t.typeArguments)
|
|
1436
|
+
if (t.typeArguments?.nodes)
|
|
1344
1437
|
lowerer.unsupported("SC1090", t, "extending generic classes");
|
|
1345
1438
|
base = nsBase;
|
|
1346
1439
|
continue;
|
|
@@ -1359,13 +1452,13 @@ mixin) {
|
|
|
1359
1452
|
if (!t.expression.questionDotToken) {
|
|
1360
1453
|
const propBase = propertyAssignedClassInfoOf(lowerer, memberSym);
|
|
1361
1454
|
if (propBase) {
|
|
1362
|
-
if (t.typeArguments)
|
|
1455
|
+
if (t.typeArguments?.nodes)
|
|
1363
1456
|
lowerer.unsupported("SC1090", t, "extending generic classes");
|
|
1364
1457
|
const baseDecl = propBase.decl;
|
|
1365
1458
|
if (baseDecl != null &&
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
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)`);
|
|
1369
1462
|
}
|
|
1370
1463
|
base = propBase;
|
|
1371
1464
|
continue;
|
|
@@ -1374,11 +1467,9 @@ mixin) {
|
|
|
1374
1467
|
// fence (the generic computed-expression one below would hide
|
|
1375
1468
|
// what actually blocks it).
|
|
1376
1469
|
const rebinds = memberSym !== undefined &&
|
|
1377
|
-
|
|
1378
|
-
.declarationsOf(memberSym)
|
|
1379
|
-
.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;
|
|
1380
1471
|
if (rebinds) {
|
|
1381
|
-
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)`);
|
|
1382
1473
|
}
|
|
1383
1474
|
}
|
|
1384
1475
|
}
|
|
@@ -1387,7 +1478,7 @@ mixin) {
|
|
|
1387
1478
|
// so its statics queue ahead of the derived class's — the
|
|
1388
1479
|
// recursion order delivers exactly that).
|
|
1389
1480
|
if (t && ts.isClassExpression(t.expression)) {
|
|
1390
|
-
if (t.typeArguments)
|
|
1481
|
+
if (t.typeArguments?.nodes)
|
|
1391
1482
|
lowerer.unsupported("SC1090", t, "extending generic classes");
|
|
1392
1483
|
const baseExpr = lowerer.lowerClassExpressionInfo(t.expression);
|
|
1393
1484
|
base = baseExpr;
|
|
@@ -1399,7 +1490,7 @@ mixin) {
|
|
|
1399
1490
|
// through the monomorphized chain (lower-mixins.ts). A call whose
|
|
1400
1491
|
// callee is NOT a mixin function keeps the computed-expression
|
|
1401
1492
|
// fence below.
|
|
1402
|
-
if (t && ts.isCallExpression(t.expression) && !t.typeArguments) {
|
|
1493
|
+
if (t && ts.isCallExpression(t.expression) && !t.typeArguments?.nodes) {
|
|
1403
1494
|
const mixinBase = lowerer.mixinCallClassInfoOf(t.expression);
|
|
1404
1495
|
if (mixinBase) {
|
|
1405
1496
|
base = mixinBase;
|
|
@@ -1447,6 +1538,9 @@ mixin) {
|
|
|
1447
1538
|
if (lowerer.builtinErrorInfoOf(symbol)?.def.name === "%AssertionError") {
|
|
1448
1539
|
lowerer.unsupported("SC1090", t, "extending AssertionError (its constructor takes an options object the subclass constructor would have to forward — extend Error, or construct AssertionError directly)");
|
|
1449
1540
|
}
|
|
1541
|
+
if (lowerer.builtinErrorInfoOf(symbol)?.def.name === "%SuppressedError") {
|
|
1542
|
+
lowerer.unsupported("SC1090", t, "extending SuppressedError (extend Error and keep error and suppressed in fields)");
|
|
1543
|
+
}
|
|
1450
1544
|
const named = (symbol && lowerer.classBySymbol.get(symbol)) ??
|
|
1451
1545
|
lowerer.builtinErrorInfoOf(symbol) ??
|
|
1452
1546
|
lowerer.builtinEmitterInfoOf(symbol) ??
|
|
@@ -1484,7 +1578,7 @@ mixin) {
|
|
|
1484
1578
|
base = instBase;
|
|
1485
1579
|
continue;
|
|
1486
1580
|
}
|
|
1487
|
-
if (t.typeArguments)
|
|
1581
|
+
if (t.typeArguments?.nodes)
|
|
1488
1582
|
lowerer.unsupported("SC1090", t, "extending generic classes");
|
|
1489
1583
|
base = named;
|
|
1490
1584
|
if (!base) {
|
|
@@ -1494,7 +1588,7 @@ mixin) {
|
|
|
1494
1588
|
}
|
|
1495
1589
|
}
|
|
1496
1590
|
if (base?.localClass && !functionLocalClass(decl) && !computedBase && !factoryBaseExpression) {
|
|
1497
|
-
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];
|
|
1498
1592
|
if (heritage)
|
|
1499
1593
|
factoryBaseExpression = heritage.expression;
|
|
1500
1594
|
else
|
|
@@ -1502,9 +1596,7 @@ mixin) {
|
|
|
1502
1596
|
}
|
|
1503
1597
|
if (lowerer.collectingExprClasses.has(decl)) {
|
|
1504
1598
|
for (let parent = base; parent; parent = parent.base) {
|
|
1505
|
-
if (parent.
|
|
1506
|
-
parent.builtinStream !== undefined ||
|
|
1507
|
-
parent.builtinEventTarget !== undefined) {
|
|
1599
|
+
if (parent.builtinEventTarget !== undefined) {
|
|
1508
1600
|
lowerer.unsupported("SC1090", decl, "classes extending builtin bases as values (the inherited runtime constructor has no class-value adapter)");
|
|
1509
1601
|
}
|
|
1510
1602
|
}
|
|
@@ -1527,6 +1619,7 @@ mixin) {
|
|
|
1527
1619
|
const fieldOrder = [];
|
|
1528
1620
|
const methods = new Map();
|
|
1529
1621
|
const methodEntryFences = new Map();
|
|
1622
|
+
const returnAdapters = new Map();
|
|
1530
1623
|
// Own accessor declarations ("get:x"/"set:x" → node), for the
|
|
1531
1624
|
// partial-override analysis below (diagnostics need the node).
|
|
1532
1625
|
const accessorNodes = new Map();
|
|
@@ -1555,12 +1648,12 @@ mixin) {
|
|
|
1555
1648
|
const runtimePrototypeMembers = [];
|
|
1556
1649
|
// Public JS accessors need live constructor descriptors, including
|
|
1557
1650
|
// receiver-sensitive getters and setters inherited by subclasses.
|
|
1558
|
-
const checkedStatics = isJsSourceFile(
|
|
1651
|
+
const checkedStatics = isJsSourceFile(ts.getSourceFileOfNode(decl)) &&
|
|
1559
1652
|
((base && hasRuntimeStatics(base)) ||
|
|
1560
|
-
decl.members.some((member) => ts.isAccessor(member) &&
|
|
1653
|
+
decl.members.nodes.some((member) => ts.isAccessor(member) &&
|
|
1561
1654
|
!ts.isPrivateIdentifier(member.name) &&
|
|
1562
|
-
member.modifiers?.some((modifier) => modifier.kind === ts.SyntaxKind.StaticKeyword))) &&
|
|
1563
|
-
!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 &&
|
|
1564
1657
|
ts.isPrivateIdentifier(member.name) &&
|
|
1565
1658
|
ts
|
|
1566
1659
|
.getModifiers(member)
|
|
@@ -1593,13 +1686,13 @@ mixin) {
|
|
|
1593
1686
|
lowerer.unsupported("SC1071", member);
|
|
1594
1687
|
const mName = member.name.text;
|
|
1595
1688
|
const typeParams = [];
|
|
1596
|
-
for (const tp of fnNode.typeParameters) {
|
|
1689
|
+
for (const tp of fnNode.typeParameters.nodes) {
|
|
1597
1690
|
const sym = lowerer.checker.getSymbolAtLocation(tp.name);
|
|
1598
1691
|
if (!sym)
|
|
1599
1692
|
lowerer.unsupported("SC1090", member, "this method form");
|
|
1600
1693
|
typeParams.push(sym);
|
|
1601
1694
|
}
|
|
1602
|
-
for (const param of fnNode.parameters) {
|
|
1695
|
+
for (const param of fnNode.parameters.nodes) {
|
|
1603
1696
|
if (!ts.isIdentifier(param.name) &&
|
|
1604
1697
|
!ts.isObjectBindingPattern(param.name) &&
|
|
1605
1698
|
!ts.isArrayBindingPattern(param.name)) {
|
|
@@ -1614,9 +1707,9 @@ mixin) {
|
|
|
1614
1707
|
instances: new Map(),
|
|
1615
1708
|
});
|
|
1616
1709
|
};
|
|
1617
|
-
for (const member of decl.members) {
|
|
1710
|
+
for (const member of decl.members.nodes) {
|
|
1618
1711
|
if ((functionLocalClass(decl) || checkedStatics) &&
|
|
1619
|
-
isJsSourceFile(
|
|
1712
|
+
isJsSourceFile(ts.getSourceFileOfNode(decl)) &&
|
|
1620
1713
|
(ts.isClassStaticBlockDeclaration(member) ||
|
|
1621
1714
|
ts
|
|
1622
1715
|
.getModifiers(member)
|
|
@@ -1625,7 +1718,7 @@ mixin) {
|
|
|
1625
1718
|
continue;
|
|
1626
1719
|
}
|
|
1627
1720
|
if (functionLocalClass(decl) &&
|
|
1628
|
-
isJsSourceFile(
|
|
1721
|
+
isJsSourceFile(ts.getSourceFileOfNode(decl)) &&
|
|
1629
1722
|
(ts.isMethodDeclaration(member) || ts.isAccessor(member)) &&
|
|
1630
1723
|
member.body &&
|
|
1631
1724
|
!ts.isPrivateIdentifier(member.name)) {
|
|
@@ -1690,11 +1783,11 @@ mixin) {
|
|
|
1690
1783
|
if (type.kind === "void")
|
|
1691
1784
|
lowerer.badType(member.name, lowerer.typeOf(member.name));
|
|
1692
1785
|
if (type.kind === "dyn" &&
|
|
1693
|
-
!isJsSourceFile(
|
|
1786
|
+
!isJsSourceFile(ts.getSourceFileOfNode(member)) &&
|
|
1694
1787
|
!lowerer.classFieldStoresDyn(lowerer.typeOf(member.name)) &&
|
|
1695
1788
|
(member.type !== undefined ||
|
|
1696
1789
|
(lowerer.typeOf(member.name).flags & ts.TypeFlags.Any) === 0)) {
|
|
1697
|
-
lowerer.unsupported("SC1090", member.name,
|
|
1790
|
+
lowerer.unsupported("SC1090", member.name, `${dynFieldTypeSpelling(lowerer, member.name)}-typed static fields`);
|
|
1698
1791
|
}
|
|
1699
1792
|
staticFields.push({
|
|
1700
1793
|
name: member.name.text,
|
|
@@ -1716,7 +1809,7 @@ mixin) {
|
|
|
1716
1809
|
lowerer.badType(member.name, lowerer.typeOf(member.name));
|
|
1717
1810
|
}
|
|
1718
1811
|
staticMethods.set(member.name.text, { params: shapes, ret: ft.ret, member });
|
|
1719
|
-
if (implicitMonoFile(
|
|
1812
|
+
if (implicitMonoFile(ts.getSourceFileOfNode(decl)) &&
|
|
1720
1813
|
!functionLocalClass(decl) &&
|
|
1721
1814
|
inst === undefined &&
|
|
1722
1815
|
decl.typeParameters === undefined) {
|
|
@@ -1761,9 +1854,21 @@ mixin) {
|
|
|
1761
1854
|
const memberName = member.name;
|
|
1762
1855
|
if (errorRooted && memberName && classMemberNameOf(lowerer, memberName) === "cause") {
|
|
1763
1856
|
if (ts.isPropertyDeclaration(member) &&
|
|
1764
|
-
!member.modifiers?.some((m) => m.kind === ts.SyntaxKind.StaticKeyword)) {
|
|
1765
|
-
|
|
1766
|
-
|
|
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
|
+
}
|
|
1767
1872
|
fieldOrder.push({
|
|
1768
1873
|
name: "cause",
|
|
1769
1874
|
type: DYN,
|
|
@@ -1829,11 +1934,11 @@ mixin) {
|
|
|
1829
1934
|
!inst &&
|
|
1830
1935
|
!mixin &&
|
|
1831
1936
|
ts.isMethodDeclaration(member) &&
|
|
1832
|
-
!member.modifiers?.some((m) => m.kind === ts.SyntaxKind.StaticKeyword)) {
|
|
1937
|
+
!member.modifiers?.nodes.some((m) => m.kind === ts.SyntaxKind.StaticKeyword)) {
|
|
1833
1938
|
const reason = emitOverrideShapeReason(lowerer, member);
|
|
1834
1939
|
if (reason === null) {
|
|
1835
|
-
const eventSym = lowerer.checker.getSymbolAtLocation(member.parameters[0].name);
|
|
1836
|
-
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);
|
|
1837
1942
|
if (eventSym && restSym) {
|
|
1838
1943
|
emitOverride = { decl: member, eventSym, restSym };
|
|
1839
1944
|
continue;
|
|
@@ -1881,6 +1986,21 @@ mixin) {
|
|
|
1881
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("/")})`);
|
|
1882
1987
|
}
|
|
1883
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);
|
|
1884
2004
|
}
|
|
1885
2005
|
}
|
|
1886
2006
|
if (ts.isPropertyDeclaration(member)) {
|
|
@@ -1913,18 +2033,27 @@ mixin) {
|
|
|
1913
2033
|
? String(Number(member.name.text))
|
|
1914
2034
|
: member.name.text;
|
|
1915
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;
|
|
1916
2041
|
if (fieldName === null ||
|
|
1917
|
-
(!member.initializer &&
|
|
2042
|
+
(!member.initializer &&
|
|
2043
|
+
!isJsSourceFile(ts.getSourceFileOfNode(member)) &&
|
|
2044
|
+
!declaredOnly)) {
|
|
1918
2045
|
lowerer.unsupported("SC1090", member, "computed class fields without an initializer and a stable string, number, or module-level literal Symbol()/Symbol.for() key");
|
|
1919
2046
|
}
|
|
1920
2047
|
const declared = lowerer.typeOf(member);
|
|
1921
2048
|
const inferred = member.type || !member.initializer
|
|
1922
2049
|
? declared
|
|
1923
2050
|
: lowerer.checker.getBaseTypeOfLiteralType(lowerer.typeOf(member.initializer));
|
|
1924
|
-
const mapped = member.initializer
|
|
2051
|
+
const mapped = member.initializer || declaredOnly
|
|
1925
2052
|
? (lowerer.mapTypeOf(inferred) ?? dynFallbackType(lowerer, member, inferred))
|
|
1926
2053
|
: DYN;
|
|
1927
|
-
let type = mapped?.kind === "record" &&
|
|
2054
|
+
let type = mapped?.kind === "record" &&
|
|
2055
|
+
isJsSourceFile(ts.getSourceFileOfNode(member)) &&
|
|
2056
|
+
!member.type
|
|
1928
2057
|
? DYN
|
|
1929
2058
|
: mapped
|
|
1930
2059
|
? jsOpenObjectType(member, mapped, lowerer.shapes, lowerer.unions)
|
|
@@ -1932,17 +2061,29 @@ mixin) {
|
|
|
1932
2061
|
if (!type ||
|
|
1933
2062
|
type.kind === "void" ||
|
|
1934
2063
|
(type.kind === "dyn" &&
|
|
1935
|
-
!isJsSourceFile(
|
|
1936
|
-
!lowerer.
|
|
2064
|
+
!isJsSourceFile(ts.getSourceFileOfNode(member)) &&
|
|
2065
|
+
!lowerer.classFieldStoresDyn(inferred)))
|
|
1937
2066
|
lowerer.badType(member, inferred);
|
|
1938
|
-
if (isJsSourceFile(
|
|
2067
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(member))) {
|
|
1939
2068
|
type = inheritedJsFieldType(lowerer, decl, fieldName, type);
|
|
1940
2069
|
if (base?.fields.get(fieldName)?.kind === "dyn")
|
|
1941
2070
|
type = DYN;
|
|
1942
2071
|
if (base && !fields.has(fieldName) && lowerer.dynConvertible(type))
|
|
1943
2072
|
type = DYN;
|
|
1944
2073
|
}
|
|
1945
|
-
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
|
+
}
|
|
1946
2087
|
const previous = fields.get(fieldName);
|
|
1947
2088
|
if (previous) {
|
|
1948
2089
|
if (symbolKey && !symbolFields.has(symbolKey.identity)) {
|
|
@@ -2018,9 +2159,9 @@ mixin) {
|
|
|
2018
2159
|
// as undefined on construction, verified), and reads/writes ride
|
|
2019
2160
|
// the ordinary undefined-armed union machinery.
|
|
2020
2161
|
let type = lowerer.irTypeOf(member.name);
|
|
2021
|
-
if (isJsSourceFile(
|
|
2022
|
-
const constructor = decl.members.find((part) => ts.isConstructorDeclaration(part) && !!part.body);
|
|
2023
|
-
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 ?? []) {
|
|
2024
2165
|
if (!ts.isExpressionStatement(statement) ||
|
|
2025
2166
|
!ts.isBinaryExpression(statement.expression) ||
|
|
2026
2167
|
statement.expression.operatorToken.kind !== ts.SyntaxKind.EqualsToken)
|
|
@@ -2038,18 +2179,20 @@ mixin) {
|
|
|
2038
2179
|
}
|
|
2039
2180
|
// Unannotated JavaScript callback slots retain the original
|
|
2040
2181
|
// callable and its receiver instead of adapting its signature.
|
|
2041
|
-
if (isJsSourceFile(
|
|
2182
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(member)) &&
|
|
2042
2183
|
!member.type &&
|
|
2043
|
-
!/@type\b/.test(
|
|
2184
|
+
!/@type\b/.test(ts.getSourceFileOfNode(member).text.slice(member.pos, ts.tokenStartOfNode(member))) &&
|
|
2044
2185
|
(type.kind === "func" || type.kind === "record") &&
|
|
2045
2186
|
lowerer.dynConvertible(type))
|
|
2046
2187
|
type = DYN;
|
|
2047
2188
|
// JS permits reads before a constructor's first assignment even
|
|
2048
2189
|
// when its inferred field type omits undefined.
|
|
2049
|
-
if (isJsSourceFile(
|
|
2190
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(member)) &&
|
|
2191
|
+
!member.initializer &&
|
|
2192
|
+
type.kind !== "dyn") {
|
|
2050
2193
|
type = lowerer.withUndefinedArmOf(type) ?? DYN;
|
|
2051
2194
|
}
|
|
2052
|
-
if (isJsSourceFile(
|
|
2195
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(member))) {
|
|
2053
2196
|
type = inheritedJsFieldType(lowerer, decl, member.name.text, type);
|
|
2054
2197
|
if (base?.fields.get(member.name.text)?.kind === "dyn")
|
|
2055
2198
|
type = DYN;
|
|
@@ -2062,9 +2205,9 @@ mixin) {
|
|
|
2062
2205
|
// them in the constructor. Use the same native checked-dynamic
|
|
2063
2206
|
// storage as implicit constructor-assigned JS fields.
|
|
2064
2207
|
if (type.kind === "dyn" &&
|
|
2065
|
-
!isJsSourceFile(
|
|
2208
|
+
!isJsSourceFile(ts.getSourceFileOfNode(member)) &&
|
|
2066
2209
|
!lowerer.classFieldStoresDyn(lowerer.typeOf(member.name))) {
|
|
2067
|
-
lowerer.unsupported("SC1090", member.name,
|
|
2210
|
+
lowerer.unsupported("SC1090", member.name, `${dynFieldTypeSpelling(lowerer, member.name)}-typed class fields`);
|
|
2068
2211
|
}
|
|
2069
2212
|
const undefinedInitializer = type.kind === "dyn" && !member.initializer ? locOf(member) : undefined;
|
|
2070
2213
|
if (fields.has(member.name.text)) {
|
|
@@ -2163,8 +2306,8 @@ mixin) {
|
|
|
2163
2306
|
// FIRST (before every declared field, as undefined), and the
|
|
2164
2307
|
// assignments run after super() and the field initializers, in
|
|
2165
2308
|
// parameter order (see paramPropInitStmts).
|
|
2166
|
-
for (const p of member.parameters) {
|
|
2167
|
-
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 ||
|
|
2168
2311
|
m.kind === ts.SyntaxKind.PrivateKeyword ||
|
|
2169
2312
|
m.kind === ts.SyntaxKind.ProtectedKeyword ||
|
|
2170
2313
|
m.kind === ts.SyntaxKind.ReadonlyKeyword ||
|
|
@@ -2172,7 +2315,7 @@ mixin) {
|
|
|
2172
2315
|
if (!isParamProp) {
|
|
2173
2316
|
// Non-keyword modifiers (parameter decorators) are rejected
|
|
2174
2317
|
// by tsc under standard decorators; defensive.
|
|
2175
|
-
if (p.modifiers?.length)
|
|
2318
|
+
if (p.modifiers?.nodes.length)
|
|
2176
2319
|
lowerer.unsupported("SC1090", p, "this parameter form");
|
|
2177
2320
|
continue;
|
|
2178
2321
|
}
|
|
@@ -2183,7 +2326,7 @@ mixin) {
|
|
|
2183
2326
|
}
|
|
2184
2327
|
const name = p.name.text;
|
|
2185
2328
|
if (errorRooted && name === "cause") {
|
|
2186
|
-
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)");
|
|
2187
2330
|
}
|
|
2188
2331
|
const shape = lowerer.paramShape(p);
|
|
2189
2332
|
const type = shape.bodyType ?? shape.type;
|
|
@@ -2191,7 +2334,7 @@ mixin) {
|
|
|
2191
2334
|
lowerer.badType(p.name, lowerer.typeOf(p.name));
|
|
2192
2335
|
// The class-field dyn rule verbatim (KEEP NARROW).
|
|
2193
2336
|
if (type.kind === "dyn" && !lowerer.classFieldStoresDyn(lowerer.typeOf(p))) {
|
|
2194
|
-
lowerer.unsupported("SC1090", p.name,
|
|
2337
|
+
lowerer.unsupported("SC1090", p.name, `${dynFieldTypeSpelling(lowerer, p)}-typed class fields`);
|
|
2195
2338
|
}
|
|
2196
2339
|
// `override x` (and any same-named inherited member) would
|
|
2197
2340
|
// redeclare a base slot — the declared-field rule verbatim.
|
|
@@ -2249,7 +2392,14 @@ mixin) {
|
|
|
2249
2392
|
!typeEquals(overridden.sig.ret, overrideReturnAbi(lowerer, ret, overridden.sig.ret, className, base)))) {
|
|
2250
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)");
|
|
2251
2394
|
}
|
|
2252
|
-
|
|
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
|
+
});
|
|
2253
2403
|
continue;
|
|
2254
2404
|
}
|
|
2255
2405
|
// A body-less method is an OVERLOAD SIGNATURE (abstract methods
|
|
@@ -2284,7 +2434,7 @@ mixin) {
|
|
|
2284
2434
|
// dispatch worlds could meet: an inherited declaration of the
|
|
2285
2435
|
// name (the override stays on the vtable), a shadowed field, or
|
|
2286
2436
|
// a generic-class instantiation's member.
|
|
2287
|
-
if (implicitMonoFile(
|
|
2437
|
+
if (implicitMonoFile(ts.getSourceFileOfNode(decl)) &&
|
|
2288
2438
|
!functionLocalClass(decl) &&
|
|
2289
2439
|
ts.isIdentifier(member.name) &&
|
|
2290
2440
|
!lowerer.virtualJsMethods.has(member) &&
|
|
@@ -2324,12 +2474,12 @@ mixin) {
|
|
|
2324
2474
|
}
|
|
2325
2475
|
// JS inference may retain only a symbol sentinel while a method
|
|
2326
2476
|
// also returns values from an untyped mutable field or local.
|
|
2327
|
-
if (isJsSourceFile(
|
|
2477
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(member)) &&
|
|
2328
2478
|
!member.type &&
|
|
2329
2479
|
!hasExplicitJsDocReturn(member) &&
|
|
2330
2480
|
ft.ret.kind === "symbol")
|
|
2331
2481
|
ft.ret = DYN;
|
|
2332
|
-
if (isJsSourceFile(
|
|
2482
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(member)) &&
|
|
2333
2483
|
lowerer.prototypeMethodAccesses.has(mName) &&
|
|
2334
2484
|
!lowerer.findMethodOn(base, mName)?.declarer.def.runtime &&
|
|
2335
2485
|
shapes.every((p) => p.mode === "required" || p.mode === "omittable")) {
|
|
@@ -2378,7 +2528,7 @@ mixin) {
|
|
|
2378
2528
|
// against the STATIC receiver's shape, so `m(x?: number)` and
|
|
2379
2529
|
// `m(x: number | undefined)` interchange soundly in overrides.
|
|
2380
2530
|
const overridden = lowerer.findMethodOn(base, mName);
|
|
2381
|
-
if (overridden && isJsSourceFile(
|
|
2531
|
+
if (overridden && isJsSourceFile(ts.getSourceFileOfNode(member))) {
|
|
2382
2532
|
// An unannotated JS override can return a checked value into
|
|
2383
2533
|
// the inherited native ABI, just as its untyped parameters do.
|
|
2384
2534
|
// Body lowering inserts the conversion at each return.
|
|
@@ -2400,7 +2550,7 @@ mixin) {
|
|
|
2400
2550
|
// Defaults stay local to each declaration, so only inherited
|
|
2401
2551
|
// required/optional slots participate in this refinement.
|
|
2402
2552
|
for (let i = 0; i < shapes.length; i++) {
|
|
2403
|
-
const parameter = member.parameters[i];
|
|
2553
|
+
const parameter = member.parameters.nodes[i];
|
|
2404
2554
|
const inherited = overridden.sig.params[i];
|
|
2405
2555
|
if (parameter &&
|
|
2406
2556
|
inherited &&
|
|
@@ -2419,7 +2569,7 @@ mixin) {
|
|
|
2419
2569
|
// calls fill them with undefined. Typed tails and rest/arguments
|
|
2420
2570
|
// readers keep the exact-signature fence.
|
|
2421
2571
|
if (overridden &&
|
|
2422
|
-
isJsSourceFile(
|
|
2572
|
+
isJsSourceFile(ts.getSourceFileOfNode(member)) &&
|
|
2423
2573
|
shapes.length < overridden.sig.params.length &&
|
|
2424
2574
|
!bodyReadsArguments(member) &&
|
|
2425
2575
|
shapes.every((p, i) => (p.mode === "required" || p.mode === "omittable") &&
|
|
@@ -2431,28 +2581,116 @@ mixin) {
|
|
|
2431
2581
|
.slice(shapes.length)
|
|
2432
2582
|
.map((p) => ({ type: p.type, mode: "omittable" })));
|
|
2433
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
|
+
}
|
|
2434
2624
|
if (overridden &&
|
|
2435
2625
|
member.asteriskToken === undefined &&
|
|
2436
2626
|
(overridden.sig.params.length !== shapes.length ||
|
|
2437
2627
|
!overridden.sig.params.every((p, i) => typeEquals(p.type, shapes[i].type)) ||
|
|
2438
2628
|
!typeEquals(overridden.sig.ret, overrideReturnAbi(lowerer, ft.ret, overridden.sig.ret, className, base)))) {
|
|
2439
|
-
const fencedJsOverride = isJsSourceFile(
|
|
2629
|
+
const fencedJsOverride = isJsSourceFile(ts.getSourceFileOfNode(member)) &&
|
|
2440
2630
|
overridden.declarer.decl !== null &&
|
|
2441
|
-
isJsSourceFile(overridden.declarer.decl
|
|
2631
|
+
isJsSourceFile(ts.getSourceFileOfNode(overridden.declarer.decl)) &&
|
|
2442
2632
|
overridden.sig.gen === undefined;
|
|
2443
|
-
|
|
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) {
|
|
2444
2682
|
// A dormant JS method must not poison the whole class. Keep
|
|
2445
2683
|
// the inherited call/dispatch ABI and refuse at method entry;
|
|
2446
2684
|
// lowering this body with the base signature would change JS.
|
|
2447
2685
|
const returnOnly = overridden.sig.params.length === shapes.length &&
|
|
2448
2686
|
overridden.sig.params.every((p, i) => typeEquals(p.type, shapes[i].type)) &&
|
|
2449
|
-
!member.parameters.some((parameter, index) => {
|
|
2687
|
+
!member.parameters.nodes.some((parameter, index) => {
|
|
2450
2688
|
if (!parameter.initializer)
|
|
2451
2689
|
return false;
|
|
2452
|
-
const baseMember = overridden.declarer.decl?.members.find((candidate) => ts.isMethodDeclaration(candidate) &&
|
|
2690
|
+
const baseMember = overridden.declarer.decl?.members?.nodes.find((candidate) => ts.isMethodDeclaration(candidate) &&
|
|
2453
2691
|
classMemberNameOf(lowerer, candidate.name) === mName);
|
|
2454
2692
|
const inherited = baseMember && ts.isMethodDeclaration(baseMember)
|
|
2455
|
-
? baseMember.parameters[index]?.initializer
|
|
2693
|
+
? baseMember.parameters.nodes[index]?.initializer
|
|
2456
2694
|
: undefined;
|
|
2457
2695
|
if (!inherited)
|
|
2458
2696
|
return false;
|
|
@@ -2470,14 +2708,42 @@ mixin) {
|
|
|
2470
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)");
|
|
2471
2709
|
}
|
|
2472
2710
|
}
|
|
2473
|
-
|
|
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;
|
|
2474
2718
|
// Async methods dispatch STATICALLY (the body enters through its
|
|
2475
2719
|
// fiber spawn wrapper; vtable slots hold raw implementations) —
|
|
2476
2720
|
// an override chain touching an async method on either end would
|
|
2477
2721
|
// put a spawn wrapper behind a virtual slot, so it fences.
|
|
2478
|
-
|
|
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)) {
|
|
2479
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)`;
|
|
2480
|
-
if (isJsSourceFile(
|
|
2746
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(member)))
|
|
2481
2747
|
methodEntryFences.set(mName, unsupportedDiag("SC1090", locOf(member.name), message));
|
|
2482
2748
|
else
|
|
2483
2749
|
lowerer.unsupported("SC1090", member.name, message);
|
|
@@ -2485,7 +2751,7 @@ mixin) {
|
|
|
2485
2751
|
if (overridden &&
|
|
2486
2752
|
(member.asteriskToken !== undefined || overridden.sig.gen !== undefined)) {
|
|
2487
2753
|
const message = `overriding the generator method '${mName}' (generator methods dispatch statically — a virtual slot cannot enter their spawn wrapper)`;
|
|
2488
|
-
if (isJsSourceFile(
|
|
2754
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(member)))
|
|
2489
2755
|
methodEntryFences.set(mName, unsupportedDiag("SC1090", locOf(member.name), message));
|
|
2490
2756
|
else
|
|
2491
2757
|
lowerer.unsupported("SC1090", member.name, message);
|
|
@@ -2505,7 +2771,7 @@ mixin) {
|
|
|
2505
2771
|
});
|
|
2506
2772
|
}
|
|
2507
2773
|
else {
|
|
2508
|
-
methods.set(mName, asyncMember
|
|
2774
|
+
methods.set(mName, asyncMember && !returnAdapters.has(mName)
|
|
2509
2775
|
? { params: shapes, ret: ft.ret, async: true }
|
|
2510
2776
|
: { params: shapes, ret: ft.ret });
|
|
2511
2777
|
}
|
|
@@ -2547,7 +2813,7 @@ mixin) {
|
|
|
2547
2813
|
lowerer.unsupported("SC1090", member, "bodyless accessors");
|
|
2548
2814
|
const mName = `${isGet ? "get" : "set"}:${prop}`;
|
|
2549
2815
|
if (fields.has(prop) &&
|
|
2550
|
-
isJsSourceFile(
|
|
2816
|
+
isJsSourceFile(ts.getSourceFileOfNode(decl)) &&
|
|
2551
2817
|
base?.fields.has(prop) &&
|
|
2552
2818
|
!fieldOrder.some((field) => field.name === prop)) {
|
|
2553
2819
|
// JS may override an inherited data field with a prototype
|
|
@@ -2564,14 +2830,22 @@ mixin) {
|
|
|
2564
2830
|
}
|
|
2565
2831
|
let sig;
|
|
2566
2832
|
if (isGet) {
|
|
2567
|
-
|
|
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;
|
|
2568
2842
|
if (ret.kind === "void")
|
|
2569
2843
|
lowerer.badType(member.name, lowerer.typeOf(member.name));
|
|
2570
2844
|
sig = { params: [], ret };
|
|
2571
2845
|
}
|
|
2572
2846
|
else {
|
|
2573
2847
|
// tsc rejects optional/default/rest setter params (TS1051-53).
|
|
2574
|
-
sig = { params: lowerer.paramShapes(member.parameters), ret: VOID };
|
|
2848
|
+
sig = { params: lowerer.paramShapes(member.parameters.nodes), ret: VOID };
|
|
2575
2849
|
}
|
|
2576
2850
|
if (lowerer.checkedVirtualJsAccessors.has(member)) {
|
|
2577
2851
|
if (isGet)
|
|
@@ -2635,7 +2909,7 @@ mixin) {
|
|
|
2635
2909
|
// undefined. Such fields take the deferred-init representation, whose
|
|
2636
2910
|
// slot (a nullable instance pointer) starts empty and whose reads check
|
|
2637
2911
|
// it. Fields assigned before any exposure keep their plain reads.
|
|
2638
|
-
const derived = decl.heritageClauses?.some((clause) => clause.token === ts.SyntaxKind.ExtendsKeyword) ??
|
|
2912
|
+
const derived = decl.heritageClauses?.nodes.some((clause) => clause.token === ts.SyntaxKind.ExtendsKeyword) ??
|
|
2639
2913
|
false;
|
|
2640
2914
|
// Generic instances and mixins share layouts across declarations, so
|
|
2641
2915
|
// they only report whether construction exposes the instance.
|
|
@@ -2660,7 +2934,7 @@ mixin) {
|
|
|
2660
2934
|
if (!ts.isPropertyAccessExpression(callee))
|
|
2661
2935
|
return null;
|
|
2662
2936
|
const name = callee.name.text;
|
|
2663
|
-
const declaration = decl.members.find((member) => ts.isMethodDeclaration(member) &&
|
|
2937
|
+
const declaration = decl.members.nodes.find((member) => ts.isMethodDeclaration(member) &&
|
|
2664
2938
|
member.body !== undefined &&
|
|
2665
2939
|
(ts.isIdentifier(member.name) || ts.isPrivateIdentifier(member.name)) &&
|
|
2666
2940
|
member.name.text === name);
|
|
@@ -2684,7 +2958,7 @@ mixin) {
|
|
|
2684
2958
|
const deferredInitFields = new Set(base?.deferredInitFields ?? []);
|
|
2685
2959
|
if (unguardedFields.length > 0) {
|
|
2686
2960
|
const topAssigned = new Set();
|
|
2687
|
-
for (const stmt of ctor?.body?.statements ?? []) {
|
|
2961
|
+
for (const stmt of ctor?.body?.statements?.nodes ?? []) {
|
|
2688
2962
|
if (ts.isExpressionStatement(stmt) &&
|
|
2689
2963
|
ts.isBinaryExpression(stmt.expression) &&
|
|
2690
2964
|
stmt.expression.operatorToken.kind === ts.SyntaxKind.EqualsToken &&
|
|
@@ -2692,6 +2966,16 @@ mixin) {
|
|
|
2692
2966
|
stmt.expression.left.expression.kind === ts.SyntaxKind.ThisKeyword) {
|
|
2693
2967
|
topAssigned.add(stmt.expression.left.name.text);
|
|
2694
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
|
+
}
|
|
2695
2979
|
}
|
|
2696
2980
|
for (const f of unguardedFields) {
|
|
2697
2981
|
if (topAssigned.has(f.name) || escape.assigned?.has(f.name))
|
|
@@ -2728,13 +3012,26 @@ mixin) {
|
|
|
2728
3012
|
}
|
|
2729
3013
|
}
|
|
2730
3014
|
if (escape.assigned && !inst) {
|
|
3015
|
+
let earlyReads = null;
|
|
2731
3016
|
for (const f of fieldOrder) {
|
|
2732
3017
|
if (f.redeclared || escape.assigned.has(f.name) || deferredInitFields.has(f.name))
|
|
2733
3018
|
continue;
|
|
2734
3019
|
if (paramProps.some((pp) => pp.name === f.name))
|
|
2735
3020
|
continue;
|
|
2736
3021
|
const declared = fields.get(f.name);
|
|
2737
|
-
|
|
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)
|
|
2738
3035
|
continue;
|
|
2739
3036
|
const armed = lowerer.withUndefinedArm(declared);
|
|
2740
3037
|
if (armed === null || armed.kind !== "union")
|
|
@@ -2795,7 +3092,7 @@ mixin) {
|
|
|
2795
3092
|
// assignment ran — the zeroed-memory trap a TS declaration order
|
|
2796
3093
|
// forbids via strictPropertyInitialization — so they keep a named
|
|
2797
3094
|
// fence instead of reading undefined without a diagnostic.
|
|
2798
|
-
if (isJsSourceFile(
|
|
3095
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(decl))) {
|
|
2799
3096
|
const hasAccessor = (name) => methods.has(`get:${name}`) ||
|
|
2800
3097
|
methods.has(`set:${name}`) ||
|
|
2801
3098
|
lowerer.findMethodOn(base, `get:${name}`) !== null ||
|
|
@@ -2818,14 +3115,22 @@ mixin) {
|
|
|
2818
3115
|
// goes through the key.
|
|
2819
3116
|
const lateBoundByKey = new Map();
|
|
2820
3117
|
for (const p of instType ? lowerer.checker.getPropertiesOfType(instType) : []) {
|
|
2821
|
-
if (!p.
|
|
3118
|
+
if (!ts.symbolName(p).startsWith("__@"))
|
|
2822
3119
|
continue;
|
|
2823
3120
|
const keySym = lateBoundKeySymOf(lowerer, p);
|
|
2824
3121
|
if (keySym)
|
|
2825
3122
|
lateBoundByKey.set(keySym, p);
|
|
2826
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;
|
|
2827
3132
|
if (ctor?.body) {
|
|
2828
|
-
for (const stmt of ctor.body.statements) {
|
|
3133
|
+
for (const stmt of ctor.body.statements.nodes) {
|
|
2829
3134
|
const lhs = ts.isExpressionStatement(stmt) &&
|
|
2830
3135
|
ts.isBinaryExpression(stmt.expression) &&
|
|
2831
3136
|
stmt.expression.operatorToken.kind === ts.SyntaxKind.EqualsToken
|
|
@@ -2861,7 +3166,7 @@ mixin) {
|
|
|
2861
3166
|
let type = t ? (lowerer.mapTypeOf(t) ?? dynFallbackType(lowerer, assign, t)) : null;
|
|
2862
3167
|
if (t &&
|
|
2863
3168
|
(t.flags & (ts.TypeFlags.Null | ts.TypeFlags.Undefined)) !== 0 &&
|
|
2864
|
-
isJsSourceFile(
|
|
3169
|
+
isJsSourceFile(ts.getSourceFileOfNode(decl)))
|
|
2865
3170
|
type = DYN;
|
|
2866
3171
|
if (type)
|
|
2867
3172
|
type = jsOpenObjectType(assign, type, lowerer.shapes, lowerer.unions);
|
|
@@ -2893,7 +3198,7 @@ mixin) {
|
|
|
2893
3198
|
type = inheritedJsFieldType(lowerer, decl, name, type);
|
|
2894
3199
|
// super() can invoke a subclass setter or method before its
|
|
2895
3200
|
// constructor assignments run. These slots start undefined.
|
|
2896
|
-
if (base && lowerer.dynConvertible(type))
|
|
3201
|
+
if (base && lowerer.dynConvertible(type) && !sealedPrefix?.created.has(name))
|
|
2897
3202
|
type = DYN;
|
|
2898
3203
|
fields.set(name, type);
|
|
2899
3204
|
fieldOrder.push({ name, type, initializer: undefined });
|
|
@@ -2975,17 +3280,16 @@ mixin) {
|
|
|
2975
3280
|
// static layouts cannot represent. Named fence, at the first
|
|
2976
3281
|
// assignment site.
|
|
2977
3282
|
for (const p of instType ? lowerer.checker.getPropertiesOfType(instType) : []) {
|
|
2978
|
-
if (errorRooted && p
|
|
3283
|
+
if (errorRooted && ts.symbolName(p) === "cause")
|
|
2979
3284
|
continue;
|
|
2980
|
-
if (fields.has(p
|
|
3285
|
+
if (fields.has(ts.symbolName(p)) || methods.has(ts.symbolName(p)))
|
|
2981
3286
|
continue;
|
|
2982
|
-
if (hasAccessor(p
|
|
3287
|
+
if (hasAccessor(ts.symbolName(p)))
|
|
2983
3288
|
continue;
|
|
2984
|
-
if (base &&
|
|
3289
|
+
if (base &&
|
|
3290
|
+
(base.fields.has(ts.symbolName(p)) || lowerer.findMethodOn(base, ts.symbolName(p))))
|
|
2985
3291
|
continue;
|
|
2986
|
-
const site =
|
|
2987
|
-
.declarationsOf(p)
|
|
2988
|
-
.find((d) => ts.isPropertyAccessExpression(d) ||
|
|
3292
|
+
const site = p.declarations.find((d) => ts.isPropertyAccessExpression(d) ||
|
|
2989
3293
|
ts.isBinaryExpression(d) ||
|
|
2990
3294
|
ts.isElementAccessExpression(d));
|
|
2991
3295
|
if (!site)
|
|
@@ -2996,7 +3300,7 @@ mixin) {
|
|
|
2996
3300
|
// identities (symbol parameters, mutable bindings, computed
|
|
2997
3301
|
// descriptions) or assignments outside the constructor's top
|
|
2998
3302
|
// level.
|
|
2999
|
-
if (p.
|
|
3303
|
+
if (ts.symbolName(p).startsWith("__@")) {
|
|
3000
3304
|
const keySym = lateBoundKeySymOf(lowerer, p);
|
|
3001
3305
|
const key = keySym ? classSymbolKeyOfSymbol(lowerer, keySym) : null;
|
|
3002
3306
|
if (key && symbolFields.has(key.identity))
|
|
@@ -3013,21 +3317,23 @@ mixin) {
|
|
|
3013
3317
|
// Unmappable inferences and arm-less kinds keep the fence.
|
|
3014
3318
|
// TypeScript classes keep the compile-time fence too: an annotated
|
|
3015
3319
|
// program can spell `T | undefined` itself.
|
|
3016
|
-
if (isJsSourceFile(
|
|
3320
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(decl))) {
|
|
3017
3321
|
const original = undefArmedFieldType(lowerer, p);
|
|
3018
|
-
const armed = original === null
|
|
3322
|
+
const armed = original === null
|
|
3323
|
+
? null
|
|
3324
|
+
: inheritedJsFieldType(lowerer, decl, ts.symbolName(p), original);
|
|
3019
3325
|
if (armed !== null) {
|
|
3020
3326
|
// Unknown JS properties use the instance bag: they do not
|
|
3021
3327
|
// exist until assigned, and a subclass may declare the same
|
|
3022
3328
|
// name as an ordinary layout field.
|
|
3023
3329
|
if (armed.kind === "dyn")
|
|
3024
3330
|
continue;
|
|
3025
|
-
fields.set(p
|
|
3026
|
-
fieldOrder.push({ name: p
|
|
3331
|
+
fields.set(ts.symbolName(p), armed);
|
|
3332
|
+
fieldOrder.push({ name: ts.symbolName(p), type: armed, initializer: undefined });
|
|
3027
3333
|
continue;
|
|
3028
3334
|
}
|
|
3029
3335
|
}
|
|
3030
|
-
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)`);
|
|
3031
3337
|
}
|
|
3032
3338
|
}
|
|
3033
3339
|
// Second refinement chance, OWN symbol slots: the member loop ran
|
|
@@ -3051,18 +3357,18 @@ mixin) {
|
|
|
3051
3357
|
// is NOT the pure forwarding shape has no static story — named
|
|
3052
3358
|
// fence, never a mis-typed array.
|
|
3053
3359
|
const mixinForwarding = mixin !== undefined && ctor !== null && mixinForwardingCtor(lowerer, ctor);
|
|
3054
|
-
if (mixin && ctor && !mixinForwarding && ctor.parameters.some((p) => p.dotDotDotToken)) {
|
|
3055
|
-
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)");
|
|
3056
3362
|
}
|
|
3057
3363
|
// Constructor omitted on a derived class: it inherits the base's
|
|
3058
3364
|
// (tsc types `new Derived(...)` against the inherited signature; the
|
|
3059
3365
|
// synthesized constructor forwards the same params to super).
|
|
3060
3366
|
const ctorParams = ctor && !mixinForwarding
|
|
3061
|
-
? lowerer.paramShapes(ctor.parameters)
|
|
3367
|
+
? lowerer.paramShapes(ctor.parameters.nodes)
|
|
3062
3368
|
: (base?.ctorParams ?? (callableBase ? [{ type: DYN, mode: "dynRest" }] : []));
|
|
3063
3369
|
if (ctor &&
|
|
3064
3370
|
!mixinForwarding &&
|
|
3065
|
-
isJsSourceFile(
|
|
3371
|
+
isJsSourceFile(ts.getSourceFileOfNode(ctor)) &&
|
|
3066
3372
|
!ctorParams.some((shape) => shape.mode === "rest" || shape.mode === "dynRest") &&
|
|
3067
3373
|
bodyReadsArguments(ctor)) {
|
|
3068
3374
|
ctorParams.push({ type: DYN, mode: "arguments" });
|
|
@@ -3078,9 +3384,9 @@ mixin) {
|
|
|
3078
3384
|
// INSTANTIATION prints its family's name — JS has one `Box`.
|
|
3079
3385
|
jsName: jsNameOverride ?? decl.name?.text ?? "",
|
|
3080
3386
|
...(base ? { base: base.def.name } : {}),
|
|
3081
|
-
jsLength: ctor?.parameters.findIndex((parameter) => parameter.initializer || parameter.dotDotDotToken) === -1
|
|
3082
|
-
? ctor.parameters.length
|
|
3083
|
-
: 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),
|
|
3084
3390
|
// Layout order: the base chain's fields as an IDENTICAL prefix,
|
|
3085
3391
|
// then this class's own — what makes an upcast a reinterpret.
|
|
3086
3392
|
// Redeclared INHERITED fields contribute no slot (their
|
|
@@ -3108,6 +3414,7 @@ mixin) {
|
|
|
3108
3414
|
fieldOrder,
|
|
3109
3415
|
methods,
|
|
3110
3416
|
...(methodEntryFences.size > 0 ? { methodEntryFences } : {}),
|
|
3417
|
+
...(returnAdapters.size > 0 ? { returnAdapters } : {}),
|
|
3111
3418
|
decl,
|
|
3112
3419
|
...(emitOverride !== undefined ? { emitOverride } : {}),
|
|
3113
3420
|
ctor,
|
|
@@ -3130,6 +3437,14 @@ mixin) {
|
|
|
3130
3437
|
...(deferredInitFields.size > 0 ? { deferredInitFields } : {}),
|
|
3131
3438
|
...(escape.escapes ? { constructionEscapes: true } : {}),
|
|
3132
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
|
+
}
|
|
3133
3448
|
// GENERIC members get their declaring-class backlink now that the
|
|
3134
3449
|
// info exists (instance lowering reads it for `this` typing and the
|
|
3135
3450
|
// generic-class binding merge).
|
|
@@ -3163,7 +3478,7 @@ mixin) {
|
|
|
3163
3478
|
}
|
|
3164
3479
|
if (familyMode) {
|
|
3165
3480
|
const typeParams = [];
|
|
3166
|
-
for (const tp of decl.typeParameters) {
|
|
3481
|
+
for (const tp of decl.typeParameters.nodes) {
|
|
3167
3482
|
const sym = lowerer.checker.getSymbolAtLocation(tp.name);
|
|
3168
3483
|
if (!sym)
|
|
3169
3484
|
lowerer.unsupported("SC1090", tp, "this type parameter form");
|
|
@@ -3431,6 +3746,7 @@ export function lowerStaticFieldInits(lowerer, info) {
|
|
|
3431
3746
|
// instantiation's bindings/context (a no-op for everything else —
|
|
3432
3747
|
// generic FAMILIES own their statics and carry no genericInstance).
|
|
3433
3748
|
const diagsBefore = lowerer.diags.length;
|
|
3749
|
+
const sinkMark = lowerer.diagSinkMark();
|
|
3434
3750
|
try {
|
|
3435
3751
|
return withInstanceBindings(lowerer, info, () => lowerStaticFieldInitsInner(lowerer, info));
|
|
3436
3752
|
}
|
|
@@ -3440,8 +3756,10 @@ export function lowerStaticFieldInits(lowerer, info) {
|
|
|
3440
3756
|
// letting a poisoned initializer escape the module lowering pass.
|
|
3441
3757
|
if (!(error instanceof PoisonError))
|
|
3442
3758
|
throw error;
|
|
3443
|
-
if (info.decl && isJsSourceFile(info.decl
|
|
3444
|
-
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);
|
|
3445
3763
|
if (fence)
|
|
3446
3764
|
return [fence];
|
|
3447
3765
|
}
|
|
@@ -3552,8 +3870,16 @@ function lowerStaticFieldInitsInner(lowerer, info) {
|
|
|
3552
3870
|
});
|
|
3553
3871
|
}
|
|
3554
3872
|
const items = [
|
|
3555
|
-
...info.staticFields.map((f) => ({
|
|
3556
|
-
|
|
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
|
+
})),
|
|
3557
3883
|
].sort((a, b) => a.pos - b.pos);
|
|
3558
3884
|
for (const item of items) {
|
|
3559
3885
|
if (item.kind === "block") {
|
|
@@ -3563,9 +3889,9 @@ function lowerStaticFieldInitsInner(lowerer, info) {
|
|
|
3563
3889
|
continue;
|
|
3564
3890
|
}
|
|
3565
3891
|
const f = item.f;
|
|
3566
|
-
lowerer.
|
|
3567
|
-
lowerer.bumpFileStat(locOf(f.initializer).file, "total");
|
|
3892
|
+
lowerer.countStatement(f.initializer, locOf(f.initializer).file);
|
|
3568
3893
|
const diagsBefore = lowerer.diags.length;
|
|
3894
|
+
const sinkMark = lowerer.diagSinkMark();
|
|
3569
3895
|
try {
|
|
3570
3896
|
const previousThis = lowerer.ctx.thisLocal;
|
|
3571
3897
|
const receiver = f.initializer.kind === ts.SyntaxKind.ThisKeyword || hasStaticThis(f.initializer)
|
|
@@ -3602,12 +3928,11 @@ function lowerStaticFieldInitsInner(lowerer, info) {
|
|
|
3602
3928
|
catch (e) {
|
|
3603
3929
|
if (!(e instanceof PoisonError))
|
|
3604
3930
|
throw e;
|
|
3605
|
-
lowerer.
|
|
3606
|
-
|
|
3607
|
-
|
|
3608
|
-
|
|
3609
|
-
|
|
3610
|
-
});
|
|
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);
|
|
3611
3936
|
if (fence)
|
|
3612
3937
|
out.push(fence);
|
|
3613
3938
|
}
|
|
@@ -3656,12 +3981,12 @@ export function analyzeClassDecoration(lowerer, info) {
|
|
|
3656
3981
|
: null;
|
|
3657
3982
|
if (ambientCallee !== null) {
|
|
3658
3983
|
const sym = lowerer.resolveValueSymbol(ambientCallee);
|
|
3659
|
-
const vdecl = sym && !lowerer.isStdlibSymbol(sym) ?
|
|
3984
|
+
const vdecl = sym && !lowerer.isStdlibSymbol(sym) ? sym.declarations[0] : undefined;
|
|
3660
3985
|
const ambientVar = vdecl !== undefined &&
|
|
3661
3986
|
ts.isVariableDeclaration(vdecl) &&
|
|
3662
3987
|
vdecl.initializer === undefined &&
|
|
3663
3988
|
(ts.getCombinedModifierFlags(vdecl) & ts.ModifierFlags.Ambient) !== 0 &&
|
|
3664
|
-
!
|
|
3989
|
+
!ts.getSourceFileOfNode(vdecl).isDeclarationFile;
|
|
3665
3990
|
if (ambientVar || ambientUndefinedFnSymbolOf(lowerer, ambientCallee) !== null) {
|
|
3666
3991
|
shapes.push({ kind: "ambientThrow", name: ambientCallee.text });
|
|
3667
3992
|
continue;
|
|
@@ -3853,6 +4178,54 @@ export function staticShadowBelow(info, name) {
|
|
|
3853
4178
|
s.genericStatics?.has(name) === true ||
|
|
3854
4179
|
staticShadowBelow(s, name));
|
|
3855
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
|
+
}
|
|
3856
4229
|
/** The nearest GENERIC static declaration of `name` at/above `info` —
|
|
3857
4230
|
* findStaticOn's twin over the genericStatics tables. */
|
|
3858
4231
|
export function findGenericStaticOn(lowerer, info, name) {
|
|
@@ -3907,17 +4280,22 @@ export function classValueRef(lowerer, info, blame) {
|
|
|
3907
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)`);
|
|
3908
4281
|
}
|
|
3909
4282
|
if (info.builtinError || info.builtinEmitter || info.builtinStream !== undefined) {
|
|
3910
|
-
|
|
3911
|
-
|
|
3912
|
-
|
|
3913
|
-
|
|
3914
|
-
|
|
3915
|
-
|
|
3916
|
-
|
|
3917
|
-
|
|
3918
|
-
|
|
3919
|
-
|
|
3920
|
-
|
|
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) {
|
|
3921
4299
|
lowerer.unsupported("SC1090", blame, `classes extending builtin bases as values ('${display}' inherits a runtime-provided constructor)`);
|
|
3922
4300
|
}
|
|
3923
4301
|
lowerer.noteEdge(`%${info.def.name}.constructor`);
|
|
@@ -3928,14 +4306,94 @@ export function classValueRef(lowerer, info, blame) {
|
|
|
3928
4306
|
loc: locOf(blame),
|
|
3929
4307
|
};
|
|
3930
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
|
+
}
|
|
3931
4389
|
/** Constructor-ABI equality — the classval widening rule: a classval(D)
|
|
3932
4390
|
* value may flow into a classval(C) slot only when D's completed
|
|
3933
4391
|
* constructor signature equals C's (same count, modes, and ABI types),
|
|
3934
4392
|
* which is what keeps newValue completion against C's one signature
|
|
3935
4393
|
* sound for every value legally in the slot. */
|
|
3936
4394
|
export function ctorAbiEquals(lowerer, sub, sup) {
|
|
3937
|
-
const a = sub
|
|
3938
|
-
const b = sup
|
|
4395
|
+
const a = classValueParams(sub);
|
|
4396
|
+
const b = classValueParams(sup);
|
|
3939
4397
|
return (a.length === b.length &&
|
|
3940
4398
|
a.every((p, i) => p.mode === b[i].mode && typeEquals(p.type, b[i].type)));
|
|
3941
4399
|
}
|
|
@@ -4058,7 +4516,7 @@ export function lowerStaticFieldRead(lowerer, expr) {
|
|
|
4058
4516
|
// JavaScript often assigns public statics after the class declaration.
|
|
4059
4517
|
// Their storage stays mutable and checked, while reads retain the
|
|
4060
4518
|
// checker's concrete type instead of losing the method receiver.
|
|
4061
|
-
const type = isJsSourceFile(
|
|
4519
|
+
const type = isJsSourceFile(ts.getSourceFileOfNode(expr))
|
|
4062
4520
|
? null
|
|
4063
4521
|
: lowerer.mapTypeOf(lowerer.typeOf(expr));
|
|
4064
4522
|
return type ? lowerer.coerceToExpected(value, type) : value;
|
|
@@ -4089,6 +4547,70 @@ function namedEvaluationName(expr) {
|
|
|
4089
4547
|
return p.name.text;
|
|
4090
4548
|
return "";
|
|
4091
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
|
+
}
|
|
4092
4614
|
/** Collect a class expression once per enclosing specialization. Function-local
|
|
4093
4615
|
* evaluations allocate fresh constructor objects; top-level expressions use
|
|
4094
4616
|
* immortal templates. Static initialization remains limited to whole top-level
|
|
@@ -4115,19 +4637,21 @@ export function lowerClassExpressionInfo(lowerer, expr) {
|
|
|
4115
4637
|
if (ts.isFunctionLike(p))
|
|
4116
4638
|
local = true;
|
|
4117
4639
|
}
|
|
4118
|
-
if (local &&
|
|
4640
|
+
if (local &&
|
|
4641
|
+
expr.members.nodes.some((member) => member.name && ts.isPrivateIdentifier(member.name)) &&
|
|
4642
|
+
!localPrivateFieldsAgree(expr)) {
|
|
4119
4643
|
lowerer.unsupported("SC1090", expr, "function-local classes with private brands");
|
|
4120
4644
|
}
|
|
4121
4645
|
if (local &&
|
|
4122
|
-
(expr.typeParameters?.length ||
|
|
4646
|
+
(expr.typeParameters?.nodes.length ||
|
|
4123
4647
|
decoratorNodesOf(expr).length ||
|
|
4124
|
-
expr.members.some((member) => decoratorNodesOf(member).length ||
|
|
4125
|
-
(!isJsSourceFile(
|
|
4648
|
+
expr.members.nodes.some((member) => decoratorNodesOf(member).length ||
|
|
4649
|
+
(!isJsSourceFile(ts.getSourceFileOfNode(expr)) &&
|
|
4126
4650
|
(ts.isClassStaticBlockDeclaration(member) ||
|
|
4127
4651
|
ts
|
|
4128
4652
|
.getModifiers(member)
|
|
4129
4653
|
?.some((modifier) => modifier.kind === ts.SyntaxKind.StaticKeyword))) ||
|
|
4130
|
-
(ts.isMethodDeclaration(member) && member.typeParameters?.length)))) {
|
|
4654
|
+
(ts.isMethodDeclaration(member) && member.typeParameters?.nodes.length)))) {
|
|
4131
4655
|
lowerer.unsupported("SC1090", expr, "function-local classes with statics, decorators, or generic members");
|
|
4132
4656
|
}
|
|
4133
4657
|
lowerer.collectingExprClasses.add(expr);
|
|
@@ -4135,7 +4659,7 @@ export function lowerClassExpressionInfo(lowerer, expr) {
|
|
|
4135
4659
|
if (local &&
|
|
4136
4660
|
lowerer.fnStack.length > 0 &&
|
|
4137
4661
|
!lowerer.computedClassBases.has(lowerer.classNamer(expr))) {
|
|
4138
|
-
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;
|
|
4139
4663
|
if (heritage &&
|
|
4140
4664
|
(ts.isCallExpression(heritage) ||
|
|
4141
4665
|
(ts.isIdentifier(heritage) &&
|
|
@@ -4167,7 +4691,7 @@ export function lowerClassExpressionInfo(lowerer, expr) {
|
|
|
4167
4691
|
});
|
|
4168
4692
|
info.localClass = { context: null, bodies: new Map(), captureSources: [], ready: false };
|
|
4169
4693
|
if (info.base?.localClass) {
|
|
4170
|
-
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;
|
|
4171
4695
|
if (baseExpression)
|
|
4172
4696
|
info.localClass.baseExpression = baseExpression;
|
|
4173
4697
|
}
|
|
@@ -4198,7 +4722,7 @@ export function lowerClassExpressionInfo(lowerer, expr) {
|
|
|
4198
4722
|
const wholeInit = (ts.isVariableDeclaration(holder) &&
|
|
4199
4723
|
holder.initializer !== undefined &&
|
|
4200
4724
|
ts.isVariableDeclarationList(holder.parent) &&
|
|
4201
|
-
holder.parent.declarations.length === 1 &&
|
|
4725
|
+
holder.parent.declarations.nodes.length === 1 &&
|
|
4202
4726
|
ts.isVariableStatement(holder.parent.parent) &&
|
|
4203
4727
|
ts.isSourceFile(holder.parent.parent.parent)) ||
|
|
4204
4728
|
(ts.isBinaryExpression(holder) &&
|
|
@@ -4222,8 +4746,8 @@ export function lowerClassExpressionInfo(lowerer, expr) {
|
|
|
4222
4746
|
* the member fences don't apply. */
|
|
4223
4747
|
export function lowerClassExpression(lowerer, expr) {
|
|
4224
4748
|
if (decoratorNodesOf(expr).length > 0 ||
|
|
4225
|
-
expr.members.some((m) => decoratorNodesOf(m).length > 0)) {
|
|
4226
|
-
if (!isJsSourceFile(
|
|
4749
|
+
expr.members.nodes.some((m) => decoratorNodesOf(m).length > 0)) {
|
|
4750
|
+
if (!isJsSourceFile(ts.getSourceFileOfNode(expr)) && expr.typeParameters === undefined) {
|
|
4227
4751
|
const thrown = guaranteedDecorationThrow(lowerer, expr);
|
|
4228
4752
|
if (thrown) {
|
|
4229
4753
|
// The expression's static type never materializes — the read
|
|
@@ -4405,7 +4929,7 @@ export function exactClassOfReceiver(lowerer, expr) {
|
|
|
4405
4929
|
// class-value write fence answers instead.
|
|
4406
4930
|
if (direct)
|
|
4407
4931
|
return direct.classDecorators?.valueGlobalId !== undefined ? null : direct;
|
|
4408
|
-
const decl =
|
|
4932
|
+
const decl = symbol.valueDeclaration;
|
|
4409
4933
|
if (!decl ||
|
|
4410
4934
|
!ts.isVariableDeclaration(decl) ||
|
|
4411
4935
|
decl.initializer === undefined ||
|
|
@@ -4449,7 +4973,7 @@ export function propertyAssignedClassInfoOf(lowerer, symbol) {
|
|
|
4449
4973
|
const registered = lowerer.classBySymbol.get(resolved);
|
|
4450
4974
|
if (registered)
|
|
4451
4975
|
return registered;
|
|
4452
|
-
const decls =
|
|
4976
|
+
const decls = resolved.declarations;
|
|
4453
4977
|
// The class expression's OWN symbol (tsgo's answer through CJS export
|
|
4454
4978
|
// aliases): the declaration is the expression itself. Its top-level
|
|
4455
4979
|
// assignment statement must be the binding's ONLY producer. The
|
|
@@ -4503,17 +5027,17 @@ function enclosingTopLevelClassAssignment(expr) {
|
|
|
4503
5027
|
* `Common.I`): a second assignment makes the binding dynamic, so
|
|
4504
5028
|
* callers refuse to pin the first one's class. */
|
|
4505
5029
|
function countAssignmentsTo(assign) {
|
|
4506
|
-
const sf =
|
|
5030
|
+
const sf = ts.getSourceFileOfNode(assign);
|
|
4507
5031
|
// `exports.I` and `module.exports.I` are the SAME binding in Node
|
|
4508
5032
|
// (exports aliases module.exports until a table replaces it) — fold
|
|
4509
5033
|
// the member spellings together before comparing.
|
|
4510
5034
|
const canon = (lhs) => {
|
|
4511
|
-
const text =
|
|
5035
|
+
const text = ts.getTextOfNode(lhs).replace(/\s+/g, "");
|
|
4512
5036
|
return text.startsWith("module.exports.") ? text.slice("module.".length) : text;
|
|
4513
5037
|
};
|
|
4514
5038
|
const target = canon(assign.left);
|
|
4515
5039
|
let n = 0;
|
|
4516
|
-
for (const stmt of sf.statements) {
|
|
5040
|
+
for (const stmt of sf.statements.nodes) {
|
|
4517
5041
|
if (!ts.isExpressionStatement(stmt))
|
|
4518
5042
|
continue;
|
|
4519
5043
|
const e = stmt.expression;
|
|
@@ -4561,9 +5085,9 @@ export function lowerStaticMethodCall(lowerer, call, access) {
|
|
|
4561
5085
|
// export assignment pins it) — the direct-name rules apply.
|
|
4562
5086
|
if (!ts.isIdentifier(access.expression)) {
|
|
4563
5087
|
if (!isModuleExportsAccess(access.expression) ||
|
|
4564
|
-
!isCjsJsFile(
|
|
5088
|
+
!isCjsJsFile(ts.getSourceFileOfNode(access), lowerer.program)) {
|
|
4565
5089
|
let receiverType = lowerer.mapTypeOf(lowerer.typeOf(access.expression));
|
|
4566
|
-
if (receiverType?.kind !== "classval" && isJsSourceFile(
|
|
5090
|
+
if (receiverType?.kind !== "classval" && isJsSourceFile(ts.getSourceFileOfNode(call))) {
|
|
4567
5091
|
const receiver = tryLowerExpression(lowerer, access.expression);
|
|
4568
5092
|
if (receiver?.type.kind === "classval")
|
|
4569
5093
|
receiverType = receiver.type;
|
|
@@ -4588,7 +5112,7 @@ export function lowerStaticMethodCall(lowerer, call, access) {
|
|
|
4588
5112
|
loc: locOf(call),
|
|
4589
5113
|
};
|
|
4590
5114
|
}
|
|
4591
|
-
const whole = cjsClassExprWholeExportOf(
|
|
5115
|
+
const whole = cjsClassExprWholeExportOf(ts.getSourceFileOfNode(access));
|
|
4592
5116
|
if (!whole)
|
|
4593
5117
|
return null;
|
|
4594
5118
|
return staticCallOn(lowerer, call, access, lowerer.lowerClassExpressionInfo(whole.classExpr), false);
|
|
@@ -4629,6 +5153,9 @@ function classValueIsExactlyOwn(lowerer, recv, info) {
|
|
|
4629
5153
|
}
|
|
4630
5154
|
function staticCallOn(lowerer, call, access, info, throughValue) {
|
|
4631
5155
|
const loc = locOf(call);
|
|
5156
|
+
const runtimeStatic = directRuntimeStaticCall(lowerer, call, access, info, throughValue);
|
|
5157
|
+
if (runtimeStatic)
|
|
5158
|
+
return runtimeStatic;
|
|
4632
5159
|
if ((hasRuntimeStatics(info) && !findStaticOn(lowerer, info, access.name.text)?.field) ||
|
|
4633
5160
|
(info.callableBase &&
|
|
4634
5161
|
!findStaticOn(lowerer, info, access.name.text) &&
|
|
@@ -4638,7 +5165,7 @@ function staticCallOn(lowerer, call, access, info, throughValue) {
|
|
|
4638
5165
|
recv: lowerer.lowerExprExpecting(access.expression, DYN),
|
|
4639
5166
|
method: access.name.text,
|
|
4640
5167
|
calleeName: access.name.text,
|
|
4641
|
-
args: call.arguments.map((argument) => lowerer.lowerExprExpecting(argument, DYN)),
|
|
5168
|
+
args: call.arguments.nodes.map((argument) => lowerer.lowerExprExpecting(argument, DYN)),
|
|
4642
5169
|
type: DYN,
|
|
4643
5170
|
loc,
|
|
4644
5171
|
};
|
|
@@ -4668,7 +5195,7 @@ function staticCallOn(lowerer, call, access, info, throughValue) {
|
|
|
4668
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)`);
|
|
4669
5196
|
}
|
|
4670
5197
|
const instance = genericCallInstance(lowerer, call, staticMethodForReceiver(lowerer, access, gfound.info, info, throughValue));
|
|
4671
|
-
const args = lowerer.completeArgs(call.arguments, instance.params, loc, call);
|
|
5198
|
+
const args = lowerer.completeArgs(call.arguments.nodes, instance.params, loc, call);
|
|
4672
5199
|
return { kind: "call", callee: instance.name, args, type: instance.returnType, loc };
|
|
4673
5200
|
}
|
|
4674
5201
|
if (throughValue && staticShadowBelow(info, access.name.text)) {
|
|
@@ -4677,7 +5204,7 @@ function staticCallOn(lowerer, call, access, info, throughValue) {
|
|
|
4677
5204
|
const specialized = findGenericStaticOn(lowerer, info, access.name.text);
|
|
4678
5205
|
if (specialized?.declarer === found.declarer && specialized.info.implicitParams) {
|
|
4679
5206
|
const instance = implicitCallInstance(lowerer, call, staticMethodForReceiver(lowerer, access, specialized.info, info, throughValue));
|
|
4680
|
-
const args = lowerer.completeArgs(call.arguments, instance.params, loc, call);
|
|
5207
|
+
const args = lowerer.completeArgs(call.arguments.nodes, instance.params, loc, call);
|
|
4681
5208
|
return { kind: "call", callee: instance.name, args, type: instance.returnType, loc };
|
|
4682
5209
|
}
|
|
4683
5210
|
if (found.field !== undefined) {
|
|
@@ -4692,7 +5219,7 @@ function staticCallOn(lowerer, call, access, info, throughValue) {
|
|
|
4692
5219
|
loc,
|
|
4693
5220
|
};
|
|
4694
5221
|
const params = found.field.type.params;
|
|
4695
|
-
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]));
|
|
4696
5223
|
for (let i = args.length; i < params.length; i++) {
|
|
4697
5224
|
const absent = omittedArgFor(lowerer, params[i], loc);
|
|
4698
5225
|
if (!absent) {
|
|
@@ -4722,16 +5249,184 @@ function staticCallOn(lowerer, call, access, info, throughValue) {
|
|
|
4722
5249
|
return {
|
|
4723
5250
|
kind: "call",
|
|
4724
5251
|
callee: instance.name,
|
|
4725
|
-
args: lowerer.completeArgs(call.arguments, instance.params, loc, call),
|
|
5252
|
+
args: lowerer.completeArgs(call.arguments.nodes, instance.params, loc, call),
|
|
4726
5253
|
type: instance.returnType,
|
|
4727
5254
|
loc,
|
|
4728
5255
|
};
|
|
4729
5256
|
}
|
|
4730
5257
|
const fnName = `%${found.declarer.def.name}.static:${access.name.text}`;
|
|
4731
5258
|
lowerer.noteEdge(fnName);
|
|
4732
|
-
const args = lowerer.completeArgs(call.arguments, found.method.params, loc, call);
|
|
5259
|
+
const args = lowerer.completeArgs(call.arguments.nodes, found.method.params, loc, call);
|
|
4733
5260
|
return { kind: "call", callee: fnName, args, type: found.method.ret, loc };
|
|
4734
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
|
+
}
|
|
4735
5430
|
function staticMethodForReceiver(lowerer, access, method, receiver, throughValue) {
|
|
4736
5431
|
if (!hasStaticThis(method.decl))
|
|
4737
5432
|
return method;
|
|
@@ -4774,6 +5469,10 @@ export function lowerClassValueProperty(lowerer, expr) {
|
|
|
4774
5469
|
const loc = locOf(expr);
|
|
4775
5470
|
const member = expr.name.text;
|
|
4776
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;
|
|
4777
5476
|
if (info &&
|
|
4778
5477
|
((hasRuntimeStatics(info) && !findStaticOn(lowerer, info, member)?.field) ||
|
|
4779
5478
|
(info.callableBase && !findStaticOn(lowerer, info, member))))
|
|
@@ -4800,7 +5499,8 @@ export function lowerClassValueProperty(lowerer, expr) {
|
|
|
4800
5499
|
// `module.exports.label` in a class-replaced CJS module: the
|
|
4801
5500
|
// receiver is the exact exported class, and the read is
|
|
4802
5501
|
// side-effect-free — as bindable as an identifier.
|
|
4803
|
-
!(isModuleExportsAccess(expr.expression) &&
|
|
5502
|
+
!(isModuleExportsAccess(expr.expression) &&
|
|
5503
|
+
isCjsJsFile(ts.getSourceFileOfNode(expr), lowerer.program))) {
|
|
4804
5504
|
// Devirtualized reads DISCARD the receiver value, so only
|
|
4805
5505
|
// side-effect-free receivers are claimed (the instanceOf fold
|
|
4806
5506
|
// rule); computed ones meet the pointed fence with a bindable fix.
|
|
@@ -4847,19 +5547,49 @@ export function lowerClassValueProperty(lowerer, expr) {
|
|
|
4847
5547
|
* async/generator/generic-with-body combinations before this runs, and
|
|
4848
5548
|
* the generic case fences at the caller). */
|
|
4849
5549
|
function abstractMemberSignature(lowerer, member) {
|
|
4850
|
-
for (const param of member.parameters) {
|
|
5550
|
+
for (const param of member.parameters.nodes) {
|
|
4851
5551
|
if (!ts.isIdentifier(param.name))
|
|
4852
5552
|
lowerer.unsupported("SC1031", param);
|
|
4853
5553
|
}
|
|
4854
5554
|
return {
|
|
4855
|
-
shapes: lowerer.paramShapes(member.parameters),
|
|
5555
|
+
shapes: lowerer.paramShapes(member.parameters.nodes),
|
|
4856
5556
|
ret: lowerer.declaredReturnType(member, member.name),
|
|
4857
5557
|
};
|
|
4858
5558
|
}
|
|
4859
5559
|
/** A nominal return subtype uses the same owned pointer as the inherited
|
|
4860
5560
|
* return slot. The current class is still being collected, so consult its
|
|
4861
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
|
+
}
|
|
4862
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
|
+
}
|
|
4863
5593
|
if (declared.kind !== "object" || inherited.kind !== "object")
|
|
4864
5594
|
return declared;
|
|
4865
5595
|
if (lowerer.isSubclassOf(declared.className, inherited.className) ||
|
|
@@ -4939,7 +5669,7 @@ export function collectInheritedJsFieldWrites(lowerer, files) {
|
|
|
4939
5669
|
continue;
|
|
4940
5670
|
ts.walkPreorder(file, (node) => {
|
|
4941
5671
|
if ((!ts.isClassDeclaration(node) && !ts.isClassExpression(node)) ||
|
|
4942
|
-
!node.heritageClauses?.length)
|
|
5672
|
+
!node.heritageClauses?.nodes.length)
|
|
4943
5673
|
return;
|
|
4944
5674
|
const writes = new Map();
|
|
4945
5675
|
const addWrite = (name, expression) => {
|
|
@@ -4966,10 +5696,10 @@ export function collectInheritedJsFieldWrites(lowerer, files) {
|
|
|
4966
5696
|
addWrite(name, part.right);
|
|
4967
5697
|
}
|
|
4968
5698
|
}
|
|
4969
|
-
|
|
5699
|
+
ts.forEachChild(part, scan);
|
|
4970
5700
|
};
|
|
4971
|
-
for (const member of node.members) {
|
|
4972
|
-
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))
|
|
4973
5703
|
continue;
|
|
4974
5704
|
if (ts.isPropertyDeclaration(member) && member.initializer) {
|
|
4975
5705
|
const name = ts.isPrivateIdentifier(member.name)
|
|
@@ -4999,7 +5729,7 @@ export function collectInheritedJsFieldWrites(lowerer, files) {
|
|
|
4999
5729
|
for (const base of lowerer.checker.getBaseTypes(target)) {
|
|
5000
5730
|
for (const [name, expressions] of writes) {
|
|
5001
5731
|
const property = lowerer.checker.getPropertyOfType(base, name);
|
|
5002
|
-
for (const declaration of property ?
|
|
5732
|
+
for (const declaration of property ? property.declarations : []) {
|
|
5003
5733
|
if (ts.isMethodDeclaration(declaration) || ts.isAccessor(declaration))
|
|
5004
5734
|
continue;
|
|
5005
5735
|
let owner = declaration.parent;
|
|
@@ -5007,7 +5737,7 @@ export function collectInheritedJsFieldWrites(lowerer, files) {
|
|
|
5007
5737
|
owner = owner.parent;
|
|
5008
5738
|
if (!owner ||
|
|
5009
5739
|
(!ts.isClassDeclaration(owner) && !ts.isClassExpression(owner)) ||
|
|
5010
|
-
!isJsSourceFile(
|
|
5740
|
+
!isJsSourceFile(ts.getSourceFileOfNode(owner)))
|
|
5011
5741
|
continue;
|
|
5012
5742
|
let fields = lowerer.inheritedJsFieldWrites.get(owner);
|
|
5013
5743
|
if (!fields)
|
|
@@ -5033,15 +5763,15 @@ export function collectInheritedJsFieldWrites(lowerer, files) {
|
|
|
5033
5763
|
* hierarchy identifies the original declarations through aliases as well. */
|
|
5034
5764
|
export function collectVirtualJsMethods(lowerer, files) {
|
|
5035
5765
|
const families = [];
|
|
5036
|
-
collectClassMethodMutations(lowerer, files);
|
|
5766
|
+
lowerer.speculativeTypeQueries(() => collectClassMethodMutations(lowerer, files));
|
|
5037
5767
|
const visit = (node) => {
|
|
5038
5768
|
if (ts.isClassDeclaration(node) || ts.isClassExpression(node)) {
|
|
5039
|
-
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)) &&
|
|
5040
5770
|
ts.isIdentifier(member.name) &&
|
|
5041
|
-
!member.modifiers?.some((modifier) => modifier.kind === ts.SyntaxKind.StaticKeyword));
|
|
5042
|
-
if (node.heritageClauses?.length &&
|
|
5771
|
+
!member.modifiers?.nodes.some((modifier) => modifier.kind === ts.SyntaxKind.StaticKeyword));
|
|
5772
|
+
if (node.heritageClauses?.nodes.length &&
|
|
5043
5773
|
accessors.length &&
|
|
5044
|
-
isJsSourceFile(
|
|
5774
|
+
isJsSourceFile(ts.getSourceFileOfNode(node))) {
|
|
5045
5775
|
const symbol = lowerer.typeOf(node).getSymbol();
|
|
5046
5776
|
const instance = symbol ? lowerer.checker.getDeclaredTypeOfSymbol(symbol) : null;
|
|
5047
5777
|
const seen = new Set();
|
|
@@ -5055,13 +5785,13 @@ export function collectVirtualJsMethods(lowerer, files) {
|
|
|
5055
5785
|
if (!ts.isIdentifier(member.name))
|
|
5056
5786
|
continue;
|
|
5057
5787
|
const property = lowerer.checker.getPropertyOfType(base, member.name.text);
|
|
5058
|
-
for (const declaration of property ?
|
|
5788
|
+
for (const declaration of property ? property.declarations : []) {
|
|
5059
5789
|
if ((ts.isGetAccessorDeclaration(declaration) ||
|
|
5060
5790
|
ts.isSetAccessorDeclaration(declaration)) &&
|
|
5061
|
-
isJsSourceFile(
|
|
5791
|
+
isJsSourceFile(ts.getSourceFileOfNode(declaration))) {
|
|
5062
5792
|
lowerer.checkedVirtualJsAccessors.add(declaration);
|
|
5063
5793
|
lowerer.checkedVirtualJsAccessors.add(member);
|
|
5064
|
-
for (const twin of node.members)
|
|
5794
|
+
for (const twin of node.members.nodes)
|
|
5065
5795
|
if ((ts.isGetAccessorDeclaration(twin) || ts.isSetAccessorDeclaration(twin)) &&
|
|
5066
5796
|
ts.isIdentifier(twin.name) &&
|
|
5067
5797
|
twin.name.text === member.name.text)
|
|
@@ -5075,10 +5805,10 @@ export function collectVirtualJsMethods(lowerer, files) {
|
|
|
5075
5805
|
if (instance)
|
|
5076
5806
|
markAccessors(instance);
|
|
5077
5807
|
}
|
|
5078
|
-
const members = node.members.filter((member) => ts.isMethodDeclaration(member) &&
|
|
5808
|
+
const members = node.members.nodes.filter((member) => ts.isMethodDeclaration(member) &&
|
|
5079
5809
|
ts.isIdentifier(member.name) &&
|
|
5080
|
-
!member.modifiers?.some((modifier) => modifier.kind === ts.SyntaxKind.StaticKeyword));
|
|
5081
|
-
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) {
|
|
5082
5812
|
const symbol = lowerer.typeOf(node).getSymbol();
|
|
5083
5813
|
const instance = symbol ? lowerer.checker.getDeclaredTypeOfSymbol(symbol) : null;
|
|
5084
5814
|
const seen = new Set();
|
|
@@ -5092,22 +5822,23 @@ export function collectVirtualJsMethods(lowerer, files) {
|
|
|
5092
5822
|
if (!ts.isIdentifier(member.name))
|
|
5093
5823
|
continue;
|
|
5094
5824
|
const property = lowerer.checker.getPropertyOfType(base, member.name.text);
|
|
5095
|
-
for (const declaration of property ?
|
|
5825
|
+
for (const declaration of property ? property.declarations : []) {
|
|
5096
5826
|
if (ts.isMethodDeclaration(declaration) &&
|
|
5097
|
-
isJsSourceFile(
|
|
5827
|
+
isJsSourceFile(ts.getSourceFileOfNode(declaration)) &&
|
|
5828
|
+
!checkedJsOverride(lowerer, declaration, member)) {
|
|
5098
5829
|
lowerer.virtualJsMethods.add(declaration);
|
|
5099
|
-
if (isJsSourceFile(
|
|
5100
|
-
!member.typeParameters &&
|
|
5830
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(member)) &&
|
|
5831
|
+
!member.typeParameters?.nodes &&
|
|
5101
5832
|
!member.asteriskToken &&
|
|
5102
|
-
!member.modifiers?.some((m) => m.kind === ts.SyntaxKind.AsyncKeyword) &&
|
|
5833
|
+
!member.modifiers?.nodes.some((m) => m.kind === ts.SyntaxKind.AsyncKeyword) &&
|
|
5103
5834
|
!bodyReadsArguments(member) &&
|
|
5104
|
-
member.parameters.every((p) => !p.dotDotDotToken)) {
|
|
5105
|
-
lowerer.virtualJsMethodArity.set(declaration, Math.max(lowerer.virtualJsMethodArity.get(declaration) ?? 0, member.parameters.length));
|
|
5106
|
-
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 &&
|
|
5107
5838
|
!declaration.asteriskToken &&
|
|
5108
|
-
!declaration.modifiers?.some((m) => m.kind === ts.SyntaxKind.AsyncKeyword) &&
|
|
5839
|
+
!declaration.modifiers?.nodes.some((m) => m.kind === ts.SyntaxKind.AsyncKeyword) &&
|
|
5109
5840
|
!bodyReadsArguments(declaration) &&
|
|
5110
|
-
[...member.parameters, ...declaration.parameters].every((p) => !p.dotDotDotToken);
|
|
5841
|
+
[...member.parameters.nodes, ...declaration.parameters.nodes].every((p) => !p.dotDotDotToken);
|
|
5111
5842
|
if (checked) {
|
|
5112
5843
|
lowerer.checkedVirtualJsMethods.add(declaration);
|
|
5113
5844
|
lowerer.checkedVirtualJsMethods.add(member);
|
|
@@ -5133,7 +5864,7 @@ export function collectVirtualJsMethods(lowerer, files) {
|
|
|
5133
5864
|
return;
|
|
5134
5865
|
if (ts.isReturnStatement(node) && node.expression)
|
|
5135
5866
|
lowerer.checkedVirtualJsValueReturns.add(member);
|
|
5136
|
-
|
|
5867
|
+
ts.forEachChild(node, scan);
|
|
5137
5868
|
};
|
|
5138
5869
|
scan(member);
|
|
5139
5870
|
}
|
|
@@ -5152,6 +5883,14 @@ export function collectVirtualJsMethods(lowerer, files) {
|
|
|
5152
5883
|
}
|
|
5153
5884
|
}
|
|
5154
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
|
+
}
|
|
5155
5894
|
/** The receiver's EXACT runtime class, when the expression proves it: a
|
|
5156
5895
|
* `new C(...)` expression directly, or a const binding initialized with
|
|
5157
5896
|
* one (the binding can never be reassigned to a subclass instance).
|
|
@@ -5174,7 +5913,7 @@ export function exactInstanceClassOf(lowerer, expr) {
|
|
|
5174
5913
|
if (!ts.isIdentifier(e))
|
|
5175
5914
|
return null;
|
|
5176
5915
|
const symbol = lowerer.resolveValueSymbol(e);
|
|
5177
|
-
const decl = symbol ?
|
|
5916
|
+
const decl = symbol ? symbol.valueDeclaration : undefined;
|
|
5178
5917
|
if (!decl ||
|
|
5179
5918
|
!ts.isVariableDeclaration(decl) ||
|
|
5180
5919
|
decl.initializer === undefined ||
|
|
@@ -5264,19 +6003,39 @@ export function lowerClassGenericMethodCall(lowerer, call, access, recvInfo, fou
|
|
|
5264
6003
|
loc,
|
|
5265
6004
|
}
|
|
5266
6005
|
: upcastTo(lowerer, receiver, declarer.def.name);
|
|
5267
|
-
const args = lowerer.completeArgs(call.arguments, instance.params, loc, call);
|
|
5268
|
-
|
|
6006
|
+
const args = lowerer.completeArgs(call.arguments.nodes, instance.params, loc, call);
|
|
6007
|
+
const result = {
|
|
5269
6008
|
kind: "call",
|
|
5270
6009
|
callee: instance.name,
|
|
5271
6010
|
args: [thisArg, ...args],
|
|
5272
6011
|
type: instance.returnType,
|
|
5273
6012
|
loc,
|
|
5274
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;
|
|
5275
6025
|
}
|
|
5276
6026
|
/** Wraps a derived-class expression in an upcast when the target base
|
|
5277
6027
|
* class differs (a no-op reinterpret at runtime; keeps IR types exact). */
|
|
5278
6028
|
export function upcastTo(lowerer, expr, className) {
|
|
5279
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
|
+
}
|
|
5280
6039
|
return { kind: "upcast", value: expr, type: { kind: "object", className }, loc: expr.loc };
|
|
5281
6040
|
}
|
|
5282
6041
|
return expr;
|
|
@@ -5294,24 +6053,24 @@ export function upcastTo(lowerer, expr, className) {
|
|
|
5294
6053
|
* form with an exact static story under monomorphization (the
|
|
5295
6054
|
* instantiation adopts the base's ABI; see collectClassShapeInner). */
|
|
5296
6055
|
function mixinForwardingCtor(lowerer, ctor) {
|
|
5297
|
-
if (ctor.parameters.length !== 1 || !ctor.body)
|
|
6056
|
+
if (ctor.parameters.nodes.length !== 1 || !ctor.body)
|
|
5298
6057
|
return false;
|
|
5299
|
-
const p = ctor.parameters[0];
|
|
6058
|
+
const p = ctor.parameters.nodes[0];
|
|
5300
6059
|
if (!p.dotDotDotToken || !ts.isIdentifier(p.name))
|
|
5301
6060
|
return false;
|
|
5302
6061
|
const paramName = p.name;
|
|
5303
6062
|
const paramSym = lowerer.checker.getSymbolAtLocation(paramName);
|
|
5304
6063
|
if (!paramSym)
|
|
5305
6064
|
return false;
|
|
5306
|
-
const first = ctor.body.statements[0];
|
|
6065
|
+
const first = ctor.body.statements.nodes[0];
|
|
5307
6066
|
if (!first || !ts.isExpressionStatement(first) || !ts.isCallExpression(first.expression))
|
|
5308
6067
|
return false;
|
|
5309
6068
|
const call = first.expression;
|
|
5310
6069
|
if (call.expression.kind !== ts.SyntaxKind.SuperKeyword)
|
|
5311
6070
|
return false;
|
|
5312
|
-
if (call.arguments.length !== 1)
|
|
6071
|
+
if (call.arguments.nodes.length !== 1)
|
|
5313
6072
|
return false;
|
|
5314
|
-
const a = call.arguments[0];
|
|
6073
|
+
const a = call.arguments.nodes[0];
|
|
5315
6074
|
if (!ts.isSpreadElement(a) || !ts.isIdentifier(a.expression))
|
|
5316
6075
|
return false;
|
|
5317
6076
|
const spreadIdent = a.expression;
|
|
@@ -5364,7 +6123,7 @@ export function lowerClassMembers(lowerer, info) {
|
|
|
5364
6123
|
catch (e) {
|
|
5365
6124
|
if (!(e instanceof PoisonError))
|
|
5366
6125
|
throw e;
|
|
5367
|
-
if (info.decl && isJsSourceFile(info.decl
|
|
6126
|
+
if (info.decl && isJsSourceFile(ts.getSourceFileOfNode(info.decl))) {
|
|
5368
6127
|
const types = [
|
|
5369
6128
|
{ kind: "object", className },
|
|
5370
6129
|
...info.ctorParams.map((param) => param.type),
|
|
@@ -5475,7 +6234,7 @@ function lowerClassCtorInner(lowerer, info) {
|
|
|
5475
6234
|
// The default-param prologue runs FIRST — before field initializers
|
|
5476
6235
|
// and (in a derived class) before super(): JS evaluates parameter
|
|
5477
6236
|
// defaults on entry, ahead of everything the body does.
|
|
5478
|
-
const declared = lowerer.declareParams(info.ctor.parameters, info.ctorParams);
|
|
6237
|
+
const declared = lowerer.declareParams(info.ctor.parameters.nodes, info.ctorParams);
|
|
5479
6238
|
params.push(...declared.params);
|
|
5480
6239
|
if (info.ctorParams.at(-1)?.mode === "arguments") {
|
|
5481
6240
|
const local = lowerer.declareHiddenLocal("%arguments", DYN);
|
|
@@ -5491,7 +6250,7 @@ function lowerClassCtorInner(lowerer, info) {
|
|
|
5491
6250
|
body.push(...lowerer.fieldInitStmts(info, thisLocal));
|
|
5492
6251
|
body.push(...paramPropInitStmts(lowerer, info, thisLocal));
|
|
5493
6252
|
if (info.ctor.body)
|
|
5494
|
-
body.push(...lowerer.lowerStmts(info.ctor.body.statements));
|
|
6253
|
+
body.push(...lowerer.lowerStmts(info.ctor.body.statements.nodes));
|
|
5495
6254
|
}
|
|
5496
6255
|
else if (info.ctor.body) {
|
|
5497
6256
|
body.push(...lowerer.lowerDerivedCtorBody(info, thisLocal));
|
|
@@ -5548,7 +6307,7 @@ function lowerClassCtorInner(lowerer, info) {
|
|
|
5548
6307
|
* private, static and abstract members are not prototype string keys. */
|
|
5549
6308
|
function classPrototypeNames(decl) {
|
|
5550
6309
|
const names = [];
|
|
5551
|
-
for (const member of decl.members) {
|
|
6310
|
+
for (const member of decl.members.nodes) {
|
|
5552
6311
|
if (!ts.isMethodDeclaration(member) &&
|
|
5553
6312
|
!ts.isGetAccessorDeclaration(member) &&
|
|
5554
6313
|
!ts.isSetAccessorDeclaration(member))
|
|
@@ -5600,7 +6359,8 @@ export function classMemberNameOf(lowerer, name) {
|
|
|
5600
6359
|
if (member === "iterator" ||
|
|
5601
6360
|
member === "asyncIterator" ||
|
|
5602
6361
|
member === "dispose" ||
|
|
5603
|
-
member === "asyncDispose"
|
|
6362
|
+
member === "asyncDispose" ||
|
|
6363
|
+
member === "toPrimitive") {
|
|
5604
6364
|
return `sym:${member}`;
|
|
5605
6365
|
}
|
|
5606
6366
|
}
|
|
@@ -5913,6 +6673,77 @@ function lowerClassMethodMemberInner(lowerer, info, fnLike) {
|
|
|
5913
6673
|
allowDiagSink: true,
|
|
5914
6674
|
});
|
|
5915
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;
|
|
5916
6747
|
const prevClass = lowerer.currentClass;
|
|
5917
6748
|
lowerer.currentClass = info;
|
|
5918
6749
|
// ASYNC methods: the module function is an async IrFunction — its
|
|
@@ -5941,7 +6772,7 @@ function lowerClassMethodMemberInner(lowerer, info, fnLike) {
|
|
|
5941
6772
|
const params = [{ localId: thisLocal.id, name: "this", type: thisType }];
|
|
5942
6773
|
// `this` is declared first, so method parameter DEFAULTS may use it
|
|
5943
6774
|
// (JS allows this in method defaults; it is param 0 here).
|
|
5944
|
-
const declared = lowerer.declareParams(fnLike.parameters, sig.params);
|
|
6775
|
+
const declared = lowerer.declareParams(fnLike.parameters.nodes, sig.params);
|
|
5945
6776
|
params.push(...declared.params);
|
|
5946
6777
|
// A shorter JS override still implements every inherited ABI slot.
|
|
5947
6778
|
// These tail parameters have no source binding or default prologue.
|
|
@@ -5952,10 +6783,10 @@ function lowerClassMethodMemberInner(lowerer, info, fnLike) {
|
|
|
5952
6783
|
if (shape.mode === "arguments")
|
|
5953
6784
|
fnCtx.argumentsLocal = local;
|
|
5954
6785
|
}
|
|
5955
|
-
const body = [...declared.prologue, ...lowerer.lowerStmts(fnLike.body.statements)];
|
|
6786
|
+
const body = [...declared.prologue, ...lowerer.lowerStmts(fnLike.body.statements.nodes)];
|
|
5956
6787
|
appendImplicitUndefinedReturn(lowerer, body, bodyReturn, locOf(fnLike));
|
|
5957
6788
|
const fn = {
|
|
5958
|
-
name:
|
|
6789
|
+
name: fnName,
|
|
5959
6790
|
params,
|
|
5960
6791
|
returnType: bodyReturn,
|
|
5961
6792
|
locals: lowerer.ctx.locals,
|
|
@@ -5985,7 +6816,7 @@ export function lowerStaticMethod(lowerer, info, name) {
|
|
|
5985
6816
|
const entry = info.staticMethods?.get(name);
|
|
5986
6817
|
if (!entry?.member.body)
|
|
5987
6818
|
return null;
|
|
5988
|
-
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;
|
|
5989
6820
|
const isGenerator = entry.member.asteriskToken !== undefined;
|
|
5990
6821
|
if (isGenerator && (entry.ret.kind !== "generator" || (entry.ret.async === true) !== isAsync)) {
|
|
5991
6822
|
lowerer.badType(entry.member.name, lowerer.typeOf(entry.member.name));
|
|
@@ -6006,13 +6837,13 @@ export function lowerStaticMethod(lowerer, info, name) {
|
|
|
6006
6837
|
lowerer.fnStack.push(fnCtx);
|
|
6007
6838
|
try {
|
|
6008
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)`);
|
|
6009
|
-
const declared = lowerer.declareParams(entry.member.parameters, entry.params);
|
|
6840
|
+
const declared = lowerer.declareParams(entry.member.parameters.nodes, entry.params);
|
|
6010
6841
|
if (entry.params.at(-1)?.mode === "arguments") {
|
|
6011
6842
|
const local = lowerer.declareHiddenLocal("%arguments", DYN);
|
|
6012
6843
|
declared.params.push({ localId: local.id, name: "%arguments", type: DYN });
|
|
6013
6844
|
fnCtx.argumentsLocal = local;
|
|
6014
6845
|
}
|
|
6015
|
-
const body = [...declared.prologue, ...lowerer.lowerStmts(entry.member.body.statements)];
|
|
6846
|
+
const body = [...declared.prologue, ...lowerer.lowerStmts(entry.member.body.statements.nodes)];
|
|
6016
6847
|
appendImplicitUndefinedReturn(lowerer, body, bodyReturn, locOf(entry.member));
|
|
6017
6848
|
const fn = {
|
|
6018
6849
|
name: `%${info.def.name}.static:${name}`,
|
|
@@ -6083,6 +6914,13 @@ export function throwingSetterFn(lowerer, info, prop) {
|
|
|
6083
6914
|
loc,
|
|
6084
6915
|
};
|
|
6085
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
|
+
}
|
|
6086
6924
|
/** The base a constructor chain actually CALLS into: generic FAMILIES are
|
|
6087
6925
|
* never constructed (no `%<family>.constructor` exists), so an
|
|
6088
6926
|
* instantiation's construction-relevant base is the family's own base —
|
|
@@ -6126,14 +6964,15 @@ export function fieldInitStmts(lowerer, info, thisLocal) {
|
|
|
6126
6964
|
className: info.def.name,
|
|
6127
6965
|
field: f.name,
|
|
6128
6966
|
value: dynUndefinedExpr(loc),
|
|
6967
|
+
define: true,
|
|
6129
6968
|
loc,
|
|
6130
6969
|
});
|
|
6131
6970
|
}
|
|
6132
6971
|
if (!f.initializer)
|
|
6133
6972
|
continue;
|
|
6134
|
-
lowerer.
|
|
6135
|
-
lowerer.bumpFileStat(locOf(f.initializer).file, "total");
|
|
6973
|
+
lowerer.countStatement(f.initializer, locOf(f.initializer).file);
|
|
6136
6974
|
const diagsBefore = lowerer.diags.length;
|
|
6975
|
+
const sinkMark = lowerer.diagSinkMark();
|
|
6137
6976
|
try {
|
|
6138
6977
|
const value = lowerer.lowerExprExpecting(f.initializer, f.type);
|
|
6139
6978
|
out.push({
|
|
@@ -6142,18 +6981,18 @@ export function fieldInitStmts(lowerer, info, thisLocal) {
|
|
|
6142
6981
|
className: info.def.name,
|
|
6143
6982
|
field: f.name,
|
|
6144
6983
|
value,
|
|
6984
|
+
define: true,
|
|
6145
6985
|
loc: locOf(f.initializer),
|
|
6146
6986
|
});
|
|
6147
6987
|
}
|
|
6148
6988
|
catch (e) {
|
|
6149
6989
|
if (!(e instanceof PoisonError))
|
|
6150
6990
|
throw e;
|
|
6151
|
-
lowerer.
|
|
6152
|
-
|
|
6153
|
-
|
|
6154
|
-
|
|
6155
|
-
|
|
6156
|
-
});
|
|
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);
|
|
6157
6996
|
if (fence)
|
|
6158
6997
|
out.push(fence);
|
|
6159
6998
|
}
|
|
@@ -6192,6 +7031,24 @@ function paramPropInitStmts(lowerer, info, thisLocal) {
|
|
|
6192
7031
|
}
|
|
6193
7032
|
return out;
|
|
6194
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
|
+
}
|
|
6195
7052
|
/** Super statements initialize the base and then the derived fields on
|
|
6196
7053
|
* whichever control-flow path executes. Repeated calls are explicitly
|
|
6197
7054
|
* refused until native layouts can allocate a second receiver. */
|
|
@@ -6204,7 +7061,7 @@ export function lowerDerivedCtorBody(lowerer, info, thisLocal, forward) {
|
|
|
6204
7061
|
const previousInitialized = context.superInitialized;
|
|
6205
7062
|
context.superInitialized = initialized;
|
|
6206
7063
|
context.superCall = (superCall) => {
|
|
6207
|
-
if (!
|
|
7064
|
+
if (!superCallInStatementPosition(superCall))
|
|
6208
7065
|
lowerer.unsupported("SC1090", superCall, "super() in an expression position");
|
|
6209
7066
|
superSeen = true;
|
|
6210
7067
|
const loc = locOf(superCall);
|
|
@@ -6224,11 +7081,11 @@ export function lowerDerivedCtorBody(lowerer, info, thisLocal, forward) {
|
|
|
6224
7081
|
},
|
|
6225
7082
|
];
|
|
6226
7083
|
if (info.callableBase) {
|
|
6227
|
-
if (superCall.arguments.some(ts.isSpreadElement))
|
|
7084
|
+
if (superCall.arguments.nodes.some(ts.isSpreadElement))
|
|
6228
7085
|
lowerer.unsupported("SC1090", superCall, "spreading explicit super arguments into an ordinary constructor");
|
|
6229
7086
|
const pack = {
|
|
6230
7087
|
kind: "dynArrLit",
|
|
6231
|
-
elems: superCall.arguments.map((arg) => lowerer.lowerExprExpecting(arg, DYN)),
|
|
7088
|
+
elems: superCall.arguments.nodes.map((arg) => lowerer.lowerExprExpecting(arg, DYN)),
|
|
6232
7089
|
type: DYN,
|
|
6233
7090
|
loc,
|
|
6234
7091
|
};
|
|
@@ -6236,19 +7093,19 @@ export function lowerDerivedCtorBody(lowerer, info, thisLocal, forward) {
|
|
|
6236
7093
|
}
|
|
6237
7094
|
else {
|
|
6238
7095
|
const base = superBaseOf(info);
|
|
6239
|
-
if (base.builtinEmitter && superCall.arguments.length > 0)
|
|
7096
|
+
if (base.builtinEmitter && superCall.arguments.nodes.length > 0)
|
|
6240
7097
|
lowerer.unsupported("SC1090", superCall, "EventEmitter constructor options ('captureRejections')");
|
|
6241
7098
|
if (base.builtinStream) {
|
|
6242
|
-
statements.push(...lowerStreamSuperCall(lowerer, info, base, superCall.arguments, thisLocal, loc, superCall));
|
|
7099
|
+
statements.push(...lowerStreamSuperCall(lowerer, info, base, superCall.arguments.nodes, thisLocal, loc, superCall));
|
|
6243
7100
|
}
|
|
6244
7101
|
else {
|
|
6245
7102
|
const surplusSpread = forward === undefined &&
|
|
6246
7103
|
!base.builtinError &&
|
|
6247
7104
|
!base.builtinEmitter &&
|
|
6248
7105
|
base.ctorParams.length === 0 &&
|
|
6249
|
-
superCall.arguments.some(ts.isSpreadElement);
|
|
7106
|
+
superCall.arguments.nodes.some(ts.isSpreadElement);
|
|
6250
7107
|
if (surplusSpread) {
|
|
6251
|
-
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);
|
|
6252
7109
|
for (const value of evaluated)
|
|
6253
7110
|
statements.push({ kind: "exprStmt", expr: value, loc });
|
|
6254
7111
|
}
|
|
@@ -6256,26 +7113,26 @@ export function lowerDerivedCtorBody(lowerer, info, thisLocal, forward) {
|
|
|
6256
7113
|
!base.builtinError &&
|
|
6257
7114
|
!base.builtinEmitter &&
|
|
6258
7115
|
!base.ctorParams.some((param) => param.mode === "rest" || param.mode === "dynRest") &&
|
|
6259
|
-
!superCall.arguments.some(ts.isSpreadElement) &&
|
|
6260
|
-
superCall.arguments.length > base.ctorParams.length;
|
|
7116
|
+
!superCall.arguments.nodes.some(ts.isSpreadElement) &&
|
|
7117
|
+
superCall.arguments.nodes.length > base.ctorParams.length;
|
|
6261
7118
|
let args = surplusSpread
|
|
6262
7119
|
? []
|
|
6263
7120
|
: forward !== undefined
|
|
6264
7121
|
? forward
|
|
6265
7122
|
: base.builtinError
|
|
6266
|
-
? lowerer.errorConstructorArgs(superCall.arguments, loc, superCall)
|
|
7123
|
+
? lowerer.errorConstructorArgs(superCall.arguments.nodes, loc, superCall)
|
|
6267
7124
|
: base.builtinEmitter
|
|
6268
7125
|
? []
|
|
6269
7126
|
: lowerer.completeArgs(surplus
|
|
6270
|
-
? superCall.arguments.slice(0, base.ctorParams.length)
|
|
6271
|
-
: superCall.arguments, base.ctorParams, loc, superCall);
|
|
7127
|
+
? superCall.arguments.nodes.slice(0, base.ctorParams.length)
|
|
7128
|
+
: superCall.arguments.nodes, base.ctorParams, loc, superCall);
|
|
6272
7129
|
if (surplus) {
|
|
6273
7130
|
args = args.map((arg) => {
|
|
6274
7131
|
const local = lowerer.declareHiddenLocal("%superArgument", arg.type);
|
|
6275
7132
|
statements.push({ kind: "varDecl", localId: local.id, init: arg, loc });
|
|
6276
7133
|
return { kind: "varRef", localId: local.id, type: arg.type, loc };
|
|
6277
7134
|
});
|
|
6278
|
-
for (const argument of superCall.arguments.slice(base.ctorParams.length)) {
|
|
7135
|
+
for (const argument of superCall.arguments.nodes.slice(base.ctorParams.length)) {
|
|
6279
7136
|
statements.push({
|
|
6280
7137
|
kind: "exprStmt",
|
|
6281
7138
|
expr: lowerer.lowerExpr(argument),
|
|
@@ -6315,7 +7172,7 @@ export function lowerDerivedCtorBody(lowerer, info, thisLocal, forward) {
|
|
|
6315
7172
|
};
|
|
6316
7173
|
};
|
|
6317
7174
|
try {
|
|
6318
|
-
const result = lowerer.lowerStmts(info.ctor.body.statements);
|
|
7175
|
+
const result = lowerer.lowerStmts(info.ctor.body.statements.nodes);
|
|
6319
7176
|
result.push({
|
|
6320
7177
|
kind: "if",
|
|
6321
7178
|
cond: {
|
|
@@ -6362,7 +7219,6 @@ export function lowerDerivedCtorBody(lowerer, info, thisLocal, forward) {
|
|
|
6362
7219
|
* `this` (upcast; retained by the varRef read — the callee owns and
|
|
6363
7220
|
* releases its param per the universal convention). */
|
|
6364
7221
|
export function superCallStmt(lowerer, info, thisLocal, args, loc) {
|
|
6365
|
-
const base = superBaseOf(info);
|
|
6366
7222
|
const thisRef = {
|
|
6367
7223
|
kind: "varRef",
|
|
6368
7224
|
localId: thisLocal.id,
|
|
@@ -6407,6 +7263,8 @@ export function superCallStmt(lowerer, info, thisLocal, args, loc) {
|
|
|
6407
7263
|
},
|
|
6408
7264
|
loc,
|
|
6409
7265
|
};
|
|
7266
|
+
// A callable base has no class info, so the base is read after that case.
|
|
7267
|
+
const base = superBaseOf(info);
|
|
6410
7268
|
if (base.builtinError) {
|
|
6411
7269
|
// super(message) into the runtime-provided Error constructor: stamps
|
|
6412
7270
|
// name/message on the (already-allocated) object. Receiver + message
|
|
@@ -6451,7 +7309,7 @@ export function superCallStmt(lowerer, info, thisLocal, args, loc) {
|
|
|
6451
7309
|
return lowerStreamSuperCall(lowerer, info, base, [], thisLocal, loc, info.decl ?? info.ctor)[0];
|
|
6452
7310
|
}
|
|
6453
7311
|
lowerer.noteSuperConstructorEdge(`%${base.def.name}.constructor`);
|
|
6454
|
-
|
|
7312
|
+
const call = {
|
|
6455
7313
|
kind: "exprStmt",
|
|
6456
7314
|
expr: {
|
|
6457
7315
|
kind: "call",
|
|
@@ -6462,6 +7320,7 @@ export function superCallStmt(lowerer, info, thisLocal, args, loc) {
|
|
|
6462
7320
|
},
|
|
6463
7321
|
loc,
|
|
6464
7322
|
};
|
|
7323
|
+
return superIntoResultSlot(lowerer, base, info, call, lowerer.upcastTo({ ...thisRef }, base.def.name), info.ctor ?? info.decl);
|
|
6465
7324
|
}
|
|
6466
7325
|
/** `super.method(args)`: the base chain's implementation, called
|
|
6467
7326
|
* DIRECTLY over this method's own `this` (upcast to the declarer) —
|
|
@@ -6492,7 +7351,7 @@ export function lowerSuperMethodCall(lowerer, call, access) {
|
|
|
6492
7351
|
const instance = genericCallInstance(lowerer, call, gfound.info);
|
|
6493
7352
|
const loc = locOf(call);
|
|
6494
7353
|
const thisRef = { kind: "varRef", localId: thisL.id, type: thisL.type, loc };
|
|
6495
|
-
const args = lowerer.completeArgs(call.arguments, instance.params, loc, call);
|
|
7354
|
+
const args = lowerer.completeArgs(call.arguments.nodes, instance.params, loc, call);
|
|
6496
7355
|
return {
|
|
6497
7356
|
kind: "call",
|
|
6498
7357
|
callee: instance.name,
|
|
@@ -6553,8 +7412,8 @@ export function lowerSuperMethodCall(lowerer, call, access) {
|
|
|
6553
7412
|
kind: "dynCall",
|
|
6554
7413
|
callee,
|
|
6555
7414
|
receiver: lowerer.coerceToExpected(thisRef, DYN),
|
|
6556
|
-
calleeName:
|
|
6557
|
-
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)),
|
|
6558
7417
|
type: DYN,
|
|
6559
7418
|
loc,
|
|
6560
7419
|
};
|
|
@@ -6571,7 +7430,7 @@ export function lowerSuperMethodCall(lowerer, call, access) {
|
|
|
6571
7430
|
};
|
|
6572
7431
|
}
|
|
6573
7432
|
lowerer.noteEdge(`%${found.declarer.def.name}.${access.name.text}`);
|
|
6574
|
-
const args = lowerer.completeArgs(call.arguments, found.sig.params, loc, call);
|
|
7433
|
+
const args = lowerer.completeArgs(call.arguments.nodes, found.sig.params, loc, call);
|
|
6575
7434
|
return {
|
|
6576
7435
|
kind: "call",
|
|
6577
7436
|
callee: `%${found.declarer.def.name}.${access.name.text}`,
|
|
@@ -6688,6 +7547,47 @@ function inheritsBuiltinStreamCtor(lowerer, info) {
|
|
|
6688
7547
|
}
|
|
6689
7548
|
return false;
|
|
6690
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
|
+
}
|
|
6691
7591
|
/** Preserve argument evaluation order and option presence through builtin
|
|
6692
7592
|
* and inherited Error constructors. Checked-dynamic conversion retains
|
|
6693
7593
|
* Error identity and distinguishes a missing cause from undefined. */
|
|
@@ -6796,38 +7696,29 @@ function lowerProgramClassNew(lowerer, expr, declaredInfo, loc) {
|
|
|
6796
7696
|
if (info.localClass)
|
|
6797
7697
|
lowerer.unsupported("SC1090", expr, "construction through a function-local class's internal name");
|
|
6798
7698
|
lowerer.noteEdge(`%${info.def.name}.constructor`);
|
|
6799
|
-
|
|
6800
|
-
// zero arguments (the options bag fences, like the super() form).
|
|
6801
|
-
// Stream subclasses come first: their chain roots at the emitter
|
|
6802
|
-
// too, but the message should name the stream story.
|
|
6803
|
-
if (inheritsBuiltinStreamCtor(lowerer, info) && (expr.arguments ?? []).length > 0) {
|
|
6804
|
-
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(...)");
|
|
6805
|
-
}
|
|
6806
|
-
if (lowerer.inheritsBuiltinEmitterCtor(info) && (expr.arguments ?? []).length > 0) {
|
|
6807
|
-
lowerer.unsupported("SC1090", expr.arguments[0], "EventEmitter constructor options ('captureRejections')");
|
|
6808
|
-
}
|
|
7699
|
+
refuseInheritedBuiltinCtorArgs(lowerer, info, expr);
|
|
6809
7700
|
// A ctor-less chain into a builtin error base inherits both arguments;
|
|
6810
7701
|
// each synthesized constructor forwards the same pair to its base.
|
|
6811
7702
|
const args = lowerer.inheritsBuiltinErrorCtor(info)
|
|
6812
|
-
? lowerer.errorConstructorArgs(expr.arguments ?? [], loc, expr)
|
|
6813
|
-
: 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);
|
|
6814
7705
|
for (let current = info; current; current = current.base) {
|
|
6815
7706
|
if (current.def.baseValueGlobal)
|
|
6816
|
-
return {
|
|
7707
|
+
return constructedValue(lowerer, info, {
|
|
6817
7708
|
kind: "newValue",
|
|
6818
7709
|
callee: classValueRef(lowerer, info, expr),
|
|
6819
7710
|
args,
|
|
6820
7711
|
type: { kind: "object", className: info.def.name },
|
|
6821
7712
|
loc,
|
|
6822
|
-
};
|
|
7713
|
+
});
|
|
6823
7714
|
}
|
|
6824
|
-
return {
|
|
7715
|
+
return constructedValue(lowerer, info, {
|
|
6825
7716
|
kind: "new",
|
|
6826
7717
|
className: info.def.name,
|
|
6827
7718
|
args,
|
|
6828
7719
|
type: { kind: "object", className: info.def.name },
|
|
6829
7720
|
loc,
|
|
6830
|
-
};
|
|
7721
|
+
});
|
|
6831
7722
|
}
|
|
6832
7723
|
function assignedThisFieldType(lowerer, expr) {
|
|
6833
7724
|
const parent = expr.parent;
|
|
@@ -6840,15 +7731,47 @@ function assignedThisFieldType(lowerer, expr) {
|
|
|
6840
7731
|
}
|
|
6841
7732
|
return lowerer.currentClass?.fields.get(parent.left.name.text) ?? null;
|
|
6842
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
|
+
}
|
|
6843
7739
|
export function lowerNew(lowerer, expr) {
|
|
6844
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
|
+
}
|
|
6845
7762
|
const worker = lowerWorkerNew(lowerer, expr);
|
|
6846
7763
|
if (worker)
|
|
6847
7764
|
return worker;
|
|
7765
|
+
const readlineUi = lowerReadlineUiNew(lowerer, expr);
|
|
7766
|
+
if (readlineUi)
|
|
7767
|
+
return readlineUi;
|
|
7768
|
+
const channel = lowerMessageChannelNew(lowerer, expr) ?? lowerBroadcastChannelNew(lowerer, expr);
|
|
7769
|
+
if (channel)
|
|
7770
|
+
return channel;
|
|
6848
7771
|
let intlConstructor = expr.expression;
|
|
6849
7772
|
if (ts.isIdentifier(intlConstructor)) {
|
|
6850
7773
|
const symbol = lowerer.resolveValueSymbol(intlConstructor);
|
|
6851
|
-
const declaration = symbol ?
|
|
7774
|
+
const declaration = symbol ? symbol.valueDeclaration : undefined;
|
|
6852
7775
|
if (declaration && ts.isVariableDeclaration(declaration) && declaration.initializer)
|
|
6853
7776
|
intlConstructor = declaration.initializer;
|
|
6854
7777
|
}
|
|
@@ -6857,6 +7780,9 @@ export function lowerNew(lowerer, expr) {
|
|
|
6857
7780
|
: null;
|
|
6858
7781
|
if (intl && intl !== "Segmenter")
|
|
6859
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;
|
|
6860
7786
|
const instanceConstructor = lowerInstanceConstructorNew(lowerer, expr);
|
|
6861
7787
|
if (instanceConstructor)
|
|
6862
7788
|
return instanceConstructor;
|
|
@@ -6866,11 +7792,9 @@ export function lowerNew(lowerer, expr) {
|
|
|
6866
7792
|
if (ts.isIdentifier(expr.expression)) {
|
|
6867
7793
|
const symbol = lowerer.resolveValueSymbol(expr.expression);
|
|
6868
7794
|
const declaration = symbol &&
|
|
6869
|
-
|
|
6870
|
-
.declarationsOf(symbol)
|
|
6871
|
-
.find((node) => ts.isFunctionDeclaration(node) && node.body !== undefined);
|
|
7795
|
+
symbol.declarations.find((node) => ts.isFunctionDeclaration(node) && node.body !== undefined);
|
|
6872
7796
|
if (declaration && ts.isFunctionDeclaration(declaration) && declaration.body) {
|
|
6873
|
-
const last = declaration.body.statements.at(-1);
|
|
7797
|
+
const last = declaration.body.statements.nodes.at(-1);
|
|
6874
7798
|
if (last &&
|
|
6875
7799
|
ts.isReturnStatement(last) &&
|
|
6876
7800
|
last.expression &&
|
|
@@ -6907,7 +7831,7 @@ export function lowerNew(lowerer, expr) {
|
|
|
6907
7831
|
if (ts.isPropertyAccessExpression(expr.expression) &&
|
|
6908
7832
|
expr.expression.name.text === "Segmenter" &&
|
|
6909
7833
|
lowerer.isStdlibGlobal(expr.expression.expression, "Intl")) {
|
|
6910
|
-
const args = expr.arguments ?? [];
|
|
7834
|
+
const args = expr.arguments?.nodes ?? [];
|
|
6911
7835
|
const undefinedArg = (arg) => (lowerer.typeOf(arg).flags & ts.TypeFlags.Undefined) !== 0;
|
|
6912
7836
|
if (args.length > 2 || (args[0] && !undefinedArg(args[0]))) {
|
|
6913
7837
|
lowerer.noLowering("Intl.Segmenter locale negotiation", expr, "omit the locale or pass undefined for default Unicode grapheme segmentation");
|
|
@@ -6916,7 +7840,7 @@ export function lowerNew(lowerer, expr) {
|
|
|
6916
7840
|
if (options &&
|
|
6917
7841
|
!undefinedArg(options) &&
|
|
6918
7842
|
!(ts.isObjectLiteralExpression(options) &&
|
|
6919
|
-
options.properties.every((property) => ts.isPropertyAssignment(property) &&
|
|
7843
|
+
options.properties.nodes.every((property) => ts.isPropertyAssignment(property) &&
|
|
6920
7844
|
(ts.isIdentifier(property.name) || ts.isStringLiteral(property.name)) &&
|
|
6921
7845
|
property.name.text === "granularity" &&
|
|
6922
7846
|
ts.isStringLiteral(property.initializer) &&
|
|
@@ -6956,8 +7880,8 @@ export function lowerNew(lowerer, expr) {
|
|
|
6956
7880
|
: memberSym;
|
|
6957
7881
|
const emitterInfo = lowerer.builtinEmitterInfoOf(resolved);
|
|
6958
7882
|
if (emitterInfo) {
|
|
6959
|
-
if ((expr.arguments ?? []).length > 0) {
|
|
6960
|
-
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')");
|
|
6961
7885
|
}
|
|
6962
7886
|
return {
|
|
6963
7887
|
kind: "libCall",
|
|
@@ -6978,8 +7902,8 @@ export function lowerNew(lowerer, expr) {
|
|
|
6978
7902
|
// `new zlib.Gzip(options?)` — the zlib stream classes.
|
|
6979
7903
|
const zlibModeNs = zlibStreamModeOf(lowerer, resolved);
|
|
6980
7904
|
if (zlibModeNs !== null) {
|
|
6981
|
-
const what = `new zlib.${
|
|
6982
|
-
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);
|
|
6983
7907
|
}
|
|
6984
7908
|
// `new N.C(...)` / `new a.Point(...)` — construction through a
|
|
6985
7909
|
// USER namespace qualifier (import= alias chains included): the
|
|
@@ -7026,7 +7950,7 @@ export function lowerNew(lowerer, expr) {
|
|
|
7026
7950
|
// member-export symbol's; the class collects on demand (a body
|
|
7027
7951
|
// lowering ahead of the assignment statement).
|
|
7028
7952
|
if (!expr.expression.questionDotToken &&
|
|
7029
|
-
((isCjsJsFile(
|
|
7953
|
+
((isCjsJsFile(ts.getSourceFileOfNode(expr), lowerer.program) &&
|
|
7030
7954
|
(isModuleExportsAccess(expr.expression.expression) ||
|
|
7031
7955
|
(ts.isIdentifier(expr.expression.expression) &&
|
|
7032
7956
|
expr.expression.expression.text === "exports" &&
|
|
@@ -7041,7 +7965,7 @@ export function lowerNew(lowerer, expr) {
|
|
|
7041
7965
|
memberSym,
|
|
7042
7966
|
resolved,
|
|
7043
7967
|
lowerer.resolveValueSymbol(expr.expression.name) ?? undefined,
|
|
7044
|
-
lowerer.cjsModuleExportSymbol(
|
|
7968
|
+
lowerer.cjsModuleExportSymbol(ts.getSourceFileOfNode(expr), expr.expression.name.text),
|
|
7045
7969
|
];
|
|
7046
7970
|
const exportSym = candidates.find((s) => s !== undefined);
|
|
7047
7971
|
const g = candidates
|
|
@@ -7061,14 +7985,14 @@ export function lowerNew(lowerer, expr) {
|
|
|
7061
7985
|
};
|
|
7062
7986
|
below(info);
|
|
7063
7987
|
const callee = { kind: "varRef", localId: g.id, type: g.type, loc };
|
|
7064
|
-
const args = lowerer.completeArgs(expr.arguments ?? [], info.ctorParams, loc, expr);
|
|
7065
|
-
return {
|
|
7988
|
+
const args = lowerer.completeArgs(expr.arguments?.nodes ?? [], info.ctorParams, loc, expr);
|
|
7989
|
+
return constructedFromValue(lowerer, info, {
|
|
7066
7990
|
kind: "newValue",
|
|
7067
7991
|
callee,
|
|
7068
7992
|
args,
|
|
7069
7993
|
type: { kind: "object", className: info.def.name },
|
|
7070
7994
|
loc,
|
|
7071
|
-
};
|
|
7995
|
+
}, expr);
|
|
7072
7996
|
}
|
|
7073
7997
|
}
|
|
7074
7998
|
}
|
|
@@ -7092,7 +8016,10 @@ export function lowerNew(lowerer, expr) {
|
|
|
7092
8016
|
if (ts.isIdentifier(expr.expression) ||
|
|
7093
8017
|
(ts.isPropertyAccessExpression(expr.expression) &&
|
|
7094
8018
|
ts.isIdentifier(expr.expression.name) &&
|
|
7095
|
-
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))))) {
|
|
7096
8023
|
// `import C = N.C; new C()` — the alias's own source-order guards
|
|
7097
8024
|
// (a no-op for every non-import= binding).
|
|
7098
8025
|
if (ts.isIdentifier(expr.expression))
|
|
@@ -7100,7 +8027,7 @@ export function lowerNew(lowerer, expr) {
|
|
|
7100
8027
|
const identifier = ts.isIdentifier(expr.expression) ? expr.expression : expr.expression.name;
|
|
7101
8028
|
const symbol = ts.isIdentifier(identifier) ? lowerer.resolveValueSymbol(identifier) : null;
|
|
7102
8029
|
if (ts.isIdentifier(identifier) && lowerer.isStdlibGlobal(identifier, "Array")) {
|
|
7103
|
-
return lowerArrayConstructor(lowerer, expr, expr.arguments ?? []);
|
|
8030
|
+
return lowerArrayConstructor(lowerer, expr, expr.arguments?.nodes ?? []);
|
|
7104
8031
|
}
|
|
7105
8032
|
if (isNativeProxyInitializer(lowerer, expr))
|
|
7106
8033
|
return lowerNativeProxy(lowerer, expr);
|
|
@@ -7116,7 +8043,7 @@ export function lowerNew(lowerer, expr) {
|
|
|
7116
8043
|
// `cause` own-property record) / "Error" for absent, and the legacy
|
|
7117
8044
|
// numeric code from the name table.
|
|
7118
8045
|
if (errInfo && errInfo.def.name === "%DOMException") {
|
|
7119
|
-
const args = expr.arguments ?? [];
|
|
8046
|
+
const args = expr.arguments?.nodes ?? [];
|
|
7120
8047
|
if (args.length > 2) {
|
|
7121
8048
|
lowerer.noLowering(`new DOMException with ${args.length} arguments`, expr);
|
|
7122
8049
|
}
|
|
@@ -7149,7 +8076,7 @@ export function lowerNew(lowerer, expr) {
|
|
|
7149
8076
|
if (errInfo && errInfo.def.name === "%AssertionError") {
|
|
7150
8077
|
// new AssertionError(options): Node validates the options object and
|
|
7151
8078
|
// generates the message from operator, actual and expected.
|
|
7152
|
-
const args = expr.arguments ?? [];
|
|
8079
|
+
const args = expr.arguments?.nodes ?? [];
|
|
7153
8080
|
if (args.length > 1 || args.some(ts.isSpreadElement)) {
|
|
7154
8081
|
lowerer.noLowering(`new AssertionError with this argument list`, expr);
|
|
7155
8082
|
}
|
|
@@ -7161,8 +8088,21 @@ export function lowerNew(lowerer, expr) {
|
|
|
7161
8088
|
loc,
|
|
7162
8089
|
};
|
|
7163
8090
|
}
|
|
8091
|
+
if (errInfo && errInfo.def.name === "%SuppressedError") {
|
|
8092
|
+
const args = expr.arguments?.nodes ?? [];
|
|
8093
|
+
if (args.length > 3 || args.some(ts.isSpreadElement)) {
|
|
8094
|
+
lowerer.noLowering(`new SuppressedError with this argument list`, expr);
|
|
8095
|
+
}
|
|
8096
|
+
return {
|
|
8097
|
+
kind: "libCall",
|
|
8098
|
+
fn: "error.newSuppressed",
|
|
8099
|
+
args: [0, 1, 2].map((index) => args[index] ? lowerer.lowerExprExpecting(args[index], DYN) : dynUndefinedExpr(loc)),
|
|
8100
|
+
type: { kind: "object", className: "%SuppressedError" },
|
|
8101
|
+
loc,
|
|
8102
|
+
};
|
|
8103
|
+
}
|
|
7164
8104
|
if (errInfo && errInfo.def.name === "%AggregateError") {
|
|
7165
|
-
const args = expr.arguments ?? [];
|
|
8105
|
+
const args = expr.arguments?.nodes ?? [];
|
|
7166
8106
|
if (args.length > 3 || args.some(ts.isSpreadElement)) {
|
|
7167
8107
|
lowerer.noLowering(`new AggregateError with this argument list`, expr);
|
|
7168
8108
|
}
|
|
@@ -7176,7 +8116,7 @@ export function lowerNew(lowerer, expr) {
|
|
|
7176
8116
|
};
|
|
7177
8117
|
}
|
|
7178
8118
|
if (errInfo) {
|
|
7179
|
-
const args = lowerer.errorConstructorArgs(expr.arguments ?? [], loc, expr);
|
|
8119
|
+
const args = lowerer.errorConstructorArgs(expr.arguments?.nodes ?? [], loc, expr);
|
|
7180
8120
|
return {
|
|
7181
8121
|
kind: "libCall",
|
|
7182
8122
|
fn: "error.newOptions",
|
|
@@ -7190,8 +8130,8 @@ export function lowerNew(lowerer, expr) {
|
|
|
7190
8130
|
// (@types/node's captureRejections) has no lowering.
|
|
7191
8131
|
const emitterInfo = lowerer.builtinEmitterInfoOf(symbol);
|
|
7192
8132
|
if (emitterInfo) {
|
|
7193
|
-
if ((expr.arguments ?? []).length > 0) {
|
|
7194
|
-
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')");
|
|
7195
8135
|
}
|
|
7196
8136
|
return {
|
|
7197
8137
|
kind: "libCall",
|
|
@@ -7211,8 +8151,8 @@ export function lowerNew(lowerer, expr) {
|
|
|
7211
8151
|
return lowerStreamNew(lowerer, expr, streamInfo);
|
|
7212
8152
|
const zlibMode = zlibStreamModeOf(lowerer, symbol);
|
|
7213
8153
|
if (zlibMode !== null) {
|
|
7214
|
-
const what = `new zlib.${
|
|
7215
|
-
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);
|
|
7216
8156
|
}
|
|
7217
8157
|
// `new URL(input)`: the WHATWG URL class (stdlib/@types provenance —
|
|
7218
8158
|
// a user's own `class URL` resolves through classBySymbol below).
|
|
@@ -7221,8 +8161,8 @@ export function lowerNew(lowerer, expr) {
|
|
|
7221
8161
|
// libregexp engine the literals ride. The pattern compiles EAGERLY,
|
|
7222
8162
|
// so bad input throws Node's catchable SyntaxError at construction.
|
|
7223
8163
|
// Checked arguments retain native regexes and perform runtime coercion.
|
|
7224
|
-
if (symbol && symbol
|
|
7225
|
-
const args = expr.arguments ?? [];
|
|
8164
|
+
if (symbol && ts.symbolName(symbol) === "RegExp" && lowerer.isStdlibSymbol(symbol)) {
|
|
8165
|
+
const args = expr.arguments?.nodes ?? [];
|
|
7226
8166
|
if (args.length > 2) {
|
|
7227
8167
|
lowerer.noLowering(`new RegExp with ${args.length} arguments`, expr);
|
|
7228
8168
|
}
|
|
@@ -7270,6 +8210,11 @@ export function lowerNew(lowerer, expr) {
|
|
|
7270
8210
|
};
|
|
7271
8211
|
const pattern = strArg(args[0], "pattern");
|
|
7272
8212
|
const flags = strArg(args[1], "flags argument");
|
|
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)");
|
|
8217
|
+
}
|
|
7273
8218
|
return {
|
|
7274
8219
|
kind: "libCall",
|
|
7275
8220
|
fn: "regex.new",
|
|
@@ -7278,27 +8223,64 @@ export function lowerNew(lowerer, expr) {
|
|
|
7278
8223
|
loc,
|
|
7279
8224
|
};
|
|
7280
8225
|
}
|
|
7281
|
-
if (symbol && symbol
|
|
8226
|
+
if (symbol && ts.symbolName(symbol) === "URL" && lowerer.isStdlibSymbol(symbol)) {
|
|
7282
8227
|
return lowerUrlNew(lowerer, expr);
|
|
7283
8228
|
}
|
|
7284
8229
|
// `new URLSearchParams(init?)`: the WHATWG list (stdlib provenance —
|
|
7285
8230
|
// see lowerSearchParamsNew for the lowered init shapes).
|
|
7286
|
-
if (symbol && symbol
|
|
8231
|
+
if (symbol && ts.symbolName(symbol) === "URLSearchParams" && lowerer.isStdlibSymbol(symbol)) {
|
|
7287
8232
|
return lowerSearchParamsNew(lowerer, expr, loc);
|
|
7288
8233
|
}
|
|
7289
8234
|
// Date's read-only value slice: store the constructor's TimeClip'd
|
|
7290
8235
|
// epoch milliseconds as the scalar date kind. That is sufficient
|
|
7291
8236
|
// for every getter and toISOString; identity and setters stay
|
|
7292
8237
|
// fenced, so copying the scalar cannot create an observable lie.
|
|
7293
|
-
if (symbol && symbol
|
|
7294
|
-
const args = expr.arguments ?? [];
|
|
7295
|
-
if (args.some(ts.isSpreadElement)
|
|
7296
|
-
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 };
|
|
7297
8278
|
}
|
|
7298
|
-
if (isJsSourceFile(
|
|
8279
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(expr))) {
|
|
7299
8280
|
return {
|
|
7300
8281
|
kind: "libCall",
|
|
7301
|
-
|
|
8282
|
+
// One argument: a string parses with the full date parser.
|
|
8283
|
+
fn: args.length === 1 ? "date.nativeNewValue" : "date.nativeNew",
|
|
7302
8284
|
args: [
|
|
7303
8285
|
{
|
|
7304
8286
|
kind: "dynArrLit",
|
|
@@ -7327,34 +8309,52 @@ export function lowerNew(lowerer, expr) {
|
|
|
7327
8309
|
lowerer.noLowering(`new Date of '${lowerer.fmt(arg.type)}' values`, args[0], "pass milliseconds, a date string, or another Date value", symbol);
|
|
7328
8310
|
}
|
|
7329
8311
|
// `new StringDecoder(encoding?)` (node:string_decoder): the decoder
|
|
7330
|
-
// is a two-field record — the CANONICAL encoding name (
|
|
7331
|
-
//
|
|
7332
|
-
//
|
|
7333
|
-
//
|
|
7334
|
-
//
|
|
7335
|
-
|
|
7336
|
-
|
|
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 ?? [];
|
|
7337
8321
|
if (args.length > 1) {
|
|
7338
8322
|
lowerer.noLowering("new StringDecoder with 2 arguments", expr, undefined, symbol);
|
|
7339
8323
|
}
|
|
7340
|
-
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
|
+
};
|
|
7341
8340
|
const decT = lowerer.mapTypeOf(lowerer.typeOf(expr));
|
|
7342
8341
|
if (decT?.kind !== "record")
|
|
7343
8342
|
lowerer.badType(expr, lowerer.typeOf(expr));
|
|
7344
8343
|
return {
|
|
7345
8344
|
kind: "recordLit",
|
|
7346
8345
|
fields: [
|
|
7347
|
-
{ name: "%enc", value:
|
|
8346
|
+
{ name: "%enc", value: encoding },
|
|
7348
8347
|
{ name: "%pending", value: { kind: "numLit", value: 0, type: F64, loc } },
|
|
7349
8348
|
],
|
|
7350
8349
|
type: decT,
|
|
7351
8350
|
loc,
|
|
7352
8351
|
};
|
|
7353
8352
|
}
|
|
8353
|
+
const codec = symbol ? ts.symbolName(symbol) : undefined;
|
|
7354
8354
|
if (symbol &&
|
|
7355
|
-
(
|
|
8355
|
+
(codec === "TextDecoder" || codec === "TextEncoder") &&
|
|
7356
8356
|
lowerer.isStdlibSymbol(symbol)) {
|
|
7357
|
-
return lowerTextCodecNew(lowerer, expr,
|
|
8357
|
+
return lowerTextCodecNew(lowerer, expr, codec);
|
|
7358
8358
|
}
|
|
7359
8359
|
// `new Uint8Array(...)` / `new Uint32Array(...)` / `new
|
|
7360
8360
|
// Float32Array(...)` / `new Float64Array(...)`: the typed-array
|
|
@@ -7388,25 +8388,26 @@ export function lowerNew(lowerer, expr) {
|
|
|
7388
8388
|
// types get their half named specifically instead of the component
|
|
7389
8389
|
// fence (SC2009, which names Map slots at value positions elsewhere).
|
|
7390
8390
|
// Both Array() and new Array() share the elements/count lowering.
|
|
7391
|
-
if (symbol
|
|
7392
|
-
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);
|
|
7393
8393
|
if (object)
|
|
7394
8394
|
return object;
|
|
7395
8395
|
}
|
|
7396
|
-
if (symbol
|
|
7397
|
-
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 ?? []);
|
|
7398
8398
|
}
|
|
7399
|
-
|
|
7400
|
-
|
|
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;
|
|
7401
8402
|
const isPairLit = (el) => ts.isArrayLiteralExpression(el) &&
|
|
7402
|
-
el.elements.length === 2 &&
|
|
7403
|
-
!el.elements.some(ts.isSpreadElement);
|
|
7404
|
-
const entriesLit = seedArg && ts.isArrayLiteralExpression(seedArg) && seedArg.elements.every(isPairLit)
|
|
7405
|
-
? 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)
|
|
7406
8407
|
: null;
|
|
7407
8408
|
let tsType = lowerer.typeOf(expr);
|
|
7408
8409
|
let mapped = lowerer.mapTypeOf(tsType);
|
|
7409
|
-
if (mapped === null && isJsSourceFile(
|
|
8410
|
+
if (mapped === null && isJsSourceFile(ts.getSourceFileOfNode(expr)))
|
|
7410
8411
|
mapped = lowerer.irTypeOf(expr);
|
|
7411
8412
|
const fieldType = assignedThisFieldType(lowerer, expr);
|
|
7412
8413
|
if (mapped?.kind !== "map" && fieldType?.kind === "map")
|
|
@@ -7421,8 +8422,8 @@ export function lowerNew(lowerer, expr) {
|
|
|
7421
8422
|
parent = parent.parent;
|
|
7422
8423
|
// `satisfies` checks a view but retains the expression's own type.
|
|
7423
8424
|
const contextualSeed = !ts.isSatisfiesExpression(parent) &&
|
|
7424
|
-
(expr.typeArguments?.length ?? 0) === 0 &&
|
|
7425
|
-
(entriesLit !== null || (expr.arguments?.length ?? 0) === 0);
|
|
8425
|
+
(expr.typeArguments?.nodes.length ?? 0) === 0 &&
|
|
8426
|
+
(entriesLit !== null || (expr.arguments?.nodes.length ?? 0) === 0);
|
|
7426
8427
|
// JavaScript's `new Map()` has no type-argument syntax: the no-arg
|
|
7427
8428
|
// constructor overload pins Map<any, any> whatever the JSDoc says
|
|
7428
8429
|
// (`@type` on the declaration types the VARIABLE, not this
|
|
@@ -7442,7 +8443,7 @@ export function lowerNew(lowerer, expr) {
|
|
|
7442
8443
|
if (seeded)
|
|
7443
8444
|
return seeded;
|
|
7444
8445
|
}
|
|
7445
|
-
if ((expr.arguments?.length ?? 0) > 0 && !entriesLit) {
|
|
8446
|
+
if ((expr.arguments?.nodes.length ?? 0) > 0 && !entriesLit) {
|
|
7446
8447
|
lowerer.noLowering("new Map(entries)", expr, "supported seeds: an array literal of [key, value] pair literals, or a " +
|
|
7447
8448
|
"[K, V][]-typed tuple-array value, a matching collection or collection iterator, or null/undefined");
|
|
7448
8449
|
}
|
|
@@ -7450,10 +8451,10 @@ export function lowerNew(lowerer, expr) {
|
|
|
7450
8451
|
if (!entriesLit)
|
|
7451
8452
|
return { kind: "mapNew", type: mapped, loc };
|
|
7452
8453
|
const seed = entriesLit.map((pair) => ({
|
|
7453
|
-
key: lowerer.lowerCollectionKey(pair.elements[0], mapped.key),
|
|
8454
|
+
key: lowerer.lowerCollectionKey(pair.elements.nodes[0], mapped.key),
|
|
7454
8455
|
value: mapped.value.kind === "dyn"
|
|
7455
|
-
? lowerer.lowerCollectionKey(pair.elements[1], mapped.value)
|
|
7456
|
-
: 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),
|
|
7457
8458
|
}));
|
|
7458
8459
|
return { kind: "mapNew", seed, type: mapped, loc };
|
|
7459
8460
|
}
|
|
@@ -7466,8 +8467,8 @@ export function lowerNew(lowerer, expr) {
|
|
|
7466
8467
|
// config-cache shape: module init constructs the caches
|
|
7467
8468
|
// unconditionally; the format path never touches them. TypeScript
|
|
7468
8469
|
// keeps the compile fence.
|
|
7469
|
-
if (isJsSourceFile(
|
|
7470
|
-
(expr.arguments?.length ?? 0) === 0 &&
|
|
8470
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(expr)) &&
|
|
8471
|
+
(expr.arguments?.nodes.length ?? 0) === 0 &&
|
|
7471
8472
|
targs.length > 0 &&
|
|
7472
8473
|
targs.every((t) => (t.flags & ts.TypeFlags.Any) !== 0)) {
|
|
7473
8474
|
return { kind: "dynObjLit", type: DYN, loc };
|
|
@@ -7481,21 +8482,22 @@ export function lowerNew(lowerer, expr) {
|
|
|
7481
8482
|
}
|
|
7482
8483
|
if (targs[1]) {
|
|
7483
8484
|
lowerer.unsupported("SC1090", expr, `Map values of type '${lowerer.checker.typeToString(targs[1])}' ` +
|
|
7484
|
-
`(Map values must be number, string, boolean, records, class instances, ` +
|
|
8485
|
+
`(Map values must be number, string, boolean, records, class instances, functions, ` +
|
|
7485
8486
|
`typed arrays, arrays, promises, Maps, Sets, or supported unions and checked values)`);
|
|
7486
8487
|
}
|
|
7487
8488
|
lowerer.badType(expr, tsType);
|
|
7488
8489
|
}
|
|
7489
8490
|
// Weak containers share checked native key identities and lifetime hooks.
|
|
7490
|
-
if ((symbol
|
|
8491
|
+
if (((symbol !== null && ts.symbolName(symbol) === "WeakMap") ||
|
|
8492
|
+
(symbol !== null && ts.symbolName(symbol) === "WeakSet")) &&
|
|
7491
8493
|
lowerer.isStdlibSymbol(symbol)) {
|
|
7492
|
-
const args = expr.arguments ?? [];
|
|
8494
|
+
const args = expr.arguments?.nodes ?? [];
|
|
7493
8495
|
if (args.length > 1 || args.some(ts.isSpreadElement)) {
|
|
7494
|
-
lowerer.unsupported("SC1090", expr, `${symbol
|
|
8496
|
+
lowerer.unsupported("SC1090", expr, `${ts.symbolName(symbol)} construction with surplus or spread arguments`);
|
|
7495
8497
|
}
|
|
7496
8498
|
return {
|
|
7497
8499
|
kind: "libCall",
|
|
7498
|
-
fn: symbol
|
|
8500
|
+
fn: ts.symbolName(symbol) === "WeakMap" ? "weakMap.new" : "weakSet.new",
|
|
7499
8501
|
args: [args[0] ? lowerer.lowerExprExpecting(args[0], DYN) : dynUndefinedExpr(loc)],
|
|
7500
8502
|
type: DYN,
|
|
7501
8503
|
loc,
|
|
@@ -7503,27 +8505,27 @@ export function lowerNew(lowerer, expr) {
|
|
|
7503
8505
|
}
|
|
7504
8506
|
// `new Set<T>()`: construct + bulk add from supported values,
|
|
7505
8507
|
// including live collection cursors. Duplicates collapse in insertion order.
|
|
7506
|
-
if (
|
|
8508
|
+
if (ts.isIdentifier(identifier) && lowerer.isStdlibGlobal(identifier, "Set")) {
|
|
7507
8509
|
const tsType = lowerer.typeOf(expr);
|
|
7508
8510
|
let mapped = lowerer.mapTypeOf(tsType);
|
|
7509
8511
|
const fieldType = assignedThisFieldType(lowerer, expr);
|
|
7510
8512
|
if (mapped?.kind !== "set" && fieldType?.kind === "set")
|
|
7511
8513
|
mapped = fieldType;
|
|
7512
|
-
if (mapped?.kind === "set" && (expr.arguments?.length ?? 0) === 1) {
|
|
7513
|
-
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);
|
|
7514
8516
|
if (seeded)
|
|
7515
8517
|
return seeded;
|
|
7516
8518
|
}
|
|
7517
8519
|
if (!mapped &&
|
|
7518
|
-
isJsSourceFile(
|
|
7519
|
-
(expr.arguments?.length ?? 0) <= 1 &&
|
|
7520
|
-
!expr.arguments?.some(ts.isSpreadElement)) {
|
|
8520
|
+
isJsSourceFile(ts.getSourceFileOfNode(expr)) &&
|
|
8521
|
+
(expr.arguments?.nodes.length ?? 0) <= 1 &&
|
|
8522
|
+
!expr.arguments?.nodes.some(ts.isSpreadElement)) {
|
|
7521
8523
|
return {
|
|
7522
8524
|
kind: "libCall",
|
|
7523
8525
|
fn: "dyn.nativeSetNew",
|
|
7524
8526
|
args: [
|
|
7525
|
-
expr.arguments?.[0]
|
|
7526
|
-
? lowerer.lowerExprExpecting(expr.arguments[0], DYN)
|
|
8527
|
+
expr.arguments?.nodes[0]
|
|
8528
|
+
? lowerer.lowerExprExpecting(expr.arguments.nodes[0], DYN)
|
|
7527
8529
|
: dynUndefinedExpr(loc),
|
|
7528
8530
|
],
|
|
7529
8531
|
type: DYN,
|
|
@@ -7536,12 +8538,12 @@ export function lowerNew(lowerer, expr) {
|
|
|
7536
8538
|
// (interned strings — see the JS token stance in lower-exprs), so
|
|
7537
8539
|
// the honest construction is a Set of those scalars.
|
|
7538
8540
|
if (!mapped &&
|
|
7539
|
-
isJsSourceFile(
|
|
7540
|
-
(expr.arguments?.length ?? 0) === 1 &&
|
|
7541
|
-
ts.isArrayLiteralExpression(expr.arguments[0]) &&
|
|
7542
|
-
!expr.arguments[0].elements.some(ts.isSpreadElement)) {
|
|
7543
|
-
const lit = expr.arguments[0];
|
|
7544
|
-
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));
|
|
7545
8547
|
const first = elems[0];
|
|
7546
8548
|
if (first !== undefined &&
|
|
7547
8549
|
(first.type.kind === "string" || first.type.kind === "f64") &&
|
|
@@ -7551,7 +8553,7 @@ export function lowerNew(lowerer, expr) {
|
|
|
7551
8553
|
return { kind: "setNew", seed, type: setT, loc };
|
|
7552
8554
|
}
|
|
7553
8555
|
}
|
|
7554
|
-
if ((expr.arguments?.length ?? 0) > 0) {
|
|
8556
|
+
if ((expr.arguments?.nodes.length ?? 0) > 0) {
|
|
7555
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 " +
|
|
7556
8558
|
"supported key values seeds a Set");
|
|
7557
8559
|
}
|
|
@@ -7567,18 +8569,20 @@ export function lowerNew(lowerer, expr) {
|
|
|
7567
8569
|
// `new AsyncLocalStorage()` (node:async_hooks): a fresh store id —
|
|
7568
8570
|
// an f64 handle (type-mapper.ts), the Channel story. Construction options
|
|
7569
8571
|
// ({ defaultValue, name }) have no lowering yet.
|
|
7570
|
-
if (symbol
|
|
7571
|
-
|
|
8572
|
+
if (symbol !== null &&
|
|
8573
|
+
ts.symbolName(symbol) === "AsyncLocalStorage" &&
|
|
8574
|
+
lowerer.isStdlibSymbol(symbol)) {
|
|
8575
|
+
if ((expr.arguments?.nodes.length ?? 0) > 0) {
|
|
7572
8576
|
lowerer.noLowering("new AsyncLocalStorage(options)", expr, "the zero-argument constructor is the supported form (defaultValue/name options have no lowering yet)");
|
|
7573
8577
|
}
|
|
7574
8578
|
return { kind: "libCall", fn: "als.new", args: [], type: F64, loc };
|
|
7575
8579
|
}
|
|
7576
8580
|
// `new Promise<T>((resolve) => ...)`: the ambient Promise constructor.
|
|
7577
|
-
if (symbol
|
|
8581
|
+
if (symbol !== null && ts.symbolName(symbol) === "Promise" && lowerer.isStdlibSymbol(symbol)) {
|
|
7578
8582
|
const type = lowerer.irTypeOf(expr);
|
|
7579
8583
|
if (type.kind !== "promise")
|
|
7580
8584
|
lowerer.badType(expr, lowerer.typeOf(expr));
|
|
7581
|
-
const args = expr.arguments ?? [];
|
|
8585
|
+
const args = expr.arguments?.nodes ?? [];
|
|
7582
8586
|
if (args.length !== 1) {
|
|
7583
8587
|
lowerer.unsupported("SC1090", expr, "Promise construction without an executor");
|
|
7584
8588
|
}
|
|
@@ -7590,8 +8594,9 @@ export function lowerNew(lowerer, expr) {
|
|
|
7590
8594
|
const a0 = args[0];
|
|
7591
8595
|
if (ts.isIdentifier(a0) && a0.text === "setImmediate") {
|
|
7592
8596
|
const sym = lowerer.checker.getSymbolAtLocation(a0);
|
|
7593
|
-
const decls = sym ?
|
|
7594
|
-
if (decls.length > 0 &&
|
|
8597
|
+
const decls = sym ? sym.declarations : [];
|
|
8598
|
+
if (decls.length > 0 &&
|
|
8599
|
+
decls.every((d) => lowerer.isStdlibFile(ts.getSourceFileOfNode(d)))) {
|
|
7595
8600
|
// The settled value is the undefined dyn value — the result
|
|
7596
8601
|
// is promise<dyn> whatever T the checker inferred for the
|
|
7597
8602
|
// unusual executor (Promise<unknown> in the suite's shape).
|
|
@@ -7612,7 +8617,10 @@ export function lowerNew(lowerer, expr) {
|
|
|
7612
8617
|
// catch-side instanceof and the uncaught printer working). First
|
|
7613
8618
|
// settle wins, exactly JS: reject-after-resolve and double-reject
|
|
7614
8619
|
// are no-ops, and an executor throw after any settle is swallowed.
|
|
7615
|
-
|
|
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;
|
|
7616
8624
|
if (executor.type.kind !== "func")
|
|
7617
8625
|
lowerer.badType(args[0], lowerer.typeOf(args[0]));
|
|
7618
8626
|
if (executor.type.params.length > 1) {
|
|
@@ -7644,11 +8652,11 @@ export function lowerNew(lowerer, expr) {
|
|
|
7644
8652
|
// Every other new Buffer form keeps the fence below — the
|
|
7645
8653
|
// constructing forms would owe the deprecation warning.
|
|
7646
8654
|
if (expr.expression.text === "Buffer" &&
|
|
7647
|
-
expr.arguments?.length === 2 &&
|
|
7648
|
-
!expr.arguments.some(ts.isSpreadElement) &&
|
|
7649
|
-
lowerer.mapTypeOf(lowerer.typeOf(expr.arguments[0]))?.kind !== "string" &&
|
|
7650
|
-
lowerer.mapTypeOf(lowerer.typeOf(expr.arguments[1]))?.kind === "string") {
|
|
7651
|
-
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]);
|
|
7652
8660
|
if (first.kind === "unitLit" ||
|
|
7653
8661
|
first.type.kind === "dyn" ||
|
|
7654
8662
|
lowerer.dynConvertible(first.type)) {
|
|
@@ -7657,7 +8665,7 @@ export function lowerNew(lowerer, expr) {
|
|
|
7657
8665
|
// throw only via the ctor body's later reads — it does NOT
|
|
7658
8666
|
// observe it before throwing, so dropping it is exact for
|
|
7659
8667
|
// effect-free operands; effectful ones keep the fence.
|
|
7660
|
-
const enc = lowerer.lowerExpr(expr.arguments[1]);
|
|
8668
|
+
const enc = lowerer.lowerExpr(expr.arguments.nodes[1]);
|
|
7661
8669
|
if (enc.kind === "strLit" || isSafeToRepeat(enc)) {
|
|
7662
8670
|
return {
|
|
7663
8671
|
kind: "libCall",
|
|
@@ -7707,7 +8715,7 @@ export function lowerNew(lowerer, expr) {
|
|
|
7707
8715
|
return bi?.module === "crypto" && bi.member === "X509Certificate";
|
|
7708
8716
|
})());
|
|
7709
8717
|
if (isX509) {
|
|
7710
|
-
const args = expr.arguments ?? [];
|
|
8718
|
+
const args = expr.arguments?.nodes ?? [];
|
|
7711
8719
|
if (args.length !== 1) {
|
|
7712
8720
|
lowerer.noLowering("X509Certificate with this argument shape", expr, "the supported form is new X509Certificate(readFileSync(path))");
|
|
7713
8721
|
}
|
|
@@ -7800,29 +8808,55 @@ export function lowerNew(lowerer, expr) {
|
|
|
7800
8808
|
return lowerCheckedConstructor(lowerer, expr, callee);
|
|
7801
8809
|
if (callee.type.kind !== "classval")
|
|
7802
8810
|
lowerer.badType(expr.expression, lowerer.typeOf(expr.expression));
|
|
7803
|
-
lowerer.noteEdge(
|
|
8811
|
+
lowerer.noteEdge(classValueConstructor(info.def).fn);
|
|
7804
8812
|
// Every constructor a value in this slot can dispatch to is a
|
|
7805
8813
|
// descendant's — mark them reachable like a virtual edge.
|
|
7806
8814
|
const below = (c) => {
|
|
7807
8815
|
for (const s of c.subclasses) {
|
|
7808
|
-
lowerer.noteEdge(
|
|
8816
|
+
lowerer.noteEdge(classValueConstructor(s.def).fn);
|
|
7809
8817
|
below(s);
|
|
7810
8818
|
}
|
|
7811
8819
|
};
|
|
7812
8820
|
below(info);
|
|
7813
|
-
|
|
7814
|
-
|
|
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, {
|
|
7815
8835
|
kind: "newValue",
|
|
7816
8836
|
callee,
|
|
7817
8837
|
args,
|
|
7818
8838
|
type: { kind: "object", className: info.def.name },
|
|
7819
8839
|
loc,
|
|
7820
|
-
};
|
|
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;
|
|
7821
8854
|
}
|
|
7822
8855
|
if (calleeT?.kind === "union") {
|
|
7823
8856
|
const def = lowerer.unions.get(calleeT.unionId);
|
|
7824
8857
|
if (def?.arms.some((a) => a.kind === "classval")) {
|
|
7825
|
-
if (def.arms.every((arm) => arm.kind === "classval" ||
|
|
8858
|
+
if (def.arms.every((arm) => arm.kind === "classval" ||
|
|
8859
|
+
(isJsSourceFile(ts.getSourceFileOfNode(expr)) && isUnitType(arm))) &&
|
|
7826
8860
|
lowerer.dynConvertible(calleeT)) {
|
|
7827
8861
|
const callee = lowerer.lowerExprExpecting(expr.expression, DYN);
|
|
7828
8862
|
return lowerCheckedConstructor(lowerer, expr, callee);
|
|
@@ -7846,7 +8880,7 @@ export function lowerNew(lowerer, expr) {
|
|
|
7846
8880
|
if (ctorName !== null) {
|
|
7847
8881
|
const raw = lowerer.checker.getSymbolAtLocation(ctorName);
|
|
7848
8882
|
const sym = raw && raw.flags & ts.SymbolFlags.Alias ? lowerer.checker.getAliasedSymbol(raw) : raw;
|
|
7849
|
-
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;
|
|
7850
8884
|
if (hint !== undefined) {
|
|
7851
8885
|
lowerer.unsupported("SC1090", expr, hint);
|
|
7852
8886
|
}
|
|
@@ -7858,13 +8892,22 @@ export function lowerNew(lowerer, expr) {
|
|
|
7858
8892
|
(callee.type.kind === "dyn" ||
|
|
7859
8893
|
((callee.type.kind === "func" || callee.type.kind === "classval") &&
|
|
7860
8894
|
lowerer.dynConvertible(callee.type)))) {
|
|
7861
|
-
|
|
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);
|
|
7862
8905
|
}
|
|
7863
8906
|
lowerer.unsupported("SC1090", expr, "constructing values other than classes declared in the program");
|
|
7864
8907
|
}
|
|
7865
8908
|
function lowerCheckedConstructor(lowerer, expr, callee) {
|
|
7866
8909
|
const loc = locOf(expr);
|
|
7867
|
-
const args = expr.arguments ?? [];
|
|
8910
|
+
const args = expr.arguments?.nodes ?? [];
|
|
7868
8911
|
if (args.some(ts.isSpreadElement)) {
|
|
7869
8912
|
const packed = lowerer.completeArgs(args, [{ type: DYN, mode: "dynRest" }], loc, expr)[0];
|
|
7870
8913
|
return checkedClassConstructionPacked(lowerer, callee, packed, loc);
|