@scriptc/compiler 0.1.6 → 0.2.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 +73 -25
- package/ambient/scriptc-overrides.d.ts +10 -6
- package/ambient/scriptc.d.ts +28 -5
- package/dist/backend/build-cache.d.ts +1 -3
- package/dist/backend/build-cache.js +3 -22
- package/dist/backend/build-cache.js.map +1 -1
- package/dist/backend/cache-root.d.ts +3 -0
- package/dist/backend/cache-root.js +23 -0
- package/dist/backend/cache-root.js.map +1 -0
- package/dist/backend/cycle-analysis.d.ts +15 -0
- package/dist/backend/cycle-analysis.js +107 -0
- package/dist/backend/cycle-analysis.js.map +1 -0
- package/dist/backend/cycle-analysis.test.js +124 -0
- package/dist/backend/cycle-analysis.test.js.map +1 -0
- package/dist/backend/debug-symbols.d.ts +8 -0
- package/dist/backend/debug-symbols.js +52 -0
- package/dist/backend/debug-symbols.js.map +1 -0
- package/dist/backend/executable-features.d.ts +4 -0
- package/dist/backend/executable-features.js +42 -0
- package/dist/backend/executable-features.js.map +1 -0
- package/dist/backend/external-c.d.ts +5 -27
- package/dist/backend/external-c.js +5 -40
- package/dist/backend/external-c.js.map +1 -1
- package/dist/backend/ffi-callbacks.d.ts +2 -3
- package/dist/backend/ffi-callbacks.js +2 -3
- package/dist/backend/ffi-callbacks.js.map +1 -1
- package/dist/backend/library-identity-markers.d.ts +4 -9
- package/dist/backend/library-identity-markers.js +11 -49
- package/dist/backend/library-identity-markers.js.map +1 -1
- package/dist/backend/library-pack.d.ts +5 -0
- package/dist/backend/library-pack.js +123 -0
- package/dist/backend/library-pack.js.map +1 -0
- package/dist/backend/link-plan-core.d.ts +20 -0
- package/dist/backend/link-plan-core.js +18 -0
- package/dist/backend/link-plan-core.js.map +1 -0
- package/dist/backend/link-plan.d.ts +2 -1
- package/dist/backend/link-plan.js +18 -17
- package/dist/backend/link-plan.js.map +1 -1
- package/dist/backend/link-trace.d.ts +2 -0
- package/dist/backend/link-trace.js +24 -0
- package/dist/backend/link-trace.js.map +1 -0
- package/dist/backend/linker.js +9 -1
- package/dist/backend/linker.js.map +1 -1
- package/dist/backend/literals.d.ts +9 -0
- package/dist/backend/literals.js +35 -0
- package/dist/backend/literals.js.map +1 -0
- package/dist/backend/literals.test.d.ts +1 -0
- package/dist/backend/literals.test.js +53 -0
- package/dist/backend/literals.test.js.map +1 -0
- package/dist/backend/llvm/blocks.d.ts +4 -0
- package/dist/backend/llvm/blocks.js +25 -4
- package/dist/backend/llvm/blocks.js.map +1 -1
- package/dist/backend/llvm/blocks.test.d.ts +1 -0
- package/dist/backend/llvm/blocks.test.js +91 -0
- package/dist/backend/llvm/blocks.test.js.map +1 -0
- package/dist/backend/llvm/classes.d.ts +14 -8
- package/dist/backend/llvm/classes.js +70 -28
- package/dist/backend/llvm/classes.js.map +1 -1
- package/dist/backend/llvm/common.d.ts +5 -1
- package/dist/backend/llvm/common.js +45 -4
- package/dist/backend/llvm/common.js.map +1 -1
- package/dist/backend/llvm/debug-info.d.ts +32 -0
- package/dist/backend/llvm/debug-info.js +198 -0
- package/dist/backend/llvm/debug-info.js.map +1 -0
- package/dist/backend/llvm/debug-info.test.d.ts +1 -0
- package/dist/backend/llvm/debug-info.test.js +110 -0
- package/dist/backend/llvm/debug-info.test.js.map +1 -0
- package/dist/backend/llvm/dyn.d.ts +16 -2
- package/dist/backend/llvm/dyn.js +498 -175
- package/dist/backend/llvm/dyn.js.map +1 -1
- package/dist/backend/llvm/emitter.d.ts +598 -1
- package/dist/backend/llvm/emitter.js +739 -409
- package/dist/backend/llvm/emitter.js.map +1 -1
- package/dist/backend/llvm/emitter.test.d.ts +1 -0
- package/dist/backend/llvm/emitter.test.js +179 -0
- package/dist/backend/llvm/emitter.test.js.map +1 -0
- package/dist/backend/llvm/expr-async.js +23 -14
- package/dist/backend/llvm/expr-async.js.map +1 -1
- package/dist/backend/llvm/expr-bytes.d.ts +1 -1
- package/dist/backend/llvm/expr-bytes.js +32 -14
- package/dist/backend/llvm/expr-bytes.js.map +1 -1
- package/dist/backend/llvm/expr-callbacks.d.ts +1 -1
- package/dist/backend/llvm/expr-callbacks.js +25 -22
- package/dist/backend/llvm/expr-callbacks.js.map +1 -1
- package/dist/backend/llvm/expr-calls.js +136 -35
- package/dist/backend/llvm/expr-calls.js.map +1 -1
- package/dist/backend/llvm/expr-containers.d.ts +1 -1
- package/dist/backend/llvm/expr-containers.js +43 -14
- package/dist/backend/llvm/expr-containers.js.map +1 -1
- package/dist/backend/llvm/expr-context.d.ts +5 -260
- package/dist/backend/llvm/expr-control.js +9 -5
- package/dist/backend/llvm/expr-control.js.map +1 -1
- package/dist/backend/llvm/expr-dispatch.d.ts +1 -1
- package/dist/backend/llvm/expr-dispatch.js +2 -0
- package/dist/backend/llvm/expr-dispatch.js.map +1 -1
- package/dist/backend/llvm/expr-dynamic.js +72 -74
- package/dist/backend/llvm/expr-dynamic.js.map +1 -1
- package/dist/backend/llvm/expr-island.d.ts +1 -1
- package/dist/backend/llvm/expr-island.js +11 -7
- package/dist/backend/llvm/expr-island.js.map +1 -1
- package/dist/backend/llvm/expr-primitives.d.ts +1 -1
- package/dist/backend/llvm/expr-primitives.js +51 -30
- package/dist/backend/llvm/expr-primitives.js.map +1 -1
- package/dist/backend/llvm/expr-primitives.test.js +1 -1
- package/dist/backend/llvm/expr-records.d.ts +5 -1
- package/dist/backend/llvm/expr-records.js +43 -4
- package/dist/backend/llvm/expr-records.js.map +1 -1
- package/dist/backend/llvm/expr-stream-bridges.d.ts +4 -4
- package/dist/backend/llvm/expr-stream-bridges.js +102 -121
- package/dist/backend/llvm/expr-stream-bridges.js.map +1 -1
- package/dist/backend/llvm/expr-stream-bridges.test.d.ts +1 -0
- package/dist/backend/llvm/expr-stream-bridges.test.js +55 -0
- package/dist/backend/llvm/expr-stream-bridges.test.js.map +1 -0
- package/dist/backend/llvm/expr-stream-callbacks.d.ts +1 -1
- package/dist/backend/llvm/expr-stream-callbacks.js +12 -12
- package/dist/backend/llvm/expr-stream-callbacks.js.map +1 -1
- package/dist/backend/llvm/layouts.d.ts +19 -0
- package/dist/backend/llvm/layouts.js +12 -0
- package/dist/backend/llvm/layouts.js.map +1 -0
- package/dist/backend/llvm/lib-abi.d.ts +19 -0
- package/dist/backend/llvm/lib-abi.js +82 -0
- package/dist/backend/llvm/lib-abi.js.map +1 -0
- package/dist/backend/llvm/lib-connect.d.ts +2 -0
- package/dist/backend/llvm/lib-connect.js +51 -0
- package/dist/backend/llvm/lib-connect.js.map +1 -0
- package/dist/backend/llvm/lib-datagram.d.ts +2 -0
- package/dist/backend/llvm/lib-datagram.js +135 -0
- package/dist/backend/llvm/lib-datagram.js.map +1 -0
- package/dist/backend/llvm/lib-dispatch.js +50 -6
- package/dist/backend/llvm/lib-dispatch.js.map +1 -1
- package/dist/backend/llvm/lib-filesystem.js +59 -18
- package/dist/backend/llvm/lib-filesystem.js.map +1 -1
- package/dist/backend/llvm/lib-http2.d.ts +2 -0
- package/dist/backend/llvm/lib-http2.js +215 -0
- package/dist/backend/llvm/lib-http2.js.map +1 -0
- package/dist/backend/llvm/lib-lookup.d.ts +2 -0
- package/dist/backend/llvm/lib-lookup.js +39 -0
- package/dist/backend/llvm/lib-lookup.js.map +1 -0
- package/dist/backend/llvm/lib-network.js +25 -2
- package/dist/backend/llvm/lib-network.js.map +1 -1
- package/dist/backend/llvm/lib-process.js +21 -16
- package/dist/backend/llvm/lib-process.js.map +1 -1
- package/dist/backend/llvm/lib-shared.js +125 -1
- package/dist/backend/llvm/lib-shared.js.map +1 -1
- package/dist/backend/llvm/lib-stream.js +3 -2
- package/dist/backend/llvm/lib-stream.js.map +1 -1
- package/dist/backend/llvm/lib-test.d.ts +2 -0
- package/dist/backend/llvm/lib-test.js +34 -0
- package/dist/backend/llvm/lib-test.js.map +1 -0
- package/dist/backend/llvm/lib-tls.d.ts +2 -0
- package/dist/backend/llvm/lib-tls.js +82 -0
- package/dist/backend/llvm/lib-tls.js.map +1 -0
- package/dist/backend/llvm/shapes.d.ts +10 -9
- package/dist/backend/llvm/shapes.js +35 -130
- package/dist/backend/llvm/shapes.js.map +1 -1
- package/dist/backend/llvm/split.js +4 -1
- package/dist/backend/llvm/split.js.map +1 -1
- package/dist/backend/llvm/split.test.js +26 -1
- package/dist/backend/llvm/split.test.js.map +1 -1
- package/dist/backend/llvm/unsupported.d.ts +1 -0
- package/dist/backend/llvm/unsupported.js +1 -2
- package/dist/backend/llvm/unsupported.js.map +1 -1
- package/dist/backend/llvm/walkers.js +1 -7
- package/dist/backend/llvm/walkers.js.map +1 -1
- package/dist/backend/mangle.d.ts +2 -2
- package/dist/backend/mangle.js +16 -5
- package/dist/backend/mangle.js.map +1 -1
- package/dist/backend/{c/may-throw.d.ts → may-throw.d.ts} +1 -1
- package/dist/backend/{c/may-throw.js → may-throw.js} +51 -46
- package/dist/backend/may-throw.js.map +1 -0
- package/dist/backend/may-throw.test.d.ts +1 -0
- package/dist/backend/may-throw.test.js +58 -0
- package/dist/backend/may-throw.test.js.map +1 -0
- package/dist/backend/native-codegen-core.d.ts +22 -0
- package/dist/backend/native-codegen-core.js +44 -0
- package/dist/backend/native-codegen-core.js.map +1 -0
- package/dist/backend/native-codegen.d.ts +3 -19
- package/dist/backend/native-codegen.js +5 -44
- package/dist/backend/native-codegen.js.map +1 -1
- package/dist/backend/native-codegen.test.js +2 -2
- package/dist/backend/native-codegen.test.js.map +1 -1
- package/dist/backend/native-link-info-core.d.ts +94 -0
- package/dist/backend/native-link-info-core.js +62 -0
- package/dist/backend/native-link-info-core.js.map +1 -0
- package/dist/backend/native-link-info.d.ts +3 -88
- package/dist/backend/native-link-info.js +12 -243
- package/dist/backend/native-link-info.js.map +1 -1
- package/dist/backend/native-link-info.test.js +41 -146
- package/dist/backend/native-link-info.test.js.map +1 -1
- package/dist/backend/native-toolchain.d.ts +10 -25
- package/dist/backend/native-toolchain.js +89 -219
- package/dist/backend/native-toolchain.js.map +1 -1
- package/dist/backend/native-toolchain.test.js +15 -5
- package/dist/backend/native-toolchain.test.js.map +1 -1
- package/dist/backend/native-tools.d.ts +24 -0
- package/dist/backend/native-tools.js +33 -0
- package/dist/backend/native-tools.js.map +1 -0
- package/dist/backend/object-localize.js +19 -8
- package/dist/backend/object-localize.js.map +1 -1
- package/dist/backend/object-localize.test.js +22 -0
- package/dist/backend/object-localize.test.js.map +1 -1
- package/dist/backend/runtime-abi.d.ts +2 -2
- package/dist/backend/runtime-abi.js +2 -2
- package/dist/backend/runtime-pack-core.d.ts +101 -0
- package/dist/backend/runtime-pack-core.js +172 -0
- package/dist/backend/runtime-pack-core.js.map +1 -0
- package/dist/backend/runtime-pack-native.d.ts +21 -0
- package/dist/backend/runtime-pack-native.js +70 -0
- package/dist/backend/runtime-pack-native.js.map +1 -0
- package/dist/backend/runtime-pack-targets.test.js +1 -1
- package/dist/backend/runtime-pack.d.ts +3 -83
- package/dist/backend/runtime-pack.js +8 -151
- package/dist/backend/runtime-pack.js.map +1 -1
- package/dist/backend/runtime-pack.test.js +24 -1
- package/dist/backend/runtime-pack.test.js.map +1 -1
- package/dist/backend/source-locations.d.ts +12 -0
- package/dist/backend/source-locations.js +32 -0
- package/dist/backend/source-locations.js.map +1 -0
- package/dist/backend/source-locations.test.d.ts +1 -0
- package/dist/backend/source-locations.test.js +16 -0
- package/dist/backend/source-locations.test.js.map +1 -0
- package/dist/backend/target-diagnostics.d.ts +22 -0
- package/dist/backend/target-diagnostics.js +108 -0
- package/dist/backend/target-diagnostics.js.map +1 -0
- package/dist/backend/target-platform.d.ts +15 -0
- package/dist/backend/target-platform.js +72 -0
- package/dist/backend/target-platform.js.map +1 -0
- package/dist/backend/targets.d.ts +13 -4
- package/dist/backend/targets.js +95 -30
- package/dist/backend/targets.js.map +1 -1
- package/dist/backend/targets.test.js +65 -4
- package/dist/backend/targets.test.js.map +1 -1
- package/dist/backend/toolchain-environment.d.ts +6 -0
- package/dist/backend/toolchain-environment.js +99 -0
- package/dist/backend/toolchain-environment.js.map +1 -0
- package/dist/backend/vendor-archives.d.ts +1 -9
- package/dist/backend/vendor-archives.js +2 -9
- package/dist/backend/vendor-archives.js.map +1 -1
- package/dist/backend/vendor-inputs.d.ts +9 -0
- package/dist/backend/vendor-inputs.js +10 -0
- package/dist/backend/vendor-inputs.js.map +1 -0
- package/dist/backend/warm-cache.d.ts +3 -0
- package/dist/backend/warm-cache.js +41 -0
- package/dist/backend/warm-cache.js.map +1 -0
- package/dist/cli/command.d.ts +3 -0
- package/dist/cli/command.js +328 -0
- package/dist/cli/command.js.map +1 -0
- package/dist/cli/host.d.ts +24 -0
- package/dist/cli/host.js +2 -0
- package/dist/cli/host.js.map +1 -0
- package/dist/cli/output-options.d.ts +26 -0
- package/dist/cli/output-options.js +60 -0
- package/dist/cli/output-options.js.map +1 -0
- package/dist/cli/paths.d.ts +12 -0
- package/dist/cli/paths.js +42 -0
- package/dist/cli/paths.js.map +1 -0
- package/dist/cli/usage.d.ts +74 -0
- package/dist/cli/usage.js +86 -0
- package/dist/cli/usage.js.map +1 -0
- package/dist/cli/wasi-paths.d.ts +8 -0
- package/dist/cli/wasi-paths.js +41 -0
- package/dist/cli/wasi-paths.js.map +1 -0
- package/dist/cli/wasi-runner.d.ts +2 -0
- package/dist/cli/wasi-runner.js +28 -0
- package/dist/cli/wasi-runner.js.map +1 -0
- package/dist/compat/fetch-profile.js +3 -3
- package/dist/compat/fetch-profile.js.map +1 -1
- package/dist/compile-types.d.ts +162 -0
- package/dist/compile-types.js +2 -0
- package/dist/compile-types.js.map +1 -0
- package/dist/coverage/report.js +11 -5
- package/dist/coverage/report.js.map +1 -1
- package/dist/coverage/surface-manifest.js +5 -2
- package/dist/coverage/surface-manifest.js.map +1 -1
- package/dist/diagnostics/diagnostic.d.ts +4 -0
- package/dist/diagnostics/diagnostic.js +15 -3
- package/dist/diagnostics/diagnostic.js.map +1 -1
- package/dist/executable/executable-cache.d.ts +3 -4
- package/dist/executable/executable-cache.js +33 -10
- package/dist/executable/executable-cache.js.map +1 -1
- package/dist/executable/executable-cache.test.js +38 -16
- package/dist/executable/executable-cache.test.js.map +1 -1
- package/dist/executable/prepare.d.ts +14 -0
- package/dist/executable/prepare.js +66 -0
- package/dist/executable/prepare.js.map +1 -0
- package/dist/ffi/ffi-manifest.d.ts +11 -4
- package/dist/ffi/ffi-manifest.js +170 -58
- package/dist/ffi/ffi-manifest.js.map +1 -1
- package/dist/ffi/ffi-manifest.test.d.ts +1 -0
- package/dist/ffi/ffi-manifest.test.js +111 -0
- package/dist/ffi/ffi-manifest.test.js.map +1 -0
- package/dist/format-integer.d.ts +3 -0
- package/dist/format-integer.js +14 -0
- package/dist/format-integer.js.map +1 -0
- package/dist/frontend/analysis.d.ts +5 -0
- package/dist/frontend/analysis.js +88 -0
- package/dist/frontend/analysis.js.map +1 -0
- package/dist/frontend/arguments-usage.d.ts +4 -0
- package/dist/frontend/arguments-usage.js +40 -0
- package/dist/frontend/arguments-usage.js.map +1 -0
- package/dist/frontend/binding-source.d.ts +4 -0
- package/dist/frontend/binding-source.js +18 -0
- package/dist/frontend/binding-source.js.map +1 -0
- package/dist/frontend/builtin-modules.d.ts +1 -1
- package/dist/frontend/builtin-modules.js +1 -1
- package/dist/frontend/builtin-modules.js.map +1 -1
- package/dist/frontend/cjs-lexer.d.ts +4 -25
- package/dist/frontend/cjs-lexer.js +6 -806
- package/dist/frontend/cjs-lexer.js.map +1 -1
- package/dist/frontend/cjs-resolve.d.ts +5 -0
- package/dist/frontend/cjs-resolve.js +429 -0
- package/dist/frontend/cjs-resolve.js.map +1 -0
- package/dist/frontend/cjs-syntax.d.ts +26 -0
- package/dist/frontend/cjs-syntax.js +806 -0
- package/dist/frontend/cjs-syntax.js.map +1 -0
- package/dist/frontend/comptime-node.d.ts +4 -0
- package/dist/frontend/comptime-node.js +16 -0
- package/dist/frontend/comptime-node.js.map +1 -0
- package/dist/frontend/comptime-node.test.d.ts +1 -0
- package/dist/frontend/comptime-node.test.js +37 -0
- package/dist/frontend/comptime-node.test.js.map +1 -0
- package/dist/frontend/dts-paths.d.ts +3 -4
- package/dist/frontend/dts-paths.js +15 -8
- package/dist/frontend/dts-paths.js.map +1 -1
- package/dist/frontend/fork-target.js +2 -2
- package/dist/frontend/fork-target.js.map +1 -1
- package/dist/frontend/helper-tokens.d.ts +1 -0
- package/dist/frontend/helper-tokens.js +147 -0
- package/dist/frontend/helper-tokens.js.map +1 -0
- package/dist/frontend/helper-tokens.test.d.ts +1 -0
- package/dist/frontend/helper-tokens.test.js +35 -0
- package/dist/frontend/helper-tokens.test.js.map +1 -0
- package/dist/frontend/inferred-js-diagnostics.d.ts +5 -0
- package/dist/frontend/inferred-js-diagnostics.js +69 -0
- package/dist/frontend/inferred-js-diagnostics.js.map +1 -0
- package/dist/frontend/inferred-js-diagnostics.test.d.ts +1 -0
- package/dist/frontend/inferred-js-diagnostics.test.js +58 -0
- package/dist/frontend/inferred-js-diagnostics.test.js.map +1 -0
- package/dist/frontend/input-tracker.d.ts +5 -2
- package/dist/frontend/input-tracker.js +24 -3
- package/dist/frontend/input-tracker.js.map +1 -1
- package/dist/frontend/input-tracker.test.js +23 -0
- package/dist/frontend/input-tracker.test.js.map +1 -1
- package/dist/frontend/lib-contract.js +32 -24
- package/dist/frontend/lib-contract.js.map +1 -1
- package/dist/frontend/literal-values.d.ts +4 -0
- package/dist/frontend/literal-values.js +21 -0
- package/dist/frontend/literal-values.js.map +1 -0
- package/dist/frontend/literal-values.test.d.ts +1 -0
- package/dist/frontend/literal-values.test.js +91 -0
- package/dist/frontend/literal-values.test.js.map +1 -0
- package/dist/frontend/lowering/abstract-equality.d.ts +1 -1
- package/dist/frontend/lowering/abstract-equality.js +3 -0
- package/dist/frontend/lowering/abstract-equality.js.map +1 -1
- package/dist/frontend/lowering/array-indexed-mutation.js +11 -6
- package/dist/frontend/lowering/array-indexed-mutation.js.map +1 -1
- package/dist/frontend/lowering/array-values.d.ts +4 -1
- package/dist/frontend/lowering/array-values.js +43 -1
- package/dist/frontend/lowering/array-values.js.map +1 -1
- package/dist/frontend/lowering/callback-arg.js +1 -0
- package/dist/frontend/lowering/callback-arg.js.map +1 -1
- package/dist/frontend/lowering/class-callbacks.d.ts +12 -0
- package/dist/frontend/lowering/class-callbacks.js +63 -0
- package/dist/frontend/lowering/class-callbacks.js.map +1 -0
- package/dist/frontend/lowering/class-descriptors.d.ts +9 -0
- package/dist/frontend/lowering/class-descriptors.js +73 -0
- package/dist/frontend/lowering/class-descriptors.js.map +1 -0
- package/dist/frontend/lowering/class-dynamic-dispatch.d.ts +41 -0
- package/dist/frontend/lowering/class-dynamic-dispatch.js +803 -0
- package/dist/frontend/lowering/class-dynamic-dispatch.js.map +1 -0
- package/dist/frontend/lowering/class-dynamic-dispatch.test.d.ts +1 -0
- package/dist/frontend/lowering/class-dynamic-dispatch.test.js +92 -0
- package/dist/frontend/lowering/class-dynamic-dispatch.test.js.map +1 -0
- package/dist/frontend/lowering/class-instance-constructor.d.ts +7 -0
- package/dist/frontend/lowering/class-instance-constructor.js +64 -0
- package/dist/frontend/lowering/class-instance-constructor.js.map +1 -0
- package/dist/frontend/lowering/class-method-values.d.ts +10 -0
- package/dist/frontend/lowering/class-method-values.js +170 -0
- package/dist/frontend/lowering/class-method-values.js.map +1 -0
- package/dist/frontend/lowering/class-prototypes.d.ts +16 -0
- package/dist/frontend/lowering/class-prototypes.js +134 -0
- package/dist/frontend/lowering/class-prototypes.js.map +1 -0
- package/dist/frontend/lowering/class-static-data.d.ts +6 -0
- package/dist/frontend/lowering/class-static-data.js +56 -0
- package/dist/frontend/lowering/class-static-data.js.map +1 -0
- package/dist/frontend/lowering/containers/buffer-numeric-methods.d.ts +4 -0
- package/dist/frontend/lowering/containers/buffer-numeric-methods.js +26 -0
- package/dist/frontend/lowering/containers/buffer-numeric-methods.js.map +1 -0
- package/dist/frontend/lowering/containers/bytes.d.ts +11 -7
- package/dist/frontend/lowering/containers/bytes.js +164 -155
- package/dist/frontend/lowering/containers/bytes.js.map +1 -1
- package/dist/frontend/lowering/containers/string-and-regexp.d.ts +2 -2
- package/dist/frontend/lowering/containers/string-and-regexp.js +39 -16
- package/dist/frontend/lowering/containers/string-and-regexp.js.map +1 -1
- package/dist/frontend/lowering/containers/string-replacement.d.ts +7 -0
- package/dist/frontend/lowering/containers/string-replacement.js +217 -0
- package/dist/frontend/lowering/containers/string-replacement.js.map +1 -0
- package/dist/frontend/lowering/error-methods.d.ts +11 -0
- package/dist/frontend/lowering/error-methods.js +78 -0
- package/dist/frontend/lowering/error-methods.js.map +1 -0
- package/dist/frontend/lowering/expressions/global-symbols.d.ts +6 -0
- package/dist/frontend/lowering/expressions/global-symbols.js +11 -0
- package/dist/frontend/lowering/expressions/global-symbols.js.map +1 -0
- package/dist/frontend/lowering/expressions/native-proxy.d.ts +7 -0
- package/dist/frontend/lowering/expressions/native-proxy.js +49 -0
- package/dist/frontend/lowering/expressions/native-proxy.js.map +1 -0
- package/dist/frontend/lowering/expressions/nullish-assignment.d.ts +6 -0
- package/dist/frontend/lowering/expressions/nullish-assignment.js +124 -0
- package/dist/frontend/lowering/expressions/nullish-assignment.js.map +1 -0
- package/dist/frontend/lowering/expressions/object-literals.d.ts +8 -8
- package/dist/frontend/lowering/expressions/object-literals.js +485 -185
- package/dist/frontend/lowering/expressions/object-literals.js.map +1 -1
- package/dist/frontend/lowering/expressions/optional-chains.d.ts +5 -6
- package/dist/frontend/lowering/expressions/optional-chains.js +27 -14
- package/dist/frontend/lowering/expressions/optional-chains.js.map +1 -1
- package/dist/frontend/lowering/expressions/try-lower-expression.js +1 -0
- package/dist/frontend/lowering/expressions/try-lower-expression.js.map +1 -1
- package/dist/frontend/lowering/expressions/union-field-write.d.ts +8 -0
- package/dist/frontend/lowering/expressions/union-field-write.js +71 -0
- package/dist/frontend/lowering/expressions/union-field-write.js.map +1 -0
- package/dist/frontend/lowering/function-context.d.ts +93 -0
- package/dist/frontend/lowering/function-context.js +103 -0
- package/dist/frontend/lowering/function-context.js.map +1 -0
- package/dist/frontend/lowering/generator-delegation.d.ts +7 -0
- package/dist/frontend/lowering/generator-delegation.js +85 -0
- package/dist/frontend/lowering/generator-delegation.js.map +1 -0
- package/dist/frontend/lowering/generator-dynamic-dispatch.d.ts +10 -0
- package/dist/frontend/lowering/generator-dynamic-dispatch.js +105 -0
- package/dist/frontend/lowering/generator-dynamic-dispatch.js.map +1 -0
- package/dist/frontend/lowering/lib-boundary.d.ts +2 -1
- package/dist/frontend/lowering/lib-boundary.js +59 -20
- package/dist/frontend/lowering/lib-boundary.js.map +1 -1
- package/dist/frontend/lowering/lib-boundary.test.d.ts +1 -0
- package/dist/frontend/lowering/lib-boundary.test.js +45 -0
- package/dist/frontend/lowering/lib-boundary.test.js.map +1 -0
- package/dist/frontend/lowering/lower-array-sort.d.ts +1 -1
- package/dist/frontend/lowering/lower-assert.d.ts +1 -1
- package/dist/frontend/lowering/lower-assert.js.map +1 -1
- package/dist/frontend/lowering/lower-async-iteration.d.ts +1 -1
- package/dist/frontend/lowering/lower-async-iteration.js.map +1 -1
- package/dist/frontend/lowering/lower-builtin-values.d.ts +12 -0
- package/dist/frontend/lowering/lower-builtin-values.js +139 -0
- package/dist/frontend/lowering/lower-builtin-values.js.map +1 -0
- package/dist/frontend/lowering/lower-builtins.d.ts +27 -41
- package/dist/frontend/lowering/lower-builtins.js +553 -346
- package/dist/frontend/lowering/lower-builtins.js.map +1 -1
- package/dist/frontend/lowering/lower-calls.d.ts +22 -26
- package/dist/frontend/lowering/lower-calls.js +1373 -380
- package/dist/frontend/lowering/lower-calls.js.map +1 -1
- package/dist/frontend/lowering/lower-classes.d.ts +83 -45
- package/dist/frontend/lowering/lower-classes.js +952 -339
- package/dist/frontend/lowering/lower-classes.js.map +1 -1
- package/dist/frontend/lowering/lower-comptime.d.ts +1 -1
- package/dist/frontend/lowering/lower-comptime.js +23 -32
- package/dist/frontend/lowering/lower-comptime.js.map +1 -1
- package/dist/frontend/lowering/lower-containers.d.ts +27 -32
- package/dist/frontend/lowering/lower-containers.js +796 -151
- package/dist/frontend/lowering/lower-containers.js.map +1 -1
- package/dist/frontend/lowering/lower-dgram.d.ts +1 -1
- package/dist/frontend/lowering/lower-dgram.js.map +1 -1
- package/dist/frontend/lowering/lower-enums.d.ts +1 -1
- package/dist/frontend/lowering/lower-enums.js.map +1 -1
- package/dist/frontend/lowering/lower-event-emitter.d.ts +30 -1
- package/dist/frontend/lowering/lower-event-emitter.js +58 -26
- package/dist/frontend/lowering/lower-event-emitter.js.map +1 -1
- package/dist/frontend/lowering/lower-expando.d.ts +7 -1
- package/dist/frontend/lowering/lower-expando.js +14 -6
- package/dist/frontend/lowering/lower-expando.js.map +1 -1
- package/dist/frontend/lowering/lower-exprs.d.ts +35 -11
- package/dist/frontend/lowering/lower-exprs.js +1785 -790
- package/dist/frontend/lowering/lower-exprs.js.map +1 -1
- package/dist/frontend/lowering/lower-generators.d.ts +2 -5
- package/dist/frontend/lowering/lower-generators.js +77 -46
- package/dist/frontend/lowering/lower-generators.js.map +1 -1
- package/dist/frontend/lowering/lower-global-value.d.ts +7 -0
- package/dist/frontend/lowering/lower-global-value.js +17 -0
- package/dist/frontend/lowering/lower-global-value.js.map +1 -0
- package/dist/frontend/lowering/lower-inspect.d.ts +1 -1
- package/dist/frontend/lowering/lower-inspect.js +17 -8
- package/dist/frontend/lowering/lower-inspect.js.map +1 -1
- package/dist/frontend/lowering/lower-island.d.ts +5 -8
- package/dist/frontend/lowering/lower-island.js +34 -23
- package/dist/frontend/lowering/lower-island.js.map +1 -1
- package/dist/frontend/lowering/lower-mixins.d.ts +2 -2
- package/dist/frontend/lowering/lower-mixins.js +5 -3
- package/dist/frontend/lowering/lower-mixins.js.map +1 -1
- package/dist/frontend/lowering/lower-modules.d.ts +1 -1
- package/dist/frontend/lowering/lower-modules.js +252 -38
- package/dist/frontend/lowering/lower-modules.js.map +1 -1
- package/dist/frontend/lowering/lower-namespaces.d.ts +1 -1
- package/dist/frontend/lowering/lower-namespaces.js.map +1 -1
- package/dist/frontend/lowering/lower-node-module.d.ts +1 -1
- package/dist/frontend/lowering/lower-node-module.js +13 -10
- package/dist/frontend/lowering/lower-node-module.js.map +1 -1
- package/dist/frontend/lowering/lower-server.d.ts +1 -1
- package/dist/frontend/lowering/lower-server.js +6 -10
- package/dist/frontend/lowering/lower-server.js.map +1 -1
- package/dist/frontend/lowering/lower-stmts.d.ts +10 -14
- package/dist/frontend/lowering/lower-stmts.js +731 -532
- package/dist/frontend/lowering/lower-stmts.js.map +1 -1
- package/dist/frontend/lowering/lower-stream.d.ts +1 -1
- package/dist/frontend/lowering/lower-stream.js +19 -10
- package/dist/frontend/lowering/lower-stream.js.map +1 -1
- package/dist/frontend/lowering/lower-test.d.ts +1 -1
- package/dist/frontend/lowering/lower-test.js.map +1 -1
- package/dist/frontend/lowering/lower-url.d.ts +6 -0
- package/dist/frontend/lowering/lower-url.js +77 -0
- package/dist/frontend/lowering/lower-url.js.map +1 -0
- package/dist/frontend/lowering/lowerer.d.ts +113 -189
- package/dist/frontend/lowering/lowerer.js +1033 -663
- package/dist/frontend/lowering/lowerer.js.map +1 -1
- package/dist/frontend/lowering/lowerer.test.d.ts +1 -0
- package/dist/frontend/lowering/lowerer.test.js +26 -0
- package/dist/frontend/lowering/lowerer.test.js.map +1 -0
- package/dist/frontend/lowering/native-ffi.d.ts +5 -0
- package/dist/frontend/lowering/native-ffi.js +40 -0
- package/dist/frontend/lowering/native-ffi.js.map +1 -0
- package/dist/frontend/lowering/object-enumeration-receiver.d.ts +7 -0
- package/dist/frontend/lowering/object-enumeration-receiver.js +33 -0
- package/dist/frontend/lowering/object-enumeration-receiver.js.map +1 -0
- package/dist/frontend/lowering/object-factory-new.d.ts +8 -0
- package/dist/frontend/lowering/object-factory-new.js +68 -0
- package/dist/frontend/lowering/object-factory-new.js.map +1 -0
- package/dist/frontend/lowering/optional-arguments.js +6 -1
- package/dist/frontend/lowering/optional-arguments.js.map +1 -1
- package/dist/frontend/lowering/pairs-snapshot.js +2 -1
- package/dist/frontend/lowering/pairs-snapshot.js.map +1 -1
- package/dist/frontend/lowering/runtime-optional-locals.d.ts +14 -0
- package/dist/frontend/lowering/runtime-optional-locals.js +41 -0
- package/dist/frontend/lowering/runtime-optional-locals.js.map +1 -0
- package/dist/frontend/lowering/runtime-optional-locals.test.d.ts +1 -0
- package/dist/frontend/lowering/runtime-optional-locals.test.js +85 -0
- package/dist/frontend/lowering/runtime-optional-locals.test.js.map +1 -0
- package/dist/frontend/lowering/sanitize-class-types.d.ts +8 -0
- package/dist/frontend/lowering/sanitize-class-types.js +79 -0
- package/dist/frontend/lowering/sanitize-class-types.js.map +1 -0
- package/dist/frontend/lowering/sanitize-class-types.test.d.ts +1 -0
- package/dist/frontend/lowering/sanitize-class-types.test.js +60 -0
- package/dist/frontend/lowering/sanitize-class-types.test.js.map +1 -0
- package/dist/frontend/lowering/static-this.d.ts +5 -1
- package/dist/frontend/lowering/static-this.js +28 -2
- package/dist/frontend/lowering/static-this.js.map +1 -1
- package/dist/frontend/lowering/string-index.d.ts +7 -0
- package/dist/frontend/lowering/string-index.js +39 -0
- package/dist/frontend/lowering/string-index.js.map +1 -0
- package/dist/frontend/lowering/surfaces.d.ts +9 -4
- package/dist/frontend/lowering/surfaces.js +98 -35
- package/dist/frontend/lowering/surfaces.js.map +1 -1
- package/dist/frontend/lowering/symbol-fields.d.ts +22 -0
- package/dist/frontend/lowering/symbol-fields.js +183 -0
- package/dist/frontend/lowering/symbol-fields.js.map +1 -0
- package/dist/frontend/lowering/symbol-methods.d.ts +7 -0
- package/dist/frontend/lowering/symbol-methods.js +30 -0
- package/dist/frontend/lowering/symbol-methods.js.map +1 -0
- package/dist/frontend/lowering/text-decoder-encoding.d.ts +10 -0
- package/dist/frontend/lowering/text-decoder-encoding.js +77 -0
- package/dist/frontend/lowering/text-decoder-encoding.js.map +1 -0
- package/dist/frontend/lowering/text-decoder-encoding.test.d.ts +1 -0
- package/dist/frontend/lowering/text-decoder-encoding.test.js +38 -0
- package/dist/frontend/lowering/text-decoder-encoding.test.js.map +1 -0
- package/dist/frontend/lowering/union-narrow.d.ts +9 -0
- package/dist/frontend/lowering/union-narrow.js +59 -0
- package/dist/frontend/lowering/union-narrow.js.map +1 -0
- package/dist/frontend/lowering/union-narrow.test.d.ts +1 -0
- package/dist/frontend/lowering/union-narrow.test.js +72 -0
- package/dist/frontend/lowering/union-narrow.test.js.map +1 -0
- package/dist/frontend/lowering/union-retag.d.ts +43 -0
- package/dist/frontend/lowering/union-retag.js +259 -0
- package/dist/frontend/lowering/union-retag.js.map +1 -0
- package/dist/frontend/lowering/union-retag.test.d.ts +1 -0
- package/dist/frontend/lowering/union-retag.test.js +405 -0
- package/dist/frontend/lowering/union-retag.test.js.map +1 -0
- package/dist/frontend/lowering/unregistered-class-types.d.ts +14 -0
- package/dist/frontend/lowering/unregistered-class-types.js +94 -0
- package/dist/frontend/lowering/unregistered-class-types.js.map +1 -0
- package/dist/frontend/lowering/unregistered-class-types.test.d.ts +1 -0
- package/dist/frontend/lowering/unregistered-class-types.test.js +65 -0
- package/dist/frontend/lowering/unregistered-class-types.test.js.map +1 -0
- package/dist/frontend/lowering/width-lift.d.ts +40 -0
- package/dist/frontend/lowering/width-lift.js +2 -0
- package/dist/frontend/lowering/width-lift.js.map +1 -0
- package/dist/frontend/module-syntax.d.ts +58 -0
- package/dist/frontend/module-syntax.js +123 -0
- package/dist/frontend/module-syntax.js.map +1 -0
- package/dist/frontend/module-syntax.test.d.ts +1 -0
- package/dist/frontend/module-syntax.test.js +78 -0
- package/dist/frontend/module-syntax.test.js.map +1 -0
- package/dist/frontend/npm-fetch-analysis.d.ts +17 -0
- package/dist/frontend/npm-fetch-analysis.js +100 -0
- package/dist/frontend/npm-fetch-analysis.js.map +1 -0
- package/dist/frontend/npm-fetch-analysis.test.d.ts +1 -0
- package/dist/frontend/npm-fetch-analysis.test.js +107 -0
- package/dist/frontend/npm-fetch-analysis.test.js.map +1 -0
- package/dist/frontend/npm-fetch-node.d.ts +2 -0
- package/dist/frontend/npm-fetch-node.js +12 -0
- package/dist/frontend/npm-fetch-node.js.map +1 -0
- package/dist/frontend/npm-fetch-syntax.d.ts +6 -0
- package/dist/frontend/npm-fetch-syntax.js +207 -0
- package/dist/frontend/npm-fetch-syntax.js.map +1 -0
- package/dist/frontend/npm-node.d.ts +10 -0
- package/dist/frontend/npm-node.js +14 -0
- package/dist/frontend/npm-node.js.map +1 -0
- package/dist/frontend/npm-static-bundled-cjs.d.ts +8 -0
- package/dist/frontend/npm-static-bundled-cjs.js +236 -0
- package/dist/frontend/npm-static-bundled-cjs.js.map +1 -0
- package/dist/frontend/npm-static-bundled-cjs.test.d.ts +1 -0
- package/dist/frontend/npm-static-bundled-cjs.test.js +69 -0
- package/dist/frontend/npm-static-bundled-cjs.test.js.map +1 -0
- package/dist/frontend/npm-static-declaration-syntax.d.ts +57 -0
- package/dist/frontend/npm-static-declaration-syntax.js +944 -0
- package/dist/frontend/npm-static-declaration-syntax.js.map +1 -0
- package/dist/frontend/npm-static-declarations.d.ts +11 -39
- package/dist/frontend/npm-static-declarations.js +22 -561
- package/dist/frontend/npm-static-declarations.js.map +1 -1
- package/dist/frontend/npm-static-declarations.test.js +245 -6
- package/dist/frontend/npm-static-declarations.test.js.map +1 -1
- package/dist/frontend/npm-static-prune.d.ts +1 -1
- package/dist/frontend/npm-static-prune.js +5 -4
- package/dist/frontend/npm-static-prune.js.map +1 -1
- package/dist/frontend/npm-static-prune.test.js +1 -1
- package/dist/frontend/npm-static-prune.test.js.map +1 -1
- package/dist/frontend/npm-static-rewrite-host.d.ts +4 -0
- package/dist/frontend/npm-static-rewrite-host.js +179 -0
- package/dist/frontend/npm-static-rewrite-host.js.map +1 -0
- package/dist/frontend/npm-static-rewrite-syntax.d.ts +16 -0
- package/dist/frontend/npm-static-rewrite-syntax.js +905 -0
- package/dist/frontend/npm-static-rewrite-syntax.js.map +1 -0
- package/dist/frontend/npm-static-rewrite.d.ts +0 -5
- package/dist/frontend/npm-static-rewrite.js +2 -1079
- package/dist/frontend/npm-static-rewrite.js.map +1 -1
- package/dist/frontend/npm-static-subtyping.d.ts +5 -0
- package/dist/frontend/npm-static-subtyping.js +55 -0
- package/dist/frontend/npm-static-subtyping.js.map +1 -0
- package/dist/frontend/npm-static-subtyping.test.d.ts +1 -0
- package/dist/frontend/npm-static-subtyping.test.js +58 -0
- package/dist/frontend/npm-static-subtyping.test.js.map +1 -0
- package/dist/frontend/npm-static.d.ts +7 -15
- package/dist/frontend/npm-static.js +19 -28
- package/dist/frontend/npm-static.js.map +1 -1
- package/dist/frontend/npm.d.ts +8 -69
- package/dist/frontend/npm.js +21 -361
- package/dist/frontend/npm.js.map +1 -1
- package/dist/frontend/npm.test.js +2 -2
- package/dist/frontend/npm.test.js.map +1 -1
- package/dist/frontend/pipeline-native.d.ts +6 -0
- package/dist/frontend/pipeline-native.js +32 -0
- package/dist/frontend/pipeline-native.js.map +1 -0
- package/dist/frontend/pipeline.d.ts +54 -0
- package/dist/frontend/pipeline.js +382 -0
- package/dist/frontend/pipeline.js.map +1 -0
- package/dist/frontend/pipeline.test.d.ts +1 -0
- package/dist/frontend/pipeline.test.js +77 -0
- package/dist/frontend/pipeline.test.js.map +1 -0
- package/dist/frontend/program-analysis.d.ts +10 -0
- package/dist/frontend/program-analysis.js +14 -0
- package/dist/frontend/program-analysis.js.map +1 -0
- package/dist/frontend/program-node.d.ts +9 -0
- package/dist/frontend/program-node.js +48 -0
- package/dist/frontend/program-node.js.map +1 -0
- package/dist/frontend/program.d.ts +43 -19
- package/dist/frontend/program.js +556 -197
- package/dist/frontend/program.js.map +1 -1
- package/dist/frontend/program.test.d.ts +1 -0
- package/dist/frontend/program.test.js +202 -0
- package/dist/frontend/program.test.js.map +1 -0
- package/dist/frontend/provenance-core.d.ts +9 -0
- package/dist/frontend/provenance-core.js +435 -0
- package/dist/frontend/provenance-core.js.map +1 -0
- package/dist/frontend/provenance.d.ts +0 -4
- package/dist/frontend/provenance.js +4 -459
- package/dist/frontend/provenance.js.map +1 -1
- package/dist/frontend/resolve.d.ts +3 -1
- package/dist/frontend/resolve.js +6 -3
- package/dist/frontend/resolve.js.map +1 -1
- package/dist/frontend/runtime-resolve.d.ts +4 -3
- package/dist/frontend/runtime-resolve.js +22 -18
- package/dist/frontend/runtime-resolve.js.map +1 -1
- package/dist/frontend/runtime-resolve.test.js +53 -0
- package/dist/frontend/runtime-resolve.test.js.map +1 -1
- package/dist/frontend/services-node.d.ts +5 -0
- package/dist/frontend/services-node.js +19 -0
- package/dist/frontend/services-node.js.map +1 -0
- package/dist/frontend/services-node.test.d.ts +1 -0
- package/dist/frontend/services-node.test.js +70 -0
- package/dist/frontend/services-node.test.js.map +1 -0
- package/dist/frontend/services.d.ts +44 -0
- package/dist/frontend/services.js +90 -0
- package/dist/frontend/services.js.map +1 -0
- package/dist/frontend/services.test.d.ts +1 -0
- package/dist/frontend/services.test.js +174 -0
- package/dist/frontend/services.test.js.map +1 -0
- package/dist/frontend/ts7/adapter.d.ts +3 -3
- package/dist/frontend/ts7/adapter.js +14 -31
- package/dist/frontend/ts7/adapter.js.map +1 -1
- package/dist/frontend/ts7/api.d.ts +16 -0
- package/dist/frontend/ts7/api.js +24 -0
- package/dist/frontend/ts7/api.js.map +1 -0
- package/dist/frontend/ts7/ast-bytes.d.ts +31 -0
- package/dist/frontend/ts7/ast-bytes.js +137 -0
- package/dist/frontend/ts7/ast-bytes.js.map +1 -0
- package/dist/frontend/ts7/ast-bytes.test.d.ts +1 -0
- package/dist/frontend/ts7/ast-bytes.test.js +73 -0
- package/dist/frontend/ts7/ast-bytes.test.js.map +1 -0
- package/dist/frontend/ts7/ast-guards.generated.d.ts +353 -0
- package/dist/frontend/ts7/ast-guards.generated.js +1951 -0
- package/dist/frontend/ts7/ast-guards.generated.js.map +1 -0
- package/dist/frontend/ts7/ast-guards.test.d.ts +1 -0
- package/dist/frontend/ts7/ast-guards.test.js +43 -0
- package/dist/frontend/ts7/ast-guards.test.js.map +1 -0
- package/dist/frontend/ts7/ast-node.d.ts +194 -0
- package/dist/frontend/ts7/ast-node.js +448 -0
- package/dist/frontend/ts7/ast-node.js.map +1 -0
- package/dist/frontend/ts7/ast-node.test.d.ts +1 -0
- package/dist/frontend/ts7/ast-node.test.js +266 -0
- package/dist/frontend/ts7/ast-node.test.js.map +1 -0
- package/dist/frontend/ts7/ast-schema.generated.d.ts +503 -0
- package/dist/frontend/ts7/ast-schema.generated.js +1446 -0
- package/dist/frontend/ts7/ast-schema.generated.js.map +1 -0
- package/dist/frontend/ts7/ast-text.d.ts +6 -0
- package/dist/frontend/ts7/ast-text.js +124 -0
- package/dist/frontend/ts7/ast-text.js.map +1 -0
- package/dist/frontend/ts7/ast-text.test.d.ts +1 -0
- package/dist/frontend/ts7/ast-text.test.js +38 -0
- package/dist/frontend/ts7/ast-text.test.js.map +1 -0
- package/dist/frontend/ts7/ast-tokens.generated.d.ts +2 -0
- package/dist/frontend/ts7/ast-tokens.generated.js +155 -0
- package/dist/frontend/ts7/ast-tokens.generated.js.map +1 -0
- package/dist/frontend/ts7/ast-types.d.ts +42 -0
- package/dist/frontend/ts7/ast-types.generated.d.ts +1615 -0
- package/dist/frontend/ts7/ast-types.generated.js +5 -0
- package/dist/frontend/ts7/ast-types.generated.js.map +1 -0
- package/dist/frontend/ts7/ast-types.js +3 -0
- package/dist/frontend/ts7/ast-types.js.map +1 -0
- package/dist/frontend/ts7/ast-wire.d.ts +58 -0
- package/dist/frontend/ts7/ast-wire.js +267 -0
- package/dist/frontend/ts7/ast-wire.js.map +1 -0
- package/dist/frontend/ts7/ast-wire.test.d.ts +1 -0
- package/dist/frontend/ts7/ast-wire.test.js +151 -0
- package/dist/frontend/ts7/ast-wire.test.js.map +1 -0
- package/dist/frontend/ts7/ast.d.ts +14 -14
- package/dist/frontend/ts7/ast.js +21 -15
- package/dist/frontend/ts7/ast.js.map +1 -1
- package/dist/frontend/ts7/census-check.js +1 -0
- package/dist/frontend/ts7/census-check.js.map +1 -1
- package/dist/frontend/ts7/checker-cache.d.ts +48 -0
- package/dist/frontend/ts7/checker-cache.js +92 -0
- package/dist/frontend/ts7/checker-cache.js.map +1 -0
- package/dist/frontend/ts7/checker.d.ts +19 -46
- package/dist/frontend/ts7/checker.js +231 -161
- package/dist/frontend/ts7/checker.js.map +1 -1
- package/dist/frontend/ts7/checker.test.d.ts +1 -0
- package/dist/frontend/ts7/checker.test.js +335 -0
- package/dist/frontend/ts7/checker.test.js.map +1 -0
- package/dist/frontend/ts7/enums.d.ts +4 -27
- package/dist/frontend/ts7/enums.generated.d.ts +878 -0
- package/dist/frontend/ts7/enums.generated.js +1313 -0
- package/dist/frontend/ts7/enums.generated.js.map +1 -0
- package/dist/frontend/ts7/enums.js +4 -45
- package/dist/frontend/ts7/enums.js.map +1 -1
- package/dist/frontend/ts7/enums.test.d.ts +1 -0
- package/dist/frontend/ts7/enums.test.js +48 -0
- package/dist/frontend/ts7/enums.test.js.map +1 -0
- package/dist/frontend/ts7/native-api.d.ts +10 -0
- package/dist/frontend/ts7/native-api.js +10 -0
- package/dist/frontend/ts7/native-api.js.map +1 -0
- package/dist/frontend/ts7/native-host.d.ts +2 -0
- package/dist/frontend/ts7/native-host.js +11 -0
- package/dist/frontend/ts7/native-host.js.map +1 -0
- package/dist/frontend/ts7/native-process.d.ts +14 -0
- package/dist/frontend/ts7/native-process.js +62 -0
- package/dist/frontend/ts7/native-process.js.map +1 -0
- package/dist/frontend/ts7/program-adapter.d.ts +10 -98
- package/dist/frontend/ts7/program-adapter.js +16 -310
- package/dist/frontend/ts7/program-adapter.js.map +1 -1
- package/dist/frontend/ts7/program-host.d.ts +115 -0
- package/dist/frontend/ts7/program-host.js +347 -0
- package/dist/frontend/ts7/program-host.js.map +1 -0
- package/dist/frontend/ts7/program-host.test.d.ts +1 -0
- package/dist/frontend/ts7/program-host.test.js +207 -0
- package/dist/frontend/ts7/program-host.test.js.map +1 -0
- package/dist/frontend/ts7/rpc-api.d.ts +12 -0
- package/dist/frontend/ts7/rpc-api.js +23 -0
- package/dist/frontend/ts7/rpc-api.js.map +1 -0
- package/dist/frontend/ts7/rpc-client.d.ts +27 -0
- package/dist/frontend/ts7/rpc-client.js +102 -0
- package/dist/frontend/ts7/rpc-client.js.map +1 -0
- package/dist/frontend/ts7/rpc-client.test.d.ts +1 -0
- package/dist/frontend/ts7/rpc-client.test.js +133 -0
- package/dist/frontend/ts7/rpc-client.test.js.map +1 -0
- package/dist/frontend/ts7/rpc-filesystem.d.ts +16 -0
- package/dist/frontend/ts7/rpc-filesystem.js +42 -0
- package/dist/frontend/ts7/rpc-filesystem.js.map +1 -0
- package/dist/frontend/ts7/rpc-filesystem.test.d.ts +1 -0
- package/dist/frontend/ts7/rpc-filesystem.test.js +89 -0
- package/dist/frontend/ts7/rpc-filesystem.test.js.map +1 -0
- package/dist/frontend/ts7/rpc-process.d.ts +2 -0
- package/dist/frontend/ts7/rpc-process.js +148 -0
- package/dist/frontend/ts7/rpc-process.js.map +1 -0
- package/dist/frontend/ts7/rpc-process.test.d.ts +1 -0
- package/dist/frontend/ts7/rpc-process.test.js +29 -0
- package/dist/frontend/ts7/rpc-process.test.js.map +1 -0
- package/dist/frontend/ts7/rpc-wire.d.ts +46 -0
- package/dist/frontend/ts7/rpc-wire.js +195 -0
- package/dist/frontend/ts7/rpc-wire.js.map +1 -0
- package/dist/frontend/ts7/rpc-wire.test.d.ts +1 -0
- package/dist/frontend/ts7/rpc-wire.test.js +168 -0
- package/dist/frontend/ts7/rpc-wire.test.js.map +1 -0
- package/dist/frontend/ts7/semantic-checker.d.ts +137 -0
- package/dist/frontend/ts7/semantic-checker.js +221 -0
- package/dist/frontend/ts7/semantic-checker.js.map +1 -0
- package/dist/frontend/ts7/semantic-checker.test.d.ts +1 -0
- package/dist/frontend/ts7/semantic-checker.test.js +119 -0
- package/dist/frontend/ts7/semantic-checker.test.js.map +1 -0
- package/dist/frontend/ts7/semantic-json.d.ts +5 -0
- package/dist/frontend/ts7/semantic-json.js +52 -0
- package/dist/frontend/ts7/semantic-json.js.map +1 -0
- package/dist/frontend/ts7/semantic-json.test.d.ts +1 -0
- package/dist/frontend/ts7/semantic-json.test.js +42 -0
- package/dist/frontend/ts7/semantic-json.test.js.map +1 -0
- package/dist/frontend/ts7/semantic-model.d.ts +222 -0
- package/dist/frontend/ts7/semantic-model.js +423 -0
- package/dist/frontend/ts7/semantic-model.js.map +1 -0
- package/dist/frontend/ts7/semantic-model.test.d.ts +1 -0
- package/dist/frontend/ts7/semantic-model.test.js +322 -0
- package/dist/frontend/ts7/semantic-model.test.js.map +1 -0
- package/dist/frontend/ts7/semantic-schema.generated.d.ts +283 -0
- package/dist/frontend/ts7/semantic-schema.generated.js +222 -0
- package/dist/frontend/ts7/semantic-schema.generated.js.map +1 -0
- package/dist/frontend/ts7/semantic-types.d.ts +5 -0
- package/dist/frontend/ts7/semantic-types.js +2 -0
- package/dist/frontend/ts7/semantic-types.js.map +1 -0
- package/dist/frontend/ts7/session-cache.d.ts +17 -0
- package/dist/frontend/ts7/session-cache.js +97 -0
- package/dist/frontend/ts7/session-cache.js.map +1 -0
- package/dist/frontend/ts7/session-cache.test.d.ts +1 -0
- package/dist/frontend/ts7/session-cache.test.js +87 -0
- package/dist/frontend/ts7/session-cache.test.js.map +1 -0
- package/dist/frontend/ts7/session-path.d.ts +18 -0
- package/dist/frontend/ts7/session-path.js +203 -0
- package/dist/frontend/ts7/session-path.js.map +1 -0
- package/dist/frontend/ts7/session-path.test.d.ts +1 -0
- package/dist/frontend/ts7/session-path.test.js +34 -0
- package/dist/frontend/ts7/session-path.test.js.map +1 -0
- package/dist/frontend/ts7/session-schema.generated.d.ts +167 -0
- package/dist/frontend/ts7/session-schema.generated.js +5 -0
- package/dist/frontend/ts7/session-schema.generated.js.map +1 -0
- package/dist/frontend/ts7/session-timing.d.ts +50 -0
- package/dist/frontend/ts7/session-timing.js +61 -0
- package/dist/frontend/ts7/session-timing.js.map +1 -0
- package/dist/frontend/ts7/session-timing.test.d.ts +1 -0
- package/dist/frontend/ts7/session-timing.test.js +52 -0
- package/dist/frontend/ts7/session-timing.test.js.map +1 -0
- package/dist/frontend/ts7/session.d.ts +105 -0
- package/dist/frontend/ts7/session.js +233 -0
- package/dist/frontend/ts7/session.js.map +1 -0
- package/dist/frontend/ts7/session.test.d.ts +1 -0
- package/dist/frontend/ts7/session.test.js +215 -0
- package/dist/frontend/ts7/session.test.js.map +1 -0
- package/dist/frontend/ts7/source-parser-node.d.ts +6 -0
- package/dist/frontend/ts7/source-parser-node.js +15 -0
- package/dist/frontend/ts7/source-parser-node.js.map +1 -0
- package/dist/frontend/ts7/source-parser.d.ts +25 -0
- package/dist/frontend/ts7/source-parser.js +96 -0
- package/dist/frontend/ts7/source-parser.js.map +1 -0
- package/dist/frontend/ts7/source-parser.test.d.ts +1 -0
- package/dist/frontend/ts7/source-parser.test.js +151 -0
- package/dist/frontend/ts7/source-parser.test.js.map +1 -0
- package/dist/frontend/ts7/syntax.d.ts +3 -0
- package/dist/frontend/ts7/syntax.js +4 -0
- package/dist/frontend/ts7/syntax.js.map +1 -0
- package/dist/frontend/tsc-codes.js +3 -0
- package/dist/frontend/tsc-codes.js.map +1 -1
- package/dist/frontend/type-mapper.d.ts +29 -19
- package/dist/frontend/type-mapper.js +713 -306
- package/dist/frontend/type-mapper.js.map +1 -1
- package/dist/frontend/type-mapper.test.d.ts +1 -0
- package/dist/frontend/type-mapper.test.js +207 -0
- package/dist/frontend/type-mapper.test.js.map +1 -0
- package/dist/frontend/union-discriminants.d.ts +16 -0
- package/dist/frontend/union-discriminants.js +98 -0
- package/dist/frontend/union-discriminants.js.map +1 -0
- package/dist/frontend/union-discriminants.test.d.ts +1 -0
- package/dist/frontend/union-discriminants.test.js +182 -0
- package/dist/frontend/union-discriminants.test.js.map +1 -0
- package/dist/index.d.ts +7 -197
- package/dist/index.js +369 -1567
- package/dist/index.js.map +1 -1
- package/dist/ir/analysis.d.ts +16 -4
- package/dist/ir/analysis.js +25 -6
- package/dist/ir/analysis.js.map +1 -1
- package/dist/ir/analysis.test.js +15 -2
- package/dist/ir/analysis.test.js.map +1 -1
- package/dist/ir/constant-tables.js +67 -49
- package/dist/ir/constant-tables.js.map +1 -1
- package/dist/ir/constant-tables.test.js +1 -1
- package/dist/ir/control-flow.d.ts +6 -0
- package/dist/ir/control-flow.js +142 -0
- package/dist/ir/control-flow.js.map +1 -0
- package/dist/ir/control-flow.test.d.ts +1 -0
- package/dist/ir/control-flow.test.js +113 -0
- package/dist/ir/control-flow.test.js.map +1 -0
- package/dist/ir/integer-loops.js +7 -18
- package/dist/ir/integer-loops.js.map +1 -1
- package/dist/ir/integer-ranges.js +53 -27
- package/dist/ir/integer-ranges.js.map +1 -1
- package/dist/ir/ir.d.ts +309 -164
- package/dist/ir/ir.js +588 -879
- package/dist/ir/ir.js.map +1 -1
- package/dist/ir/ir.test.js +127 -1
- package/dist/ir/ir.test.js.map +1 -1
- package/dist/ir/scalar-records.js +165 -134
- package/dist/ir/scalar-records.js.map +1 -1
- package/dist/ir/scalar-records.test.js +1 -1
- package/dist/ir/serialize.d.ts +4 -2
- package/dist/ir/serialize.js +19 -12
- package/dist/ir/serialize.js.map +1 -1
- package/dist/ir/serialize.test.d.ts +1 -0
- package/dist/ir/serialize.test.js +53 -0
- package/dist/ir/serialize.test.js.map +1 -0
- package/dist/ir/traverse.d.ts +41 -0
- package/dist/ir/traverse.js +660 -0
- package/dist/ir/traverse.js.map +1 -0
- package/dist/ir/traverse.test.d.ts +1 -0
- package/dist/ir/traverse.test.js +242 -0
- package/dist/ir/traverse.test.js.map +1 -0
- package/dist/ir/validate.js +1956 -1496
- package/dist/ir/validate.js.map +1 -1
- package/dist/ir/validate.test.js +476 -2
- package/dist/ir/validate.test.js.map +1 -1
- package/dist/library/cache-primitives.d.ts +2 -3
- package/dist/library/cache-primitives.js +4 -6
- package/dist/library/cache-primitives.js.map +1 -1
- package/dist/library/compiler-self-identity.d.ts +1 -1
- package/dist/library/compiler-self-identity.js +31 -15
- package/dist/library/compiler-self-identity.js.map +1 -1
- package/dist/library/compiler-self-identity.test.d.ts +1 -0
- package/dist/library/compiler-self-identity.test.js +93 -0
- package/dist/library/compiler-self-identity.test.js.map +1 -0
- package/dist/library/fence-eval.js +2 -2
- package/dist/library/fence-eval.js.map +1 -1
- package/dist/library/int-infer.js +7 -6
- package/dist/library/int-infer.js.map +1 -1
- package/dist/library/int-infer.test.js +4 -4
- package/dist/library/library-cache.d.ts +3 -2
- package/dist/library/library-cache.js +5 -17
- package/dist/library/library-cache.js.map +1 -1
- package/dist/library/library-cache.test.js +54 -41
- package/dist/library/library-cache.test.js.map +1 -1
- package/dist/library/library-profile.d.ts +3 -1
- package/dist/library/library-profile.js +15 -6
- package/dist/library/library-profile.js.map +1 -1
- package/dist/library/prepare.d.ts +15 -0
- package/dist/library/prepare.js +584 -0
- package/dist/library/prepare.js.map +1 -0
- package/dist/library/semantic-source.d.ts +1 -1
- package/dist/library/semantic-source.js +8 -6
- package/dist/library/semantic-source.js.map +1 -1
- package/dist/library/sidecar-validate.js +4 -4
- package/dist/library/sidecar-validate.js.map +1 -1
- package/dist/library/sidecar.d.ts +2 -0
- package/dist/library/sidecar.js +10 -3
- package/dist/library/sidecar.js.map +1 -1
- package/dist/native/cache.d.ts +11 -0
- package/dist/native/cache.js +113 -0
- package/dist/native/cache.js.map +1 -0
- package/dist/native/cache.test.d.ts +1 -0
- package/dist/native/cache.test.js +66 -0
- package/dist/native/cache.test.js.map +1 -0
- package/dist/native/cli.d.ts +1 -0
- package/dist/native/cli.js +112 -0
- package/dist/native/cli.js.map +1 -0
- package/dist/native/compiler.d.ts +15 -0
- package/dist/native/compiler.js +336 -0
- package/dist/native/compiler.js.map +1 -0
- package/dist/native/compiler.test.d.ts +1 -0
- package/dist/native/compiler.test.js +174 -0
- package/dist/native/compiler.test.js.map +1 -0
- package/dist/native/comptime.d.ts +5 -0
- package/dist/native/comptime.js +73 -0
- package/dist/native/comptime.js.map +1 -0
- package/dist/native/comptime.test.d.ts +1 -0
- package/dist/native/comptime.test.js +65 -0
- package/dist/native/comptime.test.js.map +1 -0
- package/dist/native/executable-cache.d.ts +26 -0
- package/dist/native/executable-cache.js +228 -0
- package/dist/native/executable-cache.js.map +1 -0
- package/dist/native/executable-cache.test.d.ts +1 -0
- package/dist/native/executable-cache.test.js +151 -0
- package/dist/native/executable-cache.test.js.map +1 -0
- package/dist/native/file-identity.d.ts +4 -0
- package/dist/native/file-identity.js +14 -0
- package/dist/native/file-identity.js.map +1 -0
- package/dist/native/file-identity.test.d.ts +1 -0
- package/dist/native/file-identity.test.js +43 -0
- package/dist/native/file-identity.test.js.map +1 -0
- package/dist/native/library.d.ts +22 -0
- package/dist/native/library.js +83 -0
- package/dist/native/library.js.map +1 -0
- package/dist/native/prepare.d.ts +21 -0
- package/dist/native/prepare.js +174 -0
- package/dist/native/prepare.js.map +1 -0
- package/dist/native/prepare.test.d.ts +1 -0
- package/dist/native/prepare.test.js +70 -0
- package/dist/native/prepare.test.js.map +1 -0
- package/dist/native/sanitizer.d.ts +11 -0
- package/dist/native/sanitizer.js +135 -0
- package/dist/native/sanitizer.js.map +1 -0
- package/dist/native/sanitizer.test.d.ts +1 -0
- package/dist/native/sanitizer.test.js +58 -0
- package/dist/native/sanitizer.test.js.map +1 -0
- package/dist/native/task.d.ts +4 -0
- package/dist/native/task.js +16 -0
- package/dist/native/task.js.map +1 -0
- package/dist/native/task.test.d.ts +1 -0
- package/dist/native/task.test.js +17 -0
- package/dist/native/task.test.js.map +1 -0
- package/dist/native/toolchain.d.ts +45 -0
- package/dist/native/toolchain.js +74 -0
- package/dist/native/toolchain.js.map +1 -0
- package/dist/native/toolchain.test.d.ts +1 -0
- package/dist/native/toolchain.test.js +33 -0
- package/dist/native/toolchain.test.js.map +1 -0
- package/dist/startup-cache.d.ts +1 -1
- package/dist/startup-cache.js +2 -5
- package/dist/startup-cache.js.map +1 -1
- package/dist/timing.d.ts +4 -0
- package/dist/timing.js +19 -0
- package/dist/timing.js.map +1 -0
- package/dist/wasi-paths.js +10 -7
- package/dist/wasi-paths.js.map +1 -1
- package/package.json +28 -19
- package/surface-manifest.json +171 -18
- package/dist/backend/c/async.d.ts +0 -171
- package/dist/backend/c/async.js +0 -1317
- package/dist/backend/c/async.js.map +0 -1
- package/dist/backend/c/c-emitter.d.ts +0 -531
- package/dist/backend/c/c-emitter.js +0 -1917
- package/dist/backend/c/c-emitter.js.map +0 -1
- package/dist/backend/c/exprs.d.ts +0 -15
- package/dist/backend/c/exprs.js +0 -8803
- package/dist/backend/c/exprs.js.map +0 -1
- package/dist/backend/c/island.d.ts +0 -45
- package/dist/backend/c/island.js +0 -281
- package/dist/backend/c/island.js.map +0 -1
- package/dist/backend/c/may-throw.js.map +0 -1
- package/dist/backend/c/shapes.d.ts +0 -142
- package/dist/backend/c/shapes.js +0 -603
- package/dist/backend/c/shapes.js.map +0 -1
- package/dist/backend/c/stmts.d.ts +0 -76
- package/dist/backend/c/stmts.js +0 -1084
- package/dist/backend/c/stmts.js.map +0 -1
- package/dist/backend/c/types.d.ts +0 -71
- package/dist/backend/c/types.js +0 -459
- package/dist/backend/c/types.js.map +0 -1
- package/dist/backend/c/types.test.js +0 -32
- package/dist/backend/c/types.test.js.map +0 -1
- package/dist/backend/c/walkers.d.ts +0 -134
- package/dist/backend/c/walkers.js +0 -1773
- package/dist/backend/c/walkers.js.map +0 -1
- /package/dist/backend/{c/types.test.d.ts → cycle-analysis.test.d.ts} +0 -0
|
@@ -5,25 +5,77 @@ import { InternalCompilerError } from "../../errors.js";
|
|
|
5
5
|
* accessor access, upcasts, `new` expressions, and the builtin Error
|
|
6
6
|
* hierarchy registration. */
|
|
7
7
|
import * as ts from "../ts7/adapter.js";
|
|
8
|
-
import { BOOL, DATE_T, DYN, F64, bytesOf, JSVAL, RUNTIME_EMITTER_CLASS, RUNTIME_ERROR_CLASSES, RUNTIME_STREAM_CLASSES, STRING, UNDEFINED_T,
|
|
9
|
-
import { MAX_GENERIC_INSTANCES, appendImplicitUndefinedReturn, generatorMeta, genericCallInstance, implicitAnyParamSymbolsOf, implicitCallInstance, implicitMonoFile, omittedArgFor } from "./lower-calls.js";
|
|
10
|
-
import { isGenericCallableMemberType, typeKey } from "../type-mapper.js";
|
|
8
|
+
import { BOOL, DATE_T, DYN, F64, bytesOf, JSVAL, RUNTIME_EMITTER_CLASS, RUNTIME_ERROR_CLASSES, RUNTIME_STREAM_CLASSES, STRING, UNDEFINED_T, VOID, arrayOf, isSupportedMapKey, isSupportedMapValue, isSupportedSetElem, isUnitType, typeEquals } from "../../ir/ir.js";
|
|
9
|
+
import { MAX_GENERIC_INSTANCES, appendImplicitUndefinedReturn, bodyReadsArguments, generatorMeta, genericCallInstance, implicitAnyParamSymbolsOf, implicitCallInstance, implicitMonoFile, omittedArgFor } from "./lower-calls.js";
|
|
10
|
+
import { isGenericCallableMemberType, jsOpenObjectType, typeKey, withUnitArm } from "../type-mapper.js";
|
|
11
11
|
import { cjsClassExprWholeExportOf, isCjsJsFile, isJsSourceFile, isModuleExportsAccess, isNodeTypesPath, locOf } from "../program.js";
|
|
12
12
|
import { PoisonError, dynFallbackType, dynUndefinedExpr, newFnCtx, own } from "./lowerer.js";
|
|
13
|
-
import { lowerArrayConstructor,
|
|
13
|
+
import { lowerArrayConstructor, lowerMapSeedNew, lowerSetSeedNew } from "./lower-containers.js";
|
|
14
14
|
import { bufEncoding } from "./containers/bytes.js";
|
|
15
15
|
import { isSafeToRepeat } from "./expressions/evaluation-safety.js";
|
|
16
|
-
import { lowerSearchParamsNew } from "./lower-builtins.js";
|
|
16
|
+
import { lowerSearchParamsNew, lowerTextCodecNew } from "./lower-builtins.js";
|
|
17
17
|
import { requiresDynamicPackageDiag, unsupportedDiag } from "../../diagnostics/diagnostic.js";
|
|
18
18
|
import { STREAM_API_MEMBERS, STREAM_PROP_MEMBERS, UNDERSCORE_METHODS, lowerStreamNew, lowerStreamSuperCall, streamCtorShape } from "./lower-stream.js";
|
|
19
19
|
import { emitOverrideShapeReason, emitSpecSuperForward, emitterRooted, lowerEmitterSuperCall } from "./lower-event-emitter.js";
|
|
20
20
|
import { declSymbolOf } from "./lower-modules.js";
|
|
21
|
-
import {
|
|
21
|
+
import { classSymbolKeyOf, classSymbolKeyOfSymbol, symbolFieldDisplayName } from "./symbol-fields.js";
|
|
22
|
+
import { builtinFenceHintOf } from "./surfaces.js";
|
|
22
23
|
import { lowerHttpAgentNew, lowerHttpServerNew } from "./lower-server.js";
|
|
23
24
|
import { ambientNsRootOf, ambientUndefReadType, ambientUndefVarRootOf, ambientUndefinedFnSymbolOf, fenceEarlyAliasUse, fenceEarlyNsMemberRef, nsMemberIdentOf, nsUndefRead } from "./lower-namespaces.js";
|
|
24
25
|
import { mixinResultBindingClassOf } from "./lower-mixins.js";
|
|
25
|
-
import { rejectStaticThis } from "./static-this.js";
|
|
26
|
-
import {
|
|
26
|
+
import { hasLexicalPrivateReference, hasStaticThis, rejectStaticThis } from "./static-this.js";
|
|
27
|
+
import { lowerUrlNew } from "./lower-url.js";
|
|
28
|
+
import { isNativeProxyInitializer, lowerNativeProxy } from "./expressions/native-proxy.js";
|
|
29
|
+
import { classPrototypeData } from "./class-prototypes.js";
|
|
30
|
+
import { classStaticDataFor } from "./class-static-data.js";
|
|
31
|
+
import { lowerObjectFactoryNew } from "./object-factory-new.js";
|
|
32
|
+
import { lowerInstanceConstructorNew } from "./class-instance-constructor.js";
|
|
33
|
+
export function returnsOnlyThis(member) {
|
|
34
|
+
const body = member.body;
|
|
35
|
+
const last = body?.statements.at(-1);
|
|
36
|
+
if (!body || !last || !ts.isReturnStatement(last))
|
|
37
|
+
return false;
|
|
38
|
+
let valid = true;
|
|
39
|
+
const visit = (node) => {
|
|
40
|
+
if (ts.isFunctionLike(node))
|
|
41
|
+
return;
|
|
42
|
+
if (ts.isReturnStatement(node)) {
|
|
43
|
+
let value = node.expression;
|
|
44
|
+
while (value && ts.isParenthesizedExpression(value))
|
|
45
|
+
value = value.expression;
|
|
46
|
+
if (!value || value.kind !== ts.SyntaxKind.ThisKeyword)
|
|
47
|
+
valid = false;
|
|
48
|
+
}
|
|
49
|
+
node.forEachChild(visit);
|
|
50
|
+
};
|
|
51
|
+
body.forEachChild(visit);
|
|
52
|
+
return valid;
|
|
53
|
+
}
|
|
54
|
+
function functionLocalClass(decl) {
|
|
55
|
+
for (let parent = decl.parent; parent && !ts.isSourceFile(parent); parent = parent.parent) {
|
|
56
|
+
if (ts.isFunctionLike(parent))
|
|
57
|
+
return true;
|
|
58
|
+
}
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
export function storedClassValueType(lowerer, expression) {
|
|
62
|
+
if (ts.isPropertyAccessExpression(expression) && !expression.questionDotToken) {
|
|
63
|
+
const member = nsMemberIdentOf(lowerer, expression);
|
|
64
|
+
if (member)
|
|
65
|
+
return storedClassValueType(lowerer, member);
|
|
66
|
+
}
|
|
67
|
+
if (expression.kind === ts.SyntaxKind.ThisKeyword) {
|
|
68
|
+
const stored = lowerer.resolveThis();
|
|
69
|
+
if (stored?.type.kind === "classval")
|
|
70
|
+
return stored.type;
|
|
71
|
+
}
|
|
72
|
+
if (ts.isIdentifier(expression)) {
|
|
73
|
+
const stored = lowerer.peekLocal(expression) ?? lowerer.globalOf(expression);
|
|
74
|
+
if (stored?.type.kind === "classval")
|
|
75
|
+
return stored.type;
|
|
76
|
+
}
|
|
77
|
+
return lowerer.mapTypeOf(lowerer.typeOf(expression));
|
|
78
|
+
}
|
|
27
79
|
/** The KEY symbol behind a LATE-BOUND (`__@name@id`) property: resolved
|
|
28
80
|
* from the argument of the element-access assignment that declared it
|
|
29
81
|
* (`this[kLimit] = v` — the declaration list holds the BinaryExpression
|
|
@@ -92,8 +144,8 @@ function symbolSlotReturnType(lowerer, fnLike, symbolFields, fields) {
|
|
|
92
144
|
return null;
|
|
93
145
|
if (e.expression.kind !== ts.SyntaxKind.ThisKeyword)
|
|
94
146
|
return null;
|
|
95
|
-
const key =
|
|
96
|
-
const fieldName = key ? symbolFields.get(key.
|
|
147
|
+
const key = classSymbolKeyOf(lowerer, e.argumentExpression);
|
|
148
|
+
const fieldName = key ? symbolFields.get(key.identity) : undefined;
|
|
97
149
|
const t = fieldName !== undefined ? fields.get(fieldName) : undefined;
|
|
98
150
|
if (t === undefined || t.kind === "dyn")
|
|
99
151
|
return null;
|
|
@@ -103,7 +155,7 @@ function symbolSlotReturnType(lowerer, fnLike, symbolFields, fields) {
|
|
|
103
155
|
}
|
|
104
156
|
return out;
|
|
105
157
|
}
|
|
106
|
-
/** The builtin Error hierarchy
|
|
158
|
+
/** The builtin Error hierarchy
|
|
107
159
|
* as eagerly-registered ClassInfos: mapType names them the moment a lib
|
|
108
160
|
* Error type appears, so the infos must exist before any lowering. They
|
|
109
161
|
* are runtime-provided — no decl, no lowerable bodies; `new`/super()/
|
|
@@ -126,11 +178,16 @@ export function registerBuiltinErrorClasses(lowerer) {
|
|
|
126
178
|
// subclass declaring its own `code` field lays out AFTER it,
|
|
127
179
|
// never colliding), and it is NOT in the fields map below: the
|
|
128
180
|
// READ has its own `string | undefined` lowering (error.code),
|
|
129
|
-
// never a plain-string field access.
|
|
181
|
+
// never a plain-string field access. `%cause` is the following
|
|
182
|
+
// owned dyn slot; NULL means absent, dyn undefined means present.
|
|
130
183
|
fields: [
|
|
131
184
|
{ name: "name", type: STRING },
|
|
132
185
|
{ name: "message", type: STRING },
|
|
133
186
|
{ name: "%code", type: STRING },
|
|
187
|
+
{ name: "%cause", type: DYN },
|
|
188
|
+
{ name: "%causeEnumerable", type: BOOL },
|
|
189
|
+
{ name: "%stackFrames", type: STRING },
|
|
190
|
+
{ name: "%stack", type: STRING },
|
|
134
191
|
],
|
|
135
192
|
loc,
|
|
136
193
|
},
|
|
@@ -148,10 +205,9 @@ export function registerBuiltinErrorClasses(lowerer) {
|
|
|
148
205
|
decl: null,
|
|
149
206
|
builtinError: true,
|
|
150
207
|
ctor: null,
|
|
151
|
-
//
|
|
152
|
-
//
|
|
153
|
-
|
|
154
|
-
ctorParams: [{ type: STRING, mode: "omittable" }],
|
|
208
|
+
// Inherited constructors forward both raw arguments. The runtime
|
|
209
|
+
// applies the undefined message default and InstallErrorCause.
|
|
210
|
+
ctorParams: [{ type: DYN, mode: "omittable" }, { type: DYN, mode: "omittable" }],
|
|
155
211
|
base,
|
|
156
212
|
subclasses: [],
|
|
157
213
|
throwingSetters: [],
|
|
@@ -278,17 +334,56 @@ export function builtinStreamInfoOf(lowerer, symbol) {
|
|
|
278
334
|
});
|
|
279
335
|
return declared ? (lowerer.classes.get(irName) ?? null) : null;
|
|
280
336
|
}
|
|
337
|
+
/** A dictionary lookup may be absent even when its checker type is a
|
|
338
|
+
* required reference. Keep literal nullish fallbacks in inferred JS storage. */
|
|
339
|
+
function jsFieldInitializerType(lowerer, type, expression) {
|
|
340
|
+
let node = expression;
|
|
341
|
+
while (ts.isParenthesizedExpression(node))
|
|
342
|
+
node = node.expression;
|
|
343
|
+
if (node.kind === ts.SyntaxKind.NullKeyword)
|
|
344
|
+
return withUnitArm(type, "nullT", lowerer.unions) ?? type;
|
|
345
|
+
const inferred = lowerer.typeOf(node);
|
|
346
|
+
for (const arm of inferred.isUnionType() ? ts.constituentTypes(inferred) : [inferred]) {
|
|
347
|
+
if ((arm.flags & ts.TypeFlags.Undefined) !== 0)
|
|
348
|
+
type = lowerer.withUndefinedArmOf(type) ?? type;
|
|
349
|
+
if ((arm.flags & ts.TypeFlags.Null) !== 0)
|
|
350
|
+
type = withUnitArm(type, "nullT", lowerer.unions) ?? type;
|
|
351
|
+
}
|
|
352
|
+
if (ts.isConditionalExpression(node)) {
|
|
353
|
+
return jsFieldInitializerType(lowerer, jsFieldInitializerType(lowerer, type, node.whenTrue), node.whenFalse);
|
|
354
|
+
}
|
|
355
|
+
if (ts.isBinaryExpression(node)) {
|
|
356
|
+
if (node.operatorToken.kind === ts.SyntaxKind.AmpersandAmpersandToken)
|
|
357
|
+
type = jsFieldInitializerType(lowerer, type, node.left);
|
|
358
|
+
if (node.operatorToken.kind === ts.SyntaxKind.AmpersandAmpersandToken ||
|
|
359
|
+
node.operatorToken.kind === ts.SyntaxKind.BarBarToken ||
|
|
360
|
+
node.operatorToken.kind === ts.SyntaxKind.QuestionQuestionToken)
|
|
361
|
+
return jsFieldInitializerType(lowerer, type, node.right);
|
|
362
|
+
}
|
|
363
|
+
return type;
|
|
364
|
+
}
|
|
281
365
|
/** The undefined-armed union of a JS class property's inferred type — the
|
|
282
366
|
* honest slot for a field first assigned outside the constructor's top
|
|
283
367
|
* level (undefined until the write runs, Node-exact). Null when the
|
|
284
|
-
* inference is unmappable
|
|
285
|
-
* fields — KEEP NARROW), or an arm-less kind that cannot join a union
|
|
368
|
+
* inference is unmappable or an arm-less kind that cannot join a union
|
|
286
369
|
* (genResultRecord's list, including scalar-backed Date values). */
|
|
287
370
|
function undefArmedFieldType(lowerer, p) {
|
|
288
371
|
const t = lowerer.checker.getTypeOfSymbol(p);
|
|
289
|
-
const
|
|
290
|
-
|
|
372
|
+
const site = lowerer.checker.declarationsOf(p)[0];
|
|
373
|
+
let mapped = lowerer.mapTypeOf(t) ?? (site ? dynFallbackType(lowerer, site, t) : null);
|
|
374
|
+
if (mapped && site)
|
|
375
|
+
mapped = jsOpenObjectType(site, mapped, lowerer.shapes, lowerer.unions);
|
|
376
|
+
if (!mapped || mapped.kind === "void")
|
|
291
377
|
return null;
|
|
378
|
+
for (const declaration of lowerer.checker.declarationsOf(p)) {
|
|
379
|
+
const assignment = ts.isBinaryExpression(declaration) ? declaration : declaration.parent;
|
|
380
|
+
if (assignment && ts.isBinaryExpression(assignment) && assignment.operatorToken.kind === ts.SyntaxKind.EqualsToken) {
|
|
381
|
+
mapped = jsFieldInitializerType(lowerer, mapped, assignment.right);
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
// An implicit JS value already carries undefined in its native box.
|
|
385
|
+
if (mapped.kind === "dyn")
|
|
386
|
+
return mapped;
|
|
292
387
|
const byKey = new Map();
|
|
293
388
|
const arms = mapped.kind === "union" ? (lowerer.unions.get(mapped.unionId)?.arms ?? []) : [mapped];
|
|
294
389
|
for (const a of arms) {
|
|
@@ -539,7 +634,7 @@ function inferredEmptyCollectionFieldType(lowerer, decl, field, initializer) {
|
|
|
539
634
|
if (collection === "Map" && node.expression.name.text === "set" && node.arguments.length === 2) {
|
|
540
635
|
const key = mappedArgument(node.arguments[0]);
|
|
541
636
|
const value = mappedArgument(node.arguments[1]);
|
|
542
|
-
if (key !== null && value !== null && isSupportedMapKey(key) && isSupportedMapValue(value)) {
|
|
637
|
+
if (key !== null && value !== null && isSupportedMapKey(key, key.kind === "union" ? lowerer.unions.get(key.unionId)?.arms : undefined) && isSupportedMapValue(value)) {
|
|
543
638
|
mapKeys.push(key);
|
|
544
639
|
mapValues.push(value);
|
|
545
640
|
}
|
|
@@ -548,7 +643,7 @@ function inferredEmptyCollectionFieldType(lowerer, decl, field, initializer) {
|
|
|
548
643
|
(node.expression.name.text === "add" || node.expression.name.text === "has" || node.expression.name.text === "delete") &&
|
|
549
644
|
node.arguments.length === 1) {
|
|
550
645
|
const element = mappedArgument(node.arguments[0]);
|
|
551
|
-
if (element !== null && isSupportedSetElem(element))
|
|
646
|
+
if (element !== null && isSupportedSetElem(element, element.kind === "union" ? lowerer.unions.get(element.unionId)?.arms : undefined))
|
|
552
647
|
setElements.push(element);
|
|
553
648
|
}
|
|
554
649
|
return undefined;
|
|
@@ -709,6 +804,19 @@ mixin) {
|
|
|
709
804
|
// base is its family (whose base is the declared one) — the heritage
|
|
710
805
|
// clause resolved when the family collected.
|
|
711
806
|
let base = inst ? inst.family : mixin ? mixin.base : null;
|
|
807
|
+
let callableBase;
|
|
808
|
+
const adoptCallableBase = (expression) => {
|
|
809
|
+
if (!isJsSourceFile(decl.getSourceFile()) || functionLocalClass(decl) ||
|
|
810
|
+
!ts.isClassDeclaration(decl) || familyMode || inst || mixin)
|
|
811
|
+
return false;
|
|
812
|
+
const signatures = lowerer.checker.getCallSignatures(lowerer.typeOf(expression));
|
|
813
|
+
const source = signatures.length === 1 ? lowerer.checker.signatureDeclaration(signatures[0]) : undefined;
|
|
814
|
+
if (!source || !isJsSourceFile(source.getSourceFile()) ||
|
|
815
|
+
!(ts.isFunctionDeclaration(source) || ts.isFunctionExpression(source)))
|
|
816
|
+
return false;
|
|
817
|
+
callableBase = { expression, constructorId: `%g.${className}.base`, prototypeId: `%g.${className}.basePrototype` };
|
|
818
|
+
return true;
|
|
819
|
+
};
|
|
712
820
|
// A family whose `extends` clause mentions its OWN type parameters
|
|
713
821
|
// (`class D<T> extends Box<T>`) would need a different base per
|
|
714
822
|
// instantiation — no single family interval can sit above all of
|
|
@@ -754,6 +862,14 @@ mixin) {
|
|
|
754
862
|
const resolved = memberSym && memberSym.flags & ts.SymbolFlags.Alias
|
|
755
863
|
? lowerer.checker.getAliasedSymbol(memberSym)
|
|
756
864
|
: memberSym;
|
|
865
|
+
const globalError = !t.expression.questionDotToken && lowerer.isStdlibGlobal(t.expression.expression, "globalThis")
|
|
866
|
+
? lowerer.builtinErrorInfoOf(resolved) : null;
|
|
867
|
+
if (globalError && globalError.def.name !== "%DOMException") {
|
|
868
|
+
if (t.typeArguments)
|
|
869
|
+
lowerer.unsupported("SC1090", t, "extending generic classes");
|
|
870
|
+
base = globalError;
|
|
871
|
+
continue;
|
|
872
|
+
}
|
|
757
873
|
const emitterBase = lowerer.builtinEmitterInfoOf(resolved);
|
|
758
874
|
const streamBaseNs = builtinStreamInfoOf(lowerer, resolved);
|
|
759
875
|
if (emitterBase || streamBaseNs) {
|
|
@@ -772,8 +888,12 @@ mixin) {
|
|
|
772
888
|
lowerer.unsupported("SC1090", t, "extending generic classes");
|
|
773
889
|
if (memberSym)
|
|
774
890
|
fenceEarlyNsMemberRef(lowerer, t.expression, memberSym);
|
|
775
|
-
const
|
|
891
|
+
const stored = storedClassValueType(lowerer, t.expression);
|
|
892
|
+
const nsBase = (resolved ? lowerer.classBySymbol.get(resolved) : undefined) ??
|
|
893
|
+
(stored?.kind === "classval" ? lowerer.classes.get(stored.className) : undefined);
|
|
776
894
|
if (!nsBase) {
|
|
895
|
+
if (adoptCallableBase(t.expression))
|
|
896
|
+
continue;
|
|
777
897
|
lowerer.unsupported("SC1090", t, `extending the namespace member '${t.expression.name.text}' (no class lowering)`);
|
|
778
898
|
}
|
|
779
899
|
base = nsBase;
|
|
@@ -880,7 +1000,11 @@ mixin) {
|
|
|
880
1000
|
// A const BINDING of a mixin call (`const Tagged = M(Base);
|
|
881
1001
|
// class D extends Tagged {}`): the binding pins that call's
|
|
882
1002
|
// instantiation — collected on demand (lower-mixins.ts).
|
|
883
|
-
mixinResultBindingClassOf(lowerer, symbol) ??
|
|
1003
|
+
mixinResultBindingClassOf(lowerer, symbol) ??
|
|
1004
|
+
(() => {
|
|
1005
|
+
const stored = storedClassValueType(lowerer, t.expression);
|
|
1006
|
+
return stored?.kind === "classval" ? lowerer.classes.get(stored.className) : null;
|
|
1007
|
+
})() ?? null;
|
|
884
1008
|
// `extends Box<number>` — a GENERIC program class as the base: the
|
|
885
1009
|
// base is the concrete INSTANTIATION, resolved through the heritage
|
|
886
1010
|
// type (mapType registers/reuses `Box%0`).
|
|
@@ -898,13 +1022,38 @@ mixin) {
|
|
|
898
1022
|
lowerer.unsupported("SC1090", t, "extending generic classes");
|
|
899
1023
|
base = named;
|
|
900
1024
|
if (!base) {
|
|
1025
|
+
if (adoptCallableBase(t.expression))
|
|
1026
|
+
continue;
|
|
901
1027
|
lowerer.unsupported("SC1090", t, `extending classes not declared in the program ('${t.expression.text}')`);
|
|
902
1028
|
}
|
|
903
1029
|
}
|
|
1030
|
+
if (base?.localClass && !functionLocalClass(decl))
|
|
1031
|
+
lowerer.unsupported("SC1090", decl, "extending a function-local class outside a function");
|
|
1032
|
+
if (lowerer.collectingExprClasses.has(decl)) {
|
|
1033
|
+
for (let parent = base; parent; parent = parent.base) {
|
|
1034
|
+
if (parent.builtinEmitter || parent.builtinStream !== undefined) {
|
|
1035
|
+
lowerer.unsupported("SC1090", decl, "classes extending builtin bases as values (the inherited runtime constructor has no class-value adapter)");
|
|
1036
|
+
}
|
|
1037
|
+
}
|
|
1038
|
+
}
|
|
904
1039
|
const fields = new Map(base ? base.fields : []);
|
|
905
|
-
const
|
|
1040
|
+
const errorRooted = (() => {
|
|
1041
|
+
for (let c = base; c; c = c.base)
|
|
1042
|
+
if (c.builtinError)
|
|
1043
|
+
return true;
|
|
1044
|
+
return false;
|
|
1045
|
+
})();
|
|
1046
|
+
const symbolFields = new Map();
|
|
1047
|
+
if (base?.symbolFields)
|
|
1048
|
+
for (const [symbol, name] of base.symbolFields)
|
|
1049
|
+
symbolFields.set(symbol, name);
|
|
1050
|
+
const symbolMethods = new Map();
|
|
1051
|
+
if (base?.symbolMethods)
|
|
1052
|
+
for (const [symbol, name] of base.symbolMethods)
|
|
1053
|
+
symbolMethods.set(symbol, name);
|
|
906
1054
|
const fieldOrder = [];
|
|
907
1055
|
const methods = new Map();
|
|
1056
|
+
const methodEntryFences = new Map();
|
|
908
1057
|
// Own accessor declarations ("get:x"/"set:x" → node), for the
|
|
909
1058
|
// partial-override analysis below (diagnostics need the node).
|
|
910
1059
|
const accessorNodes = new Map();
|
|
@@ -1026,7 +1175,7 @@ mixin) {
|
|
|
1026
1175
|
const type = lowerer.irTypeOf(member.name);
|
|
1027
1176
|
if (type.kind === "void")
|
|
1028
1177
|
lowerer.badType(member.name, lowerer.typeOf(member.name));
|
|
1029
|
-
if (type.kind === "dyn") {
|
|
1178
|
+
if (type.kind === "dyn" && !isJsSourceFile(member.getSourceFile())) {
|
|
1030
1179
|
lowerer.unsupported("SC1090", member.name, "'unknown'-typed static fields");
|
|
1031
1180
|
}
|
|
1032
1181
|
staticFields.push({
|
|
@@ -1043,10 +1192,22 @@ mixin) {
|
|
|
1043
1192
|
if (ts.isMethodDeclaration(member) &&
|
|
1044
1193
|
(ts.isIdentifier(member.name) || ts.isPrivateIdentifier(member.name)) &&
|
|
1045
1194
|
member.body &&
|
|
1046
|
-
member.typeParameters === undefined
|
|
1047
|
-
member.asteriskToken === undefined) {
|
|
1195
|
+
member.typeParameters === undefined) {
|
|
1048
1196
|
const { shapes, funcType: ft } = lowerer.lambdaSignature(member);
|
|
1197
|
+
if (member.asteriskToken !== undefined && ft.ret.kind !== "generator") {
|
|
1198
|
+
lowerer.badType(member.name, lowerer.typeOf(member.name));
|
|
1199
|
+
}
|
|
1049
1200
|
staticMethods.set(member.name.text, { params: shapes, ret: ft.ret, member });
|
|
1201
|
+
if (implicitMonoFile(decl.getSourceFile()) && !functionLocalClass(decl) &&
|
|
1202
|
+
inst === undefined && decl.typeParameters === undefined) {
|
|
1203
|
+
const implicit = implicitAnyParamSymbolsOf(lowerer, member, true);
|
|
1204
|
+
if (implicit)
|
|
1205
|
+
genericStatics.set(member.name.text, {
|
|
1206
|
+
decl: member, baseName: member.name.text,
|
|
1207
|
+
qualifiedName: `%${className}.static:${member.name.text}%implicit`,
|
|
1208
|
+
typeParams: [], instances: new Map(), implicitParams: implicit,
|
|
1209
|
+
});
|
|
1210
|
+
}
|
|
1050
1211
|
}
|
|
1051
1212
|
// GENERIC static methods monomorphize like top-level generic
|
|
1052
1213
|
// functions (`%C.static:m%n`), async ones included — a generic
|
|
@@ -1075,6 +1236,9 @@ mixin) {
|
|
|
1075
1236
|
// 7's ClassElement base carries no `name`; read it structurally
|
|
1076
1237
|
// (every named member kind stores a PropertyName there).
|
|
1077
1238
|
const memberName = member.name;
|
|
1239
|
+
if (errorRooted && memberName && classMemberNameOf(lowerer, memberName) === "cause") {
|
|
1240
|
+
lowerer.unsupported("SC1090", memberName, "redeclaring Error.cause (pass the cause in the Error constructor options)");
|
|
1241
|
+
}
|
|
1078
1242
|
// #PRIVATE members compile: their names ('#m') are unspellable by
|
|
1079
1243
|
// any public identifier, so they ride the ordinary fields/methods
|
|
1080
1244
|
// maps collision-free — with the base-chain walks doubling as
|
|
@@ -1187,6 +1351,35 @@ mixin) {
|
|
|
1187
1351
|
// get/set pair — declare the field and accessors explicitly.
|
|
1188
1352
|
lowerer.unsupported("SC1090", member, "auto-accessor fields ('accessor x')");
|
|
1189
1353
|
}
|
|
1354
|
+
if (ts.isComputedPropertyName(member.name)) {
|
|
1355
|
+
const key = classSymbolKeyOf(lowerer, member.name.expression);
|
|
1356
|
+
if (!key || (!member.initializer && !isJsSourceFile(member.getSourceFile()))) {
|
|
1357
|
+
lowerer.unsupported("SC1090", member, "computed class fields without an initializer and a stable module-level literal Symbol()/Symbol.for() key");
|
|
1358
|
+
}
|
|
1359
|
+
const declared = lowerer.typeOf(member);
|
|
1360
|
+
const inferred = member.type || !member.initializer ? declared : lowerer.checker.getBaseTypeOfLiteralType(lowerer.typeOf(member.initializer));
|
|
1361
|
+
const mapped = member.initializer ? lowerer.mapTypeOf(inferred) ?? dynFallbackType(lowerer, member, inferred) : DYN;
|
|
1362
|
+
const type = mapped ? jsOpenObjectType(member, mapped, lowerer.shapes, lowerer.unions) : null;
|
|
1363
|
+
if (!type || type.kind === "void" || (type.kind === "dyn" && !isJsSourceFile(member.getSourceFile())))
|
|
1364
|
+
lowerer.badType(member, inferred);
|
|
1365
|
+
const undefinedInitializer = !member.initializer ? locOf(member) : undefined;
|
|
1366
|
+
const previous = fields.get(key.fieldName);
|
|
1367
|
+
if (previous) {
|
|
1368
|
+
if (!symbolFields.has(key.identity)) {
|
|
1369
|
+
lowerer.unsupported("SC1090", member.name, `distinct keys sharing the printable name '${symbolFieldDisplayName(key.fieldName)}' in one class`);
|
|
1370
|
+
}
|
|
1371
|
+
if (!typeEquals(previous, type)) {
|
|
1372
|
+
lowerer.unsupported("SC1090", member.name, "redeclaring symbol-keyed fields at a different type");
|
|
1373
|
+
}
|
|
1374
|
+
fieldOrder.push({ name: key.fieldName, type, initializer: member.initializer, ...(undefinedInitializer ? { undefinedInitializer } : {}), redeclared: true });
|
|
1375
|
+
}
|
|
1376
|
+
else {
|
|
1377
|
+
fields.set(key.fieldName, type);
|
|
1378
|
+
fieldOrder.push({ name: key.fieldName, type, initializer: member.initializer, ...(undefinedInitializer ? { undefinedInitializer } : {}) });
|
|
1379
|
+
}
|
|
1380
|
+
symbolFields.set(key.identity, key.fieldName);
|
|
1381
|
+
continue;
|
|
1382
|
+
}
|
|
1190
1383
|
// #private fields ride the ordinary field machinery — the '#'
|
|
1191
1384
|
// name is unspellable publicly, so the slot never collides, and
|
|
1192
1385
|
// enumeration surfaces (inspect) exclude it like Node.
|
|
@@ -1232,14 +1425,21 @@ mixin) {
|
|
|
1232
1425
|
// undefined arm (undefFieldInitLineC — Node defines the property
|
|
1233
1426
|
// as undefined on construction, verified), and reads/writes ride
|
|
1234
1427
|
// the ordinary undefined-armed union machinery.
|
|
1235
|
-
|
|
1428
|
+
let type = lowerer.irTypeOf(member.name);
|
|
1429
|
+
// JS permits reads before a constructor's first assignment even
|
|
1430
|
+
// when its inferred field type omits undefined.
|
|
1431
|
+
if (isJsSourceFile(member.getSourceFile()) && !member.initializer && type.kind !== "dyn") {
|
|
1432
|
+
type = lowerer.withUndefinedArmOf(type) ?? DYN;
|
|
1433
|
+
}
|
|
1236
1434
|
if (type.kind === "void")
|
|
1237
1435
|
lowerer.badType(member.name, lowerer.typeOf(member.name));
|
|
1238
|
-
//
|
|
1239
|
-
//
|
|
1240
|
-
|
|
1436
|
+
// Bundled JS declares fields without annotations before assigning
|
|
1437
|
+
// them in the constructor. Use the same native checked-dynamic
|
|
1438
|
+
// storage as implicit constructor-assigned JS fields.
|
|
1439
|
+
if (type.kind === "dyn" && !isJsSourceFile(member.getSourceFile())) {
|
|
1241
1440
|
lowerer.unsupported("SC1090", member.name, "'unknown'-typed class fields");
|
|
1242
1441
|
}
|
|
1442
|
+
const undefinedInitializer = type.kind === "dyn" && !member.initializer ? locOf(member) : undefined;
|
|
1243
1443
|
if (fields.has(member.name.text)) {
|
|
1244
1444
|
// REDECLARING an inherited field: Node [[Define]]s the OWN
|
|
1245
1445
|
// property again when THIS class's field initializers run
|
|
@@ -1249,13 +1449,12 @@ mixin) {
|
|
|
1249
1449
|
// slot, no new slot, no layout change (the `class
|
|
1250
1450
|
// ConfigError extends Error { name = "ConfigError" }`; the
|
|
1251
1451
|
// builtin Error prefix included — reads, toString, and throw
|
|
1252
|
-
// reports all answer the overwritten name like Node). A
|
|
1253
|
-
//
|
|
1254
|
-
//
|
|
1255
|
-
// no single slot type — both keep the fence.
|
|
1452
|
+
// reports all answer the overwritten name like Node). A bare
|
|
1453
|
+
// JS dyn redeclaration resets the existing slot to undefined.
|
|
1454
|
+
// Other bare or type-changing redeclarations keep the fence.
|
|
1256
1455
|
const baseType = fields.get(member.name.text);
|
|
1257
|
-
if (member.initializer && typeEquals(type, baseType)) {
|
|
1258
|
-
fieldOrder.push({ name: member.name.text, type, initializer: member.initializer, redeclared: true });
|
|
1456
|
+
if ((member.initializer || type.kind === "dyn") && typeEquals(type, baseType)) {
|
|
1457
|
+
fieldOrder.push({ name: member.name.text, type, initializer: member.initializer, ...(undefinedInitializer ? { undefinedInitializer } : {}), redeclared: true });
|
|
1259
1458
|
continue;
|
|
1260
1459
|
}
|
|
1261
1460
|
lowerer.unsupported("SC1090", member.name, member.initializer
|
|
@@ -1280,7 +1479,7 @@ mixin) {
|
|
|
1280
1479
|
// (the constructor may be declared later in the class body).
|
|
1281
1480
|
const admitsUndefined = (type.kind === "union" &&
|
|
1282
1481
|
(lowerer.unions.get(type.unionId)?.arms.some((a) => a.kind === "undefinedT") ?? false)) ||
|
|
1283
|
-
type.kind === "jsval";
|
|
1482
|
+
type.kind === "jsval" || type.kind === "dyn";
|
|
1284
1483
|
if (!member.initializer && !admitsUndefined) {
|
|
1285
1484
|
const opts = lowerer.program.getCompilerOptions();
|
|
1286
1485
|
const spi = opts.strictPropertyInitialization ?? opts.strict ?? false;
|
|
@@ -1300,7 +1499,7 @@ mixin) {
|
|
|
1300
1499
|
}
|
|
1301
1500
|
}
|
|
1302
1501
|
fields.set(member.name.text, type);
|
|
1303
|
-
fieldOrder.push({ name: member.name.text, type, initializer: member.initializer });
|
|
1502
|
+
fieldOrder.push({ name: member.name.text, type, initializer: member.initializer, ...(undefinedInitializer ? { undefinedInitializer } : {}) });
|
|
1304
1503
|
}
|
|
1305
1504
|
else if (ts.isConstructorDeclaration(member)) {
|
|
1306
1505
|
// A body-less constructor is an OVERLOAD SIGNATURE: type-world,
|
|
@@ -1344,6 +1543,9 @@ mixin) {
|
|
|
1344
1543
|
lowerer.unsupported("SC1090", p, "this parameter property form");
|
|
1345
1544
|
}
|
|
1346
1545
|
const name = p.name.text;
|
|
1546
|
+
if (errorRooted && name === "cause") {
|
|
1547
|
+
lowerer.unsupported("SC1090", p.name, "redeclaring Error.cause (pass the cause in the Error constructor options)");
|
|
1548
|
+
}
|
|
1347
1549
|
const shape = lowerer.paramShape(p);
|
|
1348
1550
|
const type = shape.bodyType ?? shape.type;
|
|
1349
1551
|
if (type.kind === "void")
|
|
@@ -1368,15 +1570,18 @@ mixin) {
|
|
|
1368
1570
|
const mName = classMemberNameOf(lowerer, member.name);
|
|
1369
1571
|
if (mName === null)
|
|
1370
1572
|
lowerer.unsupported("SC1090", member, "computed method names");
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1573
|
+
if (ts.isComputedPropertyName(member.name)) {
|
|
1574
|
+
const key = classSymbolKeyOf(lowerer, member.name.expression);
|
|
1575
|
+
if (key) {
|
|
1576
|
+
if ([...symbolMethods, ...symbolFields].some(([identity, name]) => name === mName && identity !== key.identity)) {
|
|
1577
|
+
lowerer.unsupported("SC1090", member.name, `distinct symbol keys sharing the printable name '${symbolFieldDisplayName(mName)}' in one class`);
|
|
1578
|
+
}
|
|
1579
|
+
symbolMethods.set(key.identity, mName);
|
|
1580
|
+
}
|
|
1379
1581
|
}
|
|
1582
|
+
// Generator calls use their spawn wrapper. Public methods are
|
|
1583
|
+
// direct calls only when no subclass overrides the method;
|
|
1584
|
+
// override chains involving generators fence below.
|
|
1380
1585
|
// An ABSTRACT method is a signature with no body — type-world,
|
|
1381
1586
|
// except that it declares the vtable slot: calls through
|
|
1382
1587
|
// base-typed receivers are ordinary virtual dispatch, and tsc
|
|
@@ -1431,20 +1636,9 @@ mixin) {
|
|
|
1431
1636
|
collectGenericMember(member, false);
|
|
1432
1637
|
continue;
|
|
1433
1638
|
}
|
|
1434
|
-
// Async
|
|
1435
|
-
//
|
|
1436
|
-
//
|
|
1437
|
-
// surface is synchronous still compiles (commander: parse()
|
|
1438
|
-
// works, parseAsync() traps where called). TS async methods
|
|
1439
|
-
// collect below like any method: the body is an async
|
|
1440
|
-
// IrFunction (fiber spawn wrapper, `this` as param 0), calls
|
|
1441
|
-
// dispatch STATICALLY — override chains fence (the vtable slot
|
|
1442
|
-
// machinery has no fiber-spawn story), so every call site is a
|
|
1443
|
-
// direct call the emitter routes through the spawn wrapper.
|
|
1444
|
-
if (member.modifiers?.some((m) => m.kind === ts.SyntaxKind.AsyncKeyword) &&
|
|
1445
|
-
isJsSourceFile(decl.getSourceFile())) {
|
|
1446
|
-
continue;
|
|
1447
|
-
}
|
|
1639
|
+
// Async methods collect with the same direct-call spawn wrapper
|
|
1640
|
+
// for JavaScript and TypeScript classes. Override chains remain
|
|
1641
|
+
// fenced below because vtable slots cannot enter that wrapper.
|
|
1448
1642
|
// IMPLICIT-ANY monomorphization (npm-static JS): a method whose
|
|
1449
1643
|
// signature carries bindable untyped params collects like a
|
|
1450
1644
|
// GENERIC method — into genericMethods, no vtable slot, one
|
|
@@ -1454,13 +1648,14 @@ mixin) {
|
|
|
1454
1648
|
// dispatch worlds could meet: an inherited declaration of the
|
|
1455
1649
|
// name (the override stays on the vtable), a shadowed field, or
|
|
1456
1650
|
// a generic-class instantiation's member.
|
|
1457
|
-
if (implicitMonoFile(decl.getSourceFile()) &&
|
|
1651
|
+
if (implicitMonoFile(decl.getSourceFile()) && !functionLocalClass(decl) &&
|
|
1458
1652
|
ts.isIdentifier(member.name) &&
|
|
1653
|
+
!lowerer.virtualJsMethods.has(member) &&
|
|
1459
1654
|
inst === undefined && decl.typeParameters === undefined &&
|
|
1460
1655
|
!fields.has(member.name.text) &&
|
|
1461
1656
|
!lowerer.findMethodOn(base, member.name.text) &&
|
|
1462
1657
|
!findGenericMethodOn(lowerer, base, member.name.text)) {
|
|
1463
|
-
const implicit = implicitAnyParamSymbolsOf(lowerer, member);
|
|
1658
|
+
const implicit = implicitAnyParamSymbolsOf(lowerer, member, true);
|
|
1464
1659
|
if (implicit) {
|
|
1465
1660
|
genericMethods.set(member.name.text, {
|
|
1466
1661
|
decl: member,
|
|
@@ -1474,6 +1669,15 @@ mixin) {
|
|
|
1474
1669
|
}
|
|
1475
1670
|
}
|
|
1476
1671
|
const { shapes, funcType: ft } = lowerer.lambdaSignature(member);
|
|
1672
|
+
// JS subclasses can add parameters to a method. Reserve checked
|
|
1673
|
+
// argument slots in the base before constructing its vtable; shorter
|
|
1674
|
+
// bodies ignore them and omitted call arguments become undefined.
|
|
1675
|
+
const virtualArity = lowerer.virtualJsMethodArity.get(member) ?? shapes.length;
|
|
1676
|
+
if (virtualArity > shapes.length && !bodyReadsArguments(member) &&
|
|
1677
|
+
shapes.every((p) => p.type.kind === "dyn" && (p.mode === "required" || p.mode === "omittable"))) {
|
|
1678
|
+
while (shapes.length < virtualArity)
|
|
1679
|
+
shapes.push({ type: DYN, mode: "omittable" });
|
|
1680
|
+
}
|
|
1477
1681
|
if (fields.has(mName)) {
|
|
1478
1682
|
lowerer.unsupported("SC1090", member.name, "methods shadowing inherited fields");
|
|
1479
1683
|
}
|
|
@@ -1499,17 +1703,61 @@ mixin) {
|
|
|
1499
1703
|
// against the STATIC receiver's shape, so `m(x?: number)` and
|
|
1500
1704
|
// `m(x: number | undefined)` interchange soundly in overrides.
|
|
1501
1705
|
const overridden = lowerer.findMethodOn(base, mName);
|
|
1502
|
-
if (overridden
|
|
1503
|
-
//
|
|
1504
|
-
//
|
|
1505
|
-
|
|
1506
|
-
|
|
1706
|
+
if (overridden && isJsSourceFile(member.getSourceFile())) {
|
|
1707
|
+
// Fluent overrides return the same native receiver. Keep the
|
|
1708
|
+
// inherited return ABI and upcast `this` when lowering returns.
|
|
1709
|
+
if (overridden.sig.ret.kind === "object" && base &&
|
|
1710
|
+
(base.def.name === overridden.sig.ret.className || lowerer.isSubclassOf(base.def.name, overridden.sig.ret.className)) &&
|
|
1711
|
+
returnsOnlyThis(member))
|
|
1712
|
+
ft.ret = overridden.sig.ret;
|
|
1713
|
+
// An unannotated JS parameter can use the base's typed ABI.
|
|
1714
|
+
// Defaults stay local to each declaration, so only inherited
|
|
1715
|
+
// required/optional slots participate in this refinement.
|
|
1716
|
+
for (let i = 0; i < shapes.length; i++) {
|
|
1717
|
+
const parameter = member.parameters[i];
|
|
1718
|
+
const inherited = overridden.sig.params[i];
|
|
1719
|
+
if (parameter && inherited && !parameter.type && !parameter.initializer && !parameter.dotDotDotToken &&
|
|
1720
|
+
shapes[i].type.kind === "dyn" && inherited.type.kind !== "dyn" &&
|
|
1721
|
+
(inherited.mode === "required" || inherited.mode === "omittable")) {
|
|
1722
|
+
shapes[i] = { ...inherited };
|
|
1723
|
+
}
|
|
1724
|
+
}
|
|
1725
|
+
}
|
|
1726
|
+
// JS overrides may ignore trailing arguments. Retain the base's
|
|
1727
|
+
// checked-value ABI slots as unused parameters, and let shorter
|
|
1728
|
+
// calls fill them with undefined. Typed tails and rest/arguments
|
|
1729
|
+
// readers keep the exact-signature fence.
|
|
1730
|
+
if (overridden && isJsSourceFile(member.getSourceFile()) &&
|
|
1731
|
+
shapes.length < overridden.sig.params.length &&
|
|
1732
|
+
!bodyReadsArguments(member) &&
|
|
1733
|
+
shapes.every((p, i) => (p.mode === "required" || p.mode === "omittable") && typeEquals(p.type, overridden.sig.params[i].type)) &&
|
|
1734
|
+
overridden.sig.params.slice(shapes.length).every((p) => p.type.kind === "dyn" && (p.mode === "required" || p.mode === "omittable"))) {
|
|
1735
|
+
shapes.push(...overridden.sig.params.slice(shapes.length).map((p) => ({ type: p.type, mode: "omittable" })));
|
|
1507
1736
|
}
|
|
1508
1737
|
if (overridden &&
|
|
1509
1738
|
(overridden.sig.params.length !== shapes.length ||
|
|
1510
1739
|
!overridden.sig.params.every((p, i) => typeEquals(p.type, shapes[i].type)) ||
|
|
1511
1740
|
!typeEquals(overridden.sig.ret, ft.ret))) {
|
|
1512
|
-
|
|
1741
|
+
const fencedJsOverride = isJsSourceFile(member.getSourceFile()) &&
|
|
1742
|
+
overridden.declarer.decl !== null && isJsSourceFile(overridden.declarer.decl.getSourceFile()) &&
|
|
1743
|
+
member.modifiers?.some((m) => m.kind === ts.SyntaxKind.AsyncKeyword) !== true &&
|
|
1744
|
+
overridden.sig.async !== true &&
|
|
1745
|
+
member.asteriskToken === undefined && overridden.sig.gen === undefined;
|
|
1746
|
+
if (fencedJsOverride) {
|
|
1747
|
+
// A dormant JS method must not poison the whole class. Keep
|
|
1748
|
+
// the inherited call/dispatch ABI and refuse at method entry;
|
|
1749
|
+
// lowering this body with the base signature would change JS.
|
|
1750
|
+
const returnOnly = overridden.sig.params.length === shapes.length &&
|
|
1751
|
+
overridden.sig.params.every((p, i) => typeEquals(p.type, shapes[i].type));
|
|
1752
|
+
methodEntryFences.set(mName, unsupportedDiag("SC1090", locOf(member.name), returnOnly
|
|
1753
|
+
? `overriding method '${mName}' with a different return type (the native return type must match the base declaration exactly)`
|
|
1754
|
+
: `overriding method '${mName}' with a different signature (the native parameter and return types must match the base declaration exactly)`));
|
|
1755
|
+
shapes.splice(0, shapes.length, ...overridden.sig.params);
|
|
1756
|
+
ft.ret = overridden.sig.ret;
|
|
1757
|
+
}
|
|
1758
|
+
else {
|
|
1759
|
+
lowerer.unsupported("SC1090", member.name, "overriding a method with a different signature (parameter and return types must match the base declaration exactly)");
|
|
1760
|
+
}
|
|
1513
1761
|
}
|
|
1514
1762
|
const asyncMember = member.modifiers?.some((m) => m.kind === ts.SyntaxKind.AsyncKeyword) === true;
|
|
1515
1763
|
// Async methods dispatch STATICALLY (the body enters through its
|
|
@@ -1519,7 +1767,10 @@ mixin) {
|
|
|
1519
1767
|
if (overridden && (asyncMember || overridden.sig.async === true)) {
|
|
1520
1768
|
lowerer.unsupported("SC1090", member.name, `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)`);
|
|
1521
1769
|
}
|
|
1522
|
-
|
|
1770
|
+
if (overridden && (member.asteriskToken !== undefined || overridden.sig.gen !== undefined)) {
|
|
1771
|
+
lowerer.unsupported("SC1090", member.name, `overriding the generator method '${mName}' (generator methods dispatch statically — a virtual slot cannot enter their spawn wrapper)`);
|
|
1772
|
+
}
|
|
1773
|
+
// A GENERATOR method carries its channels on the sig:
|
|
1523
1774
|
// the body lowers as a generator IrFunction (`this` as param 0),
|
|
1524
1775
|
// and every call — direct by construction — enters through the
|
|
1525
1776
|
// emitted gen-spawn wrapper, answering the suspended generator.
|
|
@@ -1609,7 +1860,7 @@ mixin) {
|
|
|
1609
1860
|
lowerer.unsupported("SC1090", member, "index signatures");
|
|
1610
1861
|
}
|
|
1611
1862
|
else if (!ts.isSemicolonClassElement(member)) {
|
|
1612
|
-
lowerer.unsupported("SC1090", member, `syntax '${ts.
|
|
1863
|
+
lowerer.unsupported("SC1090", member, `syntax '${ts.syntaxKindName(member.kind)}'`);
|
|
1613
1864
|
}
|
|
1614
1865
|
}
|
|
1615
1866
|
// Parameter properties join the shape FIRST among own fields —
|
|
@@ -1724,6 +1975,9 @@ mixin) {
|
|
|
1724
1975
|
// forbids via strictPropertyInitialization — so they keep a named
|
|
1725
1976
|
// fence instead of a silent undefined.
|
|
1726
1977
|
if (isJsSourceFile(decl.getSourceFile())) {
|
|
1978
|
+
const hasAccessor = (name) => methods.has(`get:${name}`) || methods.has(`set:${name}`) ||
|
|
1979
|
+
lowerer.findMethodOn(base, `get:${name}`) !== null ||
|
|
1980
|
+
lowerer.findMethodOn(base, `set:${name}`) !== null;
|
|
1727
1981
|
// Named classes (declarations and self-binding expressions) resolve
|
|
1728
1982
|
// by name; the nameless default-export declaration by its module's
|
|
1729
1983
|
// default-export symbol.
|
|
@@ -1755,9 +2009,11 @@ mixin) {
|
|
|
1755
2009
|
lhs.expression.kind === ts.SyntaxKind.ThisKeyword) {
|
|
1756
2010
|
const assign = lhs;
|
|
1757
2011
|
const name = assign.name.text;
|
|
2012
|
+
if (errorRooted && name === "cause")
|
|
2013
|
+
continue;
|
|
1758
2014
|
// Later assignments to an already-declared field (own or
|
|
1759
2015
|
// inherited) are writes, not declarations.
|
|
1760
|
-
if (fields.has(name))
|
|
2016
|
+
if (fields.has(name) || hasAccessor(name))
|
|
1761
2017
|
continue;
|
|
1762
2018
|
if (methods.has(name) || lowerer.findMethodOn(base, name)) {
|
|
1763
2019
|
lowerer.unsupported("SC1090", assign, "constructor-assigned fields shadowing methods");
|
|
@@ -1772,11 +2028,16 @@ mixin) {
|
|
|
1772
2028
|
// TS-annotated `unknown` fields keep their fence (KEEP NARROW
|
|
1773
2029
|
// applies where an annotation could say better).
|
|
1774
2030
|
let type = t ? (lowerer.mapTypeOf(t) ?? dynFallbackType(lowerer, assign, t)) : null;
|
|
2031
|
+
if (t && (t.flags & (ts.TypeFlags.Null | ts.TypeFlags.Undefined)) !== 0 && isJsSourceFile(decl.getSourceFile()))
|
|
2032
|
+
type = DYN;
|
|
2033
|
+
if (type)
|
|
2034
|
+
type = jsOpenObjectType(assign, type, lowerer.shapes, lowerer.unions);
|
|
1775
2035
|
if (type?.kind === "dyn") {
|
|
1776
2036
|
type = inferredEmptyCollectionFieldType(lowerer, decl, name, rhs) ?? type;
|
|
1777
2037
|
}
|
|
1778
2038
|
if (!type || type.kind === "void")
|
|
1779
2039
|
lowerer.badType(assign, t ?? lowerer.typeOf(assign));
|
|
2040
|
+
type = jsFieldInitializerType(lowerer, type, rhs);
|
|
1780
2041
|
// A JSDoc claim the BODY contradicts (`@type {Command}`
|
|
1781
2042
|
// assigned `undefined` — the lazy-init idiom): the
|
|
1782
2043
|
// representation follows the body — the field widens to the
|
|
@@ -1801,7 +2062,7 @@ mixin) {
|
|
|
1801
2062
|
continue;
|
|
1802
2063
|
}
|
|
1803
2064
|
// `this[kLimit] = v` at the constructor's top level with a
|
|
1804
|
-
// STATICALLY-RESOLVABLE
|
|
2065
|
+
// STATICALLY-RESOLVABLE symbol key (classSymbolKeyOf's
|
|
1805
2066
|
// contract — the countdown.js idiom): the key is a compile-time
|
|
1806
2067
|
// identity, so the member is an ordinary hidden field of the
|
|
1807
2068
|
// static layout under Node's inspect spelling; no runtime
|
|
@@ -1811,17 +2072,17 @@ mixin) {
|
|
|
1811
2072
|
// late-bound fence below.
|
|
1812
2073
|
if (lhs && ts.isElementAccessExpression(lhs) &&
|
|
1813
2074
|
lhs.expression.kind === ts.SyntaxKind.ThisKeyword) {
|
|
1814
|
-
const key =
|
|
2075
|
+
const key = classSymbolKeyOf(lowerer, lhs.argumentExpression);
|
|
1815
2076
|
if (!key)
|
|
1816
2077
|
continue;
|
|
1817
2078
|
// A key already declared (own or inherited) makes later
|
|
1818
2079
|
// assignments writes, not declarations.
|
|
1819
|
-
if (symbolFields.has(key.
|
|
2080
|
+
if (symbolFields.has(key.identity))
|
|
1820
2081
|
continue;
|
|
1821
2082
|
if (fields.has(key.fieldName)) {
|
|
1822
2083
|
// Two DISTINCT Symbol(...) consts with one description in
|
|
1823
2084
|
// one layout would need one printable name for two slots.
|
|
1824
|
-
lowerer.unsupported("SC1090", lhs, `distinct symbol keys sharing the printable name '${key.fieldName}' in one class`);
|
|
2085
|
+
lowerer.unsupported("SC1090", lhs, `distinct symbol keys sharing the printable name '${symbolFieldDisplayName(key.fieldName)}' in one class`);
|
|
1825
2086
|
}
|
|
1826
2087
|
const propSym = lateBoundByKey.get(key.sym);
|
|
1827
2088
|
// tsgo does not synthesize the late-bound `__@name@id`
|
|
@@ -1838,11 +2099,13 @@ mixin) {
|
|
|
1838
2099
|
: rhs
|
|
1839
2100
|
? lowerer.checker.getBaseTypeOfLiteralType(lowerer.checker.getTypeAtLocation(rhs))
|
|
1840
2101
|
: undefined;
|
|
1841
|
-
|
|
2102
|
+
let type = t ? (lowerer.mapTypeOf(t) ?? dynFallbackType(lowerer, lhs, t)) : null;
|
|
2103
|
+
if (type)
|
|
2104
|
+
type = jsOpenObjectType(lhs, type, lowerer.shapes, lowerer.unions);
|
|
1842
2105
|
if (!type || type.kind === "void")
|
|
1843
2106
|
lowerer.badType(lhs, t ?? lowerer.typeOf(lhs));
|
|
1844
2107
|
fields.set(key.fieldName, type);
|
|
1845
|
-
symbolFields.set(key.
|
|
2108
|
+
symbolFields.set(key.identity, key.fieldName);
|
|
1846
2109
|
fieldOrder.push({ name: key.fieldName, type, initializer: undefined });
|
|
1847
2110
|
}
|
|
1848
2111
|
}
|
|
@@ -1853,9 +2116,11 @@ mixin) {
|
|
|
1853
2116
|
// static layouts cannot represent. Named fence, at the first
|
|
1854
2117
|
// assignment site.
|
|
1855
2118
|
for (const p of instType ? lowerer.checker.getPropertiesOfType(instType) : []) {
|
|
2119
|
+
if (errorRooted && p.name === "cause")
|
|
2120
|
+
continue;
|
|
1856
2121
|
if (fields.has(p.name) || methods.has(p.name))
|
|
1857
2122
|
continue;
|
|
1858
|
-
if (
|
|
2123
|
+
if (hasAccessor(p.name))
|
|
1859
2124
|
continue;
|
|
1860
2125
|
if (base && (base.fields.has(p.name) || lowerer.findMethodOn(base, p.name)))
|
|
1861
2126
|
continue;
|
|
@@ -1866,14 +2131,15 @@ mixin) {
|
|
|
1866
2131
|
// Late-bound properties: the ones the scan above collected are
|
|
1867
2132
|
// real fields under their printable names — skip. The rest keep
|
|
1868
2133
|
// a fence that names the supported form: keys that are runtime
|
|
1869
|
-
// identities (symbol parameters,
|
|
2134
|
+
// identities (symbol parameters, mutable bindings, computed
|
|
1870
2135
|
// descriptions) or assignments outside the constructor's top
|
|
1871
2136
|
// level.
|
|
1872
2137
|
if (p.name.startsWith("__@")) {
|
|
1873
2138
|
const keySym = lateBoundKeySymOf(lowerer, p);
|
|
1874
|
-
|
|
2139
|
+
const key = keySym ? classSymbolKeyOfSymbol(lowerer, keySym) : null;
|
|
2140
|
+
if (key && symbolFields.has(key.identity))
|
|
1875
2141
|
continue;
|
|
1876
|
-
lowerer.unsupported("SC1090", site, "symbol-keyed class fields outside the supported form (a module-level
|
|
2142
|
+
lowerer.unsupported("SC1090", site, "symbol-keyed class fields outside the supported form (a stable module-level literal Symbol()/Symbol.for() key, assigned unconditionally at the top of the constructor)");
|
|
1877
2143
|
}
|
|
1878
2144
|
// JS classes: a property first assigned in a method or a
|
|
1879
2145
|
// conditional constructor position holds `undefined` until the
|
|
@@ -1888,6 +2154,11 @@ mixin) {
|
|
|
1888
2154
|
if (isJsSourceFile(decl.getSourceFile())) {
|
|
1889
2155
|
const armed = undefArmedFieldType(lowerer, p);
|
|
1890
2156
|
if (armed !== null) {
|
|
2157
|
+
// Unknown JS properties use the instance bag: they do not
|
|
2158
|
+
// exist until assigned, and a subclass may declare the same
|
|
2159
|
+
// name as an ordinary layout field.
|
|
2160
|
+
if (armed.kind === "dyn")
|
|
2161
|
+
continue;
|
|
1891
2162
|
fields.set(p.name, armed);
|
|
1892
2163
|
fieldOrder.push({ name: p.name, type: armed, initializer: undefined });
|
|
1893
2164
|
continue;
|
|
@@ -1925,7 +2196,7 @@ mixin) {
|
|
|
1925
2196
|
// synthesized constructor forwards the same params to super).
|
|
1926
2197
|
const ctorParams = ctor && !mixinForwarding
|
|
1927
2198
|
? lowerer.paramShapes(ctor.parameters)
|
|
1928
|
-
: (base?.ctorParams ?? []);
|
|
2199
|
+
: (base?.ctorParams ?? (callableBase ? [{ type: DYN, mode: "dynRest" }] : []));
|
|
1929
2200
|
const info = {
|
|
1930
2201
|
def: {
|
|
1931
2202
|
name: className,
|
|
@@ -1935,6 +2206,9 @@ mixin) {
|
|
|
1935
2206
|
// INSTANTIATION prints its family's name — JS has one `Box`.
|
|
1936
2207
|
jsName: jsNameOverride ?? decl.name?.text ?? "",
|
|
1937
2208
|
...(base ? { base: base.def.name } : {}),
|
|
2209
|
+
jsLength: ctor?.parameters.findIndex((parameter) => parameter.initializer || parameter.dotDotDotToken) === -1
|
|
2210
|
+
? ctor.parameters.length
|
|
2211
|
+
: Math.max(0, ctor?.parameters.findIndex((parameter) => parameter.initializer || parameter.dotDotDotToken) ?? 0),
|
|
1938
2212
|
// Layout order: the base chain's fields as an IDENTICAL prefix,
|
|
1939
2213
|
// then this class's own — what makes an upcast a reinterpret.
|
|
1940
2214
|
// Redeclared INHERITED fields contribute no slot (their
|
|
@@ -1955,18 +2229,21 @@ mixin) {
|
|
|
1955
2229
|
fields,
|
|
1956
2230
|
fieldOrder,
|
|
1957
2231
|
methods,
|
|
2232
|
+
...(methodEntryFences.size > 0 ? { methodEntryFences } : {}),
|
|
1958
2233
|
decl,
|
|
1959
2234
|
...(emitOverride !== undefined ? { emitOverride } : {}),
|
|
1960
2235
|
ctor,
|
|
1961
2236
|
ctorParams,
|
|
1962
2237
|
...(paramProps.length > 0 ? { paramProps } : {}),
|
|
1963
2238
|
base,
|
|
2239
|
+
...(callableBase ? { callableBase } : {}),
|
|
1964
2240
|
subclasses: [],
|
|
1965
2241
|
throwingSetters,
|
|
1966
2242
|
staticFields,
|
|
1967
2243
|
...(staticMethods.size > 0 ? { staticMethods } : {}),
|
|
1968
2244
|
...(staticBlocks.length > 0 ? { staticBlocks } : {}),
|
|
1969
2245
|
...(symbolFields.size > 0 ? { symbolFields } : {}),
|
|
2246
|
+
...(symbolMethods.size > 0 ? { symbolMethods } : {}),
|
|
1970
2247
|
...(classDecoratorNodes.length > 0 ? { classDecorators: { nodes: classDecoratorNodes } } : {}),
|
|
1971
2248
|
...(deferredInitFields.size > 0 ? { deferredInitFields } : {}),
|
|
1972
2249
|
};
|
|
@@ -2020,6 +2297,9 @@ mixin) {
|
|
|
2020
2297
|
if (base)
|
|
2021
2298
|
base.subclasses.push(info);
|
|
2022
2299
|
lowerer.classes.set(className, info);
|
|
2300
|
+
if (callableBase) {
|
|
2301
|
+
lowerer.globalsList.push({ id: callableBase.constructorId, name: `${className} base`, type: DYN, mutable: false }, { id: callableBase.prototypeId, name: `${className} base prototype`, type: DYN, mutable: false });
|
|
2302
|
+
}
|
|
2023
2303
|
// A NAMED class binds its name (declarations in their scope, class
|
|
2024
2304
|
// expressions inside their own bodies — tsc resolves both to this
|
|
2025
2305
|
// symbol); a nameless default-export declaration binds its module's
|
|
@@ -2051,7 +2331,7 @@ mixin) {
|
|
|
2051
2331
|
* unmapped, the fenced-JS-class story. Null answers (unmappable type
|
|
2052
2332
|
* arguments, the instance cap, an uncollected family) make the whole
|
|
2053
2333
|
* reference unmappable — per-site diagnostics own the fence. */
|
|
2054
|
-
export function genericClassInstanceType(lowerer, decl, ref) {
|
|
2334
|
+
export function genericClassInstanceType(lowerer, decl, ref, mapArgument) {
|
|
2055
2335
|
const gci = lowerer.genericClassByDecl.get(decl);
|
|
2056
2336
|
if (!gci) {
|
|
2057
2337
|
// The family never collected (a deferred/poisoned declaration): the
|
|
@@ -2078,7 +2358,7 @@ export function genericClassInstanceType(lowerer, decl, ref) {
|
|
|
2078
2358
|
const mapped = [];
|
|
2079
2359
|
if (args.length === gci.typeParams.length) {
|
|
2080
2360
|
for (const a of args) {
|
|
2081
|
-
const m = lowerer.mapTypeOf(a);
|
|
2361
|
+
const m = lowerer.mapTypeOf(a, mapArgument);
|
|
2082
2362
|
if (!m || m.kind === "void") {
|
|
2083
2363
|
// An UNBOUND type parameter argument (`Box<T>` outside any
|
|
2084
2364
|
// instantiation) stays honestly unmapped — nothing concrete is
|
|
@@ -2218,6 +2498,15 @@ function lowerStaticFieldInitsInner(lowerer, info) {
|
|
|
2218
2498
|
// initializers and static blocks (verified against Node — the
|
|
2219
2499
|
// decorated result is what `this`/the class name mean inside them).
|
|
2220
2500
|
const out = [...lowerClassDecoration(lowerer, info)];
|
|
2501
|
+
if (info.callableBase) {
|
|
2502
|
+
const { expression, constructorId, prototypeId } = info.callableBase;
|
|
2503
|
+
const loc = locOf(expression);
|
|
2504
|
+
out.push({ kind: "assign", localId: constructorId, value: lowerer.lowerExprExpecting(expression, DYN), loc }, { kind: "assign", localId: prototypeId, value: { kind: "libCall", fn: "dyn.classBasePrototype",
|
|
2505
|
+
args: [{ kind: "varRef", localId: constructorId, type: DYN, loc }], type: DYN, loc }, loc });
|
|
2506
|
+
const prototype = classPrototypeData(lowerer, info, loc);
|
|
2507
|
+
if (prototype)
|
|
2508
|
+
out.push({ kind: "exprStmt", expr: prototype, loc });
|
|
2509
|
+
}
|
|
2221
2510
|
const items = [
|
|
2222
2511
|
...info.staticFields.map((f) => ({ pos: f.initializer.getStart(), kind: "field", f })),
|
|
2223
2512
|
...(info.staticBlocks ?? []).map((b) => ({ pos: b.getStart(), kind: "block", b })),
|
|
@@ -2232,6 +2521,7 @@ function lowerStaticFieldInitsInner(lowerer, info) {
|
|
|
2232
2521
|
const f = item.f;
|
|
2233
2522
|
lowerer.stats.statementsTotal++;
|
|
2234
2523
|
lowerer.bumpFileStat(locOf(f.initializer).file, "total");
|
|
2524
|
+
const diagsBefore = lowerer.diags.length;
|
|
2235
2525
|
try {
|
|
2236
2526
|
// `this` in a static field initializer names the CLASS (like a
|
|
2237
2527
|
// static block's), with arrows transparent and this-binding
|
|
@@ -2246,6 +2536,11 @@ function lowerStaticFieldInitsInner(lowerer, info) {
|
|
|
2246
2536
|
throw e;
|
|
2247
2537
|
lowerer.stats.statementsFailed++;
|
|
2248
2538
|
lowerer.bumpFileStat(locOf(f.initializer).file, "failed");
|
|
2539
|
+
if (isJsSourceFile(f.initializer.getSourceFile()) && lowerer.diagSink === null) {
|
|
2540
|
+
const fence = lowerer.deferToRuntimeFence(diagsBefore, f.initializer, { kind: "statement" });
|
|
2541
|
+
if (fence)
|
|
2542
|
+
out.push(fence);
|
|
2543
|
+
}
|
|
2249
2544
|
}
|
|
2250
2545
|
}
|
|
2251
2546
|
return out;
|
|
@@ -2520,6 +2815,9 @@ function staticMethodValue(lowerer, declarer, name, sig, blame, loc) {
|
|
|
2520
2815
|
export function classValueRef(lowerer, info, blame) {
|
|
2521
2816
|
const display = info.def.name.replace(/^%|^%m\d+\./, "");
|
|
2522
2817
|
fenceDecorationThrows(lowerer, info, blame);
|
|
2818
|
+
if (info.localClass && !ts.isClassExpression(blame) && !ts.isClassDeclaration(blame)) {
|
|
2819
|
+
lowerer.unsupported("SC1090", blame, "named self references inside function-local classes");
|
|
2820
|
+
}
|
|
2523
2821
|
if (info.generic) {
|
|
2524
2822
|
// `typeof Box` — the uninstantiated FAMILY as a value: no thunk, no
|
|
2525
2823
|
// single constructor ABI. INSTANTIATIONS have class objects
|
|
@@ -2529,10 +2827,10 @@ export function classValueRef(lowerer, info, blame) {
|
|
|
2529
2827
|
if (info.builtinError || info.builtinEmitter || info.builtinStream !== undefined) {
|
|
2530
2828
|
lowerer.unsupported("SC1090", blame, `builtin classes as values ('${display}' is runtime-provided — reference program-declared classes instead)`);
|
|
2531
2829
|
}
|
|
2532
|
-
if (lowerer.
|
|
2830
|
+
if (lowerer.inheritsBuiltinEmitterCtor(info) ||
|
|
2533
2831
|
inheritsBuiltinStreamCtor(lowerer, info) ||
|
|
2534
2832
|
(() => { for (let c = info.base; c; c = c.base)
|
|
2535
|
-
if (c.
|
|
2833
|
+
if (c.builtinEmitter || c.builtinStream !== undefined)
|
|
2536
2834
|
return true; return false; })()) {
|
|
2537
2835
|
lowerer.unsupported("SC1090", blame, `classes extending builtin bases as values ('${display}' inherits a runtime-provided constructor)`);
|
|
2538
2836
|
}
|
|
@@ -2554,6 +2852,26 @@ export function ctorAbiEquals(lowerer, sub, sup) {
|
|
|
2554
2852
|
const b = sup.ctorParams;
|
|
2555
2853
|
return a.length === b.length && a.every((p, i) => p.mode === b[i].mode && typeEquals(p.type, b[i].type));
|
|
2556
2854
|
}
|
|
2855
|
+
/** Writable storage for an own static field named through its exact class.
|
|
2856
|
+
* Inherited writes create a new subclass property in JS, so they must not
|
|
2857
|
+
* update the declaring class's global. */
|
|
2858
|
+
export function staticFieldWriteTarget(lowerer, access) {
|
|
2859
|
+
if (access.questionDotToken || (!ts.isIdentifier(access.expression) && access.expression.kind !== ts.SyntaxKind.ThisKeyword))
|
|
2860
|
+
return null;
|
|
2861
|
+
const info = lowerer.exactClassOfReceiver(access.expression);
|
|
2862
|
+
if (!info)
|
|
2863
|
+
return null;
|
|
2864
|
+
const found = lowerer.findStaticOn(info, access.name.text);
|
|
2865
|
+
if (!found?.field)
|
|
2866
|
+
return null;
|
|
2867
|
+
if (found.declarer !== info) {
|
|
2868
|
+
lowerer.unsupported("SC1090", access, `assigning the inherited static '${access.name.text}' through a subclass name (JS creates an OWN property on the subclass — assign through '${found.declarer.def.jsName ?? found.declarer.def.name}' instead)`);
|
|
2869
|
+
}
|
|
2870
|
+
if (found.field.readonly) {
|
|
2871
|
+
lowerer.unsupported("SC1090", access, `assigning the readonly static '${access.name.text}'`);
|
|
2872
|
+
}
|
|
2873
|
+
return { id: found.field.globalId, type: found.field.type };
|
|
2874
|
+
}
|
|
2557
2875
|
/** `C.x` where C is a class declared in the program and x a static
|
|
2558
2876
|
* member of its chain: field reads are the module global, static
|
|
2559
2877
|
* methods become interned closures, and `.name` folds to the class's
|
|
@@ -2563,15 +2881,16 @@ export function ctorAbiEquals(lowerer, sub, sup) {
|
|
|
2563
2881
|
export function lowerStaticFieldRead(lowerer, expr) {
|
|
2564
2882
|
if (expr.questionDotToken)
|
|
2565
2883
|
return null;
|
|
2566
|
-
if (!ts.isIdentifier(expr.expression))
|
|
2884
|
+
if (!ts.isIdentifier(expr.expression) && expr.expression.kind !== ts.SyntaxKind.ThisKeyword)
|
|
2567
2885
|
return null;
|
|
2568
|
-
const symbol = lowerer.resolveValueSymbol(expr.expression);
|
|
2886
|
+
const symbol = ts.isIdentifier(expr.expression) ? lowerer.resolveValueSymbol(expr.expression) : null;
|
|
2569
2887
|
const info = (symbol ? lowerer.classBySymbol.get(symbol) : undefined) ??
|
|
2570
2888
|
// A require binding over `module.exports = class {…}` (the alias
|
|
2571
2889
|
// lands on the expression's own symbol): resolve/collect on demand,
|
|
2572
2890
|
// or `C.name` below would fall through to paths that answer for
|
|
2573
2891
|
// stdlib globals instead of this class.
|
|
2574
2892
|
propertyAssignedClassInfoOf(lowerer, symbol) ??
|
|
2893
|
+
exactClassOfReceiver(lowerer, expr.expression) ??
|
|
2575
2894
|
undefined;
|
|
2576
2895
|
if (!info)
|
|
2577
2896
|
return null;
|
|
@@ -2611,6 +2930,9 @@ export function lowerStaticFieldRead(lowerer, expr) {
|
|
|
2611
2930
|
if (expr.name.text === "name" && info.def.jsName !== undefined) {
|
|
2612
2931
|
return { kind: "strLit", value: info.def.jsName, type: STRING, loc };
|
|
2613
2932
|
}
|
|
2933
|
+
const data = classStaticDataFor(lowerer, info, expr.name.text, loc);
|
|
2934
|
+
if (data)
|
|
2935
|
+
return { kind: "dynKeyGet", value: data, key: { kind: "strLit", value: expr.name.text, type: STRING, loc }, type: DYN, loc };
|
|
2614
2936
|
return null;
|
|
2615
2937
|
}
|
|
2616
2938
|
/** NamedEvaluation's answer for a class expression's `.name`: its own
|
|
@@ -2635,19 +2957,12 @@ function namedEvaluationName(expr) {
|
|
|
2635
2957
|
return p.name.text;
|
|
2636
2958
|
return "";
|
|
2637
2959
|
}
|
|
2638
|
-
/**
|
|
2639
|
-
|
|
2640
|
-
|
|
2641
|
-
|
|
2642
|
-
* first collection. The honest v1 boundary is TOP-LEVEL evaluation
|
|
2643
|
-
* positions only: each evaluation of a class expression in JS mints a
|
|
2644
|
-
* DISTINCT class (fresh identity, fresh statics), and one immortal
|
|
2645
|
-
* class object is exact only for expressions that evaluate exactly
|
|
2646
|
-
* once. Statics-bearing expressions additionally restrict to positions
|
|
2647
|
-
* where "immediately before the enclosing statement" IS the evaluation
|
|
2648
|
-
* point (lowerFileInit drains pendingClassExprInits there). */
|
|
2960
|
+
/** Collect a class expression once per enclosing specialization. Function-local
|
|
2961
|
+
* evaluations allocate fresh constructor objects; top-level expressions use
|
|
2962
|
+
* immortal templates. Static initialization remains limited to whole top-level
|
|
2963
|
+
* initializers, where pendingClassExprInits preserves its evaluation point. */
|
|
2649
2964
|
export function lowerClassExpressionInfo(lowerer, expr) {
|
|
2650
|
-
const cached = lowerer.
|
|
2965
|
+
const cached = lowerer.exprClassInfoByName.get(lowerer.classNamer(expr));
|
|
2651
2966
|
if (cached)
|
|
2652
2967
|
return cached;
|
|
2653
2968
|
// Reentrancy guard: heritage resolution can DEMAND another class
|
|
@@ -2660,13 +2975,22 @@ export function lowerClassExpressionInfo(lowerer, expr) {
|
|
|
2660
2975
|
if (lowerer.collectingExprClasses.has(expr)) {
|
|
2661
2976
|
lowerer.unsupported("SC1090", expr, "class expressions whose extends chain re-enters their own collection (a cyclic base through property assignments)");
|
|
2662
2977
|
}
|
|
2663
|
-
|
|
2664
|
-
|
|
2665
|
-
|
|
2666
|
-
|
|
2667
|
-
if (ts.isFunctionLike(p) || ts.isClassStaticBlockDeclaration(p)) {
|
|
2668
|
-
lowerer.unsupported("SC1090", expr, "class expressions inside functions (each evaluation creates a DISTINCT class in JS — fresh identity, fresh statics; declare the class at top level)");
|
|
2978
|
+
let local = false;
|
|
2979
|
+
for (let p = expr.parent; p !== undefined && !ts.isSourceFile(p); p = p.parent) {
|
|
2980
|
+
if (ts.isClassStaticBlockDeclaration(p)) {
|
|
2981
|
+
lowerer.unsupported("SC1090", expr, "class expressions inside static blocks");
|
|
2669
2982
|
}
|
|
2983
|
+
if (ts.isFunctionLike(p))
|
|
2984
|
+
local = true;
|
|
2985
|
+
}
|
|
2986
|
+
if (local && expr.members.some((member) => member.name && ts.isPrivateIdentifier(member.name))) {
|
|
2987
|
+
lowerer.unsupported("SC1090", expr, "function-local classes with private brands");
|
|
2988
|
+
}
|
|
2989
|
+
if (local && (expr.typeParameters?.length ||
|
|
2990
|
+
decoratorNodesOf(expr).length || expr.members.some((member) => ts.isClassStaticBlockDeclaration(member) || decoratorNodesOf(member).length ||
|
|
2991
|
+
ts.getModifiers(member)?.some((modifier) => modifier.kind === ts.SyntaxKind.StaticKeyword) ||
|
|
2992
|
+
(ts.isMethodDeclaration(member) && member.typeParameters?.length)))) {
|
|
2993
|
+
lowerer.unsupported("SC1090", expr, "function-local classes with statics, decorators, or generic members");
|
|
2670
2994
|
}
|
|
2671
2995
|
lowerer.collectingExprClasses.add(expr);
|
|
2672
2996
|
try {
|
|
@@ -2678,7 +3002,17 @@ export function lowerClassExpressionInfo(lowerer, expr) {
|
|
|
2678
3002
|
const info = lowerer.classes.get(lowerer.classNamer(expr));
|
|
2679
3003
|
if (!info)
|
|
2680
3004
|
throw new PoisonError(); // collection poisoned and reported
|
|
2681
|
-
|
|
3005
|
+
if (local) {
|
|
3006
|
+
info.def.localCaptures = [];
|
|
3007
|
+
info.def.fields.push({ name: `%classEnvironment:${info.def.name}`, type: { kind: "classval", className: info.def.name } });
|
|
3008
|
+
info.localClass = { context: null, bodies: new Map(), captureSources: [], ready: false };
|
|
3009
|
+
if (info.base?.localClass) {
|
|
3010
|
+
const baseExpression = expr.heritageClauses?.find((clause) => clause.token === ts.SyntaxKind.ExtendsKeyword)?.types[0]?.expression;
|
|
3011
|
+
if (baseExpression)
|
|
3012
|
+
info.localClass.baseExpression = baseExpression;
|
|
3013
|
+
}
|
|
3014
|
+
}
|
|
3015
|
+
lowerer.exprClassInfoByName.set(info.def.name, info);
|
|
2682
3016
|
lowerer.exprClasses.push(info);
|
|
2683
3017
|
lowerer.onExprClassCollected?.(info);
|
|
2684
3018
|
// Static field initializers and static blocks run when the class
|
|
@@ -2733,7 +3067,50 @@ export function lowerClassExpression(lowerer, expr) {
|
|
|
2733
3067
|
}
|
|
2734
3068
|
}
|
|
2735
3069
|
}
|
|
2736
|
-
|
|
3070
|
+
const info = lowerClassExpressionInfo(lowerer, expr);
|
|
3071
|
+
if (info.localClass && !info.localClass.ready) {
|
|
3072
|
+
const context = newFnCtx(true, null, null, VOID);
|
|
3073
|
+
info.localClass.context = context;
|
|
3074
|
+
lowerer.fnStack.push(context);
|
|
3075
|
+
try {
|
|
3076
|
+
const bodies = lowerClassMembers(lowerer, info);
|
|
3077
|
+
for (const body of bodies)
|
|
3078
|
+
info.localClass.bodies.set(body.name, body);
|
|
3079
|
+
info.def.localCaptures = context.captures;
|
|
3080
|
+
info.localClass.captureSources = context.captureSources;
|
|
3081
|
+
if (info.localClass.baseExpression && info.base) {
|
|
3082
|
+
info.def.localBaseCapture = info.def.localCaptures.length;
|
|
3083
|
+
info.def.localCaptures.push({ localId: "%base", name: "base", type: { kind: "classval", className: info.base.def.name } });
|
|
3084
|
+
}
|
|
3085
|
+
info.localClass.ready = true;
|
|
3086
|
+
}
|
|
3087
|
+
finally {
|
|
3088
|
+
lowerer.fnStack.pop();
|
|
3089
|
+
info.localClass.context = null;
|
|
3090
|
+
}
|
|
3091
|
+
}
|
|
3092
|
+
const value = classValueRef(lowerer, info, expr);
|
|
3093
|
+
if (info.localClass?.baseExpression && info.base && value.kind === "classRef") {
|
|
3094
|
+
const loc = locOf(expr);
|
|
3095
|
+
const base = lowerer.lowerExpr(info.localClass.baseExpression);
|
|
3096
|
+
const baseLocal = lowerer.declareHiddenLocal("%classBase", base.type);
|
|
3097
|
+
baseLocal.boxed = true;
|
|
3098
|
+
const clsLocal = lowerer.declareHiddenLocal("%classValue", value.type);
|
|
3099
|
+
const baseRef = { kind: "varRef", localId: baseLocal.id, type: base.type, loc };
|
|
3100
|
+
const clsRef = { kind: "varRef", localId: clsLocal.id, type: value.type, loc };
|
|
3101
|
+
const basePrototype = classPrototypeData(lowerer, info.base, loc, baseRef);
|
|
3102
|
+
info.localPrototypeData = true;
|
|
3103
|
+
return { kind: "seqExpr", stmts: [
|
|
3104
|
+
{ kind: "varDecl", localId: baseLocal.id, init: base, loc },
|
|
3105
|
+
{ kind: "varDecl", localId: clsLocal.id, init: { ...value, captures: [...info.localClass.captureSources, baseLocal.id] }, loc },
|
|
3106
|
+
{ kind: "exprStmt", expr: { kind: "libCall", fn: "dyn.classPrototype", args: [
|
|
3107
|
+
{ kind: "dynFrom", value: clsRef, type: DYN, loc }, basePrototype,
|
|
3108
|
+
], type: DYN, loc }, loc },
|
|
3109
|
+
], result: clsRef, type: value.type, loc };
|
|
3110
|
+
}
|
|
3111
|
+
return info.localClass && value.kind === "classRef"
|
|
3112
|
+
? { ...value, captures: info.localClass.captureSources }
|
|
3113
|
+
: value;
|
|
2737
3114
|
}
|
|
2738
3115
|
/** The EXACT class a receiver expression is statically known to BE (not
|
|
2739
3116
|
* merely be typed by): the class name itself, or a `const` binding
|
|
@@ -2742,6 +3119,12 @@ export function lowerClassExpression(lowerer, expr) {
|
|
|
2742
3119
|
* hit the declaring class's storage exactly (the shadowing hazards of
|
|
2743
3120
|
* general class values don't arise). Null for everything else. */
|
|
2744
3121
|
export function exactClassOfReceiver(lowerer, expr) {
|
|
3122
|
+
// A class-valued lexical this is introduced only for an exact static
|
|
3123
|
+
// receiver specialization; ordinary instance this remains an object.
|
|
3124
|
+
if (expr.kind === ts.SyntaxKind.ThisKeyword) {
|
|
3125
|
+
const receiver = lowerer.resolveThis();
|
|
3126
|
+
return receiver?.type.kind === "classval" ? lowerer.classes.get(receiver.type.className) ?? null : null;
|
|
3127
|
+
}
|
|
2745
3128
|
if (!ts.isIdentifier(expr))
|
|
2746
3129
|
return null;
|
|
2747
3130
|
const symbol = lowerer.resolveValueSymbol(expr);
|
|
@@ -2764,7 +3147,7 @@ export function exactClassOfReceiver(lowerer, expr) {
|
|
|
2764
3147
|
while (ts.isParenthesizedExpression(init))
|
|
2765
3148
|
init = init.expression;
|
|
2766
3149
|
if (ts.isClassExpression(init))
|
|
2767
|
-
return lowerer.
|
|
3150
|
+
return lowerer.exprClassInfoByName.get(lowerer.classNamer(init)) ?? null;
|
|
2768
3151
|
if (ts.isIdentifier(init)) {
|
|
2769
3152
|
const initSym = lowerer.resolveValueSymbol(init);
|
|
2770
3153
|
const aliased = initSym ? (lowerer.classBySymbol.get(initSym) ?? null) : null;
|
|
@@ -2880,12 +3263,32 @@ function countAssignmentsTo(assign) {
|
|
|
2880
3263
|
export function lowerStaticMethodCall(lowerer, call, access) {
|
|
2881
3264
|
if (access.questionDotToken)
|
|
2882
3265
|
return null;
|
|
3266
|
+
if (access.expression.kind === ts.SyntaxKind.ThisKeyword) {
|
|
3267
|
+
const receiver = lowerer.resolveThis();
|
|
3268
|
+
const info = receiver?.type.kind === "classval" ? lowerer.classes.get(receiver.type.className) : undefined;
|
|
3269
|
+
if (info)
|
|
3270
|
+
return staticCallOn(lowerer, call, access, info, false);
|
|
3271
|
+
}
|
|
2883
3272
|
// `module.exports.describe()` in a module whose whole export IS a
|
|
2884
3273
|
// class expression: the receiver is exactly that class (the kept
|
|
2885
3274
|
// export assignment pins it) — the direct-name rules apply.
|
|
2886
3275
|
if (!ts.isIdentifier(access.expression)) {
|
|
2887
|
-
if (!isModuleExportsAccess(access.expression) || !isCjsJsFile(access.getSourceFile())) {
|
|
2888
|
-
|
|
3276
|
+
if (!isModuleExportsAccess(access.expression) || !isCjsJsFile(access.getSourceFile(), lowerer.program)) {
|
|
3277
|
+
const receiverType = lowerer.mapTypeOf(lowerer.typeOf(access.expression));
|
|
3278
|
+
if (receiverType?.kind !== "classval")
|
|
3279
|
+
return null;
|
|
3280
|
+
const info = lowerer.classes.get(receiverType.className);
|
|
3281
|
+
if (!info)
|
|
3282
|
+
return null;
|
|
3283
|
+
const result = staticCallOn(lowerer, call, access, info, true);
|
|
3284
|
+
if (!result)
|
|
3285
|
+
return null;
|
|
3286
|
+
// Evaluate and validate the receiver before evaluating arguments.
|
|
3287
|
+
// A typed checker projection cannot turn a replaced field into a call
|
|
3288
|
+
// to the class that originally occupied it.
|
|
3289
|
+
const receiver = lowerer.lowerExprExpecting(access.expression, receiverType);
|
|
3290
|
+
return { kind: "seqExpr", stmts: [{ kind: "exprStmt", expr: receiver, loc: locOf(access.expression) }],
|
|
3291
|
+
result, type: result.type, loc: locOf(call) };
|
|
2889
3292
|
}
|
|
2890
3293
|
const whole = cjsClassExprWholeExportOf(access.getSourceFile());
|
|
2891
3294
|
if (!whole)
|
|
@@ -2951,13 +3354,19 @@ function staticCallOn(lowerer, call, access, info, throughValue) {
|
|
|
2951
3354
|
if (throughValue && staticShadowBelow(lowerer, info, access.name.text)) {
|
|
2952
3355
|
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)`);
|
|
2953
3356
|
}
|
|
2954
|
-
const instance = genericCallInstance(lowerer, call, gfound.info);
|
|
3357
|
+
const instance = genericCallInstance(lowerer, call, staticMethodForReceiver(lowerer, access, gfound.info, info, throughValue));
|
|
2955
3358
|
const args = lowerer.completeArgs(call.arguments, instance.params, loc, call);
|
|
2956
3359
|
return { kind: "call", callee: instance.name, args, type: instance.returnType, loc };
|
|
2957
3360
|
}
|
|
2958
3361
|
if (throughValue && staticShadowBelow(lowerer, info, access.name.text)) {
|
|
2959
3362
|
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)`);
|
|
2960
3363
|
}
|
|
3364
|
+
const specialized = findGenericStaticOn(lowerer, info, access.name.text);
|
|
3365
|
+
if (specialized?.declarer === found.declarer && specialized.info.implicitParams) {
|
|
3366
|
+
const instance = implicitCallInstance(lowerer, call, staticMethodForReceiver(lowerer, access, specialized.info, info, throughValue));
|
|
3367
|
+
const args = lowerer.completeArgs(call.arguments, instance.params, loc, call);
|
|
3368
|
+
return { kind: "call", callee: instance.name, args, type: instance.returnType, loc };
|
|
3369
|
+
}
|
|
2961
3370
|
if (found.field !== undefined) {
|
|
2962
3371
|
// A func-typed static field in call position: read the global,
|
|
2963
3372
|
// call through the value (the ctor-assigned-callback pattern).
|
|
@@ -2975,11 +3384,42 @@ function staticCallOn(lowerer, call, access, info, throughValue) {
|
|
|
2975
3384
|
}
|
|
2976
3385
|
return { kind: "callValue", callee, args, type: found.field.type.ret, loc };
|
|
2977
3386
|
}
|
|
3387
|
+
if (found.method.member.body && hasStaticThis(found.method.member)) {
|
|
3388
|
+
const generic = found.method.receiverInfo ??= {
|
|
3389
|
+
decl: found.method.member, baseName: access.name.text,
|
|
3390
|
+
qualifiedName: `%${found.declarer.def.name}.static:${access.name.text}`,
|
|
3391
|
+
typeParams: [], instances: new Map(), member: { cls: found.declarer, kind: "static" },
|
|
3392
|
+
};
|
|
3393
|
+
const instance = genericCallInstance(lowerer, call, staticMethodForReceiver(lowerer, access, generic, info, throughValue));
|
|
3394
|
+
return { kind: "call", callee: instance.name,
|
|
3395
|
+
args: lowerer.completeArgs(call.arguments, instance.params, loc, call), type: instance.returnType, loc };
|
|
3396
|
+
}
|
|
2978
3397
|
const fnName = `%${found.declarer.def.name}.static:${access.name.text}`;
|
|
2979
3398
|
lowerer.noteEdge(fnName);
|
|
2980
3399
|
const args = lowerer.completeArgs(call.arguments, found.method.params, loc, call);
|
|
2981
3400
|
return { kind: "call", callee: fnName, args, type: found.method.ret, loc };
|
|
2982
3401
|
}
|
|
3402
|
+
function staticMethodForReceiver(lowerer, access, method, receiver, throughValue) {
|
|
3403
|
+
if (!hasStaticThis(method.decl))
|
|
3404
|
+
return method;
|
|
3405
|
+
// A private name in the inherited body belongs to the declaring class,
|
|
3406
|
+
// even when the receiver declares a different private with that spelling.
|
|
3407
|
+
// Do not resolve it by receiver name until the static ABI tracks the brand.
|
|
3408
|
+
if (method.member && method.member.cls !== receiver && hasLexicalPrivateReference(method.decl)) {
|
|
3409
|
+
lowerer.unsupported("SC1090", access, "private member references in an inherited receiver-dependent static method");
|
|
3410
|
+
}
|
|
3411
|
+
if (throughValue && !classValueIsExactlyOwn(lowerer, access.expression, receiver)) {
|
|
3412
|
+
lowerer.unsupported("SC1090", access, "receiver-dependent static methods through a polymorphic class value");
|
|
3413
|
+
}
|
|
3414
|
+
const instances = method.receiverSpecializations ??= new Map();
|
|
3415
|
+
let specialized = instances.get(receiver.def.name);
|
|
3416
|
+
if (!specialized) {
|
|
3417
|
+
specialized = { ...method, qualifiedName: `${method.qualifiedName}%on.${receiver.def.name}`,
|
|
3418
|
+
instances: new Map(), staticReceiver: receiver, receiverSpecializations: new Map() };
|
|
3419
|
+
instances.set(receiver.def.name, specialized);
|
|
3420
|
+
}
|
|
3421
|
+
return specialized;
|
|
3422
|
+
}
|
|
2983
3423
|
/** Static member access through a class VALUE (`X.m` where X is
|
|
2984
3424
|
* classval-typed): devirtualized — the member resolves against the
|
|
2985
3425
|
* static class's chain, exact when no strict descendant redeclares it
|
|
@@ -2990,7 +3430,7 @@ function staticCallOn(lowerer, call, access, info, throughValue) {
|
|
|
2990
3430
|
export function lowerClassValueProperty(lowerer, expr) {
|
|
2991
3431
|
if (expr.questionDotToken)
|
|
2992
3432
|
return null;
|
|
2993
|
-
const recvT =
|
|
3433
|
+
const recvT = storedClassValueType(lowerer, expr.expression);
|
|
2994
3434
|
if (recvT?.kind !== "classval")
|
|
2995
3435
|
return null;
|
|
2996
3436
|
const loc = locOf(expr);
|
|
@@ -3005,10 +3445,11 @@ export function lowerClassValueProperty(lowerer, expr) {
|
|
|
3005
3445
|
return { kind: "libCall", fn: "class.name", args: [recv], type: STRING, loc };
|
|
3006
3446
|
}
|
|
3007
3447
|
if (!ts.isIdentifier(expr.expression) &&
|
|
3448
|
+
expr.expression.kind !== ts.SyntaxKind.ThisKeyword &&
|
|
3008
3449
|
// `module.exports.label` in a class-replaced CJS module: the
|
|
3009
3450
|
// receiver is the exact exported class, and the read is
|
|
3010
3451
|
// side-effect-free — as bindable as an identifier.
|
|
3011
|
-
!(isModuleExportsAccess(expr.expression) && isCjsJsFile(expr.getSourceFile()))) {
|
|
3452
|
+
!(isModuleExportsAccess(expr.expression) && isCjsJsFile(expr.getSourceFile(), lowerer.program))) {
|
|
3012
3453
|
// Devirtualized reads DISCARD the receiver value, so only
|
|
3013
3454
|
// side-effect-free receivers are claimed (the instanceOf fold
|
|
3014
3455
|
// rule); computed ones meet the pointed fence with a bindable fix.
|
|
@@ -3110,9 +3551,57 @@ export function findGenericMethodOn(lowerer, info, name) {
|
|
|
3110
3551
|
* method `name` — overrideBelow's twin: generic methods have no vtable
|
|
3111
3552
|
* slot, so a call that could reach an override compiles only when the
|
|
3112
3553
|
* receiver's runtime class is statically exact. */
|
|
3113
|
-
function genericOverrideBelow(lowerer, info, name) {
|
|
3554
|
+
export function genericOverrideBelow(lowerer, info, name) {
|
|
3114
3555
|
return info.subclasses.some((s) => s.genericMethods?.has(name) === true || genericOverrideBelow(lowerer, s, name));
|
|
3115
3556
|
}
|
|
3557
|
+
/** Discover overrides before choosing inferred method ABIs. Class collection
|
|
3558
|
+
* visits bases first, including imported bases and class expressions, so the
|
|
3559
|
+
* collected subclass graph cannot answer this question yet. The checker
|
|
3560
|
+
* hierarchy identifies the original declarations through aliases as well. */
|
|
3561
|
+
export function collectVirtualJsMethods(lowerer, files) {
|
|
3562
|
+
if (!files.some(isJsSourceFile))
|
|
3563
|
+
return;
|
|
3564
|
+
const visit = (node) => {
|
|
3565
|
+
if (ts.isClassDeclaration(node) || ts.isClassExpression(node)) {
|
|
3566
|
+
const members = node.members.filter((member) => ts.isMethodDeclaration(member) && ts.isIdentifier(member.name) &&
|
|
3567
|
+
!member.modifiers?.some((modifier) => modifier.kind === ts.SyntaxKind.StaticKeyword));
|
|
3568
|
+
if (node.heritageClauses?.length && members.length > 0) {
|
|
3569
|
+
const symbol = lowerer.typeOf(node).getSymbol();
|
|
3570
|
+
const instance = symbol ? lowerer.checker.getDeclaredTypeOfSymbol(symbol) : null;
|
|
3571
|
+
const seen = new Set();
|
|
3572
|
+
const markBases = (type) => {
|
|
3573
|
+
const target = type.isTypeReference() ? type.getTarget() : type;
|
|
3574
|
+
if (target === undefined || !target.isClassOrInterface() || seen.has(target))
|
|
3575
|
+
return;
|
|
3576
|
+
seen.add(target);
|
|
3577
|
+
for (const base of lowerer.checker.getBaseTypes(target)) {
|
|
3578
|
+
for (const member of members) {
|
|
3579
|
+
if (!ts.isIdentifier(member.name))
|
|
3580
|
+
continue;
|
|
3581
|
+
const property = lowerer.checker.getPropertyOfType(base, member.name.text);
|
|
3582
|
+
for (const declaration of property ? lowerer.checker.declarationsOf(property) : []) {
|
|
3583
|
+
if (ts.isMethodDeclaration(declaration) && isJsSourceFile(declaration.getSourceFile())) {
|
|
3584
|
+
lowerer.virtualJsMethods.add(declaration);
|
|
3585
|
+
if (isJsSourceFile(member.getSourceFile()) && !member.typeParameters &&
|
|
3586
|
+
!member.asteriskToken && !member.modifiers?.some((m) => m.kind === ts.SyntaxKind.AsyncKeyword) &&
|
|
3587
|
+
!bodyReadsArguments(member) &&
|
|
3588
|
+
member.parameters.every((p) => !p.initializer && !p.dotDotDotToken)) {
|
|
3589
|
+
lowerer.virtualJsMethodArity.set(declaration, Math.max(lowerer.virtualJsMethodArity.get(declaration) ?? 0, member.parameters.length));
|
|
3590
|
+
}
|
|
3591
|
+
}
|
|
3592
|
+
}
|
|
3593
|
+
}
|
|
3594
|
+
markBases(base);
|
|
3595
|
+
}
|
|
3596
|
+
};
|
|
3597
|
+
if (instance)
|
|
3598
|
+
markBases(instance);
|
|
3599
|
+
}
|
|
3600
|
+
}
|
|
3601
|
+
};
|
|
3602
|
+
for (const file of files)
|
|
3603
|
+
ts.walkPreorder(file, visit);
|
|
3604
|
+
}
|
|
3116
3605
|
/** The receiver's EXACT runtime class, when the expression proves it: a
|
|
3117
3606
|
* `new C(...)` expression directly, or a const binding initialized with
|
|
3118
3607
|
* one (the binding can never be reassigned to a subclass instance).
|
|
@@ -3274,13 +3763,20 @@ function mixinForwardingCtor(lowerer, ctor) {
|
|
|
3274
3763
|
return !extraRef;
|
|
3275
3764
|
}
|
|
3276
3765
|
export function lowerClassMembers(lowerer, info) {
|
|
3766
|
+
// Local class bodies are lowered when their expression captures its
|
|
3767
|
+
// lexical environment. Type collection alone can discover a class in
|
|
3768
|
+
// an owner skipped by the coverage remainder; it must not relower the
|
|
3769
|
+
// constructor without that environment.
|
|
3770
|
+
if (info.localClass && info.localClass.context === null) {
|
|
3771
|
+
return [...info.localClass.bodies.values()];
|
|
3772
|
+
}
|
|
3277
3773
|
const out = [];
|
|
3278
3774
|
const className = info.def.name;
|
|
3279
3775
|
// Generic-class INSTANTIATIONS (and mixin instantiations) are
|
|
3280
3776
|
// demand-driven like generic-fn instances, not reachability units:
|
|
3281
3777
|
// they are never registered as units, so wantBody's name-keyed gate
|
|
3282
3778
|
// cannot apply — every member of a demanded instantiation lowers.
|
|
3283
|
-
const always = info.genericInstance !== undefined || info.mixinInstance !== undefined;
|
|
3779
|
+
const always = info.genericInstance !== undefined || info.mixinInstance !== undefined || info.localClass !== undefined;
|
|
3284
3780
|
// A FAMILY has no constructor function at all (nothing constructs it;
|
|
3285
3781
|
// construction resolves to instantiations) and declares no instance
|
|
3286
3782
|
// members — only its statics lower below.
|
|
@@ -3311,13 +3807,14 @@ export function lowerClassMembers(lowerer, info) {
|
|
|
3311
3807
|
throw e;
|
|
3312
3808
|
}
|
|
3313
3809
|
}
|
|
3314
|
-
|
|
3315
|
-
|
|
3316
|
-
|
|
3317
|
-
|
|
3318
|
-
|
|
3319
|
-
|
|
3320
|
-
|
|
3810
|
+
if (info.staticMethods)
|
|
3811
|
+
for (const [name] of info.staticMethods) {
|
|
3812
|
+
if (!lowerer.wantBody(`%${className}.static:${name}`))
|
|
3813
|
+
continue;
|
|
3814
|
+
const fn = lowerStaticMethod(lowerer, info, name);
|
|
3815
|
+
if (fn)
|
|
3816
|
+
out.push(fn);
|
|
3817
|
+
}
|
|
3321
3818
|
for (const prop of info.throwingSetters) {
|
|
3322
3819
|
if (always || lowerer.wantBody(`%${className}.set:${prop}`))
|
|
3323
3820
|
out.push(lowerer.throwingSetterFn(info, prop));
|
|
@@ -3329,14 +3826,29 @@ export function lowerClassMembers(lowerer, info) {
|
|
|
3329
3826
|
* the base's signature — forward every param to super(), then run own
|
|
3330
3827
|
* field initializers. */
|
|
3331
3828
|
export function lowerClassCtor(lowerer, info) {
|
|
3829
|
+
const cached = info.localClass?.bodies.get(`%${info.def.name}.constructor`);
|
|
3830
|
+
if (cached)
|
|
3831
|
+
return cached;
|
|
3332
3832
|
return withInstanceBindings(lowerer, info, () => lowerClassCtorInner(lowerer, info));
|
|
3333
3833
|
}
|
|
3834
|
+
function classCaptureParams(info, context) {
|
|
3835
|
+
if (!info.localClass)
|
|
3836
|
+
return {};
|
|
3837
|
+
const environment = info.localClass.context;
|
|
3838
|
+
if (!environment)
|
|
3839
|
+
throw new InternalCompilerError("local class lowered outside its lexical environment");
|
|
3840
|
+
return { classCaptures: (context.captures ?? []).map((capture, index) => {
|
|
3841
|
+
if (!capture)
|
|
3842
|
+
throw new InternalCompilerError("missing local class capture");
|
|
3843
|
+
return { ...capture, slot: environment.captures.findIndex((entry) => entry.localId === context.captureSources[index]) };
|
|
3844
|
+
}) };
|
|
3845
|
+
}
|
|
3334
3846
|
function lowerClassCtorInner(lowerer, info) {
|
|
3335
3847
|
const className = info.def.name;
|
|
3336
3848
|
const thisType = { kind: "object", className };
|
|
3337
3849
|
const prevClass = lowerer.currentClass;
|
|
3338
3850
|
lowerer.currentClass = info;
|
|
3339
|
-
lowerer.fnStack.push(newFnCtx(
|
|
3851
|
+
lowerer.fnStack.push(newFnCtx(info.localClass !== undefined, null, null, VOID));
|
|
3340
3852
|
try {
|
|
3341
3853
|
const thisLocal = lowerer.declareThis(thisType);
|
|
3342
3854
|
const params = [{ localId: thisLocal.id, name: "this", type: thisType }];
|
|
@@ -3366,7 +3878,7 @@ function lowerClassCtorInner(lowerer, info) {
|
|
|
3366
3878
|
const declared = lowerer.declareParams(info.ctor.parameters, info.ctorParams);
|
|
3367
3879
|
params.push(...declared.params);
|
|
3368
3880
|
body.push(...declared.prologue);
|
|
3369
|
-
if (!ctorBase) {
|
|
3881
|
+
if (!ctorBase && !info.callableBase) {
|
|
3370
3882
|
// Node's base-class order: field initializers run at the start
|
|
3371
3883
|
// of construction, the parameter-property assignments open the
|
|
3372
3884
|
// constructor body (probed — a field initializer reading a
|
|
@@ -3381,7 +3893,7 @@ function lowerClassCtorInner(lowerer, info) {
|
|
|
3381
3893
|
}
|
|
3382
3894
|
}
|
|
3383
3895
|
else {
|
|
3384
|
-
if (ctorBase) {
|
|
3896
|
+
if (ctorBase || info.callableBase) {
|
|
3385
3897
|
// Synthetic forwarding params (the inherited ABI signature).
|
|
3386
3898
|
// Nothing references them by symbol — only the super call below,
|
|
3387
3899
|
// which forwards the already-completed values UNCHANGED (defaults
|
|
@@ -3411,6 +3923,7 @@ function lowerClassCtorInner(lowerer, info) {
|
|
|
3411
3923
|
params,
|
|
3412
3924
|
returnType: VOID,
|
|
3413
3925
|
locals: lowerer.ctx.locals,
|
|
3926
|
+
...classCaptureParams(info, lowerer.ctx),
|
|
3414
3927
|
body,
|
|
3415
3928
|
loc: locOf(info.ctor ?? info.decl),
|
|
3416
3929
|
};
|
|
@@ -3450,7 +3963,7 @@ export function classMemberNameOf(lowerer, name) {
|
|
|
3450
3963
|
return `sym:${member}`;
|
|
3451
3964
|
}
|
|
3452
3965
|
}
|
|
3453
|
-
return lowerer.foldedStringKeyOf(name.expression);
|
|
3966
|
+
return classSymbolKeyOf(lowerer, name.expression)?.fieldName ?? lowerer.foldedStringKeyOf(name.expression);
|
|
3454
3967
|
}
|
|
3455
3968
|
export function classIteratorOf(lowerer, t) {
|
|
3456
3969
|
if (t.kind !== "object")
|
|
@@ -3651,6 +4164,11 @@ export function classIteratorRestDrainCall(lowerer, cit, itVal, loc) {
|
|
|
3651
4164
|
* (accessors are methods with property syntax: "get:x"/"set:x" entries —
|
|
3652
4165
|
* see collectClassShape). */
|
|
3653
4166
|
export function lowerClassMethodMember(lowerer, info, fnLike) {
|
|
4167
|
+
if (info.localClass?.ready) {
|
|
4168
|
+
const member = classMemberNameOf(lowerer, fnLike.name);
|
|
4169
|
+
const name = ts.isMethodDeclaration(fnLike) ? member : `${ts.isGetAccessor(fnLike) ? "get" : "set"}:${member}`;
|
|
4170
|
+
return info.localClass.bodies.get(`%${info.def.name}.${name}`) ?? null;
|
|
4171
|
+
}
|
|
3654
4172
|
return withInstanceBindings(lowerer, info, () => lowerClassMethodMemberInner(lowerer, info, fnLike));
|
|
3655
4173
|
}
|
|
3656
4174
|
function lowerClassMethodMemberInner(lowerer, info, fnLike) {
|
|
@@ -3665,6 +4183,21 @@ function lowerClassMethodMemberInner(lowerer, info, fnLike) {
|
|
|
3665
4183
|
const sig = info.methods.get(mName);
|
|
3666
4184
|
if (!sig || !fnLike.body)
|
|
3667
4185
|
return null;
|
|
4186
|
+
const entryFence = info.methodEntryFences?.get(mName);
|
|
4187
|
+
if (entryFence) {
|
|
4188
|
+
lowerer.runtimeFences.push(entryFence);
|
|
4189
|
+
return lowerer.deferToRuntimeFence(lowerer.diags.length, fnLike.name, {
|
|
4190
|
+
kind: "function",
|
|
4191
|
+
name: `%${className}.${mName}`,
|
|
4192
|
+
params: [
|
|
4193
|
+
{ localId: "this.0", name: "this", type: thisType },
|
|
4194
|
+
...sig.params.map((p, i) => ({ localId: `p.${i}`, name: `p${i}`, type: p.type })),
|
|
4195
|
+
],
|
|
4196
|
+
returnType: sig.ret,
|
|
4197
|
+
fallback: entryFence,
|
|
4198
|
+
allowDiagSink: true,
|
|
4199
|
+
});
|
|
4200
|
+
}
|
|
3668
4201
|
const prevClass = lowerer.currentClass;
|
|
3669
4202
|
lowerer.currentClass = info;
|
|
3670
4203
|
// ASYNC methods: the module function is an async IrFunction — its
|
|
@@ -3674,18 +4207,16 @@ function lowerClassMethodMemberInner(lowerer, info, fnLike) {
|
|
|
3674
4207
|
// spawn's argument pack). Dispatch is static by construction — the
|
|
3675
4208
|
// override fence at collection keeps async methods out of vtables.
|
|
3676
4209
|
const isAsync = sig.async === true;
|
|
3677
|
-
//
|
|
3678
|
-
//
|
|
3679
|
-
//
|
|
3680
|
-
// never virtualize) enters through the emitted gen-spawn wrapper with
|
|
3681
|
-
// `this` in the argument pack, answering the suspended generator.
|
|
4210
|
+
// GENERATOR methods: the module function returns the TReturn channel,
|
|
4211
|
+
// yields ride ctx.generator, and direct calls enter through the emitted
|
|
4212
|
+
// gen-spawn wrapper with `this` in the argument pack.
|
|
3682
4213
|
const genCh = sig.gen !== undefined && sig.ret.kind === "generator" ? sig.gen : null;
|
|
3683
4214
|
const bodyReturn = genCh !== null
|
|
3684
4215
|
? lowerer.genBodyReturnType(sig.ret)
|
|
3685
4216
|
: isAsync && sig.ret.kind === "promise"
|
|
3686
4217
|
? sig.ret.inner
|
|
3687
4218
|
: sig.ret;
|
|
3688
|
-
const fnCtx = newFnCtx(
|
|
4219
|
+
const fnCtx = newFnCtx(info.localClass !== undefined, null, null, bodyReturn);
|
|
3689
4220
|
fnCtx.isAsync = isAsync;
|
|
3690
4221
|
if (genCh !== null)
|
|
3691
4222
|
fnCtx.generator = genCh;
|
|
@@ -3697,6 +4228,15 @@ function lowerClassMethodMemberInner(lowerer, info, fnLike) {
|
|
|
3697
4228
|
// (JS allows this in method defaults; it is param 0 here).
|
|
3698
4229
|
const declared = lowerer.declareParams(fnLike.parameters, sig.params);
|
|
3699
4230
|
params.push(...declared.params);
|
|
4231
|
+
// A shorter JS override still implements every inherited ABI slot.
|
|
4232
|
+
// These tail parameters have no source binding or default prologue.
|
|
4233
|
+
for (const shape of sig.params.slice(declared.params.length)) {
|
|
4234
|
+
const name = shape.mode === "arguments" ? "%arguments" : "%ignored";
|
|
4235
|
+
const local = lowerer.declareHiddenLocal(name, shape.type);
|
|
4236
|
+
params.push({ localId: local.id, name, type: shape.type });
|
|
4237
|
+
if (shape.mode === "arguments")
|
|
4238
|
+
fnCtx.argumentsLocal = local;
|
|
4239
|
+
}
|
|
3700
4240
|
const body = [...declared.prologue, ...lowerer.lowerStmts(fnLike.body.statements)];
|
|
3701
4241
|
appendImplicitUndefinedReturn(lowerer, body, bodyReturn, locOf(fnLike));
|
|
3702
4242
|
const fn = {
|
|
@@ -3704,6 +4244,7 @@ function lowerClassMethodMemberInner(lowerer, info, fnLike) {
|
|
|
3704
4244
|
params,
|
|
3705
4245
|
returnType: bodyReturn,
|
|
3706
4246
|
locals: lowerer.ctx.locals,
|
|
4247
|
+
...classCaptureParams(info, lowerer.ctx),
|
|
3707
4248
|
body,
|
|
3708
4249
|
loc: locOf(fnLike),
|
|
3709
4250
|
};
|
|
@@ -3729,18 +4270,31 @@ export function lowerStaticMethod(lowerer, info, name) {
|
|
|
3729
4270
|
const entry = info.staticMethods?.get(name);
|
|
3730
4271
|
if (!entry?.member.body)
|
|
3731
4272
|
return null;
|
|
3732
|
-
|
|
3733
|
-
|
|
3734
|
-
|
|
3735
|
-
|
|
3736
|
-
|
|
3737
|
-
|
|
4273
|
+
const isAsync = entry.member.modifiers?.some((m) => m.kind === ts.SyntaxKind.AsyncKeyword) === true;
|
|
4274
|
+
const isGenerator = entry.member.asteriskToken !== undefined;
|
|
4275
|
+
if (isGenerator && (entry.ret.kind !== "generator" || (entry.ret.async === true) !== isAsync)) {
|
|
4276
|
+
lowerer.badType(entry.member.name, lowerer.typeOf(entry.member.name));
|
|
4277
|
+
}
|
|
4278
|
+
if (isAsync && !isGenerator && entry.ret.kind !== "promise") {
|
|
4279
|
+
lowerer.badType(entry.member.name, lowerer.typeOf(entry.member.name));
|
|
4280
|
+
}
|
|
4281
|
+
const genCh = isGenerator && entry.ret.kind === "generator" ? generatorMeta(lowerer, entry.ret) : null;
|
|
4282
|
+
const bodyReturn = genCh !== null
|
|
4283
|
+
? lowerer.genBodyReturnType(entry.ret)
|
|
4284
|
+
: isAsync && entry.ret.kind === "promise" ? entry.ret.inner : entry.ret;
|
|
3738
4285
|
const fnCtx = newFnCtx(false, null, null, bodyReturn);
|
|
3739
4286
|
fnCtx.isAsync = isAsync;
|
|
4287
|
+
if (genCh !== null)
|
|
4288
|
+
fnCtx.generator = genCh;
|
|
3740
4289
|
lowerer.fnStack.push(fnCtx);
|
|
3741
4290
|
try {
|
|
3742
4291
|
rejectStaticThis(lowerer, entry.member.body, (keyword) => `'${keyword}' in static methods (it names the RECEIVER class — a dynamic value; reference the class by name instead)`);
|
|
3743
4292
|
const declared = lowerer.declareParams(entry.member.parameters, entry.params);
|
|
4293
|
+
if (entry.params.at(-1)?.mode === "arguments") {
|
|
4294
|
+
const local = lowerer.declareHiddenLocal("%arguments", DYN);
|
|
4295
|
+
declared.params.push({ localId: local.id, name: "%arguments", type: DYN });
|
|
4296
|
+
fnCtx.argumentsLocal = local;
|
|
4297
|
+
}
|
|
3744
4298
|
const body = [...declared.prologue, ...lowerer.lowerStmts(entry.member.body.statements)];
|
|
3745
4299
|
appendImplicitUndefinedReturn(lowerer, body, bodyReturn, locOf(entry.member));
|
|
3746
4300
|
const fn = {
|
|
@@ -3753,6 +4307,8 @@ export function lowerStaticMethod(lowerer, info, name) {
|
|
|
3753
4307
|
};
|
|
3754
4308
|
if (isAsync)
|
|
3755
4309
|
fn.async = true;
|
|
4310
|
+
if (genCh !== null)
|
|
4311
|
+
fn.generator = genCh;
|
|
3756
4312
|
return fn;
|
|
3757
4313
|
}
|
|
3758
4314
|
catch (e) {
|
|
@@ -3827,10 +4383,22 @@ export function fieldInitStmts(lowerer, info, thisLocal) {
|
|
|
3827
4383
|
const out = [];
|
|
3828
4384
|
const thisType = { kind: "object", className: info.def.name };
|
|
3829
4385
|
for (const f of info.fieldOrder) {
|
|
4386
|
+
if (f.undefinedInitializer) {
|
|
4387
|
+
const loc = f.undefinedInitializer;
|
|
4388
|
+
out.push({
|
|
4389
|
+
kind: "fieldSet",
|
|
4390
|
+
obj: { kind: "varRef", localId: thisLocal.id, type: thisType, loc },
|
|
4391
|
+
className: info.def.name,
|
|
4392
|
+
field: f.name,
|
|
4393
|
+
value: dynUndefinedExpr(loc),
|
|
4394
|
+
loc,
|
|
4395
|
+
});
|
|
4396
|
+
}
|
|
3830
4397
|
if (!f.initializer)
|
|
3831
4398
|
continue;
|
|
3832
4399
|
lowerer.stats.statementsTotal++;
|
|
3833
4400
|
lowerer.bumpFileStat(locOf(f.initializer).file, "total");
|
|
4401
|
+
const diagsBefore = lowerer.diags.length;
|
|
3834
4402
|
try {
|
|
3835
4403
|
const value = lowerer.lowerExprExpecting(f.initializer, f.type);
|
|
3836
4404
|
out.push({
|
|
@@ -3847,6 +4415,11 @@ export function fieldInitStmts(lowerer, info, thisLocal) {
|
|
|
3847
4415
|
throw e;
|
|
3848
4416
|
lowerer.stats.statementsFailed++;
|
|
3849
4417
|
lowerer.bumpFileStat(locOf(f.initializer).file, "failed");
|
|
4418
|
+
if (isJsSourceFile(f.initializer.getSourceFile()) && lowerer.diagSink === null) {
|
|
4419
|
+
const fence = lowerer.deferToRuntimeFence(diagsBefore, f.initializer, { kind: "statement" });
|
|
4420
|
+
if (fence)
|
|
4421
|
+
out.push(fence);
|
|
4422
|
+
}
|
|
3850
4423
|
}
|
|
3851
4424
|
}
|
|
3852
4425
|
return out;
|
|
@@ -3896,59 +4469,79 @@ export function lowerDerivedCtorBody(lowerer, info, thisLocal,
|
|
|
3896
4469
|
forward) {
|
|
3897
4470
|
const out = [];
|
|
3898
4471
|
let superSeen = false;
|
|
3899
|
-
|
|
3900
|
-
|
|
3901
|
-
|
|
3902
|
-
|
|
3903
|
-
|
|
3904
|
-
|
|
3905
|
-
|
|
3906
|
-
|
|
3907
|
-
|
|
3908
|
-
|
|
3909
|
-
|
|
3910
|
-
|
|
3911
|
-
|
|
3912
|
-
|
|
3913
|
-
|
|
3914
|
-
if (superSeen)
|
|
3915
|
-
lowerer.unsupported("SC1090", stmt, "multiple super() calls");
|
|
3916
|
-
superSeen = true;
|
|
3917
|
-
const base = superBaseOf(info);
|
|
3918
|
-
if (base.builtinEmitter && superCall.arguments.length > 0) {
|
|
3919
|
-
// @types/node admits super({ captureRejections }) — no lowering.
|
|
3920
|
-
lowerer.unsupported("SC1090", superCall, "EventEmitter constructor options ('captureRejections')");
|
|
4472
|
+
const statements = info.ctor.body.statements;
|
|
4473
|
+
const entry = { stmts: statements, index: 0, ctx: lowerer.ctx, frame: lowerer.scopes[lowerer.scopes.length - 1], out };
|
|
4474
|
+
lowerer.activeStmtLists.push(entry);
|
|
4475
|
+
try {
|
|
4476
|
+
for (let index = 0; index < statements.length; index++) {
|
|
4477
|
+
entry.index = index;
|
|
4478
|
+
const stmt = statements[index];
|
|
4479
|
+
const superCall = ts.isExpressionStatement(stmt) &&
|
|
4480
|
+
ts.isCallExpression(stmt.expression) &&
|
|
4481
|
+
stmt.expression.expression.kind === ts.SyntaxKind.SuperKeyword
|
|
4482
|
+
? stmt.expression
|
|
4483
|
+
: null;
|
|
4484
|
+
if (!superCall) {
|
|
4485
|
+
out.push(...lowerer.lowerStmts([stmt]));
|
|
4486
|
+
continue;
|
|
3921
4487
|
}
|
|
3922
|
-
if (
|
|
3923
|
-
|
|
3924
|
-
|
|
3925
|
-
|
|
4488
|
+
if (!lowerer.suppressStats) {
|
|
4489
|
+
lowerer.stats.statementsTotal++;
|
|
4490
|
+
lowerer.bumpFileStat(locOf(stmt).file, "total");
|
|
4491
|
+
}
|
|
4492
|
+
try {
|
|
4493
|
+
if (superSeen)
|
|
4494
|
+
lowerer.unsupported("SC1090", stmt, "multiple super() calls");
|
|
4495
|
+
superSeen = true;
|
|
4496
|
+
if (info.callableBase) {
|
|
4497
|
+
if (superCall.arguments.some(ts.isSpreadElement))
|
|
4498
|
+
lowerer.unsupported("SC1090", superCall, "spreading explicit super arguments into an ordinary constructor");
|
|
4499
|
+
const loc = locOf(stmt);
|
|
4500
|
+
const pack = { kind: "dynArrLit", elems: superCall.arguments.map((arg) => lowerer.lowerExprExpecting(arg, DYN)), type: DYN, loc };
|
|
4501
|
+
out.push(lowerer.superCallStmt(info, thisLocal, [pack], loc));
|
|
4502
|
+
out.push(...lowerer.fieldInitStmts(info, thisLocal));
|
|
4503
|
+
out.push(...paramPropInitStmts(lowerer, info, thisLocal));
|
|
4504
|
+
continue;
|
|
4505
|
+
}
|
|
4506
|
+
const base = superBaseOf(info);
|
|
4507
|
+
if (base.builtinEmitter && superCall.arguments.length > 0) {
|
|
4508
|
+
// @types/node admits super({ captureRejections }) — no lowering.
|
|
4509
|
+
lowerer.unsupported("SC1090", superCall, "EventEmitter constructor options ('captureRejections')");
|
|
4510
|
+
}
|
|
4511
|
+
if (base.builtinStream) {
|
|
4512
|
+
// super(options?) into a runtime stream base: the stream spoke
|
|
4513
|
+
// parses the options and binds overridden underscore methods.
|
|
4514
|
+
out.push(...lowerStreamSuperCall(lowerer, info, base, superCall.arguments, thisLocal, locOf(stmt), stmt));
|
|
4515
|
+
out.push(...lowerer.fieldInitStmts(info, thisLocal));
|
|
4516
|
+
out.push(...paramPropInitStmts(lowerer, info, thisLocal));
|
|
4517
|
+
continue;
|
|
4518
|
+
}
|
|
4519
|
+
const args = forward !== undefined
|
|
4520
|
+
? forward
|
|
4521
|
+
: base.builtinError
|
|
4522
|
+
? lowerer.errorConstructorArgs(superCall.arguments, locOf(stmt), stmt)
|
|
4523
|
+
: base.builtinEmitter
|
|
4524
|
+
? []
|
|
4525
|
+
: lowerer.completeArgs(superCall.arguments, base.ctorParams, locOf(stmt), stmt);
|
|
4526
|
+
out.push(lowerer.superCallStmt(info, thisLocal, args, locOf(stmt)));
|
|
4527
|
+
// super() returns → field initializers → parameter-property
|
|
4528
|
+
// assignments (Node's order, probed) → the rest of the body.
|
|
3926
4529
|
out.push(...lowerer.fieldInitStmts(info, thisLocal));
|
|
3927
4530
|
out.push(...paramPropInitStmts(lowerer, info, thisLocal));
|
|
3928
|
-
continue;
|
|
3929
4531
|
}
|
|
3930
|
-
|
|
3931
|
-
|
|
3932
|
-
|
|
3933
|
-
|
|
3934
|
-
|
|
3935
|
-
|
|
3936
|
-
|
|
3937
|
-
out.push(lowerer.superCallStmt(info, thisLocal, args, locOf(stmt)));
|
|
3938
|
-
// super() returns → field initializers → parameter-property
|
|
3939
|
-
// assignments (Node's order, probed) → the rest of the body.
|
|
3940
|
-
out.push(...lowerer.fieldInitStmts(info, thisLocal));
|
|
3941
|
-
out.push(...paramPropInitStmts(lowerer, info, thisLocal));
|
|
3942
|
-
}
|
|
3943
|
-
catch (e) {
|
|
3944
|
-
if (!(e instanceof PoisonError))
|
|
3945
|
-
throw e;
|
|
3946
|
-
if (!lowerer.suppressStats) {
|
|
3947
|
-
lowerer.stats.statementsFailed++;
|
|
3948
|
-
lowerer.bumpFileStat(locOf(stmt).file, "failed");
|
|
4532
|
+
catch (e) {
|
|
4533
|
+
if (!(e instanceof PoisonError))
|
|
4534
|
+
throw e;
|
|
4535
|
+
if (!lowerer.suppressStats) {
|
|
4536
|
+
lowerer.stats.statementsFailed++;
|
|
4537
|
+
lowerer.bumpFileStat(locOf(stmt).file, "failed");
|
|
4538
|
+
}
|
|
3949
4539
|
}
|
|
3950
4540
|
}
|
|
3951
4541
|
}
|
|
4542
|
+
finally {
|
|
4543
|
+
lowerer.activeStmtLists.pop();
|
|
4544
|
+
}
|
|
3952
4545
|
if (!superSeen) {
|
|
3953
4546
|
// tsc guarantees the call exists somewhere; if it wasn't a top-level
|
|
3954
4547
|
// statement the per-site rejection above already fired — this is the
|
|
@@ -3968,6 +4561,12 @@ export function superCallStmt(lowerer, info, thisLocal, args, loc) {
|
|
|
3968
4561
|
type: { kind: "object", className: info.def.name },
|
|
3969
4562
|
loc,
|
|
3970
4563
|
};
|
|
4564
|
+
if (info.callableBase)
|
|
4565
|
+
return {
|
|
4566
|
+
kind: "exprStmt", expr: { kind: "libCall", fn: "dyn.classSuper",
|
|
4567
|
+
args: [{ kind: "varRef", localId: info.callableBase.constructorId, type: DYN, loc },
|
|
4568
|
+
lowerer.coerceToExpected(thisRef, DYN), args[0]], type: VOID, loc }, loc,
|
|
4569
|
+
};
|
|
3971
4570
|
if (base.builtinError) {
|
|
3972
4571
|
// super(message) into the runtime-provided Error constructor: stamps
|
|
3973
4572
|
// name/message on the (already-allocated) object. Receiver + message
|
|
@@ -3977,7 +4576,7 @@ export function superCallStmt(lowerer, info, thisLocal, args, loc) {
|
|
|
3977
4576
|
kind: "exprStmt",
|
|
3978
4577
|
expr: {
|
|
3979
4578
|
kind: "libCall",
|
|
3980
|
-
fn: "error.
|
|
4579
|
+
fn: "error.ctorOptions",
|
|
3981
4580
|
args: [lowerer.upcastTo(thisRef, base.def.name), ...args],
|
|
3982
4581
|
type: VOID,
|
|
3983
4582
|
loc,
|
|
@@ -4081,9 +4680,12 @@ export function lowerSuperMethodCall(lowerer, call, access) {
|
|
|
4081
4680
|
const thisLocal = lowerer.resolveThis();
|
|
4082
4681
|
if (!thisLocal)
|
|
4083
4682
|
lowerer.unsupported("SC1080", access);
|
|
4084
|
-
lowerer.noteEdge(`%${found.declarer.def.name}.${access.name.text}`);
|
|
4085
4683
|
const loc = locOf(call);
|
|
4086
4684
|
const thisRef = { kind: "varRef", localId: thisLocal.id, type: thisLocal.type, loc };
|
|
4685
|
+
if (found.declarer.builtinError) {
|
|
4686
|
+
return { kind: "libCall", fn: "error.toString", args: [lowerer.upcastTo(thisRef, "%Error")], type: STRING, loc };
|
|
4687
|
+
}
|
|
4688
|
+
lowerer.noteEdge(`%${found.declarer.def.name}.${access.name.text}`);
|
|
4087
4689
|
const args = lowerer.completeArgs(call.arguments, found.sig.params, loc, call);
|
|
4088
4690
|
return {
|
|
4089
4691
|
kind: "call",
|
|
@@ -4163,8 +4765,8 @@ export function lowerSuperAccessorWrite(lowerer, access, rhs, loc) {
|
|
|
4163
4765
|
}
|
|
4164
4766
|
/** True when `info`'s EFFECTIVE constructor — its own, or the one
|
|
4165
4767
|
* inherited through ctor-less bases — is a builtin error class's. Such
|
|
4166
|
-
* classes construct with the error
|
|
4167
|
-
* constructors forward
|
|
4768
|
+
* classes construct with the error argument rule, and their synthesized
|
|
4769
|
+
* constructors forward both checked-dynamic values to error.ctorOptions. */
|
|
4168
4770
|
export function inheritsBuiltinErrorCtor(lowerer, info) {
|
|
4169
4771
|
for (let c = info; c; c = c.base) {
|
|
4170
4772
|
if (c.builtinError)
|
|
@@ -4201,25 +4803,18 @@ function inheritsBuiltinStreamCtor(lowerer, info) {
|
|
|
4201
4803
|
}
|
|
4202
4804
|
return false;
|
|
4203
4805
|
}
|
|
4204
|
-
/**
|
|
4205
|
-
|
|
4206
|
-
|
|
4207
|
-
|
|
4208
|
-
|
|
4209
|
-
|
|
4210
|
-
|
|
4211
|
-
|
|
4212
|
-
|
|
4213
|
-
|
|
4214
|
-
|
|
4215
|
-
|
|
4216
|
-
const value = lowerer.lowerExpr(args[0]);
|
|
4217
|
-
if (value.type.kind === "string")
|
|
4218
|
-
return value;
|
|
4219
|
-
if (value.kind === "unitLit" && value.unit === "undefined") {
|
|
4220
|
-
return { kind: "strLit", value: "", type: STRING, loc };
|
|
4221
|
-
}
|
|
4222
|
-
lowerer.unsupported("SC1090", args[0], `Error messages of type '${lowerer.fmt(value.type)}' (the message must be a string)`);
|
|
4806
|
+
/** Preserve argument evaluation order and option presence through builtin
|
|
4807
|
+
* and inherited Error constructors. Checked-dynamic conversion retains
|
|
4808
|
+
* Error identity and distinguishes a missing cause from undefined. */
|
|
4809
|
+
export function errorConstructorArgs(lowerer, args, loc, blame) {
|
|
4810
|
+
if (args.length > 2)
|
|
4811
|
+
lowerer.unsupported("SC1090", blame, "Error constructors with more than two arguments");
|
|
4812
|
+
return [0, 1].map((i) => {
|
|
4813
|
+
const arg = args[i];
|
|
4814
|
+
if (!arg)
|
|
4815
|
+
return dynUndefinedExpr(loc);
|
|
4816
|
+
return lowerer.lowerExprExpecting(arg, DYN);
|
|
4817
|
+
});
|
|
4223
4818
|
}
|
|
4224
4819
|
/** `new C(...)` of a registered PROGRAM class — the shared tail of the
|
|
4225
4820
|
* identifier and namespace-qualified construction forms. */
|
|
@@ -4252,6 +4847,8 @@ function fenceDecorationThrows(lowerer, info, blame) {
|
|
|
4252
4847
|
function lowerProgramClassNew(lowerer, expr, declaredInfo, loc) {
|
|
4253
4848
|
const info = genericNewTarget(lowerer, expr, declaredInfo);
|
|
4254
4849
|
fenceDecorationThrows(lowerer, info, expr);
|
|
4850
|
+
if (info.localClass)
|
|
4851
|
+
lowerer.unsupported("SC1090", expr, "construction through a function-local class's internal name");
|
|
4255
4852
|
lowerer.noteEdge(`%${info.def.name}.constructor`);
|
|
4256
4853
|
// A ctor-less chain into an EventEmitter base inherits `new C()` —
|
|
4257
4854
|
// zero arguments (the options bag fences, like the super() form).
|
|
@@ -4263,11 +4860,10 @@ function lowerProgramClassNew(lowerer, expr, declaredInfo, loc) {
|
|
|
4263
4860
|
if (lowerer.inheritsBuiltinEmitterCtor(info) && (expr.arguments ?? []).length > 0) {
|
|
4264
4861
|
lowerer.unsupported("SC1090", expr.arguments[0], "EventEmitter constructor options ('captureRejections')");
|
|
4265
4862
|
}
|
|
4266
|
-
// A ctor-less chain into a builtin error base inherits
|
|
4267
|
-
//
|
|
4268
|
-
// not the general ABI completion.
|
|
4863
|
+
// A ctor-less chain into a builtin error base inherits both arguments;
|
|
4864
|
+
// each synthesized constructor forwards the same pair to its base.
|
|
4269
4865
|
const args = lowerer.inheritsBuiltinErrorCtor(info)
|
|
4270
|
-
?
|
|
4866
|
+
? lowerer.errorConstructorArgs(expr.arguments ?? [], loc, expr)
|
|
4271
4867
|
: lowerer.completeArgs(expr.arguments ?? [], info.ctorParams, loc, expr);
|
|
4272
4868
|
return {
|
|
4273
4869
|
kind: "new",
|
|
@@ -4290,6 +4886,58 @@ function assignedThisFieldType(lowerer, expr) {
|
|
|
4290
4886
|
}
|
|
4291
4887
|
export function lowerNew(lowerer, expr) {
|
|
4292
4888
|
const loc = locOf(expr);
|
|
4889
|
+
const instanceConstructor = lowerInstanceConstructorNew(lowerer, expr);
|
|
4890
|
+
if (instanceConstructor)
|
|
4891
|
+
return instanceConstructor;
|
|
4892
|
+
const objectFactory = lowerObjectFactoryNew(lowerer, expr);
|
|
4893
|
+
if (objectFactory)
|
|
4894
|
+
return objectFactory;
|
|
4895
|
+
let selected = expr.expression;
|
|
4896
|
+
while (ts.isParenthesizedExpression(selected))
|
|
4897
|
+
selected = selected.expression;
|
|
4898
|
+
if (ts.isConditionalExpression(selected)) {
|
|
4899
|
+
const yes = exactClassOfReceiver(lowerer, selected.whenTrue);
|
|
4900
|
+
const no = exactClassOfReceiver(lowerer, selected.whenFalse);
|
|
4901
|
+
if (yes && no && !yes.classDecorators && !no.classDecorators) {
|
|
4902
|
+
const yesType = { kind: "object", className: yes.def.name };
|
|
4903
|
+
const noType = { kind: "object", className: no.def.name };
|
|
4904
|
+
const type = yes === no ? yesType : { kind: "union", unionId: lowerer.unions.intern([yesType, noType].sort((a, b) => typeKey(a) < typeKey(b) ? -1 : 1)) };
|
|
4905
|
+
return { kind: "ternary", cond: lowerer.lowerCondition(selected.condition),
|
|
4906
|
+
then: lowerer.coerceInto(expr, lowerProgramClassNew(lowerer, expr, yes, loc), type),
|
|
4907
|
+
else_: lowerer.coerceInto(expr, lowerProgramClassNew(lowerer, expr, no, loc), type), type, loc };
|
|
4908
|
+
}
|
|
4909
|
+
}
|
|
4910
|
+
if (ts.isPropertyAccessExpression(expr.expression) && expr.expression.name.text === "Segmenter" &&
|
|
4911
|
+
lowerer.isStdlibGlobal(expr.expression.expression, "Intl")) {
|
|
4912
|
+
const args = expr.arguments ?? [];
|
|
4913
|
+
const undefinedArg = (arg) => (lowerer.typeOf(arg).flags & ts.TypeFlags.Undefined) !== 0;
|
|
4914
|
+
if (args.length > 2 || (args[0] && !undefinedArg(args[0]))) {
|
|
4915
|
+
lowerer.noLowering("Intl.Segmenter locale negotiation", expr, "omit the locale or pass undefined for default Unicode grapheme segmentation");
|
|
4916
|
+
}
|
|
4917
|
+
const options = args[1];
|
|
4918
|
+
if (options && !undefinedArg(options) &&
|
|
4919
|
+
!(ts.isObjectLiteralExpression(options) && options.properties.every((property) => ts.isPropertyAssignment(property) &&
|
|
4920
|
+
(ts.isIdentifier(property.name) || ts.isStringLiteral(property.name)) && property.name.text === "granularity" &&
|
|
4921
|
+
ts.isStringLiteral(property.initializer) && property.initializer.text === "grapheme"))) {
|
|
4922
|
+
lowerer.noLowering("Intl.Segmenter options", options, 'the native segmenter supports default options and { granularity: "grapheme" }; word and sentence segmentation remain unsupported');
|
|
4923
|
+
}
|
|
4924
|
+
// Explicit undefined expressions can carry effects; retain argument order.
|
|
4925
|
+
const stmts = args.map((arg) => {
|
|
4926
|
+
const value = lowerer.lowerExpr(arg);
|
|
4927
|
+
return { kind: "exprStmt", expr: value.type.kind === "void" ? value : lowerer.coerceInto(arg, value, DYN), loc: locOf(arg) };
|
|
4928
|
+
});
|
|
4929
|
+
const result = { kind: "libCall", fn: "intl.segmenterNew", args: [], type: DYN, loc };
|
|
4930
|
+
return stmts.length ? { kind: "seqExpr", stmts, result, type: DYN, loc } : result;
|
|
4931
|
+
}
|
|
4932
|
+
const consoleCtor = ts.isIdentifier(expr.expression)
|
|
4933
|
+
? lowerer.builtinImportOf(expr.expression)
|
|
4934
|
+
: ts.isPropertyAccessExpression(expr.expression) &&
|
|
4935
|
+
lowerer.builtinNamespaceModuleOf(expr.expression.expression) === "console"
|
|
4936
|
+
? { module: "console", member: expr.expression.name.text }
|
|
4937
|
+
: null;
|
|
4938
|
+
if (consoleCtor?.module === "console" && consoleCtor.member === "Console") {
|
|
4939
|
+
lowerer.noLowering("new console.Console", expr, builtinFenceHintOf("console", "Console"));
|
|
4940
|
+
}
|
|
4293
4941
|
// `new X(...)` where X is a package-declared class, in a static build:
|
|
4294
4942
|
// the per-package requires-dynamic diagnostic (the constructor runs in
|
|
4295
4943
|
// the embedded engine). Under --dynamic, X is jsval-typed and lowers
|
|
@@ -4381,7 +5029,7 @@ export function lowerNew(lowerer, expr) {
|
|
|
4381
5029
|
// member-export symbol's; the class collects on demand (a body
|
|
4382
5030
|
// lowering ahead of the assignment statement).
|
|
4383
5031
|
if (!expr.expression.questionDotToken &&
|
|
4384
|
-
((isCjsJsFile(expr.getSourceFile()) &&
|
|
5032
|
+
((isCjsJsFile(expr.getSourceFile(), lowerer.program) &&
|
|
4385
5033
|
(isModuleExportsAccess(expr.expression.expression) ||
|
|
4386
5034
|
(ts.isIdentifier(expr.expression.expression) &&
|
|
4387
5035
|
expr.expression.expression.text === "exports" &&
|
|
@@ -4449,7 +5097,9 @@ export function lowerNew(lowerer, expr) {
|
|
|
4449
5097
|
// (a no-op for every non-import= binding).
|
|
4450
5098
|
fenceEarlyAliasUse(lowerer, expr.expression, expr);
|
|
4451
5099
|
const symbol = lowerer.resolveValueSymbol(expr.expression);
|
|
4452
|
-
|
|
5100
|
+
if (isNativeProxyInitializer(lowerer, expr))
|
|
5101
|
+
return lowerNativeProxy(lowerer, expr);
|
|
5102
|
+
// `new Error(msg?)` and its standard subclasses: the
|
|
4453
5103
|
// runtime-provided classes construct through one libCall — the result
|
|
4454
5104
|
// TYPE names which builtin, and the message completes to "" exactly
|
|
4455
5105
|
// like Node's message property default.
|
|
@@ -4487,11 +5137,11 @@ export function lowerNew(lowerer, expr) {
|
|
|
4487
5137
|
};
|
|
4488
5138
|
}
|
|
4489
5139
|
if (errInfo) {
|
|
4490
|
-
const
|
|
5140
|
+
const args = lowerer.errorConstructorArgs(expr.arguments ?? [], loc, expr);
|
|
4491
5141
|
return {
|
|
4492
5142
|
kind: "libCall",
|
|
4493
|
-
fn: "error.
|
|
4494
|
-
args
|
|
5143
|
+
fn: "error.newOptions",
|
|
5144
|
+
args,
|
|
4495
5145
|
type: { kind: "object", className: errInfo.def.name },
|
|
4496
5146
|
loc,
|
|
4497
5147
|
};
|
|
@@ -4519,25 +5169,40 @@ export function lowerNew(lowerer, expr) {
|
|
|
4519
5169
|
return lowerStreamNew(lowerer, expr, streamInfo);
|
|
4520
5170
|
// `new URL(input)`: the WHATWG URL class (stdlib/@types provenance —
|
|
4521
5171
|
// a user's own `class URL` resolves through classBySymbol below).
|
|
4522
|
-
//
|
|
4523
|
-
// ("Invalid URL"), like Node. The lib's base-argument form
|
|
4524
|
-
// typechecks and is fenced here.
|
|
5172
|
+
// Invalid input or base throws a catchable TypeError ("Invalid URL").
|
|
4525
5173
|
// `new RegExp(pattern, flags?)`: runtime construction over the same
|
|
4526
5174
|
// libregexp engine the literals ride. The pattern compiles EAGERLY,
|
|
4527
5175
|
// so bad input throws Node's catchable SyntaxError at construction.
|
|
4528
|
-
//
|
|
4529
|
-
// form keeps the fence).
|
|
5176
|
+
// Checked arguments retain native regexes and perform runtime coercion.
|
|
4530
5177
|
if (symbol && symbol.name === "RegExp" && lowerer.isStdlibSymbol(symbol)) {
|
|
4531
5178
|
const args = expr.arguments ?? [];
|
|
4532
5179
|
if (args.length > 2) {
|
|
4533
5180
|
lowerer.noLowering(`new RegExp with ${args.length} arguments`, expr);
|
|
4534
5181
|
}
|
|
5182
|
+
if (args.some(ts.isSpreadElement))
|
|
5183
|
+
lowerer.noLowering("new RegExp with spread arguments", expr);
|
|
5184
|
+
const values = args.map((arg) => lowerer.lowerExpr(arg));
|
|
5185
|
+
if (values.some((value) => value.type.kind === "dyn" || value.type.kind === "regex")) {
|
|
5186
|
+
const checked = [0, 1].map((index) => values[index]
|
|
5187
|
+
? lowerer.coerceInto(args[index], values[index], DYN)
|
|
5188
|
+
: { kind: "dynFrom", value: { kind: "unitLit", unit: "undefined", type: UNDEFINED_T, loc }, type: DYN, loc });
|
|
5189
|
+
return { kind: "libCall", fn: "regex.newChecked", args: checked, type: { kind: "regex" }, loc };
|
|
5190
|
+
}
|
|
4535
5191
|
const strArg = (a, what) => {
|
|
4536
5192
|
if (!a)
|
|
4537
5193
|
return { kind: "strLit", value: "", type: STRING, loc };
|
|
4538
|
-
const v =
|
|
5194
|
+
const v = values[args.indexOf(a)];
|
|
5195
|
+
const empty = { kind: "strLit", value: "", type: STRING, loc };
|
|
5196
|
+
if (v.type.kind === "undefinedT") {
|
|
5197
|
+
if (v.kind === "unitLit")
|
|
5198
|
+
return empty;
|
|
5199
|
+
return { kind: "seqExpr", stmts: [{ kind: "exprStmt", expr: lowerer.coerceToExpected(v, DYN), loc: locOf(a) }], result: empty, type: STRING, loc };
|
|
5200
|
+
}
|
|
5201
|
+
if (v.type.kind === "union" && lowerer.unions.get(v.type.unionId)?.arms.every((arm) => arm.kind === "string" || arm.kind === "undefinedT")) {
|
|
5202
|
+
return { kind: "nullish", left: v, right: empty, type: STRING, loc: locOf(a) };
|
|
5203
|
+
}
|
|
4539
5204
|
if (v.type.kind !== "string") {
|
|
4540
|
-
lowerer.noLowering(`new RegExp with a '${lowerer.fmt(v.type)}' ${what}`, a, "string arguments are the lowered form (a RegExp copy or ToString coercion has no lowering)");
|
|
5205
|
+
lowerer.noLowering(`new RegExp with a '${lowerer.fmt(v.type)}' ${what}`, a, "string or undefined arguments are the lowered form (a RegExp copy or ToString coercion has no lowering)");
|
|
4541
5206
|
}
|
|
4542
5207
|
return v;
|
|
4543
5208
|
};
|
|
@@ -4546,25 +5211,7 @@ export function lowerNew(lowerer, expr) {
|
|
|
4546
5211
|
return { kind: "libCall", fn: "regex.new", args: [pattern, flags], type: { kind: "regex" }, loc };
|
|
4547
5212
|
}
|
|
4548
5213
|
if (symbol && symbol.name === "URL" && lowerer.isStdlibSymbol(symbol)) {
|
|
4549
|
-
|
|
4550
|
-
if (args.length === 2) {
|
|
4551
|
-
const folded = staticForkString(lowerer.program, expr);
|
|
4552
|
-
if (folded === null) {
|
|
4553
|
-
lowerer.noLowering("new URL with a runtime-valued base", expr, "a relative literal or statically resolvable template against import.meta.url compiles", symbol);
|
|
4554
|
-
}
|
|
4555
|
-
return {
|
|
4556
|
-
kind: "libCall",
|
|
4557
|
-
fn: "url.new",
|
|
4558
|
-
args: [{ kind: "strLit", value: folded, type: STRING, loc }],
|
|
4559
|
-
type: URL_T,
|
|
4560
|
-
loc,
|
|
4561
|
-
};
|
|
4562
|
-
}
|
|
4563
|
-
if (args.length !== 1) {
|
|
4564
|
-
lowerer.noLowering(`new URL with ${args.length} argument${args.length === 1 ? "" : "s"}`, expr, "one absolute-URL string, or a static relative input against import.meta.url, is supported", symbol);
|
|
4565
|
-
}
|
|
4566
|
-
const input = lowerer.lowerExprExpecting(args[0], STRING);
|
|
4567
|
-
return { kind: "libCall", fn: "url.new", args: [input], type: URL_T, loc };
|
|
5214
|
+
return lowerUrlNew(lowerer, expr);
|
|
4568
5215
|
}
|
|
4569
5216
|
// `new URLSearchParams(init?)`: the WHATWG list (stdlib provenance —
|
|
4570
5217
|
// see lowerSearchParamsNew for the lowered init shapes).
|
|
@@ -4580,6 +5227,11 @@ export function lowerNew(lowerer, expr) {
|
|
|
4580
5227
|
if (args.some(ts.isSpreadElement) || args.length > 1) {
|
|
4581
5228
|
lowerer.noLowering(`new Date with ${args.length} arguments`, expr, "new Date(), new Date(milliseconds), and new Date(dateString) are supported; the local-time year/month field constructor has no lowering", symbol);
|
|
4582
5229
|
}
|
|
5230
|
+
if (isJsSourceFile(expr.getSourceFile())) {
|
|
5231
|
+
return { kind: "libCall", fn: "date.nativeNew", args: [
|
|
5232
|
+
{ kind: "dynArrLit", elems: args.map((arg) => lowerer.lowerExprExpecting(arg, DYN)), type: DYN, loc },
|
|
5233
|
+
], type: DYN, loc };
|
|
5234
|
+
}
|
|
4583
5235
|
if (args.length === 0) {
|
|
4584
5236
|
return { kind: "libCall", fn: "date.newNow", args: [], type: DATE_T, loc };
|
|
4585
5237
|
}
|
|
@@ -4620,14 +5272,8 @@ export function lowerNew(lowerer, expr) {
|
|
|
4620
5272
|
loc,
|
|
4621
5273
|
};
|
|
4622
5274
|
}
|
|
4623
|
-
// Encoder objects likewise never exist: lowerTextCodecCall claims
|
|
4624
|
-
// composed calls before the receiver lowers, while the same-scope
|
|
4625
|
-
// const store-then-call declaration is erased before reaching here.
|
|
4626
5275
|
if (symbol && (symbol.name === "TextDecoder" || symbol.name === "TextEncoder") && lowerer.isStdlibSymbol(symbol)) {
|
|
4627
|
-
lowerer
|
|
4628
|
-
(symbol.name === "TextDecoder"
|
|
4629
|
-
? "new TextDecoder().decode(bytes)"
|
|
4630
|
-
: "new TextEncoder().encode(s)"), symbol);
|
|
5276
|
+
return lowerTextCodecNew(lowerer, expr, symbol.name);
|
|
4631
5277
|
}
|
|
4632
5278
|
// `new Uint8Array(...)` / `new Uint32Array(...)` / `new
|
|
4633
5279
|
// Float32Array(...)` / `new Float64Array(...)`: the typed-array
|
|
@@ -4646,7 +5292,7 @@ export function lowerNew(lowerer, expr) {
|
|
|
4646
5292
|
// A rebindable decorated name constructs through its VALUE (the
|
|
4647
5293
|
// classval-typed path below — newValue through the decoration
|
|
4648
5294
|
// result's construct thunk), never the declaration directly.
|
|
4649
|
-
if (info && info.classDecorators?.valueGlobalId === undefined) {
|
|
5295
|
+
if (info && !info.localClass && info.classDecorators?.valueGlobalId === undefined) {
|
|
4650
5296
|
return lowerProgramClassNew(lowerer, expr, info, loc);
|
|
4651
5297
|
}
|
|
4652
5298
|
// `new Map<K, V>()`: the lib Map constructor. The SEEDED forms: an
|
|
@@ -4654,10 +5300,10 @@ export function lowerNew(lowerer, expr) {
|
|
|
4654
5300
|
// (`new Map([[k, v], ...])`) — each pair's key/value lower as
|
|
4655
5301
|
// ordinary K/V-typed expressions and the backend set()s them in
|
|
4656
5302
|
// order, so the tuple array never exists as a value — and a
|
|
4657
|
-
// `[K, V][]`-typed tuple-array VALUE (
|
|
5303
|
+
// `[K, V][]`-typed tuple-array VALUE (lowerMapSeedNew: a
|
|
4658
5304
|
// construct-and-set loop, pairs in array order, duplicates
|
|
4659
|
-
// overwrite).
|
|
4660
|
-
//
|
|
5305
|
+
// overwrite). Matching Maps copy their entries; nullish seeds make
|
|
5306
|
+
// empty Maps. General iterable seeds retain a fence. Unsupported key/value
|
|
4661
5307
|
// types get their half named specifically instead of the component
|
|
4662
5308
|
// fence (SC2009, which names Map slots at value positions elsewhere).
|
|
4663
5309
|
// Both Array() and new Array() share the elements/count lowering.
|
|
@@ -4688,16 +5334,29 @@ export function lowerNew(lowerer, expr) {
|
|
|
4688
5334
|
: null;
|
|
4689
5335
|
let tsType = lowerer.typeOf(expr);
|
|
4690
5336
|
let mapped = lowerer.mapTypeOf(tsType);
|
|
5337
|
+
if (mapped === null && isJsSourceFile(expr.getSourceFile()))
|
|
5338
|
+
mapped = lowerer.irTypeOf(expr);
|
|
4691
5339
|
const fieldType = assignedThisFieldType(lowerer, expr);
|
|
4692
5340
|
if (mapped?.kind !== "map" && fieldType?.kind === "map")
|
|
4693
5341
|
mapped = fieldType;
|
|
5342
|
+
// A fresh map built from pair literals can use its destination's
|
|
5343
|
+
// layout directly. Inference may otherwise split record values
|
|
5344
|
+
// into incompatible shapes (for example a nullable field), even
|
|
5345
|
+
// though every seed fits the declared value type. Existing map or
|
|
5346
|
+
// tuple-array values retain their own representation.
|
|
5347
|
+
let parent = expr.parent;
|
|
5348
|
+
while (ts.isParenthesizedExpression(parent))
|
|
5349
|
+
parent = parent.parent;
|
|
5350
|
+
// `satisfies` checks a view but retains the expression's own type.
|
|
5351
|
+
const contextualSeed = !ts.isSatisfiesExpression(parent) && (expr.typeArguments?.length ?? 0) === 0 &&
|
|
5352
|
+
(entriesLit !== null || (expr.arguments?.length ?? 0) === 0);
|
|
4694
5353
|
// JavaScript's `new Map()` has no type-argument syntax: the no-arg
|
|
4695
5354
|
// constructor overload pins Map<any, any> whatever the JSDoc says
|
|
4696
5355
|
// (`@type` on the declaration types the VARIABLE, not this
|
|
4697
5356
|
// expression). The CONTEXTUAL type carries the annotation — adopt
|
|
4698
5357
|
// it when it is a supported map. TS type arguments keep winning:
|
|
4699
5358
|
// their expression type already maps.
|
|
4700
|
-
if (mapped?.kind !== "map") {
|
|
5359
|
+
if (mapped?.kind !== "map" || contextualSeed) {
|
|
4701
5360
|
const ctx = lowerer.checker.getContextualType(expr);
|
|
4702
5361
|
const ctxMapped = ctx ? lowerer.mapTypeOf(ctx) : null;
|
|
4703
5362
|
if (ctx && ctxMapped?.kind === "map") {
|
|
@@ -4706,28 +5365,29 @@ export function lowerNew(lowerer, expr) {
|
|
|
4706
5365
|
}
|
|
4707
5366
|
}
|
|
4708
5367
|
if (seedArg && !entriesLit && mapped?.kind === "map") {
|
|
4709
|
-
const seeded =
|
|
5368
|
+
const seeded = lowerMapSeedNew(lowerer, seedArg, mapped);
|
|
4710
5369
|
if (seeded)
|
|
4711
5370
|
return seeded;
|
|
4712
5371
|
}
|
|
4713
5372
|
if ((expr.arguments?.length ?? 0) > 0 && !entriesLit) {
|
|
4714
5373
|
lowerer.noLowering("new Map(entries)", expr, "supported seeds: an array literal of [key, value] pair literals, or a " +
|
|
4715
|
-
"[K, V][]-typed tuple-array value
|
|
4716
|
-
"each entry otherwise");
|
|
5374
|
+
"[K, V][]-typed tuple-array value, a matching Map, or null/undefined");
|
|
4717
5375
|
}
|
|
4718
5376
|
if (mapped?.kind === "map") {
|
|
4719
5377
|
if (!entriesLit)
|
|
4720
5378
|
return { kind: "mapNew", type: mapped, loc };
|
|
4721
5379
|
const seed = entriesLit.map((pair) => ({
|
|
4722
|
-
key: lowerer.
|
|
4723
|
-
value:
|
|
5380
|
+
key: lowerer.lowerCollectionKey(pair.elements[0], mapped.key),
|
|
5381
|
+
value: mapped.value.kind === "dyn"
|
|
5382
|
+
? lowerer.lowerCollectionKey(pair.elements[1], mapped.value)
|
|
5383
|
+
: lowerer.lowerExprExpecting(pair.elements[1], mapped.value),
|
|
4724
5384
|
}));
|
|
4725
5385
|
return { kind: "mapNew", seed, type: mapped, loc };
|
|
4726
5386
|
}
|
|
4727
5387
|
const targs = lowerer.checker.getTypeArguments(tsType);
|
|
4728
5388
|
// JAVASCRIPT `new Map()` whose arguments never resolved past
|
|
4729
5389
|
// Map<any, any> (no annotation, no contextual type, no seed): the
|
|
4730
|
-
//
|
|
5390
|
+
// The VALUE lowers as an opaque dyn object
|
|
4731
5391
|
// (identity and truthiness are real), and every reached METHOD use
|
|
4732
5392
|
// meets its own per-site fence at runtime. The formatter's
|
|
4733
5393
|
// config-cache shape: module init constructs the caches
|
|
@@ -4740,34 +5400,35 @@ export function lowerNew(lowerer, expr) {
|
|
|
4740
5400
|
return { kind: "dynObjLit", type: DYN, loc };
|
|
4741
5401
|
}
|
|
4742
5402
|
const keyIr = targs[0] ? lowerer.mapTypeOf(targs[0]) : null;
|
|
4743
|
-
if (targs[0] && (!keyIr || !isSupportedMapKey(keyIr))) {
|
|
5403
|
+
if (targs[0] && (!keyIr || !isSupportedMapKey(keyIr, keyIr.kind === "union" ? lowerer.unions.get(keyIr.unionId)?.arms : undefined))) {
|
|
4744
5404
|
lowerer.unsupported("SC1090", expr, `Map keys of type '${lowerer.checker.typeToString(targs[0])}' ` +
|
|
4745
|
-
`(Map keys must be
|
|
5405
|
+
`(Map keys must be numbers, strings, identity references, or unions of identity references)`);
|
|
4746
5406
|
}
|
|
4747
5407
|
if (targs[1]) {
|
|
4748
5408
|
lowerer.unsupported("SC1090", expr, `Map values of type '${lowerer.checker.typeToString(targs[1])}' ` +
|
|
4749
5409
|
`(Map values must be number, string, boolean, records, class instances, ` +
|
|
4750
|
-
`arrays, promises, or unions of those — not functions,
|
|
5410
|
+
`arrays, promises, Maps, Sets, or unions of those — not functions, 'unknown', or 'any')`);
|
|
4751
5411
|
}
|
|
4752
5412
|
lowerer.badType(expr, tsType);
|
|
4753
5413
|
}
|
|
4754
|
-
//
|
|
4755
|
-
|
|
4756
|
-
|
|
4757
|
-
|
|
4758
|
-
|
|
4759
|
-
|
|
4760
|
-
|
|
4761
|
-
|
|
4762
|
-
|
|
4763
|
-
|
|
4764
|
-
|
|
4765
|
-
|
|
4766
|
-
|
|
4767
|
-
|
|
4768
|
-
|
|
4769
|
-
return { kind: "dynObjLit", type: DYN, loc };
|
|
5414
|
+
// Weak containers share checked native key identities and lifetime hooks.
|
|
5415
|
+
if ((symbol?.name === "WeakMap" || symbol?.name === "WeakSet") && lowerer.isStdlibSymbol(symbol)) {
|
|
5416
|
+
const args = expr.arguments ?? [];
|
|
5417
|
+
if (args.length > 1 || args.some(ts.isSpreadElement)) {
|
|
5418
|
+
lowerer.unsupported("SC1090", expr, `${symbol.name} construction with surplus or spread arguments`);
|
|
5419
|
+
}
|
|
5420
|
+
if (lowerer.dynamic) {
|
|
5421
|
+
const ctor = { kind: "jsOp", op: "globalGet", name: symbol.name, args: [], type: JSVAL, loc };
|
|
5422
|
+
return { kind: "jsOp", op: "construct", args: [ctor, ...args.map((arg) => lowerer.jsvalIn(lowerer.lowerExpr(arg), arg))], type: JSVAL, loc };
|
|
5423
|
+
}
|
|
5424
|
+
return {
|
|
5425
|
+
kind: "libCall", fn: symbol.name === "WeakMap" ? "weakMap.new" : "weakSet.new",
|
|
5426
|
+
args: [args[0] ? lowerer.lowerExprExpecting(args[0], DYN) : dynUndefinedExpr(loc)],
|
|
5427
|
+
type: DYN, loc,
|
|
5428
|
+
};
|
|
4770
5429
|
}
|
|
5430
|
+
// `new Set<T>()`: construct + bulk add from native arrays, tuples,
|
|
5431
|
+
// or strings. Duplicates collapse in insertion order.
|
|
4771
5432
|
if (symbol?.name === "Set" && lowerer.isStdlibSymbol(symbol)) {
|
|
4772
5433
|
const tsType = lowerer.typeOf(expr);
|
|
4773
5434
|
let mapped = lowerer.mapTypeOf(tsType);
|
|
@@ -4775,55 +5436,9 @@ export function lowerNew(lowerer, expr) {
|
|
|
4775
5436
|
if (mapped?.kind !== "set" && fieldType?.kind === "set")
|
|
4776
5437
|
mapped = fieldType;
|
|
4777
5438
|
if (mapped?.kind === "set" && (expr.arguments?.length ?? 0) === 1) {
|
|
4778
|
-
const
|
|
4779
|
-
|
|
4780
|
-
|
|
4781
|
-
// union — unmappable, so the generic literal path can't type it);
|
|
4782
|
-
// an array-typed VALUE seed lowers as itself.
|
|
4783
|
-
if (ts.isArrayLiteralExpression(argNode) && !argNode.elements.some(ts.isSpreadElement)) {
|
|
4784
|
-
const elems = argNode.elements.map((el) => lowerer.lowerExprExpecting(el, mapped.elem));
|
|
4785
|
-
const seed = { kind: "arrayLit", elems, type: arrayOf(mapped.elem), loc };
|
|
4786
|
-
return { kind: "setNew", seed, type: mapped, loc };
|
|
4787
|
-
}
|
|
4788
|
-
if (!ts.isSpreadElement(argNode)) {
|
|
4789
|
-
const argIr = lowerer.mapTypeOf(lowerer.typeOf(argNode));
|
|
4790
|
-
if (argIr?.kind === "array" && typeEquals(argIr.elem, mapped.elem)) {
|
|
4791
|
-
let seed = lowerer.lowerExpr(argNode);
|
|
4792
|
-
// A T[]-DECLARED seed whose value is an island handle (a
|
|
4793
|
-
// package's exported array — the binding never held a
|
|
4794
|
-
// static array): the VALIDATED exit copies the engine
|
|
4795
|
-
// array out (strict elements, the catchable TypeError on a
|
|
4796
|
-
// lying handle), and the bulk add proceeds on the copy —
|
|
4797
|
-
// construction reads the seed once, so the aliasing
|
|
4798
|
-
// divergence has nothing to observe.
|
|
4799
|
-
if (seed.type.kind === "jsval" && lowerer.boundaryExitSafe(arrayOf(mapped.elem))) {
|
|
4800
|
-
seed = { kind: "jsExit", value: seed, type: arrayOf(mapped.elem), loc: seed.loc };
|
|
4801
|
-
}
|
|
4802
|
-
if (typeEquals(seed.type, arrayOf(mapped.elem))) {
|
|
4803
|
-
return { kind: "setNew", seed, type: mapped, loc };
|
|
4804
|
-
}
|
|
4805
|
-
// Any other lowered kind falls through to the named fence
|
|
4806
|
-
// below — never a mistyped seed into the validator.
|
|
4807
|
-
}
|
|
4808
|
-
// Fixed tuples use record storage, not T[] storage. Snapshot
|
|
4809
|
-
// their legal elements into an array before bulk insertion;
|
|
4810
|
-
// the helper takes the tuple as one argument, so an effectful
|
|
4811
|
-
// seed expression is evaluated exactly once.
|
|
4812
|
-
if (argIr?.kind === "record") {
|
|
4813
|
-
const shape = lowerer.shapes.get(argIr.shapeId);
|
|
4814
|
-
if (shape?.tuple && shape.fields.every((field) => typeEquals(field.type, mapped.elem))) {
|
|
4815
|
-
const seedType = { kind: "array", elem: mapped.elem };
|
|
4816
|
-
const helper = lowerer.tupleArrayWidthHelper(argIr.shapeId, seedType, loc);
|
|
4817
|
-
if (helper) {
|
|
4818
|
-
const tuple = lowerer.lowerExpr(argNode);
|
|
4819
|
-
if (typeEquals(tuple.type, argIr)) {
|
|
4820
|
-
const seed = { kind: "call", callee: helper, args: [tuple], type: seedType, loc };
|
|
4821
|
-
return { kind: "setNew", seed, type: mapped, loc };
|
|
4822
|
-
}
|
|
4823
|
-
}
|
|
4824
|
-
}
|
|
4825
|
-
}
|
|
4826
|
-
}
|
|
5439
|
+
const seeded = lowerSetSeedNew(lowerer, expr.arguments[0], mapped);
|
|
5440
|
+
if (seeded)
|
|
5441
|
+
return seeded;
|
|
4827
5442
|
}
|
|
4828
5443
|
// JavaScript's identity-Set idiom: `new Set([setTimeout, atob,
|
|
4829
5444
|
// ...])` — the element TYPE (a union of stdlib signatures) has no
|
|
@@ -4847,15 +5462,15 @@ export function lowerNew(lowerer, expr) {
|
|
|
4847
5462
|
}
|
|
4848
5463
|
}
|
|
4849
5464
|
if ((expr.arguments?.length ?? 0) > 0) {
|
|
4850
|
-
lowerer.noLowering("new Set(values)", expr, "construct the Set empty and add() each value — only
|
|
4851
|
-
"already-legal elements (
|
|
5465
|
+
lowerer.noLowering("new Set(values)", expr, "construct the Set empty and add() each value — only nullish values or a matching Set, string, array, or fixed tuple of " +
|
|
5466
|
+
"already-legal elements (numbers, strings, or identity references) seeds a Set");
|
|
4852
5467
|
}
|
|
4853
5468
|
if (mapped?.kind === "set")
|
|
4854
5469
|
return { kind: "setNew", type: mapped, loc };
|
|
4855
5470
|
const targs = lowerer.checker.getTypeArguments(tsType);
|
|
4856
5471
|
if (targs[0]) {
|
|
4857
5472
|
lowerer.unsupported("SC1090", expr, `Set elements of type '${lowerer.checker.typeToString(targs[0])}' ` +
|
|
4858
|
-
`(Set elements must be
|
|
5473
|
+
`(Set elements must be numbers, strings, identity references, or unions of identity references)`);
|
|
4859
5474
|
}
|
|
4860
5475
|
lowerer.badType(expr, tsType);
|
|
4861
5476
|
}
|
|
@@ -4961,13 +5576,11 @@ export function lowerNew(lowerer, expr) {
|
|
|
4961
5576
|
String: "boxed wrapper objects have no lowering — use the string primitive (the box is only distinguishable via typeof/identity, which nothing here can honor)",
|
|
4962
5577
|
Number: "boxed wrapper objects have no lowering — use the number primitive",
|
|
4963
5578
|
Boolean: "boxed wrapper objects have no lowering — use the boolean primitive",
|
|
4964
|
-
WeakMap: "weak collections observe garbage collection, which reference counting never exposes — a strong Map behaves identically in-language: use Map",
|
|
4965
|
-
WeakSet: "weak collections observe garbage collection, which reference counting never exposes — a strong Set behaves identically in-language: use Set",
|
|
4966
5579
|
WeakRef: "deref()-after-collect exposes GC timing — genuinely dynamic; hold a strong reference instead",
|
|
4967
5580
|
FinalizationRegistry: "finalization callbacks expose GC timing — genuinely dynamic; release resources explicitly instead",
|
|
4968
5581
|
SharedArrayBuffer: "no shared-memory threads exist in a compiled program — Uint8Array is the byte storage",
|
|
4969
|
-
ArrayBuffer: "
|
|
4970
|
-
Proxy: "
|
|
5582
|
+
ArrayBuffer: "native ArrayBuffer construction supports fixed-length storage; resizable buffers remain unsupported",
|
|
5583
|
+
Proxy: "native Proxy construction requires checked-native plain targets and handlers",
|
|
4971
5584
|
Function: "runtime code generation cannot be compiled ahead of time (the eval stance) — write the function",
|
|
4972
5585
|
};
|
|
4973
5586
|
lowerer.noLowering(`new ${expr.expression.text}`, expr, ctorHints[expr.expression.text], symbol);
|
|
@@ -5055,7 +5668,7 @@ export function lowerNew(lowerer, expr) {
|
|
|
5055
5668
|
// callee (unannotated heterogeneous registries) keeps a pointed
|
|
5056
5669
|
// fence — annotate the slot with the common constructor type.
|
|
5057
5670
|
{
|
|
5058
|
-
const calleeT =
|
|
5671
|
+
const calleeT = storedClassValueType(lowerer, expr.expression);
|
|
5059
5672
|
if (calleeT?.kind === "classval") {
|
|
5060
5673
|
let info = lowerer.classes.get(calleeT.className);
|
|
5061
5674
|
if (!info && ts.isPropertyAccessExpression(expr.expression) && ts.isIdentifier(expr.expression.name)) {
|