@scriptc/compiler 0.2.10 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ambient/scriptc-node-fallback.d.ts +2 -36
- 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/checked-narrows.test.js +1 -1
- package/dist/backend/llvm/classes.js +3 -9
- package/dist/backend/llvm/classes.js.map +1 -1
- package/dist/backend/llvm/classes.test.js +7 -7
- package/dist/backend/llvm/constant-callbacks.d.ts +1 -1
- package/dist/backend/llvm/constant-callbacks.js +3 -3
- 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.test.js +1 -1
- package/dist/backend/llvm/dyn.d.ts +0 -1
- package/dist/backend/llvm/dyn.js +0 -73
- package/dist/backend/llvm/dyn.js.map +1 -1
- package/dist/backend/llvm/emitter.d.ts +3 -17
- package/dist/backend/llvm/emitter.js +53 -181
- package/dist/backend/llvm/emitter.js.map +1 -1
- package/dist/backend/llvm/emitter.test.js +3 -3
- package/dist/backend/llvm/expr-async.test.js +1 -1
- package/dist/backend/llvm/expr-containers.js +12 -8
- package/dist/backend/llvm/expr-containers.js.map +1 -1
- 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 +0 -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 +13 -27
- package/dist/backend/llvm/expr-dynamic.js.map +1 -1
- package/dist/backend/llvm/expr-primitives.test.js +2 -2
- package/dist/backend/llvm/expr-stream-bridges.test.js +1 -1
- package/dist/backend/llvm/lib-dispatch.js +0 -1
- package/dist/backend/llvm/lib-dispatch.js.map +1 -1
- package/dist/backend/llvm/lib-filesystem.js +0 -13
- package/dist/backend/llvm/lib-filesystem.js.map +1 -1
- package/dist/backend/llvm/lib-shared.js +0 -8
- package/dist/backend/llvm/lib-shared.js.map +1 -1
- package/dist/backend/llvm/local-array-reads.test.js +1 -1
- package/dist/backend/llvm/local-union-storage.test.js +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 +24 -7
- package/dist/backend/llvm/map-read-lifetimes.test.js.map +1 -1
- package/dist/backend/llvm/shapes.js +1 -2
- 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 +1 -1
- package/dist/backend/llvm/string-construction.test.js +1 -1
- package/dist/backend/llvm/string-lifetimes.test.js +1 -1
- package/dist/backend/llvm/switch-dispatch.test.js +1 -1
- package/dist/backend/may-throw.js +0 -9
- 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 +2 -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.js +4 -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 +9 -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/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/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 +2 -10
- package/dist/frontend/lowering/containers/string-and-regexp.js.map +1 -1
- 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 +0 -1
- 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/lib-boundary.js +10 -77
- package/dist/frontend/lowering/lib-boundary.js.map +1 -1
- package/dist/frontend/lowering/lower-array-sort.js +1 -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 +47 -463
- package/dist/frontend/lowering/lower-calls.js.map +1 -1
- package/dist/frontend/lowering/lower-classes.js +11 -49
- 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-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 +50 -907
- package/dist/frontend/lowering/lower-exprs.js.map +1 -1
- package/dist/frontend/lowering/lower-functions.js +2 -5
- package/dist/frontend/lowering/lower-functions.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 +25 -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 +1 -3
- package/dist/frontend/lowering/lower-stream.js.map +1 -1
- package/dist/frontend/lowering/lowerer.d.ts +17 -151
- package/dist/frontend/lowering/lowerer.js +73 -770
- 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/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/sanitize-class-types.test.js +2 -2
- 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 +5 -65
- package/dist/frontend/lowering/surfaces.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 +42 -153
- 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 +0 -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 +1 -55
- 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/initializer-bindings.test.js +1 -1
- package/dist/ir/int32-slots.d.ts +3 -3
- package/dist/ir/int32-slots.js +5 -19
- package/dist/ir/int32-slots.js.map +1 -1
- package/dist/ir/int32-slots.test.js +1 -1
- package/dist/ir/ir.d.ts +12 -284
- package/dist/ir/ir.js +10 -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 +5 -41
- 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 +0 -21
- package/dist/ir/traverse.js.map +1 -1
- package/dist/ir/unshare.test.js +1 -1
- package/dist/ir/validate.js +9 -207
- package/dist/ir/validate.js.map +1 -1
- package/dist/ir/validate.test.js +6 -6
- 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 -88
- 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.d.ts +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.d.ts +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.d.ts +0 -1
- package/dist/native/runtime-typescript.test.js +0 -41
- package/dist/native/runtime-typescript.test.js.map +0 -1
|
@@ -25,10 +25,10 @@ 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
34
|
import { arrayValueRead, arrayValueStore, arrayValueType, lowerSafeIndexRead, tryLowerIndexTruthiness, tryLowerNumericIndexRead, lowerSafeBytesRead, } from "./array-values.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;
|
|
@@ -3196,9 +2775,8 @@ export function maybeNarrow(lowerer, expr, node) {
|
|
|
3196
2775
|
const narrowedTs = lowerer.typeOf(node);
|
|
3197
2776
|
const narrowed = lowerer.mapTypeOf(narrowedTs);
|
|
3198
2777
|
// `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
|
|
2778
|
+
// lib predicate narrows to `any[]`, possibly intersected with another
|
|
2779
|
+
// type. That mapping may be a checked value or a synthetic record, but
|
|
3202
2780
|
// the tag test proved the union's one array-valued arm, so bridge to it
|
|
3203
2781
|
// with the same trusted unionNarrow the mapped case below builds.
|
|
3204
2782
|
if (lowerer.checkerAnyArrayType(narrowedTs)) {
|
|
@@ -3743,18 +3321,6 @@ function volatileEnvRead(e) {
|
|
|
3743
3321
|
}
|
|
3744
3322
|
return null;
|
|
3745
3323
|
}
|
|
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
3324
|
function lowerLooseNullCompare(lowerer, expr, loc) {
|
|
3759
3325
|
const negated = expr.operatorToken.kind === ts.SyntaxKind.ExclamationEqualsToken;
|
|
3760
3326
|
const unwrap = (e) => ts.isParenthesizedExpression(e) ? unwrap(e.expression) : e;
|
|
@@ -3819,7 +3385,7 @@ function lowerLooseNullCompare(lowerer, expr, loc) {
|
|
|
3819
3385
|
loc,
|
|
3820
3386
|
};
|
|
3821
3387
|
}
|
|
3822
|
-
if (other.type.kind === "
|
|
3388
|
+
if (other.type.kind === "void") {
|
|
3823
3389
|
return null; // no static tag to test — keep the fence
|
|
3824
3390
|
}
|
|
3825
3391
|
// The env-volatility escape (see lowerUnitComparison): a narrowed
|
|
@@ -3976,10 +3542,8 @@ function isMemberReceiver(node) {
|
|
|
3976
3542
|
function lowerNullishPair(lowerer, expr, loc, left) {
|
|
3977
3543
|
if (left.type.kind === "dyn") {
|
|
3978
3544
|
// `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
|
|
3545
|
+
// runtime kind (scr_dyn_is_nullish — UNDEF/NULL take the default).
|
|
3546
|
+
// Both sides live in the checked-dynamic tree — the right converts through
|
|
3983
3547
|
// the usual boundary and evaluates lazily in its branch; a default
|
|
3984
3548
|
// with no dyn representation keeps the fence.
|
|
3985
3549
|
const right = lowerer.coerceToExpected(lowerer.lowerExpr(expr.right), DYN);
|
|
@@ -3988,13 +3552,6 @@ function lowerNullishPair(lowerer, expr, loc, left) {
|
|
|
3988
3552
|
}
|
|
3989
3553
|
return { kind: "nullish", left, right, type: DYN, loc };
|
|
3990
3554
|
}
|
|
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
3555
|
if (left.type.kind !== "union")
|
|
3999
3556
|
return left;
|
|
4000
3557
|
const def = lowerer.unions.get(left.type.unionId);
|
|
@@ -4438,10 +3995,6 @@ export function ensureBool(lowerer, e, node) {
|
|
|
4438
3995
|
// tag (plus the scalar payload for number/string).
|
|
4439
3996
|
return { kind: "dynTest", test: "truthy", value: e, type: BOOL, loc: e.loc };
|
|
4440
3997
|
}
|
|
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
3998
|
if (e.type.kind === "union") {
|
|
4446
3999
|
lowerer.requireTruthyUnion(e.type.unionId, node);
|
|
4447
4000
|
return { kind: "toBool", operand: e, type: BOOL, loc: e.loc };
|
|
@@ -4459,23 +4012,15 @@ export function ensureBool(lowerer, e, node) {
|
|
|
4459
4012
|
}
|
|
4460
4013
|
lowerer.badType(node, lowerer.typeOf(node));
|
|
4461
4014
|
}
|
|
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
4015
|
export function requireTruthyUnion(lowerer, unionId, node) {
|
|
4467
4016
|
const def = lowerer.unions.get(unionId);
|
|
4468
4017
|
if (def && def.arms.every((a) => a.kind !== "dyn" && a.kind !== "caught"))
|
|
4469
4018
|
return;
|
|
4470
4019
|
lowerer.unsupported("SC1090", node, `union-typed conditions with 'unknown' arms (${NARROW_FIRST})`);
|
|
4471
4020
|
}
|
|
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
4021
|
export function eqComparableUnion(lowerer, unionId) {
|
|
4477
4022
|
const def = lowerer.unions.get(unionId);
|
|
4478
|
-
return
|
|
4023
|
+
return !!def && def.arms.every((a) => a.kind !== "dyn" && a.kind !== "caught");
|
|
4479
4024
|
}
|
|
4480
4025
|
/** Property access on a string or array receiver: `.length` lowers to the
|
|
4481
4026
|
* matching intrinsic; a bare method reference (`const f = s.slice` — a
|
|
@@ -4883,9 +4428,7 @@ export function lowerIntrinsicProperty(lowerer, expr) {
|
|
|
4883
4428
|
return null;
|
|
4884
4429
|
}
|
|
4885
4430
|
if (kind === "f64") {
|
|
4886
|
-
|
|
4887
|
-
// bare reference has no value form regardless of --dynamic.
|
|
4888
|
-
if (own(ISLAND_SURFACE.number, name) !== undefined) {
|
|
4431
|
+
if (own(STDLIB_SURFACE.number, name) !== undefined) {
|
|
4889
4432
|
lowerer.unsupported("SC1090", expr, `number methods as values (call '${name}' directly)`);
|
|
4890
4433
|
}
|
|
4891
4434
|
return null;
|
|
@@ -4929,22 +4472,7 @@ export function lowerIntrinsicProperty(lowerer, expr) {
|
|
|
4929
4472
|
? lowerer.checkedNarrowCall(helper, receiver, present, locOf(expr.expression))
|
|
4930
4473
|
: lowerer.maybeNarrow(receiver, expr.expression);
|
|
4931
4474
|
}
|
|
4932
|
-
// An island handle behind a typed-array .d.ts surface: the engine
|
|
4933
4475
|
// 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
4476
|
return { kind: "bytesIntrinsic", method: name, receiver, args: [], type: F64, loc };
|
|
4949
4477
|
}
|
|
4950
4478
|
if (name === "byteOffset") {
|
|
@@ -5023,24 +4551,6 @@ export function lowerIntrinsicProperty(lowerer, expr) {
|
|
|
5023
4551
|
? lowerer.checkedNarrowCall(helper, receiver, present, locOf(expr.expression))
|
|
5024
4552
|
: lowerer.maybeNarrow(receiver, expr.expression);
|
|
5025
4553
|
}
|
|
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
4554
|
// A CHECKED-DYNAMIC value behind an array-typed checker spelling
|
|
5045
4555
|
// (`Object.keys(u).length` — the dyn walk answers a dyn array while
|
|
5046
4556
|
// tsc spells string[]): the runtime-world dispatch — a dyn keyed
|
|
@@ -5066,7 +4576,7 @@ export function lowerIntrinsicProperty(lowerer, expr) {
|
|
|
5066
4576
|
if (kind === "string"
|
|
5067
4577
|
? own(STR_METHODS, name) !== undefined ||
|
|
5068
4578
|
STRING_INDEX_METHODS.has(name) ||
|
|
5069
|
-
own(
|
|
4579
|
+
own(STDLIB_SURFACE.string, name) !== undefined
|
|
5070
4580
|
: ARRAY_METHODS.has(name)) {
|
|
5071
4581
|
lowerer.unsupported("SC1090", expr, `${kind} methods as values (call '${name}' directly)`);
|
|
5072
4582
|
}
|
|
@@ -5171,11 +4681,8 @@ export function lowerArrayLiteral(lowerer, expr, expected) {
|
|
|
5171
4681
|
!(ts.isIdentifier(el) && el.text === "undefined"));
|
|
5172
4682
|
const ownUnhelpful = mapped === null ||
|
|
5173
4683
|
mapped.kind === "dyn" ||
|
|
5174
|
-
// The checker
|
|
5175
|
-
// own type decides nothing either — nor does an island ('any')
|
|
5176
|
-
// residue under a STATIC union slot.
|
|
4684
|
+
// The checker may echo the context union rather than infer this literal.
|
|
5177
4685
|
mapped.kind === "union" ||
|
|
5178
|
-
mapped.kind === "jsval" ||
|
|
5179
4686
|
(mapped.kind === "array" && nonUnitElems && lowerer.unitOnlyElem(mapped.elem));
|
|
5180
4687
|
if (ownUnhelpful) {
|
|
5181
4688
|
const def = lowerer.unions.get(ctxUnion.unionId);
|
|
@@ -5223,11 +4730,9 @@ export function lowerArrayLiteral(lowerer, expr, expected) {
|
|
|
5223
4730
|
tryLowerExpression(lowerer, element.expression)?.type.kind === "dyn"))
|
|
5224
4731
|
mapped = DYN;
|
|
5225
4732
|
// 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") &&
|
|
4733
|
+
// (tsgo's readonly-[] TupleType conversion) uses a unit-element array,
|
|
4734
|
+
// mapType's own `[] as const` rule.
|
|
4735
|
+
if (mapped === null &&
|
|
5231
4736
|
expr.elements.length === 0 &&
|
|
5232
4737
|
(tsType.flags & ts.TypeFlags.Any) !== 0 &&
|
|
5233
4738
|
underConstAssertion(expr)) {
|
|
@@ -5257,22 +4762,7 @@ export function lowerArrayLiteral(lowerer, expr, expected) {
|
|
|
5257
4762
|
// tsc padded an UNDER-LENGTH literal against an optional-element
|
|
5258
4763
|
// tuple context (`options || []` with `options?: [string?,
|
|
5259
4764
|
// 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
|
-
}
|
|
4765
|
+
// literal spells fewer): no fixed shape holds it.
|
|
5276
4766
|
lowerer.badType(expr, tsType);
|
|
5277
4767
|
}
|
|
5278
4768
|
const byName = new Map(shape.fields.map((f) => [f.name, f.type]));
|
|
@@ -5375,10 +4865,9 @@ export function lowerArrayLiteral(lowerer, expr, expected) {
|
|
|
5375
4865
|
while (ts.isParenthesizedExpression(srcNode))
|
|
5376
4866
|
srcNode = srcNode.expression;
|
|
5377
4867
|
lowerer.fenceStaticHeadersIteration(el.expression);
|
|
5378
|
-
let src =
|
|
5379
|
-
(
|
|
5380
|
-
|
|
5381
|
-
: lowerer.lowerExpr(el.expression));
|
|
4868
|
+
let src = ts.isConditionalExpression(srcNode)
|
|
4869
|
+
? lowerTernary(lowerer, srcNode, type)
|
|
4870
|
+
: lowerer.lowerExpr(el.expression);
|
|
5382
4871
|
src = lowerCollectionSpread(lowerer, src, el.expression) ?? src;
|
|
5383
4872
|
// `[...new SymbolIterator]`: a CLASS ITERABLE drains through its
|
|
5384
4873
|
// own protocol into a fresh element array (classIteratorDrainCall
|
|
@@ -5933,33 +5422,6 @@ export function lowerElementAccess(lowerer, expr) {
|
|
|
5933
5422
|
return lowerer.maybeNarrow({ kind: "dynKeyGet", value: receiver, key, type: DYN, loc: locOf(expr) }, expr);
|
|
5934
5423
|
}
|
|
5935
5424
|
}
|
|
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
5425
|
// Typed-array element read `b[i]` — like arrayGet with a scalar
|
|
5964
5426
|
// result; any invalid index traps (the array discipline; JS would
|
|
5965
5427
|
// read undefined — divergence 4's policy).
|
|
@@ -5976,12 +5438,6 @@ export function lowerElementAccess(lowerer, expr) {
|
|
|
5976
5438
|
? lowerer.checkedNarrowCall(helper, recv, present, locOf(expr.expression))
|
|
5977
5439
|
: lowerer.maybeNarrow(recv, expr.expression);
|
|
5978
5440
|
}
|
|
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
5441
|
const index = lowerOptionalNumber(lowerer, lowerer.lowerExpr(expr.argumentExpression), locOf(expr.argumentExpression), expr.argumentExpression);
|
|
5986
5442
|
if (isJsSourceFile(expr.getSourceFile()) && recv.type.kind === "bytes") {
|
|
5987
5443
|
return {
|
|
@@ -6033,14 +5489,6 @@ export function lowerElementAccess(lowerer, expr) {
|
|
|
6033
5489
|
const shape = lowerer.shapes.get(receiverIr.shapeId);
|
|
6034
5490
|
if (shape?.tuple) {
|
|
6035
5491
|
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
5492
|
if (obj.type.kind === "dyn") {
|
|
6045
5493
|
// Object.entries over a checked value stores each pair in the
|
|
6046
5494
|
// dynamic tree even when the checker names a tuple type.
|
|
@@ -6091,14 +5539,6 @@ export function lowerElementAccess(lowerer, expr) {
|
|
|
6091
5539
|
: lowerer.maybeNarrow(get, expr);
|
|
6092
5540
|
}
|
|
6093
5541
|
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
5542
|
return lowerer.lowerRecordKeyRead(expr, receiverIr.shapeId, shape);
|
|
6103
5543
|
}
|
|
6104
5544
|
}
|
|
@@ -6325,14 +5765,6 @@ export function lowerElementAccess(lowerer, expr) {
|
|
|
6325
5765
|
? lowerer.checkedNarrowCall(helper, arr, present, locOf(expr.expression))
|
|
6326
5766
|
: lowerer.maybeNarrow(arr, expr.expression);
|
|
6327
5767
|
}
|
|
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
5768
|
// The checker sees an array but the VALUE lowered checked-dynamic (a
|
|
6337
5769
|
// jsdoc-typed default export from a .js module — signature 14): the
|
|
6338
5770
|
// read rides the dynCheck boundary when the array shape is one the checked-dynamic tree
|
|
@@ -6410,33 +5842,6 @@ export function lowerElementAccess(lowerer, expr) {
|
|
|
6410
5842
|
// narrows literal-index element accesses).
|
|
6411
5843
|
return lowerer.maybeNarrow({ kind: "arrayGet", arr, index, type: elemT, loc: locOf(expr) }, expr);
|
|
6412
5844
|
}
|
|
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
5845
|
/** `r[k]` over a (non-tuple) record shape. A LITERAL key naming a declared
|
|
6441
5846
|
* field is the bracket spelling of field access (the ONLY spelling tsc
|
|
6442
5847
|
* permits for signature-declared fields under
|
|
@@ -7190,39 +6595,6 @@ export function lowerElementWrite(lowerer, expr) {
|
|
|
7190
6595
|
if (receiver?.type.kind === "array")
|
|
7191
6596
|
receiverIr = receiver.type;
|
|
7192
6597
|
}
|
|
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
6598
|
// A checked-dynamic receiver TYPE (`unknown[]` and the collapsed
|
|
7227
6599
|
// `(string | object)[]` map to DYN wholesale now): the dyn keyed
|
|
7228
6600
|
// write — dyn.keySet. Number keys canonicalize through the JS-exact
|
|
@@ -7276,18 +6648,6 @@ export function lowerElementWrite(lowerer, expr) {
|
|
|
7276
6648
|
// the runtime coerces JS-exactly; invalid indices are ignored.
|
|
7277
6649
|
if (receiverIr?.kind === "bytes") {
|
|
7278
6650
|
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
6651
|
const index = lowerer.lowerExpr(target.argumentExpression);
|
|
7292
6652
|
if (index.type.kind === "dyn" && recv.type.kind === "bytes") {
|
|
7293
6653
|
return {
|
|
@@ -7306,24 +6666,11 @@ export function lowerElementWrite(lowerer, expr) {
|
|
|
7306
6666
|
// — literal indices only, like the read.
|
|
7307
6667
|
if (receiverIr?.kind === "record") {
|
|
7308
6668
|
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
6669
|
if (shape) {
|
|
7313
6670
|
const obj = lowerer.lowerExpr(target.expression);
|
|
7314
6671
|
if (hasClassPayload(lowerer, obj.type)) {
|
|
7315
6672
|
lowerer.unsupported("SC1090", target, "computed property writes through structural views of class instances (use a declared literal key)");
|
|
7316
6673
|
}
|
|
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
6674
|
// A record-mapped CHECKER type over a VALUE living in the checked-dynamic tree (a
|
|
7328
6675
|
// JS file-scope object-literal global): the checked-dynamic keyed
|
|
7329
6676
|
// write — dyn.keySet (later writes win, insertion order; Node's
|
|
@@ -7488,9 +6835,8 @@ export function lowerElementWrite(lowerer, expr) {
|
|
|
7488
6835
|
// arm above — later writes win in insertion order, number keys
|
|
7489
6836
|
// canonicalize through the JS-exact formatter (ToPropertyKey's string
|
|
7490
6837
|
// 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
|
|
6838
|
+
// receivers throw Node's TypeErrors at runtime. An unmapped checker type
|
|
6839
|
+
// probes the receiver's lowered representation: a dyn value takes the same
|
|
7494
6840
|
// write, anything else falls through to the fences.
|
|
7495
6841
|
if (receiverIr?.kind === "dyn" || receiverIr?.kind === "object" || receiverIr === null) {
|
|
7496
6842
|
const obj = receiverIr !== null
|
|
@@ -7530,19 +6876,6 @@ export function lowerElementWrite(lowerer, expr) {
|
|
|
7530
6876
|
lowerer.unsupported("SC1090", target, "assignment to non-array elements");
|
|
7531
6877
|
}
|
|
7532
6878
|
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
6879
|
if (arr.type.kind === "union" &&
|
|
7547
6880
|
lowerer.armTag(arr.type.unionId, UNDEFINED_T) >= 0 &&
|
|
7548
6881
|
receiverIr.kind === "array") {
|
|
@@ -7630,10 +6963,6 @@ export function ensureString(lowerer, e, node) {
|
|
|
7630
6963
|
const boxed = { kind: "dynFrom", value: e, type: DYN, loc: e.loc };
|
|
7631
6964
|
return { kind: "toString", operand: boxed, type: STRING, loc: e.loc };
|
|
7632
6965
|
}
|
|
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
6966
|
if (e.type.kind === "object") {
|
|
7638
6967
|
// String(err) / `${err}` uses the same dispatch as err.toString().
|
|
7639
6968
|
for (let c = lowerer.classes.get(e.type.className) ?? null; c; c = c.base) {
|
|
@@ -7875,12 +7204,8 @@ export function lowerAsExpression(lowerer, expr) {
|
|
|
7875
7204
|
const use = runtimeOptionalUseOf(expr);
|
|
7876
7205
|
if (inner.type.kind === "union" && runtimeOptionalAssertionErases(lowerer, expr, inner, use))
|
|
7877
7206
|
return inner;
|
|
7878
|
-
if (inner.type.kind !== "dyn"
|
|
7879
|
-
// A STATIC value cast `as any` is the explicit island entrance.
|
|
7207
|
+
if (inner.type.kind !== "dyn") {
|
|
7880
7208
|
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
7209
|
const target = lowerer.mapTypeOf(targetTs0);
|
|
7885
7210
|
if (target?.kind === "object") {
|
|
7886
7211
|
const asserted = checkedClassAssertion(lowerer, inner, target, locOf(expr));
|
|
@@ -7958,25 +7283,6 @@ export function lowerAsExpression(lowerer, expr) {
|
|
|
7958
7283
|
}
|
|
7959
7284
|
return inner; // erasure, unchanged
|
|
7960
7285
|
}
|
|
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
7286
|
const targetTs = lowerer.checker.getTypeFromTypeNode(expr.type);
|
|
7981
7287
|
const target = lowerer.mapTypeOf(targetTs) ?? dynFallbackType(lowerer, expr.type, targetTs);
|
|
7982
7288
|
if (!target)
|
|
@@ -8045,9 +7351,6 @@ export function lowerPrefixUnary(lowerer, expr) {
|
|
|
8045
7351
|
switch (expr.operator) {
|
|
8046
7352
|
case ts.SyntaxKind.MinusToken: {
|
|
8047
7353
|
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
7354
|
if (raw.type.kind === "bigint") {
|
|
8052
7355
|
return { kind: "libCall", fn: "bigint.neg", args: [raw], type: BIGINT_T, loc };
|
|
8053
7356
|
}
|
|
@@ -8069,9 +7372,6 @@ export function lowerPrefixUnary(lowerer, expr) {
|
|
|
8069
7372
|
// Unary + is ToNumber; on an already-number operand it's identity,
|
|
8070
7373
|
// and a STRING operand runs the runtime's ECMA-exact StringToNumber
|
|
8071
7374
|
// (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
7375
|
if (raw.type.kind === "string") {
|
|
8076
7376
|
return { kind: "libCall", fn: "num.fromString", args: [raw], type: F64, loc };
|
|
8077
7377
|
}
|
|
@@ -8363,38 +7663,6 @@ function seqExprSafeStmt(s) {
|
|
|
8363
7663
|
return false;
|
|
8364
7664
|
}
|
|
8365
7665
|
}
|
|
8366
|
-
/** Run one supported `any` binary operation in the island. Checked-dynamic
|
|
8367
|
-
* operands marshal in only after lowerBinary's identity-preserving native
|
|
8368
|
-
* cases have had their chance (notably dyn strict equality). */
|
|
8369
|
-
function lowerAnyBinaryInIsland(lowerer, expr, left, right, loc) {
|
|
8370
|
-
const op = expr.operatorToken.kind;
|
|
8371
|
-
const JS_BIN = {
|
|
8372
|
-
[ts.SyntaxKind.PlusToken]: "add",
|
|
8373
|
-
[ts.SyntaxKind.MinusToken]: "sub",
|
|
8374
|
-
[ts.SyntaxKind.AsteriskToken]: "mul",
|
|
8375
|
-
[ts.SyntaxKind.SlashToken]: "div",
|
|
8376
|
-
[ts.SyntaxKind.PercentToken]: "mod",
|
|
8377
|
-
[ts.SyntaxKind.AsteriskAsteriskToken]: "pow",
|
|
8378
|
-
[ts.SyntaxKind.LessThanToken]: "lt",
|
|
8379
|
-
[ts.SyntaxKind.LessThanEqualsToken]: "le",
|
|
8380
|
-
[ts.SyntaxKind.GreaterThanToken]: "gt",
|
|
8381
|
-
[ts.SyntaxKind.GreaterThanEqualsToken]: "ge",
|
|
8382
|
-
[ts.SyntaxKind.EqualsEqualsEqualsToken]: "eq",
|
|
8383
|
-
[ts.SyntaxKind.ExclamationEqualsEqualsToken]: "neq",
|
|
8384
|
-
};
|
|
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
|
-
return {
|
|
8391
|
-
kind: "jsOp",
|
|
8392
|
-
op: jop,
|
|
8393
|
-
args: [lowerer.jsvalIn(left, expr.left), lowerer.jsvalIn(right, expr.right)],
|
|
8394
|
-
type,
|
|
8395
|
-
loc,
|
|
8396
|
-
};
|
|
8397
|
-
}
|
|
8398
7666
|
export function lowerCompoundValueToTarget(lowerer, expr, compound, target) {
|
|
8399
7667
|
const loc = locOf(expr);
|
|
8400
7668
|
const read = {
|
|
@@ -8406,27 +7674,6 @@ export function lowerCompoundValueToTarget(lowerer, expr, compound, target) {
|
|
|
8406
7674
|
const rhs = lowerer.lowerExpr(expr.right);
|
|
8407
7675
|
const numericRead = lowerOptionalNumber(lowerer, read, loc);
|
|
8408
7676
|
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
7677
|
if (compound === "+" &&
|
|
8431
7678
|
(target.type.kind === "string" ||
|
|
8432
7679
|
(target.type.kind === "union" &&
|
|
@@ -8704,49 +7951,6 @@ export function lowerBinary(lowerer, expr) {
|
|
|
8704
7951
|
};
|
|
8705
7952
|
}
|
|
8706
7953
|
}
|
|
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
7954
|
// `h.k = v` on a CHECKED-DYNAMIC receiver in VALUE position
|
|
8751
7955
|
// (`var _ = module.exports = foo`): receiver first, then RHS
|
|
8752
7956
|
// (JS's reference-before-value order), the keyed write, and the
|
|
@@ -9062,34 +8266,20 @@ export function lowerBinary(lowerer, expr) {
|
|
|
9062
8266
|
}
|
|
9063
8267
|
}
|
|
9064
8268
|
}
|
|
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.
|
|
8269
|
+
// Unsupported `any`-origin operations get their specific diagnostic;
|
|
8270
|
+
// unknown retains the narrowing diagnostic below.
|
|
9070
8271
|
if ((left.type.kind === "dyn" && lowerer.anyOrigin(expr.left)) ||
|
|
9071
8272
|
(right.type.kind === "dyn" && lowerer.anyOrigin(expr.right))) {
|
|
9072
8273
|
// `JSON.parse` and other checked-dynamic producers deliberately
|
|
9073
8274
|
// remain dyn when assigned to an `any` local: eagerly converting
|
|
9074
8275
|
// 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);
|
|
8276
|
+
// unsupported operator, require an explicit represented type.
|
|
9080
8277
|
lowerer.anyOpFence(`the '${ts.tokenToString(op) ?? ts.syntaxKindName(op)}' operator`, expr);
|
|
9081
8278
|
}
|
|
9082
8279
|
// tsc allows ===/!== on unknown (arithmetic/comparisons it rejects
|
|
9083
8280
|
// itself); a dynamic equality would need a dyn walk — validate first.
|
|
9084
8281
|
lowerer.unsupported("SC1100", expr, "operators on 'unknown' values");
|
|
9085
8282
|
}
|
|
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
8283
|
if (left.type.kind === "bigint" && right.type.kind === "bigint") {
|
|
9094
8284
|
const binary = {
|
|
9095
8285
|
[ts.SyntaxKind.PlusToken]: "bigint.add",
|
|
@@ -9787,16 +8977,6 @@ function lowerLogicalPair(lowerer, expr, left) {
|
|
|
9787
8977
|
loc,
|
|
9788
8978
|
};
|
|
9789
8979
|
}
|
|
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
8980
|
if (isJsSourceFile(expr.getSourceFile()) &&
|
|
9801
8981
|
op === ts.SyntaxKind.AmpersandAmpersandToken &&
|
|
9802
8982
|
left.type.kind === "union" &&
|
|
@@ -9847,10 +9027,7 @@ function lowerLogicalPair(lowerer, expr, left) {
|
|
|
9847
9027
|
left.type.kind === "union") {
|
|
9848
9028
|
const leftArms = lowerer.unions.get(left.type.unionId)?.arms;
|
|
9849
9029
|
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;
|
|
9030
|
+
const rightIsStatic = rightArms?.every((arm) => arm.kind !== "dyn" && arm.kind !== "caught" && arm.kind !== "void") ?? false;
|
|
9854
9031
|
if (leftArms &&
|
|
9855
9032
|
rightArms &&
|
|
9856
9033
|
rightIsStatic &&
|
|
@@ -10187,12 +9364,6 @@ export function lowerCaughtTypeofTest(lowerer, expr, loc) {
|
|
|
10187
9364
|
}
|
|
10188
9365
|
return null;
|
|
10189
9366
|
}
|
|
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
9367
|
function typeofAnswer(arm) {
|
|
10197
9368
|
switch (arm.kind) {
|
|
10198
9369
|
case "f64":
|
|
@@ -10757,22 +9928,7 @@ export function lowerInstanceOf(lowerer, expr, loc) {
|
|
|
10757
9928
|
const sockTest = lowerSocketInstanceOf(lowerer, expr, loc);
|
|
10758
9929
|
if (sockTest !== null)
|
|
10759
9930
|
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"))) {
|
|
9931
|
+
if (lowerer.isStdlibGlobal(expr.right, "Set") || lowerer.isStdlibGlobal(expr.right, "Map")) {
|
|
10776
9932
|
const collection = lowerer.isStdlibGlobal(expr.right, "Map") ? "map" : "set";
|
|
10777
9933
|
const value = lowerer.lowerExpr(expr.left);
|
|
10778
9934
|
if (value.type.kind === "union") {
|
|
@@ -10833,18 +9989,6 @@ export function lowerInstanceOf(lowerer, expr, loc) {
|
|
|
10833
9989
|
}
|
|
10834
9990
|
if (lowerer.isStdlibGlobal(expr.right, "WeakMap") ||
|
|
10835
9991
|
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
9992
|
const value = lowerer.coerceInto(expr.left, lowerer.lowerExpr(expr.left), DYN);
|
|
10849
9993
|
return {
|
|
10850
9994
|
kind: "libCall",
|
|
@@ -12701,12 +11845,11 @@ function lowerUnionKeyedRead(lowerer, expr, unionId, value, key, literalField) {
|
|
|
12701
11845
|
}
|
|
12702
11846
|
if (joinArms.length === 0)
|
|
12703
11847
|
return null;
|
|
12704
|
-
// The join must
|
|
12705
|
-
//
|
|
12706
|
-
// siblings). The caller owns the diagnostic for a refused join.
|
|
11848
|
+
// The join must satisfy native union invariants. The caller owns the
|
|
11849
|
+
// diagnostic when a container or opaque arm prevents that join.
|
|
12707
11850
|
if (joinArms.length > 1 &&
|
|
12708
11851
|
(!unionContainerArmsOk(joinArms) ||
|
|
12709
|
-
joinArms.some((a) => a.kind === "dyn" || a.kind === "
|
|
11852
|
+
joinArms.some((a) => a.kind === "dyn" || a.kind === "generator" || a.kind === "caught"))) {
|
|
12710
11853
|
return null;
|
|
12711
11854
|
}
|
|
12712
11855
|
joinArms.sort((a, b) => (typeKey(a) < typeKey(b) ? -1 : 1));
|