@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,1224 @@
|
|
|
1
|
+
import { canonicalIndexLiteral } from '../../representation/array-index.js';
|
|
2
|
+
import { disjointNativeRecordIndexOf, nativeRecordIndexReadCarrierOf } from '../../ir/native-record-index.js';
|
|
3
|
+
import { cppDenseLengthName, createCppEmitBlockedError, defineValueAlias, operandText, isIntegerStorageValue, wellKnownSymbolMemberOf } from './emit-context.js';
|
|
4
|
+
import { carriesUndefined, isCanonicalNumberPropertyKeyText, recordIndexForKeyCarrier, representationKey } from '../../representation/model.js';
|
|
5
|
+
import { alignedValueText, widenedStoreText } from './emit-narrowing.js';
|
|
6
|
+
import { dictionaryPrototypeMethods, keyedCollectionPrototypeMethods, numberPrototypeMethods, promisePrototypeMethods } from './prototype/emit-prototype-invoke.js';
|
|
7
|
+
import { iteratorPrototypeMethods } from './prototype/emit-prototype-iterator.js';
|
|
8
|
+
import { arrayInheritedMemberRefusals, arrayMemberRefusals, arrayPrototypeMethods } from './prototype/emit-prototype-array.js';
|
|
9
|
+
import { stringMemberRefusals, stringPrototypeMethods } from './prototype/emit-prototype-string.js';
|
|
10
|
+
import { cppReactiveRevisionFieldName, recordFieldsOfShape, recordIndexesOfShape, cppRecordIndexSidecarNameFor, cppRecordIndexAttributesNameFor } from './records.js';
|
|
11
|
+
import { cppArrayExtensionStructName, cppRecordFieldName, cppRecordFieldPresenceName, cppStringLiteral, cppTypeOf, cppUndefinedIn, cppUndefinedValue } from './types.js';
|
|
12
|
+
import { toStringText } from './emit-tostring.js';
|
|
13
|
+
import { typedArrayBufferMemberText, typedArrayBufferMembers, binaryToStringTagText, typedArrayElementSpelling, typedArrayPrototypeMethods } from './emit-buffers.js';
|
|
14
|
+
/**
|
|
15
|
+
* How a member reads on each built-in carrier.
|
|
16
|
+
*
|
|
17
|
+
* These are renderings, not decisions. `emit-properties.ts` remains the one
|
|
18
|
+
* place that *chooses* which of them a given key means -- its own header
|
|
19
|
+
* explains why that choice must not be split, and this file does not split it.
|
|
20
|
+
* What moves here is the mechanical part: given that the receiver is already
|
|
21
|
+
* known to be an Array, a typed array, a string or a scalar, what text does
|
|
22
|
+
* the member read render to. Each answers `null` for a receiver that is not
|
|
23
|
+
* its own, so the caller's dispatch stays a single ordered sequence.
|
|
24
|
+
*/
|
|
25
|
+
export { canonicalIndexLiteral } from '../../representation/array-index.js';
|
|
26
|
+
/**
|
|
27
|
+
* The Array-exotic reading of a property access, or `null` when the receiver is
|
|
28
|
+
* not an Array.
|
|
29
|
+
*
|
|
30
|
+
* `length` is the accessor, not a member: an Array's length is derived from its
|
|
31
|
+
* slots, and a struct field spelling would let it drift from them. A constant
|
|
32
|
+
* key that spells a canonical index (`a[0]`, `a["0"]`) is an element access
|
|
33
|
+
* exactly like a computed one, just with the index known at compile time.
|
|
34
|
+
* A constant key naming one of `arrayPrototypeMethods` (see
|
|
35
|
+
* `emit-prototype-array.ts`, the one authority for which those are) defers
|
|
36
|
+
* instead of refusing: the access records which method was reached and renders
|
|
37
|
+
* nothing, and the following call fuses it with the receiver. Every other
|
|
38
|
+
* constant key is still an ordinary property this carrier has no table for,
|
|
39
|
+
* and stays refused by name -- with a stated reason where `arrayMemberRefusals`
|
|
40
|
+
* has one, because "not built yet" and "cannot be built without X" are
|
|
41
|
+
* different answers and only the second tells you what to build.
|
|
42
|
+
*
|
|
43
|
+
* `result` is the `[[Get]]`'s own SSA value id, needed only for the deferred
|
|
44
|
+
* branch (to key `ctx.prototypeMethodReads` by); every other branch ignores
|
|
45
|
+
* it, the same asymmetry `nativeHandleMemberText` already has.
|
|
46
|
+
*/
|
|
47
|
+
/**
|
|
48
|
+
* An indexed Array read whose result carrier can be ABSENT, or `null` when it
|
|
49
|
+
* cannot and the plain reader is right.
|
|
50
|
+
*
|
|
51
|
+
* `elementAt` has no absent answer -- it aborts -- and under the type
|
|
52
|
+
* `lib.es5.d.ts` gives `a[i]` that is the honest behaviour, because the result
|
|
53
|
+
* carrier is `T` and there is no `undefined` in it to produce.
|
|
54
|
+
* `noUncheckedIndexedAccess` is one case where the checker says otherwise: the
|
|
55
|
+
* result is `T | undefined`, the carrier is absence-capable, and the
|
|
56
|
+
* language's own answer for a hole or an out-of-range index is that
|
|
57
|
+
* `undefined` rather than a fault. A genuinely dynamic element/result pair is
|
|
58
|
+
* the other: `gea::Value` itself carries `undefined`, so returning the bare
|
|
59
|
+
* reader would abort where its stated result can represent the exact answer.
|
|
60
|
+
* Emitting the bare reader for either leaves two authorities on one read --
|
|
61
|
+
* the carrier promising absence the access never produces.
|
|
62
|
+
*
|
|
63
|
+
* The presence test is `ArrayObject::hasElement`, which is `elementAt`'s own
|
|
64
|
+
* abort condition negated and stated once in the runtime, so "readable" cannot
|
|
65
|
+
* drift between the two. Both arms are written in the optional's own spelling
|
|
66
|
+
* rather than relying on the conditional operator to find a common type
|
|
67
|
+
* through `Optional<T>`'s converting constructor -- the same shape
|
|
68
|
+
* `narrowedLoadText` already writes for a narrowed optional load.
|
|
69
|
+
*
|
|
70
|
+
* The receiver and the key are re-mentioned, not re-evaluated: both are
|
|
71
|
+
* operand texts, which are SSA names or literals.
|
|
72
|
+
*
|
|
73
|
+
* `null` for every other mismatch, which keeps this to the case it can answer:
|
|
74
|
+
* a result carrier that differs from the element for some other reason is left
|
|
75
|
+
* exactly as it rendered before.
|
|
76
|
+
*/
|
|
77
|
+
const absentCapableElementText = (ctx, receiverText, reader, keyText, element, result) => {
|
|
78
|
+
const present = presentElementText(ctx, element, result, `${receiverText}->${reader}(${keyText})`);
|
|
79
|
+
if (present === null)
|
|
80
|
+
return null;
|
|
81
|
+
// `hasElementValue`, never `hasElement`: this arm publishes the language's
|
|
82
|
+
// `undefined` for the absent case, and an index whose stored element is
|
|
83
|
+
// ITSELF `undefined` (`pushUndefined` -- a template object's invalid escape,
|
|
84
|
+
// a literal `[0, undefined]`) reads as `undefined` too. `hasElement` answers
|
|
85
|
+
// `[[HasProperty]]`, which is `true` there; see its twin in the runtime for
|
|
86
|
+
// why one predicate must not answer both.
|
|
87
|
+
const has = reader === 'elementAtIndex' ? 'hasElementValueAtIndex' : 'hasElementValue';
|
|
88
|
+
const carrier = result?.representation ?? element;
|
|
89
|
+
const absent = carrier.kind === 'tagged-union'
|
|
90
|
+
? alignedValueText(ctx, 'emit-carrier-members.ts:141', { kind: 'undefined' }, carrier, cppUndefinedValue)
|
|
91
|
+
: `${cppTypeOf(carrier)}()`;
|
|
92
|
+
return absent === null ? null : `(${receiverText}->${has}(${keyText}) ? ${present} : ${absent})`;
|
|
93
|
+
};
|
|
94
|
+
/**
|
|
95
|
+
* An indexed read whose result carrier is not the element's, RECONCILED --
|
|
96
|
+
* the same read written in the carrier the access publishes.
|
|
97
|
+
*
|
|
98
|
+
* `absentCapableElementText` answers the absence question and nothing else, so
|
|
99
|
+
* every other disagreement between the element and the published carrier fell
|
|
100
|
+
* through to the bare reader, whose C++ type is the ELEMENT's. Two authorities
|
|
101
|
+
* on one read again: hono's `newResponse: NewResponse = (...args) =>
|
|
102
|
+
* this.#newResponse(...args)` reads `args[0]` out of an array of boxes and
|
|
103
|
+
* publishes `Data | null` -- the tuple element the checker states for that
|
|
104
|
+
* position -- and the bare `elementAt(0)` handed a `gea::Value` to a
|
|
105
|
+
* `gea::Optional<gea::TaggedUnion<...>>` parameter with nothing between them.
|
|
106
|
+
*
|
|
107
|
+
* The read is reconciled through the one conversion authority, which for a
|
|
108
|
+
* `dynamic` element is the checked unbox. A pair it cannot answer is left as
|
|
109
|
+
* the bare reader rendered before: this states the conversions that ARE
|
|
110
|
+
* licensed rather than becoming a new refusal over reads that already emit.
|
|
111
|
+
*/
|
|
112
|
+
const reconciledElementText = (ctx, element, result, text) => {
|
|
113
|
+
const carrier = result?.representation;
|
|
114
|
+
if (carrier === undefined || representationKey(carrier) === representationKey(element))
|
|
115
|
+
return text;
|
|
116
|
+
return alignedValueText(ctx, 'emit-carrier-members.ts:166', element, carrier, text) ?? text;
|
|
117
|
+
};
|
|
118
|
+
/**
|
|
119
|
+
* An element already PROVEN present, written in the result's own carrier, or
|
|
120
|
+
* `null` when that carrier is not absence-capable and the element stands as it
|
|
121
|
+
* is.
|
|
122
|
+
*
|
|
123
|
+
* Two readers produce a proven-present element and both need this: the guarded
|
|
124
|
+
* arm of `absentCapableElementText`, whose guard is the proof, and the dense
|
|
125
|
+
* window's fast path, whose flag is (`ir/dense-loops.ts` admits a window only
|
|
126
|
+
* for an array with no hole and an index the loop's own bound covers -- the
|
|
127
|
+
* general form is what runs otherwise). Stating it once is what keeps the two
|
|
128
|
+
* arms of that window's conditional in one C++ type instead of leaving the
|
|
129
|
+
* conditional operator to find one through `Optional<T>`'s converting
|
|
130
|
+
* constructor.
|
|
131
|
+
*/
|
|
132
|
+
export const presentElementText = (ctx, element, result, text) => {
|
|
133
|
+
const carrier = result?.representation;
|
|
134
|
+
// A present dynamic element already has the result's exact carrier. Returning
|
|
135
|
+
// its text here lets `absentCapableElementText` guard the fallible reader and
|
|
136
|
+
// use `gea::Value()` for a hole without boxing or changing a present value.
|
|
137
|
+
if (element.kind === 'dynamic' && carrier?.kind === 'dynamic')
|
|
138
|
+
return text;
|
|
139
|
+
if (carrier === undefined)
|
|
140
|
+
return null;
|
|
141
|
+
// A result that is the element plus `undefined` spelled as a tagged union
|
|
142
|
+
// (`undefined | null | T` over a `(T | null)[]`, where an `Optional` of an
|
|
143
|
+
// `Optional` has no primitive): the present arm is the element WIDENED into
|
|
144
|
+
// the union by the one conversion authority, the absent arm is the union's
|
|
145
|
+
// own `undefined`.
|
|
146
|
+
if (carrier.kind === 'tagged-union' && carriesUndefined(carrier))
|
|
147
|
+
return alignedValueText(ctx, 'emit-carrier-members.ts:195', element, carrier, text);
|
|
148
|
+
if (carrier.kind !== 'optional' || carrier.absence !== 'undefined')
|
|
149
|
+
return null;
|
|
150
|
+
// An element that is ITSELF the result's carrier -- `(string | undefined)[]`
|
|
151
|
+
// read at a position, or the `optional(string)` capture slots of a
|
|
152
|
+
// `RegExpExecArray` snapshot -- is present as stored, absence included.
|
|
153
|
+
// Converting it into the carrier's PAYLOAD below narrows it (`(*x)`), which
|
|
154
|
+
// on a stored absent element is the empty payload, and re-wrapping that
|
|
155
|
+
// reports a hole as a present empty value: `const [, b = 'B'] = ['0',
|
|
156
|
+
// undefined]` bound `b` to `''`, so the default never fired.
|
|
157
|
+
if (representationKey(carrier) === representationKey(element))
|
|
158
|
+
return text;
|
|
159
|
+
const converted = alignedValueText(ctx, 'emit-carrier-members.ts:205', element, carrier.payload, text);
|
|
160
|
+
return converted === null ? null : `${cppTypeOf(carrier)}(${converted})`;
|
|
161
|
+
};
|
|
162
|
+
/**
|
|
163
|
+
* Whether an Array member read is a deferred `Array.prototype` METHOD read,
|
|
164
|
+
* and what it is.
|
|
165
|
+
*
|
|
166
|
+
* The one statement of that test. `arrayAccessText` below asks it rather than
|
|
167
|
+
* repeating it, and so does the walk that settles
|
|
168
|
+
* `EmitContext.prototypeMethodReads` before a body renders -- one
|
|
169
|
+
* implementation, two callers, which is what keeps a fact to one authority.
|
|
170
|
+
* The exclusions are the branches that claim the key FIRST and are therefore
|
|
171
|
+
* part of the same question: `length`, a field the array's extension declares,
|
|
172
|
+
* and a canonical index.
|
|
173
|
+
*/
|
|
174
|
+
export const deferredArrayMethodClaim = (staticKeyTexts, receiver, key) => {
|
|
175
|
+
const carrier = receiver.representation;
|
|
176
|
+
if (carrier.kind !== 'array-object')
|
|
177
|
+
return null;
|
|
178
|
+
const staticKey = staticKeyTexts.get(key.value);
|
|
179
|
+
if (staticKey === undefined || staticKey === 'length')
|
|
180
|
+
return null;
|
|
181
|
+
if (carrier.extension?.some((field) => field.key === staticKey) === true)
|
|
182
|
+
return null;
|
|
183
|
+
if (canonicalIndexLiteral(staticKey) !== null)
|
|
184
|
+
return null;
|
|
185
|
+
if (!arrayPrototypeMethods.has(staticKey))
|
|
186
|
+
return null;
|
|
187
|
+
return {
|
|
188
|
+
receiverKind: 'array-object',
|
|
189
|
+
member: staticKey,
|
|
190
|
+
receiver: { kind: 'operand', operand: receiver },
|
|
191
|
+
receiverElement: representationKey(carrier.element),
|
|
192
|
+
arrayCarrier: carrier
|
|
193
|
+
};
|
|
194
|
+
};
|
|
195
|
+
export const arrayAccessText = (ctx, receiver, key, result) => {
|
|
196
|
+
if (receiver.representation.kind !== 'array-object')
|
|
197
|
+
return null;
|
|
198
|
+
// A wrapped dense window's divisor, already read at its own preheader: the
|
|
199
|
+
// loop cannot resize the array, and re-reading the length there is what stops
|
|
200
|
+
// the backend keeping the window's base pointer in a register.
|
|
201
|
+
const hoisted = result === null ? undefined : ctx.denseLengths.get(result.id);
|
|
202
|
+
if (hoisted !== undefined)
|
|
203
|
+
return cppDenseLengthName(hoisted);
|
|
204
|
+
const receiverText = operandText(ctx, receiver);
|
|
205
|
+
const staticKey = ctx.staticKeyTexts.get(key.value);
|
|
206
|
+
if (staticKey === 'length')
|
|
207
|
+
return `${receiverText}->length()`;
|
|
208
|
+
// A field the array's extended interface declares (`array-object.extension`,
|
|
209
|
+
// `NodeArray.pos`): read off the extension sidecar the runtime array holds,
|
|
210
|
+
// typed by the generated struct `records.ts` declared for these fields. A
|
|
211
|
+
// read of an array that never gained its fields sees the struct's own
|
|
212
|
+
// defaults (`extensionFields`), never allocates. An optional field answers
|
|
213
|
+
// from its presence bit the way a record's does (`narrowedFieldReadText`):
|
|
214
|
+
// the stored value when set, the published carrier's own `undefined`
|
|
215
|
+
// otherwise -- and a read the branch already proved present publishes a
|
|
216
|
+
// carrier with no `undefined` in it, which is the plain member load.
|
|
217
|
+
const extensionField = staticKey === undefined ? undefined : receiver.representation.extension?.find((field) => field.key === staticKey);
|
|
218
|
+
if (extensionField !== undefined && receiver.representation.extension) {
|
|
219
|
+
const struct = cppArrayExtensionStructName(receiver.representation.extension);
|
|
220
|
+
const fields = `${receiverText}->template extensionFields<${struct}>()`;
|
|
221
|
+
const present = reconciledElementText(ctx, extensionField.value, result, `${fields}.${cppRecordFieldName(extensionField.key)}`);
|
|
222
|
+
const absent = extensionField.required || result === null ? null : cppUndefinedIn(result.representation);
|
|
223
|
+
return absent === null ? present : `(${fields}.${cppRecordFieldPresenceName(extensionField.key)} ? ${present} : ${absent})`;
|
|
224
|
+
}
|
|
225
|
+
if (wellKnownSymbolMemberOf(ctx, key) === 'toStringTag')
|
|
226
|
+
return binaryToStringTagText(receiver.representation);
|
|
227
|
+
if (staticKey !== undefined) {
|
|
228
|
+
const index = canonicalIndexLiteral(staticKey);
|
|
229
|
+
if (index !== null) {
|
|
230
|
+
return (absentCapableElementText(ctx, receiverText, 'elementAt', index, receiver.representation.element, result) ??
|
|
231
|
+
reconciledElementText(ctx, receiver.representation.element, result, `${receiverText}->elementAt(${index})`));
|
|
232
|
+
}
|
|
233
|
+
if (deferredArrayMethodClaim(ctx.staticKeyTexts, receiver, key) !== null) {
|
|
234
|
+
if (result === null) {
|
|
235
|
+
throw createCppEmitBlockedError('property-access:array-object:get:false', `"${staticKey}" is an Array.prototype method, and this access publishes no value for its call to consume`);
|
|
236
|
+
}
|
|
237
|
+
// The receiver's reactive origin travels onto the method read so the CALL
|
|
238
|
+
// can tick it if the member mutates (`emitCall`); the read itself renders
|
|
239
|
+
// nothing. Nothing is recorded HERE, because the origin travels through
|
|
240
|
+
// every get alike -- `reactive-dependencies.ts` carries it onto this
|
|
241
|
+
// result the same way it carries it onto a field read, and this rung
|
|
242
|
+
// restating it was a second authority that could only ever agree.
|
|
243
|
+
return '';
|
|
244
|
+
}
|
|
245
|
+
const stated = arrayMemberRefusals.get(staticKey);
|
|
246
|
+
if (stated !== undefined) {
|
|
247
|
+
throw createCppEmitBlockedError('property-access:array-object:get:false', `"${staticKey}" is an Array.prototype member this backend states no rendering for: ${stated}`);
|
|
248
|
+
}
|
|
249
|
+
if (arrayInheritedMemberRefusals.has(staticKey)) {
|
|
250
|
+
throw createCppEmitBlockedError('property-access:array-object:get:false', `"${staticKey}" is a name an Array INHERITS, not an own property, and this backend renders nothing for it off an array receiver -- ` +
|
|
251
|
+
'the dynamic-property sidecar below answers own properties only, so letting this key reach it would publish `undefined` for a ' +
|
|
252
|
+
'value the language reads off the prototype chain');
|
|
253
|
+
}
|
|
254
|
+
// Anything else is an ORDINARY own property of the Array object, and this
|
|
255
|
+
// function is not the authority on those. `gea::nativeDynamicGet` is: an
|
|
256
|
+
// ArrayObject participates in the identity-keyed expando table exactly as
|
|
257
|
+
// every other native object does, and `finalizeTemplateObject` writes
|
|
258
|
+
// GetTemplateObject's `raw` into that very table. Refusing here with "no
|
|
259
|
+
// property table is installed for one" was a second authority stating a
|
|
260
|
+
// premise the runtime contradicts, and it refused every tag declared
|
|
261
|
+
// `readonly string[]` -- the supertype spelling a tag is entitled to use
|
|
262
|
+
// (`test/runtime/template-strings-readonly-array.ts`), whose carrier
|
|
263
|
+
// therefore has no `raw` extension to read the property off statically.
|
|
264
|
+
// Returning `null` hands the key to `nativeSidecarGetText`, which asks
|
|
265
|
+
// that one authority. Nothing that compiles today moves: every key
|
|
266
|
+
// reaching this line is one emission refused outright a moment ago.
|
|
267
|
+
return null;
|
|
268
|
+
}
|
|
269
|
+
// A STRING key is what `for (const i in array)` binds -- `arrayOwnEnumerableKeys`
|
|
270
|
+
// publishes `std::to_string(index)` for every present element -- and hono's
|
|
271
|
+
// RegExp router indexes straight back with it (`handlerMap[i] =
|
|
272
|
+
// handlerData[indexReplacementMap[i]]`, the `in` loop over a sparse
|
|
273
|
+
// replacement map). CanonicalNumericIndexString is the whole conversion the
|
|
274
|
+
// language performs there, and `gea::detail::arrayIndexFromKeyText` is it; every
|
|
275
|
+
// read below this line is then the identical number-keyed access, absence
|
|
276
|
+
// rule included. A key that is not a canonical index answers exactly as a
|
|
277
|
+
// non-index NUMBER already does here rather than reaching the Array
|
|
278
|
+
// object's own ordinary properties, which no element access reads.
|
|
279
|
+
if (key.representation.kind === 'string') {
|
|
280
|
+
const indexText = `gea::detail::arrayIndexFromKeyText(${operandText(ctx, key)})`;
|
|
281
|
+
return (absentCapableElementText(ctx, receiverText, 'elementAt', indexText, receiver.representation.element, result) ??
|
|
282
|
+
reconciledElementText(ctx, receiver.representation.element, result, `${receiverText}->elementAt(${indexText})`));
|
|
283
|
+
}
|
|
284
|
+
if (key.representation.kind !== 'scalar') {
|
|
285
|
+
throw createCppEmitBlockedError('property-access:array-object:get:true', `an Array element access keyed by a "${key.representation.kind}" carrier needs a ToPropertyKey conversion, which is not installed`);
|
|
286
|
+
}
|
|
287
|
+
// An index the integer census narrowed goes straight in as an integer --
|
|
288
|
+
// see `ArrayObject::elementAtIndex` for why the double round trip is not
|
|
289
|
+
// merely redundant.
|
|
290
|
+
const reader = isIntegerStorageValue(ctx, key.value) ? 'elementAtIndex' : 'elementAt';
|
|
291
|
+
const keyText = operandText(ctx, key);
|
|
292
|
+
return (absentCapableElementText(ctx, receiverText, reader, keyText, receiver.representation.element, result) ??
|
|
293
|
+
reconciledElementText(ctx, receiver.representation.element, result, `${receiverText}->${reader}(${keyText})`));
|
|
294
|
+
};
|
|
295
|
+
/**
|
|
296
|
+
* The TypedArray reading of a property access, or `null` when the receiver
|
|
297
|
+
* is not a typed array.
|
|
298
|
+
*
|
|
299
|
+
* Unlike `array-object`, a typed array has no ordinary-property domain at
|
|
300
|
+
* all -- ECMA-262 23.2's integer-indexed exotic object answers every
|
|
301
|
+
* non-canonical-index key through the ordinary `[[Get]]` this carrier keeps
|
|
302
|
+
* no table for, so a constant key other than `length` or a canonical index
|
|
303
|
+
* is refused by name exactly the way `arrayAccessText` refuses one for an
|
|
304
|
+
* Array.
|
|
305
|
+
*/
|
|
306
|
+
/**
|
|
307
|
+
* Whether a typed-array member read is a deferred `%TypedArray%.prototype`
|
|
308
|
+
* method read. Stated once, asked by the renderer below and by the walk that
|
|
309
|
+
* settles `EmitContext.prototypeMethodReads`. The exclusions are the keys
|
|
310
|
+
* claimed first and therefore part of the same question: `length`, a canonical
|
|
311
|
+
* index, and the three block-shaped members `emit-buffers.ts` owns.
|
|
312
|
+
*/
|
|
313
|
+
export const deferredTypedArrayMethodClaim = (staticKeyTexts, receiver, key) => {
|
|
314
|
+
const carrier = receiver.representation;
|
|
315
|
+
if (carrier.kind !== 'typed-array')
|
|
316
|
+
return null;
|
|
317
|
+
const staticKey = staticKeyTexts.get(key.value);
|
|
318
|
+
if (staticKey === undefined || staticKey === 'length')
|
|
319
|
+
return null;
|
|
320
|
+
if (canonicalIndexLiteral(staticKey) !== null || typedArrayBufferMembers.has(staticKey))
|
|
321
|
+
return null;
|
|
322
|
+
if (!typedArrayPrototypeMethods.has(staticKey))
|
|
323
|
+
return null;
|
|
324
|
+
return {
|
|
325
|
+
receiverKind: 'typed-array',
|
|
326
|
+
member: staticKey,
|
|
327
|
+
receiver: { kind: 'operand', operand: receiver },
|
|
328
|
+
receiverElement: typedArrayElementSpelling(carrier)
|
|
329
|
+
};
|
|
330
|
+
};
|
|
331
|
+
export const typedArrayAccessText = (ctx, receiver, key, result) => {
|
|
332
|
+
if (receiver.representation.kind !== 'typed-array')
|
|
333
|
+
return null;
|
|
334
|
+
const receiverText = operandText(ctx, receiver);
|
|
335
|
+
const staticKey = ctx.staticKeyTexts.get(key.value);
|
|
336
|
+
if (staticKey === 'length')
|
|
337
|
+
return `${receiverText}->length()`;
|
|
338
|
+
if (staticKey !== undefined) {
|
|
339
|
+
const index = canonicalIndexLiteral(staticKey);
|
|
340
|
+
if (index !== null)
|
|
341
|
+
return absentCapableNumericElementText(receiverText, index, result) ?? `${receiverText}->elementAt(${index})`;
|
|
342
|
+
// The block-shaped half of the same carrier -- `buffer`/`byteLength`/
|
|
343
|
+
// `byteOffset` and the four range methods -- lives in `emit-buffers.ts`
|
|
344
|
+
// with `ArrayBuffer` and `DataView`, because what each of them is about is
|
|
345
|
+
// the underlying block rather than an element. See that file's header.
|
|
346
|
+
const bufferMember = typedArrayBufferMemberText(receiverText, receiver.representation, staticKey);
|
|
347
|
+
if (bufferMember !== null) {
|
|
348
|
+
// The member's own carrier is not always the one the READ publishes.
|
|
349
|
+
// `Uint8Array.prototype.buffer` is declared `ArrayBufferLike` -- a union
|
|
350
|
+
// of `ArrayBuffer` and `SharedArrayBuffer` -- while a view over a plain
|
|
351
|
+
// buffer hands back exactly one of them, so the store needs the arm
|
|
352
|
+
// injection that `gea::TaggedUnion` has no converting constructor for.
|
|
353
|
+
// @hono/node-server's `handleMessage` reads `data.buffer` off a
|
|
354
|
+
// `Uint8Array` into such a cell and clang refused the assignment.
|
|
355
|
+
//
|
|
356
|
+
// The union-arm reading of the same three members already aligns this
|
|
357
|
+
// way (`emit-union-properties.ts`), with the same source spelling; only
|
|
358
|
+
// the direct receiver handed its text over unaligned, which is the two
|
|
359
|
+
// -authorities shape rather than a missing recipe.
|
|
360
|
+
if (result === null)
|
|
361
|
+
return bufferMember;
|
|
362
|
+
const source = staticKey === 'buffer'
|
|
363
|
+
? { kind: receiver.representation.buffer, ownership: 'shared-refcount' }
|
|
364
|
+
: { kind: 'scalar', domain: 'number' };
|
|
365
|
+
const aligned = alignedValueText(ctx, 'emit-carrier-members.ts:411', source, result.representation, bufferMember);
|
|
366
|
+
if (aligned === null) {
|
|
367
|
+
throw createCppEmitBlockedError(`property-access:typed-array:get:false`, `a typed array's "${staticKey}" carries "${representationKey(source)}" while the read publishes ` +
|
|
368
|
+
`"${representationKey(result.representation)}", and no installed conversion reconciles them`);
|
|
369
|
+
}
|
|
370
|
+
return aligned;
|
|
371
|
+
}
|
|
372
|
+
if (deferredTypedArrayMethodClaim(ctx.staticKeyTexts, receiver, key) !== null) {
|
|
373
|
+
if (result === null) {
|
|
374
|
+
throw createCppEmitBlockedError('property-access:typed-array:get:false', `"${staticKey}" is a %TypedArray%.prototype method, and this access publishes no value for its call to consume`);
|
|
375
|
+
}
|
|
376
|
+
return '';
|
|
377
|
+
}
|
|
378
|
+
throw createCppEmitBlockedError('property-access:typed-array:get:false', `a typed array property "${staticKey}" is an ordinary property, and typed arrays have no ordinary-property table -- ` +
|
|
379
|
+
`only length, ${[...typedArrayBufferMembers].join(', ')} and ${[...typedArrayPrototypeMethods].join(', ')} are implemented`);
|
|
380
|
+
}
|
|
381
|
+
if (key.representation.kind !== 'scalar') {
|
|
382
|
+
throw createCppEmitBlockedError('property-access:typed-array:get:true', `a typed array element access keyed by a "${key.representation.kind}" carrier needs a ToPropertyKey conversion, which is not installed`);
|
|
383
|
+
}
|
|
384
|
+
const keyText = operandText(ctx, key);
|
|
385
|
+
return absentCapableNumericElementText(receiverText, keyText, result) ?? `${receiverText}->elementAt(${keyText})`;
|
|
386
|
+
};
|
|
387
|
+
/**
|
|
388
|
+
* `absentCapableElementText` for the typed-array reader.
|
|
389
|
+
*
|
|
390
|
+
* The same defect and the same cure, one carrier along: under
|
|
391
|
+
* `noUncheckedIndexedAccess` the checker types `view[i]` as `number |
|
|
392
|
+
* undefined`, and `TypedArray::elementAt` cannot answer that `undefined` --
|
|
393
|
+
* it aborts on an index outside the view. Left as the bare reader, this half
|
|
394
|
+
* is WORSE than the Array half was: `Optional<double>` converts implicitly
|
|
395
|
+
* from the `double` the reader returns, so the mismatch compiles, and the
|
|
396
|
+
* program aborts on a read JavaScript answers with a value.
|
|
397
|
+
*
|
|
398
|
+
* The payload is required to be a `scalar` rather than converted, because
|
|
399
|
+
* what `elementAt` produces is not a carrier this backend selected -- the
|
|
400
|
+
* reader's return type is `double` for all eight views, whatever the element
|
|
401
|
+
* domain is. Asking `convertedValueText` would mean inventing a source
|
|
402
|
+
* carrier to ask about; requiring the one payload that reader fits is the
|
|
403
|
+
* same fact stated where it is true.
|
|
404
|
+
*/
|
|
405
|
+
export const absentCapableNumericElementText = (receiverText, keyText, result) => {
|
|
406
|
+
const carrier = result?.representation;
|
|
407
|
+
if (carrier === undefined || carrier.kind !== 'optional' || carrier.absence !== 'undefined')
|
|
408
|
+
return null;
|
|
409
|
+
if (carrier.payload.kind !== 'scalar')
|
|
410
|
+
return null;
|
|
411
|
+
const optional = cppTypeOf(carrier);
|
|
412
|
+
return `(${receiverText}->hasElement(${keyText}) ? ${optional}(${receiverText}->elementAt(${keyText})) : ${optional}())`;
|
|
413
|
+
};
|
|
414
|
+
/**
|
|
415
|
+
* The String reading of a property access, or `null` when the receiver is not
|
|
416
|
+
* a `string`.
|
|
417
|
+
*
|
|
418
|
+
* `length` is the only own data property a JavaScript string has; everything
|
|
419
|
+
* else `String.prototype` exposes is a method, and a method reference is a
|
|
420
|
+
* `[[Get]]` too -- `s.slice(...)`'s callee is its own `property` operation,
|
|
421
|
+
* cited by the call the same way a class method's is. Rendering one as a
|
|
422
|
+
* value needs a receiver-carrying calling convention, and the checker's
|
|
423
|
+
* structural signature for an ambient interface method (as opposed to a class
|
|
424
|
+
* method body) carries no `this` parameter -- `structural.ts`'s
|
|
425
|
+
* `implicitReceiverOf` synthesizes one only for a class's own method, not for
|
|
426
|
+
* a `lib.es5.d.ts` interface member. Rendering the method anyway would emit a
|
|
427
|
+
* call that drops the receiver, exactly the mismatch `emit.ts`'s call
|
|
428
|
+
* emission already refuses by its own fail-closed guard.
|
|
429
|
+
*
|
|
430
|
+
* A key naming one of `stringPrototypeMethods` (see `emit-prototype-string.ts`,
|
|
431
|
+
* the one authority for which those are) is the one exception: instead of rendering the method here, the access
|
|
432
|
+
* defers -- it records which member was reached off which receiver and
|
|
433
|
+
* renders nothing, and the following call fuses receiver, method and
|
|
434
|
+
* arguments into one expression, sidestepping the missing-receiver problem
|
|
435
|
+
* entirely rather than solving it generically. Every other key is still
|
|
436
|
+
* refused by name instead of guessed at: the gap is the missing receiver
|
|
437
|
+
* upstream, not a rendering this file could supply for an unimplemented
|
|
438
|
+
* method.
|
|
439
|
+
*
|
|
440
|
+
* The one key that is neither `length` nor a method is a canonical INDEX --
|
|
441
|
+
* `s[i]`, ECMA-262 10.4.3's String exotic `[[Get]]`, which answers a
|
|
442
|
+
* single-code-unit string. See `stringIndexText`.
|
|
443
|
+
*/
|
|
444
|
+
export const isDeclaredStringPrototypeKey = (key) => stringPrototypeMethods.has(key) || stringMemberRefusals.has(key);
|
|
445
|
+
/**
|
|
446
|
+
* A symbol's own `description` -- `Symbol.prototype.description`, ECMA-262
|
|
447
|
+
* 20.4.3.2, an accessor whose value is `undefined` for `Symbol()` and the
|
|
448
|
+
* string given otherwise, which is exactly the `gea::Optional<std::string>`
|
|
449
|
+
* `gea::symbolDescription` answers and the `optional(string)` carrier the
|
|
450
|
+
* checker's `string | undefined` derives to. test262's `propertyHelper.js`
|
|
451
|
+
* reads it for every symbol-keyed `verifyProperty`. The other
|
|
452
|
+
* `Symbol.prototype` members (`toString`, `valueOf`, `[@@toPrimitive]`) are
|
|
453
|
+
* methods and refuse by name until an invocation asks for them.
|
|
454
|
+
*/
|
|
455
|
+
export const symbolMemberText = (ctx, receiver, key, result) => {
|
|
456
|
+
if (receiver.representation.kind !== 'symbol')
|
|
457
|
+
return null;
|
|
458
|
+
const staticKey = ctx.staticKeyTexts.get(key.value);
|
|
459
|
+
if (staticKey === 'description') {
|
|
460
|
+
const text = `gea::symbolDescription(${operandText(ctx, receiver)})`;
|
|
461
|
+
if (result === null)
|
|
462
|
+
return text;
|
|
463
|
+
const source = { kind: 'optional', payload: { kind: 'string' }, absence: 'undefined' };
|
|
464
|
+
const converted = alignedValueText(ctx, 'emit-carrier-members.ts:423', source, result.representation, text);
|
|
465
|
+
if (converted === null) {
|
|
466
|
+
throw createCppEmitBlockedError('property-access:symbol:get:false', `"description" is an optional string, and no conversion is installed into the "${representationKey(result.representation)}" this read publishes`);
|
|
467
|
+
}
|
|
468
|
+
return converted;
|
|
469
|
+
}
|
|
470
|
+
throw createCppEmitBlockedError(`property-access:symbol:get:${String(staticKey === undefined)}`, `"${staticKey ?? '<computed>'}" is not a member this backend renders on a symbol receiver; only "description" is`);
|
|
471
|
+
};
|
|
472
|
+
/**
|
|
473
|
+
* Whether a String member read is a deferred `String.prototype` method read.
|
|
474
|
+
* One statement of the test; `stringMemberText` and the prototype-read walk
|
|
475
|
+
* both ask it.
|
|
476
|
+
*/
|
|
477
|
+
export const deferredStringMethodClaim = (staticKeyTexts, receiver, key) => {
|
|
478
|
+
if (receiver.representation.kind !== 'string')
|
|
479
|
+
return null;
|
|
480
|
+
const staticKey = staticKeyTexts.get(key.value);
|
|
481
|
+
if (staticKey === undefined || staticKey === 'length')
|
|
482
|
+
return null;
|
|
483
|
+
if (!stringPrototypeMethods.has(staticKey))
|
|
484
|
+
return null;
|
|
485
|
+
return { receiverKind: 'string', member: staticKey, receiver: { kind: 'operand', operand: receiver }, receiverElement: null };
|
|
486
|
+
};
|
|
487
|
+
export const stringMemberText = (ctx, receiver, key, result) => {
|
|
488
|
+
if (receiver.representation.kind !== 'string')
|
|
489
|
+
return null;
|
|
490
|
+
const receiverText = operandText(ctx, receiver);
|
|
491
|
+
const staticKey = ctx.staticKeyTexts.get(key.value);
|
|
492
|
+
// A JavaScript String's `length` is its count of UTF-16 CODE UNITS
|
|
493
|
+
// (ECMA-262 6.1.4 / 22.1.4.1), which is not its byte count once anything
|
|
494
|
+
// outside ASCII appears. This backend stores a string as UTF-8, so the two
|
|
495
|
+
// index spaces differ and the spec's is the one that wins -- the same answer
|
|
496
|
+
// v1 gives (`ir/emission/cpp/passes/properties/access.ts`, which spells this
|
|
497
|
+
// read as `gea_cpp_string_utf16_length` for exactly this receiver).
|
|
498
|
+
//
|
|
499
|
+
// `gea::runtime::string::utf16Length` is v1's own function, ported with its
|
|
500
|
+
// memo: this read sits inside `for (i...) s.charCodeAt(i)` loops, so an
|
|
501
|
+
// unmemoized scan here is what makes such a loop quadratic.
|
|
502
|
+
if (staticKey === 'length')
|
|
503
|
+
return `static_cast<double>(gea::runtime::string::utf16Length(${receiverText}))`;
|
|
504
|
+
if (staticKey !== undefined) {
|
|
505
|
+
if (deferredStringMethodClaim(ctx.staticKeyTexts, receiver, key) !== null) {
|
|
506
|
+
if (result === null) {
|
|
507
|
+
throw createCppEmitBlockedError('property-access:string:get:false', `"${staticKey}" is a String.prototype method, and this access publishes no value for its call to consume`);
|
|
508
|
+
}
|
|
509
|
+
return '';
|
|
510
|
+
}
|
|
511
|
+
// A constant key that spells a canonical index is an element access
|
|
512
|
+
// exactly as a computed one is, just with the index known here --
|
|
513
|
+
// the same carve-out `arrayAccessText` makes above, and for the same
|
|
514
|
+
// reason: `s[0]` and `s["0"]` reach this file as one constant text,
|
|
515
|
+
// because `ToPropertyKey` already turned the number into a String.
|
|
516
|
+
const index = canonicalIndexLiteral(staticKey);
|
|
517
|
+
if (index !== null)
|
|
518
|
+
return stringIndexText(receiverText, index, result, staticKey);
|
|
519
|
+
const stated = stringMemberRefusals.get(staticKey);
|
|
520
|
+
throw createCppEmitBlockedError('property-access:string:get:false', stated !== undefined
|
|
521
|
+
? `"${staticKey}" is a String.prototype member this backend states no rendering for: ${stated}`
|
|
522
|
+
: `"${staticKey}" is a String.prototype method, not a data property; calling it needs a receiver-carrying calling ` +
|
|
523
|
+
'convention this program did not derive one for, and reading it as a value has no native implementation installed -- ' +
|
|
524
|
+
`only ${[...stringPrototypeMethods].join(', ')} ${stringPrototypeMethods.size === 1 ? 'is' : 'are'} implemented`);
|
|
525
|
+
}
|
|
526
|
+
// A genuinely computed key. On a string there is exactly one thing it can
|
|
527
|
+
// be: an index. `ToPropertyKey` of a number is its String, and no
|
|
528
|
+
// `String.prototype` member has a name a number spells, so a computed key
|
|
529
|
+
// that is a `scalar` reaches the exotic `[[Get]]` and nothing else. A key
|
|
530
|
+
// carried as anything but a scalar would need the ToPropertyKey conversion
|
|
531
|
+
// this backend has not installed, and stays refused by name.
|
|
532
|
+
if (key.representation.kind !== 'scalar') {
|
|
533
|
+
throw createCppEmitBlockedError('property-access:string:get:true', `a String property access keyed by a "${key.representation.kind}" carrier needs a ToPropertyKey conversion, which is not installed`);
|
|
534
|
+
}
|
|
535
|
+
return stringIndexText(receiverText, operandText(ctx, key), result, null);
|
|
536
|
+
};
|
|
537
|
+
/**
|
|
538
|
+
* `s[i]` -- ECMA-262 10.4.3's String exotic `[[Get]]`.
|
|
539
|
+
*
|
|
540
|
+
* The result is a one-code-unit string, and the unit is
|
|
541
|
+
* `gea::runtime::string::charAt`'s: this backend stores a string as UTF-8 and
|
|
542
|
+
* the spec indexes it in UTF-16 code units, so `charAt` -- which already owns
|
|
543
|
+
* that projection (`substringUtf16` over `utf16Length`) -- is where the index
|
|
544
|
+
* space is decided, rather than restated here where the two could disagree.
|
|
545
|
+
*
|
|
546
|
+
* ## Out of range, and the carrier
|
|
547
|
+
*
|
|
548
|
+
* The spec's answer for an out-of-range or non-integer index is `undefined`,
|
|
549
|
+
* and `charAt`'s is the empty string. That divergence is not observable
|
|
550
|
+
* through the type the checker gives this read: `lib.es5.d.ts` declares
|
|
551
|
+
* `String`'s index signature `readonly [index: number]: string`, so the result
|
|
552
|
+
* carrier is `string`, there is no `undefined` in it to produce, and a program
|
|
553
|
+
* that compares the result against `undefined` is refused by the checker
|
|
554
|
+
* before this emitter is reached ("types 'string' and 'undefined' have no
|
|
555
|
+
* overlap"). `arrayAccessText`'s `elementAt` answers an out-of-range Array
|
|
556
|
+
* index the same way and for the same reason -- the checker types `a[i]` as
|
|
557
|
+
* `T`, not `T | undefined` -- so this is the backend's existing convention,
|
|
558
|
+
* not a new one taken here.
|
|
559
|
+
*
|
|
560
|
+
* A program compiled with `noUncheckedIndexedAccess` is the case where the
|
|
561
|
+
* difference IS in the type: the checker then says `string | undefined`, the
|
|
562
|
+
* carrier is absence-capable, and a bare `std::string` would be the wrong
|
|
563
|
+
* one. That is refused by name rather than rendered, because producing the
|
|
564
|
+
* absence needs a materialization this function is not the place to decide.
|
|
565
|
+
*
|
|
566
|
+
* The integer guard on the computed path is this access's own rule and not
|
|
567
|
+
* `charAt`'s: `charAt(1.5)` truncates to 1 and answers a real code unit,
|
|
568
|
+
* while `s[1.5]` reads the ordinary property `"1.5"`, which a string does not
|
|
569
|
+
* have. Under a `string` carrier the honest answer for it is the same empty
|
|
570
|
+
* string every other out-of-range index gets. A constant index has already
|
|
571
|
+
* been proved canonical by `canonicalIndexLiteral`, so it needs no guard at
|
|
572
|
+
* all.
|
|
573
|
+
*/
|
|
574
|
+
export const stringIndexText = (receiverText, indexText, result, staticKey) => {
|
|
575
|
+
// `noUncheckedIndexedAccess` types this read `string | undefined`: the
|
|
576
|
+
// checker's own admission the index may be out of range. `charAtOrAbsent`
|
|
577
|
+
// (gea_runtime.h) is the exact materialization -- see its own comment for
|
|
578
|
+
// why `charAt`'s empty-string-means-out-of-range convention loses nothing
|
|
579
|
+
// by becoming `Optional<std::string>()`.
|
|
580
|
+
const isOptionalString = (representation) => representation.kind === 'optional' && representation.absence === 'undefined' && representation.payload.kind === 'string';
|
|
581
|
+
const wantsAbsence = result !== null && isOptionalString(result.representation);
|
|
582
|
+
if (result !== null && result.representation.kind !== 'string' && !wantsAbsence) {
|
|
583
|
+
throw createCppEmitBlockedError(`property-access:string:get:${String(staticKey === null)}`, `a String index read${staticKey === null ? '' : ` ("${staticKey}")`} whose result is carried as ` +
|
|
584
|
+
`"${result.representation.kind}" rather than "string" needs an absence materialization this backend has not installed ` +
|
|
585
|
+
'-- the shape `noUncheckedIndexedAccess` gives every indexed read');
|
|
586
|
+
}
|
|
587
|
+
const charAtSpelling = wantsAbsence ? 'charAtOrAbsent' : 'charAt';
|
|
588
|
+
if (staticKey !== null)
|
|
589
|
+
return `gea::runtime::string::${charAtSpelling}(${receiverText}, ${indexText})`;
|
|
590
|
+
const emptyResult = wantsAbsence ? 'gea::Optional<std::string>()' : 'std::string()';
|
|
591
|
+
const returnType = wantsAbsence ? 'gea::Optional<std::string>' : 'std::string';
|
|
592
|
+
return (`([&]() -> ${returnType} { const double gea_index = ${indexText}; ` +
|
|
593
|
+
`if (!std::isfinite(gea_index) || gea_index < 0.0 || std::floor(gea_index) != gea_index) return ${emptyResult}; ` +
|
|
594
|
+
`return gea::runtime::string::${charAtSpelling}(${receiverText}, gea_index); })()`);
|
|
595
|
+
};
|
|
596
|
+
/**
|
|
597
|
+
* The scalar reading of a property access, or `null` when the receiver is not
|
|
598
|
+
* a `scalar`.
|
|
599
|
+
*
|
|
600
|
+
* A `scalar` (`number`, `boolean`, `bigint`, ...) has no own data property at
|
|
601
|
+
* all: `Number.prototype`/`Boolean.prototype` expose only methods (`toFixed`,
|
|
602
|
+
* `toString`, `valueOf`, ...), never a stored field the way String's `length`
|
|
603
|
+
* is. So this is `stringMemberText`'s non-`length` branch with nothing left
|
|
604
|
+
* over to carve out first -- and it defers on the same terms: a key naming one
|
|
605
|
+
* of `numberPrototypeMethods` records the read and renders nothing, so the
|
|
606
|
+
* call that follows fuses receiver, method and arguments into one expression.
|
|
607
|
+
* Every other key is a method reference refused for the identical reason the
|
|
608
|
+
* String path refuses one: the checker's structural signature for a
|
|
609
|
+
* `lib.es5.d.ts` interface method carries no `this` parameter, so there is no
|
|
610
|
+
* receiver a rendered call could close over.
|
|
611
|
+
*/
|
|
612
|
+
/**
|
|
613
|
+
* A `promise` receiver's members.
|
|
614
|
+
*
|
|
615
|
+
* A promise has no data property at all: `then`/`catch`/`finally` are
|
|
616
|
+
* `Promise.prototype` methods, and the checker's structural signature for one
|
|
617
|
+
* carries no `this` parameter -- the same missing-receiver reason
|
|
618
|
+
* `stringMemberText` and `scalarMemberText` state. So `then` defers and fuses
|
|
619
|
+
* with its call, and every other member is refused by name.
|
|
620
|
+
*
|
|
621
|
+
* `finally` is deliberately not deferred. 27.2.5.3 runs its callback on BOTH
|
|
622
|
+
* settlements and then re-raises the original one -- a fulfilled promise's
|
|
623
|
+
* value passes through and a rejected promise's rejection is re-thrown after
|
|
624
|
+
* the callback -- which is a rendering this backend does not have. `catch`
|
|
625
|
+
* does: `gea::Promise` carries a rejection (an `exception_ptr`, see the
|
|
626
|
+
* carrier's own comment) and `promiseCatchText` renders the handler over it.
|
|
627
|
+
*/
|
|
628
|
+
/** Whether a Promise member read is a deferred `Promise.prototype` method read. Stated once; the renderer and the walk both ask it. */
|
|
629
|
+
export const deferredPromiseMethodClaim = (staticKeyTexts, receiver, key) => {
|
|
630
|
+
const carrier = receiver.representation;
|
|
631
|
+
if (carrier.kind !== 'promise')
|
|
632
|
+
return null;
|
|
633
|
+
const staticKey = staticKeyTexts.get(key.value);
|
|
634
|
+
if (staticKey === undefined || !promisePrototypeMethods.has(staticKey))
|
|
635
|
+
return null;
|
|
636
|
+
return {
|
|
637
|
+
receiverKind: 'promise',
|
|
638
|
+
member: staticKey,
|
|
639
|
+
receiver: { kind: 'operand', operand: receiver },
|
|
640
|
+
receiverElement: null,
|
|
641
|
+
promiseCarrier: carrier
|
|
642
|
+
};
|
|
643
|
+
};
|
|
644
|
+
export const promiseMemberText = (ctx, receiver, key, result) => {
|
|
645
|
+
if (receiver.representation.kind !== 'promise')
|
|
646
|
+
return null;
|
|
647
|
+
const staticKey = ctx.staticKeyTexts.get(key.value);
|
|
648
|
+
if (staticKey === undefined) {
|
|
649
|
+
throw createCppEmitBlockedError('property-access:promise:get:true', 'a promise property access keyed by a non-constant key has no ToPropertyKey or native member table installed');
|
|
650
|
+
}
|
|
651
|
+
if (deferredPromiseMethodClaim(ctx.staticKeyTexts, receiver, key) !== null) {
|
|
652
|
+
if (result === null) {
|
|
653
|
+
throw createCppEmitBlockedError('property-access:promise:get:false', `"${staticKey}" is a Promise.prototype method, and this access publishes no value for its call to consume`);
|
|
654
|
+
}
|
|
655
|
+
return '';
|
|
656
|
+
}
|
|
657
|
+
throw createCppEmitBlockedError('property-access:promise:get:false', `"${staticKey}" is a Promise.prototype member this backend states no rendering for -- only ${[...promisePrototypeMethods].join(', ')} ` +
|
|
658
|
+
'is implemented');
|
|
659
|
+
};
|
|
660
|
+
/**
|
|
661
|
+
* An `iterator` receiver's members -- a generator value or one of the four
|
|
662
|
+
* fixed-storage cursor sources, all carried as `gea::Iterator<T, TReturn,
|
|
663
|
+
* TNext>` (`representation/model.ts`'s `iterator` kind) -- of which `next`,
|
|
664
|
+
* `return` and `throw` are the ones this backend renders.
|
|
665
|
+
*
|
|
666
|
+
* Deferred and fused with its call exactly as a Promise member is, and for
|
|
667
|
+
* the same reason `stringMemberText` states: the ambient `Generator`
|
|
668
|
+
* interface method has no `this` parameter, so there is no receiver-carrying
|
|
669
|
+
* calling convention a first-class value could be built from. The claimed
|
|
670
|
+
* member set is `iteratorPrototypeMethods`'s (`emit-prototype-iterator.ts`),
|
|
671
|
+
* one authority with the renderer -- and `manifest/capabilities.ts` claims
|
|
672
|
+
* the same members by name (`iterator(next):get:false`, and its `return`/
|
|
673
|
+
* `throw` siblings), so a member that reaches here unclaimed is a preflight
|
|
674
|
+
* defect, reported as one. `iteratorCallText` refines `return`/`throw`
|
|
675
|
+
* further, by the receiver's own `source` tag, to the one carrier
|
|
676
|
+
* (`'generator'`) whose real prototype defines them at all.
|
|
677
|
+
*/
|
|
678
|
+
/** Whether an iterator member read is a deferred `%GeneratorPrototype%` method read. Stated once; the renderer and the walk both ask it. */
|
|
679
|
+
export const deferredIteratorMethodClaim = (staticKeyTexts, receiver, key) => {
|
|
680
|
+
const carrier = receiver.representation;
|
|
681
|
+
if (carrier.kind !== 'iterator')
|
|
682
|
+
return null;
|
|
683
|
+
const staticKey = staticKeyTexts.get(key.value);
|
|
684
|
+
if (staticKey === undefined || !iteratorPrototypeMethods.has(staticKey))
|
|
685
|
+
return null;
|
|
686
|
+
return {
|
|
687
|
+
receiverKind: 'iterator',
|
|
688
|
+
member: staticKey,
|
|
689
|
+
receiver: { kind: 'operand', operand: receiver },
|
|
690
|
+
receiverElement: representationKey(carrier.element),
|
|
691
|
+
iteratorCarrier: carrier
|
|
692
|
+
};
|
|
693
|
+
};
|
|
694
|
+
export const iteratorMemberText = (ctx, receiver, key, result) => {
|
|
695
|
+
const carrier = receiver.representation;
|
|
696
|
+
if (carrier.kind !== 'iterator')
|
|
697
|
+
return null;
|
|
698
|
+
const staticKey = ctx.staticKeyTexts.get(key.value);
|
|
699
|
+
if (staticKey === undefined) {
|
|
700
|
+
throw createCppEmitBlockedError('property-access:iterator:get:true', 'an iterator property access keyed by a non-constant key has no ToPropertyKey or native member table installed');
|
|
701
|
+
}
|
|
702
|
+
if (deferredIteratorMethodClaim(ctx.staticKeyTexts, receiver, key) !== null) {
|
|
703
|
+
if (result === null) {
|
|
704
|
+
throw createCppEmitBlockedError('property-access:iterator:get:false', `"${staticKey}" is a %GeneratorPrototype% method, and this access publishes no value for its call to consume`);
|
|
705
|
+
}
|
|
706
|
+
return '';
|
|
707
|
+
}
|
|
708
|
+
throw createCppEmitBlockedError('property-access:iterator:get:false', `"${staticKey}" is a %GeneratorPrototype% member this backend states no rendering for -- only ${[...iteratorPrototypeMethods].join(', ')} is implemented`);
|
|
709
|
+
};
|
|
710
|
+
/**
|
|
711
|
+
* A `keyed-collection` receiver's members -- `Map`/`Set`/`WeakMap`/`WeakSet`.
|
|
712
|
+
*
|
|
713
|
+
* `size` is the one member that renders here and now: it is an accessor over
|
|
714
|
+
* the collection's own storage (ECMA-262 23.1.3.14 / 24.2.3.9), not a method,
|
|
715
|
+
* so there is no call to fuse with. Every claimed METHOD defers and fuses with
|
|
716
|
+
* its call exactly as `substring` does off a string, for the identical reason
|
|
717
|
+
* `stringMemberText` states: the checker gives an ambient interface method no
|
|
718
|
+
* `this` parameter, so a materialized method value would have nowhere to carry
|
|
719
|
+
* the receiver.
|
|
720
|
+
*
|
|
721
|
+
* Which methods are claimed is `keyedCollectionMethods`'s answer, per family
|
|
722
|
+
* (`emit-prototype-invoke.ts`) -- one authority, so a member that defers here
|
|
723
|
+
* is always a member that renders there. `size` is deliberately absent from
|
|
724
|
+
* the weak families: ECMA-262 gives a WeakMap/WeakSet no `size`, no `clear`
|
|
725
|
+
* and no iteration at all, because none of it is observable when entries may
|
|
726
|
+
* be collected.
|
|
727
|
+
*/
|
|
728
|
+
/**
|
|
729
|
+
* Whether a `keyed-collection`'s `size` is the DATA property 23.1.3.14 and
|
|
730
|
+
* 24.2.3.9 declare -- true for `Map`/`Set`, false for the weak pair, which
|
|
731
|
+
* has no `size` at all.
|
|
732
|
+
*
|
|
733
|
+
* The two callers below have to disagree about `size` in exactly opposite
|
|
734
|
+
* directions: the claim must EXCLUDE it, because a data property is not a
|
|
735
|
+
* deferred method read, and the renderer must SPELL it. They said so in two
|
|
736
|
+
* separately-written boolean expressions over the same two facts, which is
|
|
737
|
+
* the two-authorities defect at its smallest -- if either side ever learned
|
|
738
|
+
* about a third strong family, or `WeakMap` ever grew a `size`, only one of
|
|
739
|
+
* them would learn it, and a `.size` read would silently become a refusal or
|
|
740
|
+
* a method reference.
|
|
741
|
+
*/
|
|
742
|
+
const keyedCollectionSizeIsDataProperty = (carrier, staticKey) => staticKey === 'size' && (carrier.family === 'map' || carrier.family === 'set');
|
|
743
|
+
/** Whether a Map/Set/WeakMap/WeakSet member read is a deferred prototype method read. Stated once; the renderer and the walk both ask it. */
|
|
744
|
+
export const deferredKeyedCollectionMethodClaim = (staticKeyTexts, receiver, key) => {
|
|
745
|
+
const carrier = receiver.representation;
|
|
746
|
+
if (carrier.kind !== 'keyed-collection')
|
|
747
|
+
return null;
|
|
748
|
+
const staticKey = staticKeyTexts.get(key.value);
|
|
749
|
+
if (staticKey === undefined)
|
|
750
|
+
return null;
|
|
751
|
+
if (keyedCollectionSizeIsDataProperty(carrier, staticKey))
|
|
752
|
+
return null;
|
|
753
|
+
if (!keyedCollectionPrototypeMethods(carrier.family).has(staticKey))
|
|
754
|
+
return null;
|
|
755
|
+
return {
|
|
756
|
+
receiverKind: 'keyed-collection',
|
|
757
|
+
member: staticKey,
|
|
758
|
+
receiver: { kind: 'operand', operand: receiver },
|
|
759
|
+
receiverElement: representationKey(carrier.key),
|
|
760
|
+
collectionFamily: carrier.family,
|
|
761
|
+
collectionCarrier: carrier
|
|
762
|
+
};
|
|
763
|
+
};
|
|
764
|
+
export const keyedCollectionMemberText = (ctx, receiver, key, result) => {
|
|
765
|
+
const carrier = receiver.representation;
|
|
766
|
+
if (carrier.kind !== 'keyed-collection')
|
|
767
|
+
return null;
|
|
768
|
+
const staticKey = ctx.staticKeyTexts.get(key.value);
|
|
769
|
+
if (staticKey === undefined) {
|
|
770
|
+
throw createCppEmitBlockedError('property-access:keyed-collection:get:true', `a ${carrier.family} property access keyed by a non-constant key has no ToPropertyKey or native member table installed`);
|
|
771
|
+
}
|
|
772
|
+
const strong = carrier.family === 'map' || carrier.family === 'set';
|
|
773
|
+
if (keyedCollectionSizeIsDataProperty(carrier, staticKey)) {
|
|
774
|
+
return `${operandText(ctx, receiver)}${memberAccessOperator(carrier.ownership)}size()`;
|
|
775
|
+
}
|
|
776
|
+
if (deferredKeyedCollectionMethodClaim(ctx.staticKeyTexts, receiver, key) !== null) {
|
|
777
|
+
if (result === null) {
|
|
778
|
+
throw createCppEmitBlockedError('property-access:keyed-collection:get:false', `"${staticKey}" is a ${carrier.family} prototype method, and this access publishes no value for its call to consume`);
|
|
779
|
+
}
|
|
780
|
+
return '';
|
|
781
|
+
}
|
|
782
|
+
throw createCppEmitBlockedError('property-access:keyed-collection:get:false', `"${staticKey}" is a ${carrier.family} member this backend states no rendering for -- only ` +
|
|
783
|
+
`${[...(strong ? ['size'] : []), ...keyedCollectionPrototypeMethods(carrier.family)].join(', ')} ` +
|
|
784
|
+
`${keyedCollectionPrototypeMethods(carrier.family).size === 0 ? 'is' : 'are'} implemented`);
|
|
785
|
+
};
|
|
786
|
+
/**
|
|
787
|
+
* `shared-refcount` is a `shared_ptr` and needs `->`; `owned`/`borrowed` are the
|
|
788
|
+
* struct itself (or a reference to it) and use `.`.
|
|
789
|
+
*
|
|
790
|
+
* Lives here rather than in `emit-properties.ts`, where every call site of it
|
|
791
|
+
* is, because `recordIndexSidecarTableOf` below needs it too and this file
|
|
792
|
+
* cannot import back from that one (`emit-properties.ts` already imports the
|
|
793
|
+
* carrier renderers *from* here; the dependency only runs one way). A single
|
|
794
|
+
* mechanical helper crossing that line is cheaper than reversing it.
|
|
795
|
+
*/
|
|
796
|
+
export const memberAccessOperator = (ownership) => (ownership === 'shared-refcount' ? '->' : '.');
|
|
797
|
+
/**
|
|
798
|
+
* The companion revision cell a reactive origin ticks, spelled.
|
|
799
|
+
*
|
|
800
|
+
* The fact (`ReactiveRevisionOrigin`) names the owning OPERAND and the field;
|
|
801
|
+
* the C++ name of that operand exists only once its defining operation has
|
|
802
|
+
* rendered, which is why the spelling is taken here, at the store that ticks
|
|
803
|
+
* it, and not at the read that recorded the origin.
|
|
804
|
+
*/
|
|
805
|
+
export const reactiveRevisionText = (ctx, origin) => {
|
|
806
|
+
const carrier = origin.receiver.representation;
|
|
807
|
+
// A carrier with no ownership of its own is a value, and `.` reaches its
|
|
808
|
+
// member -- the same default `memberAccessOperator` gives everything that is
|
|
809
|
+
// not a shared reference.
|
|
810
|
+
const ownership = 'ownership' in carrier ? carrier.ownership : 'owned';
|
|
811
|
+
return `${operandText(ctx, origin.receiver)}${memberAccessOperator(ownership)}${cppReactiveRevisionFieldName(origin.key)}`;
|
|
812
|
+
};
|
|
813
|
+
/**
|
|
814
|
+
* One key, spelled in the domain the keyed container is actually keyed by --
|
|
815
|
+
* for a struct's index sidecar and for a bare `dictionary` receiver alike.
|
|
816
|
+
*
|
|
817
|
+
* A property key is a string in the source language: `a[0]` and `{ [N]: v }`
|
|
818
|
+
* with `const N = 2` both publish the constant `"0"`/`"2"`, while
|
|
819
|
+
* `gea::NumericDictionary` is keyed by `double`. The two have to be reconciled
|
|
820
|
+
* or the emitted subscript does not compile. This is the identical rule
|
|
821
|
+
* `emit-allocation.ts`'s `emitAllocateDictionary` already applies to the fields
|
|
822
|
+
* an allocation installs, lifted to one function so an allocation, a later
|
|
823
|
+
* store and a read cannot end up with three opinions about how a key is
|
|
824
|
+
* spelled.
|
|
825
|
+
*
|
|
826
|
+
* A key whose own carrier already matches the container's domain passes through
|
|
827
|
+
* untouched -- `strings[i]` with a `double` index is already a `double`. Only a
|
|
828
|
+
* cross-domain key needs the language conversion. A number used against a
|
|
829
|
+
* string-keyed sidecar is ordinary `ToPropertyKey`, so it goes through the
|
|
830
|
+
* backend's exact Number::toString renderer. A string used against a
|
|
831
|
+
* number-keyed sidecar only passes when it is constant and canonicalizable;
|
|
832
|
+
* converting an arbitrary runtime string would make `a["01"]` and `a[1]`
|
|
833
|
+
* name the same slot.
|
|
834
|
+
*/
|
|
835
|
+
/**
|
|
836
|
+
* An `Object.prototype` method reached through a `dictionary` receiver:
|
|
837
|
+
* recorded as a deferred prototype read and rendered at the call, exactly as a
|
|
838
|
+
* String or Date member is.
|
|
839
|
+
*
|
|
840
|
+
* Answering `true` means the access produced no C++ of its own and the caller
|
|
841
|
+
* must return -- the read's value is materialized by
|
|
842
|
+
* `prototypeMethodCallText`, which fuses receiver and call into one
|
|
843
|
+
* expression. `false` means this is not one, and every remaining path is
|
|
844
|
+
* unchanged.
|
|
845
|
+
*
|
|
846
|
+
* Only a CONSTANT key is claimed. `bag[k]` with a runtime `k` really is an
|
|
847
|
+
* index read even when `k` happens to spell `"hasOwnProperty"` at runtime,
|
|
848
|
+
* and the checker types it as the index's own value; claiming it here would
|
|
849
|
+
* be this file disagreeing with the carrier the rest of the program agreed
|
|
850
|
+
* on.
|
|
851
|
+
*/
|
|
852
|
+
/**
|
|
853
|
+
* Whether a dictionary member read is a deferred `Object.prototype` method
|
|
854
|
+
* read. Stated once; the renderer and the walk both ask it. Only a CONSTANT
|
|
855
|
+
* key is claimed -- `bag[k]` with a runtime `k` is an index read even when `k`
|
|
856
|
+
* happens to spell `"hasOwnProperty"`.
|
|
857
|
+
*/
|
|
858
|
+
export const deferredDictionaryMethodClaim = (staticKeyTexts, receiver, key) => {
|
|
859
|
+
const carrier = receiver.representation;
|
|
860
|
+
if (carrier.kind !== 'dictionary')
|
|
861
|
+
return null;
|
|
862
|
+
const staticKey = staticKeyTexts.get(key.value);
|
|
863
|
+
if (staticKey === undefined || !dictionaryPrototypeMethods.has(staticKey))
|
|
864
|
+
return null;
|
|
865
|
+
return {
|
|
866
|
+
receiverKind: 'dictionary',
|
|
867
|
+
member: staticKey,
|
|
868
|
+
receiver: { kind: 'operand', operand: receiver },
|
|
869
|
+
receiverElement: null,
|
|
870
|
+
dictionaryTable: { accessor: memberAccessOperator(carrier.ownership), key: carrier.key }
|
|
871
|
+
};
|
|
872
|
+
};
|
|
873
|
+
export const dictionaryPrototypeMemberRead = (ctx, operation) => {
|
|
874
|
+
if (deferredDictionaryMethodClaim(ctx.staticKeyTexts, operation.receiver, operation.key) === null)
|
|
875
|
+
return false;
|
|
876
|
+
// `dictionaryTableOf` is not asked for the member spelling here: it also
|
|
877
|
+
// reconciles the KEY, and this key is a method name rather than an entry --
|
|
878
|
+
// against a number-keyed table that reconciliation would (rightly) refuse
|
|
879
|
+
// `"hasOwnProperty"` as not spelling a numeric key. Only the accessor half
|
|
880
|
+
// is wanted, and it is the same `memberAccessOperator` that function uses.
|
|
881
|
+
return true;
|
|
882
|
+
};
|
|
883
|
+
export const keyedTableKeyText = (ctx, key, domain) => {
|
|
884
|
+
const text = operandText(ctx, key);
|
|
885
|
+
const carrier = key.representation;
|
|
886
|
+
const matches = domain === 'number'
|
|
887
|
+
? carrier.kind === 'scalar' && carrier.domain === 'number'
|
|
888
|
+
: domain === 'symbol'
|
|
889
|
+
? carrier.kind === 'symbol'
|
|
890
|
+
: carrier.kind === 'string';
|
|
891
|
+
if (matches)
|
|
892
|
+
return text;
|
|
893
|
+
if (domain === 'string' && carrier.kind === 'scalar' && carrier.domain === 'number') {
|
|
894
|
+
const converted = toStringText(text, carrier, ctx.classes, ctx.deriver);
|
|
895
|
+
if (converted !== null)
|
|
896
|
+
return converted;
|
|
897
|
+
}
|
|
898
|
+
if (domain === 'string' &&
|
|
899
|
+
carrier.kind === 'tagged-union' &&
|
|
900
|
+
carrier.arms.every((arm) => arm.value.kind === 'string' || (arm.value.kind === 'scalar' && arm.value.domain === 'number'))) {
|
|
901
|
+
const arms = carrier.arms.map((arm, index) => {
|
|
902
|
+
const value = `${text}.get<${index}>()`;
|
|
903
|
+
if (arm.value.kind === 'string')
|
|
904
|
+
return value;
|
|
905
|
+
const converted = toStringText(value, arm.value, ctx.classes, ctx.deriver);
|
|
906
|
+
if (converted === null) {
|
|
907
|
+
throw createCppEmitBlockedError(`runtime-helper:computation:to-property-key:${representationKey(arm.value)}`, `a string-keyed index sidecar cannot convert the numeric arm "${representationKey(arm.value)}" to a property key`);
|
|
908
|
+
}
|
|
909
|
+
return converted;
|
|
910
|
+
});
|
|
911
|
+
const dispatched = arms.reduceRight((rest, arm, index) => (index === arms.length - 1 ? arm : `${text}.is<${index}>() ? ${arm} : (${rest})`), '');
|
|
912
|
+
return arms.length > 1 ? `(${dispatched})` : dispatched;
|
|
913
|
+
}
|
|
914
|
+
// A string index signature is reached through ToPropertyKey just like an
|
|
915
|
+
// ordinary object property. `toStringText` is exact for every non-Symbol
|
|
916
|
+
// primitive carrier, including an optional/tagged union's nullish arms and
|
|
917
|
+
// a genuinely dynamic box's primitive tags. Its boxed Symbol/Object cases
|
|
918
|
+
// abort by name instead of fabricating a string slot this sidecar cannot
|
|
919
|
+
// represent.
|
|
920
|
+
if (domain === 'string') {
|
|
921
|
+
const converted = toStringText(text, carrier, ctx.classes, ctx.deriver);
|
|
922
|
+
if (converted !== null)
|
|
923
|
+
return converted;
|
|
924
|
+
}
|
|
925
|
+
if (domain === 'symbol') {
|
|
926
|
+
throw createCppEmitBlockedError('runtime-helper:computation:to-property-key:symbol', `a symbol-keyed index sidecar is subscripted with a "${representationKey(carrier)}" key; symbols are identity values and cannot be ` +
|
|
927
|
+
'recovered from a string or numeric property-key spelling');
|
|
928
|
+
}
|
|
929
|
+
const staticKey = ctx.staticKeyTexts.get(key.value);
|
|
930
|
+
if (staticKey === undefined) {
|
|
931
|
+
throw createCppEmitBlockedError(`runtime-helper:computation:to-property-key:${domain}`, `a ${domain}-keyed index sidecar is subscripted with a "${representationKey(carrier)}" key that is not a compile-time constant; ` +
|
|
932
|
+
'converting one domain to the other at runtime is a ToPropertyKey conversion this subscript does not perform');
|
|
933
|
+
}
|
|
934
|
+
if (domain === 'string')
|
|
935
|
+
return cppStringLiteral(staticKey);
|
|
936
|
+
if (!isCanonicalNumberPropertyKeyText(staticKey)) {
|
|
937
|
+
throw createCppEmitBlockedError('runtime-helper:computation:to-property-key:number', `a number-keyed index sidecar is subscripted with "${staticKey}", which does not spell a numeric key`);
|
|
938
|
+
}
|
|
939
|
+
return cppStringLiteral(staticKey);
|
|
940
|
+
};
|
|
941
|
+
/**
|
|
942
|
+
* The dynamic-property sidecar behind a `record-with-index`/`native-record-ref`
|
|
943
|
+
* receiver, in both spellings a use of it needs -- the identical shape a bare
|
|
944
|
+
* `dictionary` carrier's own table function returns (`emit-properties.ts`'s
|
|
945
|
+
* `dictionaryTableOf`), aimed one member deeper at the struct's `gea_dynamic`
|
|
946
|
+
* field instead of at the receiver itself.
|
|
947
|
+
*
|
|
948
|
+
* `record-with-index` carries its `indexes` inline (model.ts); a
|
|
949
|
+
* `native-record-ref` only names a shape, so its sidecar (if it has one) is
|
|
950
|
+
* resolved through `records.ts`'s `recordIndexesOfShape` -- the identical
|
|
951
|
+
* deriver-backed lookup `emit-properties.ts`'s `declaredFieldRepresentation`
|
|
952
|
+
* already uses for a `native-record-ref`'s named fields, asked for its index
|
|
953
|
+
* instead of its fields. `null` covers three different receivers with one
|
|
954
|
+
* answer -- neither carrier, a `record-with-index` (impossible: every one has
|
|
955
|
+
* an index by construction), and a `native-record-ref` whose named shape has
|
|
956
|
+
* none -- the last of which is exactly what `preflight/property-access.ts`'s
|
|
957
|
+
* `nativeRecordRefHasIndexSidecar` already refuses to certify, so an
|
|
958
|
+
* uncertified program is the only way emission reaches here for one.
|
|
959
|
+
*
|
|
960
|
+
* The sidecar field is always embedded *by value* in the struct
|
|
961
|
+
* (`records.ts`'s `renderStructDefinition`), regardless of the struct's own
|
|
962
|
+
* ownership -- so reaching the struct itself uses the receiver's own
|
|
963
|
+
* accessor (`->` for `shared-refcount`, `.` otherwise), and every operation
|
|
964
|
+
* on the sidecar value it names uses `.`, never a second dispatch on an
|
|
965
|
+
* ownership the sidecar does not have its own copy of.
|
|
966
|
+
*/
|
|
967
|
+
export const recordIndexSidecarTableOf = (ctx, receiver, key) => {
|
|
968
|
+
const representation = receiver.representation;
|
|
969
|
+
if (representation.kind !== 'record-with-index' && representation.kind !== 'native-record-ref')
|
|
970
|
+
return null;
|
|
971
|
+
const indexes = representation.kind === 'record-with-index' ? representation.indexes : recordIndexesOfShape(ctx.deriver, representation.shapeId);
|
|
972
|
+
const staticKey = ctx.staticKeyTexts.get(key.value);
|
|
973
|
+
const index = recordIndexForKeyCarrier(indexes, key.representation, staticKey);
|
|
974
|
+
if (!index)
|
|
975
|
+
return null;
|
|
976
|
+
// A constant key that names one of the receiver's own declared fields is
|
|
977
|
+
// that field -- the struct half of the split layout -- and must not be
|
|
978
|
+
// shadowed by the sidecar sitting beside it (`.length` on an
|
|
979
|
+
// `ArrayLike<number>`).
|
|
980
|
+
//
|
|
981
|
+
// Asked here for BOTH carriers rather than only for `native-record-ref`.
|
|
982
|
+
// `emitGet` reaches this only after `recordWithIndexFieldText` has already
|
|
983
|
+
// declined, so for a `record-with-index` read the test is redundant -- but
|
|
984
|
+
// that made the answer depend on the caller having asked in the right order,
|
|
985
|
+
// and the STORE path has no such predecessor: its declared-field case is the
|
|
986
|
+
// generic struct-member write at the very END of `emitFieldStoreLines`, so a
|
|
987
|
+
// sidecar branch placed before it can only be correct if this function
|
|
988
|
+
// declines a declared key on its own. Making it total is what lets the store
|
|
989
|
+
// side exist at all.
|
|
990
|
+
if (staticKey !== undefined) {
|
|
991
|
+
const fields = representation.kind === 'record-with-index' ? representation.fields : recordFieldsOfShape(ctx.deriver, representation.shapeId);
|
|
992
|
+
if (fields?.some((field) => field.key === staticKey))
|
|
993
|
+
return null;
|
|
994
|
+
}
|
|
995
|
+
const structAccessor = memberAccessOperator(representation.ownership);
|
|
996
|
+
const receiverText = operandText(ctx, receiver);
|
|
997
|
+
const sidecarText = `${receiverText}${structAccessor}${cppRecordIndexSidecarNameFor(index, indexes)}`;
|
|
998
|
+
const keyText = keyedTableKeyText(ctx, key, index.key);
|
|
999
|
+
const propertyKey = index.key === 'symbol'
|
|
1000
|
+
? `gea::PropertyKey::symbol(${keyText})`
|
|
1001
|
+
: index.key === 'number'
|
|
1002
|
+
? key.representation.kind === 'scalar' && key.representation.domain === 'number'
|
|
1003
|
+
? `gea::PropertyKey::number(${keyText})`
|
|
1004
|
+
: `gea::PropertyKey::string(${keyText})`
|
|
1005
|
+
: `gea::PropertyKey::string(${keyText})`;
|
|
1006
|
+
return {
|
|
1007
|
+
member: `${sidecarText}.`,
|
|
1008
|
+
subscript: `${sidecarText}[${keyText}]`,
|
|
1009
|
+
key: keyText,
|
|
1010
|
+
value: index.value,
|
|
1011
|
+
receiver: receiverText,
|
|
1012
|
+
accessor: structAccessor,
|
|
1013
|
+
propertyKey,
|
|
1014
|
+
attributes: `${receiverText}${structAccessor}${cppRecordIndexAttributesNameFor(index, indexes)}`,
|
|
1015
|
+
disjoint: disjointNativeRecordIndexOf(ctx.deriver, representation, key.representation, staticKey) !== null,
|
|
1016
|
+
index
|
|
1017
|
+
};
|
|
1018
|
+
};
|
|
1019
|
+
/**
|
|
1020
|
+
* Reading a computed-keyed property out of a `record-with-index`/
|
|
1021
|
+
* `native-record-ref` receiver's dynamic-property sidecar.
|
|
1022
|
+
*
|
|
1023
|
+
* Identical to `emit-properties.ts`'s `dictionaryReadText`, one member
|
|
1024
|
+
* deeper: the checker itself routes a computed numeric/string read of an
|
|
1025
|
+
* interface that mixes named fields with an index signature
|
|
1026
|
+
* (`ArrayLike<number>`) through the index signature rather than through any
|
|
1027
|
+
* specific named field, because a runtime key's identity is not known at
|
|
1028
|
+
* compile time -- so this is reached exactly when
|
|
1029
|
+
* `preflight/property-access.ts` admits it, over the identical
|
|
1030
|
+
* `gea::Dictionary`/`gea::NumericDictionary` machinery, never over a struct
|
|
1031
|
+
* member the checker could not have meant.
|
|
1032
|
+
*/
|
|
1033
|
+
export const recordIndexSidecarReadText = (ctx, operation) => {
|
|
1034
|
+
const table = recordIndexSidecarTableOf(ctx, operation.receiver, operation.key);
|
|
1035
|
+
if (table === null)
|
|
1036
|
+
return null;
|
|
1037
|
+
const read = operation.result.representation;
|
|
1038
|
+
const source = nativeRecordIndexReadCarrierOf(table.index, read);
|
|
1039
|
+
const raw = `${table.member}read(${table.key})`;
|
|
1040
|
+
const lookup = read.kind === 'optional' && read.absence === 'undefined'
|
|
1041
|
+
? `(${table.member}has(${table.key}) ? ${cppTypeOf(source)}(${raw}) : ${cppTypeOf(source)}())`
|
|
1042
|
+
: raw;
|
|
1043
|
+
const indexedRead = (() => {
|
|
1044
|
+
if (representationKey(source) === representationKey(read))
|
|
1045
|
+
return lookup;
|
|
1046
|
+
const converted = alignedValueText(ctx, 'emit-carrier-members.ts:995', source, read, lookup);
|
|
1047
|
+
if (converted !== null)
|
|
1048
|
+
return converted;
|
|
1049
|
+
throw createCppEmitBlockedError(`conversion:${representationKey(source)}->${representationKey(read)}`, `reads an index sidecar value carried as "${representationKey(source)}" into "${representationKey(read)}", and no conversion is installed`);
|
|
1050
|
+
})();
|
|
1051
|
+
const representation = operation.receiver.representation;
|
|
1052
|
+
const generated = representation.kind === 'record-with-index' || (representation.kind === 'native-record-ref' && representation.native === null);
|
|
1053
|
+
const fields = representation.kind === 'record-with-index'
|
|
1054
|
+
? representation.fields
|
|
1055
|
+
: representation.kind === 'native-record-ref'
|
|
1056
|
+
? recordFieldsOfShape(ctx.deriver, representation.shapeId)
|
|
1057
|
+
: null;
|
|
1058
|
+
// A runtime key can equal a declared field even though the checker typed the
|
|
1059
|
+
// expression through the index signature. Query the fixed layout before the
|
|
1060
|
+
// sidecar and decode the transient Value into the published native carrier;
|
|
1061
|
+
// a deleted fixed slot therefore yields undefined (or a checked mismatch),
|
|
1062
|
+
// never an older sidecar entry with the same PropertyKey.
|
|
1063
|
+
if (!table.disjoint && generated && ctx.staticKeyTexts.get(operation.key.value) === undefined && fields !== null && fields.length > 0) {
|
|
1064
|
+
const fixed = alignedValueText(ctx, 'emit-carrier-members.ts:1017', { kind: 'dynamic', reason: 'declared-any-never-narrowed' }, read, '__gea_fixed');
|
|
1065
|
+
if (fixed === null) {
|
|
1066
|
+
throw createCppEmitBlockedError(`conversion:${representationKey({ kind: 'dynamic', reason: 'declared-any-never-narrowed' })}->${representationKey(read)}`, `a computed key can collide with a fixed field, but its transient reflected value cannot be decoded as "${representationKey(read)}"`);
|
|
1067
|
+
}
|
|
1068
|
+
return (`([&]() -> ${cppTypeOf(read)} { const gea::PropertyKey __gea_key = ${table.propertyKey}; ` +
|
|
1069
|
+
`if (${table.receiver}${table.accessor}gea_matchesOwnField(__gea_key)) { gea::Value __gea_fixed; ` +
|
|
1070
|
+
`${table.receiver}${table.accessor}gea_readOwnField(__gea_key, __gea_fixed); return ${fixed}; } return ${indexedRead}; })()`);
|
|
1071
|
+
}
|
|
1072
|
+
return indexedRead;
|
|
1073
|
+
};
|
|
1074
|
+
/**
|
|
1075
|
+
* Writing a property that names no declared field -- constant or computed --
|
|
1076
|
+
* into a `record-with-index`/`native-record-ref` receiver's index sidecar.
|
|
1077
|
+
*
|
|
1078
|
+
* The store counterpart of `recordIndexSidecarReadText` directly above, and
|
|
1079
|
+
* built the identical way: `recordIndexSidecarTableOf` already declines a
|
|
1080
|
+
* CONSTANT key that names one of the receiver's own declared fields (the
|
|
1081
|
+
* struct half of the split layout, written by the generic field store at the
|
|
1082
|
+
* end of `emitFieldStoreLines` instead), so asking it is enough to tell the
|
|
1083
|
+
* two halves apart -- this function does not re-decide that split, only
|
|
1084
|
+
* dispatch on its answer. A COMPUTED key can never name a declared field in
|
|
1085
|
+
* the first place (`recordIndexSidecarReadText`'s own comment states why:
|
|
1086
|
+
* the checker itself routes a computed access of a mixed-shape type through
|
|
1087
|
+
* the index signature, never through a named field, because a runtime key's
|
|
1088
|
+
* identity is not known at compile time), so `recordIndexSidecarTableOf`
|
|
1089
|
+
* answers it unconditionally, the same way `record-with-index:get:true`
|
|
1090
|
+
* already claims the read.
|
|
1091
|
+
*
|
|
1092
|
+
* `{ count: 1, 0: 'zero' }` against
|
|
1093
|
+
* `interface Mixed { count: number; [index: number]: string }` is ordinary
|
|
1094
|
+
* TypeScript: `count` is the struct half of the split layout and `0` is the
|
|
1095
|
+
* open half. Only an index signature admits the second key at all -- without
|
|
1096
|
+
* one TypeScript rejects it as an excess property -- so this is reached
|
|
1097
|
+
* exactly when the sidecar is the key's only possible home.
|
|
1098
|
+
*
|
|
1099
|
+
* The read side has resolved both halves since it was written; the store
|
|
1100
|
+
* side originally had a counterpart for the constant half only, so a
|
|
1101
|
+
* constant key that named no field fell through every branch of
|
|
1102
|
+
* `emitFieldStoreLines` to the generic struct-member write at its end and
|
|
1103
|
+
* spelled `receiver->gea_slot_0`, a member `records.ts` never laid out
|
|
1104
|
+
* because it laid out the sidecar instead -- and a COMPUTED key that named no
|
|
1105
|
+
* field fell all the way to `emitNativeSidecarSet`, which reaches this same
|
|
1106
|
+
* receiver but through the wrong table: its own `gea::nativeDynamicSet` is
|
|
1107
|
+
* the BOXED dynamic-property expando a native type's `(this as any)[k] = v`
|
|
1108
|
+
* cast reaches, keyed and valued in `gea::Value`, not the typed table this
|
|
1109
|
+
* carrier's own index signature already states a value carrier for -- so an
|
|
1110
|
+
* array-typed (or otherwise unboxed) sidecar value had no box tag to go
|
|
1111
|
+
* through and refused outright, though the identical value already reads
|
|
1112
|
+
* back correctly through `recordIndexSidecarReadText` on the very same
|
|
1113
|
+
* carrier. Widening this function to the computed case, ahead of
|
|
1114
|
+
* `emitNativeSidecarSet` in `emitFieldStoreLines`'s own dispatch order
|
|
1115
|
+
* (unchanged), is what makes the store side total the way the read side
|
|
1116
|
+
* already is; `emitNativeSidecarSet` keeps its computed-key claim for every
|
|
1117
|
+
* receiver that has no such typed sidecar to route into at all.
|
|
1118
|
+
*/
|
|
1119
|
+
export const recordIndexAttributeKeyText = (index, key, text) => index.key === 'number' && key.kind === 'scalar' ? `gea::PropertyKey::number(${text}).text()` : text;
|
|
1120
|
+
export const emitRecordIndexSidecarStore = (ctx, lines, operation) => {
|
|
1121
|
+
const table = recordIndexSidecarTableOf(ctx, operation.receiver, operation.key);
|
|
1122
|
+
if (table === null)
|
|
1123
|
+
return false;
|
|
1124
|
+
// Reconciled against the table's declared value carrier for the reason
|
|
1125
|
+
// `emit-properties.ts`'s `dictionary` branch states: the sidecar holds one
|
|
1126
|
+
// joined carrier, and a value written into it becomes that carrier through
|
|
1127
|
+
// the conversion, never through an overload that does not exist.
|
|
1128
|
+
const valueText = operandText(ctx, operation.value);
|
|
1129
|
+
// A post-definition indexed assignment must consult the same writable and
|
|
1130
|
+
// extensible state `Object.defineProperty` installed. The value itself
|
|
1131
|
+
// stays in the typed sidecar -- only the boolean result crosses this
|
|
1132
|
+
// control-flow boundary, never the value through `gea::Value`.
|
|
1133
|
+
const stored = alignedValueText(ctx, 'emit-carrier-members.ts:1094', operation.value.representation, table.value, valueText);
|
|
1134
|
+
if (stored === null)
|
|
1135
|
+
throw createCppEmitBlockedError(`conversion:${representationKey(operation.value.representation)}->${representationKey(table.value)}`, 'the indexed store has no selected native value conversion');
|
|
1136
|
+
const extensible = table.accessor === '->' ? `gea::nativeIsExtensible(${table.receiver})` : 'true';
|
|
1137
|
+
const write = (() => {
|
|
1138
|
+
if (operation.kind !== 'define-own-property') {
|
|
1139
|
+
return `${table.receiver}${table.accessor}gea_writeOwnIndexNative(${table.propertyKey}, ${stored}, ${extensible})`;
|
|
1140
|
+
}
|
|
1141
|
+
if (table.disjoint) {
|
|
1142
|
+
const attributes = operation.attributes;
|
|
1143
|
+
const attributeKey = recordIndexAttributeKeyText(table.index, operation.key.representation, '__gea_key');
|
|
1144
|
+
return (`([&]() -> bool { const auto __gea_key = ${table.key}; const ${cppTypeOf(table.value)} __gea_value = ${stored}; ` +
|
|
1145
|
+
`const bool __gea_exists = ${table.member}has(__gea_key); if (!__gea_exists && !${extensible}) return false; ` +
|
|
1146
|
+
`const auto __gea_attribute_key = ${attributeKey}; auto __gea_attributes = ${table.attributes}.attributes(__gea_attribute_key); ` +
|
|
1147
|
+
`auto __gea_next = __gea_exists ? ${table.member}read(__gea_key) : __gea_value; ` +
|
|
1148
|
+
`if (!gea::applyNativeFixedDataDescriptor(__gea_next, __gea_attributes, __gea_value, __gea_exists, ` +
|
|
1149
|
+
`true, ${attributes.writable}, true, ${attributes.enumerable}, true, ${attributes.configurable})) return false; ` +
|
|
1150
|
+
`${table.member}operator[](__gea_key) = std::move(__gea_next); ${table.attributes}.set(__gea_attribute_key, __gea_attributes); return true; })()`);
|
|
1151
|
+
}
|
|
1152
|
+
const boxed = widenedStoreText({ kind: 'dynamic', reason: 'declared-any-never-narrowed' }, table.value, stored) ??
|
|
1153
|
+
(table.value.kind === 'dynamic' ? stored : null);
|
|
1154
|
+
if (boxed === null) {
|
|
1155
|
+
throw createCppEmitBlockedError(`conversion:${representationKey(table.value)}->dynamic`, `define-own-property needs a transient descriptor value for "${representationKey(table.value)}", but that carrier has no authenticated Value boundary`);
|
|
1156
|
+
}
|
|
1157
|
+
const attributes = operation.attributes;
|
|
1158
|
+
return (`([&]() -> bool { const gea::PropertyKey __gea_key = ${table.propertyKey}; ` +
|
|
1159
|
+
`gea::PropertyDescriptor __gea_descriptor = gea::PropertyDescriptor::assignment(${boxed}); ` +
|
|
1160
|
+
`__gea_descriptor.writable = ${attributes.writable}; __gea_descriptor.enumerable = ${attributes.enumerable}; ` +
|
|
1161
|
+
`__gea_descriptor.configurable = ${attributes.configurable}; ` +
|
|
1162
|
+
`if (${table.receiver}${table.accessor}gea_matchesOwnField(__gea_key)) ` +
|
|
1163
|
+
`return ${table.receiver}${table.accessor}gea_defineOwnField(__gea_key, __gea_descriptor, ${extensible}); ` +
|
|
1164
|
+
`return ${table.receiver}${table.accessor}gea_defineOwnIndex(__gea_key, __gea_descriptor, ${extensible}); })()`);
|
|
1165
|
+
})();
|
|
1166
|
+
if (operation.kind === 'set' && operation.strict) {
|
|
1167
|
+
lines.push(`if (!${write}) gea::host::throwRuntimeError("TypeError", "Cannot assign to indexed property");`);
|
|
1168
|
+
}
|
|
1169
|
+
else if (operation.kind === 'define-own-property') {
|
|
1170
|
+
lines.push(`if (!${write}) gea::host::throwRuntimeError("TypeError", "Cannot define indexed property");`);
|
|
1171
|
+
}
|
|
1172
|
+
else {
|
|
1173
|
+
lines.push(`${write};`);
|
|
1174
|
+
}
|
|
1175
|
+
// A store publishes the object it wrote into, not a success boolean, and it
|
|
1176
|
+
// NAMES the receiver rather than copying it -- the same handover every other
|
|
1177
|
+
// store branch performs.
|
|
1178
|
+
if (operation.result)
|
|
1179
|
+
defineValueAlias(ctx, operation.result, operandText(ctx, operation.receiver));
|
|
1180
|
+
return true;
|
|
1181
|
+
};
|
|
1182
|
+
/**
|
|
1183
|
+
* Whether a scalar member read is a deferred `Number`/`BigInt.prototype`
|
|
1184
|
+
* method read. Stated once; the renderer and the walk both ask it.
|
|
1185
|
+
*/
|
|
1186
|
+
export const deferredScalarMethodClaim = (staticKeyTexts, receiver, key) => {
|
|
1187
|
+
const carrier = receiver.representation;
|
|
1188
|
+
if (carrier.kind !== 'scalar')
|
|
1189
|
+
return null;
|
|
1190
|
+
const staticKey = staticKeyTexts.get(key.value);
|
|
1191
|
+
if (staticKey === undefined)
|
|
1192
|
+
return null;
|
|
1193
|
+
const operand = { kind: 'operand', operand: receiver };
|
|
1194
|
+
if (carrier.domain === 'number' && numberPrototypeMethods.has(staticKey))
|
|
1195
|
+
return { receiverKind: 'number', member: staticKey, receiver: operand, receiverElement: null };
|
|
1196
|
+
if (carrier.domain === 'bigint' && (staticKey === 'toString' || staticKey === 'valueOf'))
|
|
1197
|
+
return { receiverKind: 'bigint', member: staticKey, receiver: operand, receiverElement: null };
|
|
1198
|
+
return null;
|
|
1199
|
+
};
|
|
1200
|
+
export const scalarMemberText = (ctx, receiver, key, result) => {
|
|
1201
|
+
if (receiver.representation.kind !== 'scalar')
|
|
1202
|
+
return null;
|
|
1203
|
+
const domain = receiver.representation.domain;
|
|
1204
|
+
const staticKey = ctx.staticKeyTexts.get(key.value);
|
|
1205
|
+
if (staticKey !== undefined) {
|
|
1206
|
+
// The same deferral `stringMemberText` performs, for the same reason: the
|
|
1207
|
+
// member has no receiver-carrying convention to build a callable from, so
|
|
1208
|
+
// the read renders nothing and the call that follows fuses the two.
|
|
1209
|
+
// `emit-prototype-invoke.ts` owns which keys that is.
|
|
1210
|
+
const claim = deferredScalarMethodClaim(ctx.staticKeyTexts, receiver, key);
|
|
1211
|
+
if (claim?.receiverKind === 'number') {
|
|
1212
|
+
if (result === null) {
|
|
1213
|
+
throw createCppEmitBlockedError('property-access:scalar:get:false', `"${staticKey}" is a Number.prototype method, and this access publishes no value for its call to consume`);
|
|
1214
|
+
}
|
|
1215
|
+
return '';
|
|
1216
|
+
}
|
|
1217
|
+
if (claim?.receiverKind === 'bigint' && result !== null)
|
|
1218
|
+
return '';
|
|
1219
|
+
throw createCppEmitBlockedError('property-access:scalar:get:false', `"${staticKey}" is a ${domain}-valued scalar's prototype method, not a data property; calling it needs a ` +
|
|
1220
|
+
'receiver-carrying calling convention this program did not derive one for, and reading it as a value has no native ' +
|
|
1221
|
+
`implementation installed -- only ${[...numberPrototypeMethods].join(', ')} are implemented, and only off a number`);
|
|
1222
|
+
}
|
|
1223
|
+
throw createCppEmitBlockedError('property-access:scalar:get:true', 'a scalar property access keyed by a non-constant key has no ToPropertyKey or native member table installed');
|
|
1224
|
+
};
|