@scriptc/compiler 0.2.10 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ambient/scriptc-node-fallback.d.ts +7 -38
- package/ambient/scriptc-overrides.d.ts +1 -25
- package/ambient/scriptc.d.ts +1 -9
- package/dist/backend/cycle-analysis.test.js +1 -1
- package/dist/backend/cycle-mutability.d.ts +1 -1
- package/dist/backend/cycle-mutability.js +1 -18
- package/dist/backend/cycle-mutability.js.map +1 -1
- package/dist/backend/executable-features.d.ts +1 -1
- package/dist/backend/executable-features.js +3 -8
- package/dist/backend/executable-features.js.map +1 -1
- package/dist/backend/immutability.d.ts +1 -1
- package/dist/backend/immutability.js +1 -1
- package/dist/backend/immutability.test.js +1 -1
- package/dist/backend/library-pack.js +0 -2
- package/dist/backend/library-pack.js.map +1 -1
- package/dist/backend/linker.js +1 -1
- package/dist/backend/linker.js.map +1 -1
- package/dist/backend/llvm/bigint-wrap.d.ts +4 -0
- package/dist/backend/llvm/bigint-wrap.js +590 -0
- package/dist/backend/llvm/bigint-wrap.js.map +1 -0
- package/dist/backend/llvm/blocks.d.ts +2 -0
- package/dist/backend/llvm/blocks.js +4 -0
- package/dist/backend/llvm/blocks.js.map +1 -1
- package/dist/backend/llvm/call-lifetimes.js +15 -4
- package/dist/backend/llvm/call-lifetimes.js.map +1 -1
- package/dist/backend/llvm/call-lifetimes.test.js +14 -3
- package/dist/backend/llvm/call-lifetimes.test.js.map +1 -1
- package/dist/backend/llvm/checked-narrows.test.js +2 -2
- package/dist/backend/llvm/checked-narrows.test.js.map +1 -1
- package/dist/backend/llvm/classes.js +60 -21
- package/dist/backend/llvm/classes.js.map +1 -1
- package/dist/backend/llvm/classes.test.js +11 -11
- package/dist/backend/llvm/classes.test.js.map +1 -1
- package/dist/backend/llvm/common.d.ts +7 -5
- package/dist/backend/llvm/common.js +7 -5
- package/dist/backend/llvm/common.js.map +1 -1
- package/dist/backend/llvm/constant-callbacks.d.ts +1 -1
- package/dist/backend/llvm/constant-callbacks.js +13 -31
- package/dist/backend/llvm/constant-callbacks.js.map +1 -1
- package/dist/backend/llvm/constant-callbacks.test.js +1 -1
- package/dist/backend/llvm/dense-array-access.js +133 -45
- package/dist/backend/llvm/dense-array-access.js.map +1 -1
- package/dist/backend/llvm/dense-array-access.test.js +54 -2
- package/dist/backend/llvm/dense-array-access.test.js.map +1 -1
- package/dist/backend/llvm/dyn.d.ts +2 -1
- package/dist/backend/llvm/dyn.js +4 -73
- package/dist/backend/llvm/dyn.js.map +1 -1
- package/dist/backend/llvm/emitter.d.ts +123 -23
- package/dist/backend/llvm/emitter.js +729 -258
- package/dist/backend/llvm/emitter.js.map +1 -1
- package/dist/backend/llvm/emitter.test.js +17 -10
- package/dist/backend/llvm/emitter.test.js.map +1 -1
- package/dist/backend/llvm/expr-async.js +120 -43
- package/dist/backend/llvm/expr-async.js.map +1 -1
- package/dist/backend/llvm/expr-async.test.js +2 -2
- package/dist/backend/llvm/expr-async.test.js.map +1 -1
- package/dist/backend/llvm/expr-bytes.js +51 -36
- package/dist/backend/llvm/expr-bytes.js.map +1 -1
- package/dist/backend/llvm/expr-callbacks.js +72 -3
- package/dist/backend/llvm/expr-callbacks.js.map +1 -1
- package/dist/backend/llvm/expr-calls.d.ts +1 -1
- package/dist/backend/llvm/expr-calls.js +159 -30
- package/dist/backend/llvm/expr-calls.js.map +1 -1
- package/dist/backend/llvm/expr-calls.test.js +132 -0
- package/dist/backend/llvm/expr-calls.test.js.map +1 -0
- package/dist/backend/llvm/expr-containers.js +25 -8
- package/dist/backend/llvm/expr-containers.js.map +1 -1
- package/dist/backend/llvm/expr-context.d.ts +2 -0
- package/dist/backend/llvm/expr-control.js +4 -107
- package/dist/backend/llvm/expr-control.js.map +1 -1
- package/dist/backend/llvm/expr-dispatch.d.ts +1 -2
- package/dist/backend/llvm/expr-dispatch.js +3 -41
- package/dist/backend/llvm/expr-dispatch.js.map +1 -1
- package/dist/backend/llvm/expr-dynamic.d.ts +1 -1
- package/dist/backend/llvm/expr-dynamic.js +39 -31
- package/dist/backend/llvm/expr-dynamic.js.map +1 -1
- package/dist/backend/llvm/expr-primitives.d.ts +7 -0
- package/dist/backend/llvm/expr-primitives.js +80 -22
- package/dist/backend/llvm/expr-primitives.js.map +1 -1
- package/dist/backend/llvm/expr-primitives.test.js +97 -7
- package/dist/backend/llvm/expr-primitives.test.js.map +1 -1
- package/dist/backend/llvm/expr-records.d.ts +9 -0
- package/dist/backend/llvm/expr-records.js +134 -16
- package/dist/backend/llvm/expr-records.js.map +1 -1
- package/dist/backend/llvm/expr-stream-bridges.d.ts +1 -1
- package/dist/backend/llvm/expr-stream-bridges.js +80 -1
- package/dist/backend/llvm/expr-stream-bridges.js.map +1 -1
- package/dist/backend/llvm/expr-stream-bridges.test.js +51 -2
- package/dist/backend/llvm/expr-stream-bridges.test.js.map +1 -1
- package/dist/backend/llvm/int32-abi.d.ts +31 -0
- package/dist/backend/llvm/int32-abi.js +62 -0
- package/dist/backend/llvm/int32-abi.js.map +1 -0
- package/dist/backend/llvm/int32-abi.test.js +107 -0
- package/dist/backend/llvm/int32-abi.test.js.map +1 -0
- package/dist/backend/llvm/int32-locals.d.ts +30 -0
- package/dist/backend/llvm/int32-locals.js +95 -0
- package/dist/backend/llvm/int32-locals.js.map +1 -0
- package/dist/backend/llvm/integer-values.d.ts +4 -0
- package/dist/backend/llvm/integer-values.js +30 -1
- package/dist/backend/llvm/integer-values.js.map +1 -1
- package/dist/backend/llvm/integer-views.d.ts +8 -1
- package/dist/backend/llvm/integer-views.js +47 -2
- package/dist/backend/llvm/integer-views.js.map +1 -1
- package/dist/backend/llvm/lazy-captures.d.ts +16 -0
- package/dist/backend/llvm/lazy-captures.js +88 -2
- package/dist/backend/llvm/lazy-captures.js.map +1 -1
- package/dist/backend/llvm/lazy-captures.test.js +48 -0
- package/dist/backend/llvm/lazy-captures.test.js.map +1 -1
- package/dist/backend/llvm/lib-dispatch.js +14 -1
- package/dist/backend/llvm/lib-dispatch.js.map +1 -1
- package/dist/backend/llvm/lib-filesystem.js +3 -13
- package/dist/backend/llvm/lib-filesystem.js.map +1 -1
- package/dist/backend/llvm/lib-shared.js +7 -8
- package/dist/backend/llvm/lib-shared.js.map +1 -1
- package/dist/backend/llvm/local-array-reads.js +21 -2
- package/dist/backend/llvm/local-array-reads.js.map +1 -1
- package/dist/backend/llvm/local-array-reads.test.js +4 -3
- package/dist/backend/llvm/local-array-reads.test.js.map +1 -1
- package/dist/backend/llvm/local-union-storage.test.js +3 -3
- package/dist/backend/llvm/local-union-storage.test.js.map +1 -1
- package/dist/backend/llvm/map-number-lookup.d.ts +7 -0
- package/dist/backend/llvm/map-number-lookup.js +16 -2
- package/dist/backend/llvm/map-number-lookup.js.map +1 -1
- package/dist/backend/llvm/map-read-lifetimes.js +7 -1
- package/dist/backend/llvm/map-read-lifetimes.js.map +1 -1
- package/dist/backend/llvm/map-read-lifetimes.test.js +25 -8
- package/dist/backend/llvm/map-read-lifetimes.test.js.map +1 -1
- package/dist/backend/llvm/reference-effects.js +2 -0
- package/dist/backend/llvm/reference-effects.js.map +1 -1
- package/dist/backend/llvm/reference-writes.d.ts +3 -0
- package/dist/backend/llvm/reference-writes.js +10 -2
- package/dist/backend/llvm/reference-writes.js.map +1 -1
- package/dist/backend/llvm/regex-matchers.d.ts +39 -0
- package/dist/backend/llvm/regex-matchers.js +1649 -0
- package/dist/backend/llvm/regex-matchers.js.map +1 -0
- package/dist/backend/llvm/regex-matchers.test.js +96 -0
- package/dist/backend/llvm/regex-matchers.test.js.map +1 -0
- package/dist/backend/llvm/shapes.d.ts +36 -1
- package/dist/backend/llvm/shapes.js +128 -16
- package/dist/backend/llvm/shapes.js.map +1 -1
- package/dist/backend/llvm/shapes.test.js +3 -3
- package/dist/backend/llvm/stack-unions.test.js +2 -2
- package/dist/backend/llvm/stack-unions.test.js.map +1 -1
- package/dist/backend/llvm/string-construction.test.js +3 -3
- package/dist/backend/llvm/string-construction.test.js.map +1 -1
- package/dist/backend/llvm/string-lifetimes.test.js +6 -6
- package/dist/backend/llvm/string-lifetimes.test.js.map +1 -1
- package/dist/backend/llvm/string-literal-equality.d.ts +22 -0
- package/dist/backend/llvm/string-literal-equality.js +78 -0
- package/dist/backend/llvm/string-literal-equality.js.map +1 -0
- package/dist/backend/llvm/switch-dispatch.js +59 -13
- package/dist/backend/llvm/switch-dispatch.js.map +1 -1
- package/dist/backend/llvm/switch-dispatch.test.js +72 -7
- package/dist/backend/llvm/switch-dispatch.test.js.map +1 -1
- package/dist/backend/llvm/union-retype.test.d.ts +1 -0
- package/dist/backend/llvm/union-retype.test.js +229 -0
- package/dist/backend/llvm/union-retype.test.js.map +1 -0
- package/dist/backend/llvm/wrapping-sums.d.ts +17 -0
- package/dist/backend/llvm/wrapping-sums.js +113 -0
- package/dist/backend/llvm/wrapping-sums.js.map +1 -0
- package/dist/backend/loop-polls.js +1 -0
- package/dist/backend/loop-polls.js.map +1 -1
- package/dist/backend/mangle.d.ts +9 -0
- package/dist/backend/mangle.js +15 -0
- package/dist/backend/mangle.js.map +1 -1
- package/dist/backend/may-throw.js +6 -12
- package/dist/backend/may-throw.js.map +1 -1
- package/dist/backend/may-throw.test.js +1 -1
- package/dist/backend/native/artifact-stamps.js +0 -2
- package/dist/backend/native/artifact-stamps.js.map +1 -1
- package/dist/backend/native/cache-warm.d.ts +1 -1
- package/dist/backend/native/cache-warm.js +2 -3
- package/dist/backend/native/cache-warm.js.map +1 -1
- package/dist/backend/native/compiler-fingerprint.d.ts +1 -1
- package/dist/backend/native/compiler-fingerprint.js +4 -7
- package/dist/backend/native/compiler-fingerprint.js.map +1 -1
- package/dist/backend/native/contracts.d.ts +3 -28
- package/dist/backend/native/driver.js +1 -3
- package/dist/backend/native/driver.js.map +1 -1
- package/dist/backend/native/executable.d.ts +0 -15
- package/dist/backend/native/executable.js +17 -172
- package/dist/backend/native/executable.js.map +1 -1
- package/dist/backend/native/tool-identity.js +0 -1
- package/dist/backend/native/tool-identity.js.map +1 -1
- package/dist/backend/native/vendor.d.ts +1 -1
- package/dist/backend/native/vendor.js +1 -1
- package/dist/backend/native/vendor.js.map +1 -1
- package/dist/backend/native-link-info-core.d.ts +0 -2
- package/dist/backend/native-link-info-core.js.map +1 -1
- package/dist/backend/native-toolchain.test.js +23 -33
- package/dist/backend/native-toolchain.test.js.map +1 -1
- package/dist/backend/publication.test.js +1 -1
- package/dist/backend/runtime-abi.d.ts +2 -2
- package/dist/backend/runtime-abi.js +2 -2
- package/dist/backend/runtime-pack-core.d.ts +1 -2
- package/dist/backend/runtime-pack-core.js +5 -14
- package/dist/backend/runtime-pack-core.js.map +1 -1
- package/dist/backend/runtime-pack-targets.test.js +3 -8
- package/dist/backend/runtime-pack-targets.test.js.map +1 -1
- package/dist/backend/runtime-pack.test.js +22 -19
- package/dist/backend/runtime-pack.test.js.map +1 -1
- package/dist/backend/target-diagnostics.d.ts +0 -5
- package/dist/backend/target-diagnostics.js +1 -11
- package/dist/backend/target-diagnostics.js.map +1 -1
- package/dist/backend/target-diagnostics.test.js +1 -1
- package/dist/backend/vendor-archives.d.ts +1 -7
- package/dist/backend/vendor-archives.js +9 -189
- package/dist/backend/vendor-archives.js.map +1 -1
- package/dist/backend/vendor-inputs.d.ts +0 -1
- package/dist/backend/vendor-inputs.js +0 -1
- package/dist/backend/vendor-inputs.js.map +1 -1
- package/dist/backend/warm-cache.js +3 -5
- package/dist/backend/warm-cache.js.map +1 -1
- package/dist/cli/command.js +4 -8
- package/dist/cli/command.js.map +1 -1
- package/dist/cli/host.d.ts +1 -1
- package/dist/cli/usage.d.ts +1 -5
- package/dist/cli/usage.js +4 -9
- package/dist/cli/usage.js.map +1 -1
- package/dist/compat/fetch-profile.d.ts +2 -2
- package/dist/compat/fetch-profile.js +16 -25
- package/dist/compat/fetch-profile.js.map +1 -1
- package/dist/compile-types.d.ts +2 -17
- package/dist/contracts/check.js +6 -6
- package/dist/contracts/check.js.map +1 -1
- package/dist/coverage/report.d.ts +5 -22
- package/dist/coverage/report.js +12 -76
- package/dist/coverage/report.js.map +1 -1
- package/dist/coverage/surface-manifest.d.ts +3 -3
- package/dist/coverage/surface-manifest.js +22 -27
- package/dist/coverage/surface-manifest.js.map +1 -1
- package/dist/coverage/verdict-cache.d.ts +1 -3
- package/dist/coverage/verdict-cache.js +2 -7
- package/dist/coverage/verdict-cache.js.map +1 -1
- package/dist/diagnostics/diagnostic.d.ts +11 -60
- package/dist/diagnostics/diagnostic.js +39 -118
- package/dist/diagnostics/diagnostic.js.map +1 -1
- package/dist/diagnostics/envelope.d.ts +3 -4
- package/dist/diagnostics/envelope.js +0 -9
- package/dist/diagnostics/envelope.js.map +1 -1
- package/dist/diagnostics/envelope.test.js +1 -1
- package/dist/diagnostics/envelope.test.js.map +1 -1
- package/dist/executable/executable-cache.d.ts +0 -3
- package/dist/executable/executable-cache.js +2 -4
- package/dist/executable/executable-cache.js.map +1 -1
- package/dist/executable/executable-cache.test.js +0 -4
- package/dist/executable/executable-cache.test.js.map +1 -1
- package/dist/executable/prepare.js +5 -2
- package/dist/executable/prepare.js.map +1 -1
- package/dist/frontend/analysis.js +10 -10
- package/dist/frontend/analysis.js.map +1 -1
- package/dist/frontend/cjs-syntax.js +0 -88
- package/dist/frontend/cjs-syntax.js.map +1 -1
- package/dist/frontend/dts-paths.d.ts +1 -1
- package/dist/frontend/dts-paths.js +1 -1
- package/dist/frontend/lowering/abstract-equality.js +1 -4
- package/dist/frontend/lowering/abstract-equality.js.map +1 -1
- package/dist/frontend/lowering/array-values.d.ts +14 -0
- package/dist/frontend/lowering/array-values.js +33 -11
- package/dist/frontend/lowering/array-values.js.map +1 -1
- package/dist/frontend/lowering/builtins/arguments.js +0 -13
- package/dist/frontend/lowering/builtins/arguments.js.map +1 -1
- package/dist/frontend/lowering/builtins/crypto.d.ts +0 -4
- package/dist/frontend/lowering/builtins/crypto.js +0 -4
- package/dist/frontend/lowering/builtins/crypto.js.map +1 -1
- package/dist/frontend/lowering/builtins/json.js +1 -39
- package/dist/frontend/lowering/builtins/json.js.map +1 -1
- package/dist/frontend/lowering/builtins/module-resolution.d.ts +0 -15
- package/dist/frontend/lowering/builtins/module-resolution.js +5 -44
- package/dist/frontend/lowering/builtins/module-resolution.js.map +1 -1
- package/dist/frontend/lowering/builtins/numbers.d.ts +0 -6
- package/dist/frontend/lowering/builtins/numbers.js +6 -57
- package/dist/frontend/lowering/builtins/numbers.js.map +1 -1
- package/dist/frontend/lowering/builtins/promises.js +4 -67
- package/dist/frontend/lowering/builtins/promises.js.map +1 -1
- package/dist/frontend/lowering/builtins/workers.js +1 -1
- package/dist/frontend/lowering/builtins/workers.js.map +1 -1
- package/dist/frontend/lowering/call-arguments.d.ts +1 -37
- package/dist/frontend/lowering/call-arguments.js +11 -94
- package/dist/frontend/lowering/call-arguments.js.map +1 -1
- package/dist/frontend/lowering/call-signatures.d.ts +1 -6
- package/dist/frontend/lowering/call-signatures.js +16 -68
- package/dist/frontend/lowering/call-signatures.js.map +1 -1
- package/dist/frontend/lowering/class-dynamic-dispatch.d.ts +19 -4
- package/dist/frontend/lowering/class-dynamic-dispatch.js +168 -98
- package/dist/frontend/lowering/class-dynamic-dispatch.js.map +1 -1
- package/dist/frontend/lowering/class-dynamic-dispatch.test.js +44 -4
- package/dist/frontend/lowering/class-dynamic-dispatch.test.js.map +1 -1
- package/dist/frontend/lowering/class-method-mutations.js +0 -2
- package/dist/frontend/lowering/class-method-mutations.js.map +1 -1
- package/dist/frontend/lowering/class-protocols.js +1 -1
- package/dist/frontend/lowering/class-protocols.js.map +1 -1
- package/dist/frontend/lowering/coercions/function-adapters.js +5 -35
- package/dist/frontend/lowering/coercions/function-adapters.js.map +1 -1
- package/dist/frontend/lowering/coercions/state.d.ts +0 -1
- package/dist/frontend/lowering/coercions/state.js +0 -1
- package/dist/frontend/lowering/coercions/state.js.map +1 -1
- package/dist/frontend/lowering/coercions/structural-plans.js +2 -4
- package/dist/frontend/lowering/coercions/structural-plans.js.map +1 -1
- package/dist/frontend/lowering/coercions/structural.js +2 -12
- package/dist/frontend/lowering/coercions/structural.js.map +1 -1
- package/dist/frontend/lowering/coercions/unions.js +0 -1
- package/dist/frontend/lowering/coercions/unions.js.map +1 -1
- package/dist/frontend/lowering/containers/array-callbacks.js +49 -28
- package/dist/frontend/lowering/containers/array-callbacks.js.map +1 -1
- package/dist/frontend/lowering/containers/array-construction.js +2 -3
- package/dist/frontend/lowering/containers/array-construction.js.map +1 -1
- package/dist/frontend/lowering/containers/array-methods.js +10 -54
- package/dist/frontend/lowering/containers/array-methods.js.map +1 -1
- package/dist/frontend/lowering/containers/array-pipelines.d.ts +54 -0
- package/dist/frontend/lowering/containers/array-pipelines.js +1827 -0
- package/dist/frontend/lowering/containers/array-pipelines.js.map +1 -0
- package/dist/frontend/lowering/containers/bytes.js +0 -1
- package/dist/frontend/lowering/containers/bytes.js.map +1 -1
- package/dist/frontend/lowering/containers/callback-arguments.js +2 -10
- package/dist/frontend/lowering/containers/callback-arguments.js.map +1 -1
- package/dist/frontend/lowering/containers/collection-methods.js +1 -6
- package/dist/frontend/lowering/containers/collection-methods.js.map +1 -1
- package/dist/frontend/lowering/containers/exec-result-uses.d.ts +10 -0
- package/dist/frontend/lowering/containers/exec-result-uses.js +88 -0
- package/dist/frontend/lowering/containers/exec-result-uses.js.map +1 -0
- package/dist/frontend/lowering/containers/indexed-objects.js +0 -2
- package/dist/frontend/lowering/containers/indexed-objects.js.map +1 -1
- package/dist/frontend/lowering/containers/string-and-regexp.d.ts +0 -6
- package/dist/frontend/lowering/containers/string-and-regexp.js +17 -17
- package/dist/frontend/lowering/containers/string-and-regexp.js.map +1 -1
- package/dist/frontend/lowering/containers/string-replacement.d.ts +2 -1
- package/dist/frontend/lowering/containers/string-replacement.js +32 -136
- package/dist/frontend/lowering/containers/string-replacement.js.map +1 -1
- package/dist/frontend/lowering/devirtualize.d.ts +33 -0
- package/dist/frontend/lowering/devirtualize.js +199 -0
- package/dist/frontend/lowering/devirtualize.js.map +1 -0
- package/dist/frontend/lowering/expressions/evaluation-safety.js +0 -3
- package/dist/frontend/lowering/expressions/evaluation-safety.js.map +1 -1
- package/dist/frontend/lowering/expressions/native-proxy.js +1 -1
- package/dist/frontend/lowering/expressions/native-proxy.js.map +1 -1
- package/dist/frontend/lowering/expressions/nullish-assignment.js +55 -8
- package/dist/frontend/lowering/expressions/nullish-assignment.js.map +1 -1
- package/dist/frontend/lowering/expressions/object-literals.d.ts +0 -8
- package/dist/frontend/lowering/expressions/object-literals.js +8 -35
- package/dist/frontend/lowering/expressions/object-literals.js.map +1 -1
- package/dist/frontend/lowering/expressions/optional-chains.d.ts +0 -4
- package/dist/frontend/lowering/expressions/optional-chains.js +3 -66
- package/dist/frontend/lowering/expressions/optional-chains.js.map +1 -1
- package/dist/frontend/lowering/function-context.js +0 -1
- package/dist/frontend/lowering/function-context.js.map +1 -1
- package/dist/frontend/lowering/generic-functions.js +0 -1
- package/dist/frontend/lowering/generic-functions.js.map +1 -1
- package/dist/frontend/lowering/identifier-uses.d.ts +7 -0
- package/dist/frontend/lowering/identifier-uses.js +23 -0
- package/dist/frontend/lowering/identifier-uses.js.map +1 -0
- package/dist/frontend/lowering/iterator-adapters.js +51 -3
- package/dist/frontend/lowering/iterator-adapters.js.map +1 -1
- package/dist/frontend/lowering/lib-boundary.js +10 -77
- package/dist/frontend/lowering/lib-boundary.js.map +1 -1
- package/dist/frontend/lowering/lower-array-sort.js +14 -10
- package/dist/frontend/lowering/lower-array-sort.js.map +1 -1
- package/dist/frontend/lowering/lower-array-sort.test.js +2 -2
- package/dist/frontend/lowering/lower-array-sort.test.js.map +1 -1
- package/dist/frontend/lowering/lower-assert.js +2 -3
- package/dist/frontend/lowering/lower-assert.js.map +1 -1
- package/dist/frontend/lowering/lower-async-iteration.js +1 -1
- package/dist/frontend/lowering/lower-calls.d.ts +2 -27
- package/dist/frontend/lowering/lower-calls.js +111 -493
- package/dist/frontend/lowering/lower-calls.js.map +1 -1
- package/dist/frontend/lowering/lower-classes.js +12 -60
- package/dist/frontend/lowering/lower-classes.js.map +1 -1
- package/dist/frontend/lowering/lower-comptime.js +2 -3
- package/dist/frontend/lowering/lower-comptime.js.map +1 -1
- package/dist/frontend/lowering/lower-console.d.ts +14 -0
- package/dist/frontend/lowering/lower-console.js +195 -0
- package/dist/frontend/lowering/lower-console.js.map +1 -0
- package/dist/frontend/lowering/lower-enums.js +5 -8
- package/dist/frontend/lowering/lower-enums.js.map +1 -1
- package/dist/frontend/lowering/lower-event-emitter.js +3 -4
- package/dist/frontend/lowering/lower-event-emitter.js.map +1 -1
- package/dist/frontend/lowering/lower-expando.js +3 -5
- package/dist/frontend/lowering/lower-expando.js.map +1 -1
- package/dist/frontend/lowering/lower-exprs.d.ts +0 -8
- package/dist/frontend/lowering/lower-exprs.js +180 -905
- package/dist/frontend/lowering/lower-exprs.js.map +1 -1
- package/dist/frontend/lowering/lower-functions.js +9 -8
- package/dist/frontend/lowering/lower-functions.js.map +1 -1
- package/dist/frontend/lowering/lower-generators.d.ts +10 -0
- package/dist/frontend/lowering/lower-generators.js +108 -41
- package/dist/frontend/lowering/lower-generators.js.map +1 -1
- package/dist/frontend/lowering/lower-inspect.js +1 -50
- package/dist/frontend/lowering/lower-inspect.js.map +1 -1
- package/dist/frontend/lowering/lower-modules.d.ts +0 -43
- package/dist/frontend/lowering/lower-modules.js +29 -329
- package/dist/frontend/lowering/lower-modules.js.map +1 -1
- package/dist/frontend/lowering/lower-modules.test.js +5 -5
- package/dist/frontend/lowering/lower-modules.test.js.map +1 -1
- package/dist/frontend/lowering/lower-server.js +0 -30
- package/dist/frontend/lowering/lower-server.js.map +1 -1
- package/dist/frontend/lowering/lower-stdlib.d.ts +98 -0
- package/dist/frontend/lowering/{lower-island.js → lower-stdlib.js} +97 -1160
- package/dist/frontend/lowering/lower-stdlib.js.map +1 -0
- package/dist/frontend/lowering/lower-stmts.d.ts +0 -16
- package/dist/frontend/lowering/lower-stmts.js +58 -1016
- package/dist/frontend/lowering/lower-stmts.js.map +1 -1
- package/dist/frontend/lowering/lower-stmts.test.js +1 -1
- package/dist/frontend/lowering/lower-stmts.test.js.map +1 -1
- package/dist/frontend/lowering/lower-stream.js +14 -13
- package/dist/frontend/lowering/lower-stream.js.map +1 -1
- package/dist/frontend/lowering/lowerer.d.ts +42 -155
- package/dist/frontend/lowering/lowerer.js +192 -816
- package/dist/frontend/lowering/lowerer.js.map +1 -1
- package/dist/frontend/lowering/lowerer.test.js +4 -51
- package/dist/frontend/lowering/lowerer.test.js.map +1 -1
- package/dist/frontend/lowering/nan-coded-reads.d.ts +16 -0
- package/dist/frontend/lowering/nan-coded-reads.js +108 -1
- package/dist/frontend/lowering/nan-coded-reads.js.map +1 -1
- package/dist/frontend/lowering/narrowing-stability.js +1 -1
- package/dist/frontend/lowering/narrowing-stability.js.map +1 -1
- package/dist/frontend/lowering/optional-arguments.js +0 -2
- package/dist/frontend/lowering/optional-arguments.js.map +1 -1
- package/dist/frontend/lowering/runtime-optional-bounds.d.ts +4 -0
- package/dist/frontend/lowering/runtime-optional-bounds.js +2 -0
- package/dist/frontend/lowering/runtime-optional-bounds.js.map +1 -1
- package/dist/frontend/lowering/runtime-optional-bounds.test.js +27 -0
- package/dist/frontend/lowering/runtime-optional-bounds.test.js.map +1 -1
- package/dist/frontend/lowering/sanitize-class-types.test.js +2 -2
- package/dist/frontend/lowering/split-consumers.js +2 -18
- package/dist/frontend/lowering/split-consumers.js.map +1 -1
- package/dist/frontend/lowering/strict-equality.js +1 -1
- package/dist/frontend/lowering/strict-equality.js.map +1 -1
- package/dist/frontend/lowering/surfaces.d.ts +6 -45
- package/dist/frontend/lowering/surfaces.js +8 -73
- package/dist/frontend/lowering/surfaces.js.map +1 -1
- package/dist/frontend/lowering/union-retag.d.ts +6 -1
- package/dist/frontend/lowering/union-retag.js +64 -1
- package/dist/frontend/lowering/union-retag.js.map +1 -1
- package/dist/frontend/lowering/union-retag.test.js +46 -0
- package/dist/frontend/lowering/union-retag.test.js.map +1 -1
- package/dist/frontend/module-syntax.d.ts +0 -3
- package/dist/frontend/module-syntax.js.map +1 -1
- package/dist/frontend/npm-node.d.ts +0 -7
- package/dist/frontend/npm-node.js +0 -7
- package/dist/frontend/npm-node.js.map +1 -1
- package/dist/frontend/npm-static-rewrite-syntax.d.ts +1 -1
- package/dist/frontend/npm-static-rewrite-syntax.js +6 -82
- package/dist/frontend/npm-static-rewrite-syntax.js.map +1 -1
- package/dist/frontend/npm-static.d.ts +1 -1
- package/dist/frontend/npm-static.js +6 -71
- package/dist/frontend/npm-static.js.map +1 -1
- package/dist/frontend/npm.d.ts +3 -319
- package/dist/frontend/npm.js +6 -1007
- package/dist/frontend/npm.js.map +1 -1
- package/dist/frontend/npm.test.js +2 -197
- package/dist/frontend/npm.test.js.map +1 -1
- package/dist/frontend/pipeline-native.js +1 -2
- package/dist/frontend/pipeline-native.js.map +1 -1
- package/dist/frontend/pipeline.d.ts +3 -11
- package/dist/frontend/pipeline.js +37 -56
- package/dist/frontend/pipeline.js.map +1 -1
- package/dist/frontend/pipeline.test.js +12 -6
- package/dist/frontend/pipeline.test.js.map +1 -1
- package/dist/frontend/program.d.ts +0 -34
- package/dist/frontend/program.js +12 -97
- package/dist/frontend/program.js.map +1 -1
- package/dist/frontend/provenance-core.d.ts +0 -4
- package/dist/frontend/provenance-core.js +4 -37
- package/dist/frontend/provenance-core.js.map +1 -1
- package/dist/frontend/provenance-registry.d.ts +0 -4
- package/dist/frontend/provenance-registry.js +0 -20
- package/dist/frontend/provenance-registry.js.map +1 -1
- package/dist/frontend/resolve.d.ts +0 -12
- package/dist/frontend/resolve.js +0 -34
- package/dist/frontend/resolve.js.map +1 -1
- package/dist/frontend/runtime-resolve.js +2 -2
- package/dist/frontend/runtime-resolve.js.map +1 -1
- package/dist/frontend/services-node.js +2 -3
- package/dist/frontend/services-node.js.map +1 -1
- package/dist/frontend/services.d.ts +1 -8
- package/dist/frontend/services.js +2 -22
- package/dist/frontend/services.js.map +1 -1
- package/dist/frontend/services.test.js +0 -38
- package/dist/frontend/services.test.js.map +1 -1
- package/dist/frontend/tsc-codes.js +0 -11
- package/dist/frontend/tsc-codes.js.map +1 -1
- package/dist/frontend/type-mapper.d.ts +2 -27
- package/dist/frontend/type-mapper.js +58 -156
- package/dist/frontend/type-mapper.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +7 -10
- package/dist/index.js.map +1 -1
- package/dist/ir/api.d.ts +1 -1
- package/dist/ir/api.js +1 -1
- package/dist/ir/api.js.map +1 -1
- package/dist/ir/builtin-effects.js +2 -5
- package/dist/ir/builtin-effects.js.map +1 -1
- package/dist/ir/builtin-signatures.d.ts +1 -1
- package/dist/ir/builtin-signatures.js +13 -56
- package/dist/ir/builtin-signatures.js.map +1 -1
- package/dist/ir/constant-globals.test.js +1 -1
- package/dist/ir/constant-tables.test.js +1 -1
- package/dist/ir/final-fields.test.js +1 -1
- package/dist/ir/function-references.d.ts +12 -0
- package/dist/ir/function-references.js +29 -0
- package/dist/ir/function-references.js.map +1 -0
- package/dist/ir/function-references.test.d.ts +1 -0
- package/dist/ir/function-references.test.js +276 -0
- package/dist/ir/function-references.test.js.map +1 -0
- package/dist/ir/initializer-bindings.test.js +1 -1
- package/dist/ir/int32-slots.d.ts +10 -7
- package/dist/ir/int32-slots.js +219 -68
- package/dist/ir/int32-slots.js.map +1 -1
- package/dist/ir/int32-slots.test.js +39 -2
- package/dist/ir/int32-slots.test.js.map +1 -1
- package/dist/ir/integer-ranges.d.ts +4 -4
- package/dist/ir/integer-ranges.js +89 -64
- package/dist/ir/integer-ranges.js.map +1 -1
- package/dist/ir/integer-ranges.test.js +71 -9
- package/dist/ir/integer-ranges.test.js.map +1 -1
- package/dist/ir/intrinsic-signatures.js +1 -0
- package/dist/ir/intrinsic-signatures.js.map +1 -1
- package/dist/ir/ir.d.ts +64 -290
- package/dist/ir/ir.js +11 -259
- package/dist/ir/ir.js.map +1 -1
- package/dist/ir/ir.test.js +2 -7
- package/dist/ir/ir.test.js.map +1 -1
- package/dist/ir/runtime-features.d.ts +3 -30
- package/dist/ir/runtime-features.js +8 -43
- package/dist/ir/runtime-features.js.map +1 -1
- package/dist/ir/scalar-records.test.js +1 -1
- package/dist/ir/serialize.d.ts +1 -1
- package/dist/ir/serialize.js +3 -3
- package/dist/ir/serialize.js.map +1 -1
- package/dist/ir/traverse.js +4 -21
- package/dist/ir/traverse.js.map +1 -1
- package/dist/ir/unshare.test.js +1 -1
- package/dist/ir/validate.js +66 -213
- package/dist/ir/validate.js.map +1 -1
- package/dist/ir/validate.test.js +31 -13
- package/dist/ir/validate.test.js.map +1 -1
- package/dist/library/fence-eval.test.js +1 -1
- package/dist/library/int-infer.test.js +4 -4
- package/dist/library/library-cache.test.js +5 -5
- package/dist/library/prepare.js +5 -20
- package/dist/library/prepare.js.map +1 -1
- package/dist/native/cli.js +0 -2
- package/dist/native/cli.js.map +1 -1
- package/dist/native/compiler.test.js +2 -4
- package/dist/native/compiler.test.js.map +1 -1
- package/dist/native/prepare.js +2 -4
- package/dist/native/prepare.js.map +1 -1
- package/dist/native/sanitizer.js +2 -16
- package/dist/native/sanitizer.js.map +1 -1
- package/dist/native/sanitizer.test.js +0 -3
- package/dist/native/sanitizer.test.js.map +1 -1
- package/dist/startup-cache.js +0 -2
- package/dist/startup-cache.js.map +1 -1
- package/package.json +20 -20
- package/surface-manifest.json +80 -104
- package/dist/backend/llvm/expr-island.d.ts +0 -15
- package/dist/backend/llvm/expr-island.js +0 -709
- package/dist/backend/llvm/expr-island.js.map +0 -1
- package/dist/frontend/lowering/coercions/island.d.ts +0 -37
- package/dist/frontend/lowering/coercions/island.js +0 -350
- package/dist/frontend/lowering/coercions/island.js.map +0 -1
- package/dist/frontend/lowering/lower-island.d.ts +0 -229
- package/dist/frontend/lowering/lower-island.js.map +0 -1
- package/dist/frontend/lowering/lower-island.test.js +0 -56
- package/dist/frontend/lowering/lower-island.test.js.map +0 -1
- package/dist/frontend/npm-fetch-analysis.d.ts +0 -17
- package/dist/frontend/npm-fetch-analysis.js +0 -109
- package/dist/frontend/npm-fetch-analysis.js.map +0 -1
- package/dist/frontend/npm-fetch-analysis.test.js +0 -130
- package/dist/frontend/npm-fetch-analysis.test.js.map +0 -1
- package/dist/frontend/npm-fetch-node.d.ts +0 -2
- package/dist/frontend/npm-fetch-node.js +0 -12
- package/dist/frontend/npm-fetch-node.js.map +0 -1
- package/dist/frontend/npm-fetch-syntax.d.ts +0 -6
- package/dist/frontend/npm-fetch-syntax.js +0 -202
- package/dist/frontend/npm-fetch-syntax.js.map +0 -1
- package/dist/native/runtime-typescript.d.ts +0 -4
- package/dist/native/runtime-typescript.js +0 -74
- package/dist/native/runtime-typescript.js.map +0 -1
- package/dist/native/runtime-typescript.test.js +0 -41
- package/dist/native/runtime-typescript.test.js.map +0 -1
- /package/dist/{frontend/lowering/lower-island.test.d.ts → backend/llvm/expr-calls.test.d.ts} +0 -0
- /package/dist/{frontend/npm-fetch-analysis.test.d.ts → backend/llvm/int32-abi.test.d.ts} +0 -0
- /package/dist/{native/runtime-typescript.test.d.ts → backend/llvm/regex-matchers.test.d.ts} +0 -0
|
@@ -25,13 +25,13 @@ import { lowerUnionFieldRead, lowerUnionFieldWrite } from "./expressions/union-f
|
|
|
25
25
|
import { captureContextArguments } from "./function-context.js";
|
|
26
26
|
import { OBJECT_CALLABLE_VALUES } from "./surfaces.js";
|
|
27
27
|
import { wasiGuestPath } from "../../wasi-paths.js";
|
|
28
|
-
import { BIGINT_T, BYTES_ELEMENT_NAME, BOOL, CAUGHT, DYN, DYN_HANDLE_KINDS, F64,
|
|
28
|
+
import { BIGINT_T, BYTES_ELEMENT_NAME, BOOL, CAUGHT, DYN, DYN_HANDLE_KINDS, F64, NULL_T, REF_TRUTHY_KINDS, REGEX, RUNTIME_ERROR_CLASSES, SEARCH_PARAMS_T, STRING, UNDEFINED_T, VOID, arrayOf, canAdaptDynFuncTo, canDynCheckTo, canBoxFuncIntoDyn, funcOf, isDynTypedRefType, isSupportedArrayElem, isUnitType, shapeHasAccessorSlots, typeEquals, typeKey, unionContainerArmsOk, } from "../../ir/ir.js";
|
|
29
29
|
import { cjsClassExprWholeExportOf, cjsExportAssignmentOf, cjsExportDiscardReason, isCjsExportTableLiteral, isCjsJsFile, isJsSourceFile, isModuleExportsAccess, isNodeEsmFile, locOf, } from "../program.js";
|
|
30
|
-
import { ARRAY_METHODS, builtinConstLit, builtinFenceHintOf, builtinModuleConstOf, builtinModulesArrayLit, builtinModuleFnOf, COMPOUND_ASSIGN_OPS,
|
|
31
|
-
import { UNSUPPORTED, blockedBindingUseDiag,
|
|
30
|
+
import { ARRAY_METHODS, builtinConstLit, builtinFenceHintOf, builtinModuleConstOf, builtinModulesArrayLit, builtinModuleFnOf, COMPOUND_ASSIGN_OPS, STDLIB_SURFACE, isChildSurfaceMember, MAP_METHODS, NARROW_FIRST, SET_METHODS, STRING_INDEX_METHODS, STR_METHODS, UNSUPPORTED_EXPR, sideEffectFreeOptionValue, stdlibGlobalNameOf, } from "./surfaces.js";
|
|
31
|
+
import { UNSUPPORTED, blockedBindingUseDiag, unsupportedPackageValueDiag, unsupportedDiag, } from "../../diagnostics/diagnostic.js";
|
|
32
32
|
import { PoisonError, dynFallbackType, jsFuncNameOf, neverTaintedJsType, own } from "./lowerer.js";
|
|
33
33
|
import { lowerCollectionSpread } from "./containers/collection-methods.js";
|
|
34
|
-
import { arrayValueRead, arrayValueStore, arrayValueType, lowerSafeIndexRead, tryLowerIndexTruthiness, tryLowerNumericIndexRead, lowerSafeBytesRead, } from "./array-values.js";
|
|
34
|
+
import { arrayNumberRead, arrayValueRead, arrayValueStore, arrayValueType, lowerSafeIndexRead, tryLowerIndexTruthiness, tryLowerNumericIndexRead, tryLowerBytesReadNumberEquality, lowerSafeBytesRead, } from "./array-values.js";
|
|
35
35
|
import { strCharsCall } from "./containers/array-construction.js";
|
|
36
36
|
import { lowerOptionalStringIndex } from "./string-index.js";
|
|
37
37
|
import { tryLowerIndexedComparison } from "./indexed-comparison.js";
|
|
@@ -53,11 +53,11 @@ import { lowerYield } from "./lower-generators.js";
|
|
|
53
53
|
import { errorPropertyRead, errorPropertyWrite, errorToStringCall } from "./error-methods.js";
|
|
54
54
|
import { lowerStreamProperty, lowerStreamStateProperty, streamSidesOf } from "./lower-stream.js";
|
|
55
55
|
import { unionWideningTags } from "../../ir/analysis.js";
|
|
56
|
-
import { isSafeToDiscard,
|
|
56
|
+
import { isSafeToDiscard, isSafeToRepeat } from "./expressions/evaluation-safety.js";
|
|
57
57
|
import { globalSymbolKey } from "./expressions/global-symbols.js";
|
|
58
58
|
import { lowerShortCircuitAssignment } from "./expressions/nullish-assignment.js";
|
|
59
59
|
import { hasOptionalChainGuard, isOptionalChainTail, isRequireMainFilename, } from "./expressions/optional-chains.js";
|
|
60
|
-
import {
|
|
60
|
+
import { foldedStringKeyOf } from "./expressions/object-literals.js";
|
|
61
61
|
import { tryLowerExpression } from "./expressions/try-lower-expression.js";
|
|
62
62
|
import { fenceNodeModuleMutation, isNodeModuleValue, lowerNodeModuleIdentifier, lowerNodeModuleProperty, lowerRequireCacheElement, lowerRequireCacheHas, lowerRequireMainProperty, } from "./lower-node-module.js";
|
|
63
63
|
import { lowerAbstractEquality } from "./abstract-equality.js";
|
|
@@ -378,335 +378,6 @@ function lowerExprInner(lowerer, expr) {
|
|
|
378
378
|
}
|
|
379
379
|
lowerer.unsupported("SC1090", expr, "'void' with an effectful operand in value position (hoist the operand to its own statement — statement-position 'void e' and void-returning arrow bodies compile)");
|
|
380
380
|
}
|
|
381
|
-
// Literals in an `any`-typed slot (the CONTEXTUAL type is what the
|
|
382
|
-
// record/array lowerings would consult) build natively in the island:
|
|
383
|
-
// each value lowers statically and marshals in. An UNMAPPABLE
|
|
384
|
-
// contextual type falls back to the literal's own type, exactly like
|
|
385
|
-
// lowerObjectLiteral's fallback — a package call's options parameter
|
|
386
|
-
// is often an unmappable intersection while the literal's own type
|
|
387
|
-
// absorbs to jsval (a bare-jsval field, an npm-typed member).
|
|
388
|
-
if ((ts.isObjectLiteralExpression(expr) || ts.isArrayLiteralExpression(expr)) &&
|
|
389
|
-
(() => {
|
|
390
|
-
const ctxTs = lowerer.checker.getContextualType(expr);
|
|
391
|
-
const mapped = (ctxTs ? lowerer.mapTypeOf(ctxTs) : null) ?? lowerer.mapTypeOf(lowerer.typeOf(expr));
|
|
392
|
-
if (mapped?.kind !== "jsval")
|
|
393
|
-
return false;
|
|
394
|
-
// The tsgo readonly-[] panic repair (see lowerArrayLiteral): an
|
|
395
|
-
// EMPTY array literal under a const assertion is the empty tuple —
|
|
396
|
-
// its `any` answer is a panicked query, not an island slot.
|
|
397
|
-
if (ts.isArrayLiteralExpression(expr) &&
|
|
398
|
-
expr.elements.length === 0 &&
|
|
399
|
-
underConstAssertion(expr)) {
|
|
400
|
-
return false;
|
|
401
|
-
}
|
|
402
|
-
// A JS variable INITIALIZER whose BINDING registered as a
|
|
403
|
-
// checked-dynamic module global (the typedef-annotated
|
|
404
|
-
// doc-builder consts whose JSDoc types degraded — DYN slots):
|
|
405
|
-
// the island build could never land (no engine→dyn crossing
|
|
406
|
-
// exists), so the literal takes its own world's path instead —
|
|
407
|
-
// the dyn literal, or a static record the slot converts.
|
|
408
|
-
if (isJsSourceFile(expr.getSourceFile()) &&
|
|
409
|
-
ts.isVariableDeclaration(expr.parent) &&
|
|
410
|
-
expr.parent.initializer === expr &&
|
|
411
|
-
ts.isIdentifier(expr.parent.name)) {
|
|
412
|
-
const bindSym = lowerer.checker.getSymbolAtLocation(expr.parent.name);
|
|
413
|
-
const g = bindSym ? lowerer.globalsBySymbol.get(bindSym) : undefined;
|
|
414
|
-
if (g?.type.kind === "dyn")
|
|
415
|
-
return false;
|
|
416
|
-
}
|
|
417
|
-
// A PROJECT-DECLARED contextual type that only ABSORBED to the
|
|
418
|
-
// island (a doc-builder typedef whose field's JSDoc type
|
|
419
|
-
// reference degraded to checker-`any` — the tsgo multi-file
|
|
420
|
-
// value-as-type residue) is not an npm slot: when the literal's
|
|
421
|
-
// OWN type maps statically, it builds that way — the binding's
|
|
422
|
-
// checked-dynamic slot takes the dyn conversion. Genuinely
|
|
423
|
-
// island slots (npm .d.ts provenance, plain `any`) keep the
|
|
424
|
-
// native build.
|
|
425
|
-
if (ctxTs !== undefined && (ctxTs.flags & ts.TypeFlags.Any) === 0) {
|
|
426
|
-
// Intersection/tuple typedefs (`Line & {readonly soft: true}`)
|
|
427
|
-
// carry provenance on the ALIAS symbol.
|
|
428
|
-
const sym = ctxTs.getSymbol() ?? ctxTs.getAliasSymbol();
|
|
429
|
-
const decls = sym ? lowerer.checker.declarationsOf(sym) : [];
|
|
430
|
-
const projectDeclared = decls.length > 0 &&
|
|
431
|
-
decls.every((d) => {
|
|
432
|
-
const sf = d.getSourceFile();
|
|
433
|
-
return !sf.isDeclarationFile && !sf.fileName.includes("/node_modules/");
|
|
434
|
-
});
|
|
435
|
-
if (projectDeclared) {
|
|
436
|
-
// A spread already stored in the island must copy there too.
|
|
437
|
-
// Later overrides can make the literal's own inferred shape
|
|
438
|
-
// appear static without making that source a native record.
|
|
439
|
-
if (ts.isObjectLiteralExpression(expr) &&
|
|
440
|
-
expr.properties.some((p) => ts.isSpreadAssignment(p) &&
|
|
441
|
-
lowerer.mapTypeOf(lowerer.typeOf(p.expression))?.kind === "jsval")) {
|
|
442
|
-
return true;
|
|
443
|
-
}
|
|
444
|
-
const own = lowerer.mapTypeOf(lowerer.typeOf(expr));
|
|
445
|
-
if (own?.kind === "record" || own?.kind === "array")
|
|
446
|
-
return false;
|
|
447
|
-
}
|
|
448
|
-
}
|
|
449
|
-
return true;
|
|
450
|
-
})()) {
|
|
451
|
-
if (ts.isObjectLiteralExpression(expr)) {
|
|
452
|
-
// Two engine literals when a CONDITIONAL spread participates
|
|
453
|
-
// (`{ a, ...(c ? { k: v } : {}) }` — the optional-key idiom): the
|
|
454
|
-
// whole literal becomes `c ? objLit(with) : objLit(without)`. The
|
|
455
|
-
// shared properties' nodes ride BOTH arms (exactly one arm
|
|
456
|
-
// evaluates, so each property still evaluates once); the reorder
|
|
457
|
-
// of `c` before earlier properties is unobservable because the
|
|
458
|
-
// condition must be a side-effect-free read. The spread arm's keys
|
|
459
|
-
// are truly ABSENT when the empty arm is taken — engine-exact
|
|
460
|
-
// (`"k" in o` is false), which the static record path can't say.
|
|
461
|
-
const argsWithout = [];
|
|
462
|
-
const argsWith = [];
|
|
463
|
-
const getters = [];
|
|
464
|
-
let spread = null;
|
|
465
|
-
// A MEMBER a JS file cannot lower or marshal: defer like a
|
|
466
|
-
// statement fence, shaped by what the member IS. A FUNCTION-shaped
|
|
467
|
-
// member (a generic function as a value, a signature with
|
|
468
|
-
// checked-dynamic parameters — the doc-builder public aggregate's
|
|
469
|
-
// degraded pieces) becomes a host closure that THROWS the captured
|
|
470
|
-
// diagnostic when invoked — building the aggregate compiles and
|
|
471
|
-
// only a CALL through the island stops the run. A DATA-shaped
|
|
472
|
-
// member must NOT become a callable (the retired fence box's
|
|
473
|
-
// silent wrong answers: typeof said "function", downstream errors
|
|
474
|
-
// blamed the wrong thing — the withPlugins `plugins:` slot), so it
|
|
475
|
-
// defines through the engine's getter machinery instead: READING
|
|
476
|
-
// the member throws the diagnostic — the honest granularity, since
|
|
477
|
-
// using the value is exactly what cannot be answered. `getterName`
|
|
478
|
-
// null keeps the closure shape (function-shaped members, and the
|
|
479
|
-
// conditional-spread arms where getters cannot combine).
|
|
480
|
-
const islandMemberFence = (diagsBefore, err, valueNode, getterName = null) => {
|
|
481
|
-
if (!isJsSourceFile(expr.getSourceFile()))
|
|
482
|
-
throw err;
|
|
483
|
-
const fence = lowerer.deferToRuntimeFence(diagsBefore, valueNode, {
|
|
484
|
-
kind: "closure",
|
|
485
|
-
name: () => `%fn${lowerer.lambdaCounter++}_islfence`,
|
|
486
|
-
returnType: VOID,
|
|
487
|
-
type: { kind: "func", params: [], ret: VOID },
|
|
488
|
-
});
|
|
489
|
-
if (!fence)
|
|
490
|
-
throw err;
|
|
491
|
-
if (getterName !== null) {
|
|
492
|
-
getters.push({
|
|
493
|
-
name: getterName,
|
|
494
|
-
fn: lowerer.jsvalIn(fence, valueNode),
|
|
495
|
-
loc: locOf(valueNode),
|
|
496
|
-
});
|
|
497
|
-
return null;
|
|
498
|
-
}
|
|
499
|
-
return lowerer.jsvalIn(fence, valueNode);
|
|
500
|
-
};
|
|
501
|
-
// The member's SHAPE decides the fence's granularity: syntactic
|
|
502
|
-
// functions and checker-callable values keep the call-time
|
|
503
|
-
// closure; everything else (call results, awaits, data reads —
|
|
504
|
-
// the withPlugins `plugins:` shape) fences at the READ.
|
|
505
|
-
const funcShapedMember = (p) => {
|
|
506
|
-
if (ts.isMethodDeclaration(p))
|
|
507
|
-
return true;
|
|
508
|
-
const src = ts.isPropertyAssignment(p)
|
|
509
|
-
? p.initializer
|
|
510
|
-
: ts.isShorthandPropertyAssignment(p)
|
|
511
|
-
? p.name
|
|
512
|
-
: null;
|
|
513
|
-
if (!src || !ts.isExpression(src))
|
|
514
|
-
return true; // unknown form: keep the closure shape
|
|
515
|
-
let inner = src;
|
|
516
|
-
while (ts.isParenthesizedExpression(inner))
|
|
517
|
-
inner = inner.expression;
|
|
518
|
-
if (ts.isArrowFunction(inner) || ts.isFunctionExpression(inner))
|
|
519
|
-
return true;
|
|
520
|
-
return lowerer.checker.getCallSignatures(lowerer.typeOf(src)).length > 0;
|
|
521
|
-
};
|
|
522
|
-
const pushProp = (name, value, valueNode, into) => {
|
|
523
|
-
const diagsBefore = lowerer.diags.length;
|
|
524
|
-
let marshaled;
|
|
525
|
-
try {
|
|
526
|
-
marshaled = lowerer.jsvalIn(value, valueNode);
|
|
527
|
-
}
|
|
528
|
-
catch (err) {
|
|
529
|
-
// A value that LOWERED but cannot cross (a promise, a class
|
|
530
|
-
// instance): func-typed values keep the call-time closure;
|
|
531
|
-
// data-shaped values fence at the read (the getter), unless a
|
|
532
|
-
// conditional spread owns the literal (getters cannot combine).
|
|
533
|
-
if (!(err instanceof PoisonError))
|
|
534
|
-
throw err;
|
|
535
|
-
const asGetter = value.type.kind !== "func" && spread === null;
|
|
536
|
-
const fence = islandMemberFence(diagsBefore, err, valueNode, asGetter ? name.text : null);
|
|
537
|
-
if (fence === null)
|
|
538
|
-
return; // registered as a fence getter — no data property
|
|
539
|
-
marshaled = fence;
|
|
540
|
-
}
|
|
541
|
-
for (const args of into) {
|
|
542
|
-
args.push({
|
|
543
|
-
kind: "jsMarshal",
|
|
544
|
-
value: { kind: "strLit", value: name.text, type: STRING, loc: locOf(name) },
|
|
545
|
-
type: JSVAL,
|
|
546
|
-
loc: locOf(name),
|
|
547
|
-
});
|
|
548
|
-
args.push(marshaled);
|
|
549
|
-
}
|
|
550
|
-
};
|
|
551
|
-
const spreadSrcs = [];
|
|
552
|
-
let sawPlainProp = false;
|
|
553
|
-
for (const prop of expr.properties) {
|
|
554
|
-
if (ts.isSpreadAssignment(prop)) {
|
|
555
|
-
const cs = conditionalSpreadOf(prop.expression);
|
|
556
|
-
if (cs && cs !== "unsupported" && !spread) {
|
|
557
|
-
if (spreadSrcs.length > 0) {
|
|
558
|
-
lowerer.unsupported("SC1090", prop, "a conditional spread mixed with plain spreads in an 'any'-typed object literal");
|
|
559
|
-
}
|
|
560
|
-
const cond = lowerer.lowerCondition(cs.cond);
|
|
561
|
-
if (!isSafeToMoveConditionEarlier(cond)) {
|
|
562
|
-
lowerer.unsupported("SC1090", prop, "conditional spreads with effectful conditions in an 'any'-typed object literal (bind the condition to a const first)");
|
|
563
|
-
}
|
|
564
|
-
spread = { cond, whenTrue: cs.whenTrue };
|
|
565
|
-
for (const p of cs.props) {
|
|
566
|
-
const v = ts.isPropertyAssignment(p)
|
|
567
|
-
? lowerer.lowerExpr(p.initializer)
|
|
568
|
-
: lowerer.lowerShorthandValue(p);
|
|
569
|
-
pushProp(p.name, v, p, [argsWith]);
|
|
570
|
-
}
|
|
571
|
-
continue;
|
|
572
|
-
}
|
|
573
|
-
// A PLAIN spread (`{ ...options, plugins }` — the withPlugins
|
|
574
|
-
// argument-rebuild shape): the source copies into the fresh
|
|
575
|
-
// engine object through the spec's CopyDataProperties (the
|
|
576
|
-
// objSpread op). Spreads must precede explicit properties
|
|
577
|
-
// (the composition applies explicit keys AFTER the copies —
|
|
578
|
-
// JS's later-wins — which a spread after them would invert);
|
|
579
|
-
// mixing with a conditional spread keeps the fence.
|
|
580
|
-
if (cs === undefined || cs === null) {
|
|
581
|
-
if (sawPlainProp || spread) {
|
|
582
|
-
lowerer.unsupported("SC1090", prop, "object spread after explicit properties (or mixed with a conditional spread) in an 'any'-typed object literal — spreads must come first");
|
|
583
|
-
}
|
|
584
|
-
spreadSrcs.push(lowerer.jsvalIn(lowerer.lowerExpr(prop.expression), prop.expression));
|
|
585
|
-
continue;
|
|
586
|
-
}
|
|
587
|
-
lowerer.unsupported("SC1090", prop, "this spread form in an 'any'-typed object literal (one `...(c ? { k: v } : {})` conditional spread is supported — bind other shapes to a const and set keys explicitly)");
|
|
588
|
-
}
|
|
589
|
-
sawPlainProp = true;
|
|
590
|
-
// `name: value`, the shorthand `{ name }` (the value is the
|
|
591
|
-
// identifier itself, resolved through the shorthand VALUE symbol
|
|
592
|
-
// like the static record path), and METHODS — `{ load() {...} }`
|
|
593
|
-
// is a function expression under a shorthand name, marshaled
|
|
594
|
-
// like any closure value (this-uses keep the static path's
|
|
595
|
-
// rejection); everything else keeps the fence. Identifier and
|
|
596
|
-
// string-literal keys — engine property names have no
|
|
597
|
-
// identifier restriction ("content-type").
|
|
598
|
-
const name = prop.name;
|
|
599
|
-
// A GET accessor (`get root() { return ROOT_INDENT; }` — the
|
|
600
|
-
// doc-printer's self-referential root-indent shape): the body
|
|
601
|
-
// lowers as a zero-param closure marshaled into the engine, and
|
|
602
|
-
// the property defines through the engine's own getter
|
|
603
|
-
// machinery AFTER the literal builds (the defineGetter op) —
|
|
604
|
-
// reads through the handle invoke it natively. `this` in the
|
|
605
|
-
// body keeps the object-method rejection; setters stay fenced.
|
|
606
|
-
if (ts.isGetAccessorDeclaration(prop) &&
|
|
607
|
-
prop.body &&
|
|
608
|
-
name &&
|
|
609
|
-
(ts.isIdentifier(name) || ts.isStringLiteral(name))) {
|
|
610
|
-
lowerer.rejectThisInObjectMethod(prop.body);
|
|
611
|
-
getters.push({
|
|
612
|
-
name: name.text,
|
|
613
|
-
fn: lowerer.jsvalIn(lowerer.lowerLambda(prop), prop),
|
|
614
|
-
loc: locOf(prop),
|
|
615
|
-
});
|
|
616
|
-
continue;
|
|
617
|
-
}
|
|
618
|
-
// A member VALUE that cannot lower at all (a generic function
|
|
619
|
-
// referenced as a value — the aggregate's `align`): the same
|
|
620
|
-
// call-time fence deferral pushProp applies to marshal failures.
|
|
621
|
-
let value = null;
|
|
622
|
-
const valueDiagsBefore = lowerer.diags.length;
|
|
623
|
-
try {
|
|
624
|
-
value = ts.isPropertyAssignment(prop)
|
|
625
|
-
? lowerer.lowerExpr(prop.initializer)
|
|
626
|
-
: ts.isShorthandPropertyAssignment(prop)
|
|
627
|
-
? lowerer.lowerShorthandValue(prop)
|
|
628
|
-
: ts.isMethodDeclaration(prop) && prop.body
|
|
629
|
-
? (lowerer.rejectThisInObjectMethod(prop.body), lowerer.lowerLambda(prop))
|
|
630
|
-
: null;
|
|
631
|
-
}
|
|
632
|
-
catch (err) {
|
|
633
|
-
if (!(err instanceof PoisonError))
|
|
634
|
-
throw err;
|
|
635
|
-
const nameText = name && (ts.isIdentifier(name) || ts.isStringLiteral(name)) ? name.text : null;
|
|
636
|
-
const asGetter = nameText !== null && spread === null && !funcShapedMember(prop);
|
|
637
|
-
value = islandMemberFence(valueDiagsBefore, err, prop, asGetter ? nameText : null);
|
|
638
|
-
if (value === null)
|
|
639
|
-
continue; // registered as a fence getter — no data property
|
|
640
|
-
}
|
|
641
|
-
if (value && name && (ts.isIdentifier(name) || ts.isStringLiteral(name))) {
|
|
642
|
-
pushProp(name, value, prop, [argsWithout, argsWith]);
|
|
643
|
-
}
|
|
644
|
-
else {
|
|
645
|
-
lowerer.unsupported("SC1090", prop, "this property form in an 'any'-typed object literal (only `name: value`, shorthand names, methods, and get accessors are supported)");
|
|
646
|
-
}
|
|
647
|
-
}
|
|
648
|
-
const withGetters = (obj) => getters.reduce((acc, g) => ({
|
|
649
|
-
kind: "jsOp",
|
|
650
|
-
op: "defineGetter",
|
|
651
|
-
args: [
|
|
652
|
-
acc,
|
|
653
|
-
{
|
|
654
|
-
kind: "jsMarshal",
|
|
655
|
-
value: { kind: "strLit", value: g.name, type: STRING, loc: g.loc },
|
|
656
|
-
type: JSVAL,
|
|
657
|
-
loc: g.loc,
|
|
658
|
-
},
|
|
659
|
-
g.fn,
|
|
660
|
-
],
|
|
661
|
-
type: JSVAL,
|
|
662
|
-
loc: g.loc,
|
|
663
|
-
}), obj);
|
|
664
|
-
if (!spread) {
|
|
665
|
-
if (spreadSrcs.length === 0) {
|
|
666
|
-
return withGetters({ kind: "jsOp", op: "objLit", args: argsWithout, type: JSVAL, loc });
|
|
667
|
-
}
|
|
668
|
-
// Plain spreads compose left to right onto a fresh object, the
|
|
669
|
-
// explicit properties merging LAST (JS's later-wins): spread
|
|
670
|
-
// sources evaluate before later property values by nesting
|
|
671
|
-
// order, exactly the source order.
|
|
672
|
-
let acc = { kind: "jsOp", op: "objLit", args: [], type: JSVAL, loc };
|
|
673
|
-
for (const src of spreadSrcs) {
|
|
674
|
-
acc = { kind: "jsOp", op: "objSpread", args: [acc, src], type: JSVAL, loc };
|
|
675
|
-
}
|
|
676
|
-
if (argsWithout.length > 0) {
|
|
677
|
-
acc = {
|
|
678
|
-
kind: "jsOp",
|
|
679
|
-
op: "objSpread",
|
|
680
|
-
args: [acc, { kind: "jsOp", op: "objLit", args: argsWithout, type: JSVAL, loc }],
|
|
681
|
-
type: JSVAL,
|
|
682
|
-
loc,
|
|
683
|
-
};
|
|
684
|
-
}
|
|
685
|
-
return withGetters(acc);
|
|
686
|
-
}
|
|
687
|
-
if (getters.length > 0) {
|
|
688
|
-
lowerer.unsupported("SC1090", expr, "get accessors combined with conditional spreads in an 'any'-typed object literal");
|
|
689
|
-
}
|
|
690
|
-
const withLit = { kind: "jsOp", op: "objLit", args: argsWith, type: JSVAL, loc };
|
|
691
|
-
const withoutLit = {
|
|
692
|
-
kind: "jsOp",
|
|
693
|
-
op: "objLit",
|
|
694
|
-
args: argsWithout,
|
|
695
|
-
type: JSVAL,
|
|
696
|
-
loc,
|
|
697
|
-
};
|
|
698
|
-
return {
|
|
699
|
-
kind: "ternary",
|
|
700
|
-
cond: spread.cond,
|
|
701
|
-
then: spread.whenTrue ? withLit : withoutLit,
|
|
702
|
-
else_: spread.whenTrue ? withoutLit : withLit,
|
|
703
|
-
type: JSVAL,
|
|
704
|
-
loc,
|
|
705
|
-
};
|
|
706
|
-
}
|
|
707
|
-
const args = expr.elements.map((el) => lowerer.jsvalIn(lowerer.lowerExpr(el), el));
|
|
708
|
-
return { kind: "jsOp", op: "arrLit", args, type: JSVAL, loc };
|
|
709
|
-
}
|
|
710
381
|
if (ts.isTypeOfExpression(expr)) {
|
|
711
382
|
if (lowerer.isStdlibGlobal(expr.expression, "process"))
|
|
712
383
|
return { kind: "strLit", value: "object", type: STRING, loc };
|
|
@@ -760,7 +431,7 @@ function lowerExprInner(lowerer, expr) {
|
|
|
760
431
|
tested = tested.expression;
|
|
761
432
|
if (ts.isIdentifier(tested)) {
|
|
762
433
|
const sym = lowerer.checker.getSymbolAtLocation(tested);
|
|
763
|
-
if (!sym
|
|
434
|
+
if (!sym) {
|
|
764
435
|
return { kind: "strLit", value: "undefined", type: STRING, loc };
|
|
765
436
|
}
|
|
766
437
|
if (lowerer.isStdlibSymbol(sym)) {
|
|
@@ -775,9 +446,6 @@ function lowerExprInner(lowerer, expr) {
|
|
|
775
446
|
// still evaluates: calls, getters, and checked reads can have effects
|
|
776
447
|
// or throw. Only trivial operands may disappear.
|
|
777
448
|
let operand = deferredSlotOr(lowerer, runtimeOptionalStorageOperand(lowerer, expr.expression) ?? lowerer.lowerExpr(expr.expression));
|
|
778
|
-
if (operand.type.kind === "jsval") {
|
|
779
|
-
return { kind: "jsOp", op: "typeof", args: [operand], type: STRING, loc };
|
|
780
|
-
}
|
|
781
449
|
// A checker-narrowed dyn read arrives as a VALIDATED extraction
|
|
782
450
|
// (maybeNarrow's dynCheck bridge). typeof needs no extraction — the
|
|
783
451
|
// dyn kind table answers the question directly, and answers it even
|
|
@@ -1246,19 +914,14 @@ function lowerExprInner(lowerer, expr) {
|
|
|
1246
914
|
if (lowerer.cjsLocalModuleBindingOf(expr)) {
|
|
1247
915
|
lowerer.unsupported("SC1090", expr, `module namespace objects as values (access '${expr.text}' members directly)`);
|
|
1248
916
|
}
|
|
1249
|
-
if (lowerer.
|
|
1250
|
-
// Island-backed functions have no closure representation (they
|
|
1251
|
-
// lower to engine ops at call sites only).
|
|
917
|
+
if (lowerer.stdlibGlobalFnOf(expr)) {
|
|
1252
918
|
lowerer.unsupported("SC1090", expr, `library functions as values (call '${expr.text}' directly)`);
|
|
1253
919
|
}
|
|
1254
|
-
//
|
|
1255
|
-
|
|
1256
|
-
// diagnostic, not the generic fallthrough. (Under --dynamic these
|
|
1257
|
-
// resolve as jsval globals above.)
|
|
1258
|
-
if (!lowerer.dynamic) {
|
|
920
|
+
// A declaration-only npm binding has no compiled runtime value.
|
|
921
|
+
{
|
|
1259
922
|
const pkg = lowerer.npmPackageOfSymbol(lowerer.resolveValueSymbol(expr) ?? undefined);
|
|
1260
923
|
if (pkg) {
|
|
1261
|
-
lowerer.pushDiag(
|
|
924
|
+
lowerer.pushDiag(unsupportedPackageValueDiag(pkg, loc));
|
|
1262
925
|
throw new PoisonError();
|
|
1263
926
|
}
|
|
1264
927
|
}
|
|
@@ -1356,13 +1019,13 @@ function lowerExprInner(lowerer, expr) {
|
|
|
1356
1019
|
}
|
|
1357
1020
|
return { kind: "closure", fnName: name, captures: [], type, loc };
|
|
1358
1021
|
}
|
|
1359
|
-
if (
|
|
1022
|
+
if (lowerer.isStdlibGlobal(expr, "crypto"))
|
|
1360
1023
|
return { kind: "libCall", fn: "crypto.native", args: [], type: DYN, loc };
|
|
1361
1024
|
const nativeAlias = stdlibGlobalNameOf(lowerer, expr);
|
|
1362
1025
|
if (nativeAlias === "Buffer" && expr.text !== "Buffer") {
|
|
1363
1026
|
return { kind: "strLit", value: "[builtin Buffer]", type: STRING, loc };
|
|
1364
1027
|
}
|
|
1365
|
-
if (
|
|
1028
|
+
if (lowerer.isStdlibGlobal(expr, "fetch")) {
|
|
1366
1029
|
return { kind: "libCall", fn: "fetch.function", args: [], type: DYN, loc };
|
|
1367
1030
|
}
|
|
1368
1031
|
// The lib fence's IDENTIFIER chokepoint: the real standard library
|
|
@@ -1378,7 +1041,7 @@ function lowerExprInner(lowerer, expr) {
|
|
|
1378
1041
|
// global, one token; what a token cannot do (be called, answer
|
|
1379
1042
|
// typeof "function") meets per-site fences/divergences, and
|
|
1380
1043
|
// SEMANTICS.md documents the stance.
|
|
1381
|
-
if (
|
|
1044
|
+
if (stdlibGlobalNameOf(lowerer, expr) === "globalThis") {
|
|
1382
1045
|
return lowerGlobalValue(lowerer, expr);
|
|
1383
1046
|
}
|
|
1384
1047
|
{
|
|
@@ -1388,13 +1051,6 @@ function lowerExprInner(lowerer, expr) {
|
|
|
1388
1051
|
const canonical = stdlibGlobalNameOf(lowerer, expr) ?? expr.text;
|
|
1389
1052
|
return { kind: "strLit", value: `[builtin ${canonical}]`, type: STRING, loc };
|
|
1390
1053
|
}
|
|
1391
|
-
// In a dynamic TypeScript build, the real global object is the
|
|
1392
|
-
// escape hatch for host capabilities without static lowering.
|
|
1393
|
-
// Direct globalThis.member uses still take their static surface
|
|
1394
|
-
// paths; an explicit `as any` or `: any` can reach engine ops.
|
|
1395
|
-
if (lowerer.dynamic && expr.text === "globalThis") {
|
|
1396
|
-
return { kind: "jsOp", op: "globalGet", name: "globalThis", args: [], type: JSVAL, loc };
|
|
1397
|
-
}
|
|
1398
1054
|
// The families with a WHY: each hint states what makes the
|
|
1399
1055
|
// surface genuinely non-static (or what to use instead).
|
|
1400
1056
|
const globalHints = {
|
|
@@ -1643,9 +1299,8 @@ function lowerExprInner(lowerer, expr) {
|
|
|
1643
1299
|
const promiseArm = def.arms[promiseTag];
|
|
1644
1300
|
const inner = promiseArm.kind === "promise" ? promiseArm.inner : VOID;
|
|
1645
1301
|
const units = def.arms.filter(isUnitType);
|
|
1646
|
-
if (inner.kind === "union" || inner.kind === "dyn"
|
|
1302
|
+
if (inner.kind === "union" || inner.kind === "dyn") {
|
|
1647
1303
|
// A union inner would need an arm-wise re-tag into the result
|
|
1648
|
-
// union; dyn/jsval inners have their own boundary stories.
|
|
1649
1304
|
lowerer.unsupported("SC1090", expr, `awaiting '${lowerer.fmt(value.type)}' (the promise's inner type has no combined result union — await the promise arm after narrowing instead)`);
|
|
1650
1305
|
}
|
|
1651
1306
|
let type;
|
|
@@ -1675,27 +1330,6 @@ function lowerExprInner(lowerer, expr) {
|
|
|
1675
1330
|
if (value.type.kind === "dyn") {
|
|
1676
1331
|
return { kind: "libCall", fn: "async.awaitDyn", args: [value], type: DYN, loc };
|
|
1677
1332
|
}
|
|
1678
|
-
// A jsval whose CHECKER type is a promise is a package-returned
|
|
1679
|
-
// promise: the value lives in the engine. Bridge it — a static
|
|
1680
|
-
// promise the engine promise settles (fulfillment = the retained
|
|
1681
|
-
// handle or void, rejection = the bridged reason) — and await
|
|
1682
|
-
// THAT: the fiber parks like any await, resumes with the settled
|
|
1683
|
-
// jsval, or re-throws the crossed rejection.
|
|
1684
|
-
if (value.type.kind === "jsval") {
|
|
1685
|
-
// ANY island value bridges — the runtime's Promise.resolve(v)
|
|
1686
|
-
// .then(...) wiring awaits thenables and non-thenables exactly
|
|
1687
|
-
// like JS (`await reg.load()` where the checker only knows
|
|
1688
|
-
// 'any' must still park on the returned engine promise).
|
|
1689
|
-
const mapped = lowerer.mapTypeOf(lowerer.typeOf(expr.expression));
|
|
1690
|
-
const inner = mapped?.kind === "promise" && mapped.inner.kind === "void" ? VOID : JSVAL;
|
|
1691
|
-
const bridged = {
|
|
1692
|
-
kind: "jsBridgePromise",
|
|
1693
|
-
value,
|
|
1694
|
-
type: { kind: "promise", inner },
|
|
1695
|
-
loc,
|
|
1696
|
-
};
|
|
1697
|
-
return { kind: "awaitExpr", value: bridged, type: inner, loc };
|
|
1698
|
-
}
|
|
1699
1333
|
// A TYPED non-promise operand (`await 42`, an awaited record):
|
|
1700
1334
|
// JS awaits non-thenables through exactly one microtask turn and
|
|
1701
1335
|
// yields the value itself — evaluate the operand, hop, answer it.
|
|
@@ -1765,9 +1399,7 @@ function lowerExprInner(lowerer, expr) {
|
|
|
1765
1399
|
return lowerer.lowerBinary(expr);
|
|
1766
1400
|
if (ts.isCallExpression(expr)) {
|
|
1767
1401
|
// The tail of an optional chain whose `?.` sits deeper
|
|
1768
|
-
// (`x?.trim().toLowerCase()`): the whole tail short-circuits
|
|
1769
|
-
// the guard, so it lowers as one chain (dyn/island receivers keep
|
|
1770
|
-
// their own undefined-propagating reads — see isOptionalChainTail).
|
|
1402
|
+
// (`x?.trim().toLowerCase()`): the whole tail short-circuits together.
|
|
1771
1403
|
if (isOptionalChainTail(lowerer, expr))
|
|
1772
1404
|
return lowerer.lowerOptionalChain(expr);
|
|
1773
1405
|
return lowerer.lowerCall(expr);
|
|
@@ -1809,7 +1441,7 @@ function lowerExprInner(lowerer, expr) {
|
|
|
1809
1441
|
return lowerer.lowerSuperAccessorRead(expr);
|
|
1810
1442
|
}
|
|
1811
1443
|
// Enum member reads (`E.A`) fold to their compile-time constants —
|
|
1812
|
-
// claimed FIRST so no receiver-shaped path (records,
|
|
1444
|
+
// claimed FIRST so no receiver-shaped path (records, the
|
|
1813
1445
|
// identifier fence on the enum object) sees them. lower-enums.ts.
|
|
1814
1446
|
{
|
|
1815
1447
|
const en = lowerEnumAccess(lowerer, expr);
|
|
@@ -1868,7 +1500,7 @@ function lowerExprInner(lowerer, expr) {
|
|
|
1868
1500
|
loc,
|
|
1869
1501
|
};
|
|
1870
1502
|
}
|
|
1871
|
-
if (
|
|
1503
|
+
if (lowerer.stdlibGlobalMember(expr, "Object") === "freeze") {
|
|
1872
1504
|
const name = "%builtin.Object.freeze";
|
|
1873
1505
|
if (!lowerer.liftedFns.some((fn) => fn.name === name))
|
|
1874
1506
|
lowerer.liftedFns.push({
|
|
@@ -1909,8 +1541,7 @@ function lowerExprInner(lowerer, expr) {
|
|
|
1909
1541
|
// in a native program. Declared globals retain their own lowering;
|
|
1910
1542
|
// arbitrary global-object mutation remains fenced. Preserve a dyn
|
|
1911
1543
|
// undefined value so stored probes compose with optional calls.
|
|
1912
|
-
if (
|
|
1913
|
-
stdlibGlobalNameOf(lowerer, expr.expression) === "globalThis" &&
|
|
1544
|
+
if (stdlibGlobalNameOf(lowerer, expr.expression) === "globalThis" &&
|
|
1914
1545
|
!lowerer.checker.getPropertyOfType(lowerer.typeOf(expr.expression), expr.name.text)) {
|
|
1915
1546
|
return dynUndefinedExpr(loc);
|
|
1916
1547
|
}
|
|
@@ -1936,63 +1567,11 @@ function lowerExprInner(lowerer, expr) {
|
|
|
1936
1567
|
lowerer.fenceStaticResponseMember(expr, "read");
|
|
1937
1568
|
lowerer.fenceStaticHeadersMember(expr, "read");
|
|
1938
1569
|
lowerer.fenceStaticReadableStreamMember(expr, "read");
|
|
1939
|
-
// Island receiver: o.x is an engine property read (getProp may throw
|
|
1940
1570
|
// — reading off null/undefined — bridged catchably like everything
|
|
1941
1571
|
// at the boundary). `o?.x` arrives here too, through the chain
|
|
1942
1572
|
// lowering's re-dispatch (a questionDotToken past the gate above is
|
|
1943
1573
|
// always chain-handled; the receiver reads back as the chain's
|
|
1944
1574
|
// bound handle).
|
|
1945
|
-
if (lowerer.isIslandExpr(expr.expression)) {
|
|
1946
|
-
const receiver = lowerer.lowerExpr(expr.expression);
|
|
1947
|
-
// The checker said 'any' but the VALUE lives in the checked-dynamic tree (`this`
|
|
1948
|
-
// in a plain JS function — dyn.this — or a checked-dynamic local
|
|
1949
|
-
// behind an any-typed spelling): the property read is the checked-dynamic tree's
|
|
1950
|
-
// own keyed read, dyn results and dyn chains exactly like every
|
|
1951
|
-
// checked-dynamic member access (a nullish receiver throws V8's
|
|
1952
|
-
// catchable TypeError, exactly Node). Never a jsOp over a dyn —
|
|
1953
|
-
// the two dynamic worlds don't share a value representation.
|
|
1954
|
-
if (receiver.type.kind === "dyn") {
|
|
1955
|
-
return {
|
|
1956
|
-
kind: "dynKeyGet",
|
|
1957
|
-
key: { kind: "strLit", value: expr.name.text, type: STRING, loc },
|
|
1958
|
-
value: receiver,
|
|
1959
|
-
type: DYN,
|
|
1960
|
-
loc,
|
|
1961
|
-
};
|
|
1962
|
-
}
|
|
1963
|
-
const read = {
|
|
1964
|
-
kind: "jsOp",
|
|
1965
|
-
op: "getProp",
|
|
1966
|
-
name: expr.name.text,
|
|
1967
|
-
args: [receiver],
|
|
1968
|
-
type: JSVAL,
|
|
1969
|
-
loc,
|
|
1970
|
-
};
|
|
1971
|
-
// A member the .d.ts DECLARES as a primitive exits eagerly to that
|
|
1972
|
-
// static type (`f.mediaType` on a package handle IS a string):
|
|
1973
|
-
// primitives copy by value across the boundary — no aliasing, no
|
|
1974
|
-
// cost — and every static consumer (intrinsics, templates,
|
|
1975
|
-
// comparisons) works on the result. Trust-but-verify: a lying
|
|
1976
|
-
// declaration throws the catchable TypeError instead of smuggling
|
|
1977
|
-
// a mistyped handle into string ops. A Uint8Array member exits the
|
|
1978
|
-
// same way (`result.audio.uint8Array` — the generated-media
|
|
1979
|
-
// payload) as a validated u8 COPY, the boundary's aliasing stance
|
|
1980
|
-
// (divergences 44/45; engine Buffers pass — they ARE Uint8Arrays).
|
|
1981
|
-
// Other composites stay handles (eager JSON copies would change
|
|
1982
|
-
// aliasing), and chain-handled reads stay jsval (the chain's unit
|
|
1983
|
-
// path is the engine's undefined — see lowerOptionalChain).
|
|
1984
|
-
if (!expr.questionDotToken) {
|
|
1985
|
-
const declared = lowerer.mapTypeOf(lowerer.typeOf(expr));
|
|
1986
|
-
if (declared &&
|
|
1987
|
-
(declared.kind === "f64" ||
|
|
1988
|
-
declared.kind === "bool" ||
|
|
1989
|
-
declared.kind === "string" ||
|
|
1990
|
-
(declared.kind === "bytes" && declared.elem === "u8"))) {
|
|
1991
|
-
return { kind: "jsExit", value: read, type: declared, loc };
|
|
1992
|
-
}
|
|
1993
|
-
}
|
|
1994
|
-
return read;
|
|
1995
|
-
}
|
|
1996
1575
|
// `m.index` on a for-of-over-matchAll binding reads the companion-
|
|
1997
1576
|
// index array at this iteration's cursor — always a number: every
|
|
1998
1577
|
// drained row matched, so the lib's `.index` is never undefined
|
|
@@ -2268,13 +1847,13 @@ function lowerExprInner(lowerer, expr) {
|
|
|
2268
1847
|
isJsSourceFile(expr.getSourceFile())) {
|
|
2269
1848
|
const canonical = stdlibGlobalNameOf(lowerer, expr);
|
|
2270
1849
|
if (canonical !== null) {
|
|
2271
|
-
if (
|
|
1850
|
+
if (canonical === "globalThis")
|
|
2272
1851
|
return lowerGlobalValue(lowerer, expr);
|
|
2273
|
-
if (
|
|
1852
|
+
if (canonical === "ArrayBuffer")
|
|
2274
1853
|
return { kind: "libCall", fn: "arrayBuffer.constructor", args: [], type: DYN, loc };
|
|
2275
|
-
if (
|
|
1854
|
+
if (canonical === "fetch")
|
|
2276
1855
|
return { kind: "libCall", fn: "fetch.function", args: [], type: DYN, loc };
|
|
2277
|
-
if (
|
|
1856
|
+
if (Object.values(BYTES_ELEMENT_NAME).includes(canonical))
|
|
2278
1857
|
return {
|
|
2279
1858
|
kind: "libCall",
|
|
2280
1859
|
fn: "bytes.constructor",
|
|
@@ -2929,7 +2508,7 @@ export function lowerTernary(lowerer, expr, expected) {
|
|
|
2929
2508
|
(lowerer.typeOf(expr).flags & ts.TypeFlags.Any) !== 0) {
|
|
2930
2509
|
const a = thenRaw.type;
|
|
2931
2510
|
const b = elseRaw.type;
|
|
2932
|
-
const staticArm = (t) => t.kind !== "dyn" && t.kind !== "caught" && t.kind !== "
|
|
2511
|
+
const staticArm = (t) => t.kind !== "dyn" && t.kind !== "caught" && t.kind !== "void";
|
|
2933
2512
|
if (staticArm(a) && staticArm(b)) {
|
|
2934
2513
|
if (typeEquals(a, b)) {
|
|
2935
2514
|
anyJoin = a;
|
|
@@ -3193,12 +2772,14 @@ export function maybeNarrow(lowerer, expr, node) {
|
|
|
3193
2772
|
if (symbol && lowerer.unstableSwitchBindings.has(symbol))
|
|
3194
2773
|
return expr;
|
|
3195
2774
|
}
|
|
2775
|
+
if (ts.isPropertyAccessExpression(node) &&
|
|
2776
|
+
getterResultHoldsUndeclaredUndefined(lowerer, node, expr))
|
|
2777
|
+
return expr;
|
|
3196
2778
|
const narrowedTs = lowerer.typeOf(node);
|
|
3197
2779
|
const narrowed = lowerer.mapTypeOf(narrowedTs);
|
|
3198
2780
|
// `Array.isArray(u)` on a union with one readonly array/tuple arm: the
|
|
3199
|
-
// lib predicate narrows to `any[]`,
|
|
3200
|
-
//
|
|
3201
|
-
// array-of-handles, nothing, or a synthetic intersection record — but
|
|
2781
|
+
// lib predicate narrows to `any[]`, possibly intersected with another
|
|
2782
|
+
// type. That mapping may be a checked value or a synthetic record, but
|
|
3202
2783
|
// the tag test proved the union's one array-valued arm, so bridge to it
|
|
3203
2784
|
// with the same trusted unionNarrow the mapped case below builds.
|
|
3204
2785
|
if (lowerer.checkerAnyArrayType(narrowedTs)) {
|
|
@@ -3302,6 +2883,27 @@ export function maybeNarrow(lowerer, expr, node) {
|
|
|
3302
2883
|
loc: expr.loc,
|
|
3303
2884
|
};
|
|
3304
2885
|
}
|
|
2886
|
+
/** A getter read whose runtime result can be undefined (an unchecked
|
|
2887
|
+
* element read in its body, or in another member of its override family)
|
|
2888
|
+
* although its declared type cannot. The checker's type for the read is
|
|
2889
|
+
* then no narrowing proof, so the read keeps the getter's result. */
|
|
2890
|
+
function getterResultHoldsUndeclaredUndefined(lowerer, node, expr) {
|
|
2891
|
+
if (expr.type.kind !== "union" || lowerer.armTag(expr.type.unionId, UNDEFINED_T) < 0)
|
|
2892
|
+
return false;
|
|
2893
|
+
const getter = (expr.kind === "virtualCall" && expr.method.startsWith("get:")) ||
|
|
2894
|
+
(expr.kind === "call" && expr.callee.includes(".get:"));
|
|
2895
|
+
if (!getter)
|
|
2896
|
+
return false;
|
|
2897
|
+
const symbol = lowerer.checker.getSymbolAtLocation(node.name);
|
|
2898
|
+
if (!symbol || (symbol.flags & ts.SymbolFlags.GetAccessor) === 0)
|
|
2899
|
+
return false;
|
|
2900
|
+
const declared = lowerer.checker.getTypeOfSymbol(symbol);
|
|
2901
|
+
const holdsUndefined = (type) => (type.flags &
|
|
2902
|
+
(ts.TypeFlags.Undefined | ts.TypeFlags.Void | ts.TypeFlags.Any | ts.TypeFlags.Unknown)) !==
|
|
2903
|
+
0;
|
|
2904
|
+
return !(holdsUndefined(declared) ||
|
|
2905
|
+
(declared.isUnionType() && ts.constituentTypes(declared).some(holdsUndefined)));
|
|
2906
|
+
}
|
|
3305
2907
|
/** The checked form of maybeNarrow's arm extraction for a narrowing the
|
|
3306
2908
|
* checker may hold past code that replaced the value (a call clearing the
|
|
3307
2909
|
* property; see NarrowingStability). Every other arm throws the TypeError
|
|
@@ -3743,18 +3345,6 @@ function volatileEnvRead(e) {
|
|
|
3743
3345
|
}
|
|
3744
3346
|
return null;
|
|
3745
3347
|
}
|
|
3746
|
-
/** `x == null` / `x != null` — JS's idiomatic null-OR-undefined test, the
|
|
3747
|
-
* ONE loose comparison with static semantics: `== null` matches exactly
|
|
3748
|
-
* null and undefined (0, "", and false do not). Requires a syntactic
|
|
3749
|
-
* null LITERAL on either side; the other operand's unit arms become a
|
|
3750
|
-
* runtime tag test — one `unionIsTag` when the union has a single unit
|
|
3751
|
-
* arm, a short-circuit pair over both tags otherwise (that shape re-emits
|
|
3752
|
-
* the operand, so only side-effect-free reads compose; anything else
|
|
3753
|
-
* keeps the fence). A unit-literal operand folds (null and undefined are
|
|
3754
|
-
* mutually loose-equal), and a non-nullable operand folds statically —
|
|
3755
|
-
* the same trust-the-checker bet as lowerUnitComparison. Null (fence)
|
|
3756
|
-
* when this isn't a null-literal comparison or the operand has no
|
|
3757
|
-
* lowering here (dyn/jsval/void). */
|
|
3758
3348
|
function lowerLooseNullCompare(lowerer, expr, loc) {
|
|
3759
3349
|
const negated = expr.operatorToken.kind === ts.SyntaxKind.ExclamationEqualsToken;
|
|
3760
3350
|
const unwrap = (e) => ts.isParenthesizedExpression(e) ? unwrap(e.expression) : e;
|
|
@@ -3819,7 +3409,7 @@ function lowerLooseNullCompare(lowerer, expr, loc) {
|
|
|
3819
3409
|
loc,
|
|
3820
3410
|
};
|
|
3821
3411
|
}
|
|
3822
|
-
if (other.type.kind === "
|
|
3412
|
+
if (other.type.kind === "void") {
|
|
3823
3413
|
return null; // no static tag to test — keep the fence
|
|
3824
3414
|
}
|
|
3825
3415
|
// The env-volatility escape (see lowerUnitComparison): a narrowed
|
|
@@ -3976,10 +3566,8 @@ function isMemberReceiver(node) {
|
|
|
3976
3566
|
function lowerNullishPair(lowerer, expr, loc, left) {
|
|
3977
3567
|
if (left.type.kind === "dyn") {
|
|
3978
3568
|
// `a ?? b` on a CHECKED-DYNAMIC left: the deciding test is the
|
|
3979
|
-
// runtime kind (scr_dyn_is_nullish — UNDEF/NULL take the default
|
|
3980
|
-
//
|
|
3981
|
-
// the wrap constructor scalar-normalizes engine null/undefined
|
|
3982
|
-
// away). Both sides live in the checked-dynamic tree — the right converts through
|
|
3569
|
+
// runtime kind (scr_dyn_is_nullish — UNDEF/NULL take the default).
|
|
3570
|
+
// Both sides live in the checked-dynamic tree — the right converts through
|
|
3983
3571
|
// the usual boundary and evaluates lazily in its branch; a default
|
|
3984
3572
|
// with no dyn representation keeps the fence.
|
|
3985
3573
|
const right = lowerer.coerceToExpected(lowerer.lowerExpr(expr.right), DYN);
|
|
@@ -3988,13 +3576,6 @@ function lowerNullishPair(lowerer, expr, loc, left) {
|
|
|
3988
3576
|
}
|
|
3989
3577
|
return { kind: "nullish", left, right, type: DYN, loc };
|
|
3990
3578
|
}
|
|
3991
|
-
if (left.type.kind === "jsval") {
|
|
3992
|
-
// `a ?? b` on an ISLAND value: the engine's own nullish test — the
|
|
3993
|
-
// left evaluates once, the right runs lazily in its branch and
|
|
3994
|
-
// marshals in (the emitter's jsval nullish arm).
|
|
3995
|
-
const right = lowerer.jsvalIn(lowerer.lowerExpr(expr.right), expr.right);
|
|
3996
|
-
return { kind: "nullish", left, right, type: JSVAL, loc };
|
|
3997
|
-
}
|
|
3998
3579
|
if (left.type.kind !== "union")
|
|
3999
3580
|
return left;
|
|
4000
3581
|
const def = lowerer.unions.get(left.type.unionId);
|
|
@@ -4438,10 +4019,6 @@ export function ensureBool(lowerer, e, node) {
|
|
|
4438
4019
|
// tag (plus the scalar payload for number/string).
|
|
4439
4020
|
return { kind: "dynTest", test: "truthy", value: e, type: BOOL, loc: e.loc };
|
|
4440
4021
|
}
|
|
4441
|
-
if (e.type.kind === "jsval") {
|
|
4442
|
-
// ToBoolean of an island value — the engine answers (never throws).
|
|
4443
|
-
return { kind: "jsOp", op: "truthy", args: [e], type: BOOL, loc: e.loc };
|
|
4444
|
-
}
|
|
4445
4022
|
if (e.type.kind === "union") {
|
|
4446
4023
|
lowerer.requireTruthyUnion(e.type.unionId, node);
|
|
4447
4024
|
return { kind: "toBool", operand: e, type: BOOL, loc: e.loc };
|
|
@@ -4459,23 +4036,15 @@ export function ensureBool(lowerer, e, node) {
|
|
|
4459
4036
|
}
|
|
4460
4037
|
lowerer.badType(node, lowerer.typeOf(node));
|
|
4461
4038
|
}
|
|
4462
|
-
/** Truthiness needs a ToBoolean per arm: dyn/caught arms have none (a
|
|
4463
|
-
* dynamic ToBoolean over the checked-dynamic tree / the snapshot box) — fence those
|
|
4464
|
-
* unions; every other arm kind is answerable (units false, scalars and
|
|
4465
|
-
* strings by value, refs true, jsval by the engine). */
|
|
4466
4039
|
export function requireTruthyUnion(lowerer, unionId, node) {
|
|
4467
4040
|
const def = lowerer.unions.get(unionId);
|
|
4468
4041
|
if (def && def.arms.every((a) => a.kind !== "dyn" && a.kind !== "caught"))
|
|
4469
4042
|
return;
|
|
4470
4043
|
lowerer.unsupported("SC1090", node, `union-typed conditions with 'unknown' arms (${NARROW_FIRST})`);
|
|
4471
4044
|
}
|
|
4472
|
-
/** Strict equality needs a per-arm comparison: units, scalars, strings,
|
|
4473
|
-
* and ref kinds (pointer identity) all have one; dyn/caught arms have no
|
|
4474
|
-
* static equality and jsval arms would need the engine's `===` — those
|
|
4475
|
-
* unions keep the narrow-first fence. */
|
|
4476
4045
|
export function eqComparableUnion(lowerer, unionId) {
|
|
4477
4046
|
const def = lowerer.unions.get(unionId);
|
|
4478
|
-
return
|
|
4047
|
+
return !!def && def.arms.every((a) => a.kind !== "dyn" && a.kind !== "caught");
|
|
4479
4048
|
}
|
|
4480
4049
|
/** Property access on a string or array receiver: `.length` lowers to the
|
|
4481
4050
|
* matching intrinsic; a bare method reference (`const f = s.slice` — a
|
|
@@ -4883,9 +4452,7 @@ export function lowerIntrinsicProperty(lowerer, expr) {
|
|
|
4883
4452
|
return null;
|
|
4884
4453
|
}
|
|
4885
4454
|
if (kind === "f64") {
|
|
4886
|
-
|
|
4887
|
-
// bare reference has no value form regardless of --dynamic.
|
|
4888
|
-
if (own(ISLAND_SURFACE.number, name) !== undefined) {
|
|
4455
|
+
if (own(STDLIB_SURFACE.number, name) !== undefined) {
|
|
4889
4456
|
lowerer.unsupported("SC1090", expr, `number methods as values (call '${name}' directly)`);
|
|
4890
4457
|
}
|
|
4891
4458
|
return null;
|
|
@@ -4929,22 +4496,7 @@ export function lowerIntrinsicProperty(lowerer, expr) {
|
|
|
4929
4496
|
? lowerer.checkedNarrowCall(helper, receiver, present, locOf(expr.expression))
|
|
4930
4497
|
: lowerer.maybeNarrow(receiver, expr.expression);
|
|
4931
4498
|
}
|
|
4932
|
-
// An island handle behind a typed-array .d.ts surface: the engine
|
|
4933
4499
|
// property read, exiting at the declared number type (the array
|
|
4934
|
-
// .length rule). Chain-handled reads stay jsval.
|
|
4935
|
-
if (receiver.type.kind === "jsval") {
|
|
4936
|
-
const read = {
|
|
4937
|
-
kind: "jsOp",
|
|
4938
|
-
op: "getProp",
|
|
4939
|
-
name,
|
|
4940
|
-
args: [receiver],
|
|
4941
|
-
type: JSVAL,
|
|
4942
|
-
loc,
|
|
4943
|
-
};
|
|
4944
|
-
if (expr.questionDotToken)
|
|
4945
|
-
return read;
|
|
4946
|
-
return { kind: "jsExit", value: read, type: F64, loc };
|
|
4947
|
-
}
|
|
4948
4500
|
return { kind: "bytesIntrinsic", method: name, receiver, args: [], type: F64, loc };
|
|
4949
4501
|
}
|
|
4950
4502
|
if (name === "byteOffset") {
|
|
@@ -5023,24 +4575,6 @@ export function lowerIntrinsicProperty(lowerer, expr) {
|
|
|
5023
4575
|
? lowerer.checkedNarrowCall(helper, receiver, present, locOf(expr.expression))
|
|
5024
4576
|
: lowerer.maybeNarrow(receiver, expr.expression);
|
|
5025
4577
|
}
|
|
5026
|
-
// An island handle behind an array-typed .d.ts surface
|
|
5027
|
-
// (`parts().length` on a declared `string[]` return — arrays never
|
|
5028
|
-
// exit eagerly, so the value stays jsval): an engine property read,
|
|
5029
|
-
// exiting at the declared number type. Chain-handled reads stay
|
|
5030
|
-
// jsval (the island chain's body must be a handle).
|
|
5031
|
-
if (receiver.type.kind === "jsval") {
|
|
5032
|
-
const read = {
|
|
5033
|
-
kind: "jsOp",
|
|
5034
|
-
op: "getProp",
|
|
5035
|
-
name: "length",
|
|
5036
|
-
args: [receiver],
|
|
5037
|
-
type: JSVAL,
|
|
5038
|
-
loc: locOf(expr),
|
|
5039
|
-
};
|
|
5040
|
-
if (expr.questionDotToken)
|
|
5041
|
-
return read;
|
|
5042
|
-
return { kind: "jsExit", value: read, type: F64, loc: locOf(expr) };
|
|
5043
|
-
}
|
|
5044
4578
|
// A CHECKED-DYNAMIC value behind an array-typed checker spelling
|
|
5045
4579
|
// (`Object.keys(u).length` — the dyn walk answers a dyn array while
|
|
5046
4580
|
// tsc spells string[]): the runtime-world dispatch — a dyn keyed
|
|
@@ -5066,7 +4600,7 @@ export function lowerIntrinsicProperty(lowerer, expr) {
|
|
|
5066
4600
|
if (kind === "string"
|
|
5067
4601
|
? own(STR_METHODS, name) !== undefined ||
|
|
5068
4602
|
STRING_INDEX_METHODS.has(name) ||
|
|
5069
|
-
own(
|
|
4603
|
+
own(STDLIB_SURFACE.string, name) !== undefined
|
|
5070
4604
|
: ARRAY_METHODS.has(name)) {
|
|
5071
4605
|
lowerer.unsupported("SC1090", expr, `${kind} methods as values (call '${name}' directly)`);
|
|
5072
4606
|
}
|
|
@@ -5171,11 +4705,8 @@ export function lowerArrayLiteral(lowerer, expr, expected) {
|
|
|
5171
4705
|
!(ts.isIdentifier(el) && el.text === "undefined"));
|
|
5172
4706
|
const ownUnhelpful = mapped === null ||
|
|
5173
4707
|
mapped.kind === "dyn" ||
|
|
5174
|
-
// The checker
|
|
5175
|
-
// own type decides nothing either — nor does an island ('any')
|
|
5176
|
-
// residue under a STATIC union slot.
|
|
4708
|
+
// The checker may echo the context union rather than infer this literal.
|
|
5177
4709
|
mapped.kind === "union" ||
|
|
5178
|
-
mapped.kind === "jsval" ||
|
|
5179
4710
|
(mapped.kind === "array" && nonUnitElems && lowerer.unitOnlyElem(mapped.elem));
|
|
5180
4711
|
if (ownUnhelpful) {
|
|
5181
4712
|
const def = lowerer.unions.get(ctxUnion.unionId);
|
|
@@ -5223,11 +4754,9 @@ export function lowerArrayLiteral(lowerer, expr, expected) {
|
|
|
5223
4754
|
tryLowerExpression(lowerer, element.expression)?.type.kind === "dyn"))
|
|
5224
4755
|
mapped = DYN;
|
|
5225
4756
|
// An EMPTY literal under a CONST ASSERTION whose type queries panicked
|
|
5226
|
-
// (tsgo's readonly-[] TupleType conversion
|
|
5227
|
-
//
|
|
5228
|
-
|
|
5229
|
-
// unit-element array, mapType's own `[] as const` rule.
|
|
5230
|
-
if ((mapped === null || mapped.kind === "jsval") &&
|
|
4757
|
+
// (tsgo's readonly-[] TupleType conversion) uses a unit-element array,
|
|
4758
|
+
// mapType's own `[] as const` rule.
|
|
4759
|
+
if (mapped === null &&
|
|
5231
4760
|
expr.elements.length === 0 &&
|
|
5232
4761
|
(tsType.flags & ts.TypeFlags.Any) !== 0 &&
|
|
5233
4762
|
underConstAssertion(expr)) {
|
|
@@ -5257,22 +4786,7 @@ export function lowerArrayLiteral(lowerer, expr, expected) {
|
|
|
5257
4786
|
// tsc padded an UNDER-LENGTH literal against an optional-element
|
|
5258
4787
|
// tuple context (`options || []` with `options?: [string?,
|
|
5259
4788
|
// number?]` — the instantiated type spells every position, the
|
|
5260
|
-
// literal spells fewer): no fixed shape holds it
|
|
5261
|
-
// engine's real arrays do — under --dynamic the literal builds
|
|
5262
|
-
// island-native with its ACTUAL elements, length exact. Static
|
|
5263
|
-
// builds keep the type fence (badType's dynamic probe tells the
|
|
5264
|
-
// --dynamic story).
|
|
5265
|
-
if (lowerer.dynamic &&
|
|
5266
|
-
expr.elements.length < shape.fields.length &&
|
|
5267
|
-
expr.elements.every((el) => !ts.isOmittedExpression(el))) {
|
|
5268
|
-
return {
|
|
5269
|
-
kind: "jsOp",
|
|
5270
|
-
op: "arrLit",
|
|
5271
|
-
args: expr.elements.map((el) => lowerer.jsvalIn(lowerer.lowerExpr(el), el)),
|
|
5272
|
-
type: JSVAL,
|
|
5273
|
-
loc,
|
|
5274
|
-
};
|
|
5275
|
-
}
|
|
4789
|
+
// literal spells fewer): no fixed shape holds it.
|
|
5276
4790
|
lowerer.badType(expr, tsType);
|
|
5277
4791
|
}
|
|
5278
4792
|
const byName = new Map(shape.fields.map((f) => [f.name, f.type]));
|
|
@@ -5375,10 +4889,9 @@ export function lowerArrayLiteral(lowerer, expr, expected) {
|
|
|
5375
4889
|
while (ts.isParenthesizedExpression(srcNode))
|
|
5376
4890
|
srcNode = srcNode.expression;
|
|
5377
4891
|
lowerer.fenceStaticHeadersIteration(el.expression);
|
|
5378
|
-
let src =
|
|
5379
|
-
(
|
|
5380
|
-
|
|
5381
|
-
: lowerer.lowerExpr(el.expression));
|
|
4892
|
+
let src = ts.isConditionalExpression(srcNode)
|
|
4893
|
+
? lowerTernary(lowerer, srcNode, type)
|
|
4894
|
+
: lowerer.lowerExpr(el.expression);
|
|
5382
4895
|
src = lowerCollectionSpread(lowerer, src, el.expression) ?? src;
|
|
5383
4896
|
// `[...new SymbolIterator]`: a CLASS ITERABLE drains through its
|
|
5384
4897
|
// own protocol into a fresh element array (classIteratorDrainCall
|
|
@@ -5933,33 +5446,6 @@ export function lowerElementAccess(lowerer, expr) {
|
|
|
5933
5446
|
return lowerer.maybeNarrow({ kind: "dynKeyGet", value: receiver, key, type: DYN, loc: locOf(expr) }, expr);
|
|
5934
5447
|
}
|
|
5935
5448
|
}
|
|
5936
|
-
if (receiverIr?.kind === "jsval") {
|
|
5937
|
-
// Dispatch follows the RUNTIME world (383(d)): a checker-'any'
|
|
5938
|
-
// receiver whose value LOWERED checked-dynamic (`bag.list[0]` where
|
|
5939
|
-
// bag.list is a routed keyed read off a wrapped island value) takes
|
|
5940
|
-
// the dyn keyed read below — the routed JSVAL arm reads the real
|
|
5941
|
-
// engine element; a jsval-lowered receiver keeps the island read.
|
|
5942
|
-
const recv = lowerer.lowerExpr(expr.expression);
|
|
5943
|
-
if (recv.type.kind !== "dyn")
|
|
5944
|
-
return islandElementRead(lowerer, expr, recv);
|
|
5945
|
-
const rawKey = lowerer.lowerExpr(expr.argumentExpression);
|
|
5946
|
-
const key = rawKey.type.kind === "string"
|
|
5947
|
-
? rawKey
|
|
5948
|
-
: rawKey.type.kind === "f64"
|
|
5949
|
-
? { kind: "toString", operand: rawKey, type: STRING, loc: rawKey.loc }
|
|
5950
|
-
: null;
|
|
5951
|
-
if (key) {
|
|
5952
|
-
const opt = hasOptionalChainGuard(expr.expression);
|
|
5953
|
-
return lowerer.maybeNarrow({
|
|
5954
|
-
kind: "dynKeyGet",
|
|
5955
|
-
key,
|
|
5956
|
-
...(opt ? { optional: true } : {}),
|
|
5957
|
-
value: recv,
|
|
5958
|
-
type: DYN,
|
|
5959
|
-
loc: locOf(expr),
|
|
5960
|
-
}, expr);
|
|
5961
|
-
}
|
|
5962
|
-
}
|
|
5963
5449
|
// Typed-array element read `b[i]` — like arrayGet with a scalar
|
|
5964
5450
|
// result; any invalid index traps (the array discipline; JS would
|
|
5965
5451
|
// read undefined — divergence 4's policy).
|
|
@@ -5976,12 +5462,6 @@ export function lowerElementAccess(lowerer, expr) {
|
|
|
5976
5462
|
? lowerer.checkedNarrowCall(helper, recv, present, locOf(expr.expression))
|
|
5977
5463
|
: lowerer.maybeNarrow(recv, expr.expression);
|
|
5978
5464
|
}
|
|
5979
|
-
// A typed-array .d.ts surface whose VALUE is an island handle
|
|
5980
|
-
// (`data()[0]` on a declared Uint8Array return — call results only
|
|
5981
|
-
// exit primitives eagerly): the engine element read, exiting at the
|
|
5982
|
-
// declared number type.
|
|
5983
|
-
if (recv.type.kind === "jsval")
|
|
5984
|
-
return islandElementRead(lowerer, expr, recv);
|
|
5985
5465
|
const index = lowerOptionalNumber(lowerer, lowerer.lowerExpr(expr.argumentExpression), locOf(expr.argumentExpression), expr.argumentExpression);
|
|
5986
5466
|
if (isJsSourceFile(expr.getSourceFile()) && recv.type.kind === "bytes") {
|
|
5987
5467
|
return {
|
|
@@ -6033,14 +5513,6 @@ export function lowerElementAccess(lowerer, expr) {
|
|
|
6033
5513
|
const shape = lowerer.shapes.get(receiverIr.shapeId);
|
|
6034
5514
|
if (shape?.tuple) {
|
|
6035
5515
|
let obj = lowerer.lowerExpr(expr.expression);
|
|
6036
|
-
// A tuple-typed .d.ts surface whose VALUE is an island handle
|
|
6037
|
-
// (`pair()[0]` on a declared `[number, string]` return — the
|
|
6038
|
-
// anonymous tuple type has no npm symbol, so the checker maps it
|
|
6039
|
-
// structurally while the call result stays an engine array): the
|
|
6040
|
-
// read rides engine ops, exiting at the declared per-index type
|
|
6041
|
-
// like the array path.
|
|
6042
|
-
if (obj.type.kind === "jsval")
|
|
6043
|
-
return islandElementRead(lowerer, expr, obj);
|
|
6044
5516
|
if (obj.type.kind === "dyn") {
|
|
6045
5517
|
// Object.entries over a checked value stores each pair in the
|
|
6046
5518
|
// dynamic tree even when the checker names a tuple type.
|
|
@@ -6091,14 +5563,6 @@ export function lowerElementAccess(lowerer, expr) {
|
|
|
6091
5563
|
: lowerer.maybeNarrow(get, expr);
|
|
6092
5564
|
}
|
|
6093
5565
|
if (shape && !shape.tuple) {
|
|
6094
|
-
// A record-typed .d.ts surface whose VALUE is an island handle
|
|
6095
|
-
// (`headers()["x-id"]` on a declared `Record<string, string>`
|
|
6096
|
-
// return — the stdlib alias maps structurally while the call
|
|
6097
|
-
// result stays an engine object): the read rides engine ops with
|
|
6098
|
-
// the declared-value exit, never a recordKeyGet over a jsval.
|
|
6099
|
-
const obj = lowerer.lowerExpr(expr.expression);
|
|
6100
|
-
if (obj.type.kind === "jsval")
|
|
6101
|
-
return islandElementRead(lowerer, expr, obj);
|
|
6102
5566
|
return lowerer.lowerRecordKeyRead(expr, receiverIr.shapeId, shape);
|
|
6103
5567
|
}
|
|
6104
5568
|
}
|
|
@@ -6325,14 +5789,6 @@ export function lowerElementAccess(lowerer, expr) {
|
|
|
6325
5789
|
? lowerer.checkedNarrowCall(helper, arr, present, locOf(expr.expression))
|
|
6326
5790
|
: lowerer.maybeNarrow(arr, expr.expression);
|
|
6327
5791
|
}
|
|
6328
|
-
// The checker sees an array but the VALUE is an island handle (an
|
|
6329
|
-
// array-typed .d.ts surface: `parts()[0]` on a declared `string[]`
|
|
6330
|
-
// return, `issue.path[0]` on a declared member — arrays never exit
|
|
6331
|
-
// eagerly, so the call/member read stays jsval): the read rides
|
|
6332
|
-
// engine ops with the declared-element exit, never a static arrayGet
|
|
6333
|
-
// over a jsval (the validator ICE).
|
|
6334
|
-
if (arr.type.kind === "jsval")
|
|
6335
|
-
return islandElementRead(lowerer, expr, arr);
|
|
6336
5792
|
// The checker sees an array but the VALUE lowered checked-dynamic (a
|
|
6337
5793
|
// jsdoc-typed default export from a .js module — signature 14): the
|
|
6338
5794
|
// read rides the dynCheck boundary when the array shape is one the checked-dynamic tree
|
|
@@ -6410,33 +5866,6 @@ export function lowerElementAccess(lowerer, expr) {
|
|
|
6410
5866
|
// narrows literal-index element accesses).
|
|
6411
5867
|
return lowerer.maybeNarrow({ kind: "arrayGet", arr, index, type: elemT, loc: locOf(expr) }, expr);
|
|
6412
5868
|
}
|
|
6413
|
-
/** `o[k]` where the RECEIVER is an island value — a jsval-mapped checker
|
|
6414
|
-
* type, or an array/tuple-typed .d.ts surface whose lowered value is a
|
|
6415
|
-
* handle. The key marshals in (any JS key kind — the engine does its
|
|
6416
|
-
* own ToPropertyKey) and the result stays island, EXCEPT when the
|
|
6417
|
-
* checker declares the element a primitive (`parts()[0]` on a declared
|
|
6418
|
-
* `string[]`): those exit eagerly to the static type, exactly the
|
|
6419
|
-
* island property-read rule (trust-but-verify — a lying declaration
|
|
6420
|
-
* throws the catchable TypeError; tsc puts the `| undefined` of a
|
|
6421
|
-
* short-circuiting chain on the OUTERMOST expression, so chain tails
|
|
6422
|
-
* never map primitive here). Chain-handled reads (`v?.[0]`) stay jsval
|
|
6423
|
-
* — the chain's unit path is the engine's undefined. */
|
|
6424
|
-
function islandElementRead(lowerer, expr, obj) {
|
|
6425
|
-
const loc = locOf(expr);
|
|
6426
|
-
const key = lowerer.jsvalIn(lowerer.lowerExpr(expr.argumentExpression), expr.argumentExpression);
|
|
6427
|
-
const read = { kind: "jsOp", op: "getIdx", args: [obj, key], type: JSVAL, loc };
|
|
6428
|
-
if (!expr.questionDotToken) {
|
|
6429
|
-
const declared = lowerer.mapTypeOf(lowerer.typeOf(expr));
|
|
6430
|
-
if (declared &&
|
|
6431
|
-
(declared.kind === "f64" ||
|
|
6432
|
-
declared.kind === "bool" ||
|
|
6433
|
-
declared.kind === "string" ||
|
|
6434
|
-
(declared.kind === "bytes" && declared.elem === "u8"))) {
|
|
6435
|
-
return { kind: "jsExit", value: read, type: declared, loc };
|
|
6436
|
-
}
|
|
6437
|
-
}
|
|
6438
|
-
return read;
|
|
6439
|
-
}
|
|
6440
5869
|
/** `r[k]` over a (non-tuple) record shape. A LITERAL key naming a declared
|
|
6441
5870
|
* field is the bracket spelling of field access (the ONLY spelling tsc
|
|
6442
5871
|
* permits for signature-declared fields under
|
|
@@ -6925,7 +6354,13 @@ export function lowerElementCompound(lowerer, expr, op) {
|
|
|
6925
6354
|
const receiverRef = () => varRef(receiverLocal.id, receiver.type, loc);
|
|
6926
6355
|
const indexRef = () => varRef(indexLocal.id, F64, loc);
|
|
6927
6356
|
const oldValue = receiver.type.kind === "array"
|
|
6928
|
-
?
|
|
6357
|
+
? receiver.type.elem.kind === "f64"
|
|
6358
|
+
? // Every numeric operator applies ToNumber to the old value, so a
|
|
6359
|
+
// missing element is NaN without materializing `number | undefined`.
|
|
6360
|
+
arrayNumberRead(receiverRef(), indexRef(), locOf(target))
|
|
6361
|
+
: receiver.type.elem.kind === "string" && op === "+"
|
|
6362
|
+
? arrayStringOperand(receiverRef(), indexRef(), locOf(target))
|
|
6363
|
+
: arrayValueRead(lowerer, receiverRef(), indexRef(), receiver.type.elem, locOf(target))
|
|
6929
6364
|
: {
|
|
6930
6365
|
// An invalid index reads undefined in Node, which every numeric
|
|
6931
6366
|
// compound operator turns into NaN; the write is then ignored.
|
|
@@ -7002,6 +6437,25 @@ export function lowerElementCompound(lowerer, expr, op) {
|
|
|
7002
6437
|
loc,
|
|
7003
6438
|
};
|
|
7004
6439
|
}
|
|
6440
|
+
/** ToString of one stabilized `string[]` element read for `+=`: a missing
|
|
6441
|
+
* element concatenates as "undefined". */
|
|
6442
|
+
function arrayStringOperand(arr, index, loc) {
|
|
6443
|
+
return {
|
|
6444
|
+
kind: "ternary",
|
|
6445
|
+
cond: {
|
|
6446
|
+
kind: "bin",
|
|
6447
|
+
op: "===",
|
|
6448
|
+
left: { kind: "arrayState", arr, index, type: F64, loc },
|
|
6449
|
+
right: { kind: "numLit", value: 1, type: F64, loc },
|
|
6450
|
+
type: BOOL,
|
|
6451
|
+
loc,
|
|
6452
|
+
},
|
|
6453
|
+
then: { kind: "arrayGet", arr, index, type: STRING, loc },
|
|
6454
|
+
else_: strLit("undefined", loc),
|
|
6455
|
+
type: STRING,
|
|
6456
|
+
loc,
|
|
6457
|
+
};
|
|
6458
|
+
}
|
|
7005
6459
|
/** Checked member assignment evaluates the reference before its RHS and
|
|
7006
6460
|
* yields the original assigned value, including in a chained assignment. */
|
|
7007
6461
|
function lowerDynMemberAssignment(lowerer, expr, recv) {
|
|
@@ -7190,39 +6644,6 @@ export function lowerElementWrite(lowerer, expr) {
|
|
|
7190
6644
|
if (receiver?.type.kind === "array")
|
|
7191
6645
|
receiverIr = receiver.type;
|
|
7192
6646
|
}
|
|
7193
|
-
if (receiverIr?.kind === "jsval") {
|
|
7194
|
-
const obj = lowerer.lowerExpr(target.expression);
|
|
7195
|
-
// Dispatch follows the RUNTIME world (383(d)): a checker-'any'
|
|
7196
|
-
// receiver whose value LOWERED checked-dynamic takes the dyn keyed
|
|
7197
|
-
// write — the routed JSVAL arm lands it on the real engine object.
|
|
7198
|
-
if (obj.type.kind === "dyn") {
|
|
7199
|
-
const loc = locOf(expr);
|
|
7200
|
-
const rawKey = lowerer.lowerExpr(target.argumentExpression);
|
|
7201
|
-
const key = rawKey.type.kind === "f64" || rawKey.type.kind === "bool" || rawKey.type.kind === "dyn"
|
|
7202
|
-
? { kind: "toString", operand: rawKey, type: STRING, loc: rawKey.loc }
|
|
7203
|
-
: rawKey;
|
|
7204
|
-
if (key.type.kind !== "string") {
|
|
7205
|
-
lowerer.unsupported("SC1090", target.argumentExpression, `'${lowerer.fmt(key.type)}'-typed keys in keyed writes through 'unknown' values`);
|
|
7206
|
-
}
|
|
7207
|
-
const value = lowerer.coerceToExpected(lowerer.lowerExpr(expr.right), DYN);
|
|
7208
|
-
if (value.type.kind !== "dyn") {
|
|
7209
|
-
lowerer.unsupported("SC1100", expr.right, `assigning '${lowerer.fmt(value.type)}' values through 'unknown' receivers`);
|
|
7210
|
-
}
|
|
7211
|
-
return {
|
|
7212
|
-
kind: "exprStmt",
|
|
7213
|
-
expr: { kind: "libCall", fn: "dyn.keySet", args: [obj, key, value], type: VOID, loc },
|
|
7214
|
-
loc,
|
|
7215
|
-
};
|
|
7216
|
-
}
|
|
7217
|
-
const key = lowerer.jsvalIn(lowerer.lowerExpr(target.argumentExpression), target.argumentExpression);
|
|
7218
|
-
const value = lowerer.jsvalIn(lowerer.lowerExpr(expr.right), expr.right);
|
|
7219
|
-
const loc = locOf(expr);
|
|
7220
|
-
return {
|
|
7221
|
-
kind: "exprStmt",
|
|
7222
|
-
expr: { kind: "jsOp", op: "setIdx", args: [obj, key, value], type: VOID, loc },
|
|
7223
|
-
loc,
|
|
7224
|
-
};
|
|
7225
|
-
}
|
|
7226
6647
|
// A checked-dynamic receiver TYPE (`unknown[]` and the collapsed
|
|
7227
6648
|
// `(string | object)[]` map to DYN wholesale now): the dyn keyed
|
|
7228
6649
|
// write — dyn.keySet. Number keys canonicalize through the JS-exact
|
|
@@ -7276,18 +6697,6 @@ export function lowerElementWrite(lowerer, expr) {
|
|
|
7276
6697
|
// the runtime coerces JS-exactly; invalid indices are ignored.
|
|
7277
6698
|
if (receiverIr?.kind === "bytes") {
|
|
7278
6699
|
const recv = lowerer.lowerExpr(target.expression);
|
|
7279
|
-
// The write twin: a typed-array .d.ts surface whose VALUE is a
|
|
7280
|
-
// handle takes the engine keyed write.
|
|
7281
|
-
if (recv.type.kind === "jsval") {
|
|
7282
|
-
const key = lowerer.jsvalIn(lowerer.lowerExpr(target.argumentExpression), target.argumentExpression);
|
|
7283
|
-
const value = lowerer.jsvalIn(lowerer.lowerExpr(expr.right), expr.right);
|
|
7284
|
-
const loc = locOf(expr);
|
|
7285
|
-
return {
|
|
7286
|
-
kind: "exprStmt",
|
|
7287
|
-
expr: { kind: "jsOp", op: "setIdx", args: [recv, key, value], type: VOID, loc },
|
|
7288
|
-
loc,
|
|
7289
|
-
};
|
|
7290
|
-
}
|
|
7291
6700
|
const index = lowerer.lowerExpr(target.argumentExpression);
|
|
7292
6701
|
if (index.type.kind === "dyn" && recv.type.kind === "bytes") {
|
|
7293
6702
|
return {
|
|
@@ -7306,24 +6715,11 @@ export function lowerElementWrite(lowerer, expr) {
|
|
|
7306
6715
|
// — literal indices only, like the read.
|
|
7307
6716
|
if (receiverIr?.kind === "record") {
|
|
7308
6717
|
const shape = lowerer.shapes.get(receiverIr.shapeId);
|
|
7309
|
-
// A record/tuple-typed .d.ts surface whose VALUE is an island
|
|
7310
|
-
// handle: the engine keyed write (the read dispatch's twin), never
|
|
7311
|
-
// a recordSet/recordKeySet over a jsval.
|
|
7312
6718
|
if (shape) {
|
|
7313
6719
|
const obj = lowerer.lowerExpr(target.expression);
|
|
7314
6720
|
if (hasClassPayload(lowerer, obj.type)) {
|
|
7315
6721
|
lowerer.unsupported("SC1090", target, "computed property writes through structural views of class instances (use a declared literal key)");
|
|
7316
6722
|
}
|
|
7317
|
-
if (obj.type.kind === "jsval") {
|
|
7318
|
-
const key = lowerer.jsvalIn(lowerer.lowerExpr(target.argumentExpression), target.argumentExpression);
|
|
7319
|
-
const value = lowerer.jsvalIn(lowerer.lowerExpr(expr.right), expr.right);
|
|
7320
|
-
const loc = locOf(expr);
|
|
7321
|
-
return {
|
|
7322
|
-
kind: "exprStmt",
|
|
7323
|
-
expr: { kind: "jsOp", op: "setIdx", args: [obj, key, value], type: VOID, loc },
|
|
7324
|
-
loc,
|
|
7325
|
-
};
|
|
7326
|
-
}
|
|
7327
6723
|
// A record-mapped CHECKER type over a VALUE living in the checked-dynamic tree (a
|
|
7328
6724
|
// JS file-scope object-literal global): the checked-dynamic keyed
|
|
7329
6725
|
// write — dyn.keySet (later writes win, insertion order; Node's
|
|
@@ -7488,9 +6884,8 @@ export function lowerElementWrite(lowerer, expr) {
|
|
|
7488
6884
|
// arm above — later writes win in insertion order, number keys
|
|
7489
6885
|
// canonicalize through the JS-exact formatter (ToPropertyKey's string
|
|
7490
6886
|
// side), index keys on dyn arrays set/extend elements, and non-object
|
|
7491
|
-
// receivers throw Node's TypeErrors at runtime. An
|
|
7492
|
-
//
|
|
7493
|
-
// probes the receiver's own lowered world: a dyn value takes the same
|
|
6887
|
+
// receivers throw Node's TypeErrors at runtime. An unmapped checker type
|
|
6888
|
+
// probes the receiver's lowered representation: a dyn value takes the same
|
|
7494
6889
|
// write, anything else falls through to the fences.
|
|
7495
6890
|
if (receiverIr?.kind === "dyn" || receiverIr?.kind === "object" || receiverIr === null) {
|
|
7496
6891
|
const obj = receiverIr !== null
|
|
@@ -7530,19 +6925,6 @@ export function lowerElementWrite(lowerer, expr) {
|
|
|
7530
6925
|
lowerer.unsupported("SC1090", target, "assignment to non-array elements");
|
|
7531
6926
|
}
|
|
7532
6927
|
let arr = lowerer.lowerExpr(target.expression);
|
|
7533
|
-
// The write twin of the island element read: an array-typed .d.ts
|
|
7534
|
-
// surface whose VALUE is a handle takes the engine keyed write, never
|
|
7535
|
-
// a static arraySet over a jsval.
|
|
7536
|
-
if (arr.type.kind === "jsval") {
|
|
7537
|
-
const key = lowerer.jsvalIn(lowerer.lowerExpr(target.argumentExpression), target.argumentExpression);
|
|
7538
|
-
const value = lowerer.jsvalIn(lowerer.lowerExpr(expr.right), expr.right);
|
|
7539
|
-
const loc = locOf(expr);
|
|
7540
|
-
return {
|
|
7541
|
-
kind: "exprStmt",
|
|
7542
|
-
expr: { kind: "jsOp", op: "setIdx", args: [arr, key, value], type: VOID, loc },
|
|
7543
|
-
loc,
|
|
7544
|
-
};
|
|
7545
|
-
}
|
|
7546
6928
|
if (arr.type.kind === "union" &&
|
|
7547
6929
|
lowerer.armTag(arr.type.unionId, UNDEFINED_T) >= 0 &&
|
|
7548
6930
|
receiverIr.kind === "array") {
|
|
@@ -7630,10 +7012,6 @@ export function ensureString(lowerer, e, node) {
|
|
|
7630
7012
|
const boxed = { kind: "dynFrom", value: e, type: DYN, loc: e.loc };
|
|
7631
7013
|
return { kind: "toString", operand: boxed, type: STRING, loc: e.loc };
|
|
7632
7014
|
}
|
|
7633
|
-
if (e.type.kind === "jsval") {
|
|
7634
|
-
// String(v) in the engine — JS-exact (and Node-exact in templates).
|
|
7635
|
-
return { kind: "jsOp", op: "toStr", args: [e], type: STRING, loc: e.loc };
|
|
7636
|
-
}
|
|
7637
7015
|
if (e.type.kind === "object") {
|
|
7638
7016
|
// String(err) / `${err}` uses the same dispatch as err.toString().
|
|
7639
7017
|
for (let c = lowerer.classes.get(e.type.className) ?? null; c; c = c.base) {
|
|
@@ -7875,12 +7253,8 @@ export function lowerAsExpression(lowerer, expr) {
|
|
|
7875
7253
|
const use = runtimeOptionalUseOf(expr);
|
|
7876
7254
|
if (inner.type.kind === "union" && runtimeOptionalAssertionErases(lowerer, expr, inner, use))
|
|
7877
7255
|
return inner;
|
|
7878
|
-
if (inner.type.kind !== "dyn"
|
|
7879
|
-
// A STATIC value cast `as any` is the explicit island entrance.
|
|
7256
|
+
if (inner.type.kind !== "dyn") {
|
|
7880
7257
|
const targetTs0 = lowerer.checker.getTypeFromTypeNode(expr.type);
|
|
7881
|
-
if (targetTs0.flags & ts.TypeFlags.Any && lowerer.dynamic) {
|
|
7882
|
-
return lowerer.jsvalIn(inner, expr.expression);
|
|
7883
|
-
}
|
|
7884
7258
|
const target = lowerer.mapTypeOf(targetTs0);
|
|
7885
7259
|
if (target?.kind === "object") {
|
|
7886
7260
|
const asserted = checkedClassAssertion(lowerer, inner, target, locOf(expr));
|
|
@@ -7958,25 +7332,6 @@ export function lowerAsExpression(lowerer, expr) {
|
|
|
7958
7332
|
}
|
|
7959
7333
|
return inner; // erasure, unchanged
|
|
7960
7334
|
}
|
|
7961
|
-
if (inner.type.kind === "jsval") {
|
|
7962
|
-
// The island exit. `as any` on an island value is erasure; a static
|
|
7963
|
-
// target compiles to a VALIDATED extraction (strict primitives; the
|
|
7964
|
-
// JSON round-trip + dynCheck walker for composites) that throws a
|
|
7965
|
-
// catchable TypeError on mismatch — same trust-but-verify rule as
|
|
7966
|
-
// the dyn boundary. Targets with no extraction are rejected.
|
|
7967
|
-
const targetTs = lowerer.checker.getTypeFromTypeNode(expr.type);
|
|
7968
|
-
if (targetTs.flags & ts.TypeFlags.Any)
|
|
7969
|
-
return inner;
|
|
7970
|
-
const target = lowerer.mapTypeOf(targetTs);
|
|
7971
|
-
if (!target)
|
|
7972
|
-
lowerer.badType(expr.type, targetTs);
|
|
7973
|
-
if (!lowerer.boundarySafe(target)) {
|
|
7974
|
-
lowerer.unsupported("SC1090", expr, `a checked cast of 'any' to '${lowerer.fmt(target)}' ` +
|
|
7975
|
-
`(an 'any' value can only be validated against JSON-representable types: ` +
|
|
7976
|
-
`number, string, boolean, records, arrays, and unions of those)`);
|
|
7977
|
-
}
|
|
7978
|
-
return { kind: "jsExit", value: inner, type: target, loc: locOf(expr) };
|
|
7979
|
-
}
|
|
7980
7335
|
const targetTs = lowerer.checker.getTypeFromTypeNode(expr.type);
|
|
7981
7336
|
const target = lowerer.mapTypeOf(targetTs) ?? dynFallbackType(lowerer, expr.type, targetTs);
|
|
7982
7337
|
if (!target)
|
|
@@ -8045,9 +7400,6 @@ export function lowerPrefixUnary(lowerer, expr) {
|
|
|
8045
7400
|
switch (expr.operator) {
|
|
8046
7401
|
case ts.SyntaxKind.MinusToken: {
|
|
8047
7402
|
const raw = lowerer.lowerExpr(expr.operand);
|
|
8048
|
-
if (raw.type.kind === "jsval") {
|
|
8049
|
-
return { kind: "jsOp", op: "neg", args: [raw], type: JSVAL, loc };
|
|
8050
|
-
}
|
|
8051
7403
|
if (raw.type.kind === "bigint") {
|
|
8052
7404
|
return { kind: "libCall", fn: "bigint.neg", args: [raw], type: BIGINT_T, loc };
|
|
8053
7405
|
}
|
|
@@ -8069,9 +7421,6 @@ export function lowerPrefixUnary(lowerer, expr) {
|
|
|
8069
7421
|
// Unary + is ToNumber; on an already-number operand it's identity,
|
|
8070
7422
|
// and a STRING operand runs the runtime's ECMA-exact StringToNumber
|
|
8071
7423
|
// (num.fromString — Number(aString)'s lowering, scr_string.c).
|
|
8072
|
-
if (raw.type.kind === "jsval") {
|
|
8073
|
-
return { kind: "jsOp", op: "plus", args: [raw], type: JSVAL, loc };
|
|
8074
|
-
}
|
|
8075
7424
|
if (raw.type.kind === "string") {
|
|
8076
7425
|
return { kind: "libCall", fn: "num.fromString", args: [raw], type: F64, loc };
|
|
8077
7426
|
}
|
|
@@ -8143,6 +7492,13 @@ export function lowerIncDec(lowerer, expr, prefix) {
|
|
|
8143
7492
|
return varRef(local.id, value.type, loc);
|
|
8144
7493
|
};
|
|
8145
7494
|
const finish = (read, write) => {
|
|
7495
|
+
if (read.type.kind === "bigint") {
|
|
7496
|
+
const old = save(read, "%incrementOld");
|
|
7497
|
+
const next = save(bigintStep(op, old, loc), "%incrementNext");
|
|
7498
|
+
stmts.push(write(next));
|
|
7499
|
+
const result = prefix ? next : old;
|
|
7500
|
+
return { kind: "seqExpr", stmts, result, type: result.type, loc };
|
|
7501
|
+
}
|
|
8146
7502
|
const old = save(read.type.kind === "f64"
|
|
8147
7503
|
? read
|
|
8148
7504
|
: {
|
|
@@ -8186,7 +7542,9 @@ export function lowerIncDec(lowerer, expr, prefix) {
|
|
|
8186
7542
|
lowerer.unsupported("SC1090", access, "incrementing non-number array keys");
|
|
8187
7543
|
const type = raw.type;
|
|
8188
7544
|
const read = type.kind === "array"
|
|
8189
|
-
?
|
|
7545
|
+
? type.elem.kind === "f64"
|
|
7546
|
+
? arrayNumberRead(receiver, index, loc)
|
|
7547
|
+
: arrayValueRead(lowerer, receiver, index, type.elem, loc)
|
|
8190
7548
|
: {
|
|
8191
7549
|
kind: "bytesIntrinsic",
|
|
8192
7550
|
method: "get",
|
|
@@ -8333,6 +7691,26 @@ export function lowerIncDecTarget(lowerer, expr, target, prefix) {
|
|
|
8333
7691
|
};
|
|
8334
7692
|
}
|
|
8335
7693
|
}
|
|
7694
|
+
if (target.type.kind === "bigint") {
|
|
7695
|
+
const old = lowerer.declareHiddenLocal("%bigintOld", BIGINT_T);
|
|
7696
|
+
const next = lowerer.declareHiddenLocal("%bigintNext", BIGINT_T);
|
|
7697
|
+
return {
|
|
7698
|
+
kind: "seqExpr",
|
|
7699
|
+
stmts: [
|
|
7700
|
+
{ kind: "varDecl", localId: old.id, init: varRef(target.id, BIGINT_T, loc), loc },
|
|
7701
|
+
{
|
|
7702
|
+
kind: "varDecl",
|
|
7703
|
+
localId: next.id,
|
|
7704
|
+
init: bigintStep(op, varRef(old.id, BIGINT_T, loc), loc),
|
|
7705
|
+
loc,
|
|
7706
|
+
},
|
|
7707
|
+
{ kind: "assign", localId: target.id, value: varRef(next.id, BIGINT_T, loc), loc },
|
|
7708
|
+
],
|
|
7709
|
+
result: varRef(prefix ? next.id : old.id, BIGINT_T, loc),
|
|
7710
|
+
type: BIGINT_T,
|
|
7711
|
+
loc,
|
|
7712
|
+
};
|
|
7713
|
+
}
|
|
8336
7714
|
if (target.type.kind !== "f64")
|
|
8337
7715
|
lowerer.unsupported("SC1043", expr);
|
|
8338
7716
|
return { kind: "incDec", op, prefix, localId: target.id, type: F64, loc };
|
|
@@ -8363,35 +7741,40 @@ function seqExprSafeStmt(s) {
|
|
|
8363
7741
|
return false;
|
|
8364
7742
|
}
|
|
8365
7743
|
}
|
|
8366
|
-
|
|
8367
|
-
|
|
8368
|
-
|
|
8369
|
-
|
|
8370
|
-
|
|
8371
|
-
|
|
8372
|
-
|
|
8373
|
-
|
|
8374
|
-
|
|
8375
|
-
|
|
8376
|
-
|
|
8377
|
-
|
|
8378
|
-
|
|
8379
|
-
|
|
8380
|
-
|
|
8381
|
-
|
|
8382
|
-
|
|
8383
|
-
|
|
7744
|
+
const BIGINT_COMPOUND = {
|
|
7745
|
+
"+": "bigint.add",
|
|
7746
|
+
"-": "bigint.sub",
|
|
7747
|
+
"*": "bigint.mul",
|
|
7748
|
+
"/": "bigint.div",
|
|
7749
|
+
"%": "bigint.mod",
|
|
7750
|
+
"**": "bigint.pow",
|
|
7751
|
+
"&": "bigint.and",
|
|
7752
|
+
"|": "bigint.or",
|
|
7753
|
+
"^": "bigint.xor",
|
|
7754
|
+
"<<": "bigint.shl",
|
|
7755
|
+
">>": "bigint.shr",
|
|
7756
|
+
};
|
|
7757
|
+
/** `old op= rhs` over two bigints: the binary operator's libCall. Null
|
|
7758
|
+
* for other operand types (and `>>>`, which BigInt does not have). */
|
|
7759
|
+
function bigintCompoundValue(op, left, right, loc) {
|
|
7760
|
+
if (left.type.kind !== "bigint" || right.type.kind !== "bigint" || op === ">>>")
|
|
7761
|
+
return null;
|
|
7762
|
+
return { kind: "libCall", fn: BIGINT_COMPOUND[op], args: [left, right], type: BIGINT_T, loc };
|
|
7763
|
+
}
|
|
7764
|
+
/** `++`/`--` on a bigint value: old ± 1n. */
|
|
7765
|
+
function bigintStep(op, old, loc) {
|
|
7766
|
+
const one = {
|
|
7767
|
+
kind: "libCall",
|
|
7768
|
+
fn: "bigint.parse",
|
|
7769
|
+
args: [{ kind: "strLit", value: "1", type: STRING, loc }],
|
|
7770
|
+
type: BIGINT_T,
|
|
7771
|
+
loc,
|
|
8384
7772
|
};
|
|
8385
|
-
const jop = JS_BIN[op];
|
|
8386
|
-
if (jop === undefined) {
|
|
8387
|
-
lowerer.unsupported("SC1090", expr, `operator '${ts.tokenToString(op) ?? ts.syntaxKindName(op)}' on 'any' values`);
|
|
8388
|
-
}
|
|
8389
|
-
const type = jsOpResultKind(jop) === "bool" ? BOOL : JSVAL;
|
|
8390
7773
|
return {
|
|
8391
|
-
kind: "
|
|
8392
|
-
op:
|
|
8393
|
-
args: [
|
|
8394
|
-
type,
|
|
7774
|
+
kind: "libCall",
|
|
7775
|
+
fn: op === "+" ? "bigint.add" : "bigint.sub",
|
|
7776
|
+
args: [old, one],
|
|
7777
|
+
type: BIGINT_T,
|
|
8395
7778
|
loc,
|
|
8396
7779
|
};
|
|
8397
7780
|
}
|
|
@@ -8406,27 +7789,6 @@ export function lowerCompoundValueToTarget(lowerer, expr, compound, target) {
|
|
|
8406
7789
|
const rhs = lowerer.lowerExpr(expr.right);
|
|
8407
7790
|
const numericRead = lowerOptionalNumber(lowerer, read, loc);
|
|
8408
7791
|
const numericRhs = lowerOptionalNumber(lowerer, rhs, loc);
|
|
8409
|
-
if (target.type.kind === "jsval" || rhs.type.kind === "jsval") {
|
|
8410
|
-
const JS_COMPOUND = {
|
|
8411
|
-
"+": "add",
|
|
8412
|
-
"-": "sub",
|
|
8413
|
-
"*": "mul",
|
|
8414
|
-
"/": "div",
|
|
8415
|
-
"%": "mod",
|
|
8416
|
-
"**": "pow",
|
|
8417
|
-
};
|
|
8418
|
-
const jop = JS_COMPOUND[compound];
|
|
8419
|
-
if (jop === undefined)
|
|
8420
|
-
lowerer.unsupported("SC1043", expr);
|
|
8421
|
-
const wrapped = {
|
|
8422
|
-
kind: "jsOp",
|
|
8423
|
-
op: jop,
|
|
8424
|
-
args: [lowerer.jsvalIn(read, expr.left), lowerer.jsvalIn(rhs, expr.right)],
|
|
8425
|
-
type: JSVAL,
|
|
8426
|
-
loc,
|
|
8427
|
-
};
|
|
8428
|
-
return lowerer.coerceInto(expr, wrapped, target.type);
|
|
8429
|
-
}
|
|
8430
7792
|
if (compound === "+" &&
|
|
8431
7793
|
(target.type.kind === "string" ||
|
|
8432
7794
|
(target.type.kind === "union" &&
|
|
@@ -8459,6 +7821,9 @@ export function lowerCompoundValueToTarget(lowerer, expr, compound, target) {
|
|
|
8459
7821
|
};
|
|
8460
7822
|
return lowerer.coerceInto(expr, computed, target.type);
|
|
8461
7823
|
}
|
|
7824
|
+
const bigint = bigintCompoundValue(compound, read, rhs, loc);
|
|
7825
|
+
if (bigint)
|
|
7826
|
+
return bigint;
|
|
8462
7827
|
lowerer.unsupported("SC1043", expr);
|
|
8463
7828
|
}
|
|
8464
7829
|
/** Equality of two NaN-coded values (nan-coded-reads.ts), each of which may
|
|
@@ -8704,49 +8069,6 @@ export function lowerBinary(lowerer, expr) {
|
|
|
8704
8069
|
};
|
|
8705
8070
|
}
|
|
8706
8071
|
}
|
|
8707
|
-
// `h.k = v` on an ISLAND receiver in VALUE position: the engine
|
|
8708
|
-
// property write (setProp throws the engine's TypeErrors on
|
|
8709
|
-
// nullish receivers, bridged catchably), the RHS value threaded
|
|
8710
|
-
// through as the expression's value.
|
|
8711
|
-
if (ts.isPropertyAccessExpression(expr.left) &&
|
|
8712
|
-
!expr.left.questionDotToken &&
|
|
8713
|
-
lowerer.isIslandExpr(expr.left.expression)) {
|
|
8714
|
-
const recv = lowerer.lowerExpr(expr.left.expression);
|
|
8715
|
-
const recvTmp = lowerer.declareHiddenLocal("%setRecv", recv.type);
|
|
8716
|
-
const rhsVal = lowerer.lowerExpr(expr.right);
|
|
8717
|
-
const valTmp = lowerer.declareHiddenLocal("%setVal", rhsVal.type);
|
|
8718
|
-
const valRef = () => ({
|
|
8719
|
-
kind: "varRef",
|
|
8720
|
-
localId: valTmp.id,
|
|
8721
|
-
type: rhsVal.type,
|
|
8722
|
-
loc,
|
|
8723
|
-
});
|
|
8724
|
-
return {
|
|
8725
|
-
kind: "seqExpr",
|
|
8726
|
-
stmts: [
|
|
8727
|
-
{ kind: "varDecl", localId: recvTmp.id, init: recv, loc },
|
|
8728
|
-
{ kind: "varDecl", localId: valTmp.id, init: rhsVal, loc },
|
|
8729
|
-
{
|
|
8730
|
-
kind: "exprStmt",
|
|
8731
|
-
expr: {
|
|
8732
|
-
kind: "jsOp",
|
|
8733
|
-
op: "setProp",
|
|
8734
|
-
name: expr.left.name.text,
|
|
8735
|
-
args: [
|
|
8736
|
-
{ kind: "varRef", localId: recvTmp.id, type: recv.type, loc },
|
|
8737
|
-
lowerer.jsvalIn(valRef(), expr.right),
|
|
8738
|
-
],
|
|
8739
|
-
type: VOID,
|
|
8740
|
-
loc,
|
|
8741
|
-
},
|
|
8742
|
-
loc,
|
|
8743
|
-
},
|
|
8744
|
-
],
|
|
8745
|
-
result: valRef(),
|
|
8746
|
-
type: rhsVal.type,
|
|
8747
|
-
loc,
|
|
8748
|
-
};
|
|
8749
|
-
}
|
|
8750
8072
|
// `h.k = v` on a CHECKED-DYNAMIC receiver in VALUE position
|
|
8751
8073
|
// (`var _ = module.exports = foo`): receiver first, then RHS
|
|
8752
8074
|
// (JS's reference-before-value order), the keyed write, and the
|
|
@@ -8871,6 +8193,16 @@ export function lowerBinary(lowerer, expr) {
|
|
|
8871
8193
|
left = storedLeft;
|
|
8872
8194
|
if (storedRight !== null && left.type.kind !== "union")
|
|
8873
8195
|
right = storedRight;
|
|
8196
|
+
// A typed-array read compared with a plain number needs no
|
|
8197
|
+
// `number | undefined` box.
|
|
8198
|
+
const fusedLeft = tryLowerBytesReadNumberEquality(lowerer, left, right, expr.right);
|
|
8199
|
+
if (fusedLeft)
|
|
8200
|
+
left = fusedLeft;
|
|
8201
|
+
else {
|
|
8202
|
+
const fusedRight = tryLowerBytesReadNumberEquality(lowerer, right, left, expr.left);
|
|
8203
|
+
if (fusedRight)
|
|
8204
|
+
right = fusedRight;
|
|
8205
|
+
}
|
|
8874
8206
|
}
|
|
8875
8207
|
if (strictEquality && (left.type.kind === "caught" || right.type.kind === "caught")) {
|
|
8876
8208
|
if (left.type.kind === "caught")
|
|
@@ -9062,34 +8394,20 @@ export function lowerBinary(lowerer, expr) {
|
|
|
9062
8394
|
}
|
|
9063
8395
|
}
|
|
9064
8396
|
}
|
|
9065
|
-
// `any`-origin
|
|
9066
|
-
//
|
|
9067
|
-
// here): JS's full coercion semantics (ToPrimitive, NaN, string +)
|
|
9068
|
-
// live in the engine — the dynamic-family fence, so the island
|
|
9069
|
-
// retry lifts the site. Genuine unknown keeps the SC1100 story.
|
|
8397
|
+
// Unsupported `any`-origin operations get their specific diagnostic;
|
|
8398
|
+
// unknown retains the narrowing diagnostic below.
|
|
9070
8399
|
if ((left.type.kind === "dyn" && lowerer.anyOrigin(expr.left)) ||
|
|
9071
8400
|
(right.type.kind === "dyn" && lowerer.anyOrigin(expr.right))) {
|
|
9072
8401
|
// `JSON.parse` and other checked-dynamic producers deliberately
|
|
9073
8402
|
// remain dyn when assigned to an `any` local: eagerly converting
|
|
9074
8403
|
// the binding would deep-copy its data and sever aliases. At an
|
|
9075
|
-
// operator
|
|
9076
|
-
// the engine apply JS's exact coercion semantics. Static builds
|
|
9077
|
-
// retain the SC2011 promise that --dynamic lifts this site.
|
|
9078
|
-
if (lowerer.dynamic)
|
|
9079
|
-
return lowerAnyBinaryInIsland(lowerer, expr, left, right, loc);
|
|
8404
|
+
// unsupported operator, require an explicit represented type.
|
|
9080
8405
|
lowerer.anyOpFence(`the '${ts.tokenToString(op) ?? ts.syntaxKindName(op)}' operator`, expr);
|
|
9081
8406
|
}
|
|
9082
8407
|
// tsc allows ===/!== on unknown (arithmetic/comparisons it rejects
|
|
9083
8408
|
// itself); a dynamic equality would need a dyn walk — validate first.
|
|
9084
8409
|
lowerer.unsupported("SC1100", expr, "operators on 'unknown' values");
|
|
9085
8410
|
}
|
|
9086
|
-
// Operators over 'any' execute in the island with JS-exact semantics
|
|
9087
|
-
// (ToPrimitive, NaN, string +): both operands marshal in, the engine
|
|
9088
|
-
// computes. Comparisons come back as static bools; arithmetic stays
|
|
9089
|
-
// an island value ('1 as any + "x"' is a string over there).
|
|
9090
|
-
if (left.type.kind === "jsval" || right.type.kind === "jsval") {
|
|
9091
|
-
return lowerAnyBinaryInIsland(lowerer, expr, left, right, loc);
|
|
9092
|
-
}
|
|
9093
8411
|
if (left.type.kind === "bigint" && right.type.kind === "bigint") {
|
|
9094
8412
|
const binary = {
|
|
9095
8413
|
[ts.SyntaxKind.PlusToken]: "bigint.add",
|
|
@@ -9787,16 +9105,6 @@ function lowerLogicalPair(lowerer, expr, left) {
|
|
|
9787
9105
|
loc,
|
|
9788
9106
|
};
|
|
9789
9107
|
}
|
|
9790
|
-
if (left.type.kind === "jsval" || right.type.kind === "jsval") {
|
|
9791
|
-
return {
|
|
9792
|
-
kind: "logical",
|
|
9793
|
-
op: op === ts.SyntaxKind.AmpersandAmpersandToken ? "&&" : "||",
|
|
9794
|
-
left: lowerer.jsvalIn(left, expr.left),
|
|
9795
|
-
right: lowerer.jsvalIn(right, expr.right),
|
|
9796
|
-
type: JSVAL,
|
|
9797
|
-
loc,
|
|
9798
|
-
};
|
|
9799
|
-
}
|
|
9800
9108
|
if (isJsSourceFile(expr.getSourceFile()) &&
|
|
9801
9109
|
op === ts.SyntaxKind.AmpersandAmpersandToken &&
|
|
9802
9110
|
left.type.kind === "union" &&
|
|
@@ -9847,10 +9155,7 @@ function lowerLogicalPair(lowerer, expr, left) {
|
|
|
9847
9155
|
left.type.kind === "union") {
|
|
9848
9156
|
const leftArms = lowerer.unions.get(left.type.unionId)?.arms;
|
|
9849
9157
|
const rightArms = right.type.kind === "union" ? lowerer.unions.get(right.type.unionId)?.arms : [right.type];
|
|
9850
|
-
const rightIsStatic = rightArms?.every((arm) => arm.kind !== "dyn" &&
|
|
9851
|
-
arm.kind !== "caught" &&
|
|
9852
|
-
arm.kind !== "jsval" &&
|
|
9853
|
-
arm.kind !== "void") ?? false;
|
|
9158
|
+
const rightIsStatic = rightArms?.every((arm) => arm.kind !== "dyn" && arm.kind !== "caught" && arm.kind !== "void") ?? false;
|
|
9854
9159
|
if (leftArms &&
|
|
9855
9160
|
rightArms &&
|
|
9856
9161
|
rightIsStatic &&
|
|
@@ -10187,12 +9492,6 @@ export function lowerCaughtTypeofTest(lowerer, expr, loc) {
|
|
|
10187
9492
|
}
|
|
10188
9493
|
return null;
|
|
10189
9494
|
}
|
|
10190
|
-
/** The static `typeof` answer for a union ARM's IR type, or null when the
|
|
10191
|
-
* arm has no fixed answer. Unit arms are known (`typeof undefined` is
|
|
10192
|
-
* "undefined", `typeof null` is "object" — JS's oldest wart, preserved
|
|
10193
|
-
* exactly); every ref kind is a JS object ("object"), func arms would be
|
|
10194
|
-
* "function" (unions never carry them — defensive), and the jsval/dyn/
|
|
10195
|
-
* caught/void/union kinds cannot appear as arms. */
|
|
10196
9495
|
function typeofAnswer(arm) {
|
|
10197
9496
|
switch (arm.kind) {
|
|
10198
9497
|
case "f64":
|
|
@@ -10757,22 +10056,7 @@ export function lowerInstanceOf(lowerer, expr, loc) {
|
|
|
10757
10056
|
const sockTest = lowerSocketInstanceOf(lowerer, expr, loc);
|
|
10758
10057
|
if (sockTest !== null)
|
|
10759
10058
|
return sockTest;
|
|
10760
|
-
|
|
10761
|
-
// exported class — the safeParse-style error narrowing): the spec's
|
|
10762
|
-
// InstanceofOperator runs in the engine (Symbol.hasInstance included;
|
|
10763
|
-
// a non-object RHS throws the engine's own TypeError, catchably).
|
|
10764
|
-
// The LHS marshals in — island handles pass through, static
|
|
10765
|
-
// primitives answer false exactly like the spec's non-object rule,
|
|
10766
|
-
// and unmarshalable statics (class instances, catch bindings — the
|
|
10767
|
-
// payload is a name/message snapshot, never the engine object) keep
|
|
10768
|
-
// jsvalIn's honest fences.
|
|
10769
|
-
if (lowerer.isIslandExpr(expr.right) && !lowerer.caughtLocalOf(expr.left)) {
|
|
10770
|
-
const left = lowerer.jsvalIn(lowerer.lowerExpr(expr.left), expr.left);
|
|
10771
|
-
const right = lowerer.lowerExpr(expr.right);
|
|
10772
|
-
return { kind: "jsOp", op: "instanceOf", args: [left, right], type: BOOL, loc };
|
|
10773
|
-
}
|
|
10774
|
-
if (!lowerer.dynamic &&
|
|
10775
|
-
(lowerer.isStdlibGlobal(expr.right, "Set") || lowerer.isStdlibGlobal(expr.right, "Map"))) {
|
|
10059
|
+
if (lowerer.isStdlibGlobal(expr.right, "Set") || lowerer.isStdlibGlobal(expr.right, "Map")) {
|
|
10776
10060
|
const collection = lowerer.isStdlibGlobal(expr.right, "Map") ? "map" : "set";
|
|
10777
10061
|
const value = lowerer.lowerExpr(expr.left);
|
|
10778
10062
|
if (value.type.kind === "union") {
|
|
@@ -10833,18 +10117,6 @@ export function lowerInstanceOf(lowerer, expr, loc) {
|
|
|
10833
10117
|
}
|
|
10834
10118
|
if (lowerer.isStdlibGlobal(expr.right, "WeakMap") ||
|
|
10835
10119
|
lowerer.isStdlibGlobal(expr.right, "WeakSet")) {
|
|
10836
|
-
if (lowerer.dynamic) {
|
|
10837
|
-
const value = lowerer.jsvalIn(lowerer.lowerExpr(expr.left), expr.left);
|
|
10838
|
-
const ctor = {
|
|
10839
|
-
kind: "jsOp",
|
|
10840
|
-
op: "globalGet",
|
|
10841
|
-
name: lowerer.isStdlibGlobal(expr.right, "WeakMap") ? "WeakMap" : "WeakSet",
|
|
10842
|
-
args: [],
|
|
10843
|
-
type: JSVAL,
|
|
10844
|
-
loc,
|
|
10845
|
-
};
|
|
10846
|
-
return { kind: "jsOp", op: "instanceOf", args: [value, ctor], type: BOOL, loc };
|
|
10847
|
-
}
|
|
10848
10120
|
const value = lowerer.coerceInto(expr.left, lowerer.lowerExpr(expr.left), DYN);
|
|
10849
10121
|
return {
|
|
10850
10122
|
kind: "libCall",
|
|
@@ -12701,12 +11973,11 @@ function lowerUnionKeyedRead(lowerer, expr, unionId, value, key, literalField) {
|
|
|
12701
11973
|
}
|
|
12702
11974
|
if (joinArms.length === 0)
|
|
12703
11975
|
return null;
|
|
12704
|
-
// The join must
|
|
12705
|
-
//
|
|
12706
|
-
// siblings). The caller owns the diagnostic for a refused join.
|
|
11976
|
+
// The join must satisfy native union invariants. The caller owns the
|
|
11977
|
+
// diagnostic when a container or opaque arm prevents that join.
|
|
12707
11978
|
if (joinArms.length > 1 &&
|
|
12708
11979
|
(!unionContainerArmsOk(joinArms) ||
|
|
12709
|
-
joinArms.some((a) => a.kind === "dyn" || a.kind === "
|
|
11980
|
+
joinArms.some((a) => a.kind === "dyn" || a.kind === "generator" || a.kind === "caught"))) {
|
|
12710
11981
|
return null;
|
|
12711
11982
|
}
|
|
12712
11983
|
joinArms.sort((a, b) => (typeKey(a) < typeKey(b) ? -1 : 1));
|
|
@@ -13723,6 +12994,7 @@ function lowerFieldCompoundValue(lowerer, access, op, rhsNode, loc) {
|
|
|
13723
12994
|
: lowerOptionalNumber(lowerer, rhs, loc);
|
|
13724
12995
|
let value;
|
|
13725
12996
|
const numericRead = lowerOptionalNumber(lowerer, read, loc, access);
|
|
12997
|
+
const bigintValue = rhsNode ? bigintCompoundValue(op, read, rhs, loc) : null;
|
|
13726
12998
|
if (op === "+" && read.type.kind === "string") {
|
|
13727
12999
|
value = {
|
|
13728
13000
|
kind: "strConcat",
|
|
@@ -13735,6 +13007,9 @@ function lowerFieldCompoundValue(lowerer, access, op, rhsNode, loc) {
|
|
|
13735
13007
|
else if (numericRead.type.kind === "f64" && numericRhs.type.kind === "f64") {
|
|
13736
13008
|
value = { kind: "bin", op, left: numericRead, right: numericRhs, type: F64, loc };
|
|
13737
13009
|
}
|
|
13010
|
+
else if (bigintValue) {
|
|
13011
|
+
value = bigintValue;
|
|
13012
|
+
}
|
|
13738
13013
|
else if (target.fieldType.kind === "dyn" && isJsSourceFile(access.getSourceFile())) {
|
|
13739
13014
|
const numeric = ["-", "*", "/", "%", "**"].includes(op);
|
|
13740
13015
|
const left = lowerer.coerceToExpected(read, DYN);
|