@scriptc/compiler 0.4.6 → 0.4.7
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/node-fallback/events.d.ts +6 -1
- package/ambient/node-fallback/fs-promises.d.ts +1 -1
- package/ambient/node-fallback/fs.d.ts +54 -10
- package/ambient/node-fallback/http.d.ts +3 -1
- package/ambient/node-fallback/net.d.ts +19 -0
- package/ambient/node-fallback/querystring.d.ts +3 -3
- package/ambient/scriptc-node-fallback.d.ts +58 -13
- package/dist/backend/executable-features.js +13 -0
- package/dist/backend/executable-features.js.map +1 -1
- package/dist/backend/immutability.d.ts +12 -1
- package/dist/backend/immutability.js +50 -4
- package/dist/backend/immutability.js.map +1 -1
- package/dist/backend/immutability.test.js +95 -1
- package/dist/backend/immutability.test.js.map +1 -1
- package/dist/backend/library-pack.js +2 -0
- package/dist/backend/library-pack.js.map +1 -1
- package/dist/backend/linker.d.ts +11 -0
- package/dist/backend/linker.js +31 -3
- package/dist/backend/linker.js.map +1 -1
- package/dist/backend/lld.d.ts +7 -2
- package/dist/backend/lld.js +5 -3
- package/dist/backend/lld.js.map +1 -1
- package/dist/backend/lld.test.js +10 -4
- package/dist/backend/lld.test.js.map +1 -1
- package/dist/backend/llvm/constant-callbacks.test.js +50 -1
- package/dist/backend/llvm/constant-callbacks.test.js.map +1 -1
- package/dist/backend/llvm/cpu-dispatch.js +6 -5
- package/dist/backend/llvm/cpu-dispatch.js.map +1 -1
- package/dist/backend/llvm/dyn.d.ts +53 -1
- package/dist/backend/llvm/dyn.js +221 -9
- package/dist/backend/llvm/dyn.js.map +1 -1
- package/dist/backend/llvm/emit-function.js +1 -1
- package/dist/backend/llvm/emit-function.js.map +1 -1
- package/dist/backend/llvm/emit-module.js +148 -50
- package/dist/backend/llvm/emit-module.js.map +1 -1
- package/dist/backend/llvm/emit-statements.js +39 -19
- package/dist/backend/llvm/emit-statements.js.map +1 -1
- package/dist/backend/llvm/emitter.d.ts +29 -2
- package/dist/backend/llvm/emitter.js +86 -7
- package/dist/backend/llvm/emitter.js.map +1 -1
- package/dist/backend/llvm/expr-calls.d.ts +4 -1
- package/dist/backend/llvm/expr-calls.js +20 -4
- package/dist/backend/llvm/expr-calls.js.map +1 -1
- package/dist/backend/llvm/expr-dynamic.js +209 -16
- package/dist/backend/llvm/expr-dynamic.js.map +1 -1
- package/dist/backend/llvm/expr-primitives.js +94 -11
- package/dist/backend/llvm/expr-primitives.js.map +1 -1
- package/dist/backend/llvm/expr-stream-bridges.d.ts +8 -0
- package/dist/backend/llvm/expr-stream-bridges.js +42 -2
- package/dist/backend/llvm/expr-stream-bridges.js.map +1 -1
- package/dist/backend/llvm/expr-stream-callbacks.d.ts +16 -0
- package/dist/backend/llvm/expr-stream-callbacks.js +206 -20
- package/dist/backend/llvm/expr-stream-callbacks.js.map +1 -1
- package/dist/backend/llvm/integer-values.d.ts +2 -0
- package/dist/backend/llvm/integer-values.js +6 -0
- package/dist/backend/llvm/integer-values.js.map +1 -1
- package/dist/backend/llvm/js-ic.d.ts +38 -0
- package/dist/backend/llvm/js-ic.js +295 -1
- package/dist/backend/llvm/js-ic.js.map +1 -1
- package/dist/backend/llvm/lib-dispatch.js +20 -0
- package/dist/backend/llvm/lib-dispatch.js.map +1 -1
- package/dist/backend/llvm/lib-filesystem.js +116 -11
- package/dist/backend/llvm/lib-filesystem.js.map +1 -1
- package/dist/backend/llvm/lib-process.js +136 -24
- package/dist/backend/llvm/lib-process.js.map +1 -1
- package/dist/backend/llvm/lib-shared.js +70 -0
- package/dist/backend/llvm/lib-shared.js.map +1 -1
- package/dist/backend/llvm/lib-stream.js +67 -0
- package/dist/backend/llvm/lib-stream.js.map +1 -1
- package/dist/backend/llvm/loop-entry-versions.d.ts +2 -2
- package/dist/backend/llvm/loop-entry-versions.js +43 -21
- package/dist/backend/llvm/loop-entry-versions.js.map +1 -1
- package/dist/backend/llvm/loop-state.d.ts +7 -1
- package/dist/backend/llvm/loop-state.js +20 -2
- package/dist/backend/llvm/loop-state.js.map +1 -1
- package/dist/backend/llvm/map-number-lookup.d.ts +3 -1
- package/dist/backend/llvm/map-number-lookup.js +7 -3
- package/dist/backend/llvm/map-number-lookup.js.map +1 -1
- package/dist/backend/llvm/map-number-lookup.test.js +52 -11
- package/dist/backend/llvm/map-number-lookup.test.js.map +1 -1
- package/dist/backend/llvm/receiver-brackets.test.d.ts +1 -0
- package/dist/backend/llvm/receiver-brackets.test.js +68 -0
- package/dist/backend/llvm/receiver-brackets.test.js.map +1 -0
- package/dist/backend/llvm/record-views.d.ts +22 -2
- package/dist/backend/llvm/record-views.js +139 -10
- package/dist/backend/llvm/record-views.js.map +1 -1
- package/dist/backend/llvm/record-views.test.js +76 -0
- package/dist/backend/llvm/record-views.test.js.map +1 -1
- package/dist/backend/llvm/reference-writes.js +1 -0
- package/dist/backend/llvm/reference-writes.js.map +1 -1
- package/dist/backend/llvm/shapes.d.ts +3 -0
- package/dist/backend/llvm/shapes.js +18 -3
- package/dist/backend/llvm/shapes.js.map +1 -1
- package/dist/backend/llvm/shapes.test.js +4 -0
- package/dist/backend/llvm/shapes.test.js.map +1 -1
- package/dist/backend/llvm/speculative-integers.d.ts +10 -1
- package/dist/backend/llvm/speculative-integers.js +59 -8
- package/dist/backend/llvm/speculative-integers.js.map +1 -1
- package/dist/backend/llvm/unwind-abi.d.ts +3 -3
- package/dist/backend/llvm/unwind-abi.js +8 -3
- package/dist/backend/llvm/unwind-abi.js.map +1 -1
- package/dist/backend/llvm/walkers.js +1 -1
- package/dist/backend/llvm/walkers.js.map +1 -1
- package/dist/backend/native/contracts.d.ts +54 -0
- package/dist/backend/native/executable.js +87 -5
- package/dist/backend/native/executable.js.map +1 -1
- package/dist/backend/native/library.js +1 -1
- package/dist/backend/native/library.js.map +1 -1
- package/dist/backend/native/runtime-inputs.js +5 -1
- package/dist/backend/native/runtime-inputs.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-codegen.js +3 -0
- package/dist/backend/native-codegen.js.map +1 -1
- package/dist/backend/native-link-info-core.d.ts +43 -0
- package/dist/backend/native-link-info-core.js.map +1 -1
- package/dist/backend/native-link-info.js +1 -0
- package/dist/backend/native-link-info.js.map +1 -1
- package/dist/backend/native-profile.d.ts +4 -1
- package/dist/backend/native-profile.js +12 -1
- package/dist/backend/native-profile.js.map +1 -1
- package/dist/backend/native-profile.test.js +10 -0
- package/dist/backend/native-profile.test.js.map +1 -1
- package/dist/backend/publication.d.ts +4 -1
- package/dist/backend/publication.js +4 -2
- package/dist/backend/publication.js.map +1 -1
- package/dist/backend/runtime-abi.d.ts +2 -2
- package/dist/backend/runtime-abi.js +2 -2
- package/dist/backend/runtime-pack-core.d.ts +31 -7
- package/dist/backend/runtime-pack-core.js +21 -1
- package/dist/backend/runtime-pack-core.js.map +1 -1
- package/dist/backend/runtime-pack-native.d.ts +18 -1
- package/dist/backend/runtime-pack-native.js +138 -29
- package/dist/backend/runtime-pack-native.js.map +1 -1
- package/dist/backend/runtime-pack-native.test.js +166 -4
- package/dist/backend/runtime-pack-native.test.js.map +1 -1
- package/dist/backend/runtime-pack-targets.test.js +3 -1
- package/dist/backend/runtime-pack-targets.test.js.map +1 -1
- package/dist/backend/runtime-pack.d.ts +7 -0
- package/dist/backend/runtime-pack.js +25 -3
- package/dist/backend/runtime-pack.js.map +1 -1
- package/dist/backend/runtime-pack.test.js +3 -11
- package/dist/backend/runtime-pack.test.js.map +1 -1
- package/dist/backend/vendor-archives.d.ts +4 -1
- package/dist/backend/vendor-archives.js +264 -3
- package/dist/backend/vendor-archives.js.map +1 -1
- package/dist/backend/vendor-inputs.d.ts +36 -0
- package/dist/backend/vendor-inputs.js +42 -0
- package/dist/backend/vendor-inputs.js.map +1 -1
- package/dist/backend/vendor-inputs.test.js +28 -1
- package/dist/backend/vendor-inputs.test.js.map +1 -1
- package/dist/backend/warm-cache.js +2 -0
- package/dist/backend/warm-cache.js.map +1 -1
- package/dist/compat/fetch-profile.d.ts +7 -1
- package/dist/compat/fetch-profile.js +23 -10
- package/dist/compat/fetch-profile.js.map +1 -1
- package/dist/compile-types.d.ts +7 -0
- package/dist/contracts/check.d.ts +3 -0
- package/dist/contracts/check.js +18 -5
- package/dist/contracts/check.js.map +1 -1
- package/dist/coverage/surface-manifest.js +1 -1
- package/dist/coverage/surface-manifest.js.map +1 -1
- package/dist/diagnostics/codes.d.ts +6 -0
- package/dist/diagnostics/codes.js +6 -0
- package/dist/diagnostics/codes.js.map +1 -1
- package/dist/diagnostics/diagnostic.d.ts +50 -0
- package/dist/diagnostics/diagnostic.js +142 -3
- package/dist/diagnostics/diagnostic.js.map +1 -1
- package/dist/diagnostics/dynamic-tier.js +3 -1
- package/dist/diagnostics/dynamic-tier.js.map +1 -1
- package/dist/executable/executable-cache.d.ts +29 -0
- package/dist/executable/executable-cache.js +18 -0
- package/dist/executable/executable-cache.js.map +1 -1
- package/dist/executable/executable-cache.test.js +5 -1
- package/dist/executable/executable-cache.test.js.map +1 -1
- package/dist/executable/prepare.d.ts +13 -3
- package/dist/executable/prepare.js +271 -18
- package/dist/executable/prepare.js.map +1 -1
- package/dist/frontend/early-errors.d.ts +14 -0
- package/dist/frontend/early-errors.js +305 -0
- package/dist/frontend/early-errors.js.map +1 -0
- package/dist/frontend/early-errors.test.d.ts +1 -0
- package/dist/frontend/early-errors.test.js +42 -0
- package/dist/frontend/early-errors.test.js.map +1 -0
- package/dist/frontend/inferred-js-diagnostics.test.js +23 -0
- package/dist/frontend/inferred-js-diagnostics.test.js.map +1 -1
- package/dist/frontend/input-tracker.d.ts +47 -0
- package/dist/frontend/input-tracker.js +173 -36
- package/dist/frontend/input-tracker.js.map +1 -1
- package/dist/frontend/input-tracker.test.js +86 -2
- package/dist/frontend/input-tracker.test.js.map +1 -1
- package/dist/frontend/js-inference.d.ts +2 -0
- package/dist/frontend/js-inference.js +18 -0
- package/dist/frontend/js-inference.js.map +1 -0
- package/dist/frontend/lowering/binding-analysis.d.ts +2 -1
- package/dist/frontend/lowering/binding-analysis.js +65 -1
- package/dist/frontend/lowering/binding-analysis.js.map +1 -1
- package/dist/frontend/lowering/builtin-calls.js +9 -0
- package/dist/frontend/lowering/builtin-calls.js.map +1 -1
- package/dist/frontend/lowering/builtin-namespaces.d.ts +1 -1
- package/dist/frontend/lowering/builtin-namespaces.js +19 -2
- package/dist/frontend/lowering/builtin-namespaces.js.map +1 -1
- package/dist/frontend/lowering/builtins/child-process-methods.d.ts +7 -0
- package/dist/frontend/lowering/builtins/child-process-methods.js +50 -10
- package/dist/frontend/lowering/builtins/child-process-methods.js.map +1 -1
- package/dist/frontend/lowering/builtins/child-process.js +5 -1
- package/dist/frontend/lowering/builtins/child-process.js.map +1 -1
- package/dist/frontend/lowering/builtins/dates.d.ts +1 -1
- package/dist/frontend/lowering/builtins/dates.js +23 -1
- package/dist/frontend/lowering/builtins/dates.js.map +1 -1
- package/dist/frontend/lowering/builtins/environment.d.ts +55 -0
- package/dist/frontend/lowering/builtins/environment.js +213 -2
- package/dist/frontend/lowering/builtins/environment.js.map +1 -1
- package/dist/frontend/lowering/builtins/filesystem-calls.js +47 -16
- package/dist/frontend/lowering/builtins/filesystem-calls.js.map +1 -1
- package/dist/frontend/lowering/builtins/filesystem.d.ts +25 -7
- package/dist/frontend/lowering/builtins/filesystem.js +185 -16
- package/dist/frontend/lowering/builtins/filesystem.js.map +1 -1
- package/dist/frontend/lowering/builtins/module-calls.js +39 -2
- package/dist/frontend/lowering/builtins/module-calls.js.map +1 -1
- package/dist/frontend/lowering/builtins/module-resolution.d.ts +8 -0
- package/dist/frontend/lowering/builtins/module-resolution.js +31 -5
- package/dist/frontend/lowering/builtins/module-resolution.js.map +1 -1
- package/dist/frontend/lowering/builtins/operating-system.d.ts +3 -2
- package/dist/frontend/lowering/builtins/operating-system.js +5 -4
- package/dist/frontend/lowering/builtins/operating-system.js.map +1 -1
- package/dist/frontend/lowering/builtins/process.d.ts +17 -1
- package/dist/frontend/lowering/builtins/process.js +285 -19
- package/dist/frontend/lowering/builtins/process.js.map +1 -1
- package/dist/frontend/lowering/builtins/querystring.d.ts +8 -0
- package/dist/frontend/lowering/builtins/querystring.js +202 -18
- package/dist/frontend/lowering/builtins/querystring.js.map +1 -1
- package/dist/frontend/lowering/builtins/readline.js +21 -3
- package/dist/frontend/lowering/builtins/readline.js.map +1 -1
- package/dist/frontend/lowering/builtins/reflection.js +60 -1
- package/dist/frontend/lowering/builtins/reflection.js.map +1 -1
- package/dist/frontend/lowering/builtins/text-codecs.js +208 -59
- package/dist/frontend/lowering/builtins/text-codecs.js.map +1 -1
- package/dist/frontend/lowering/builtins/url.js +20 -1
- package/dist/frontend/lowering/builtins/url.js.map +1 -1
- package/dist/frontend/lowering/builtins/v8.d.ts +5 -5
- package/dist/frontend/lowering/builtins/v8.js +7 -5
- package/dist/frontend/lowering/builtins/v8.js.map +1 -1
- package/dist/frontend/lowering/builtins/web-streams-dyn.d.ts +17 -2
- package/dist/frontend/lowering/builtins/web-streams-dyn.js +97 -9
- package/dist/frontend/lowering/builtins/web-streams-dyn.js.map +1 -1
- package/dist/frontend/lowering/call-signatures.js +77 -0
- package/dist/frontend/lowering/call-signatures.js.map +1 -1
- package/dist/frontend/lowering/cjs-exports-object.d.ts +3 -0
- package/dist/frontend/lowering/cjs-exports-object.js +1 -1
- package/dist/frontend/lowering/cjs-exports-object.js.map +1 -1
- package/dist/frontend/lowering/cjs-inline-require.js +5 -0
- package/dist/frontend/lowering/cjs-inline-require.js.map +1 -1
- package/dist/frontend/lowering/class-dynamic-dispatch.d.ts +5 -0
- package/dist/frontend/lowering/class-dynamic-dispatch.js +114 -0
- package/dist/frontend/lowering/class-dynamic-dispatch.js.map +1 -1
- package/dist/frontend/lowering/class-protocols.js +59 -10
- package/dist/frontend/lowering/class-protocols.js.map +1 -1
- package/dist/frontend/lowering/class-runtime-statics.js +15 -0
- package/dist/frontend/lowering/class-runtime-statics.js.map +1 -1
- package/dist/frontend/lowering/class-views.d.ts +13 -0
- package/dist/frontend/lowering/class-views.js +51 -0
- package/dist/frontend/lowering/class-views.js.map +1 -0
- package/dist/frontend/lowering/coercions/function-adapters.d.ts +15 -1
- package/dist/frontend/lowering/coercions/function-adapters.js +54 -10
- package/dist/frontend/lowering/coercions/function-adapters.js.map +1 -1
- package/dist/frontend/lowering/coercions/state.d.ts +7 -0
- package/dist/frontend/lowering/coercions/state.js +7 -0
- package/dist/frontend/lowering/coercions/state.js.map +1 -1
- package/dist/frontend/lowering/coercions/structural-plans.js +60 -3
- package/dist/frontend/lowering/coercions/structural-plans.js.map +1 -1
- package/dist/frontend/lowering/coercions/structural.js +29 -1
- package/dist/frontend/lowering/coercions/structural.js.map +1 -1
- package/dist/frontend/lowering/containers/array-callbacks.d.ts +8 -1
- package/dist/frontend/lowering/containers/array-callbacks.js +132 -28
- package/dist/frontend/lowering/containers/array-callbacks.js.map +1 -1
- package/dist/frontend/lowering/containers/array-construction.js +16 -5
- package/dist/frontend/lowering/containers/array-construction.js.map +1 -1
- package/dist/frontend/lowering/containers/array-methods.js +16 -0
- package/dist/frontend/lowering/containers/array-methods.js.map +1 -1
- package/dist/frontend/lowering/containers/bytes.js +4 -0
- package/dist/frontend/lowering/containers/bytes.js.map +1 -1
- package/dist/frontend/lowering/containers/callback-arguments.d.ts +11 -0
- package/dist/frontend/lowering/containers/callback-arguments.js +53 -0
- package/dist/frontend/lowering/containers/callback-arguments.js.map +1 -1
- package/dist/frontend/lowering/containers/filter-predicates.d.ts +10 -0
- package/dist/frontend/lowering/containers/filter-predicates.js +69 -3
- package/dist/frontend/lowering/containers/filter-predicates.js.map +1 -1
- package/dist/frontend/lowering/containers/indexed-objects.js +46 -2
- package/dist/frontend/lowering/containers/indexed-objects.js.map +1 -1
- package/dist/frontend/lowering/expressions/array-literals.d.ts +14 -0
- package/dist/frontend/lowering/expressions/array-literals.js +26 -10
- package/dist/frontend/lowering/expressions/array-literals.js.map +1 -1
- package/dist/frontend/lowering/expressions/binary.js +104 -12
- package/dist/frontend/lowering/expressions/binary.js.map +1 -1
- package/dist/frontend/lowering/expressions/element-access.js +121 -4
- package/dist/frontend/lowering/expressions/element-access.js.map +1 -1
- package/dist/frontend/lowering/expressions/identifiers.js +143 -3
- package/dist/frontend/lowering/expressions/identifiers.js.map +1 -1
- package/dist/frontend/lowering/expressions/keyed-field-targets.d.ts +11 -1
- package/dist/frontend/lowering/expressions/keyed-field-targets.js +22 -1
- package/dist/frontend/lowering/expressions/keyed-field-targets.js.map +1 -1
- package/dist/frontend/lowering/expressions/narrowing.js +25 -1
- package/dist/frontend/lowering/expressions/narrowing.js.map +1 -1
- package/dist/frontend/lowering/expressions/object-literals.d.ts +5 -1
- package/dist/frontend/lowering/expressions/object-literals.js +778 -229
- package/dist/frontend/lowering/expressions/object-literals.js.map +1 -1
- package/dist/frontend/lowering/expressions/optional-chains.js +66 -20
- package/dist/frontend/lowering/expressions/optional-chains.js.map +1 -1
- package/dist/frontend/lowering/expressions/property-access.d.ts +31 -0
- package/dist/frontend/lowering/expressions/property-access.js +796 -12
- package/dist/frontend/lowering/expressions/property-access.js.map +1 -1
- package/dist/frontend/lowering/expressions/relational.js +29 -1
- package/dist/frontend/lowering/expressions/relational.js.map +1 -1
- package/dist/frontend/lowering/expressions/typeof.js +17 -0
- package/dist/frontend/lowering/expressions/typeof.js.map +1 -1
- package/dist/frontend/lowering/expressions/updates.js +132 -17
- package/dist/frontend/lowering/expressions/updates.js.map +1 -1
- package/dist/frontend/lowering/frozen-records.d.ts +6 -0
- package/dist/frontend/lowering/frozen-records.js +10 -4
- package/dist/frontend/lowering/frozen-records.js.map +1 -1
- package/dist/frontend/lowering/frozen-records.test.d.ts +1 -0
- package/dist/frontend/lowering/frozen-records.test.js +44 -0
- package/dist/frontend/lowering/frozen-records.test.js.map +1 -0
- package/dist/frontend/lowering/function-names.d.ts +9 -0
- package/dist/frontend/lowering/function-names.js +95 -0
- package/dist/frontend/lowering/function-names.js.map +1 -0
- package/dist/frontend/lowering/function-returns.js +5 -3
- package/dist/frontend/lowering/function-returns.js.map +1 -1
- package/dist/frontend/lowering/generic-functions.d.ts +49 -0
- package/dist/frontend/lowering/generic-functions.js +365 -7
- package/dist/frontend/lowering/generic-functions.js.map +1 -1
- package/dist/frontend/lowering/global-values.d.ts +9 -0
- package/dist/frontend/lowering/global-values.js +44 -0
- package/dist/frontend/lowering/global-values.js.map +1 -1
- package/dist/frontend/lowering/handle-properties.js +34 -1
- package/dist/frontend/lowering/handle-properties.js.map +1 -1
- package/dist/frontend/lowering/key-order-witness.d.ts +54 -0
- package/dist/frontend/lowering/key-order-witness.js +546 -5
- package/dist/frontend/lowering/key-order-witness.js.map +1 -1
- package/dist/frontend/lowering/lib-boundary.js +14 -0
- package/dist/frontend/lowering/lib-boundary.js.map +1 -1
- package/dist/frontend/lowering/lower-assert.js +110 -1
- package/dist/frontend/lowering/lower-assert.js.map +1 -1
- package/dist/frontend/lowering/lower-builtin-values.d.ts +36 -6
- package/dist/frontend/lowering/lower-builtin-values.js +332 -58
- package/dist/frontend/lowering/lower-builtin-values.js.map +1 -1
- package/dist/frontend/lowering/lower-calls.d.ts +22 -1
- package/dist/frontend/lowering/lower-calls.js +427 -48
- package/dist/frontend/lowering/lower-calls.js.map +1 -1
- package/dist/frontend/lowering/lower-calls.test.d.ts +1 -0
- package/dist/frontend/lowering/lower-calls.test.js +78 -0
- package/dist/frontend/lowering/lower-calls.test.js.map +1 -0
- package/dist/frontend/lowering/lower-classes.d.ts +16 -5
- package/dist/frontend/lowering/lower-classes.js +168 -51
- package/dist/frontend/lowering/lower-classes.js.map +1 -1
- package/dist/frontend/lowering/lower-event-emitter.d.ts +9 -0
- package/dist/frontend/lowering/lower-event-emitter.js +383 -41
- package/dist/frontend/lowering/lower-event-emitter.js.map +1 -1
- package/dist/frontend/lowering/lower-exprs.d.ts +14 -0
- package/dist/frontend/lowering/lower-exprs.js +25 -0
- package/dist/frontend/lowering/lower-exprs.js.map +1 -1
- package/dist/frontend/lowering/lower-functions.js +2 -0
- package/dist/frontend/lowering/lower-functions.js.map +1 -1
- package/dist/frontend/lowering/lower-inspect.js +80 -33
- package/dist/frontend/lowering/lower-inspect.js.map +1 -1
- package/dist/frontend/lowering/lower-modules.js +87 -25
- package/dist/frontend/lowering/lower-modules.js.map +1 -1
- package/dist/frontend/lowering/lower-node-island.d.ts +35 -4
- package/dist/frontend/lowering/lower-node-island.js +456 -61
- package/dist/frontend/lowering/lower-node-island.js.map +1 -1
- package/dist/frontend/lowering/lower-server.js +160 -9
- package/dist/frontend/lowering/lower-server.js.map +1 -1
- package/dist/frontend/lowering/lower-shared-modules.js +13 -1
- package/dist/frontend/lowering/lower-shared-modules.js.map +1 -1
- package/dist/frontend/lowering/lower-stdlib.d.ts +3 -2
- package/dist/frontend/lowering/lower-stdlib.js +32 -18
- package/dist/frontend/lowering/lower-stdlib.js.map +1 -1
- package/dist/frontend/lowering/lower-stmts.d.ts +21 -4
- package/dist/frontend/lowering/lower-stmts.js +580 -103
- package/dist/frontend/lowering/lower-stmts.js.map +1 -1
- package/dist/frontend/lowering/lower-stream.js +126 -8
- package/dist/frontend/lowering/lower-stream.js.map +1 -1
- package/dist/frontend/lowering/lower-timers.js +133 -21
- package/dist/frontend/lowering/lower-timers.js.map +1 -1
- package/dist/frontend/lowering/lowerer.d.ts +139 -3
- package/dist/frontend/lowering/lowerer.js +579 -43
- package/dist/frontend/lowering/lowerer.js.map +1 -1
- package/dist/frontend/lowering/lowerer.test.js +1 -1
- package/dist/frontend/lowering/lowerer.test.js.map +1 -1
- package/dist/frontend/lowering/module-namespace-elements.js +15 -0
- package/dist/frontend/lowering/module-namespace-elements.js.map +1 -1
- package/dist/frontend/lowering/new-target.js +2 -2
- package/dist/frontend/lowering/nullish-empty-pattern.d.ts +17 -0
- package/dist/frontend/lowering/nullish-empty-pattern.js +118 -0
- package/dist/frontend/lowering/nullish-empty-pattern.js.map +1 -0
- package/dist/frontend/lowering/partial-assertions.d.ts +39 -0
- package/dist/frontend/lowering/partial-assertions.js +195 -0
- package/dist/frontend/lowering/partial-assertions.js.map +1 -0
- package/dist/frontend/lowering/primitive-wrappers.d.ts +34 -0
- package/dist/frontend/lowering/primitive-wrappers.js +220 -0
- package/dist/frontend/lowering/primitive-wrappers.js.map +1 -0
- package/dist/frontend/lowering/private-statics.d.ts +46 -0
- package/dist/frontend/lowering/private-statics.js +322 -0
- package/dist/frontend/lowering/private-statics.js.map +1 -0
- package/dist/frontend/lowering/record-sources.d.ts +12 -1
- package/dist/frontend/lowering/record-sources.js +60 -0
- package/dist/frontend/lowering/record-sources.js.map +1 -1
- package/dist/frontend/lowering/strict-equality.d.ts +4 -0
- package/dist/frontend/lowering/strict-equality.js +14 -0
- package/dist/frontend/lowering/strict-equality.js.map +1 -1
- package/dist/frontend/lowering/surfaces.d.ts +27 -0
- package/dist/frontend/lowering/surfaces.js +135 -62
- package/dist/frontend/lowering/surfaces.js.map +1 -1
- package/dist/frontend/lowering/unit-journal.d.ts +128 -17
- package/dist/frontend/lowering/unit-journal.js +310 -53
- package/dist/frontend/lowering/unit-journal.js.map +1 -1
- package/dist/frontend/lowering/unit-journal.test.js +91 -3
- package/dist/frontend/lowering/unit-journal.test.js.map +1 -1
- package/dist/frontend/lowering/unit-reuse.d.ts +92 -0
- package/dist/frontend/lowering/unit-reuse.js +1008 -0
- package/dist/frontend/lowering/unit-reuse.js.map +1 -0
- package/dist/frontend/lowering/width-lift.d.ts +12 -0
- package/dist/frontend/npm-file-import.test.d.ts +1 -0
- package/dist/frontend/npm-file-import.test.js +76 -0
- package/dist/frontend/npm-file-import.test.js.map +1 -0
- package/dist/frontend/npm-static.js +17 -2
- package/dist/frontend/npm-static.js.map +1 -1
- package/dist/frontend/npm.d.ts +9 -0
- package/dist/frontend/npm.js +82 -0
- package/dist/frontend/npm.js.map +1 -1
- package/dist/frontend/pipeline-native.js +2 -1
- package/dist/frontend/pipeline-native.js.map +1 -1
- package/dist/frontend/pipeline.d.ts +4 -0
- package/dist/frontend/pipeline.js +68 -7
- package/dist/frontend/pipeline.js.map +1 -1
- package/dist/frontend/program-node.d.ts +3 -0
- package/dist/frontend/program-node.js +13 -6
- package/dist/frontend/program-node.js.map +1 -1
- package/dist/frontend/program.d.ts +9 -0
- package/dist/frontend/program.js +159 -7
- package/dist/frontend/program.js.map +1 -1
- package/dist/frontend/provenance-core.js +4 -0
- package/dist/frontend/provenance-core.js.map +1 -1
- package/dist/frontend/services.d.ts +14 -0
- package/dist/frontend/services.js +52 -2
- package/dist/frontend/services.js.map +1 -1
- package/dist/frontend/services.test.js +61 -1
- package/dist/frontend/services.test.js.map +1 -1
- package/dist/frontend/shape-inference/analyze.d.ts +5 -0
- package/dist/frontend/shape-inference/analyze.js +104 -4
- package/dist/frontend/shape-inference/analyze.js.map +1 -1
- package/dist/frontend/shape-inference/domain.js +0 -1
- package/dist/frontend/shape-inference/domain.js.map +1 -1
- package/dist/frontend/shape-inference/index.js +5 -1
- package/dist/frontend/shape-inference/index.js.map +1 -1
- package/dist/frontend/shape-inference/memo.d.ts +2 -1
- package/dist/frontend/shape-inference/memo.js +6 -2
- package/dist/frontend/shape-inference/memo.js.map +1 -1
- package/dist/frontend/shape-inference/overlay.d.ts +1 -1
- package/dist/frontend/shape-inference/overlay.js +116 -2
- package/dist/frontend/shape-inference/overlay.js.map +1 -1
- package/dist/frontend/shape-inference/static-objects.js +11 -6
- package/dist/frontend/shape-inference/static-objects.js.map +1 -1
- package/dist/frontend/source-phase-imports.test.d.ts +1 -0
- package/dist/frontend/source-phase-imports.test.js +37 -0
- package/dist/frontend/source-phase-imports.test.js.map +1 -0
- package/dist/frontend/ts7/ast-node.d.ts +6 -1
- package/dist/frontend/ts7/ast-node.js +12 -0
- package/dist/frontend/ts7/ast-node.js.map +1 -1
- package/dist/frontend/ts7/ast-wire-protocols.test.js +11 -3
- package/dist/frontend/ts7/ast-wire-protocols.test.js.map +1 -1
- package/dist/frontend/ts7/ast-wire.js +3 -5
- package/dist/frontend/ts7/ast-wire.js.map +1 -1
- package/dist/frontend/ts7/checker-backend.d.ts +13 -0
- package/dist/frontend/ts7/checker-backend.js +84 -2
- package/dist/frontend/ts7/checker-backend.js.map +1 -1
- package/dist/frontend/ts7/checker-backend.test.js +126 -2
- package/dist/frontend/ts7/checker-backend.test.js.map +1 -1
- package/dist/frontend/ts7/program-host.d.ts +22 -1
- package/dist/frontend/ts7/program-host.js +49 -4
- package/dist/frontend/ts7/program-host.js.map +1 -1
- package/dist/frontend/ts7/program-host.test.js +83 -0
- package/dist/frontend/ts7/program-host.test.js.map +1 -1
- package/dist/frontend/ts7/rpc-process.d.ts +16 -1
- package/dist/frontend/ts7/rpc-process.js +170 -92
- package/dist/frontend/ts7/rpc-process.js.map +1 -1
- package/dist/frontend/ts7/rpc-process.test.js +49 -21
- package/dist/frontend/ts7/rpc-process.test.js.map +1 -1
- package/dist/frontend/tsc-codes.js +70 -0
- package/dist/frontend/tsc-codes.js.map +1 -1
- package/dist/frontend/type-mapper.d.ts +7 -2
- package/dist/frontend/type-mapper.js +148 -1
- package/dist/frontend/type-mapper.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +152 -8
- 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/build.d.ts +3 -2
- package/dist/ir/build.js +4 -2
- package/dist/ir/build.js.map +1 -1
- package/dist/ir/builtin-effects.js +53 -0
- package/dist/ir/builtin-effects.js.map +1 -1
- package/dist/ir/builtin-signatures.d.ts +1 -1
- package/dist/ir/builtin-signatures.js +211 -10
- package/dist/ir/builtin-signatures.js.map +1 -1
- package/dist/ir/codec.d.ts +82 -0
- package/dist/ir/codec.generated.d.ts +13 -0
- package/dist/ir/codec.generated.js +5274 -0
- package/dist/ir/codec.generated.js.map +1 -0
- package/dist/ir/codec.js +325 -0
- package/dist/ir/codec.js.map +1 -0
- package/dist/ir/codec.test.d.ts +1 -0
- package/dist/ir/codec.test.js +225 -0
- package/dist/ir/codec.test.js.map +1 -0
- package/dist/ir/fields.generated.d.ts +20 -10
- package/dist/ir/fields.generated.js +1031 -11
- package/dist/ir/fields.generated.js.map +1 -1
- package/dist/ir/fields.test.js +46 -2
- package/dist/ir/fields.test.js.map +1 -1
- package/dist/ir/function-references.d.ts +5 -4
- package/dist/ir/function-references.js +8 -4
- package/dist/ir/function-references.js.map +1 -1
- package/dist/ir/function-references.test.js +7 -0
- package/dist/ir/function-references.test.js.map +1 -1
- package/dist/ir/inline-array-sources.js +4 -1
- package/dist/ir/inline-array-sources.js.map +1 -1
- package/dist/ir/inline-array-views.d.ts +13 -0
- package/dist/ir/inline-array-views.js +944 -0
- package/dist/ir/inline-array-views.js.map +1 -0
- package/dist/ir/inline-arrays.d.ts +7 -0
- package/dist/ir/inline-arrays.js +190 -55
- package/dist/ir/inline-arrays.js.map +1 -1
- package/dist/ir/inline-arrays.test.js +140 -2
- package/dist/ir/inline-arrays.test.js.map +1 -1
- package/dist/ir/integer-ranges.js +16 -6
- package/dist/ir/integer-ranges.js.map +1 -1
- package/dist/ir/ir.d.ts +75 -44
- package/dist/ir/ir.js.map +1 -1
- package/dist/ir/js-ic.d.ts +10 -9
- package/dist/ir/js-ic.js +28 -20
- package/dist/ir/js-ic.js.map +1 -1
- package/dist/ir/js-ic.test.js +10 -2
- package/dist/ir/js-ic.test.js.map +1 -1
- package/dist/ir/jsval.js +374 -63
- package/dist/ir/jsval.js.map +1 -1
- package/dist/ir/jsval.test.js +96 -2
- package/dist/ir/jsval.test.js.map +1 -1
- package/dist/ir/loop-entry-ranges.js +112 -9
- package/dist/ir/loop-entry-ranges.js.map +1 -1
- package/dist/ir/loop-entry-ranges.test.js +40 -0
- package/dist/ir/loop-entry-ranges.test.js.map +1 -1
- package/dist/ir/parameter-versions.d.ts +2 -1
- package/dist/ir/parameter-versions.js +3 -1
- package/dist/ir/parameter-versions.js.map +1 -1
- package/dist/ir/receiver-readers.js +58 -2
- package/dist/ir/receiver-readers.js.map +1 -1
- package/dist/ir/runtime-features.d.ts +60 -1
- package/dist/ir/runtime-features.js +277 -2
- package/dist/ir/runtime-features.js.map +1 -1
- package/dist/ir/runtime-features.test.js +165 -1
- package/dist/ir/runtime-features.test.js.map +1 -1
- package/dist/ir/saturating-loop-jams.d.ts +8 -1
- package/dist/ir/saturating-loop-jams.js +46 -7
- package/dist/ir/saturating-loop-jams.js.map +1 -1
- package/dist/ir/saturating-loop-jams.test.js +39 -1
- package/dist/ir/saturating-loop-jams.test.js.map +1 -1
- package/dist/ir/self-captures.js +8 -1
- package/dist/ir/self-captures.js.map +1 -1
- package/dist/ir/self-captures.test.js +15 -0
- package/dist/ir/self-captures.test.js.map +1 -1
- package/dist/ir/serialize.d.ts +3 -2
- package/dist/ir/serialize.js +6 -2
- package/dist/ir/serialize.js.map +1 -1
- package/dist/ir/validate.js +82 -4
- package/dist/ir/validate.js.map +1 -1
- package/dist/ir/validate.test.js +46 -0
- package/dist/ir/validate.test.js.map +1 -1
- package/dist/library/ir-policy.js +3 -0
- package/dist/library/ir-policy.js.map +1 -1
- package/dist/native/cache.js +2 -0
- package/dist/native/cache.js.map +1 -1
- package/dist/native/cli.js +2 -0
- package/dist/native/cli.js.map +1 -1
- package/dist/native/compiler.js +8 -2
- package/dist/native/compiler.js.map +1 -1
- package/dist/native/prepare.js +32 -3
- package/dist/native/prepare.js.map +1 -1
- package/dist/native/sanitizer.js +53 -3
- package/dist/native/sanitizer.js.map +1 -1
- package/dist/native/sanitizer.test.js +88 -2
- package/dist/native/sanitizer.test.js.map +1 -1
- package/dist/native/toolchain.js +9 -2
- package/dist/native/toolchain.js.map +1 -1
- package/dist/node-islands/boundary.d.ts +25 -1
- package/dist/node-islands/boundary.js +28 -2
- package/dist/node-islands/boundary.js.map +1 -1
- package/dist/node-islands/detect.d.ts +18 -1
- package/dist/node-islands/detect.js +365 -40
- package/dist/node-islands/detect.js.map +1 -1
- package/dist/node-islands/detect.test.js +151 -4
- package/dist/node-islands/detect.test.js.map +1 -1
- package/dist/node-islands/effect-gate.js +30 -20
- package/dist/node-islands/effect-gate.js.map +1 -1
- package/dist/node-islands/effect-gate.test.js +4 -1
- package/dist/node-islands/effect-gate.test.js.map +1 -1
- package/dist/node-islands/libnode.d.ts +1 -1
- package/dist/node-islands/libnode.js +1 -1
- package/dist/node-islands/libnode.js.map +1 -1
- package/dist/node-islands/modules.d.ts +28 -0
- package/dist/node-islands/modules.js +156 -0
- package/dist/node-islands/modules.js.map +1 -1
- package/dist/node-islands/modules.test.js +105 -1
- package/dist/node-islands/modules.test.js.map +1 -1
- package/dist/node-islands/policy.js +2 -3
- package/dist/node-islands/policy.js.map +1 -1
- package/dist/node-islands/probe-recorder.d.ts +1 -0
- package/dist/node-islands/probe-recorder.js +596 -0
- package/dist/node-islands/probe-recorder.js.map +1 -0
- package/dist/node-islands/probe-recorder.test.d.ts +1 -0
- package/dist/node-islands/probe-recorder.test.js +80 -0
- package/dist/node-islands/probe-recorder.test.js.map +1 -0
- package/dist/node-islands/report.test.js +2 -0
- package/dist/node-islands/report.test.js.map +1 -1
- package/dist/node-islands/rules.js +4 -0
- package/dist/node-islands/rules.js.map +1 -1
- package/dist/node-islands/scan.d.ts +7 -1
- package/dist/node-islands/scan.js +51 -2
- package/dist/node-islands/scan.js.map +1 -1
- package/dist/node-islands/snapshot.d.ts +38 -1
- package/dist/node-islands/snapshot.js +165 -161
- package/dist/node-islands/snapshot.js.map +1 -1
- package/dist/node-islands/snapshot.test.js +63 -2
- package/dist/node-islands/snapshot.test.js.map +1 -1
- package/dist/node-islands/summary.js +8 -0
- package/dist/node-islands/summary.js.map +1 -1
- package/dist/node-islands/type-strip.d.ts +11 -0
- package/dist/node-islands/type-strip.js +157 -0
- package/dist/node-islands/type-strip.js.map +1 -0
- package/dist/node-islands/type-strip.test.d.ts +1 -0
- package/dist/node-islands/type-strip.test.js +31 -0
- package/dist/node-islands/type-strip.test.js.map +1 -0
- package/dist/project-config.d.ts +4 -0
- package/dist/project-config.js +19 -0
- package/dist/project-config.js.map +1 -1
- package/dist/project-config.test.js +10 -0
- package/dist/project-config.test.js.map +1 -1
- package/package.json +20 -20
- package/surface-manifest.json +43 -11
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { widensReducedRecords } from "../function-returns.js";
|
|
2
|
+
import { lowerStaticPrivateRead } from "../private-statics.js";
|
|
2
3
|
import { widthNarrowHelper } from "../coercions/unions.js";
|
|
3
4
|
/* Property reads (`a.b`): lowerExprInner's property-access branch, intrinsic and union properties, field reads and targets, and match-group reads. */
|
|
4
5
|
import { jsSpecialGlobalValue } from "../global-values.js";
|
|
@@ -77,10 +78,12 @@ import { InternalCompilerError } from "../../../errors.js";
|
|
|
77
78
|
import { lowerUnionFieldRead } from "./union-fields.js";
|
|
78
79
|
import { errorPropertyRead } from "../error-methods.js";
|
|
79
80
|
import { isSafeToDiscard, isSafeToRepeat } from "./evaluation-safety.js";
|
|
81
|
+
import { partialAssertionFields, partialFieldRead } from "../partial-assertions.js";
|
|
80
82
|
import { isZlibStreamMember, lowerZlibStreamBytesWritten } from "../builtins/compression.js";
|
|
81
83
|
import { isWebCryptoReceiver } from "../builtins/crypto.js";
|
|
82
84
|
import { isFsStreamMember, lowerFsStreamProperty } from "../builtins/fs-streams.js";
|
|
83
85
|
import { keyedFieldRead } from "./keyed-field-targets.js";
|
|
86
|
+
import { heldEnvValueType } from "../builtins/environment.js";
|
|
84
87
|
import { promisePrototypeValue } from "../thenables.js";
|
|
85
88
|
import { lowerChildPropertyRead } from "../handle-properties.js";
|
|
86
89
|
/** True when a property access names an ABSTRACT property declaration
|
|
@@ -189,6 +192,13 @@ export function lowerPropertyAccessExpr(lowerer, expr, loc) {
|
|
|
189
192
|
const arrayClassConstructor = lowerArrayClassConstructorRead(lowerer, expr, loc);
|
|
190
193
|
if (arrayClassConstructor !== null)
|
|
191
194
|
return arrayClassConstructor;
|
|
195
|
+
// `R.#x` for a static private on a checked-dynamic receiver: the brand
|
|
196
|
+
// check, then the native storage (private-statics.ts).
|
|
197
|
+
{
|
|
198
|
+
const staticPrivate = lowerStaticPrivateRead(lowerer, expr, loc);
|
|
199
|
+
if (staticPrivate)
|
|
200
|
+
return staticPrivate;
|
|
201
|
+
}
|
|
192
202
|
// `value.#x` on a checked-dynamic value, or on a checked extraction of
|
|
193
203
|
// one: the field of the brand-checked receiver (checkedPrivateValue).
|
|
194
204
|
if (ts.isPrivateIdentifier(expr.name)) {
|
|
@@ -552,7 +562,9 @@ export function lowerPropertyAccessExpr(lowerer, expr, loc) {
|
|
|
552
562
|
};
|
|
553
563
|
}
|
|
554
564
|
}
|
|
555
|
-
|
|
565
|
+
// `re.exec(s)?.index` takes the same read: the chain lowering binds the
|
|
566
|
+
// guarded receiver (non-nullish inside the guard) before re-dispatching.
|
|
567
|
+
if (expr.name.text === "index" || expr.name.text === "input") {
|
|
556
568
|
const represented = tryLowerExpression(lowerer, expr.expression);
|
|
557
569
|
if (represented &&
|
|
558
570
|
isMatchSliceType(lowerer, represented.type) &&
|
|
@@ -760,6 +772,26 @@ export function lowerPropertyAccessExpr(lowerer, expr, loc) {
|
|
|
760
772
|
if (promiseMember)
|
|
761
773
|
return promiseMember;
|
|
762
774
|
}
|
|
775
|
+
// A weak collection's method read as a VALUE in a JavaScript source
|
|
776
|
+
// (`wm.has.call(x, k)` — the WeakMap/WeakSet brand-check tests): the
|
|
777
|
+
// runtime's interned prototype function, which applies the method to its
|
|
778
|
+
// own receiver and throws Node's TypeError for a foreign one. A direct
|
|
779
|
+
// call keeps the instance fast path (`dynKeyGet` dispatches to the
|
|
780
|
+
// handle), and an optional read keeps the fence.
|
|
781
|
+
if (!expr.questionDotToken &&
|
|
782
|
+
isJsSourceFile(ts.getSourceFileOfNode(expr)) &&
|
|
783
|
+
!isCalleeOf(expr) &&
|
|
784
|
+
// `WeakMap.prototype.has` is the prototype table's own read: it never
|
|
785
|
+
// lowers the prototype object (a value read of `WeakMap.prototype`
|
|
786
|
+
// is a fence), so leave that spelling there.
|
|
787
|
+
!(ts.isPropertyAccessExpression(expr.expression) &&
|
|
788
|
+
expr.expression.name.text === "prototype" &&
|
|
789
|
+
stdlibGlobalNameOf(lowerer, expr.expression.expression) !== null)) {
|
|
790
|
+
const weak = lowerer.weakCollectionNamesOf(lowerer.typeOf(expr.expression));
|
|
791
|
+
if (weak !== null &&
|
|
792
|
+
weak.names.some((prototype) => WEAK_COLLECTION_METHOD_NAMES[prototype].has(expr.name.text)))
|
|
793
|
+
return weakCollectionMethodValue(lowerer, expr, weak.names, weak.nullable, expr.name.text);
|
|
794
|
+
}
|
|
763
795
|
const handled = lowerer.lowerProcessEnvGet(expr) ??
|
|
764
796
|
lowerer.lowerServerProperty(expr) ??
|
|
765
797
|
// diagnostics_channel Channel receivers — name/hasSubscribers
|
|
@@ -1363,6 +1395,20 @@ export function lowerPropertyAccessExpr(lowerer, expr, loc) {
|
|
|
1363
1395
|
const asserted = assertedMemberRead(lowerer, expr.expression, expr.name.text, recvLowered, loc);
|
|
1364
1396
|
if (asserted)
|
|
1365
1397
|
return asserted;
|
|
1398
|
+
// Lowering erases flow narrowing, so a checker-NARROWED receiver keeps
|
|
1399
|
+
// the wider union it stores (`stored?.type` after the earlier arm
|
|
1400
|
+
// returned, `(entry as { role: string }).role`): the checker's type
|
|
1401
|
+
// names one record while the value still carries its siblings. Read the
|
|
1402
|
+
// member off whichever arm the value holds — an arm that does not
|
|
1403
|
+
// declare it answers undefined, exactly Node's get — and narrow the
|
|
1404
|
+
// answer to the checker's type, which traps on an arm the checker's
|
|
1405
|
+
// narrowing ruled out (types do not lie). Reaching this point means no
|
|
1406
|
+
// lowering above claimed the read, so only refusals gain a lowering.
|
|
1407
|
+
if (recvLowered.type.kind === "union") {
|
|
1408
|
+
const read = lowerUnionValueRead(lowerer, expr, recvLowered, true);
|
|
1409
|
+
if (read)
|
|
1410
|
+
return lowerer.maybeNarrow(read, expr);
|
|
1411
|
+
}
|
|
1366
1412
|
// A checker-`any` receiver whose value is a FRESH typed result of an
|
|
1367
1413
|
// earlier step in the chain (`out.split(" ").length`, where split
|
|
1368
1414
|
// extracted the string and answered a native string[]): the member read
|
|
@@ -1602,9 +1648,165 @@ function mergeReadTypes(lowerer, types) {
|
|
|
1602
1648
|
function importMetaProperty(lowerer, expr) {
|
|
1603
1649
|
return isImportMeta(expr.expression) ? importMetaField(lowerer, expr, expr.name.text) : null;
|
|
1604
1650
|
}
|
|
1651
|
+
const DATE_PROTOTYPE_WRITE_MESSAGE = "writing through a standard library prototype (`Date.prototype` is a value for reads; a Date never observes a write to it)";
|
|
1652
|
+
/** How many member steps separate `node` from `Date.prototype` in the read
|
|
1653
|
+
* chain `node` is part of: 0 for `Date.prototype` itself, 1 for a member, 2
|
|
1654
|
+
* for a property read on a member (the interned function object). Null when
|
|
1655
|
+
* the chain is not rooted at `Date.prototype`. */
|
|
1656
|
+
function datePrototypeDepth(lowerer, node) {
|
|
1657
|
+
let depth = 0;
|
|
1658
|
+
let cur = node;
|
|
1659
|
+
for (;;) {
|
|
1660
|
+
if (ts.isPropertyAccessExpression(cur) &&
|
|
1661
|
+
lowerer.stdlibGlobalMember(cur, "Date") === "prototype")
|
|
1662
|
+
return depth;
|
|
1663
|
+
if (ts.isPropertyAccessExpression(cur) || ts.isElementAccessExpression(cur)) {
|
|
1664
|
+
cur = cur.expression;
|
|
1665
|
+
depth++;
|
|
1666
|
+
continue;
|
|
1667
|
+
}
|
|
1668
|
+
return null;
|
|
1669
|
+
}
|
|
1670
|
+
}
|
|
1671
|
+
/** The prototype object and its members are a read surface: a write that
|
|
1672
|
+
* replaces a member, or a key of the prototype itself, keeps the SC1090
|
|
1673
|
+
* refusal it reached before the prototype had a value, because a typed Date
|
|
1674
|
+
* never observes it and the write would silently differ from Node. A property
|
|
1675
|
+
* OF a member (the interned function object, `Date.prototype.getTime.length
|
|
1676
|
+
* = 1`) writes the function the dynamic tier shares with Node, which matches,
|
|
1677
|
+
* so it stays open. True when `node` is the target of such a write
|
|
1678
|
+
* (assignment, compound assignment, `delete`, `++`/`--`), directly or as the
|
|
1679
|
+
* base of the target's member chain. */
|
|
1680
|
+
export function isDatePrototypeWrite(lowerer, node) {
|
|
1681
|
+
const depth = datePrototypeDepth(lowerer, node);
|
|
1682
|
+
if (depth === null)
|
|
1683
|
+
return false;
|
|
1684
|
+
let steps = 0;
|
|
1685
|
+
let cur = node;
|
|
1686
|
+
for (;;) {
|
|
1687
|
+
while (ts.isParenthesizedExpression(cur.parent))
|
|
1688
|
+
cur = cur.parent;
|
|
1689
|
+
const parent = cur.parent;
|
|
1690
|
+
if (!parent)
|
|
1691
|
+
return false;
|
|
1692
|
+
if ((ts.isPropertyAccessExpression(parent) || ts.isElementAccessExpression(parent)) &&
|
|
1693
|
+
parent.expression === cur) {
|
|
1694
|
+
cur = parent;
|
|
1695
|
+
steps++;
|
|
1696
|
+
continue;
|
|
1697
|
+
}
|
|
1698
|
+
const written = (ts.isBinaryExpression(parent) &&
|
|
1699
|
+
parent.left === cur &&
|
|
1700
|
+
(parent.operatorToken.kind === ts.SyntaxKind.EqualsToken ||
|
|
1701
|
+
(parent.operatorToken.kind >= ts.SyntaxKind.FirstCompoundAssignment &&
|
|
1702
|
+
parent.operatorToken.kind <= ts.SyntaxKind.LastCompoundAssignment))) ||
|
|
1703
|
+
ts.isDeleteExpression(parent) ||
|
|
1704
|
+
// `++`/`--` write their operand; the other prefix unary forms (`!`,
|
|
1705
|
+
// `typeof`, `void`, `+`, `-`, `~`) only read it.
|
|
1706
|
+
((ts.isPrefixUnaryExpression(parent) || ts.isPostfixUnaryExpression(parent)) &&
|
|
1707
|
+
(parent.operator === ts.SyntaxKind.PlusPlusToken ||
|
|
1708
|
+
parent.operator === ts.SyntaxKind.MinusMinusToken));
|
|
1709
|
+
return written && depth + steps <= 1;
|
|
1710
|
+
}
|
|
1711
|
+
}
|
|
1712
|
+
/** The fence for a write found while lowering a property access (see
|
|
1713
|
+
* isDatePrototypeWrite). The cheap syntactic pre-test keeps every other
|
|
1714
|
+
* property access down to one identifier comparison: only a chain rooted at
|
|
1715
|
+
* the `Date` global can name the prototype, and the write path reaches this
|
|
1716
|
+
* before chainBlocked's early return. */
|
|
1717
|
+
export function fenceDatePrototypeWrite(lowerer, expr) {
|
|
1718
|
+
let root = expr;
|
|
1719
|
+
while (ts.isPropertyAccessExpression(root) || ts.isElementAccessExpression(root))
|
|
1720
|
+
root = root.expression;
|
|
1721
|
+
while (ts.isParenthesizedExpression(root))
|
|
1722
|
+
root = root.expression;
|
|
1723
|
+
if (!ts.isIdentifier(root) || root.text !== "Date")
|
|
1724
|
+
return;
|
|
1725
|
+
if (isDatePrototypeWrite(lowerer, expr))
|
|
1726
|
+
lowerer.unsupported("SC1090", expr, DATE_PROTOTYPE_WRITE_MESSAGE);
|
|
1727
|
+
}
|
|
1728
|
+
/** The same fence for a call-shaped write (`Object.defineProperty`,
|
|
1729
|
+
* `Object.assign`) whose target argument is `Date.prototype` or one of its
|
|
1730
|
+
* members. */
|
|
1731
|
+
export function fenceDatePrototypeWriteCall(lowerer, node) {
|
|
1732
|
+
const depth = datePrototypeDepth(lowerer, node);
|
|
1733
|
+
if (depth !== null && depth <= 1)
|
|
1734
|
+
lowerer.unsupported("SC1090", node, DATE_PROTOTYPE_WRITE_MESSAGE);
|
|
1735
|
+
}
|
|
1605
1736
|
/** The TypeError of a deferred-init field read that finds the field
|
|
1606
1737
|
* unassigned where its declared type cannot hold undefined. */
|
|
1607
1738
|
export const DEFERRED_READ_MESSAGE = "undefined is not representable in the target union (a value narrowed or asserted past it still held it)";
|
|
1739
|
+
/** A collection method read as a VALUE (`s.add`, `m.has` — the `f.call(x)`
|
|
1740
|
+
* tests and callback plumbing): the runtime's interned prototype function
|
|
1741
|
+
* for that name, which applies the method to its own receiver and throws
|
|
1742
|
+
* Node's brand-check TypeError when that receiver is not a collection of
|
|
1743
|
+
* the right kind. Only JavaScript sources take this path: a typed source
|
|
1744
|
+
* keeps its refusal (the checker's Set/Map signature has no value form).
|
|
1745
|
+
* The receiver expression still runs for its effects, and a receiver the
|
|
1746
|
+
* checker typed with an undefined arm (an out-of-bounds element of a
|
|
1747
|
+
* `Set[]`, `xs[1].has`) throws Node's TypeError at the read itself: the
|
|
1748
|
+
* member access on a nullish receiver fails before any method exists. */
|
|
1749
|
+
function dynCollectionMethodValue(lowerer, expr, prototype, name) {
|
|
1750
|
+
const loc = locOf(expr);
|
|
1751
|
+
const method = {
|
|
1752
|
+
kind: "libCall",
|
|
1753
|
+
fn: "dyn.builtinMethod",
|
|
1754
|
+
args: [
|
|
1755
|
+
{ kind: "strLit", value: prototype, type: STRING, loc },
|
|
1756
|
+
{ kind: "strLit", value: name, type: STRING, loc: locOf(expr.name) },
|
|
1757
|
+
],
|
|
1758
|
+
type: DYN,
|
|
1759
|
+
loc,
|
|
1760
|
+
};
|
|
1761
|
+
const receiver = lowerer.lowerExpr(expr.expression);
|
|
1762
|
+
const unionType = receiver.type.kind === "union" ? receiver.type : null;
|
|
1763
|
+
const units = [];
|
|
1764
|
+
if (unionType) {
|
|
1765
|
+
const def = lowerer.unions.get(unionType.unionId);
|
|
1766
|
+
def?.arms.forEach((arm, tag) => {
|
|
1767
|
+
if (isUnitType(arm))
|
|
1768
|
+
units.push({ tag, unit: arm.kind === "nullT" ? "null" : "undefined" });
|
|
1769
|
+
});
|
|
1770
|
+
}
|
|
1771
|
+
if (units.length === 0 || unionType === null) {
|
|
1772
|
+
return isSafeToDiscard(receiver)
|
|
1773
|
+
? method
|
|
1774
|
+
: {
|
|
1775
|
+
kind: "seqExpr",
|
|
1776
|
+
stmts: [{ kind: "exprStmt", expr: receiver, loc: locOf(expr.expression) }],
|
|
1777
|
+
result: method,
|
|
1778
|
+
type: DYN,
|
|
1779
|
+
loc,
|
|
1780
|
+
};
|
|
1781
|
+
}
|
|
1782
|
+
const held = lowerer.declareHiddenLocal("%collectionMethodReceiver", unionType);
|
|
1783
|
+
let result = method;
|
|
1784
|
+
for (const { tag, unit } of units) {
|
|
1785
|
+
result = {
|
|
1786
|
+
kind: "ternary",
|
|
1787
|
+
cond: {
|
|
1788
|
+
kind: "unionIsTag",
|
|
1789
|
+
unionId: unionType.unionId,
|
|
1790
|
+
tag,
|
|
1791
|
+
negated: false,
|
|
1792
|
+
value: varRef(held.id, unionType, loc),
|
|
1793
|
+
type: BOOL,
|
|
1794
|
+
loc,
|
|
1795
|
+
},
|
|
1796
|
+
then: nodeThrowExpr(1, "", `Cannot read properties of ${unit} (reading '${name}')`, DYN, loc),
|
|
1797
|
+
else_: result,
|
|
1798
|
+
type: DYN,
|
|
1799
|
+
loc,
|
|
1800
|
+
};
|
|
1801
|
+
}
|
|
1802
|
+
return {
|
|
1803
|
+
kind: "seqExpr",
|
|
1804
|
+
stmts: [{ kind: "varDecl", localId: held.id, init: receiver, loc }],
|
|
1805
|
+
result,
|
|
1806
|
+
type: DYN,
|
|
1807
|
+
loc,
|
|
1808
|
+
};
|
|
1809
|
+
}
|
|
1608
1810
|
/** Property access on a string or array receiver: `.length` lowers to the
|
|
1609
1811
|
* matching intrinsic; a bare method reference (`const f = s.slice` — a
|
|
1610
1812
|
* function value) is rejected with a specific message. Returns null for
|
|
@@ -1619,6 +1821,11 @@ export function lowerIntrinsicProperty(lowerer, expr) {
|
|
|
1619
1821
|
}
|
|
1620
1822
|
if (lowerer.stdlibGlobalMember(expr, "Reflect") === "ownKeys")
|
|
1621
1823
|
return reflectMemberValue(lowerer, "ownKeys", locOf(expr));
|
|
1824
|
+
// A write, `delete` or defineProperty through `Date.prototype` keeps its
|
|
1825
|
+
// fence: the value below is a read surface, and a typed Date never observes
|
|
1826
|
+
// a dynamic write to it. This runs before the chainBlocked early return
|
|
1827
|
+
// because a write lowers the prototype read with the chain blocked.
|
|
1828
|
+
fenceDatePrototypeWrite(lowerer, expr);
|
|
1622
1829
|
if (lowerer.chainBlocked(expr))
|
|
1623
1830
|
return null;
|
|
1624
1831
|
// Object.prototype.constructor: the Object constructor value.
|
|
@@ -1626,6 +1833,9 @@ export function lowerIntrinsicProperty(lowerer, expr) {
|
|
|
1626
1833
|
ts.isPropertyAccessExpression(expr.expression) &&
|
|
1627
1834
|
lowerer.stdlibGlobalMember(expr.expression, "Object") === "prototype")
|
|
1628
1835
|
return builtinGlobalValue("Object", locOf(expr));
|
|
1836
|
+
const primitivePrototype = jsPrimitivePrototypeValue(lowerer, expr);
|
|
1837
|
+
if (primitivePrototype)
|
|
1838
|
+
return primitivePrototype;
|
|
1629
1839
|
const builtinPrototype = builtinPrototypeMethod(lowerer, expr);
|
|
1630
1840
|
if (builtinPrototype)
|
|
1631
1841
|
return {
|
|
@@ -1660,6 +1870,37 @@ export function lowerIntrinsicProperty(lowerer, expr) {
|
|
|
1660
1870
|
return { kind: "libCall", fn: "dyn.functionApply", args: [], type: DYN, loc: locOf(expr) };
|
|
1661
1871
|
if (lowerer.stdlibGlobalMember(expr, "Array") === "prototype")
|
|
1662
1872
|
return { kind: "libCall", fn: "dyn.arrayPrototype", args: [], type: DYN, loc: locOf(expr) };
|
|
1873
|
+
// Date.prototype as a value, and its members read through it: the
|
|
1874
|
+
// prototype object the language defines (an ordinary object carrying the
|
|
1875
|
+
// interface's methods), not a Date. `Date.prototype.hasOwnProperty("x")`
|
|
1876
|
+
// and `Date.prototype.getTime` are reads of that object; a Date method
|
|
1877
|
+
// CALLED on it is a TypeError, which the checked-dynamic method dispatch
|
|
1878
|
+
// answers because the receiver is not a Date handle.
|
|
1879
|
+
if (lowerer.stdlibGlobalMember(expr, "Date") === "prototype") {
|
|
1880
|
+
return {
|
|
1881
|
+
kind: "libCall",
|
|
1882
|
+
fn: "dyn.stdlibPrototype",
|
|
1883
|
+
args: [{ kind: "strLit", value: "Date", type: STRING, loc: locOf(expr) }],
|
|
1884
|
+
type: DYN,
|
|
1885
|
+
loc: locOf(expr),
|
|
1886
|
+
};
|
|
1887
|
+
}
|
|
1888
|
+
if (ts.isPropertyAccessExpression(expr.expression) &&
|
|
1889
|
+
lowerer.stdlibGlobalMember(expr.expression, "Date") === "prototype") {
|
|
1890
|
+
return {
|
|
1891
|
+
kind: "dynKeyGet",
|
|
1892
|
+
value: {
|
|
1893
|
+
kind: "libCall",
|
|
1894
|
+
fn: "dyn.stdlibPrototype",
|
|
1895
|
+
args: [{ kind: "strLit", value: "Date", type: STRING, loc: locOf(expr.expression) }],
|
|
1896
|
+
type: DYN,
|
|
1897
|
+
loc: locOf(expr.expression),
|
|
1898
|
+
},
|
|
1899
|
+
key: { kind: "strLit", value: expr.name.text, type: STRING, loc: locOf(expr.name) },
|
|
1900
|
+
type: DYN,
|
|
1901
|
+
loc: locOf(expr),
|
|
1902
|
+
};
|
|
1903
|
+
}
|
|
1663
1904
|
if (lowerer.stdlibGlobalMember(expr, "Object") === "prototype")
|
|
1664
1905
|
return { kind: "libCall", fn: "dyn.objectPrototype", args: [], type: DYN, loc: locOf(expr) };
|
|
1665
1906
|
// Error.prototype as a value (`F.prototype = Object.create(Error.prototype)`)
|
|
@@ -2235,6 +2476,8 @@ export function lowerIntrinsicProperty(lowerer, expr) {
|
|
|
2235
2476
|
};
|
|
2236
2477
|
}
|
|
2237
2478
|
if (MAP_METHODS.has(name) || name === "forEach") {
|
|
2479
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(expr)) && !expr.questionDotToken)
|
|
2480
|
+
return dynCollectionMethodValue(lowerer, expr, "Map", name);
|
|
2238
2481
|
lowerer.unsupported("SC1090", expr, `Map methods as values (call '${name}' directly)`);
|
|
2239
2482
|
}
|
|
2240
2483
|
return null;
|
|
@@ -2253,6 +2496,8 @@ export function lowerIntrinsicProperty(lowerer, expr) {
|
|
|
2253
2496
|
};
|
|
2254
2497
|
}
|
|
2255
2498
|
if (SET_METHODS.has(name)) {
|
|
2499
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(expr)) && !expr.questionDotToken)
|
|
2500
|
+
return dynCollectionMethodValue(lowerer, expr, "Set", name);
|
|
2256
2501
|
lowerer.unsupported("SC1090", expr, `Set methods as values (call '${name}' directly)`);
|
|
2257
2502
|
}
|
|
2258
2503
|
return null;
|
|
@@ -3100,8 +3345,19 @@ function unreachableReceiver(lowerer, expr) {
|
|
|
3100
3345
|
export function lowerUnionProperty(lowerer, expr) {
|
|
3101
3346
|
if (lowerer.chainBlocked(expr))
|
|
3102
3347
|
return null;
|
|
3103
|
-
const
|
|
3348
|
+
const spelled = structuralReadType(lowerer, expr.expression) ??
|
|
3104
3349
|
lowerer.mapTypeOf(lowerer.typeOf(expr.expression));
|
|
3350
|
+
// Inside an optional-chain body the guarded receiver is checker-typed by
|
|
3351
|
+
// its non-nullish narrowing — often one record of a discriminated union
|
|
3352
|
+
// — while the bound chain value still carries the whole present union
|
|
3353
|
+
// (`stored?.type` after an earlier `stored?.type === "oauth"` return
|
|
3354
|
+
// narrowed `stored` to `ApiKeyCredential`, though the runtime-optional
|
|
3355
|
+
// storage still holds `ApiKeyCredential | OAuthCredential`). The union
|
|
3356
|
+
// reader dispatches on the runtime tag, so take the union the chain
|
|
3357
|
+
// binding hands to `lowerExpr` below instead of the spelled narrowing.
|
|
3358
|
+
const chainRecv = lowerer.chainRecvByNode.get(expr.expression);
|
|
3359
|
+
const chainUnion = spelled?.kind !== "union" && chainRecv?.type.kind === "union" ? chainRecv.type : null;
|
|
3360
|
+
const receiverIr = chainUnion ?? spelled;
|
|
3105
3361
|
// The checker can rule the receiver UNREACHABLE and the assertion that
|
|
3106
3362
|
// escapes it (`const x: never = event; (event as any).type` — the
|
|
3107
3363
|
// `default:` branch of a switch that exhausts every arm) erases to
|
|
@@ -3130,6 +3386,16 @@ export function lowerUnionProperty(lowerer, expr) {
|
|
|
3130
3386
|
else
|
|
3131
3387
|
value = narrowStoredClassValue(lowerer, value, receiverIr) ?? value;
|
|
3132
3388
|
}
|
|
3389
|
+
// The spelled type is a narrowing, so every path below (dyn, record,
|
|
3390
|
+
// object, array) was unreachable for this read before it took the stored
|
|
3391
|
+
// union: answer it only when the union reader can, and otherwise hand the
|
|
3392
|
+
// read back to the lowering the spelled type used to reach. A stored arm
|
|
3393
|
+
// the checker ruled out that has no such member (`m1?.name` where the
|
|
3394
|
+
// stored union still carries a `string` arm) must not turn an accepted
|
|
3395
|
+
// program into a refusal.
|
|
3396
|
+
if (chainUnion !== null) {
|
|
3397
|
+
return value.type.kind === "union" ? lowerUnionValueRead(lowerer, expr, value) : null;
|
|
3398
|
+
}
|
|
3133
3399
|
// A checker-union receiver whose VALUE lowered to a plain RECORD (the
|
|
3134
3400
|
// merged-signature fiction — `runner(cmd, args)` where runner joined
|
|
3135
3401
|
// a structural runner type with spawnSync's, and the local adopted
|
|
@@ -3192,9 +3458,26 @@ export function lowerUnionProperty(lowerer, expr) {
|
|
|
3192
3458
|
if (value.type.kind !== "union") {
|
|
3193
3459
|
lowerer.unsupported("SC1090", expr, "shared property access without a represented union receiver");
|
|
3194
3460
|
}
|
|
3195
|
-
const
|
|
3461
|
+
const read = lowerUnionValueRead(lowerer, expr, value);
|
|
3462
|
+
if (read)
|
|
3463
|
+
return read;
|
|
3464
|
+
lowerer.unsupported("SC1090", expr, `reading '${expr.name.text}' on a union-typed value (every arm must be an object/record ` +
|
|
3465
|
+
`with a same-typed field '${expr.name.text}'; ` +
|
|
3466
|
+
`${NARROW_FIRST})`);
|
|
3467
|
+
}
|
|
3468
|
+
/** The member read itself on a lowered UNION value: `lowerUnionProperty`
|
|
3469
|
+
* after it has produced the value (retagged to the checker's union when
|
|
3470
|
+
* the checker removed arms) and the dispatcher's narrowed-receiver
|
|
3471
|
+
* fallback, which reaches the same read with the value a checker-narrowed
|
|
3472
|
+
* receiver still stores. Returns null when no arm can answer — the caller
|
|
3473
|
+
* owns the diagnostic. */
|
|
3474
|
+
export function lowerUnionValueRead(lowerer, expr, value, missingFieldAsUndefined = false) {
|
|
3475
|
+
if (value.type.kind !== "union")
|
|
3476
|
+
return null;
|
|
3477
|
+
const unionId = value.type.unionId;
|
|
3478
|
+
const def = lowerer.unions.get(unionId);
|
|
3196
3479
|
if (!def)
|
|
3197
|
-
throw new InternalCompilerError(`lowerer bug: unknown union ${
|
|
3480
|
+
throw new InternalCompilerError(`lowerer bug: unknown union ${unionId}`);
|
|
3198
3481
|
const field = expr.name.text;
|
|
3199
3482
|
if (field === "length") {
|
|
3200
3483
|
const presentArms = def.arms.filter((arm) => !isUnitType(arm));
|
|
@@ -3221,6 +3504,31 @@ export function lowerUnionProperty(lowerer, expr) {
|
|
|
3221
3504
|
};
|
|
3222
3505
|
}
|
|
3223
3506
|
}
|
|
3507
|
+
// A union of arrays and strings (`Model[] | ModelRef[]`,
|
|
3508
|
+
// `string[] | Buffer[]`): every arm answers its own length, so the
|
|
3509
|
+
// read dispatches on the tag. Node's `.length` is a number for both,
|
|
3510
|
+
// and no arm can be absent here (a unit arm would have to throw on
|
|
3511
|
+
// this read, which the checker's narrowing already excludes).
|
|
3512
|
+
if (def.arms.length > 1 &&
|
|
3513
|
+
def.arms.every((arm) => arm.kind === "array" || arm.kind === "string")) {
|
|
3514
|
+
return perArmUnionRead(lowerer, expr, unionId, value, F64, "%unionLength", (arm, _tag, receiver) => arm.kind === "string"
|
|
3515
|
+
? {
|
|
3516
|
+
kind: "strIntrinsic",
|
|
3517
|
+
method: "length",
|
|
3518
|
+
receiver,
|
|
3519
|
+
args: [],
|
|
3520
|
+
type: F64,
|
|
3521
|
+
loc: locOf(expr),
|
|
3522
|
+
}
|
|
3523
|
+
: {
|
|
3524
|
+
kind: "arrIntrinsic",
|
|
3525
|
+
method: "length",
|
|
3526
|
+
receiver,
|
|
3527
|
+
args: [],
|
|
3528
|
+
type: F64,
|
|
3529
|
+
loc: locOf(expr),
|
|
3530
|
+
});
|
|
3531
|
+
}
|
|
3224
3532
|
}
|
|
3225
3533
|
const nonUnitArms = def.arms.filter((arm) => !isUnitType(arm));
|
|
3226
3534
|
if (nonUnitArms.length === 1 && nonUnitArms[0]?.kind === "object") {
|
|
@@ -3229,7 +3537,7 @@ export function lowerUnionProperty(lowerer, expr) {
|
|
|
3229
3537
|
if (fieldType !== undefined) {
|
|
3230
3538
|
let receiver = lowerer.runtimeOptionalPropertyReceiver(expr.expression, value, objectType, field);
|
|
3231
3539
|
if (receiver === null) {
|
|
3232
|
-
const helper = lowerer.narrowedArmHelper(
|
|
3540
|
+
const helper = lowerer.narrowedArmHelper(unionId, objectType, locOf(expr.expression));
|
|
3233
3541
|
if (helper !== null)
|
|
3234
3542
|
receiver = lowerer.checkedNarrowCall(helper, value, objectType, locOf(expr.expression));
|
|
3235
3543
|
}
|
|
@@ -3245,6 +3553,15 @@ export function lowerUnionProperty(lowerer, expr) {
|
|
|
3245
3553
|
}
|
|
3246
3554
|
}
|
|
3247
3555
|
}
|
|
3556
|
+
// A member the arms answer through an ACCESSOR (a getter inherited
|
|
3557
|
+
// from a shared base class — `renderer.hasOverlayEntries` on
|
|
3558
|
+
// `FullscreenRenderer | RegularRenderer`): there is no field slot
|
|
3559
|
+
// `unionDisc` could read, so dispatch on the tag and call each arm's
|
|
3560
|
+
// own getter. Fires only when some arm's answer is an accessor, so
|
|
3561
|
+
// data-field unions keep their `unionDisc` lowering.
|
|
3562
|
+
const accessorRead = lowerUnionAccessorRead(lowerer, expr, unionId, value);
|
|
3563
|
+
if (accessorRead)
|
|
3564
|
+
return accessorRead;
|
|
3248
3565
|
let common = null;
|
|
3249
3566
|
for (const arm of def.arms) {
|
|
3250
3567
|
let ft;
|
|
@@ -3274,7 +3591,7 @@ export function lowerUnionProperty(lowerer, expr) {
|
|
|
3274
3591
|
// arms): the JOIN path — `env.PORTLESS_PORT` on `ProcessEnv |
|
|
3275
3592
|
// Record<string, string>`, the tail read of `loaded?.config.script`.
|
|
3276
3593
|
const key = { kind: "strLit", value: field, type: STRING, loc: locOf(expr.name) };
|
|
3277
|
-
const keyed = lowerUnionKeyedRead(lowerer, expr,
|
|
3594
|
+
const keyed = lowerUnionKeyedRead(lowerer, expr, unionId, value, key, field, missingFieldAsUndefined);
|
|
3278
3595
|
if (keyed)
|
|
3279
3596
|
return keyed;
|
|
3280
3597
|
// Class arms declaring the field with compatible but different types
|
|
@@ -3304,9 +3621,197 @@ export function lowerUnionProperty(lowerer, expr) {
|
|
|
3304
3621
|
if (member)
|
|
3305
3622
|
return member;
|
|
3306
3623
|
}
|
|
3307
|
-
|
|
3308
|
-
|
|
3309
|
-
|
|
3624
|
+
return null;
|
|
3625
|
+
}
|
|
3626
|
+
/** Evaluate `value` once into a hidden local and answer the read by
|
|
3627
|
+
* dispatching on the union's tag: arm `tag` (narrowed from the local)
|
|
3628
|
+
* answers `answer(arm, tag, narrowed)`. The first non-unit arm's answer
|
|
3629
|
+
* is the fallback branch, which a representable union never reaches. */
|
|
3630
|
+
function perArmUnionRead(lowerer, expr, unionId, value, type, name, answer) {
|
|
3631
|
+
const loc = locOf(expr);
|
|
3632
|
+
const def = lowerer.unions.get(unionId);
|
|
3633
|
+
if (!def)
|
|
3634
|
+
throw new InternalCompilerError(`lowerer bug: unknown union ${unionId}`);
|
|
3635
|
+
const stable = lowerer.declareHiddenLocal(name, value.type);
|
|
3636
|
+
const ref = () => ({ kind: "varRef", localId: stable.id, type: value.type, loc });
|
|
3637
|
+
let result = null;
|
|
3638
|
+
def.arms.forEach((arm, tag) => {
|
|
3639
|
+
if (isUnitType(arm))
|
|
3640
|
+
return;
|
|
3641
|
+
const receiver = { kind: "unionNarrow", unionId, tag, value: ref(), type: arm, loc };
|
|
3642
|
+
const read = answer(arm, tag, receiver);
|
|
3643
|
+
result =
|
|
3644
|
+
result === null
|
|
3645
|
+
? read
|
|
3646
|
+
: {
|
|
3647
|
+
kind: "ternary",
|
|
3648
|
+
cond: {
|
|
3649
|
+
kind: "unionIsTag",
|
|
3650
|
+
unionId,
|
|
3651
|
+
tag,
|
|
3652
|
+
value: ref(),
|
|
3653
|
+
negated: false,
|
|
3654
|
+
type: BOOL,
|
|
3655
|
+
loc,
|
|
3656
|
+
},
|
|
3657
|
+
then: read,
|
|
3658
|
+
else_: result,
|
|
3659
|
+
type,
|
|
3660
|
+
loc,
|
|
3661
|
+
};
|
|
3662
|
+
});
|
|
3663
|
+
if (result === null)
|
|
3664
|
+
throw new InternalCompilerError(`lowerer bug: no arm answers ${name}`);
|
|
3665
|
+
return {
|
|
3666
|
+
kind: "seqExpr",
|
|
3667
|
+
stmts: [{ kind: "varDecl", localId: stable.id, init: value, loc }],
|
|
3668
|
+
result,
|
|
3669
|
+
type,
|
|
3670
|
+
loc,
|
|
3671
|
+
};
|
|
3672
|
+
}
|
|
3673
|
+
/** A member read the arms answer through an ACCESSOR — an inherited
|
|
3674
|
+
* getter (`this.renderer.hasOverlayEntries`). `unionDisc` reads record
|
|
3675
|
+
* and class FIELD slots, so a getter arm needs the tag dispatch: each
|
|
3676
|
+
* arm calls its own getter (once per read, as Node's read does). Data
|
|
3677
|
+
* arms in the same union read their slot. Every arm must answer one
|
|
3678
|
+
* type; a unit arm or an arm without the member declines (the caller's
|
|
3679
|
+
* keyed read and fences own those). Null when no arm answers through an
|
|
3680
|
+
* accessor — plain field unions keep `unionDisc`. */
|
|
3681
|
+
function lowerUnionAccessorRead(lowerer, expr, unionId, value) {
|
|
3682
|
+
const def = lowerer.unions.get(unionId);
|
|
3683
|
+
if (!def)
|
|
3684
|
+
return null;
|
|
3685
|
+
const field = expr.name.text;
|
|
3686
|
+
const getterName = `get:${field}`;
|
|
3687
|
+
let type = null;
|
|
3688
|
+
let anyAccessor = false;
|
|
3689
|
+
const arms = [];
|
|
3690
|
+
for (let tag = 0; tag < def.arms.length; tag++) {
|
|
3691
|
+
const arm = def.arms[tag];
|
|
3692
|
+
if (isUnitType(arm))
|
|
3693
|
+
return null;
|
|
3694
|
+
let answer;
|
|
3695
|
+
let read;
|
|
3696
|
+
if (arm.kind === "record") {
|
|
3697
|
+
const shape = lowerer.shapes.get(arm.shapeId);
|
|
3698
|
+
if (!shape || shape.tuple)
|
|
3699
|
+
return null;
|
|
3700
|
+
const data = shape.fields.find((f) => f.name === field);
|
|
3701
|
+
if (data) {
|
|
3702
|
+
answer = data.type;
|
|
3703
|
+
read = (receiver) => ({
|
|
3704
|
+
kind: "recordGet",
|
|
3705
|
+
obj: receiver,
|
|
3706
|
+
shapeId: arm.shapeId,
|
|
3707
|
+
field,
|
|
3708
|
+
type: data.type,
|
|
3709
|
+
loc: locOf(expr),
|
|
3710
|
+
});
|
|
3711
|
+
}
|
|
3712
|
+
else {
|
|
3713
|
+
const getter = shape.fields.find((f) => f.name === getterName);
|
|
3714
|
+
if (!getter || getter.type.kind !== "func")
|
|
3715
|
+
return null;
|
|
3716
|
+
anyAccessor = true;
|
|
3717
|
+
answer = getter.type.ret;
|
|
3718
|
+
read = (receiver) => lowerer.coerceToExpected({
|
|
3719
|
+
kind: "callValue",
|
|
3720
|
+
callee: {
|
|
3721
|
+
kind: "recordGet",
|
|
3722
|
+
obj: receiver,
|
|
3723
|
+
shapeId: arm.shapeId,
|
|
3724
|
+
field: getterName,
|
|
3725
|
+
type: getter.type,
|
|
3726
|
+
loc: locOf(expr),
|
|
3727
|
+
},
|
|
3728
|
+
args: [],
|
|
3729
|
+
type: getter.type.kind === "func" ? getter.type.ret : DYN,
|
|
3730
|
+
loc: locOf(expr),
|
|
3731
|
+
}, answer);
|
|
3732
|
+
}
|
|
3733
|
+
}
|
|
3734
|
+
else if (arm.kind === "object") {
|
|
3735
|
+
const info = lowerer.classes.get(arm.className) ?? null;
|
|
3736
|
+
const slot = info?.fields.get(field);
|
|
3737
|
+
if (slot !== undefined) {
|
|
3738
|
+
answer = slot;
|
|
3739
|
+
read = (receiver) => ({
|
|
3740
|
+
kind: "fieldGet",
|
|
3741
|
+
obj: receiver,
|
|
3742
|
+
className: arm.className,
|
|
3743
|
+
field,
|
|
3744
|
+
type: slot,
|
|
3745
|
+
loc: locOf(expr),
|
|
3746
|
+
});
|
|
3747
|
+
}
|
|
3748
|
+
else {
|
|
3749
|
+
const getter = lowerer.findMethodOn(info, getterName);
|
|
3750
|
+
if (!getter || getter.sig.ret.kind === "void")
|
|
3751
|
+
return null;
|
|
3752
|
+
anyAccessor = true;
|
|
3753
|
+
answer = getter.sig.ret;
|
|
3754
|
+
read = (receiver) => lowerer.fieldGetExpr({
|
|
3755
|
+
container: "accessor",
|
|
3756
|
+
obj: receiver,
|
|
3757
|
+
className: arm.className,
|
|
3758
|
+
field,
|
|
3759
|
+
fieldType: getter.sig.ret,
|
|
3760
|
+
}, locOf(expr), expr);
|
|
3761
|
+
}
|
|
3762
|
+
}
|
|
3763
|
+
else {
|
|
3764
|
+
return null;
|
|
3765
|
+
}
|
|
3766
|
+
if (answer.kind === "void" || isUnitType(answer))
|
|
3767
|
+
return null;
|
|
3768
|
+
if (type !== null && !typeEquals(type, answer))
|
|
3769
|
+
return null;
|
|
3770
|
+
type = answer;
|
|
3771
|
+
arms.push({ tag, read });
|
|
3772
|
+
}
|
|
3773
|
+
if (!anyAccessor || type === null || arms.length < 2)
|
|
3774
|
+
return null;
|
|
3775
|
+
return perArmUnionRead(lowerer, expr, unionId, value, type, "%unionMember", (_arm, tag, receiver) => {
|
|
3776
|
+
const entry = arms.find((a) => a.tag === tag);
|
|
3777
|
+
if (!entry)
|
|
3778
|
+
throw new InternalCompilerError("lowerer bug: accessor arm missing");
|
|
3779
|
+
return entry.read(receiver);
|
|
3780
|
+
});
|
|
3781
|
+
}
|
|
3782
|
+
/** A LITERAL-key read on a union receiver whose stored arm is a scalar
|
|
3783
|
+
* primitive the property does not exist on. Lowering erases flow
|
|
3784
|
+
* narrowing, so the value keeps arms the checker ruled out
|
|
3785
|
+
* (`{ url?: string } | "pending"` read as `x?.url` after the guard); JS
|
|
3786
|
+
* boxes a primitive and answers undefined for a name its prototype chain
|
|
3787
|
+
* does not carry, which is exactly what the unit and missing-field arms
|
|
3788
|
+
* answer. A name the primitive DOES declare (`length`, `toUpperCase`)
|
|
3789
|
+
* leaves the read to its own lowering/refusal — `{ n: number } | string`
|
|
3790
|
+
* must keep answering the string's own member, not undefined. */
|
|
3791
|
+
function primitiveArmLacksMember(lowerer, arm, field) {
|
|
3792
|
+
// `"abc"[0]` is an element read (JS indexes a string by position), not a
|
|
3793
|
+
// missing property: canonical numeric keys keep their own lowering.
|
|
3794
|
+
if (/^(?:0|[1-9]\d*)$/.test(field))
|
|
3795
|
+
return false;
|
|
3796
|
+
const checker = lowerer.checker;
|
|
3797
|
+
let primitive;
|
|
3798
|
+
switch (arm.kind) {
|
|
3799
|
+
case "string":
|
|
3800
|
+
primitive = checker.getStringType();
|
|
3801
|
+
break;
|
|
3802
|
+
case "f64":
|
|
3803
|
+
primitive = checker.getNumberType();
|
|
3804
|
+
break;
|
|
3805
|
+
case "bool":
|
|
3806
|
+
primitive = checker.getBooleanType();
|
|
3807
|
+
break;
|
|
3808
|
+
case "bigint":
|
|
3809
|
+
primitive = checker.getBigIntType();
|
|
3810
|
+
break;
|
|
3811
|
+
default:
|
|
3812
|
+
return false;
|
|
3813
|
+
}
|
|
3814
|
+
return checker.getPropertyOfType(primitive, field) === undefined;
|
|
3310
3815
|
}
|
|
3311
3816
|
/** The unionDisc generalization: a keyed read on a union receiver whose
|
|
3312
3817
|
* arms answer DIFFERENT (but joinable) types. Each arm contributes its
|
|
@@ -3325,6 +3830,15 @@ export function lowerUnionKeyedRead(lowerer, expr, unionId, value, key, literalF
|
|
|
3325
3830
|
const def = lowerer.unions.get(unionId);
|
|
3326
3831
|
if (!def)
|
|
3327
3832
|
return null;
|
|
3833
|
+
// A JavaScript-source read on a dyn-convertible receiver already has a
|
|
3834
|
+
// dynamic fallback at every call site (`dynKeyGet`), so the primitive
|
|
3835
|
+
// arm's undefined answer would REPLACE a read that compiles today and
|
|
3836
|
+
// change a working program's IR. Keep that fallback: the static answer
|
|
3837
|
+
// exists to replace a refusal, which is the TypeScript-source case.
|
|
3838
|
+
const keepsDynamicFallback = isJsSourceFile(ts.getSourceFileOfNode(expr)) && lowerer.dynConvertible(value.type);
|
|
3839
|
+
const primitiveArmAnswers = (arm) => literalField !== null &&
|
|
3840
|
+
!keepsDynamicFallback &&
|
|
3841
|
+
primitiveArmLacksMember(lowerer, arm, literalField);
|
|
3328
3842
|
// Pass 1: per-arm declared answers, joined into the result type.
|
|
3329
3843
|
const joinArms = [];
|
|
3330
3844
|
const seen = new Set();
|
|
@@ -3359,8 +3873,13 @@ export function lowerUnionKeyedRead(lowerer, expr, unionId, value, key, literalF
|
|
|
3359
3873
|
return null;
|
|
3360
3874
|
continue;
|
|
3361
3875
|
}
|
|
3362
|
-
if (arm.kind !== "record")
|
|
3876
|
+
if (arm.kind !== "record") {
|
|
3877
|
+
if (primitiveArmAnswers(arm)) {
|
|
3878
|
+
push(UNDEFINED_T);
|
|
3879
|
+
continue;
|
|
3880
|
+
}
|
|
3363
3881
|
return null;
|
|
3882
|
+
}
|
|
3364
3883
|
const shape = lowerer.shapes.get(arm.shapeId);
|
|
3365
3884
|
if (!shape || shape.tuple)
|
|
3366
3885
|
return null;
|
|
@@ -3423,8 +3942,16 @@ export function lowerUnionKeyedRead(lowerer, expr, unionId, value, key, literalF
|
|
|
3423
3942
|
return null;
|
|
3424
3943
|
continue;
|
|
3425
3944
|
}
|
|
3426
|
-
if (arm.kind !== "record")
|
|
3945
|
+
if (arm.kind !== "record") {
|
|
3946
|
+
if (primitiveArmAnswers(arm)) {
|
|
3947
|
+
// The primitive's answer above must surface as the join's
|
|
3948
|
+
// undefined arm (the backend's missing-key path stores it).
|
|
3949
|
+
if (!(type.kind === "union" && lowerer.armTag(type.unionId, UNDEFINED_T) >= 0))
|
|
3950
|
+
return null;
|
|
3951
|
+
continue;
|
|
3952
|
+
}
|
|
3427
3953
|
return null;
|
|
3954
|
+
}
|
|
3428
3955
|
const shape = lowerer.shapes.get(arm.shapeId);
|
|
3429
3956
|
if (!shape)
|
|
3430
3957
|
return null;
|
|
@@ -3556,6 +4083,44 @@ function checkedDynamicValue(expr) {
|
|
|
3556
4083
|
return expr;
|
|
3557
4084
|
return expr.kind === "dynCheck" && expr.value.type.kind === "dyn" ? expr.value : null;
|
|
3558
4085
|
}
|
|
4086
|
+
/** A GENERIC receiver type: a type parameter, or a narrowing of one that
|
|
4087
|
+
* intersects it (`"k" in options` refines a type variable to
|
|
4088
|
+
* `T & Record<"k", unknown>`). Its stored layout is whatever the call site
|
|
4089
|
+
* instantiated it with, and the CONSTRAINT's members are not necessarily
|
|
4090
|
+
* stored there. */
|
|
4091
|
+
function typeParameterReceiver(t) {
|
|
4092
|
+
try {
|
|
4093
|
+
if ((t.flags & ts.TypeFlags.TypeParameter) !== 0)
|
|
4094
|
+
return true;
|
|
4095
|
+
return ((t.flags & ts.TypeFlags.Intersection) !== 0 &&
|
|
4096
|
+
ts.constituentTypes(t).some((part) => (part.flags & ts.TypeFlags.TypeParameter) !== 0));
|
|
4097
|
+
}
|
|
4098
|
+
catch (e) {
|
|
4099
|
+
if (ts.isUnreadableConstituentsPanic(e))
|
|
4100
|
+
return false;
|
|
4101
|
+
throw e;
|
|
4102
|
+
}
|
|
4103
|
+
}
|
|
4104
|
+
/** Whether `access` is only READ (not the target of an assignment, a
|
|
4105
|
+
* delete, or an increment). The left operand of `??`, `===` or `&&`, and
|
|
4106
|
+
* the operand of `!`, `-` or `typeof`, are reads. */
|
|
4107
|
+
function readOnlyAccess(access) {
|
|
4108
|
+
const parent = access.parent;
|
|
4109
|
+
if (parent === undefined)
|
|
4110
|
+
return true;
|
|
4111
|
+
if (ts.isBinaryExpression(parent) &&
|
|
4112
|
+
parent.left === access &&
|
|
4113
|
+
parent.operatorToken.kind >= ts.SyntaxKind.FirstAssignment &&
|
|
4114
|
+
parent.operatorToken.kind <= ts.SyntaxKind.LastAssignment)
|
|
4115
|
+
return false;
|
|
4116
|
+
if (ts.isDeleteExpression(parent))
|
|
4117
|
+
return false;
|
|
4118
|
+
if (ts.isPostfixUnaryExpression(parent))
|
|
4119
|
+
return false;
|
|
4120
|
+
return (!ts.isPrefixUnaryExpression(parent) ||
|
|
4121
|
+
(parent.operator !== ts.SyntaxKind.PlusPlusToken &&
|
|
4122
|
+
parent.operator !== ts.SyntaxKind.MinusMinusToken));
|
|
4123
|
+
}
|
|
3559
4124
|
export function fieldTarget(lowerer, access) {
|
|
3560
4125
|
if (lowerer.cjsLocalModuleBindingOf(access.expression))
|
|
3561
4126
|
return null;
|
|
@@ -3647,6 +4212,47 @@ export function fieldTarget(lowerer, access) {
|
|
|
3647
4212
|
if (receiverIr?.kind === "union" && hasClassPayload(lowerer, receiverIr)) {
|
|
3648
4213
|
return representedClassFieldTarget(lowerer, access.expression, access.name.text, lowerer.lowerExpr(access.expression));
|
|
3649
4214
|
}
|
|
4215
|
+
// A generic receiver's member the INSTANTIATION cannot store: the type
|
|
4216
|
+
// parameter's constraint declares the member (so tsc admits the read),
|
|
4217
|
+
// while the record the parameter was instantiated with has no such slot —
|
|
4218
|
+
// a generic options bag read through its constraint (`options.sessionId`
|
|
4219
|
+
// under an `"sessionId" in options` guard) at a call site whose options
|
|
4220
|
+
// literal omits the optional member. Node reads the property off the
|
|
4221
|
+
// object it actually has: undefined when the caller omitted it, the extra
|
|
4222
|
+
// property when a JavaScript caller supplied one. So the read is the
|
|
4223
|
+
// checked-dynamic keyed read of the stored record, entering the static
|
|
4224
|
+
// code at the type the checker gave the read.
|
|
4225
|
+
if (!access.questionDotToken &&
|
|
4226
|
+
readOnlyAccess(access) &&
|
|
4227
|
+
typeParameterReceiver(lowerer.typeOf(access.expression))) {
|
|
4228
|
+
const storedIr = stored ?? narrowed;
|
|
4229
|
+
const arm = storedIr?.kind === "union" ? lowerer.stripUndefinedArm(storedIr) : storedIr;
|
|
4230
|
+
const shape = arm?.kind === "record" ? lowerer.shapes.get(arm.shapeId) : undefined;
|
|
4231
|
+
const admitted = lowerer.mapTypeOf(lowerer.typeOf(access));
|
|
4232
|
+
if (shape &&
|
|
4233
|
+
!shape.tuple &&
|
|
4234
|
+
!shape.indexValue &&
|
|
4235
|
+
!shape.fields.some((f) => f.name === access.name.text) &&
|
|
4236
|
+
admitted &&
|
|
4237
|
+
admitted.kind !== "void") {
|
|
4238
|
+
let obj = lowerer.lowerExpr(access.expression);
|
|
4239
|
+
if (obj.type.kind === "union" && lowerer.armTag(obj.type.unionId, UNDEFINED_T) >= 0) {
|
|
4240
|
+
const present = lowerer.stripUndefinedArm(obj.type);
|
|
4241
|
+
obj =
|
|
4242
|
+
present.kind === "record"
|
|
4243
|
+
? (lowerer.runtimeOptionalPropertyReceiver(access.expression, obj, present, access.name.text) ?? obj)
|
|
4244
|
+
: lowerer.maybeNarrow(obj, access.expression);
|
|
4245
|
+
}
|
|
4246
|
+
if (obj.type.kind !== "record")
|
|
4247
|
+
return null;
|
|
4248
|
+
return {
|
|
4249
|
+
container: "dynamic",
|
|
4250
|
+
obj: lowerer.coerceToExpected(obj, DYN),
|
|
4251
|
+
field: access.name.text,
|
|
4252
|
+
fieldType: admitted,
|
|
4253
|
+
};
|
|
4254
|
+
}
|
|
4255
|
+
}
|
|
3650
4256
|
if (receiverIr?.kind === "record") {
|
|
3651
4257
|
const shape = lowerer.shapes.get(receiverIr.shapeId);
|
|
3652
4258
|
const fieldType = shape?.fields.find((f) => f.name === access.name.text)?.type;
|
|
@@ -3875,6 +4481,21 @@ export function fieldGetExpr(lowerer, target, loc, blame) {
|
|
|
3875
4481
|
// construction), typed as the index value armed with undefined
|
|
3876
4482
|
// (mirroring lowerRecordKeyRead).
|
|
3877
4483
|
if (target.container === "recordOvf") {
|
|
4484
|
+
// A dot read through a value HELD from process.env (`const env =
|
|
4485
|
+
// process.env; env.X`): the hold aliases the live table, so the read is
|
|
4486
|
+
// the same getenv the direct spelling lowers to.
|
|
4487
|
+
if (ts.isPropertyAccessExpression(blame)) {
|
|
4488
|
+
const live = heldEnvValueType(lowerer, blame.expression);
|
|
4489
|
+
if (live !== null) {
|
|
4490
|
+
return {
|
|
4491
|
+
kind: "libCall",
|
|
4492
|
+
fn: "process.envGet",
|
|
4493
|
+
args: [{ kind: "strLit", value: target.field, type: STRING, loc }],
|
|
4494
|
+
type: live,
|
|
4495
|
+
loc,
|
|
4496
|
+
};
|
|
4497
|
+
}
|
|
4498
|
+
}
|
|
3878
4499
|
let obj = target.obj;
|
|
3879
4500
|
if (obj.type.kind === "union" && ts.isPropertyAccessExpression(blame)) {
|
|
3880
4501
|
const present = lowerer.stripUndefinedArm(obj.type);
|
|
@@ -3958,6 +4579,23 @@ export function fieldGetExpr(lowerer, target, loc, blame) {
|
|
|
3958
4579
|
}
|
|
3959
4580
|
return read;
|
|
3960
4581
|
}
|
|
4582
|
+
// A field some partial record assertion leaves unwritten (a partial
|
|
4583
|
+
// record view, partial-assertions.ts): a read of an absent field throws
|
|
4584
|
+
// the catchable TypeError instead of reading a slot the view lacks.
|
|
4585
|
+
if (partialAssertionFields(lowerer, target.shapeId).has(target.field)) {
|
|
4586
|
+
const obj = target.obj;
|
|
4587
|
+
if (isSafeToRepeat(obj))
|
|
4588
|
+
return partialFieldRead(lowerer, obj, target.shapeId, target.field, target.fieldType, loc);
|
|
4589
|
+
const stable = lowerer.declareHiddenLocal("%partialRecv", obj.type);
|
|
4590
|
+
const ref = varRef(stable.id, obj.type, loc);
|
|
4591
|
+
return {
|
|
4592
|
+
kind: "seqExpr",
|
|
4593
|
+
stmts: [{ kind: "varDecl", localId: stable.id, init: obj, loc }],
|
|
4594
|
+
result: partialFieldRead(lowerer, ref, target.shapeId, target.field, target.fieldType, loc),
|
|
4595
|
+
type: target.fieldType,
|
|
4596
|
+
loc,
|
|
4597
|
+
};
|
|
4598
|
+
}
|
|
3961
4599
|
return {
|
|
3962
4600
|
kind: "recordGet",
|
|
3963
4601
|
obj: target.obj,
|
|
@@ -4010,7 +4648,10 @@ const ERROR_CONSTRUCTOR_VALUES = new Set([
|
|
|
4010
4648
|
* constructor, and dynamic values answer `.constructor` with the same one,
|
|
4011
4649
|
* so `o.constructor === Object` and `err.constructor === TypeError` are
|
|
4012
4650
|
* exact identity tests, and `err.constructor.name` is the constructor's
|
|
4013
|
-
* name.
|
|
4651
|
+
* name. SharedArrayBuffer, DataView, BigInt64Array, BigUint64Array and
|
|
4652
|
+
* Proxy have values with Node's name, length and instanceof answers;
|
|
4653
|
+
* calling one throws Node's TypeError, and constructing through the value
|
|
4654
|
+
* is fenced. */
|
|
4014
4655
|
const GLOBAL_CONSTRUCTOR_VALUES = new Set([
|
|
4015
4656
|
"Object",
|
|
4016
4657
|
"Function",
|
|
@@ -4022,6 +4663,11 @@ const GLOBAL_CONSTRUCTOR_VALUES = new Set([
|
|
|
4022
4663
|
"WeakMap",
|
|
4023
4664
|
"WeakSet",
|
|
4024
4665
|
"FinalizationRegistry",
|
|
4666
|
+
"SharedArrayBuffer",
|
|
4667
|
+
"DataView",
|
|
4668
|
+
"BigInt64Array",
|
|
4669
|
+
"BigUint64Array",
|
|
4670
|
+
"Proxy",
|
|
4025
4671
|
...ERROR_CONSTRUCTOR_VALUES,
|
|
4026
4672
|
]);
|
|
4027
4673
|
/** The builtin global functions JavaScript sources read as interned
|
|
@@ -4190,6 +4836,94 @@ const OBJECT_PROTOTYPE_VALUE_READS = new Set([
|
|
|
4190
4836
|
"hasOwnProperty",
|
|
4191
4837
|
"propertyIsEnumerable",
|
|
4192
4838
|
]);
|
|
4839
|
+
/** The method names each weak collection's prototype declares. */
|
|
4840
|
+
const WEAK_COLLECTION_METHOD_NAMES = {
|
|
4841
|
+
WeakMap: new Set(["get", "set", "has", "delete"]),
|
|
4842
|
+
WeakSet: new Set(["add", "has", "delete"]),
|
|
4843
|
+
};
|
|
4844
|
+
/** A weak-collection method read as a VALUE (`wm.has`, the
|
|
4845
|
+
* `map.has.call(x, k)` brand-check tests): the runtime's interned prototype
|
|
4846
|
+
* function for that name, which applies the method to its own receiver and
|
|
4847
|
+
* throws Node's brand-check TypeError when that receiver is not a
|
|
4848
|
+
* WeakMap/WeakSet. A receiver typed `WeakMap | WeakSet` picks the function by
|
|
4849
|
+
* the collection the value holds, and one that admits `null`/`undefined`
|
|
4850
|
+
* throws the property-read TypeError the read itself throws in Node. Only
|
|
4851
|
+
* JavaScript sources take this path: a typed source keeps its refusal (the
|
|
4852
|
+
* checker's signature has no value form). The receiver expression still runs
|
|
4853
|
+
* for its effects. */
|
|
4854
|
+
function weakCollectionMethodValue(lowerer, expr, prototypes, nullable, name) {
|
|
4855
|
+
const loc = locOf(expr);
|
|
4856
|
+
const method = (prototype) => WEAK_COLLECTION_METHOD_NAMES[prototype].has(name)
|
|
4857
|
+
? {
|
|
4858
|
+
kind: "libCall",
|
|
4859
|
+
fn: "dyn.builtinMethod",
|
|
4860
|
+
args: [
|
|
4861
|
+
{ kind: "strLit", value: prototype, type: STRING, loc },
|
|
4862
|
+
{ kind: "strLit", value: name, type: STRING, loc: locOf(expr.name) },
|
|
4863
|
+
],
|
|
4864
|
+
type: DYN,
|
|
4865
|
+
loc,
|
|
4866
|
+
}
|
|
4867
|
+
: // The collection without the method reads it as undefined.
|
|
4868
|
+
dynUndefinedExpr(loc);
|
|
4869
|
+
const receiver = lowerer.lowerExpr(expr.expression);
|
|
4870
|
+
if (!nullable && prototypes.length === 1) {
|
|
4871
|
+
const value = method(prototypes[0]);
|
|
4872
|
+
return isSafeToDiscard(receiver)
|
|
4873
|
+
? value
|
|
4874
|
+
: {
|
|
4875
|
+
kind: "seqExpr",
|
|
4876
|
+
stmts: [{ kind: "exprStmt", expr: receiver, loc: locOf(expr.expression) }],
|
|
4877
|
+
result: value,
|
|
4878
|
+
type: DYN,
|
|
4879
|
+
loc,
|
|
4880
|
+
};
|
|
4881
|
+
}
|
|
4882
|
+
// The receiver answers the kind and unit tests below, so it waits in a
|
|
4883
|
+
// hidden local.
|
|
4884
|
+
const held = lowerer.declareHiddenLocal("%weakRecv", DYN);
|
|
4885
|
+
const ref = () => varRef(held.id, DYN, loc);
|
|
4886
|
+
let value = method(prototypes[0]);
|
|
4887
|
+
if (prototypes.length > 1)
|
|
4888
|
+
value = {
|
|
4889
|
+
kind: "ternary",
|
|
4890
|
+
cond: { kind: "libCall", fn: "weakMap.is", args: [ref()], type: BOOL, loc },
|
|
4891
|
+
then: method("WeakMap"),
|
|
4892
|
+
else_: method("WeakSet"),
|
|
4893
|
+
type: DYN,
|
|
4894
|
+
loc,
|
|
4895
|
+
};
|
|
4896
|
+
if (nullable)
|
|
4897
|
+
value = {
|
|
4898
|
+
kind: "ternary",
|
|
4899
|
+
cond: { kind: "dynTest", test: "nullish", value: ref(), type: BOOL, loc },
|
|
4900
|
+
// Node throws from the read itself, naming the unit and the member.
|
|
4901
|
+
then: {
|
|
4902
|
+
kind: "dynKeyGet",
|
|
4903
|
+
value: ref(),
|
|
4904
|
+
key: { kind: "strLit", value: name, type: STRING, loc },
|
|
4905
|
+
type: DYN,
|
|
4906
|
+
loc,
|
|
4907
|
+
},
|
|
4908
|
+
else_: value,
|
|
4909
|
+
type: DYN,
|
|
4910
|
+
loc,
|
|
4911
|
+
};
|
|
4912
|
+
return {
|
|
4913
|
+
kind: "seqExpr",
|
|
4914
|
+
stmts: [
|
|
4915
|
+
{
|
|
4916
|
+
kind: "varDecl",
|
|
4917
|
+
localId: held.id,
|
|
4918
|
+
init: lowerer.coerceInto(expr.expression, receiver, DYN),
|
|
4919
|
+
loc,
|
|
4920
|
+
},
|
|
4921
|
+
],
|
|
4922
|
+
result: value,
|
|
4923
|
+
type: DYN,
|
|
4924
|
+
loc,
|
|
4925
|
+
};
|
|
4926
|
+
}
|
|
4193
4927
|
/** Whether `expr` is the callee of a call (`o.toString()`), which keeps its
|
|
4194
4928
|
* call lowering rather than reading the member as a value. */
|
|
4195
4929
|
function isCalleeOf(expr) {
|
|
@@ -4388,4 +5122,54 @@ function globalThisWrittenNames(lowerer, globalType) {
|
|
|
4388
5122
|
}
|
|
4389
5123
|
return names;
|
|
4390
5124
|
}
|
|
5125
|
+
/** `Number.prototype` / `Boolean.prototype` in a JavaScript source: the
|
|
5126
|
+
* prototype object the checked-dynamic world builds (with its methods), or
|
|
5127
|
+
* one of its members read as a value. Typed sources keep their own
|
|
5128
|
+
* lowering, so no typed program links the unit that builds it. */
|
|
5129
|
+
function jsPrimitivePrototypeValue(lowerer, expr) {
|
|
5130
|
+
if (!isJsSourceFile(ts.getSourceFileOfNode(expr)))
|
|
5131
|
+
return null;
|
|
5132
|
+
const loc = locOf(expr);
|
|
5133
|
+
const value = (kind) => ({
|
|
5134
|
+
kind: "libCall",
|
|
5135
|
+
fn: "dyn.builtinPrototype",
|
|
5136
|
+
args: [{ kind: "strLit", value: kind, type: STRING, loc }],
|
|
5137
|
+
type: DYN,
|
|
5138
|
+
loc,
|
|
5139
|
+
});
|
|
5140
|
+
const receiver = expr.expression;
|
|
5141
|
+
if (ts.isPropertyAccessExpression(receiver) && receiver.name.text === "prototype") {
|
|
5142
|
+
const kind = primitivePrototypeKind(lowerer, receiver);
|
|
5143
|
+
if (!kind)
|
|
5144
|
+
return null;
|
|
5145
|
+
return {
|
|
5146
|
+
kind: "dynKeyGet",
|
|
5147
|
+
value: value(kind),
|
|
5148
|
+
key: { kind: "strLit", value: expr.name.text, type: STRING, loc: locOf(expr.name) },
|
|
5149
|
+
type: DYN,
|
|
5150
|
+
loc,
|
|
5151
|
+
};
|
|
5152
|
+
}
|
|
5153
|
+
const kind = primitivePrototypeKind(lowerer, expr);
|
|
5154
|
+
return kind ? value(kind) : null;
|
|
5155
|
+
}
|
|
5156
|
+
/** Whether `expr` names `Number.prototype` or `Boolean.prototype` in a
|
|
5157
|
+
* JavaScript source, which lowers to the prototype object above rather than
|
|
5158
|
+
* to the wrapper interface's numeric/boolean value. */
|
|
5159
|
+
export function isPrimitivePrototypeRead(lowerer, expr) {
|
|
5160
|
+
return primitivePrototypeKind(lowerer, expr) !== null;
|
|
5161
|
+
}
|
|
5162
|
+
/** The kind whose prototype `expr` names (`Number.prototype`) in a
|
|
5163
|
+
* JavaScript source, if any. */
|
|
5164
|
+
function primitivePrototypeKind(lowerer, expr) {
|
|
5165
|
+
if (!ts.isPropertyAccessExpression(expr) || expr.name.text !== "prototype")
|
|
5166
|
+
return null;
|
|
5167
|
+
if (!isJsSourceFile(ts.getSourceFileOfNode(expr)))
|
|
5168
|
+
return null;
|
|
5169
|
+
if (lowerer.stdlibGlobalMember(expr, "Number") === "prototype")
|
|
5170
|
+
return "Number";
|
|
5171
|
+
if (lowerer.stdlibGlobalMember(expr, "Boolean") === "prototype")
|
|
5172
|
+
return "Boolean";
|
|
5173
|
+
return null;
|
|
5174
|
+
}
|
|
4391
5175
|
//# sourceMappingURL=property-access.js.map
|