@geastack/compiler 1.0.15
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/LICENSE +202 -0
- package/README.md +149 -0
- package/dist/cli-analyze.d.ts +1 -0
- package/dist/cli-analyze.js +61 -0
- package/dist/cli-coverage.d.ts +1 -0
- package/dist/cli-coverage.js +329 -0
- package/dist/cli-emit.d.ts +10 -0
- package/dist/cli-emit.js +398 -0
- package/dist/cli-module-graph.d.ts +18 -0
- package/dist/cli-module-graph.js +123 -0
- package/dist/cli-package-source.d.ts +5 -0
- package/dist/cli-package-source.js +116 -0
- package/dist/cli-project.d.ts +2 -0
- package/dist/cli-project.js +60 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +199 -0
- package/dist/compiler.d.ts +228 -0
- package/dist/compiler.js +1029 -0
- package/dist/conversion/algebra.d.ts +218 -0
- package/dist/conversion/algebra.js +155 -0
- package/dist/conversion/build.d.ts +67 -0
- package/dist/conversion/build.js +1378 -0
- package/dist/conversion/derive.d.ts +37 -0
- package/dist/conversion/derive.js +260 -0
- package/dist/conversion/graph-validation.d.ts +8 -0
- package/dist/conversion/graph-validation.js +97 -0
- package/dist/conversion/native-callable-adapter.d.ts +13 -0
- package/dist/conversion/native-callable-adapter.js +53 -0
- package/dist/conversion/native-class-reference.d.ts +12 -0
- package/dist/conversion/native-class-reference.js +39 -0
- package/dist/conversion/native-payload-transport.d.ts +25 -0
- package/dist/conversion/native-payload-transport.js +33 -0
- package/dist/conversion/native-selection.d.ts +49 -0
- package/dist/conversion/native-selection.js +135 -0
- package/dist/conversion/native-sum.d.ts +42 -0
- package/dist/conversion/native-sum.js +115 -0
- package/dist/conversion/nodes.d.ts +55 -0
- package/dist/conversion/nodes.js +91 -0
- package/dist/conversion/operand-view.d.ts +14 -0
- package/dist/conversion/operand-view.js +20 -0
- package/dist/conversion/record-view.d.ts +157 -0
- package/dist/conversion/record-view.js +273 -0
- package/dist/conversion/registry.d.ts +217 -0
- package/dist/conversion/registry.js +1 -0
- package/dist/diagnostics/model.d.ts +76 -0
- package/dist/diagnostics/model.js +60 -0
- package/dist/diagnostics/sweep.d.ts +31 -0
- package/dist/diagnostics/sweep.js +112 -0
- package/dist/identity/ids.d.ts +179 -0
- package/dist/identity/ids.js +212 -0
- package/dist/ir/absent-class-arm.d.ts +48 -0
- package/dist/ir/absent-class-arm.js +157 -0
- package/dist/ir/borrow-effects.d.ts +23 -0
- package/dist/ir/borrow-effects.js +151 -0
- package/dist/ir/borrowed-call-arguments.d.ts +40 -0
- package/dist/ir/borrowed-call-arguments.js +117 -0
- package/dist/ir/build.d.ts +168 -0
- package/dist/ir/build.js +459 -0
- package/dist/ir/call-dispatch.d.ts +38 -0
- package/dist/ir/call-dispatch.js +502 -0
- package/dist/ir/call-entry.d.ts +142 -0
- package/dist/ir/call-entry.js +386 -0
- package/dist/ir/callable-class-flow.d.ts +27 -0
- package/dist/ir/callable-class-flow.js +1386 -0
- package/dist/ir/callable-field-slots.d.ts +22 -0
- package/dist/ir/callable-field-slots.js +166 -0
- package/dist/ir/callable-identity-demand.d.ts +52 -0
- package/dist/ir/callable-identity-demand.js +460 -0
- package/dist/ir/callable-member-candidates.d.ts +9 -0
- package/dist/ir/callable-member-candidates.js +39 -0
- package/dist/ir/callable-records.d.ts +21 -0
- package/dist/ir/callable-records.js +411 -0
- package/dist/ir/captures.d.ts +26 -0
- package/dist/ir/captures.js +335 -0
- package/dist/ir/certificate.d.ts +45 -0
- package/dist/ir/certificate.js +47 -0
- package/dist/ir/certify/carrier-keys.d.ts +73 -0
- package/dist/ir/certify/carrier-keys.js +221 -0
- package/dist/ir/certify/function-source.d.ts +4 -0
- package/dist/ir/certify/function-source.js +28 -0
- package/dist/ir/certify/has-property-key.d.ts +88 -0
- package/dist/ir/certify/has-property-key.js +116 -0
- package/dist/ir/certify/instanceof-key.d.ts +24 -0
- package/dist/ir/certify/instanceof-key.js +35 -0
- package/dist/ir/certify/property-access-keys.d.ts +172 -0
- package/dist/ir/certify/property-access-keys.js +291 -0
- package/dist/ir/certify/property-access.d.ts +3 -0
- package/dist/ir/certify/property-access.js +597 -0
- package/dist/ir/certify/runtime-helper.d.ts +3 -0
- package/dist/ir/certify/runtime-helper.js +326 -0
- package/dist/ir/certify/typeof-operand.d.ts +14 -0
- package/dist/ir/certify/typeof-operand.js +16 -0
- package/dist/ir/certify.d.ts +123 -0
- package/dist/ir/certify.js +481 -0
- package/dist/ir/class-evaluation.d.ts +26 -0
- package/dist/ir/class-evaluation.js +50 -0
- package/dist/ir/class-static-fields.d.ts +60 -0
- package/dist/ir/class-static-fields.js +108 -0
- package/dist/ir/construct-entry.d.ts +26 -0
- package/dist/ir/construct-entry.js +117 -0
- package/dist/ir/dead-values.d.ts +90 -0
- package/dist/ir/dead-values.js +184 -0
- package/dist/ir/deferral.d.ts +99 -0
- package/dist/ir/deferral.js +409 -0
- package/dist/ir/dense-loops.d.ts +230 -0
- package/dist/ir/dense-loops.js +697 -0
- package/dist/ir/dominance.d.ts +82 -0
- package/dist/ir/dominance.js +268 -0
- package/dist/ir/emission-representations.d.ts +71 -0
- package/dist/ir/emission-representations.js +350 -0
- package/dist/ir/facts.d.ts +218 -0
- package/dist/ir/facts.js +181 -0
- package/dist/ir/fixed-data-definition.d.ts +19 -0
- package/dist/ir/fixed-data-definition.js +49 -0
- package/dist/ir/generator-split.d.ts +38 -0
- package/dist/ir/generator-split.js +329 -0
- package/dist/ir/hoist.d.ts +55 -0
- package/dist/ir/hoist.js +375 -0
- package/dist/ir/instantiation.d.ts +61 -0
- package/dist/ir/instantiation.js +137 -0
- package/dist/ir/integer-storage.d.ts +170 -0
- package/dist/ir/integer-storage.js +822 -0
- package/dist/ir/integers.d.ts +161 -0
- package/dist/ir/integers.js +539 -0
- package/dist/ir/integrity-restrictions.d.ts +50 -0
- package/dist/ir/integrity-restrictions.js +118 -0
- package/dist/ir/local-iterators.d.ts +4 -0
- package/dist/ir/local-iterators.js +27 -0
- package/dist/ir/lower-allocation.d.ts +4 -0
- package/dist/ir/lower-allocation.js +325 -0
- package/dist/ir/lower-completion.d.ts +15 -0
- package/dist/ir/lower-completion.js +25 -0
- package/dist/ir/lower-destructuring.d.ts +5 -0
- package/dist/ir/lower-destructuring.js +693 -0
- package/dist/ir/lower-element.d.ts +29 -0
- package/dist/ir/lower-element.js +111 -0
- package/dist/ir/lower-exceptions.d.ts +47 -0
- package/dist/ir/lower-exceptions.js +92 -0
- package/dist/ir/lower-flow.d.ts +137 -0
- package/dist/ir/lower-flow.js +600 -0
- package/dist/ir/lower-graph.d.ts +218 -0
- package/dist/ir/lower-graph.js +687 -0
- package/dist/ir/lower-invocation.d.ts +4 -0
- package/dist/ir/lower-invocation.js +514 -0
- package/dist/ir/lower-narrow.d.ts +53 -0
- package/dist/ir/lower-narrow.js +320 -0
- package/dist/ir/lower-operands.d.ts +272 -0
- package/dist/ir/lower-operands.js +461 -0
- package/dist/ir/lower-property.d.ts +21 -0
- package/dist/ir/lower-property.js +132 -0
- package/dist/ir/lower-protocol.d.ts +11 -0
- package/dist/ir/lower-protocol.js +118 -0
- package/dist/ir/lower-short-circuit.d.ts +41 -0
- package/dist/ir/lower-short-circuit.js +63 -0
- package/dist/ir/lower.d.ts +82 -0
- package/dist/ir/lower.js +1346 -0
- package/dist/ir/model.d.ts +1474 -0
- package/dist/ir/model.js +6 -0
- package/dist/ir/native-absent-property.d.ts +3 -0
- package/dist/ir/native-absent-property.js +13 -0
- package/dist/ir/native-array-transport.d.ts +7 -0
- package/dist/ir/native-array-transport.js +46 -0
- package/dist/ir/native-callable-bind.d.ts +9 -0
- package/dist/ir/native-callable-bind.js +30 -0
- package/dist/ir/native-carrier-predicate.d.ts +34 -0
- package/dist/ir/native-carrier-predicate.js +49 -0
- package/dist/ir/native-class-accessor.d.ts +18 -0
- package/dist/ir/native-class-accessor.js +52 -0
- package/dist/ir/native-class-construction.d.ts +16 -0
- package/dist/ir/native-class-construction.js +71 -0
- package/dist/ir/native-class-initialization.d.ts +15 -0
- package/dist/ir/native-class-initialization.js +56 -0
- package/dist/ir/native-class-origins.d.ts +13 -0
- package/dist/ir/native-class-origins.js +237 -0
- package/dist/ir/native-dictionary-transport.d.ts +6 -0
- package/dist/ir/native-dictionary-transport.js +37 -0
- package/dist/ir/native-enumeration.d.ts +14 -0
- package/dist/ir/native-enumeration.js +26 -0
- package/dist/ir/native-equality.d.ts +10 -0
- package/dist/ir/native-equality.js +18 -0
- package/dist/ir/native-field-owner.d.ts +37 -0
- package/dist/ir/native-field-owner.js +183 -0
- package/dist/ir/native-fixed-layout.d.ts +41 -0
- package/dist/ir/native-fixed-layout.js +232 -0
- package/dist/ir/native-host-construction.d.ts +53 -0
- package/dist/ir/native-host-construction.js +62 -0
- package/dist/ir/native-key-query.d.ts +4 -0
- package/dist/ir/native-key-query.js +38 -0
- package/dist/ir/native-merge-transport.d.ts +25 -0
- package/dist/ir/native-merge-transport.js +71 -0
- package/dist/ir/native-record-index-transport.d.ts +11 -0
- package/dist/ir/native-record-index-transport.js +34 -0
- package/dist/ir/native-record-index.d.ts +12 -0
- package/dist/ir/native-record-index.js +27 -0
- package/dist/ir/native-reflect-field.d.ts +5 -0
- package/dist/ir/native-reflect-field.js +33 -0
- package/dist/ir/native-sequence-transport.d.ts +7 -0
- package/dist/ir/native-sequence-transport.js +53 -0
- package/dist/ir/numeric-intrinsics.d.ts +13 -0
- package/dist/ir/numeric-intrinsics.js +57 -0
- package/dist/ir/object-value-conversions.d.ts +20 -0
- package/dist/ir/object-value-conversions.js +50 -0
- package/dist/ir/physical-class-reflection.d.ts +9 -0
- package/dist/ir/physical-class-reflection.js +57 -0
- package/dist/ir/presence-proof.d.ts +42 -0
- package/dist/ir/presence-proof.js +490 -0
- package/dist/ir/program-facts.d.ts +106 -0
- package/dist/ir/program-facts.js +319 -0
- package/dist/ir/proven-branches.d.ts +16 -0
- package/dist/ir/proven-branches.js +219 -0
- package/dist/ir/queries.d.ts +41 -0
- package/dist/ir/queries.js +213 -0
- package/dist/ir/reflection-demand.d.ts +64 -0
- package/dist/ir/reflection-demand.js +1394 -0
- package/dist/ir/refusal.d.ts +43 -0
- package/dist/ir/refusal.js +28 -0
- package/dist/ir/shake.d.ts +37 -0
- package/dist/ir/shake.js +1078 -0
- package/dist/ir/static-callables.d.ts +11 -0
- package/dist/ir/static-callables.js +163 -0
- package/dist/ir/string-layout-reuse.d.ts +13 -0
- package/dist/ir/string-layout-reuse.js +39 -0
- package/dist/ir/string-length-reuse.d.ts +8 -0
- package/dist/ir/string-length-reuse.js +47 -0
- package/dist/ir/transfer.d.ts +78 -0
- package/dist/ir/transfer.js +270 -0
- package/dist/ir/type-query-results.d.ts +25 -0
- package/dist/ir/type-query-results.js +96 -0
- package/dist/ir/typed-property-access.d.ts +100 -0
- package/dist/ir/typed-property-access.js +161 -0
- package/dist/ir/verify.d.ts +19 -0
- package/dist/ir/verify.js +355 -0
- package/dist/plugins/apple/constructors.d.ts +112 -0
- package/dist/plugins/apple/constructors.js +217 -0
- package/dist/plugins/apple/host.d.ts +181 -0
- package/dist/plugins/apple/host.js +262 -0
- package/dist/plugins/apple/jsx.d.ts +2 -0
- package/dist/plugins/apple/jsx.js +293 -0
- package/dist/plugins/apple/members.d.ts +16 -0
- package/dist/plugins/apple/members.js +190 -0
- package/dist/plugins/apple/plugin.d.ts +2 -0
- package/dist/plugins/apple/plugin.js +156 -0
- package/dist/plugins/gea/component-classes.d.ts +25 -0
- package/dist/plugins/gea/component-classes.js +162 -0
- package/dist/plugins/gea/component-inline.d.ts +13 -0
- package/dist/plugins/gea/component-inline.js +532 -0
- package/dist/plugins/gea/constructors.d.ts +23 -0
- package/dist/plugins/gea/constructors.js +100 -0
- package/dist/plugins/gea/contract.d.ts +150 -0
- package/dist/plugins/gea/contract.js +195 -0
- package/dist/plugins/gea/element-ref.d.ts +31 -0
- package/dist/plugins/gea/element-ref.js +45 -0
- package/dist/plugins/gea/host.d.ts +520 -0
- package/dist/plugins/gea/host.js +762 -0
- package/dist/plugins/gea/lower.d.ts +6 -0
- package/dist/plugins/gea/lower.js +195 -0
- package/dist/plugins/gea/members.d.ts +22 -0
- package/dist/plugins/gea/members.js +221 -0
- package/dist/plugins/gea/plugin.d.ts +22 -0
- package/dist/plugins/gea/plugin.js +307 -0
- package/dist/plugins/gea/prelude.d.ts +78 -0
- package/dist/plugins/gea/prelude.js +153 -0
- package/dist/plugins/gea/producer.d.ts +5 -0
- package/dist/plugins/gea/producer.js +52 -0
- package/dist/plugins/gea/reactive-slots.d.ts +49 -0
- package/dist/plugins/gea/reactive-slots.js +578 -0
- package/dist/plugins/gea/render-bridge.d.ts +6 -0
- package/dist/plugins/gea/render-bridge.js +281 -0
- package/dist/plugins/gea/slots.d.ts +15 -0
- package/dist/plugins/gea/slots.js +36 -0
- package/dist/plugins/gea/template-analysis.d.ts +151 -0
- package/dist/plugins/gea/template-analysis.js +346 -0
- package/dist/plugins/gea/user-agent-styles.d.ts +9 -0
- package/dist/plugins/gea/user-agent-styles.js +94 -0
- package/dist/plugins/installed.d.ts +19 -0
- package/dist/plugins/installed.js +21 -0
- package/dist/plugins/load.d.ts +7 -0
- package/dist/plugins/load.js +207 -0
- package/dist/plugins/model.d.ts +735 -0
- package/dist/plugins/model.js +47 -0
- package/dist/plugins/webgl/host.d.ts +77 -0
- package/dist/plugins/webgl/host.js +162 -0
- package/dist/plugins/webgl/plugin.d.ts +40 -0
- package/dist/plugins/webgl/plugin.js +99 -0
- package/dist/preflight/obligations.d.ts +206 -0
- package/dist/preflight/obligations.js +36 -0
- package/dist/preflight/report.d.ts +20 -0
- package/dist/preflight/report.js +61 -0
- package/dist/preflight/run.d.ts +39 -0
- package/dist/preflight/run.js +403 -0
- package/dist/project-preparation.d.ts +33 -0
- package/dist/project-preparation.js +314 -0
- package/dist/projection/abi.d.ts +82 -0
- package/dist/projection/abi.js +349 -0
- package/dist/projection/apply-arguments.d.ts +12 -0
- package/dist/projection/apply-arguments.js +20 -0
- package/dist/projection/bindings.d.ts +250 -0
- package/dist/projection/bindings.js +340 -0
- package/dist/projection/callee.d.ts +196 -0
- package/dist/projection/callee.js +444 -0
- package/dist/projection/class-property-presence.d.ts +28 -0
- package/dist/projection/class-property-presence.js +58 -0
- package/dist/projection/class-prototype.d.ts +5 -0
- package/dist/projection/class-prototype.js +23 -0
- package/dist/projection/class-storage.d.ts +26 -0
- package/dist/projection/class-storage.js +236 -0
- package/dist/projection/classes.d.ts +283 -0
- package/dist/projection/classes.js +944 -0
- package/dist/projection/coercions.d.ts +20 -0
- package/dist/projection/coercions.js +33 -0
- package/dist/projection/dispatch.d.ts +167 -0
- package/dist/projection/dispatch.js +379 -0
- package/dist/projection/fields.d.ts +123 -0
- package/dist/projection/fields.js +383 -0
- package/dist/projection/instance-test.d.ts +78 -0
- package/dist/projection/instance-test.js +156 -0
- package/dist/projection/slots.d.ts +146 -0
- package/dist/projection/slots.js +663 -0
- package/dist/projection/synthesized-abi.d.ts +61 -0
- package/dist/projection/synthesized-abi.js +94 -0
- package/dist/representation/array-index.d.ts +14 -0
- package/dist/representation/array-index.js +17 -0
- package/dist/representation/callable-object.d.ts +3 -0
- package/dist/representation/callable-object.js +6 -0
- package/dist/representation/collections.d.ts +84 -0
- package/dist/representation/collections.js +139 -0
- package/dist/representation/derive.d.ts +159 -0
- package/dist/representation/derive.js +2546 -0
- package/dist/representation/difference.d.ts +30 -0
- package/dist/representation/difference.js +240 -0
- package/dist/representation/field-descriptor-policy.d.ts +19 -0
- package/dist/representation/field-descriptor-policy.js +39 -0
- package/dist/representation/function-constructor.d.ts +13 -0
- package/dist/representation/function-constructor.js +9 -0
- package/dist/representation/host-abi.d.ts +32 -0
- package/dist/representation/host-abi.js +97 -0
- package/dist/representation/host-templates.d.ts +67 -0
- package/dist/representation/host-templates.js +94 -0
- package/dist/representation/intersection.d.ts +84 -0
- package/dist/representation/intersection.js +149 -0
- package/dist/representation/literal-destination.d.ts +43 -0
- package/dist/representation/literal-destination.js +133 -0
- package/dist/representation/merge.d.ts +18 -0
- package/dist/representation/merge.js +83 -0
- package/dist/representation/model.d.ts +1160 -0
- package/dist/representation/model.js +1019 -0
- package/dist/representation/numeric-index.d.ts +13 -0
- package/dist/representation/numeric-index.js +29 -0
- package/dist/representation/object-shape.d.ts +109 -0
- package/dist/representation/object-shape.js +123 -0
- package/dist/representation/optional.d.ts +12 -0
- package/dist/representation/optional.js +87 -0
- package/dist/representation/plan.d.ts +60 -0
- package/dist/representation/plan.js +78 -0
- package/dist/representation/policies.d.ts +589 -0
- package/dist/representation/policies.js +107 -0
- package/dist/representation/primitive-domain.d.ts +1 -0
- package/dist/representation/primitive-domain.js +1 -0
- package/dist/representation/primitives.d.ts +44 -0
- package/dist/representation/primitives.js +78 -0
- package/dist/representation/publish.d.ts +49 -0
- package/dist/representation/publish.js +648 -0
- package/dist/representation/record-fields.d.ts +96 -0
- package/dist/representation/record-fields.js +116 -0
- package/dist/representation/template-object.d.ts +11 -0
- package/dist/representation/template-object.js +26 -0
- package/dist/representation/union.d.ts +30 -0
- package/dist/representation/union.js +324 -0
- package/dist/representation/value-records.d.ts +3 -0
- package/dist/representation/value-records.js +307 -0
- package/dist/representation/verify.d.ts +17 -0
- package/dist/representation/verify.js +221 -0
- package/dist/semantics/alias-this-field-declaration-transform.d.ts +4 -0
- package/dist/semantics/alias-this-field-declaration-transform.js +207 -0
- package/dist/semantics/ambient-type-realization-transform.d.ts +62 -0
- package/dist/semantics/ambient-type-realization-transform.js +168 -0
- package/dist/semantics/ambient.d.ts +24 -0
- package/dist/semantics/ambient.js +119 -0
- package/dist/semantics/borrowed-builtin-call-bind-source-transform.d.ts +4 -0
- package/dist/semantics/borrowed-builtin-call-bind-source-transform.js +341 -0
- package/dist/semantics/callable-origins.d.ts +46 -0
- package/dist/semantics/callable-origins.js +354 -0
- package/dist/semantics/class-alias.d.ts +7 -0
- package/dist/semantics/class-alias.js +37 -0
- package/dist/semantics/class-heritage.d.ts +34 -0
- package/dist/semantics/class-heritage.js +104 -0
- package/dist/semantics/commonjs-wrapper.d.ts +69 -0
- package/dist/semantics/commonjs-wrapper.js +231 -0
- package/dist/semantics/constructor-slot-subclasses.d.ts +28 -0
- package/dist/semantics/constructor-slot-subclasses.js +112 -0
- package/dist/semantics/declaration-overlay-transform.d.ts +35 -0
- package/dist/semantics/declaration-overlay-transform.js +2157 -0
- package/dist/semantics/define-property-source-transform.d.ts +4 -0
- package/dist/semantics/define-property-source-transform.js +437 -0
- package/dist/semantics/diagnostic-source-preparation.d.ts +24 -0
- package/dist/semantics/diagnostic-source-preparation.js +82 -0
- package/dist/semantics/documentation-ranges.d.ts +22 -0
- package/dist/semantics/documentation-ranges.js +36 -0
- package/dist/semantics/dynamic-fallback.d.ts +86 -0
- package/dist/semantics/dynamic-fallback.js +249 -0
- package/dist/semantics/frontend-timing.d.ts +6 -0
- package/dist/semantics/frontend-timing.js +35 -0
- package/dist/semantics/frontend.d.ts +504 -0
- package/dist/semantics/frontend.js +1157 -0
- package/dist/semantics/host-declaration-provenance.d.ts +11 -0
- package/dist/semantics/host-declaration-provenance.js +18 -0
- package/dist/semantics/host-methods.d.ts +24 -0
- package/dist/semantics/host-methods.js +74 -0
- package/dist/semantics/host-protocols.d.ts +429 -0
- package/dist/semantics/host-protocols.js +1501 -0
- package/dist/semantics/inherited-accessor.d.ts +7 -0
- package/dist/semantics/inherited-accessor.js +48 -0
- package/dist/semantics/interface-families.d.ts +70 -0
- package/dist/semantics/interface-families.js +180 -0
- package/dist/semantics/interface-implementors.d.ts +53 -0
- package/dist/semantics/interface-implementors.js +87 -0
- package/dist/semantics/jsdoc-namepath-transform.d.ts +4 -0
- package/dist/semantics/jsdoc-namepath-transform.js +85 -0
- package/dist/semantics/model/coverage.d.ts +68 -0
- package/dist/semantics/model/coverage.js +73 -0
- package/dist/semantics/model/edges.d.ts +103 -0
- package/dist/semantics/model/edges.js +20 -0
- package/dist/semantics/model/graph.d.ts +55 -0
- package/dist/semantics/model/graph.js +129 -0
- package/dist/semantics/model/operands.d.ts +159 -0
- package/dist/semantics/model/operands.js +26 -0
- package/dist/semantics/model/operations.d.ts +496 -0
- package/dist/semantics/model/operations.js +2 -0
- package/dist/semantics/model/primitive-domain.d.ts +26 -0
- package/dist/semantics/model/primitive-domain.js +38 -0
- package/dist/semantics/model/selected-signature.d.ts +261 -0
- package/dist/semantics/model/selected-signature.js +55 -0
- package/dist/semantics/model/structural-type-table.d.ts +93 -0
- package/dist/semantics/model/structural-type-table.js +237 -0
- package/dist/semantics/model/structural-types.d.ts +367 -0
- package/dist/semantics/model/structural-types.js +200 -0
- package/dist/semantics/module-resolution.d.ts +23 -0
- package/dist/semantics/module-resolution.js +227 -0
- package/dist/semantics/new-callee-class-tag-source-transform.d.ts +4 -0
- package/dist/semantics/new-callee-class-tag-source-transform.js +64 -0
- package/dist/semantics/node-project.d.ts +13 -0
- package/dist/semantics/node-project.js +107 -0
- package/dist/semantics/node-source-hooks.d.ts +1 -0
- package/dist/semantics/node-source-hooks.js +63 -0
- package/dist/semantics/normalize/absent-globals.d.ts +143 -0
- package/dist/semantics/normalize/absent-globals.js +191 -0
- package/dist/semantics/normalize/arguments-objects.d.ts +43 -0
- package/dist/semantics/normalize/arguments-objects.js +60 -0
- package/dist/semantics/normalize/asserted-arm-absence.d.ts +28 -0
- package/dist/semantics/normalize/asserted-arm-absence.js +61 -0
- package/dist/semantics/normalize/assignment-patterns.d.ts +70 -0
- package/dist/semantics/normalize/assignment-patterns.js +147 -0
- package/dist/semantics/normalize/bag-absence.d.ts +8 -0
- package/dist/semantics/normalize/bag-absence.js +42 -0
- package/dist/semantics/normalize/binding-fixpoint.d.ts +36 -0
- package/dist/semantics/normalize/binding-fixpoint.js +140 -0
- package/dist/semantics/normalize/callback-parameter-contracts.d.ts +16 -0
- package/dist/semantics/normalize/callback-parameter-contracts.js +91 -0
- package/dist/semantics/normalize/cells/agreement.d.ts +46 -0
- package/dist/semantics/normalize/cells/agreement.js +34 -0
- package/dist/semantics/normalize/cells/candidates.d.ts +17 -0
- package/dist/semantics/normalize/cells/candidates.js +35 -0
- package/dist/semantics/normalize/cells/facts.d.ts +19 -0
- package/dist/semantics/normalize/cells/facts.js +90 -0
- package/dist/semantics/normalize/cells/index.d.ts +10 -0
- package/dist/semantics/normalize/cells/index.js +6 -0
- package/dist/semantics/normalize/cells/model.d.ts +98 -0
- package/dist/semantics/normalize/cells/model.js +2 -0
- package/dist/semantics/normalize/cells/policies/bag.d.ts +44 -0
- package/dist/semantics/normalize/cells/policies/bag.js +114 -0
- package/dist/semantics/normalize/cells/policies/collection.d.ts +42 -0
- package/dist/semantics/normalize/cells/policies/collection.js +218 -0
- package/dist/semantics/normalize/cells/policies/field.d.ts +28 -0
- package/dist/semantics/normalize/cells/policies/field.js +40 -0
- package/dist/semantics/normalize/cells/policies/index.d.ts +49 -0
- package/dist/semantics/normalize/cells/policies/index.js +58 -0
- package/dist/semantics/normalize/cells/policies/local.d.ts +18 -0
- package/dist/semantics/normalize/cells/policies/local.js +37 -0
- package/dist/semantics/normalize/cells/policies/parameter.d.ts +28 -0
- package/dist/semantics/normalize/cells/policies/parameter.js +39 -0
- package/dist/semantics/normalize/cells/policies/return.d.ts +26 -0
- package/dist/semantics/normalize/cells/policies/return.js +45 -0
- package/dist/semantics/normalize/cells/policies/shared.d.ts +33 -0
- package/dist/semantics/normalize/cells/policies/shared.js +45 -0
- package/dist/semantics/normalize/cells/policy.d.ts +72 -0
- package/dist/semantics/normalize/cells/policy.js +18 -0
- package/dist/semantics/normalize/cells/registry.d.ts +14 -0
- package/dist/semantics/normalize/cells/registry.js +17 -0
- package/dist/semantics/normalize/census-refusal.d.ts +62 -0
- package/dist/semantics/normalize/census-refusal.js +27 -0
- package/dist/semantics/normalize/census.d.ts +109 -0
- package/dist/semantics/normalize/census.js +667 -0
- package/dist/semantics/normalize/collection-bindings.d.ts +278 -0
- package/dist/semantics/normalize/collection-bindings.js +677 -0
- package/dist/semantics/normalize/commonjs-module-record.d.ts +21 -0
- package/dist/semantics/normalize/commonjs-module-record.js +289 -0
- package/dist/semantics/normalize/commonjs-require.d.ts +13 -0
- package/dist/semantics/normalize/commonjs-require.js +1527 -0
- package/dist/semantics/normalize/contribution.d.ts +63 -0
- package/dist/semantics/normalize/contribution.js +172 -0
- package/dist/semantics/normalize/dead-typeof-guards.d.ts +64 -0
- package/dist/semantics/normalize/dead-typeof-guards.js +152 -0
- package/dist/semantics/normalize/deferred-intrinsic-protocols.d.ts +57 -0
- package/dist/semantics/normalize/deferred-intrinsic-protocols.js +109 -0
- package/dist/semantics/normalize/derived-expression-type.d.ts +1070 -0
- package/dist/semantics/normalize/derived-expression-type.js +3463 -0
- package/dist/semantics/normalize/evaluation-order.d.ts +16 -0
- package/dist/semantics/normalize/evaluation-order.js +37 -0
- package/dist/semantics/normalize/field-bindings.d.ts +167 -0
- package/dist/semantics/normalize/field-bindings.js +1125 -0
- package/dist/semantics/normalize/flow/array-element-continuation.d.ts +27 -0
- package/dist/semantics/normalize/flow/array-element-continuation.js +1452 -0
- package/dist/semantics/normalize/flow/callable-array-origins.d.ts +42 -0
- package/dist/semantics/normalize/flow/callable-array-origins.js +318 -0
- package/dist/semantics/normalize/flow/callable-completions.d.ts +45 -0
- package/dist/semantics/normalize/flow/callable-completions.js +82 -0
- package/dist/semantics/normalize/flow/callable-reach.d.ts +237 -0
- package/dist/semantics/normalize/flow/callable-reach.js +7174 -0
- package/dist/semantics/normalize/flow/class-family-member-read.d.ts +16 -0
- package/dist/semantics/normalize/flow/class-family-member-read.js +992 -0
- package/dist/semantics/normalize/flow/collection-value-continuation.d.ts +21 -0
- package/dist/semantics/normalize/flow/collection-value-continuation.js +192 -0
- package/dist/semantics/normalize/flow/component-solver.d.ts +199 -0
- package/dist/semantics/normalize/flow/component-solver.js +587 -0
- package/dist/semantics/normalize/flow/computed-key-set.d.ts +84 -0
- package/dist/semantics/normalize/flow/computed-key-set.js +660 -0
- package/dist/semantics/normalize/flow/export-importers.d.ts +24 -0
- package/dist/semantics/normalize/flow/export-importers.js +269 -0
- package/dist/semantics/normalize/flow/host-text-sink.d.ts +25 -0
- package/dist/semantics/normalize/flow/host-text-sink.js +87 -0
- package/dist/semantics/normalize/flow/intrinsic-array-callback-frames.d.ts +84 -0
- package/dist/semantics/normalize/flow/intrinsic-array-callback-frames.js +180 -0
- package/dist/semantics/normalize/flow/intrinsic-data-definition.d.ts +35 -0
- package/dist/semantics/normalize/flow/intrinsic-data-definition.js +140 -0
- package/dist/semantics/normalize/flow/invocation-facts.d.ts +98 -0
- package/dist/semantics/normalize/flow/invocation-facts.js +257 -0
- package/dist/semantics/normalize/flow/member-call-forwarding.d.ts +122 -0
- package/dist/semantics/normalize/flow/member-call-forwarding.js +835 -0
- package/dist/semantics/normalize/flow/model.d.ts +357 -0
- package/dist/semantics/normalize/flow/model.js +177 -0
- package/dist/semantics/normalize/flow/native-collection-protocol.d.ts +24 -0
- package/dist/semantics/normalize/flow/native-collection-protocol.js +252 -0
- package/dist/semantics/normalize/flow/node-path-token.d.ts +3 -0
- package/dist/semantics/normalize/flow/node-path-token.js +53 -0
- package/dist/semantics/normalize/flow/object-binding-continuation.d.ts +11 -0
- package/dist/semantics/normalize/flow/object-binding-continuation.js +42 -0
- package/dist/semantics/normalize/flow/origin-authority.d.ts +56 -0
- package/dist/semantics/normalize/flow/origin-authority.js +2 -0
- package/dist/semantics/normalize/flow/owned-class-receivers.d.ts +35 -0
- package/dist/semantics/normalize/flow/owned-class-receivers.js +191 -0
- package/dist/semantics/normalize/flow/parameter-values.d.ts +27 -0
- package/dist/semantics/normalize/flow/parameter-values.js +251 -0
- package/dist/semantics/normalize/flow/proof-hypotheses.d.ts +66 -0
- package/dist/semantics/normalize/flow/proof-hypotheses.js +162 -0
- package/dist/semantics/normalize/flow/record-alias-closure.d.ts +27 -0
- package/dist/semantics/normalize/flow/record-alias-closure.js +298 -0
- package/dist/semantics/normalize/flow/seeded-origins.d.ts +43 -0
- package/dist/semantics/normalize/flow/seeded-origins.js +54 -0
- package/dist/semantics/normalize/flow/source-class-data.d.ts +132 -0
- package/dist/semantics/normalize/flow/source-class-data.js +838 -0
- package/dist/semantics/normalize/flow/source-class-instanceof.d.ts +13 -0
- package/dist/semantics/normalize/flow/source-class-instanceof.js +37 -0
- package/dist/semantics/normalize/flow/source-class-static-data.d.ts +16 -0
- package/dist/semantics/normalize/flow/source-class-static-data.js +47 -0
- package/dist/semantics/normalize/flow/source-construction-frames.d.ts +12 -0
- package/dist/semantics/normalize/flow/source-construction-frames.js +118 -0
- package/dist/semantics/normalize/flow/source-invocation-frame-layout.d.ts +34 -0
- package/dist/semantics/normalize/flow/source-invocation-frame-layout.js +78 -0
- package/dist/semantics/normalize/flow/source-invocation-receiver.d.ts +37 -0
- package/dist/semantics/normalize/flow/source-invocation-receiver.js +95 -0
- package/dist/semantics/normalize/flow/source-prototype-method-identity.d.ts +23 -0
- package/dist/semantics/normalize/flow/source-prototype-method-identity.js +81 -0
- package/dist/semantics/normalize/flow/source-record-data.d.ts +29 -0
- package/dist/semantics/normalize/flow/source-record-data.js +626 -0
- package/dist/semantics/normalize/flow/source-value-session.d.ts +77 -0
- package/dist/semantics/normalize/flow/source-value-session.js +3089 -0
- package/dist/semantics/normalize/flow/targets.d.ts +118 -0
- package/dist/semantics/normalize/flow/targets.js +405 -0
- package/dist/semantics/normalize/flow/value-flow.d.ts +36 -0
- package/dist/semantics/normalize/flow/value-flow.js +823 -0
- package/dist/semantics/normalize/flow/value-provenance.d.ts +31 -0
- package/dist/semantics/normalize/flow/value-provenance.js +112 -0
- package/dist/semantics/normalize/gating.d.ts +51 -0
- package/dist/semantics/normalize/gating.js +560 -0
- package/dist/semantics/normalize/generic-function-choice.d.ts +31 -0
- package/dist/semantics/normalize/generic-function-choice.js +115 -0
- package/dist/semantics/normalize/global-host-mutations.d.ts +51 -0
- package/dist/semantics/normalize/global-host-mutations.js +5989 -0
- package/dist/semantics/normalize/host-effect-contracts.d.ts +77 -0
- package/dist/semantics/normalize/host-effect-contracts.js +143 -0
- package/dist/semantics/normalize/host-mutation-computed-keys.d.ts +38 -0
- package/dist/semantics/normalize/host-mutation-computed-keys.js +26 -0
- package/dist/semantics/normalize/host-mutation-key-reader.d.ts +66 -0
- package/dist/semantics/normalize/host-mutation-key-reader.js +192 -0
- package/dist/semantics/normalize/host-mutation-keys.d.ts +114 -0
- package/dist/semantics/normalize/host-mutation-keys.js +183 -0
- package/dist/semantics/normalize/identities.d.ts +172 -0
- package/dist/semantics/normalize/identities.js +426 -0
- package/dist/semantics/normalize/implicit-arguments-tuple.d.ts +97 -0
- package/dist/semantics/normalize/implicit-arguments-tuple.js +197 -0
- package/dist/semantics/normalize/implicit-arguments.d.ts +11 -0
- package/dist/semantics/normalize/implicit-arguments.js +39 -0
- package/dist/semantics/normalize/instantiation.d.ts +73 -0
- package/dist/semantics/normalize/instantiation.js +399 -0
- package/dist/semantics/normalize/intrinsic-property-call.d.ts +18 -0
- package/dist/semantics/normalize/intrinsic-property-call.js +69 -0
- package/dist/semantics/normalize/intrinsic-prototype.d.ts +41 -0
- package/dist/semantics/normalize/intrinsic-prototype.js +87 -0
- package/dist/semantics/normalize/intrinsic-static-member.d.ts +14 -0
- package/dist/semantics/normalize/intrinsic-static-member.js +23 -0
- package/dist/semantics/normalize/jsdoc-type-names.d.ts +32 -0
- package/dist/semantics/normalize/jsdoc-type-names.js +512 -0
- package/dist/semantics/normalize/keyof.d.ts +32 -0
- package/dist/semantics/normalize/keyof.js +110 -0
- package/dist/semantics/normalize/local-bindings.d.ts +176 -0
- package/dist/semantics/normalize/local-bindings.js +1826 -0
- package/dist/semantics/normalize/logical-result-type.d.ts +16 -0
- package/dist/semantics/normalize/logical-result-type.js +102 -0
- package/dist/semantics/normalize/namespace-paths.d.ts +57 -0
- package/dist/semantics/normalize/namespace-paths.js +108 -0
- package/dist/semantics/normalize/normalize.d.ts +57 -0
- package/dist/semantics/normalize/normalize.js +68 -0
- package/dist/semantics/normalize/object-bag-bindings.d.ts +305 -0
- package/dist/semantics/normalize/object-bag-bindings.js +1290 -0
- package/dist/semantics/normalize/omitted-stated-parameter.d.ts +53 -0
- package/dist/semantics/normalize/omitted-stated-parameter.js +59 -0
- package/dist/semantics/normalize/open-type-form.d.ts +10 -0
- package/dist/semantics/normalize/open-type-form.js +32 -0
- package/dist/semantics/normalize/parameter-bindings.d.ts +361 -0
- package/dist/semantics/normalize/parameter-bindings.js +3339 -0
- package/dist/semantics/normalize/parameter-slot.d.ts +264 -0
- package/dist/semantics/normalize/parameter-slot.js +491 -0
- package/dist/semantics/normalize/physical-overload-result.d.ts +77 -0
- package/dist/semantics/normalize/physical-overload-result.js +99 -0
- package/dist/semantics/normalize/primitive-property-absence.d.ts +12 -0
- package/dist/semantics/normalize/primitive-property-absence.js +60 -0
- package/dist/semantics/normalize/producer-context.d.ts +376 -0
- package/dist/semantics/normalize/producer-context.js +1 -0
- package/dist/semantics/normalize/producers/allocations.d.ts +3 -0
- package/dist/semantics/normalize/producers/allocations.js +863 -0
- package/dist/semantics/normalize/producers/binding-kind.d.ts +37 -0
- package/dist/semantics/normalize/producers/binding-kind.js +36 -0
- package/dist/semantics/normalize/producers/bindings.d.ts +85 -0
- package/dist/semantics/normalize/producers/bindings.js +710 -0
- package/dist/semantics/normalize/producers/boundary.d.ts +34 -0
- package/dist/semantics/normalize/producers/boundary.js +123 -0
- package/dist/semantics/normalize/producers/class-lifecycle.d.ts +3 -0
- package/dist/semantics/normalize/producers/class-lifecycle.js +902 -0
- package/dist/semantics/normalize/producers/computations.d.ts +3 -0
- package/dist/semantics/normalize/producers/computations.js +613 -0
- package/dist/semantics/normalize/producers/control-loops.d.ts +30 -0
- package/dist/semantics/normalize/producers/control-loops.js +91 -0
- package/dist/semantics/normalize/producers/control.d.ts +30 -0
- package/dist/semantics/normalize/producers/control.js +923 -0
- package/dist/semantics/normalize/producers/declaration-lifecycle.d.ts +3 -0
- package/dist/semantics/normalize/producers/declaration-lifecycle.js +390 -0
- package/dist/semantics/normalize/producers/destructuring.d.ts +45 -0
- package/dist/semantics/normalize/producers/destructuring.js +1180 -0
- package/dist/semantics/normalize/producers/dynamic-language.d.ts +3 -0
- package/dist/semantics/normalize/producers/dynamic-language.js +70 -0
- package/dist/semantics/normalize/producers/erasure.d.ts +51 -0
- package/dist/semantics/normalize/producers/erasure.js +90 -0
- package/dist/semantics/normalize/producers/installed.d.ts +3 -0
- package/dist/semantics/normalize/producers/installed.js +55 -0
- package/dist/semantics/normalize/producers/invocations.d.ts +35 -0
- package/dist/semantics/normalize/producers/invocations.js +1796 -0
- package/dist/semantics/normalize/producers/iteration-yield.d.ts +59 -0
- package/dist/semantics/normalize/producers/iteration-yield.js +235 -0
- package/dist/semantics/normalize/producers/jsx.d.ts +3 -0
- package/dist/semantics/normalize/producers/jsx.js +360 -0
- package/dist/semantics/normalize/producers/mint.d.ts +39 -0
- package/dist/semantics/normalize/producers/mint.js +44 -0
- package/dist/semantics/normalize/producers/nullish.d.ts +16 -0
- package/dist/semantics/normalize/producers/nullish.js +27 -0
- package/dist/semantics/normalize/producers/object-assignment.d.ts +8 -0
- package/dist/semantics/normalize/producers/object-assignment.js +204 -0
- package/dist/semantics/normalize/producers/object-tag.d.ts +9 -0
- package/dist/semantics/normalize/producers/object-tag.js +119 -0
- package/dist/semantics/normalize/producers/optional-chain.d.ts +44 -0
- package/dist/semantics/normalize/producers/optional-chain.js +75 -0
- package/dist/semantics/normalize/producers/properties.d.ts +21 -0
- package/dist/semantics/normalize/producers/properties.js +1053 -0
- package/dist/semantics/normalize/producers/protocol.d.ts +67 -0
- package/dist/semantics/normalize/producers/protocol.js +695 -0
- package/dist/semantics/normalize/producers/references.d.ts +53 -0
- package/dist/semantics/normalize/producers/references.js +1027 -0
- package/dist/semantics/normalize/producers/shared.d.ts +561 -0
- package/dist/semantics/normalize/producers/shared.js +1683 -0
- package/dist/semantics/normalize/producers/spread-arguments.d.ts +72 -0
- package/dist/semantics/normalize/producers/spread-arguments.js +375 -0
- package/dist/semantics/normalize/producers/tagged-template.d.ts +5 -0
- package/dist/semantics/normalize/producers/tagged-template.js +307 -0
- package/dist/semantics/normalize/producers/tuple-spread.d.ts +189 -0
- package/dist/semantics/normalize/producers/tuple-spread.js +279 -0
- package/dist/semantics/normalize/property-key-domain.d.ts +36 -0
- package/dist/semantics/normalize/property-key-domain.js +150 -0
- package/dist/semantics/normalize/reachability.d.ts +189 -0
- package/dist/semantics/normalize/reachability.js +1057 -0
- package/dist/semantics/normalize/reassigned-bindings.d.ts +13 -0
- package/dist/semantics/normalize/reassigned-bindings.js +41 -0
- package/dist/semantics/normalize/record-storage-families.d.ts +11 -0
- package/dist/semantics/normalize/record-storage-families.js +109 -0
- package/dist/semantics/normalize/return-bindings.d.ts +260 -0
- package/dist/semantics/normalize/return-bindings.js +1311 -0
- package/dist/semantics/normalize/return-paths.d.ts +2 -0
- package/dist/semantics/normalize/return-paths.js +28 -0
- package/dist/semantics/normalize/script-global-redefinition.d.ts +44 -0
- package/dist/semantics/normalize/script-global-redefinition.js +75 -0
- package/dist/semantics/normalize/specialization.d.ts +201 -0
- package/dist/semantics/normalize/specialization.js +1824 -0
- package/dist/semantics/normalize/structural-array-element.d.ts +176 -0
- package/dist/semantics/normalize/structural-array-element.js +700 -0
- package/dist/semantics/normalize/structural-array-read.d.ts +13 -0
- package/dist/semantics/normalize/structural-array-read.js +124 -0
- package/dist/semantics/normalize/structural-callable.d.ts +12 -0
- package/dist/semantics/normalize/structural-callable.js +82 -0
- package/dist/semantics/normalize/structural-creation-order.d.ts +32 -0
- package/dist/semantics/normalize/structural-creation-order.js +111 -0
- package/dist/semantics/normalize/structural-declarations.d.ts +395 -0
- package/dist/semantics/normalize/structural-declarations.js +968 -0
- package/dist/semantics/normalize/structural-declared-body.d.ts +25 -0
- package/dist/semantics/normalize/structural-declared-body.js +147 -0
- package/dist/semantics/normalize/structural-generics.d.ts +56 -0
- package/dist/semantics/normalize/structural-generics.js +120 -0
- package/dist/semantics/normalize/structural-indexed-access.d.ts +11 -0
- package/dist/semantics/normalize/structural-indexed-access.js +126 -0
- package/dist/semantics/normalize/structural-instantiated-member.d.ts +64 -0
- package/dist/semantics/normalize/structural-instantiated-member.js +407 -0
- package/dist/semantics/normalize/structural-joins.d.ts +44 -0
- package/dist/semantics/normalize/structural-joins.js +143 -0
- package/dist/semantics/normalize/structural-layout-relevance.d.ts +29 -0
- package/dist/semantics/normalize/structural-layout-relevance.js +391 -0
- package/dist/semantics/normalize/structural-layout-type.d.ts +11 -0
- package/dist/semantics/normalize/structural-layout-type.js +1468 -0
- package/dist/semantics/normalize/structural-leaves.d.ts +49 -0
- package/dist/semantics/normalize/structural-leaves.js +125 -0
- package/dist/semantics/normalize/structural-local-union.d.ts +13 -0
- package/dist/semantics/normalize/structural-local-union.js +133 -0
- package/dist/semantics/normalize/structural-members.d.ts +26 -0
- package/dist/semantics/normalize/structural-members.js +84 -0
- package/dist/semantics/normalize/structural-mutable-method.d.ts +15 -0
- package/dist/semantics/normalize/structural-mutable-method.js +109 -0
- package/dist/semantics/normalize/structural-parts.d.ts +131 -0
- package/dist/semantics/normalize/structural-parts.js +737 -0
- package/dist/semantics/normalize/structural-receiver.d.ts +66 -0
- package/dist/semantics/normalize/structural-receiver.js +551 -0
- package/dist/semantics/normalize/structural-rules.d.ts +112 -0
- package/dist/semantics/normalize/structural-rules.js +93 -0
- package/dist/semantics/normalize/structural-self-reference.d.ts +150 -0
- package/dist/semantics/normalize/structural-self-reference.js +494 -0
- package/dist/semantics/normalize/structural.d.ts +202 -0
- package/dist/semantics/normalize/structural.js +4218 -0
- package/dist/semantics/normalize/unreduced-type-form.d.ts +41 -0
- package/dist/semantics/normalize/unreduced-type-form.js +53 -0
- package/dist/semantics/normalize/unresolvable-names.d.ts +56 -0
- package/dist/semantics/normalize/unresolvable-names.js +140 -0
- package/dist/semantics/package-sources.d.ts +16 -0
- package/dist/semantics/package-sources.js +365 -0
- package/dist/semantics/program.d.ts +151 -0
- package/dist/semantics/program.js +667 -0
- package/dist/semantics/prototype-install-source-transform.d.ts +4 -0
- package/dist/semantics/prototype-install-source-transform.js +341 -0
- package/dist/semantics/prototype-object-class-source-transform.d.ts +4 -0
- package/dist/semantics/prototype-object-class-source-transform.js +525 -0
- package/dist/semantics/prototype-reparenting.d.ts +50 -0
- package/dist/semantics/prototype-reparenting.js +317 -0
- package/dist/semantics/stable-checker.d.ts +10 -0
- package/dist/semantics/stable-checker.js +148 -0
- package/dist/semantics/subclass-member-overlay-transform.d.ts +35 -0
- package/dist/semantics/subclass-member-overlay-transform.js +1418 -0
- package/dist/semantics/symbol-keyed-expando-source-transform.d.ts +4 -0
- package/dist/semantics/symbol-keyed-expando-source-transform.js +66 -0
- package/dist/semantics/this-constructor-source-transform.d.ts +4 -0
- package/dist/semantics/this-constructor-source-transform.js +122 -0
- package/dist/semantics/uninstantiable-classes.d.ts +22 -0
- package/dist/semantics/uninstantiable-classes.js +75 -0
- package/dist/targets/cpp/balanced-units.d.ts +3 -0
- package/dist/targets/cpp/balanced-units.js +58 -0
- package/dist/targets/cpp/borrowed-call-entry.d.ts +30 -0
- package/dist/targets/cpp/borrowed-call-entry.js +68 -0
- package/dist/targets/cpp/captures.d.ts +68 -0
- package/dist/targets/cpp/captures.js +269 -0
- package/dist/targets/cpp/class-layout.d.ts +313 -0
- package/dist/targets/cpp/class-layout.js +483 -0
- package/dist/targets/cpp/class-properties/computed-method-value.d.ts +25 -0
- package/dist/targets/cpp/class-properties/computed-method-value.js +22 -0
- package/dist/targets/cpp/class-properties/emit-class-properties.d.ts +216 -0
- package/dist/targets/cpp/class-properties/emit-class-properties.js +917 -0
- package/dist/targets/cpp/class-properties/native-prototype.d.ts +11 -0
- package/dist/targets/cpp/class-properties/native-prototype.js +101 -0
- package/dist/targets/cpp/class-ref-transport.d.ts +12 -0
- package/dist/targets/cpp/class-ref-transport.js +32 -0
- package/dist/targets/cpp/conversions.d.ts +3 -0
- package/dist/targets/cpp/conversions.js +2027 -0
- package/dist/targets/cpp/deferral-safety.d.ts +82 -0
- package/dist/targets/cpp/deferral-safety.js +86 -0
- package/dist/targets/cpp/direct-call-receivers.d.ts +37 -0
- package/dist/targets/cpp/direct-call-receivers.js +79 -0
- package/dist/targets/cpp/document.d.ts +74 -0
- package/dist/targets/cpp/document.js +106 -0
- package/dist/targets/cpp/emit-allocation.d.ts +60 -0
- package/dist/targets/cpp/emit-allocation.js +573 -0
- package/dist/targets/cpp/emit-arrays.d.ts +119 -0
- package/dist/targets/cpp/emit-arrays.js +1047 -0
- package/dist/targets/cpp/emit-binding-reference.d.ts +17 -0
- package/dist/targets/cpp/emit-binding-reference.js +120 -0
- package/dist/targets/cpp/emit-bindings.d.ts +158 -0
- package/dist/targets/cpp/emit-bindings.js +769 -0
- package/dist/targets/cpp/emit-buffers.d.ts +156 -0
- package/dist/targets/cpp/emit-buffers.js +573 -0
- package/dist/targets/cpp/emit-callable.d.ts +230 -0
- package/dist/targets/cpp/emit-callable.js +2154 -0
- package/dist/targets/cpp/emit-carrier-members.d.ts +406 -0
- package/dist/targets/cpp/emit-carrier-members.js +1224 -0
- package/dist/targets/cpp/emit-coercion.d.ts +26 -0
- package/dist/targets/cpp/emit-coercion.js +39 -0
- package/dist/targets/cpp/emit-context.d.ts +1882 -0
- package/dist/targets/cpp/emit-context.js +904 -0
- package/dist/targets/cpp/emit-dynamic-properties.d.ts +174 -0
- package/dist/targets/cpp/emit-dynamic-properties.js +1249 -0
- package/dist/targets/cpp/emit-equality.d.ts +39 -0
- package/dist/targets/cpp/emit-equality.js +472 -0
- package/dist/targets/cpp/emit-exceptions.d.ts +104 -0
- package/dist/targets/cpp/emit-exceptions.js +513 -0
- package/dist/targets/cpp/emit-field-owner.d.ts +4 -0
- package/dist/targets/cpp/emit-field-owner.js +27 -0
- package/dist/targets/cpp/emit-in.d.ts +31 -0
- package/dist/targets/cpp/emit-in.js +426 -0
- package/dist/targets/cpp/emit-instanceof.d.ts +19 -0
- package/dist/targets/cpp/emit-instanceof.js +601 -0
- package/dist/targets/cpp/emit-integers.d.ts +68 -0
- package/dist/targets/cpp/emit-integers.js +184 -0
- package/dist/targets/cpp/emit-iterator.d.ts +100 -0
- package/dist/targets/cpp/emit-iterator.js +1137 -0
- package/dist/targets/cpp/emit-json.d.ts +73 -0
- package/dist/targets/cpp/emit-json.js +823 -0
- package/dist/targets/cpp/emit-jsx.d.ts +74 -0
- package/dist/targets/cpp/emit-jsx.js +806 -0
- package/dist/targets/cpp/emit-mixed-binary.d.ts +51 -0
- package/dist/targets/cpp/emit-mixed-binary.js +60 -0
- package/dist/targets/cpp/emit-namespaces.d.ts +101 -0
- package/dist/targets/cpp/emit-namespaces.js +133 -0
- package/dist/targets/cpp/emit-narrowing.d.ts +738 -0
- package/dist/targets/cpp/emit-narrowing.js +3967 -0
- package/dist/targets/cpp/emit-native-equality.d.ts +3 -0
- package/dist/targets/cpp/emit-native-equality.js +14 -0
- package/dist/targets/cpp/emit-native-selection.d.ts +5 -0
- package/dist/targets/cpp/emit-native-selection.js +37 -0
- package/dist/targets/cpp/emit-object-tag.d.ts +4 -0
- package/dist/targets/cpp/emit-object-tag.js +108 -0
- package/dist/targets/cpp/emit-owned-record.d.ts +2 -0
- package/dist/targets/cpp/emit-owned-record.js +15 -0
- package/dist/targets/cpp/emit-presence.d.ts +78 -0
- package/dist/targets/cpp/emit-presence.js +376 -0
- package/dist/targets/cpp/emit-properties.d.ts +105 -0
- package/dist/targets/cpp/emit-properties.js +1640 -0
- package/dist/targets/cpp/emit-record-view.d.ts +20 -0
- package/dist/targets/cpp/emit-record-view.js +354 -0
- package/dist/targets/cpp/emit-return.d.ts +5 -0
- package/dist/targets/cpp/emit-return.js +237 -0
- package/dist/targets/cpp/emit-sum-widening.d.ts +10 -0
- package/dist/targets/cpp/emit-sum-widening.js +69 -0
- package/dist/targets/cpp/emit-tonumber.d.ts +38 -0
- package/dist/targets/cpp/emit-tonumber.js +177 -0
- package/dist/targets/cpp/emit-tostring.d.ts +92 -0
- package/dist/targets/cpp/emit-tostring.js +556 -0
- package/dist/targets/cpp/emit-typeof.d.ts +49 -0
- package/dist/targets/cpp/emit-typeof.js +317 -0
- package/dist/targets/cpp/emit-union-properties.d.ts +181 -0
- package/dist/targets/cpp/emit-union-properties.js +1281 -0
- package/dist/targets/cpp/emit.d.ts +45 -0
- package/dist/targets/cpp/emit.js +2225 -0
- package/dist/targets/cpp/error-types.d.ts +4 -0
- package/dist/targets/cpp/error-types.js +11 -0
- package/dist/targets/cpp/function-source-reads.d.ts +72 -0
- package/dist/targets/cpp/function-source-reads.js +148 -0
- package/dist/targets/cpp/host/atomics.d.ts +25 -0
- package/dist/targets/cpp/host/atomics.js +63 -0
- package/dist/targets/cpp/host/core-globals.d.ts +108 -0
- package/dist/targets/cpp/host/core-globals.js +158 -0
- package/dist/targets/cpp/host/dynamic-argument-members.d.ts +42 -0
- package/dist/targets/cpp/host/dynamic-argument-members.js +61 -0
- package/dist/targets/cpp/host/emit-host-arity.d.ts +139 -0
- package/dist/targets/cpp/host/emit-host-arity.js +232 -0
- package/dist/targets/cpp/host/emit-host-invoke.d.ts +91 -0
- package/dist/targets/cpp/host/emit-host-invoke.js +1105 -0
- package/dist/targets/cpp/host/emit-host-object.d.ts +55 -0
- package/dist/targets/cpp/host/emit-host-object.js +2206 -0
- package/dist/targets/cpp/host/emit-host-properties.d.ts +69 -0
- package/dist/targets/cpp/host/emit-host-properties.js +533 -0
- package/dist/targets/cpp/host/emit-host-reflect.d.ts +4 -0
- package/dist/targets/cpp/host/emit-host-reflect.js +180 -0
- package/dist/targets/cpp/host/emit-host-value.d.ts +120 -0
- package/dist/targets/cpp/host/emit-host-value.js +392 -0
- package/dist/targets/cpp/host/host-members.d.ts +505 -0
- package/dist/targets/cpp/host/host-members.js +819 -0
- package/dist/targets/cpp/host/host-method-aliases.d.ts +30 -0
- package/dist/targets/cpp/host/host-method-aliases.js +76 -0
- package/dist/targets/cpp/host/native-protocols.d.ts +47 -0
- package/dist/targets/cpp/host/native-protocols.js +183 -0
- package/dist/targets/cpp/host/object-protocol.d.ts +351 -0
- package/dist/targets/cpp/host/object-protocol.js +671 -0
- package/dist/targets/cpp/host-namespace-reads.d.ts +83 -0
- package/dist/targets/cpp/host-namespace-reads.js +113 -0
- package/dist/targets/cpp/manifest/capabilities.d.ts +39 -0
- package/dist/targets/cpp/manifest/capabilities.js +1484 -0
- package/dist/targets/cpp/manifest.d.ts +23 -0
- package/dist/targets/cpp/manifest.js +113 -0
- package/dist/targets/cpp/native-error-base.d.ts +38 -0
- package/dist/targets/cpp/native-error-base.js +74 -0
- package/dist/targets/cpp/native-narrowing-transport.d.ts +12 -0
- package/dist/targets/cpp/native-narrowing-transport.js +151 -0
- package/dist/targets/cpp/native-selection-helpers.d.ts +11 -0
- package/dist/targets/cpp/native-selection-helpers.js +46 -0
- package/dist/targets/cpp/native-symbol-keys.d.ts +8 -0
- package/dist/targets/cpp/native-symbol-keys.js +34 -0
- package/dist/targets/cpp/ownership.d.ts +43 -0
- package/dist/targets/cpp/ownership.js +38 -0
- package/dist/targets/cpp/owning-conversion-input.d.ts +14 -0
- package/dist/targets/cpp/owning-conversion-input.js +12 -0
- package/dist/targets/cpp/property-read-claims.d.ts +62 -0
- package/dist/targets/cpp/property-read-claims.js +23 -0
- package/dist/targets/cpp/property-store-claims.d.ts +62 -0
- package/dist/targets/cpp/property-store-claims.js +26 -0
- package/dist/targets/cpp/prototype/emit-prototype-array.d.ts +111 -0
- package/dist/targets/cpp/prototype/emit-prototype-array.js +602 -0
- package/dist/targets/cpp/prototype/emit-prototype-date.d.ts +133 -0
- package/dist/targets/cpp/prototype/emit-prototype-date.js +515 -0
- package/dist/targets/cpp/prototype/emit-prototype-error.d.ts +13 -0
- package/dist/targets/cpp/prototype/emit-prototype-error.js +54 -0
- package/dist/targets/cpp/prototype/emit-prototype-invoke.d.ts +34 -0
- package/dist/targets/cpp/prototype/emit-prototype-invoke.js +1003 -0
- package/dist/targets/cpp/prototype/emit-prototype-iterator.d.ts +47 -0
- package/dist/targets/cpp/prototype/emit-prototype-iterator.js +250 -0
- package/dist/targets/cpp/prototype/emit-prototype-promise.d.ts +46 -0
- package/dist/targets/cpp/prototype/emit-prototype-promise.js +143 -0
- package/dist/targets/cpp/prototype/emit-prototype-regexp.d.ts +335 -0
- package/dist/targets/cpp/prototype/emit-prototype-regexp.js +853 -0
- package/dist/targets/cpp/prototype/emit-prototype-string.d.ts +42 -0
- package/dist/targets/cpp/prototype/emit-prototype-string.js +252 -0
- package/dist/targets/cpp/prototype/prototype-method-reads.d.ts +25 -0
- package/dist/targets/cpp/prototype/prototype-method-reads.js +182 -0
- package/dist/targets/cpp/reactive-dependencies.d.ts +140 -0
- package/dist/targets/cpp/reactive-dependencies.js +432 -0
- package/dist/targets/cpp/reactive-origins.d.ts +44 -0
- package/dist/targets/cpp/reactive-origins.js +82 -0
- package/dist/targets/cpp/records.d.ts +277 -0
- package/dist/targets/cpp/records.js +2427 -0
- package/dist/targets/cpp/recursive-containers.d.ts +43 -0
- package/dist/targets/cpp/recursive-containers.js +144 -0
- package/dist/targets/cpp/regexp-types.d.ts +56 -0
- package/dist/targets/cpp/regexp-types.js +59 -0
- package/dist/targets/cpp/substrate.d.ts +125 -0
- package/dist/targets/cpp/substrate.js +12 -0
- package/dist/targets/cpp/translation-unit.d.ts +219 -0
- package/dist/targets/cpp/translation-unit.js +2063 -0
- package/dist/targets/cpp/types.d.ts +280 -0
- package/dist/targets/cpp/types.js +1135 -0
- package/dist/targets/cpp/virtual-methods.d.ts +95 -0
- package/dist/targets/cpp/virtual-methods.js +264 -0
- package/package.json +95 -0
- package/src/targets/cpp/runtime/gea_dynamic_proxy.h +824 -0
- package/src/targets/cpp/runtime/gea_eval.h +1376 -0
- package/src/targets/cpp/runtime/gea_native_class_prototype.h +44 -0
- package/src/targets/cpp/runtime/gea_runtime.h +29222 -0
- package/src/targets/cpp/runtime/gea_runtime_builtins.cpp +55 -0
|
@@ -0,0 +1,1281 @@
|
|
|
1
|
+
import { dictionaryKeyDomainOf, representationKey } from '../../representation/model.js';
|
|
2
|
+
import { typedArrayUnionOnly } from '../../representation/host-templates.js';
|
|
3
|
+
import { allOperationsOf } from '../../ir/model.js';
|
|
4
|
+
import { operandsOfIrOperation } from '../../ir/queries.js';
|
|
5
|
+
import { createCppEmitBlockedError, defineValueAlias, operandText, wellKnownSymbolMemberOf } from './emit-context.js';
|
|
6
|
+
import { functionSourceReadClaimOf } from './function-source-reads.js';
|
|
7
|
+
import { cppBodyName, cppRecordFieldName, cppRecordFieldPresenceName, cppStringLiteral, cppTypeOf, cppUndefinedIn } from './types.js';
|
|
8
|
+
import { declaredFieldRepresentationOf, declaredRecordFieldOf } from './records.js';
|
|
9
|
+
import { absentCapableNumericElementText, keyedTableKeyText, memberAccessOperator } from './emit-carrier-members.js';
|
|
10
|
+
import { alignedValueText, classFamilyLoadText, receiverBoundFieldText, widenedStoreText } from './emit-narrowing.js';
|
|
11
|
+
import { canonicalIndexLiteral, stringIndexText, isDeclaredStringPrototypeKey } from './emit-carrier-members.js';
|
|
12
|
+
import { objectPrototypeMemberNames } from '../../representation/record-fields.js';
|
|
13
|
+
import { classFamilyOverridesOf, classMemberOf } from './class-layout.js';
|
|
14
|
+
import { classMethodOverrideOf } from '../../projection/fields.js';
|
|
15
|
+
import { classMethodValueArmsOf, virtualDispatchKey } from '../../projection/dispatch.js';
|
|
16
|
+
import { cppVirtualMemberName } from './virtual-methods.js';
|
|
17
|
+
import { abiOfCallee } from '../../projection/callee.js';
|
|
18
|
+
import { recordAccessorsOfShape } from './records.js';
|
|
19
|
+
import { cppRecordIndexSidecarName } from './records.js';
|
|
20
|
+
import { hasNativeNumericIndexArms, nativeNumericIndexOf } from '../../representation/numeric-index.js';
|
|
21
|
+
import { binaryToStringTagText, typedArrayBufferMemberText, typedArrayPrototypeMethods } from './emit-buffers.js';
|
|
22
|
+
import { typeofTextFor } from './emit-typeof.js';
|
|
23
|
+
import { promisePrototypeMethods } from './prototype/emit-prototype-invoke.js';
|
|
24
|
+
import { classConstructorStaticMemberTextFor, classMethodValueText } from './class-properties/emit-class-properties.js';
|
|
25
|
+
import { overriddenMethodValueText } from './class-properties/computed-method-value.js';
|
|
26
|
+
import { propertyKeyText } from './emit-dynamic-properties.js';
|
|
27
|
+
import { toStringTextOver } from './emit-tostring.js';
|
|
28
|
+
import { recordLayoutPolicyOf } from '../../projection/fields.js';
|
|
29
|
+
/**
|
|
30
|
+
* Whether a read off a union whose every arm is a typed array is a deferred
|
|
31
|
+
* `TypedArray.prototype` method read, and which one.
|
|
32
|
+
*
|
|
33
|
+
* The arms differ in what they store, never in what the method means, so the
|
|
34
|
+
* whole union is one receiver for the call that follows -- which is why the
|
|
35
|
+
* carrier travels with the claim: the invoker dispatches the arm.
|
|
36
|
+
*
|
|
37
|
+
* Stated once; `taggedUnionGetText` and the prototype-read walk both ask it.
|
|
38
|
+
*/
|
|
39
|
+
export const deferredTypedArrayUnionMethodClaim = (staticKeyTexts, receiver, key) => {
|
|
40
|
+
const carrier = receiver.representation;
|
|
41
|
+
if (carrier.kind !== 'tagged-union' || !taggedUnionHasOnlyTypedArrayArms(carrier))
|
|
42
|
+
return null;
|
|
43
|
+
const staticKey = staticKeyTexts.get(key.value);
|
|
44
|
+
if (staticKey === undefined || !typedArrayPrototypeMethods.has(staticKey))
|
|
45
|
+
return null;
|
|
46
|
+
return {
|
|
47
|
+
receiverKind: 'typed-array-union',
|
|
48
|
+
member: staticKey,
|
|
49
|
+
receiver: { kind: 'operand', operand: receiver },
|
|
50
|
+
receiverElement: null,
|
|
51
|
+
typedArrayUnionCarrier: carrier
|
|
52
|
+
};
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* The receiver a tagged union's per-arm class-method read has to keep, or
|
|
56
|
+
* `null` -- the union twin of `classMethodValueReceiverClaim`.
|
|
57
|
+
*
|
|
58
|
+
* A class arm materializes a method value whose physical convention leads with
|
|
59
|
+
* the arm's own receiver, while the read's receiver is the whole union, so the
|
|
60
|
+
* call that consumes it has to be handed that union back
|
|
61
|
+
* (`EmitContext.directCallReceivers`).
|
|
62
|
+
*
|
|
63
|
+
* `deferredUnionMethodArms` is ASKED rather than restated: a union whose EVERY
|
|
64
|
+
* arm answers this key is claimed whole, before the per-arm walk runs, and
|
|
65
|
+
* only a union it declines reaches `armRuntimeFieldText`. Its text arguments
|
|
66
|
+
* do not affect whether it claims, so passing empty ones asks exactly the
|
|
67
|
+
* question without spelling anything.
|
|
68
|
+
*/
|
|
69
|
+
export const unionClassMethodValueReceiverClaim = (ctx, operation) => {
|
|
70
|
+
const receiver = operation.receiver.representation;
|
|
71
|
+
if (receiver.kind !== 'tagged-union')
|
|
72
|
+
return null;
|
|
73
|
+
// Only a read that PUBLISHES the receiver-leading convention leaves the
|
|
74
|
+
// receiver for its call to supply. Where the published callable states none,
|
|
75
|
+
// each arm has already bound its own receiver into the value
|
|
76
|
+
// (`receiverBoundFieldText`), and handing the union back at the call would
|
|
77
|
+
// pass it as the first ARGUMENT.
|
|
78
|
+
const publishedAbi = abiOfCallee(operation.result.representation);
|
|
79
|
+
if (publishedAbi === null || publishedAbi.receiver === null)
|
|
80
|
+
return null;
|
|
81
|
+
const key = ctx.staticKeyTexts.get(operation.key.value);
|
|
82
|
+
if (key === undefined || objectPrototypeMemberNames.has(key))
|
|
83
|
+
return null;
|
|
84
|
+
if (deferredUnionMethodClaim(ctx, operation.receiver, operation.key) !== null)
|
|
85
|
+
return null;
|
|
86
|
+
for (const leaf of unionPropertyLeaves(receiver, '')) {
|
|
87
|
+
const arm = leaf.representation;
|
|
88
|
+
if (arm.kind !== 'class-ref')
|
|
89
|
+
continue;
|
|
90
|
+
const site = classMemberOf(ctx.classes, arm.declaration, key);
|
|
91
|
+
if (site === null || site.kind !== 'method' || site.method.callable === null)
|
|
92
|
+
continue;
|
|
93
|
+
if (classFamilyOverridesOf(ctx.classes, arm.declaration, key).length > 0) {
|
|
94
|
+
if (classMethodValueArmsOf(ctx.classes, arm.declaration, key) !== null)
|
|
95
|
+
return operation.receiver;
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
if (ctx.captures.of(site.method.callable).kind !== 'none' || ctx.abiOfCallable(site.method.callable) === null)
|
|
99
|
+
continue;
|
|
100
|
+
return operation.receiver;
|
|
101
|
+
}
|
|
102
|
+
return null;
|
|
103
|
+
};
|
|
104
|
+
/**
|
|
105
|
+
* Property access over a native tagged union dispatches on the live arm.
|
|
106
|
+
* Declared fields, native indexed storage, and ordinary string properties
|
|
107
|
+
* retain their carriers. Nullish indexed arms throw. Unsupported prototype
|
|
108
|
+
* members and accessor dispatch remain explicit refusals.
|
|
109
|
+
*/
|
|
110
|
+
/** Receiver kinds with a declared native field layout. */
|
|
111
|
+
const addressableArmKind = (kind) => kind === 'record' || kind === 'record-with-index' || kind === 'native-record-ref' || kind === 'class-ref';
|
|
112
|
+
/** Native object carriers whose ordinary expando properties live in the runtime sidecar. */
|
|
113
|
+
const sidecarArm = (representation) => {
|
|
114
|
+
if (!('ownership' in representation) || representation.ownership !== 'shared-refcount')
|
|
115
|
+
return false;
|
|
116
|
+
return (representation.kind === 'record' ||
|
|
117
|
+
representation.kind === 'record-with-index' ||
|
|
118
|
+
representation.kind === 'native-record-ref' ||
|
|
119
|
+
representation.kind === 'class-ref' ||
|
|
120
|
+
representation.kind === 'array-object' ||
|
|
121
|
+
representation.kind === 'typed-array' ||
|
|
122
|
+
representation.kind === 'array-buffer' ||
|
|
123
|
+
representation.kind === 'shared-array-buffer' ||
|
|
124
|
+
representation.kind === 'data-view' ||
|
|
125
|
+
representation.kind === 'keyed-collection');
|
|
126
|
+
};
|
|
127
|
+
/**
|
|
128
|
+
* One arm's own field access, or `null` when this arm cannot answer the key at
|
|
129
|
+
* all -- either because its kind carries no declared-field table (`scalar`,
|
|
130
|
+
* `string`, `array-object`, `native-handle`, ...) or because it does and the
|
|
131
|
+
* key simply names none of its fields. Both are the identical fact the caller
|
|
132
|
+
* needs: "this arm does not have it," which is what makes a union with even
|
|
133
|
+
* one such arm a narrowing the program never stated.
|
|
134
|
+
*
|
|
135
|
+
* Class arms first consult their semantic member table. Their physical record
|
|
136
|
+
* can contain inherited or synthetic slots with the same spelling as a method
|
|
137
|
+
* or accessor; those slots must not shadow the class member during a union
|
|
138
|
+
* read. Missing class members likewise proceed to the runtime-property path
|
|
139
|
+
* instead of acquiring meaning from an unrelated physical slot.
|
|
140
|
+
*/
|
|
141
|
+
const armFieldSite = (ctx, arm, armExprText, key) => {
|
|
142
|
+
if (!addressableArmKind(arm.kind))
|
|
143
|
+
return null;
|
|
144
|
+
if (arm.kind === 'class-ref') {
|
|
145
|
+
const member = classMemberOf(ctx.classes, arm.declaration, key);
|
|
146
|
+
if (member === null || member.kind !== 'field')
|
|
147
|
+
return null;
|
|
148
|
+
}
|
|
149
|
+
const declared = declaredFieldRepresentationOf(ctx.deriver, arm, key, ctx.classes);
|
|
150
|
+
if (declared === null)
|
|
151
|
+
return null;
|
|
152
|
+
// Every addressable kind above carries `.ownership` (records.ts's own
|
|
153
|
+
// `declaredFieldRepresentationOf` reads the identical three kinds), so this
|
|
154
|
+
// narrowing is safe.
|
|
155
|
+
const ownership = arm.ownership;
|
|
156
|
+
const accessor = memberAccessOperator(ownership);
|
|
157
|
+
const field = declaredRecordFieldOf(ctx.deriver, arm, key, ctx.classes);
|
|
158
|
+
const generated = arm.kind !== 'native-record-ref' || arm.native === null;
|
|
159
|
+
return {
|
|
160
|
+
text: `${armExprText}${accessor}${cppRecordFieldName(key)}`,
|
|
161
|
+
representation: declared,
|
|
162
|
+
presence: generated && field && !field.required ? `${armExprText}${accessor}${cppRecordFieldPresenceName(key)}` : null
|
|
163
|
+
};
|
|
164
|
+
};
|
|
165
|
+
/**
|
|
166
|
+
* Native property lookup when a union arm has no declared field at this key.
|
|
167
|
+
* A genuine dynamic arm keeps its property table. Native objects retain their
|
|
168
|
+
* identity and use their sidecar; string/array own properties stay native too.
|
|
169
|
+
* Missing string properties can be absent, while known prototype members and
|
|
170
|
+
* unsupported object arms need a real recipe and are refused rather than boxed.
|
|
171
|
+
*/
|
|
172
|
+
/**
|
|
173
|
+
* What an arm that PROVABLY lacks the member answers.
|
|
174
|
+
*
|
|
175
|
+
* `undefined` where the read's own carrier can hold it -- which is the whole
|
|
176
|
+
* answer for `(value as { label?: string }).label` off a `string` arm, and the
|
|
177
|
+
* one this file already rendered. Where it cannot, the carrier is a bare one
|
|
178
|
+
* the checker only reached because an `as` asserted this value is the OTHER
|
|
179
|
+
* arm, so the arm renders the TypeError the language would throw at the very
|
|
180
|
+
* next use of the `undefined` it would have produced. Refusing the whole
|
|
181
|
+
* program instead -- which is what a `null` here does -- refuses every arm on
|
|
182
|
+
* account of one the program says cannot occur.
|
|
183
|
+
*
|
|
184
|
+
* Reached only after the caller has discharged "the member might exist here":
|
|
185
|
+
* `objectPrototypeMemberNames` and `isDeclaredStringPrototypeKey` are the
|
|
186
|
+
* target's own model of what a primitive arm carries, and an arm whose member
|
|
187
|
+
* set is not modelled returns `null` above rather than arriving here.
|
|
188
|
+
*/
|
|
189
|
+
const absentArmText = (published, key, arm) => {
|
|
190
|
+
const undefinedText = cppUndefinedIn(published);
|
|
191
|
+
if (undefinedText !== null)
|
|
192
|
+
return undefinedText;
|
|
193
|
+
return `gea::host::throwAbsentUnionMember<${cppTypeOf(published)}>(${cppStringLiteral(key)}, ${cppStringLiteral(arm)})`;
|
|
194
|
+
};
|
|
195
|
+
const armRuntimeFieldText = (ctx, arm, armExprText, key, operation) => {
|
|
196
|
+
const published = operation.result.representation;
|
|
197
|
+
if (arm.kind === 'null' || arm.kind === 'undefined') {
|
|
198
|
+
return `gea::host::throwGetPropertyOfNullish<${cppTypeOf(published)}>("${arm.kind}")`;
|
|
199
|
+
}
|
|
200
|
+
if (wellKnownSymbolMemberOf(ctx, operation.key) === 'toStringTag') {
|
|
201
|
+
const tag = binaryToStringTagText(arm);
|
|
202
|
+
if (tag !== null)
|
|
203
|
+
return alignedValueText(ctx, 'emit-union-properties.ts:116', { kind: 'string' }, published, tag);
|
|
204
|
+
}
|
|
205
|
+
const boxed = { kind: 'dynamic', reason: 'declared-any-never-narrowed' };
|
|
206
|
+
const propertyKey = `gea::PropertyKey::string(${cppStringLiteral(key)})`;
|
|
207
|
+
if (arm.kind === 'dynamic')
|
|
208
|
+
return alignedValueText(ctx, 'emit-union-properties.ts:120', arm, published, `${armExprText}.getProperty(${propertyKey})`);
|
|
209
|
+
const index = canonicalIndexLiteral(key);
|
|
210
|
+
if (arm.kind === 'string') {
|
|
211
|
+
if (key === 'length')
|
|
212
|
+
return alignedValueText(ctx, 'emit-union-properties.ts:124', { kind: 'scalar', domain: 'number' }, published, `static_cast<double>(gea::runtime::string::utf16Length(${armExprText}))`);
|
|
213
|
+
if (index !== null)
|
|
214
|
+
return stringIndexText(armExprText, index, operation.result, key);
|
|
215
|
+
if (objectPrototypeMemberNames.has(key) || isDeclaredStringPrototypeKey(key))
|
|
216
|
+
return null;
|
|
217
|
+
return absentArmText(published, key, 'string');
|
|
218
|
+
}
|
|
219
|
+
if (arm.kind === 'array-object') {
|
|
220
|
+
if (key === 'length')
|
|
221
|
+
return alignedValueText(ctx, 'emit-union-properties.ts:134', { kind: 'scalar', domain: 'number' }, published, `${armExprText}->length()`);
|
|
222
|
+
return index === null ? null : arrayArmReadText(armExprText, 'elementAt', index, arm.element, published);
|
|
223
|
+
}
|
|
224
|
+
if (arm.kind === 'typed-array') {
|
|
225
|
+
if (key === 'length') {
|
|
226
|
+
return alignedValueText(ctx, 'emit-union-properties.ts:139', { kind: 'scalar', domain: 'number' }, published, `${armExprText}->length()`);
|
|
227
|
+
}
|
|
228
|
+
const bufferMember = typedArrayBufferMemberText(armExprText, arm, key);
|
|
229
|
+
if (bufferMember !== null) {
|
|
230
|
+
const source = key === 'buffer' ? { kind: arm.buffer, ownership: 'shared-refcount' } : { kind: 'scalar', domain: 'number' };
|
|
231
|
+
return alignedValueText(ctx, 'emit-union-properties.ts:145', source, published, bufferMember);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
if (arm.kind === 'scalar') {
|
|
235
|
+
// Ordinary named properties on a primitive are read through its wrapper
|
|
236
|
+
// object. This runtime has no mutable Number/Boolean prototype, so a name
|
|
237
|
+
// outside Object.prototype is absent on the primitive arm. That is the
|
|
238
|
+
// native answer for overload probes such as `number | Vector3` reading
|
|
239
|
+
// `isVector3`: the scalar arm contributes `undefined`, while the class arm
|
|
240
|
+
// contributes the declared boolean marker.
|
|
241
|
+
if (!objectPrototypeMemberNames.has(key) && published.kind === 'optional' && published.absence === 'undefined') {
|
|
242
|
+
return cppUndefinedIn(published);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
if (arm.kind === 'constructor-family') {
|
|
246
|
+
return classConstructorStaticMemberTextFor(ctx, arm, key, published, () => armExprText);
|
|
247
|
+
}
|
|
248
|
+
if (objectPrototypeMemberNames.has(key))
|
|
249
|
+
return null;
|
|
250
|
+
// A promise's member set is CLOSED, which is what makes absence provable
|
|
251
|
+
// here rather than merely unrendered. ECMA-262 27.2.5 gives
|
|
252
|
+
// `Promise.prototype` exactly `then`, `catch`, `finally` and
|
|
253
|
+
// `@@toStringTag`; everything else a promise answers comes from
|
|
254
|
+
// `Object.prototype`, which the line above already returned for. And this
|
|
255
|
+
// runtime's `gea::Promise` is a `shared_ptr` to a settled-value state with
|
|
256
|
+
// no dynamic-property sidecar and no way to acquire one -- unlike a class
|
|
257
|
+
// instance, whose sidecar can hold a key the layout never declared -- so
|
|
258
|
+
// nothing can put `callbacks` on one at runtime.
|
|
259
|
+
//
|
|
260
|
+
// hono's `resolveCallback` is the shape: `(str as HtmlEscapedString)
|
|
261
|
+
// .callbacks` off a `string | HtmlEscapedString | Promise<string>`, where
|
|
262
|
+
// the `as` names the arm the author means and the other two arms answer
|
|
263
|
+
// `undefined` -- which is exactly what `!callbacks?.length` then tests. The
|
|
264
|
+
// string arm already answers that way a few lines above; refusing the whole
|
|
265
|
+
// union on account of the promise arm refused a read the carrier decides.
|
|
266
|
+
if (arm.kind === 'promise' && !promisePrototypeMethods.has(key))
|
|
267
|
+
return absentArmText(published, key, 'promise');
|
|
268
|
+
if (arm.kind === 'class-ref') {
|
|
269
|
+
const site = classMemberOf(ctx.classes, arm.declaration, key);
|
|
270
|
+
if (site !== null) {
|
|
271
|
+
if (site.kind === 'unknown-class' || site.kind === 'field')
|
|
272
|
+
return null;
|
|
273
|
+
// Select the method at the read, using the same allocation identity as
|
|
274
|
+
// a computed class-method read. Calling later with another receiver must
|
|
275
|
+
// retain this exact method, rather than redispatching through that object.
|
|
276
|
+
if (classFamilyOverridesOf(ctx.classes, arm.declaration, key).length > 0) {
|
|
277
|
+
if (site.kind === 'accessor') {
|
|
278
|
+
const dispatch = ctx.virtualDispatch.get(virtualDispatchKey(arm.declaration, key, 'get'));
|
|
279
|
+
if (dispatch === undefined)
|
|
280
|
+
return null;
|
|
281
|
+
return alignedValueText(ctx, 'emit-union-properties.ts:armRuntimeFieldText', dispatch.result, published, `${armExprText}->${cppVirtualMemberName(key, 'get')}()`);
|
|
282
|
+
}
|
|
283
|
+
if (site.kind !== 'method')
|
|
284
|
+
return null;
|
|
285
|
+
return overriddenMethodValueText(ctx, arm, armExprText, key, (method) => classMethodValueText(ctx, operation, key, method, published, armExprText, arm)).text;
|
|
286
|
+
}
|
|
287
|
+
if (site.kind === 'accessor') {
|
|
288
|
+
if (site.accessor.getter === null)
|
|
289
|
+
return null;
|
|
290
|
+
const abi = ctx.abiOfCallable(site.accessor.getter);
|
|
291
|
+
if (abi === null)
|
|
292
|
+
return null;
|
|
293
|
+
return alignedValueText(ctx, 'emit-union-properties.ts:177', abi.result, published, `${cppBodyName(site.accessor.getter)}(${armExprText})`);
|
|
294
|
+
}
|
|
295
|
+
if (site.method.callable === null || ctx.captures.of(site.method.callable).kind !== 'none')
|
|
296
|
+
return null;
|
|
297
|
+
const converted = classMethodValueText(ctx, operation, key, site.method, published, armExprText, arm).text;
|
|
298
|
+
// This arm materializes a class method even though the property read's
|
|
299
|
+
// receiver is the whole tagged union. That receiver's SSA operand is
|
|
300
|
+
// retained beside the method value so an immediate `value.method()` call
|
|
301
|
+
// can narrow it back to the receiver-bearing ABI's class arm -- recorded
|
|
302
|
+
// by `emit.ts`'s prepass, which asked
|
|
303
|
+
// `unionClassMethodValueReceiverClaim`. A detached method crosses a
|
|
304
|
+
// binding/result and therefore has a different SSA callee;
|
|
305
|
+
// `emit-callable.ts` will not consult the entry for it.
|
|
306
|
+
return converted;
|
|
307
|
+
}
|
|
308
|
+
// No member anywhere on this class's chain, and the closed reflection
|
|
309
|
+
// census proved no instance of it can hold the key as an own property
|
|
310
|
+
// (`GetOperation.absentClassArms`): the language's answer is `undefined`.
|
|
311
|
+
if (operation.absentClassArms?.includes(arm.declaration))
|
|
312
|
+
return absentArmText(published, key, 'class');
|
|
313
|
+
}
|
|
314
|
+
const accessors = arm.kind === 'record' ? arm.accessors : arm.kind === 'native-record-ref' ? recordAccessorsOfShape(ctx.deriver, arm.shapeId) : null;
|
|
315
|
+
if (accessors?.some((accessor) => accessor.key === key))
|
|
316
|
+
return null;
|
|
317
|
+
if (sidecarArm(arm)) {
|
|
318
|
+
return alignedValueText(ctx, 'emit-union-properties.ts:201', boxed, published, `gea::nativeDynamicGet(${armExprText}, ${propertyKey})`);
|
|
319
|
+
}
|
|
320
|
+
return null;
|
|
321
|
+
};
|
|
322
|
+
/** The live arm's own value, and the discriminant that says it is live -- shared with `emit-in.ts`'s per-arm `k in u` dispatch, the one other file that needs to name an arm without owning this file's field/element machinery. */
|
|
323
|
+
export const armAt = (receiverText, index) => `${receiverText}.get<${index}>()`;
|
|
324
|
+
export const armIs = (receiverText, index) => `${receiverText}.is<${index}>()`;
|
|
325
|
+
export const unionPropertyLeaves = (representation, text, test = 'true') => {
|
|
326
|
+
if (representation.kind === 'tagged-union') {
|
|
327
|
+
return representation.arms.flatMap((arm, index) => {
|
|
328
|
+
const nestedText = armAt(text, index);
|
|
329
|
+
const nestedTest = test === 'true' ? armIs(text, index) : `${test} && ${armIs(text, index)}`;
|
|
330
|
+
return unionPropertyLeaves(arm.value, nestedText, nestedTest);
|
|
331
|
+
});
|
|
332
|
+
}
|
|
333
|
+
if (representation.kind === 'optional') {
|
|
334
|
+
const presentTest = test === 'true' ? `${text}.has_value()` : `${test} && ${text}.has_value()`;
|
|
335
|
+
const absentTest = test === 'true' ? `!${text}.has_value()` : `${test} && !${text}.has_value()`;
|
|
336
|
+
return [
|
|
337
|
+
...unionPropertyLeaves(representation.payload, `(*${text})`, presentTest),
|
|
338
|
+
{ representation: { kind: representation.absence }, text, test: absentTest }
|
|
339
|
+
];
|
|
340
|
+
}
|
|
341
|
+
return [{ representation, text, test }];
|
|
342
|
+
};
|
|
343
|
+
export const dispatchedLeafExpression = (leaves, expressions) => {
|
|
344
|
+
const last = expressions[expressions.length - 1];
|
|
345
|
+
if (last === undefined)
|
|
346
|
+
return null;
|
|
347
|
+
let dispatched = last;
|
|
348
|
+
for (let index = expressions.length - 2; index >= 0; index -= 1) {
|
|
349
|
+
const leaf = leaves[index];
|
|
350
|
+
const expression = expressions[index];
|
|
351
|
+
if (leaf === undefined || expression === undefined)
|
|
352
|
+
return null;
|
|
353
|
+
dispatched = `${leaf.test} ? ${expression} : (${dispatched})`;
|
|
354
|
+
}
|
|
355
|
+
return expressions.length > 1 ? `(${dispatched})` : dispatched;
|
|
356
|
+
};
|
|
357
|
+
/** Dispatch a numeric key through each alternative's native storage. */
|
|
358
|
+
const nativeNumericUnionAccess = (ctx, operation) => {
|
|
359
|
+
const receiver = operation.receiver.representation;
|
|
360
|
+
if (receiver.kind !== 'tagged-union' || !hasNativeNumericIndexArms(receiver, ctx.deriver.derive))
|
|
361
|
+
return null;
|
|
362
|
+
// Whether the key IS a canonical-index literal is a claim, not a spelling:
|
|
363
|
+
// it picks the literal-index dispatch over the runtime-key one below. Ask
|
|
364
|
+
// the pre-render map so a `typeof`-fold `constantTexts` also accumulates at
|
|
365
|
+
// render time can never be mistaken for an index the program actually wrote.
|
|
366
|
+
const staticKey = ctx.staticKeyTexts.get(operation.key.value);
|
|
367
|
+
const literalIndex = staticKey === undefined ? null : canonicalIndexLiteral(staticKey);
|
|
368
|
+
if (literalIndex === null && (operation.key.representation.kind !== 'scalar' || operation.key.representation.domain !== 'number'))
|
|
369
|
+
return null;
|
|
370
|
+
const receiverText = operandText(ctx, operation.receiver);
|
|
371
|
+
const key = literalIndex ?? operandText(ctx, operation.key);
|
|
372
|
+
return receiver.arms.map((arm, index) => {
|
|
373
|
+
if (arm.value.kind === 'null' || arm.value.kind === 'undefined') {
|
|
374
|
+
const type = operation.kind === 'get' ? cppTypeOf(operation.result.representation) : 'void';
|
|
375
|
+
const action = operation.kind === 'get' ? 'read' : 'set';
|
|
376
|
+
const expression = `gea::host::throwGetPropertyOfNullish<${type}>("${arm.value.kind}", "${action}")`;
|
|
377
|
+
return operation.kind === 'get' ? expression : `${expression};`;
|
|
378
|
+
}
|
|
379
|
+
const storage = nativeNumericIndexOf(arm.value, ctx.deriver.derive);
|
|
380
|
+
if (!storage) {
|
|
381
|
+
throw createCppEmitBlockedError(`property-access:tagged-union(numeric-index-arms):${operation.kind}:true`, 'a numeric index alternative lost its native storage');
|
|
382
|
+
}
|
|
383
|
+
const at = armAt(receiverText, index);
|
|
384
|
+
const member = storage.kind === 'record-index'
|
|
385
|
+
? `${at}${memberAccessOperator(storage.ownership)}${cppRecordIndexSidecarName}.`
|
|
386
|
+
: `${at}${memberAccessOperator(storage.ownership)}`;
|
|
387
|
+
if (operation.kind === 'get') {
|
|
388
|
+
return storage.kind === 'elements'
|
|
389
|
+
? arrayArmReadText(at, 'elementAt', key, storage.value, operation.result.representation)
|
|
390
|
+
: dictionaryArmReadText(member, key, storage.value, operation.result.representation);
|
|
391
|
+
}
|
|
392
|
+
const written = alignedValueText(ctx, 'emit-union-properties.ts:280', operation.value.representation, storage.value, operandText(ctx, operation.value));
|
|
393
|
+
if (written === null) {
|
|
394
|
+
throw createCppEmitBlockedError(`property-access:tagged-union(numeric-index-arms):${operation.kind}:true`, "a numeric index write has no conversion into an alternative's element");
|
|
395
|
+
}
|
|
396
|
+
return storage.kind === 'elements' ? `${at}->setElement(${key}, ${written});` : `${member}operator[](${key}) = ${written};`;
|
|
397
|
+
});
|
|
398
|
+
};
|
|
399
|
+
const nativeNumericUnionGetText = (ctx, operation) => {
|
|
400
|
+
const arms = nativeNumericUnionAccess(ctx, operation);
|
|
401
|
+
if (!arms)
|
|
402
|
+
return null;
|
|
403
|
+
const receiver = operandText(ctx, operation.receiver);
|
|
404
|
+
return arms.reduceRight((rest, text, index) => (rest ? `(${armIs(receiver, index)} ? ${text} : ${rest})` : text), '');
|
|
405
|
+
};
|
|
406
|
+
const emitNativeNumericUnionSet = (ctx, lines, operation) => {
|
|
407
|
+
const arms = nativeNumericUnionAccess(ctx, operation);
|
|
408
|
+
if (!arms)
|
|
409
|
+
return false;
|
|
410
|
+
const receiver = operandText(ctx, operation.receiver);
|
|
411
|
+
lines.push(arms.map((text, index) => (index === arms.length - 1 ? `{ ${text} }` : `if (${armIs(receiver, index)}) { ${text} } else `)).join(''));
|
|
412
|
+
if (operation.result)
|
|
413
|
+
defineValueAlias(ctx, operation.result, receiver);
|
|
414
|
+
return true;
|
|
415
|
+
};
|
|
416
|
+
/**
|
|
417
|
+
* Whether every arm of this union is a typed array -- the one shape for which
|
|
418
|
+
* a COMPUTED key needs no reconciliation between arms.
|
|
419
|
+
*
|
|
420
|
+
* `TypedArray` is a union of nine views (`@types/three` states it, and so does
|
|
421
|
+
* every other package that names the family), and the arms differ only in
|
|
422
|
+
* element WIDTH: `canonicalMembersOf` keeps all nine because `int8` and
|
|
423
|
+
* `float32` really are different carriers. But `TypedArray::elementAt`
|
|
424
|
+
* returns `double` for all eight domains whatever the view holds, so a
|
|
425
|
+
* per-arm dispatch of `view[ i ]` produces the identical C++ type on every
|
|
426
|
+
* arm and there is nothing to widen, narrow or reconcile.
|
|
427
|
+
*
|
|
428
|
+
* That is exactly the reconciliation `manifest/capabilities.ts` cites as the
|
|
429
|
+
* reason the flat `tagged-union:get:true` claim is withheld -- "a per-arm
|
|
430
|
+
* dispatch of a runtime-only key would additionally have to reconcile
|
|
431
|
+
* `array-object`/`dictionary`-shaped arms". A union with no such arm does not
|
|
432
|
+
* owe that, so it is claimed under its own refined key rather than by
|
|
433
|
+
* widening the general one.
|
|
434
|
+
*/
|
|
435
|
+
export const taggedUnionHasOnlyTypedArrayArms = (representation) => typedArrayUnionOnly(representation);
|
|
436
|
+
/**
|
|
437
|
+
* Reading a COMPUTED key off a tagged union whose every arm is a typed array,
|
|
438
|
+
* or `null` when this is not that case.
|
|
439
|
+
*
|
|
440
|
+
* The same nested-ternary dispatch `taggedUnionGetText` builds for a static
|
|
441
|
+
* key, over `elementAt` instead of a field name. `absentCapableNumericElement\
|
|
442
|
+
* Text` is asked per arm for the same reason it is asked for a lone typed
|
|
443
|
+
* array: under `noUncheckedIndexedAccess` the checker types `view[ i ]` as
|
|
444
|
+
* `number | undefined`, and the bare reader aborts on an index the language
|
|
445
|
+
* answers with `undefined`.
|
|
446
|
+
*/
|
|
447
|
+
const taggedUnionElementText = (ctx, operation) => {
|
|
448
|
+
const receiver = operation.receiver.representation;
|
|
449
|
+
if (!taggedUnionHasOnlyTypedArrayArms(receiver) || receiver.kind !== 'tagged-union')
|
|
450
|
+
return null;
|
|
451
|
+
// This function only ever handles a COMPUTED key -- a static one is the
|
|
452
|
+
// general union-get's job. Asking the pre-render map keeps a render-time
|
|
453
|
+
// `typeof`-fold text from being mistaken for a key the program wrote as
|
|
454
|
+
// static, which would wrongly bail this computed-key path.
|
|
455
|
+
if (ctx.staticKeyTexts.get(operation.key.value) !== undefined)
|
|
456
|
+
return null;
|
|
457
|
+
if (operation.key.representation.kind !== 'scalar')
|
|
458
|
+
return null;
|
|
459
|
+
const receiverText = operandText(ctx, operation.receiver);
|
|
460
|
+
const keyText = operandText(ctx, operation.key);
|
|
461
|
+
const armTexts = receiver.arms.map((_arm, index) => {
|
|
462
|
+
const armText = armAt(receiverText, index);
|
|
463
|
+
return absentCapableNumericElementText(armText, keyText, operation.result) ?? `${armText}->elementAt(${keyText})`;
|
|
464
|
+
});
|
|
465
|
+
const dispatched = armTexts.reduceRight((rest, text, index) => (rest === null ? text : `${armIs(receiverText, index)} ? ${text} : (${rest})`), null);
|
|
466
|
+
if (dispatched === null)
|
|
467
|
+
return null;
|
|
468
|
+
return armTexts.length > 1 ? `(${dispatched})` : dispatched;
|
|
469
|
+
};
|
|
470
|
+
/**
|
|
471
|
+
* Writing a COMPUTED key onto a tagged union whose every arm is a typed
|
|
472
|
+
* array. The statement form of `taggedUnionElementText`, dispatched the way
|
|
473
|
+
* `emitTaggedUnionSet` dispatches a static key.
|
|
474
|
+
*
|
|
475
|
+
* `setElement` takes the `double` every view stores through, so the value is
|
|
476
|
+
* converted once against the published `scalar` rather than per arm -- the
|
|
477
|
+
* arms differ in what they hold, never in what they accept.
|
|
478
|
+
*/
|
|
479
|
+
const emitTaggedUnionElementSet = (ctx, lines, operation) => {
|
|
480
|
+
const receiver = operation.receiver.representation;
|
|
481
|
+
if (!taggedUnionHasOnlyTypedArrayArms(receiver) || receiver.kind !== 'tagged-union')
|
|
482
|
+
return false;
|
|
483
|
+
// Same computed-key-only claim as `taggedUnionElementText`'s mirror check --
|
|
484
|
+
// the pre-render map, so a render-time-folded text cannot pass for a static
|
|
485
|
+
// key here either.
|
|
486
|
+
if (ctx.staticKeyTexts.get(operation.key.value) !== undefined)
|
|
487
|
+
return false;
|
|
488
|
+
if (operation.key.representation.kind !== 'scalar')
|
|
489
|
+
return false;
|
|
490
|
+
const receiverText = operandText(ctx, operation.receiver);
|
|
491
|
+
const keyText = operandText(ctx, operation.key);
|
|
492
|
+
const valueText = operandText(ctx, operation.value);
|
|
493
|
+
const statements = receiver.arms.map((_arm, index) => `${armAt(receiverText, index)}->setElement(${keyText}, ${valueText});`);
|
|
494
|
+
let chain = '';
|
|
495
|
+
statements.forEach((statement, index) => {
|
|
496
|
+
if (statements.length === 1)
|
|
497
|
+
chain = statement;
|
|
498
|
+
else if (index === 0)
|
|
499
|
+
chain = `if (${armIs(receiverText, 0)}) { ${statement} }`;
|
|
500
|
+
else if (index === statements.length - 1)
|
|
501
|
+
chain += ` else { ${statement} }`;
|
|
502
|
+
else
|
|
503
|
+
chain += ` else if (${armIs(receiverText, index)}) { ${statement} }`;
|
|
504
|
+
});
|
|
505
|
+
lines.push(chain);
|
|
506
|
+
if (operation.result)
|
|
507
|
+
defineValueAlias(ctx, operation.result, receiverText);
|
|
508
|
+
return true;
|
|
509
|
+
};
|
|
510
|
+
/**
|
|
511
|
+
* Whether every arm of a `tagged-union` receiver is a `dictionary` -- the one
|
|
512
|
+
* other shape (besides "every arm a typed array") a COMPUTED key owes no
|
|
513
|
+
* ARM-KIND reconciliation for. Every `dictionary` renders through the
|
|
514
|
+
* identical `member.read(key)`/`member.has(key)` pair regardless of its
|
|
515
|
+
* value type, so the only reconciliation left is the ordinary per-arm VALUE
|
|
516
|
+
* one `taggedUnionGetText`'s static-key dispatch already performs -- here
|
|
517
|
+
* done with `widenedStoreText` instead of `narrowedLoadText`, because a
|
|
518
|
+
* dictionary's `value` is the concrete type actually stored and the read's
|
|
519
|
+
* published carrier is typically the WIDER union of the arms' value types
|
|
520
|
+
* (`Record<string, number> | Record<string, string>` reads as `number |
|
|
521
|
+
* string`), which is a widen, not a narrow.
|
|
522
|
+
*/
|
|
523
|
+
export const taggedUnionHasOnlyDictionaryArms = (representation) => representation.kind === 'tagged-union' && representation.arms.every((arm) => arm.value.kind === 'dictionary');
|
|
524
|
+
/**
|
|
525
|
+
* One dictionary arm's own read, reconciled to what the whole union's `get`
|
|
526
|
+
* publishes.
|
|
527
|
+
*
|
|
528
|
+
* Mirrors `dictionaryReadText` (`emit-properties.ts`) exactly -- a bare
|
|
529
|
+
* `read(key)` where the published carrier is not `optional`, and a
|
|
530
|
+
* `has(key) ? V(read(key)) : V()` where it is, because the language answers
|
|
531
|
+
* `undefined` for an absent key only where the program was compiled to say
|
|
532
|
+
* so. The one addition is the reconciliation step: where this arm's OWN
|
|
533
|
+
* value carrier differs from what the whole read publishes, `widenedStoreText`
|
|
534
|
+
* wraps it into the published union's own arm the same way an ordinary store
|
|
535
|
+
* would (`ofArm<index>`), and a value that cannot be so reconciled refuses by
|
|
536
|
+
* name -- the identical fail-closed posture `taggedUnionGetText`'s own arm
|
|
537
|
+
* loop already takes for a static key, asked here of a VALUE mismatch
|
|
538
|
+
* instead of a FIELD one.
|
|
539
|
+
*/
|
|
540
|
+
const dictionaryArmReadText = (member, keyText, dictionaryValue, published) => {
|
|
541
|
+
const rawRead = `${member}read(${keyText})`;
|
|
542
|
+
if (published.kind !== 'optional') {
|
|
543
|
+
if (representationKey(dictionaryValue) === representationKey(published))
|
|
544
|
+
return rawRead;
|
|
545
|
+
const widened = widenedStoreText(published, dictionaryValue, rawRead);
|
|
546
|
+
if (widened !== null)
|
|
547
|
+
return widened;
|
|
548
|
+
throw createCppEmitBlockedError('property-access:tagged-union(dictionary-arms):get:true', `a computed "get" on a dictionary-armed tagged union reaches an arm whose value is stored as ` +
|
|
549
|
+
`"${representationKey(dictionaryValue)}" and this read publishes "${representationKey(published)}"; no widening between those is licensed`);
|
|
550
|
+
}
|
|
551
|
+
const presentText = representationKey(dictionaryValue) === representationKey(published.payload)
|
|
552
|
+
? rawRead
|
|
553
|
+
: widenedStoreText(published.payload, dictionaryValue, rawRead);
|
|
554
|
+
if (presentText === null) {
|
|
555
|
+
throw createCppEmitBlockedError('property-access:tagged-union(dictionary-arms):get:true', `a computed "get" on a dictionary-armed tagged union reaches an arm whose value is stored as ` +
|
|
556
|
+
`"${representationKey(dictionaryValue)}" and this read publishes "optional(${representationKey(published.payload)})"; ` +
|
|
557
|
+
'no widening between those is licensed');
|
|
558
|
+
}
|
|
559
|
+
const carrier = cppTypeOf(published);
|
|
560
|
+
return `(${member}has(${keyText}) ? ${carrier}(${presentText}) : ${carrier}())`;
|
|
561
|
+
};
|
|
562
|
+
/**
|
|
563
|
+
* Reading a COMPUTED key off a tagged union whose every arm is a
|
|
564
|
+
* `dictionary` -- the dictionary-arms mirror of `taggedUnionElementText`
|
|
565
|
+
* above, over `dictionaryArmReadText` instead of `elementAt`. This is the
|
|
566
|
+
* exact shape `manifest/capabilities.ts`'s withheld `tagged-union:get:true`
|
|
567
|
+
* comment names as needing "reconciliation" and declines to build blind --
|
|
568
|
+
* hono's own `Record<string, string> | Record<string, string[]>` (a
|
|
569
|
+
* `multiple`/single-value query-string result) and `ParamIndexMap |
|
|
570
|
+
* Params` (`Record<string, number> | Record<string, string>`, a route's
|
|
571
|
+
* resolved-vs-unresolved parameter table) are both this, and nothing else in
|
|
572
|
+
* the corpus needed the `array-object`-armed case the withheld comment also
|
|
573
|
+
* names, so that half stays unbuilt rather than guessed at.
|
|
574
|
+
*/
|
|
575
|
+
const taggedUnionDictionaryGetText = (ctx, operation) => {
|
|
576
|
+
const receiver = operation.receiver.representation;
|
|
577
|
+
if (!taggedUnionHasOnlyDictionaryArms(receiver) || receiver.kind !== 'tagged-union')
|
|
578
|
+
return null;
|
|
579
|
+
// Computed-key-only claim, same as `taggedUnionElementText` above: the
|
|
580
|
+
// pre-render map, so a render-time-folded text is never mistaken for a
|
|
581
|
+
// static key and does not wrongly bail this dictionary-arms path.
|
|
582
|
+
if (ctx.staticKeyTexts.get(operation.key.value) !== undefined)
|
|
583
|
+
return null;
|
|
584
|
+
const receiverText = operandText(ctx, operation.receiver);
|
|
585
|
+
const published = operation.result.representation;
|
|
586
|
+
const armTexts = receiver.arms.map((arm, index) => {
|
|
587
|
+
const dictionary = arm.value;
|
|
588
|
+
if (dictionary.kind !== 'dictionary') {
|
|
589
|
+
// Unreachable given `taggedUnionHasOnlyDictionaryArms` above; kept so
|
|
590
|
+
// the map body stays narrowed to the dictionary variant without a cast.
|
|
591
|
+
throw createCppEmitBlockedError('property-access:tagged-union(dictionary-arms):get:true', 'a dictionary-arms union reached a non-dictionary arm');
|
|
592
|
+
}
|
|
593
|
+
const armText = armAt(receiverText, index);
|
|
594
|
+
const member = `${armText}${memberAccessOperator(dictionary.ownership)}`;
|
|
595
|
+
const keyText = keyedTableKeyText(ctx, operation.key, dictionaryKeyDomainOf(dictionary.key, operation.key.representation));
|
|
596
|
+
return dictionaryArmReadText(member, keyText, dictionary.value, published);
|
|
597
|
+
});
|
|
598
|
+
const dispatched = armTexts.reduceRight((rest, text, index) => (rest === null ? text : `${armIs(receiverText, index)} ? ${text} : (${rest})`), null);
|
|
599
|
+
if (dispatched === null)
|
|
600
|
+
return null;
|
|
601
|
+
return armTexts.length > 1 ? `(${dispatched})` : dispatched;
|
|
602
|
+
};
|
|
603
|
+
/**
|
|
604
|
+
* Whether every arm of a `tagged-union` receiver is an `array-object` -- the
|
|
605
|
+
* third shape (besides "every arm a typed array" and "every arm a
|
|
606
|
+
* dictionary") a COMPUTED key owes no ARM-KIND reconciliation for. Every
|
|
607
|
+
* `array-object` renders through the identical `elementAt`/`hasElement` pair
|
|
608
|
+
* (`emit-carrier-members.ts`'s `arrayAccessText`) regardless of what its OWN
|
|
609
|
+
* element type is, so the only reconciliation left is the ordinary per-arm
|
|
610
|
+
* VALUE one -- widening each arm's own element into the published union the
|
|
611
|
+
* same way `dictionaryArmReadText` widens a dictionary arm's value.
|
|
612
|
+
* `[T, ParamIndexMap][] | [T, Params][]` (hono's own router match result,
|
|
613
|
+
* `Result<T>`'s first slot -- two element arrays differing only in their
|
|
614
|
+
* element's second tuple slot) is exactly this.
|
|
615
|
+
*/
|
|
616
|
+
export const taggedUnionHasOnlyArrayObjectArms = (representation) => representation.kind === 'tagged-union' && representation.arms.every((arm) => arm.value.kind === 'array-object');
|
|
617
|
+
/**
|
|
618
|
+
* The exact native-sidecar predicate preflight claims for a runtime key on a
|
|
619
|
+
* tagged union. Each admitted native arm has a stable shared identity, so
|
|
620
|
+
* `nativeDynamicGet` can first consult its generated field/index dispatcher
|
|
621
|
+
* and then its expando sidecar. A by-value record cannot enter: making a
|
|
622
|
+
* sidecar for it would key mutable JS state on a transient C++ copy.
|
|
623
|
+
*/
|
|
624
|
+
const nativeSidecarUnionLeaf = (representation) => {
|
|
625
|
+
if (representation.kind === 'dynamic' || representation.kind === 'null' || representation.kind === 'undefined')
|
|
626
|
+
return true;
|
|
627
|
+
if (representation.kind === 'native-record-ref' && representation.native !== null)
|
|
628
|
+
return false;
|
|
629
|
+
return ((representation.kind === 'record' ||
|
|
630
|
+
representation.kind === 'record-with-index' ||
|
|
631
|
+
representation.kind === 'native-record-ref' ||
|
|
632
|
+
representation.kind === 'class-ref') &&
|
|
633
|
+
representation.ownership === 'shared-refcount');
|
|
634
|
+
};
|
|
635
|
+
/**
|
|
636
|
+
* Dispatch a computed [[Get]] through every arm's existing ordinary-property
|
|
637
|
+
* implementation. This is not a boxed receiver path: each native arm stays
|
|
638
|
+
* in its selected carrier and only the dynamic property result crosses the
|
|
639
|
+
* sidecar boundary before its checked decode.
|
|
640
|
+
*/
|
|
641
|
+
const taggedUnionNativeSidecarGetText = (ctx, operation) => {
|
|
642
|
+
const receiver = operation.receiver.representation;
|
|
643
|
+
// Computed-key-only claim, same as `taggedUnionElementText` above: the
|
|
644
|
+
// pre-render map, so a render-time-folded text is never mistaken for a
|
|
645
|
+
// static key and does not wrongly bail this native-sidecar path.
|
|
646
|
+
if (receiver.kind !== 'tagged-union' || ctx.staticKeyTexts.has(operation.key.value))
|
|
647
|
+
return null;
|
|
648
|
+
const leaves = unionPropertyLeaves(receiver, operandText(ctx, operation.receiver));
|
|
649
|
+
if (!leaves.every((leaf) => nativeSidecarUnionLeaf(leaf.representation)))
|
|
650
|
+
return null;
|
|
651
|
+
const site = 'a computed "get" on a native-sidecar tagged union';
|
|
652
|
+
const key = propertyKeyText(ctx, operation.key, site);
|
|
653
|
+
const published = operation.result.representation;
|
|
654
|
+
const boxed = { kind: 'dynamic', reason: 'declared-any-never-narrowed' };
|
|
655
|
+
const texts = leaves.map((leaf) => {
|
|
656
|
+
if (leaf.representation.kind === 'null' || leaf.representation.kind === 'undefined') {
|
|
657
|
+
return `gea::host::throwGetPropertyOfNullish<${cppTypeOf(published)}>("${leaf.representation.kind}")`;
|
|
658
|
+
}
|
|
659
|
+
const read = leaf.representation.kind === 'dynamic' ? `${leaf.text}.getProperty(${key})` : `gea::nativeDynamicGet(${leaf.text}, ${key})`;
|
|
660
|
+
const decoded = alignedValueText(ctx, 'emit-union-properties.ts:541', boxed, published, read);
|
|
661
|
+
if (decoded !== null)
|
|
662
|
+
return decoded;
|
|
663
|
+
throw createCppEmitBlockedError('property-access:tagged-union(native-sidecar-arms):get:true', `a computed native-sidecar read publishes "${representationKey(published)}", which has no checked dynamic decode`);
|
|
664
|
+
});
|
|
665
|
+
return dispatchedLeafExpression(leaves, texts);
|
|
666
|
+
};
|
|
667
|
+
/**
|
|
668
|
+
* One array arm's own indexed read, reconciled to what the whole union's
|
|
669
|
+
* `get` publishes -- the array-arms mirror of `dictionaryArmReadText`, over
|
|
670
|
+
* `elementAt`/`hasElement` (or the narrowed-integer `elementAtIndex`/
|
|
671
|
+
* `hasElementAtIndex` pair) instead of `read`/`has`. `widenedStoreText`
|
|
672
|
+
* performs the identical per-arm VALUE reconciliation `dictionaryArmReadText`
|
|
673
|
+
* asks of a dictionary's value: wrap this arm's own element type into the
|
|
674
|
+
* published union's matching arm (`ofArm<index>`), or refuse by name when no
|
|
675
|
+
* arm of the published carrier matches.
|
|
676
|
+
*/
|
|
677
|
+
const arrayArmReadText = (armText, reader, keyText, element, published) => {
|
|
678
|
+
const rawRead = `${armText}->${reader}(${keyText})`;
|
|
679
|
+
// `gea::Value` carries the exact `undefined` an absent Array element
|
|
680
|
+
// produces. Even though the present element and published result have the
|
|
681
|
+
// same carrier, the fallible runtime reader cannot produce that absence: it
|
|
682
|
+
// aborts. Guard only the exact dynamic/dynamic pair, leaving typed arms on
|
|
683
|
+
// their existing carrier reconciliation path.
|
|
684
|
+
if (element.kind === 'dynamic' && published.kind === 'dynamic') {
|
|
685
|
+
const has = reader === 'elementAtIndex' ? 'hasElementAtIndex' : 'hasElement';
|
|
686
|
+
return `(${armText}->${has}(${keyText}) ? ${rawRead} : gea::Value())`;
|
|
687
|
+
}
|
|
688
|
+
if (published.kind !== 'optional') {
|
|
689
|
+
if (representationKey(element) === representationKey(published))
|
|
690
|
+
return rawRead;
|
|
691
|
+
const widened = widenedStoreText(published, element, rawRead);
|
|
692
|
+
if (widened !== null)
|
|
693
|
+
return widened;
|
|
694
|
+
throw createCppEmitBlockedError('property-access:tagged-union(array-arms):get:true', `a computed "get" on an array-armed tagged union reaches an arm whose element is stored as ` +
|
|
695
|
+
`"${representationKey(element)}" and this read publishes "${representationKey(published)}"; no widening between those is licensed`);
|
|
696
|
+
}
|
|
697
|
+
const presentText = representationKey(element) === representationKey(published.payload) ? rawRead : widenedStoreText(published.payload, element, rawRead);
|
|
698
|
+
if (presentText === null) {
|
|
699
|
+
throw createCppEmitBlockedError('property-access:tagged-union(array-arms):get:true', `a computed "get" on an array-armed tagged union reaches an arm whose element is stored as ` +
|
|
700
|
+
`"${representationKey(element)}" and this read publishes "optional(${representationKey(published.payload)})"; ` +
|
|
701
|
+
'no widening between those is licensed');
|
|
702
|
+
}
|
|
703
|
+
const has = reader === 'elementAtIndex' ? 'hasElementAtIndex' : 'hasElement';
|
|
704
|
+
const carrier = cppTypeOf(published);
|
|
705
|
+
return `(${armText}->${has}(${keyText}) ? ${carrier}(${presentText}) : ${carrier}())`;
|
|
706
|
+
};
|
|
707
|
+
/**
|
|
708
|
+
* Reading a COMPUTED key off a tagged union whose every arm is an
|
|
709
|
+
* `array-object` -- the array-arms mirror of `taggedUnionDictionaryGetText`.
|
|
710
|
+
* `key.representation.kind !== 'scalar'` refuses the same `ToPropertyKey`
|
|
711
|
+
* gap `arrayAccessText` itself refuses for a lone array, and the reader is
|
|
712
|
+
* `elementAtIndex` wherever the integer census narrowed the key the same way
|
|
713
|
+
* `arrayAccessText` picks it, so a narrowed index costs no double round trip
|
|
714
|
+
* on a union receiver either.
|
|
715
|
+
*/
|
|
716
|
+
const taggedUnionArrayGetText = (ctx, operation) => {
|
|
717
|
+
const receiver = operation.receiver.representation;
|
|
718
|
+
if (!taggedUnionHasOnlyArrayObjectArms(receiver) || receiver.kind !== 'tagged-union')
|
|
719
|
+
return null;
|
|
720
|
+
// Computed-key-only claim, same as `taggedUnionElementText` above: the
|
|
721
|
+
// pre-render map, so a render-time-folded text is never mistaken for a
|
|
722
|
+
// static key and does not wrongly bail this array-arms path.
|
|
723
|
+
if (ctx.staticKeyTexts.get(operation.key.value) !== undefined)
|
|
724
|
+
return null;
|
|
725
|
+
if (operation.key.representation.kind !== 'scalar')
|
|
726
|
+
return null;
|
|
727
|
+
const receiverText = operandText(ctx, operation.receiver);
|
|
728
|
+
const keyText = operandText(ctx, operation.key);
|
|
729
|
+
const reader = ctx.integerValues.has(operation.key.value) ? 'elementAtIndex' : 'elementAt';
|
|
730
|
+
const published = operation.result.representation;
|
|
731
|
+
const armTexts = receiver.arms.map((arm, index) => {
|
|
732
|
+
const array = arm.value;
|
|
733
|
+
if (array.kind !== 'array-object') {
|
|
734
|
+
// Unreachable given `taggedUnionHasOnlyArrayObjectArms` above; kept so
|
|
735
|
+
// the map body stays narrowed to the array-object variant without a
|
|
736
|
+
// cast.
|
|
737
|
+
throw createCppEmitBlockedError('property-access:tagged-union(array-arms):get:true', 'an array-arms union reached a non-array arm');
|
|
738
|
+
}
|
|
739
|
+
const armText = armAt(receiverText, index);
|
|
740
|
+
return arrayArmReadText(armText, reader, keyText, array.element, published);
|
|
741
|
+
});
|
|
742
|
+
const dispatched = armTexts.reduceRight((rest, text, index) => (rest === null ? text : `${armIs(receiverText, index)} ? ${text} : (${rest})`), null);
|
|
743
|
+
if (dispatched === null)
|
|
744
|
+
return null;
|
|
745
|
+
return armTexts.length > 1 ? `(${dispatched})` : dispatched;
|
|
746
|
+
};
|
|
747
|
+
const deferredUnionMethodArmsOf = (ctx, representation, key) => {
|
|
748
|
+
if (representation.kind === 'tagged-union') {
|
|
749
|
+
const nested = [];
|
|
750
|
+
for (const [index, arm] of representation.arms.entries()) {
|
|
751
|
+
const armArms = deferredUnionMethodArmsOf(ctx, arm.value, key);
|
|
752
|
+
if (armArms === null)
|
|
753
|
+
return null;
|
|
754
|
+
nested.push(...armArms.map((entry) => ({ ...entry, path: [index, ...entry.path] })));
|
|
755
|
+
}
|
|
756
|
+
return nested;
|
|
757
|
+
}
|
|
758
|
+
if (representation.kind !== 'class-ref')
|
|
759
|
+
return null;
|
|
760
|
+
const site = classMemberOf(ctx.classes, representation.declaration, key);
|
|
761
|
+
if (site === null || site.kind !== 'method' || site.method.callable === null)
|
|
762
|
+
return null;
|
|
763
|
+
// An own property written over the method (`this.match = ...`, which hono's
|
|
764
|
+
// SmartRouter does to memoise its choice) shadows the prototype for every
|
|
765
|
+
// later read. Calling the declared body straight from the union tag would
|
|
766
|
+
// answer with the body the assignment replaced. The lone-class twins of this
|
|
767
|
+
// claim already decline on the same question; this one did not, and the
|
|
768
|
+
// program compiled to the wrong answer rather than refusing.
|
|
769
|
+
if (classMethodOverrideOf(ctx.classes, representation.declaration, key) !== null)
|
|
770
|
+
return null;
|
|
771
|
+
if (classFamilyOverridesOf(ctx.classes, representation.declaration, key).length > 0)
|
|
772
|
+
return null;
|
|
773
|
+
if (ctx.captures.of(site.method.callable).kind !== 'none' || ctx.abiOfCallable(site.method.callable) === null)
|
|
774
|
+
return null;
|
|
775
|
+
return [{ path: [], receiverRepresentation: representation, callable: site.method.callable }];
|
|
776
|
+
};
|
|
777
|
+
/**
|
|
778
|
+
* Whether a member read through a tagged union is a deferred method read whose
|
|
779
|
+
* every arm names a concrete body, and which bodies those are.
|
|
780
|
+
*
|
|
781
|
+
* The read itself has no single callable ABI -- each arm keeps its own
|
|
782
|
+
* receiver and covariant result -- so the following call dispatches by union
|
|
783
|
+
* tag. What travels is the arm PATH and the body, never a spelled receiver:
|
|
784
|
+
* `emit-callable.ts` folds `armAt`/`armIs` down the path from the union's own
|
|
785
|
+
* operand at the call, which is the first point where that operand has a name.
|
|
786
|
+
*
|
|
787
|
+
* Stated once; `taggedUnionGetText` and the prepass walk both ask it.
|
|
788
|
+
*/
|
|
789
|
+
/**
|
|
790
|
+
* `x.toString()` where `x` is a tagged union -- hono's own `input =
|
|
791
|
+
* input.toString()` over `string | URL`.
|
|
792
|
+
*
|
|
793
|
+
* This is the EXPLICIT spelling of the operation `${x}` already renders for
|
|
794
|
+
* the same carrier, so it is answered by the same table (`toStringTextOver`),
|
|
795
|
+
* which descends per arm: a string arm is itself (22.1.3.29 returns the
|
|
796
|
+
* primitive), a class arm with its own `toString` calls that method, a class
|
|
797
|
+
* without one is the "[object Object]" tag. Routing it through the per-arm
|
|
798
|
+
* FIELD walk instead is what refused it -- there is no field named "toString"
|
|
799
|
+
* on a string.
|
|
800
|
+
*
|
|
801
|
+
* Fail-closed in two ways, both because `x.toString()` is NOT ToString(x):
|
|
802
|
+
*
|
|
803
|
+
* - a nullish arm answers `null`/`undefined` to ToString and throws a
|
|
804
|
+
* TypeError to `.toString()`, so any arm that can be absent declines the
|
|
805
|
+
* whole claim rather than printing the text "null";
|
|
806
|
+
* - `explicit` stays false, which is what keeps a symbol arm refusing:
|
|
807
|
+
* `String(sym)` is legal and `sym.toString()`'s own 20.4.3.3 is not the
|
|
808
|
+
* same function this table would render for it.
|
|
809
|
+
*
|
|
810
|
+
* A union `toStringTextOver` cannot render at all declines here too, so the
|
|
811
|
+
* arm that has no ToString keeps its own named refusal from the field walk.
|
|
812
|
+
*/
|
|
813
|
+
export const deferredUnionToStringClaim = (ctx, receiver, key) => {
|
|
814
|
+
const carrier = receiver.representation;
|
|
815
|
+
if (carrier.kind !== 'tagged-union')
|
|
816
|
+
return null;
|
|
817
|
+
if (ctx.staticKeyTexts.get(key.value) !== 'toString')
|
|
818
|
+
return null;
|
|
819
|
+
for (const arm of carrier.arms) {
|
|
820
|
+
if (arm.value.kind === 'null' || arm.value.kind === 'undefined' || arm.value.kind === 'optional')
|
|
821
|
+
return null;
|
|
822
|
+
}
|
|
823
|
+
const layouts = recordLayoutPolicyOf(ctx.deriver, ctx.classes);
|
|
824
|
+
if (toStringTextOver('gea_receiver', carrier, layouts) === null)
|
|
825
|
+
return null;
|
|
826
|
+
return { receiverKind: 'union-to-string', member: 'toString', receiver: { kind: 'operand', operand: receiver }, receiverElement: null };
|
|
827
|
+
};
|
|
828
|
+
/** The call half of `deferredUnionToStringClaim`, fused with the read above. */
|
|
829
|
+
export const unionToStringCallText = (ctx, carrier, receiverText) => {
|
|
830
|
+
const text = toStringTextOver(receiverText, carrier, recordLayoutPolicyOf(ctx.deriver, ctx.classes));
|
|
831
|
+
if (text === null) {
|
|
832
|
+
throw createCppEmitBlockedError('property-access:tagged-union:get:false', `a union "toString" was claimed for "${representationKey(carrier)}" and its ToString table then declined it`);
|
|
833
|
+
}
|
|
834
|
+
return text;
|
|
835
|
+
};
|
|
836
|
+
export const deferredUnionMethodClaim = (ctx, receiver, key) => {
|
|
837
|
+
if (receiver.representation.kind !== 'tagged-union')
|
|
838
|
+
return null;
|
|
839
|
+
const staticKey = ctx.staticKeyTexts.get(key.value);
|
|
840
|
+
if (staticKey === undefined)
|
|
841
|
+
return null;
|
|
842
|
+
const arms = deferredUnionMethodArmsOf(ctx, receiver.representation, staticKey);
|
|
843
|
+
return arms === null ? null : { receiver, arms };
|
|
844
|
+
};
|
|
845
|
+
/**
|
|
846
|
+
* Reading a STATIC key off a tagged-union receiver, or `null` when this is not
|
|
847
|
+
* that case (a different receiver kind, or a computed key this file declines).
|
|
848
|
+
*
|
|
849
|
+
* Every arm is resolved and, where its declared field carrier differs from
|
|
850
|
+
* what this GET publishes, reconciled through `convertedValueText` -- the
|
|
851
|
+
* general reconciliation `emit-bindings.ts`'s own store and `emit-return.ts`'s
|
|
852
|
+
* own ABI result already ask, needed here in both directions an arm can
|
|
853
|
+
* disagree with the union's own published read: narrower (an arm's field is
|
|
854
|
+
* one union the published read narrows further) and wider (an arm's field is
|
|
855
|
+
* a plain value the published read still states as the whole tuple-union,
|
|
856
|
+
* `request.ts`'s own `Result<T>`). An arm that resolves to nothing, or whose
|
|
857
|
+
* field cannot be reconciled to the published carrier by any means including
|
|
858
|
+
* a dynamic boundary (`armDynamicFieldText`), refuses the WHOLE union by
|
|
859
|
+
* name: a dispatch that silently dropped one arm's read would be a wrong
|
|
860
|
+
* answer for
|
|
861
|
+
* every value that happened to be that arm, which is worse than refusing to
|
|
862
|
+
* compile.
|
|
863
|
+
*/
|
|
864
|
+
export const taggedUnionGetText = (ctx, lines, operation) => {
|
|
865
|
+
const receiver = operation.receiver.representation;
|
|
866
|
+
if (receiver.kind !== 'tagged-union')
|
|
867
|
+
return null;
|
|
868
|
+
const numeric = nativeNumericUnionGetText(ctx, operation);
|
|
869
|
+
if (numeric !== null)
|
|
870
|
+
return numeric;
|
|
871
|
+
const element = taggedUnionElementText(ctx, operation);
|
|
872
|
+
if (element !== null)
|
|
873
|
+
return element;
|
|
874
|
+
const arrayElement = taggedUnionArrayGetText(ctx, operation);
|
|
875
|
+
if (arrayElement !== null)
|
|
876
|
+
return arrayElement;
|
|
877
|
+
const dictionaryElement = taggedUnionDictionaryGetText(ctx, operation);
|
|
878
|
+
if (dictionaryElement !== null)
|
|
879
|
+
return dictionaryElement;
|
|
880
|
+
const nativeSidecar = taggedUnionNativeSidecarGetText(ctx, operation);
|
|
881
|
+
if (nativeSidecar !== null)
|
|
882
|
+
return nativeSidecar;
|
|
883
|
+
// The STATIC-key dispatch below decides which per-arm field/method site
|
|
884
|
+
// answers this read; that decision must come from the pre-render map, never
|
|
885
|
+
// from `constantTexts`'s render-time `typeof`-fold accretion, or a computed
|
|
886
|
+
// key the earlier computed-key claims above correctly declined would be
|
|
887
|
+
// treated as naming a field here instead.
|
|
888
|
+
const key = ctx.staticKeyTexts.get(operation.key.value);
|
|
889
|
+
if (key === undefined)
|
|
890
|
+
return null;
|
|
891
|
+
const receiverText = operandText(ctx, operation.receiver);
|
|
892
|
+
const published = operation.result.representation;
|
|
893
|
+
// `String | Function` is one value with two exact `toString` algorithms:
|
|
894
|
+
// String.prototype.toString returns the primitive itself, while
|
|
895
|
+
// Function.prototype.toString returns the callable's registered source.
|
|
896
|
+
// A `Function` arm is deliberately carried as `dynamic(untyped-callable)`
|
|
897
|
+
// because it promises callability without stating an ABI. Its Value retains
|
|
898
|
+
// the call table selected before payload erasure, and that table now exposes
|
|
899
|
+
// the same CallableObject source fact the statically typed path reads.
|
|
900
|
+
//
|
|
901
|
+
// Snapshot the union at the GET, before call arguments can mutate the cell
|
|
902
|
+
// it came from. The following CALL consumes the ready string expression via
|
|
903
|
+
// `functionSourceReads`, exactly as a lone callable's deferred read does.
|
|
904
|
+
if (functionSourceReadClaimOf(ctx.staticKeyTexts, operation) === 'union') {
|
|
905
|
+
// The snapshot has to be taken HERE, before a call argument can replace the
|
|
906
|
+
// cell the union was read from; that position is all this site still owns.
|
|
907
|
+
// The claim, the name and the per-arm dispatch the following call consumes
|
|
908
|
+
// are settled by `function-source-reads.ts`.
|
|
909
|
+
const name = ctx.functionSourceSnapshotNames.get(operation.result.id);
|
|
910
|
+
if (name === undefined) {
|
|
911
|
+
throw createCppEmitBlockedError('call-abi:function-source', 'a settled function-source read reached its render with no snapshot name');
|
|
912
|
+
}
|
|
913
|
+
ctx.declarations.push({ name, type: cppTypeOf(receiver) });
|
|
914
|
+
lines.push(`${name} = ${receiverText};`);
|
|
915
|
+
return '';
|
|
916
|
+
}
|
|
917
|
+
if (deferredTypedArrayUnionMethodClaim(ctx.staticKeyTexts, operation.receiver, operation.key) !== null) {
|
|
918
|
+
// Recorded by the prototype-read walk, which asked the same claim.
|
|
919
|
+
return '';
|
|
920
|
+
}
|
|
921
|
+
if (deferredUnionMethodClaim(ctx, operation.receiver, operation.key) !== null) {
|
|
922
|
+
// Recorded by the prototype-read walk's sibling, which asked the same claim.
|
|
923
|
+
return '';
|
|
924
|
+
}
|
|
925
|
+
if (deferredUnionToStringClaim(ctx, operation.receiver, operation.key) !== null) {
|
|
926
|
+
// Recorded by the prototype-read walk, which asked the same claim.
|
|
927
|
+
return '';
|
|
928
|
+
}
|
|
929
|
+
// A read nothing but `typeof` consumes, off arms that disagree about the
|
|
930
|
+
// member: the question has a per-arm answer and the value has none, so the
|
|
931
|
+
// `typeof` renders the dispatch and this renders nothing at all. Settled by
|
|
932
|
+
// `unionMemberTypeofReadsOf`, which is where the conditions live.
|
|
933
|
+
if (ctx.unionMemberTypeofReads.has(operation.result.id))
|
|
934
|
+
return '';
|
|
935
|
+
if (ctx.prototypeMethodReads.get(operation.result.id)?.receiverKind === 'mixed-union') {
|
|
936
|
+
// A heterogeneous union whose arms disagree about this member: the walk
|
|
937
|
+
// recorded one answer PER ARM (`mixedUnionClaimOf`), and the call fusion
|
|
938
|
+
// spells the dispatch. Asked of the recorded fact rather than re-derived,
|
|
939
|
+
// because the claim is per-arm and re-deriving it here would be the second
|
|
940
|
+
// authority the single-census refactor exists to remove.
|
|
941
|
+
return '';
|
|
942
|
+
}
|
|
943
|
+
const leaves = unionPropertyLeaves(receiver, receiverText);
|
|
944
|
+
const armTexts = leaves.map((leaf) => {
|
|
945
|
+
const site = armFieldSite(ctx, leaf.representation, leaf.text, key);
|
|
946
|
+
if (site === null) {
|
|
947
|
+
const native = armRuntimeFieldText(ctx, leaf.representation, leaf.text, key, operation);
|
|
948
|
+
if (native !== null)
|
|
949
|
+
return native;
|
|
950
|
+
// No native recipe is not proof of absence: a prototype or accessor
|
|
951
|
+
// may answer this key. Keep that case visible instead of inventing an
|
|
952
|
+
// undefined result or boxing the typed receiver.
|
|
953
|
+
throw createCppEmitBlockedError('property-access:tagged-union:get:false', `a "get" of "${key}" on a tagged union reaches an arm carried as "${representationKey(leaf.representation)}" with no native property recipe ` +
|
|
954
|
+
`producing "${representationKey(published)}"; boxing a typed receiver is not a property implementation`);
|
|
955
|
+
}
|
|
956
|
+
if (representationKey(site.representation) === representationKey(published))
|
|
957
|
+
return site.text;
|
|
958
|
+
// `convertedValueText`, not `narrowedLoadText` alone: this arm's field can
|
|
959
|
+
// need to WIDEN into what the whole union's `get` publishes just as often
|
|
960
|
+
// as it needs to narrow out of one -- hono's own `Result<T>` (`request.ts`'s
|
|
961
|
+
// `#matchResult[0]`) is a tuple union whose "0" field is a plain
|
|
962
|
+
// `array-object` on one arm and the census still publishes the READ as the
|
|
963
|
+
// two-arm union, because the other tuple arm's own "0" differs. That is a
|
|
964
|
+
// widen (`widenedStoreText`'s job), and `narrowedLoadText` alone only ever
|
|
965
|
+
// reads FROM a union, never INTO one (its own `inner.kind !== 'tagged-union'
|
|
966
|
+
// -> null` at the top) -- `convertedValueText` is the superset that tries
|
|
967
|
+
// both, plus the optional-payload wrap (`this.#matchResult[1]`, present-or-
|
|
968
|
+
// absent), before it is asked to fail closed.
|
|
969
|
+
const converted = classFamilyLoadText(ctx, site.representation, published, site.text) ??
|
|
970
|
+
// A `this`-typed function stored in one arm's field, read through a
|
|
971
|
+
// member the union's own declaration states as a method -- hono's
|
|
972
|
+
// `RegExpRouter.match` against `Router<T>.match`. The receiver the
|
|
973
|
+
// language binds is the object this read went through, and it is in
|
|
974
|
+
// hand here.
|
|
975
|
+
receiverBoundFieldText(ctx, site.representation, published, site.text, operation.receiver.representation, operandText(ctx, operation.receiver)) ??
|
|
976
|
+
alignedValueText(ctx, 'emit-union-properties.ts:788', site.representation, published, site.text);
|
|
977
|
+
if (converted !== null)
|
|
978
|
+
return converted;
|
|
979
|
+
throw createCppEmitBlockedError('property-access:tagged-union:get:false', `a "get" of "${key}" on a tagged union reaches an arm whose field is stored as "${representationKey(site.representation)}" and this ` +
|
|
980
|
+
`read publishes "${representationKey(published)}"; no conversion between those is licensed`);
|
|
981
|
+
});
|
|
982
|
+
// Built right-to-left with `reduceRight` rather than by indexing the array,
|
|
983
|
+
// so the accumulator and the arm text are always the `string` the map above
|
|
984
|
+
// produced -- never `string | undefined` from a bounds check TypeScript
|
|
985
|
+
// cannot itself prove.
|
|
986
|
+
const dispatched = dispatchedLeafExpression(leaves, armTexts);
|
|
987
|
+
// A tagged union always has at least two arms (`representation/model.ts`),
|
|
988
|
+
// so this is unreachable in practice; it is here only so the function's own
|
|
989
|
+
// type stays honest about an empty map rather than asserting one away.
|
|
990
|
+
if (dispatched === null)
|
|
991
|
+
return null;
|
|
992
|
+
return dispatched;
|
|
993
|
+
};
|
|
994
|
+
const unionLeafSetText = (ctx, operation, leaf, key, rawValueText) => {
|
|
995
|
+
if (leaf.representation.kind === 'null' || leaf.representation.kind === 'undefined') {
|
|
996
|
+
return `gea::host::throwGetPropertyOfNullish<void>("${leaf.representation.kind}", "set");`;
|
|
997
|
+
}
|
|
998
|
+
const site = armFieldSite(ctx, leaf.representation, leaf.text, key);
|
|
999
|
+
if (site !== null) {
|
|
1000
|
+
const converted = alignedValueText(ctx, 'emit-union-properties.ts:820', operation.value.representation, site.representation, rawValueText);
|
|
1001
|
+
if (converted === null) {
|
|
1002
|
+
throw createCppEmitBlockedError(`property-access:tagged-union:${operation.kind}:false`, `a "${operation.kind}" of "${key}" carries "${representationKey(operation.value.representation)}" into a field stored as ` +
|
|
1003
|
+
`"${representationKey(site.representation)}", and no conversion is installed`);
|
|
1004
|
+
}
|
|
1005
|
+
const writes = `${site.text} = ${converted};${site.presence === null ? '' : ` ${site.presence} = true;`}`;
|
|
1006
|
+
const ownership = addressableArmKind(leaf.representation.kind)
|
|
1007
|
+
? leaf.representation
|
|
1008
|
+
.ownership
|
|
1009
|
+
: 'owned';
|
|
1010
|
+
return ownership === 'shared-refcount' && ctx.nativeIntegrityRestricted
|
|
1011
|
+
? `if (gea::nativeOwnFieldsWritable(${leaf.text})) { ${writes} }`
|
|
1012
|
+
: writes;
|
|
1013
|
+
}
|
|
1014
|
+
if (leaf.representation.kind === 'class-ref') {
|
|
1015
|
+
const member = classMemberOf(ctx.classes, leaf.representation.declaration, key);
|
|
1016
|
+
if (member?.kind === 'accessor' && member.accessor.setter !== null) {
|
|
1017
|
+
if (classFamilyOverridesOf(ctx.classes, leaf.representation.declaration, key).length > 0) {
|
|
1018
|
+
throw createCppEmitBlockedError(`property-access:tagged-union:${operation.kind}:false`, `a "${operation.kind}" of accessor "${key}" through class ${leaf.representation.declaration} needs virtual setter dispatch`);
|
|
1019
|
+
}
|
|
1020
|
+
const abi = ctx.abiOfCallable(member.accessor.setter);
|
|
1021
|
+
const parameter = abi?.parameters[0]?.value;
|
|
1022
|
+
if (abi === null || parameter === undefined) {
|
|
1023
|
+
throw createCppEmitBlockedError(`property-access:tagged-union:${operation.kind}:false`, `setter "${key}" publishes no one-parameter callable convention`);
|
|
1024
|
+
}
|
|
1025
|
+
const converted = alignedValueText(ctx, 'emit-union-properties.ts:849', operation.value.representation, parameter, rawValueText);
|
|
1026
|
+
if (converted === null) {
|
|
1027
|
+
throw createCppEmitBlockedError(`property-access:tagged-union:${operation.kind}:false`, `setter "${key}" expects "${representationKey(parameter)}", while this write carries "${representationKey(operation.value.representation)}"`);
|
|
1028
|
+
}
|
|
1029
|
+
return `${cppBodyName(member.accessor.setter)}(${leaf.text}, ${converted});`;
|
|
1030
|
+
}
|
|
1031
|
+
}
|
|
1032
|
+
const propertyKey = `gea::PropertyKey::string(${cppStringLiteral(key)})`;
|
|
1033
|
+
const boxedValue = sidecarStoredValueText(operation, rawValueText);
|
|
1034
|
+
if (leaf.representation.kind === 'dynamic' && boxedValue !== null) {
|
|
1035
|
+
return `${leaf.text}.setProperty(${propertyKey}, ${boxedValue});`;
|
|
1036
|
+
}
|
|
1037
|
+
if (sidecarArm(leaf.representation) && boxedValue !== null) {
|
|
1038
|
+
return `gea::nativeDynamicSet(${leaf.text}, ${propertyKey}, ${boxedValue});`;
|
|
1039
|
+
}
|
|
1040
|
+
throw createCppEmitBlockedError(`property-access:tagged-union:${operation.kind}:false`, `a "${operation.kind}" of "${key}" on a tagged union reaches an arm carried as "${representationKey(leaf.representation)}", which declares ` +
|
|
1041
|
+
`no writable field or setter "${key}"; not every arm of this union answers this member`);
|
|
1042
|
+
};
|
|
1043
|
+
/** The written value in the boxed carrier an arm's expando sidecar holds, or `null` when it has no boxed store. */
|
|
1044
|
+
const sidecarStoredValueText = (operation, valueText) => widenedStoreText({ kind: 'dynamic', reason: 'declared-any-never-narrowed' }, operation.value.representation, valueText);
|
|
1045
|
+
/**
|
|
1046
|
+
* A computed [[Set]] through every arm's own ordinary-property store -- the
|
|
1047
|
+
* store twin of `taggedUnionNativeSidecarGetText`, over the same admitted
|
|
1048
|
+
* leaves. `nativeDynamicSet` writes a declared field when the key names one
|
|
1049
|
+
* and the arm's identity-keyed expando otherwise, which is the same split the
|
|
1050
|
+
* static-key fallback in `unionLeafSetText` already relies on. Only the value
|
|
1051
|
+
* crosses into the sidecar's boxed carrier; each arm stays native.
|
|
1052
|
+
*/
|
|
1053
|
+
const emitTaggedUnionNativeSidecarSet = (ctx, lines, operation) => {
|
|
1054
|
+
const receiver = operation.receiver.representation;
|
|
1055
|
+
if (receiver.kind !== 'tagged-union')
|
|
1056
|
+
return false;
|
|
1057
|
+
const receiverText = operandText(ctx, operation.receiver);
|
|
1058
|
+
const leaves = unionPropertyLeaves(receiver, receiverText);
|
|
1059
|
+
if (!leaves.every((leaf) => nativeSidecarUnionLeaf(leaf.representation)))
|
|
1060
|
+
return false;
|
|
1061
|
+
const key = propertyKeyText(ctx, operation.key, 'a computed "set" on a native-sidecar tagged union');
|
|
1062
|
+
const value = sidecarStoredValueText(operation, operandText(ctx, operation.value));
|
|
1063
|
+
if (value === null) {
|
|
1064
|
+
throw createCppEmitBlockedError('property-access:tagged-union(native-sidecar-arms):set:true', `a computed native-sidecar store carries "${representationKey(operation.value.representation)}", which has no boxed store`);
|
|
1065
|
+
}
|
|
1066
|
+
const statements = leaves.map((leaf) => {
|
|
1067
|
+
if (leaf.representation.kind === 'null' || leaf.representation.kind === 'undefined') {
|
|
1068
|
+
return `gea::host::throwGetPropertyOfNullish<void>("${leaf.representation.kind}", "set");`;
|
|
1069
|
+
}
|
|
1070
|
+
return leaf.representation.kind === 'dynamic'
|
|
1071
|
+
? `${leaf.text}.setProperty(${key}, ${value});`
|
|
1072
|
+
: `gea::nativeDynamicSet(${leaf.text}, ${key}, ${value});`;
|
|
1073
|
+
});
|
|
1074
|
+
let chain = '';
|
|
1075
|
+
statements.forEach((statement, index) => {
|
|
1076
|
+
if (statements.length === 1)
|
|
1077
|
+
chain = statement;
|
|
1078
|
+
else if (index === 0)
|
|
1079
|
+
chain = `if (${leaves[0]?.test ?? 'false'}) { ${statement} }`;
|
|
1080
|
+
else if (index === statements.length - 1)
|
|
1081
|
+
chain += ` else { ${statement} }`;
|
|
1082
|
+
else
|
|
1083
|
+
chain += ` else if (${leaves[index]?.test ?? 'false'}) { ${statement} }`;
|
|
1084
|
+
});
|
|
1085
|
+
lines.push(chain);
|
|
1086
|
+
if (operation.result)
|
|
1087
|
+
defineValueAlias(ctx, operation.result, receiverText);
|
|
1088
|
+
return true;
|
|
1089
|
+
};
|
|
1090
|
+
/**
|
|
1091
|
+
* Writing a STATIC key onto a tagged-union receiver -- `set` and
|
|
1092
|
+
* `define-own-property` alike, for the identical reason
|
|
1093
|
+
* `emit-properties.ts`'s `emitFieldStoreLines` treats the two as one write:
|
|
1094
|
+
* a definition with no descriptor this backend cannot spell already refused
|
|
1095
|
+
* upstream (`ir/lower-property.ts`), and a default data descriptor IS an
|
|
1096
|
+
* ordinary assignment.
|
|
1097
|
+
*
|
|
1098
|
+
* The dispatch is a real `if`/`else if`/`else` over the union's own arms
|
|
1099
|
+
* rather than one expression, because a store is a statement: every arm but
|
|
1100
|
+
* the last is tested, and the last is unconditional, which is sound only
|
|
1101
|
+
* because the union's own tag is guaranteed to be one of them.
|
|
1102
|
+
*/
|
|
1103
|
+
export const emitTaggedUnionSet = (ctx, lines, operation) => {
|
|
1104
|
+
const receiver = operation.receiver.representation;
|
|
1105
|
+
if (receiver.kind !== 'tagged-union')
|
|
1106
|
+
return false;
|
|
1107
|
+
if (emitNativeNumericUnionSet(ctx, lines, operation))
|
|
1108
|
+
return true;
|
|
1109
|
+
if (emitTaggedUnionElementSet(ctx, lines, operation))
|
|
1110
|
+
return true;
|
|
1111
|
+
// Same STATIC-key claim as `taggedUnionGetText` above: the pre-render map,
|
|
1112
|
+
// never `constantTexts`'s render-time accretion, decides which arm's field
|
|
1113
|
+
// or setter this write targets.
|
|
1114
|
+
const key = ctx.staticKeyTexts.get(operation.key.value);
|
|
1115
|
+
if (key === undefined)
|
|
1116
|
+
return operation.kind === 'set' && emitTaggedUnionNativeSidecarSet(ctx, lines, operation);
|
|
1117
|
+
const receiverText = operandText(ctx, operation.receiver);
|
|
1118
|
+
const rawValueText = operandText(ctx, operation.value);
|
|
1119
|
+
const leaves = unionPropertyLeaves(receiver, receiverText);
|
|
1120
|
+
const statements = leaves.map((leaf) => unionLeafSetText(ctx, operation, leaf, key, rawValueText));
|
|
1121
|
+
// Built by walking the array with `forEach` rather than indexing it, for
|
|
1122
|
+
// the identical `noUncheckedIndexedAccess` reason `taggedUnionGetText`
|
|
1123
|
+
// avoids indexing above: `stmt` and `index` come straight from the
|
|
1124
|
+
// callback, never through a bounds check TypeScript cannot verify.
|
|
1125
|
+
let chain = '';
|
|
1126
|
+
statements.forEach((stmt, index) => {
|
|
1127
|
+
if (statements.length === 1) {
|
|
1128
|
+
chain = stmt;
|
|
1129
|
+
}
|
|
1130
|
+
else if (index === 0) {
|
|
1131
|
+
chain = `if (${leaves[0]?.test ?? 'false'}) { ${stmt} }`;
|
|
1132
|
+
}
|
|
1133
|
+
else if (index === statements.length - 1) {
|
|
1134
|
+
chain += ` else { ${stmt} }`;
|
|
1135
|
+
}
|
|
1136
|
+
else {
|
|
1137
|
+
chain += ` else if (${leaves[index]?.test ?? 'false'}) { ${stmt} }`;
|
|
1138
|
+
}
|
|
1139
|
+
});
|
|
1140
|
+
lines.push(chain);
|
|
1141
|
+
// The store's own result is the receiver threaded onward, exactly as the
|
|
1142
|
+
// ordinary record field store publishes the object it wrote into
|
|
1143
|
+
// (`emit-properties.ts`'s `emitFieldStoreLines`), not the success boolean
|
|
1144
|
+
// the internal method nominally returns.
|
|
1145
|
+
if (operation.result)
|
|
1146
|
+
defineValueAlias(ctx, operation.result, receiverText);
|
|
1147
|
+
return true;
|
|
1148
|
+
};
|
|
1149
|
+
/**
|
|
1150
|
+
* Every deferred tagged-union method read in one body, settled before the body
|
|
1151
|
+
* renders a line. Composes; decides nothing -- `deferredUnionMethodClaim` is
|
|
1152
|
+
* the one statement of what such a read is, and this is its other caller.
|
|
1153
|
+
*/
|
|
1154
|
+
/**
|
|
1155
|
+
* What `typeof` answers for ONE arm's view of a member, or `null` where this
|
|
1156
|
+
* file cannot answer it exactly.
|
|
1157
|
+
*
|
|
1158
|
+
* Every arm answers from a table this backend already owns, never from the
|
|
1159
|
+
* absence of a renderer -- the same discipline `armHasNoCallableMember`
|
|
1160
|
+
* states, for the same reason: "the language answers undefined here" and "this
|
|
1161
|
+
* member is not implemented yet" are different facts, and guessing between
|
|
1162
|
+
* them is a narrowing that silently takes the wrong branch.
|
|
1163
|
+
*
|
|
1164
|
+
* - a declared field on the arm: what its own carrier is;
|
|
1165
|
+
* - a class member: a method is `"function"`, an accessor is whatever its
|
|
1166
|
+
* getter returns;
|
|
1167
|
+
* - a class that declares NO such member: the expando read, for the reason
|
|
1168
|
+
* `UnionMemberTypeofAnswer` states;
|
|
1169
|
+
* - a promise: `Promise.prototype`'s member set is closed (ECMA-262 27.2.5)
|
|
1170
|
+
* and `gea::Promise` has no dynamic-property sidecar, so a member of it is
|
|
1171
|
+
* `"function"` and anything else is `"undefined"`;
|
|
1172
|
+
* - a string: `String.prototype`'s member set is the modelled one, so the same
|
|
1173
|
+
* split, with `length` the one member that is a number.
|
|
1174
|
+
*
|
|
1175
|
+
* `deferred` marks the arms whose member is a PROTOTYPE METHOD -- the ones
|
|
1176
|
+
* with no function object to hand over, which is the only reason the whole
|
|
1177
|
+
* claim exists. `unionMemberTypeofReadsOf` requires one.
|
|
1178
|
+
*/
|
|
1179
|
+
const armMemberTypeofAnswer = (ctx, arm, key) => {
|
|
1180
|
+
const settled = (answer, deferred = false) => ({ answer: { kind: 'constant', answer }, deferred });
|
|
1181
|
+
const site = armFieldSite(ctx, arm, '', key);
|
|
1182
|
+
if (site !== null) {
|
|
1183
|
+
const answer = typeofTextFor(site.representation);
|
|
1184
|
+
return answer === null ? null : settled(answer);
|
|
1185
|
+
}
|
|
1186
|
+
if (arm.kind === 'class-ref') {
|
|
1187
|
+
const member = classMemberOf(ctx.classes, arm.declaration, key);
|
|
1188
|
+
if (member === null)
|
|
1189
|
+
return sidecarArm(arm) ? { answer: { kind: 'expando' }, deferred: false } : null;
|
|
1190
|
+
if (member.kind === 'method')
|
|
1191
|
+
return settled('function');
|
|
1192
|
+
if (member.kind !== 'accessor' || member.accessor.getter === null)
|
|
1193
|
+
return null;
|
|
1194
|
+
const abi = ctx.abiOfCallable(member.accessor.getter);
|
|
1195
|
+
if (abi === null)
|
|
1196
|
+
return null;
|
|
1197
|
+
const answer = typeofTextFor(abi.result);
|
|
1198
|
+
return answer === null ? null : settled(answer);
|
|
1199
|
+
}
|
|
1200
|
+
if (arm.kind === 'promise')
|
|
1201
|
+
return promisePrototypeMethods.has(key) ? settled('function', true) : settled('undefined');
|
|
1202
|
+
if (arm.kind === 'string') {
|
|
1203
|
+
if (key === 'length')
|
|
1204
|
+
return settled('number');
|
|
1205
|
+
if (canonicalIndexLiteral(key) !== null)
|
|
1206
|
+
return null;
|
|
1207
|
+
return isDeclaredStringPrototypeKey(key) ? settled('function', true) : settled('undefined');
|
|
1208
|
+
}
|
|
1209
|
+
return null;
|
|
1210
|
+
};
|
|
1211
|
+
/**
|
|
1212
|
+
* Member reads whose ONLY consumer is `typeof`, off a union whose arms
|
|
1213
|
+
* disagree about the member -- see `EmitContext.unionMemberTypeofReads`.
|
|
1214
|
+
*
|
|
1215
|
+
* Three conditions keep this from taking over reads the ordinary path already
|
|
1216
|
+
* renders, and all three are about not moving output that was already right:
|
|
1217
|
+
*
|
|
1218
|
+
* - at least one arm's member must be a PROTOTYPE METHOD. Those are the only
|
|
1219
|
+
* members this backend can call but never hand over as a value, so they are
|
|
1220
|
+
* the only reason a read like this has nothing to produce. Every other union
|
|
1221
|
+
* either renders the member or refuses for a reason of its own.
|
|
1222
|
+
* - at least one arm must have no declared field site, which is the arm that
|
|
1223
|
+
* disagrees.
|
|
1224
|
+
* - `Object.prototype`'s own names are excluded: they are on every arm, so
|
|
1225
|
+
* they are never the disagreement.
|
|
1226
|
+
*/
|
|
1227
|
+
export const unionMemberTypeofReadsOf = (ctx, body) => {
|
|
1228
|
+
const claimed = new Map();
|
|
1229
|
+
for (const block of body.blocks.values()) {
|
|
1230
|
+
for (const operation of allOperationsOf(block)) {
|
|
1231
|
+
if (operation.kind !== 'get')
|
|
1232
|
+
continue;
|
|
1233
|
+
const receiver = operation.receiver.representation;
|
|
1234
|
+
if (receiver.kind !== 'tagged-union')
|
|
1235
|
+
continue;
|
|
1236
|
+
const key = ctx.staticKeyTexts.get(operation.key.value);
|
|
1237
|
+
if (key === undefined || objectPrototypeMemberNames.has(key))
|
|
1238
|
+
continue;
|
|
1239
|
+
const leaves = unionPropertyLeaves(receiver, '');
|
|
1240
|
+
const resolved = leaves.map((leaf) => armMemberTypeofAnswer(ctx, leaf.representation, key));
|
|
1241
|
+
if (!resolved.every((entry) => entry !== null))
|
|
1242
|
+
continue;
|
|
1243
|
+
if (!resolved.some((entry) => entry.deferred))
|
|
1244
|
+
continue;
|
|
1245
|
+
if (leaves.every((leaf) => armFieldSite(ctx, leaf.representation, '', key) !== null))
|
|
1246
|
+
continue;
|
|
1247
|
+
claimed.set(operation.result.id, { receiver: operation.receiver, member: key, answers: resolved.map((entry) => entry.answer) });
|
|
1248
|
+
}
|
|
1249
|
+
}
|
|
1250
|
+
if (claimed.size === 0)
|
|
1251
|
+
return claimed;
|
|
1252
|
+
// A claimed read renders NOTHING, so anything but a `typeof` reading it
|
|
1253
|
+
// would name a value that was never defined. The scan is over every operand
|
|
1254
|
+
// in the body rather than over the claims themselves, because a value's
|
|
1255
|
+
// consumers are not reachable from its producer.
|
|
1256
|
+
const otherwiseConsumed = new Set();
|
|
1257
|
+
for (const block of body.blocks.values())
|
|
1258
|
+
for (const operation of allOperationsOf(block)) {
|
|
1259
|
+
if (operation.kind === 'compute' && operation.form === 'typeof')
|
|
1260
|
+
continue;
|
|
1261
|
+
for (const operand of operandsOfIrOperation(operation))
|
|
1262
|
+
otherwiseConsumed.add(operand.value);
|
|
1263
|
+
}
|
|
1264
|
+
for (const value of claimed.keys())
|
|
1265
|
+
if (otherwiseConsumed.has(value))
|
|
1266
|
+
claimed.delete(value);
|
|
1267
|
+
return claimed;
|
|
1268
|
+
};
|
|
1269
|
+
export const unionMethodReadsOf = (ctx, body) => {
|
|
1270
|
+
const reads = new Map();
|
|
1271
|
+
for (const block of body.blocks.values()) {
|
|
1272
|
+
for (const operation of allOperationsOf(block)) {
|
|
1273
|
+
if (operation.kind !== 'get')
|
|
1274
|
+
continue;
|
|
1275
|
+
const claim = deferredUnionMethodClaim(ctx, operation.receiver, operation.key);
|
|
1276
|
+
if (claim !== null)
|
|
1277
|
+
reads.set(operation.result.id, claim);
|
|
1278
|
+
}
|
|
1279
|
+
}
|
|
1280
|
+
return reads;
|
|
1281
|
+
};
|