@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,1378 @@
|
|
|
1
|
+
import { abiKey, arrayExtensionKey, representationKey } from '../representation/model.js';
|
|
2
|
+
import { optionalOf } from '../representation/optional.js';
|
|
3
|
+
import { createConversionDerivationContext, deriveConversionCapability } from './derive.js';
|
|
4
|
+
import { validateConversionGraph } from './graph-validation.js';
|
|
5
|
+
/**
|
|
6
|
+
* A registry with nothing installed.
|
|
7
|
+
*
|
|
8
|
+
* Every lookup answers `null`, so every capability derives to `never` with a
|
|
9
|
+
* stated reason. That is the honest description of a backend whose conversion
|
|
10
|
+
* primitives have not been written yet: the gaps are enumerated rather than
|
|
11
|
+
* hidden behind a capability nobody implemented.
|
|
12
|
+
*/
|
|
13
|
+
export const emptyConversionRegistry = Object.freeze({
|
|
14
|
+
scalarMaterializer: () => null,
|
|
15
|
+
stringMaterializer: () => null,
|
|
16
|
+
symbolMaterializer: () => null,
|
|
17
|
+
nullMaterializer: () => null,
|
|
18
|
+
undefinedMaterializer: () => null,
|
|
19
|
+
classRefMaterializer: () => null,
|
|
20
|
+
nativeHandleMaterializer: () => null,
|
|
21
|
+
recordMaterializer: () => null,
|
|
22
|
+
recordRefMaterializer: () => null,
|
|
23
|
+
arrayObjectDomain: () => null,
|
|
24
|
+
functionMaterializer: () => null,
|
|
25
|
+
functionValueDispatchMaterializer: () => null,
|
|
26
|
+
optionalAbsenceTag: (_absence) => null,
|
|
27
|
+
boxedIdentityMaterializer: () => null,
|
|
28
|
+
taggedUnionArmClassifier: () => null,
|
|
29
|
+
narrowing: () => null,
|
|
30
|
+
widening: () => null,
|
|
31
|
+
recasting: () => null,
|
|
32
|
+
staticRecipe: () => null,
|
|
33
|
+
coercion: () => null
|
|
34
|
+
});
|
|
35
|
+
/**
|
|
36
|
+
* Every carrier a narrowing can land on, given the one the cell holds.
|
|
37
|
+
*
|
|
38
|
+
* The list is the shape of the source, not a search: an optional narrows to its
|
|
39
|
+
* payload, a union narrows to one of its arms, and an optional *of* a union
|
|
40
|
+
* narrows three ways -- the union still wrapped, straight through to an arm
|
|
41
|
+
* because `if (x && typeof x === 'string')` proves both facts at once, or to an
|
|
42
|
+
* optional of an arm because `if (typeof x !== 'string')` proves which arm is
|
|
43
|
+
* live and says nothing at all about presence.
|
|
44
|
+
*
|
|
45
|
+
* Arms are deduplicated by carrier rather than by position. A union whose arms
|
|
46
|
+
* are `string | string | string` at the *carrier* level -- three different
|
|
47
|
+
* declared types that all lower to one C++ type -- offers exactly one narrowing
|
|
48
|
+
* target, and the choice of which arm is live is the load's problem, not this
|
|
49
|
+
* enumeration's.
|
|
50
|
+
*/
|
|
51
|
+
/**
|
|
52
|
+
* The narrowing targets reachable by ruling out exactly one arm -- the shape a
|
|
53
|
+
* single `typeof`/`instanceof` guard's negative branch proves (`h instanceof
|
|
54
|
+
* Headers` inside `const h: Headers | Record<string,string> |
|
|
55
|
+
* [string,string][]` leaves the `else` branch holding the other two, still a
|
|
56
|
+
* union). Ruling out more than one arm at once is two guards, which reads as
|
|
57
|
+
* two successive single-arm narrowings rather than a target this enumeration
|
|
58
|
+
* would have to search combinatorially for -- so this stays linear in the
|
|
59
|
+
* arm count, never exponential.
|
|
60
|
+
*
|
|
61
|
+
* `< 3` returns nothing on purpose: a two-arm union with one arm ruled out
|
|
62
|
+
* narrows to that ONE remaining arm, which the plain per-arm enumeration
|
|
63
|
+
* right below already offers.
|
|
64
|
+
*/
|
|
65
|
+
const dropOneArmUnionsOf = (union) => {
|
|
66
|
+
if (union.arms.length < 3)
|
|
67
|
+
return [];
|
|
68
|
+
// `TaggedUnionArm.tag` is minted once, in representation/union.ts, as the
|
|
69
|
+
// arm's zero-based POSITION stringified -- representationKey embeds it
|
|
70
|
+
// verbatim. Dropping an arm without renumbering the survivors leaves their
|
|
71
|
+
// tags citing their OLD position, so this subset's key never matches the
|
|
72
|
+
// real, independently-derived representation of the same union elsewhere
|
|
73
|
+
// in the plan, and no conversion node ever gets minted for it.
|
|
74
|
+
return union.arms.map((_, dropped) => ({
|
|
75
|
+
kind: 'tagged-union',
|
|
76
|
+
arms: union.arms.filter((__, index) => index !== dropped).map((arm, position) => ({ ...arm, tag: String(position) }))
|
|
77
|
+
}));
|
|
78
|
+
};
|
|
79
|
+
const noNarrowingSteps = { nested: [], subsets: [] };
|
|
80
|
+
const narrowingStepsOf = (source) => {
|
|
81
|
+
if (source.kind === 'tagged-union') {
|
|
82
|
+
// A union whose absence lives INSIDE an arm's own optional narrows to an
|
|
83
|
+
// OPTIONAL of another arm, which neither the bare arms nor the
|
|
84
|
+
// drop-one-arm unions reach. hono's `compose` binds `let handler` to a
|
|
85
|
+
// `Function | (Next | undefined)` cell -- arms `record` and
|
|
86
|
+
// `optional(callable)` -- and reads it back as `Function | undefined`.
|
|
87
|
+
// The absence tag comes from the optional arm that holds it, because that
|
|
88
|
+
// is the only absence this union can express.
|
|
89
|
+
//
|
|
90
|
+
// The absence may also be an arm of its OWN -- three's `@type {?Array<Plane>}`
|
|
91
|
+
// field is `undefined | null | Array<Plane>` (a JS field is readable before
|
|
92
|
+
// its constructor writes it, so the census tags both absences), and
|
|
93
|
+
// `if ( srcPlanes !== null )` rules out exactly one of them. What is left is
|
|
94
|
+
// one absence beside one value, which IS an optional -- and every read past
|
|
95
|
+
// that guard carries it. Without this the cell answered the three-arm union
|
|
96
|
+
// and its guarded reads answered `optional(Array<Plane>, undefined)`, with
|
|
97
|
+
// no pair between them in the graph: 4 unmet `binding-read-conversion`
|
|
98
|
+
// obligations on the three.js app for one field, and the same shape wherever a
|
|
99
|
+
// nullable JSDoc field is guarded. `targets/cpp/conversions.ts` already
|
|
100
|
+
// installs `tagged-union -> optional(arm)` (`live-arm-optional`); only the
|
|
101
|
+
// pairing was missing.
|
|
102
|
+
const absences = [
|
|
103
|
+
...new Set(source.arms.flatMap((arm) => arm.value.kind === 'optional'
|
|
104
|
+
? [arm.value.absence]
|
|
105
|
+
: arm.value.kind === 'undefined'
|
|
106
|
+
? ['undefined']
|
|
107
|
+
: arm.value.kind === 'null'
|
|
108
|
+
? ['null']
|
|
109
|
+
: []))
|
|
110
|
+
];
|
|
111
|
+
const optionalArms = source.arms
|
|
112
|
+
.filter((arm) => arm.value.kind !== 'optional' && arm.value.kind !== 'undefined' && arm.value.kind !== 'null')
|
|
113
|
+
.flatMap((arm) => absences.map((absence) => ({ kind: 'optional', payload: arm.value, absence })));
|
|
114
|
+
return { nested: distinctByKey([...source.arms.map((arm) => arm.value), ...optionalArms]), subsets: dropOneArmUnionsOf(source) };
|
|
115
|
+
}
|
|
116
|
+
if (source.kind !== 'optional')
|
|
117
|
+
return noNarrowingSteps;
|
|
118
|
+
// The ABSENT side is a narrowing target too, and it had no pairing at all.
|
|
119
|
+
//
|
|
120
|
+
// `if ( dstArray === null )` proves the cell holds absence, and every read
|
|
121
|
+
// inside that branch carries the absent value's OWN carrier -- `null`, whose
|
|
122
|
+
// C++ value is `nullptr`, or `undefined`. This enumeration offered only the
|
|
123
|
+
// present side, so those reads asked for an `optional(T,null) -> null`
|
|
124
|
+
// conversion that nothing had ever proposed a node for. three's
|
|
125
|
+
// `WebGLClipping` does it twice on one field.
|
|
126
|
+
const absent = { kind: source.absence };
|
|
127
|
+
const payload = source.payload;
|
|
128
|
+
if (payload.kind !== 'tagged-union')
|
|
129
|
+
return { nested: distinctByKey([payload, absent]), subsets: [] };
|
|
130
|
+
const arms = payload.arms.map((arm) => arm.value);
|
|
131
|
+
const subsetUnions = dropOneArmUnionsOf(payload);
|
|
132
|
+
return {
|
|
133
|
+
nested: distinctByKey([
|
|
134
|
+
payload,
|
|
135
|
+
absent,
|
|
136
|
+
...arms,
|
|
137
|
+
...arms.map((arm) => ({ kind: 'optional', payload: arm, absence: source.absence }))
|
|
138
|
+
]),
|
|
139
|
+
subsets: distinctByKey([
|
|
140
|
+
...subsetUnions,
|
|
141
|
+
// The subset union still wrapped in optional -- `if (x !== undefined &&
|
|
142
|
+
// typeof x !== 'number')` proves which arm is excluded but says nothing
|
|
143
|
+
// about presence, so the live narrowing keeps the absence tag.
|
|
144
|
+
...subsetUnions.map((sub) => ({ kind: 'optional', payload: sub, absence: source.absence }))
|
|
145
|
+
])
|
|
146
|
+
};
|
|
147
|
+
};
|
|
148
|
+
/**
|
|
149
|
+
* Every carrier a narrowing can reach, following arms that are THEMSELVES
|
|
150
|
+
* unions or optionals.
|
|
151
|
+
*
|
|
152
|
+
* `narrowingStepsOf` strips exactly one level, and one level is not what the
|
|
153
|
+
* language proves. three's JSDoc nullable field is `undefined | null | X`, and
|
|
154
|
+
* when `X` is itself a union -- `?(string|number|boolean)` -- a guard past the
|
|
155
|
+
* two absences lands inside `X`: `undefined | null | (string|number)` narrowed
|
|
156
|
+
* to `number` is two steps, and the outer shape narrowed to the same outer
|
|
157
|
+
* shape with a SMALLER inner union is two steps as well. Neither pairing was
|
|
158
|
+
* ever proposed, so no node was minted and every such read reported a missing
|
|
159
|
+
* conversion for a recipe that already exists -- `emit-narrowing.ts`'s
|
|
160
|
+
* `narrowedUnionSubsetText` recurses one level in for exactly this shape and
|
|
161
|
+
* had no obligation counterpart.
|
|
162
|
+
*
|
|
163
|
+
* Depth-bounded rather than fixpointed, and deduplicated by key. Each step
|
|
164
|
+
* strips one level of nesting so it terminates on its own for a finite carrier,
|
|
165
|
+
* but a `Representation` graph may be genuinely cyclic (the standard way to
|
|
166
|
+
* spell a recursive type), which is the same hazard `ConversionDerivationContext`
|
|
167
|
+
* guards with `inProgress`. Three levels is what the shapes in play need: an
|
|
168
|
+
* optional over a union over a union.
|
|
169
|
+
*/
|
|
170
|
+
const NARROWING_DEPTH = 3;
|
|
171
|
+
/**
|
|
172
|
+
* Memo for the two functions below, keyed by the source's STRUCTURAL key.
|
|
173
|
+
*
|
|
174
|
+
* `representationKey` has its own memo, but it is keyed by object IDENTITY --
|
|
175
|
+
* and the closure walk below MINTS representations as it goes (the absent
|
|
176
|
+
* side, `dropOneArmUnionsOf`'s one-arm-smaller unions, `distinctByKey`'s
|
|
177
|
+
* arrays). Every minted object is a fresh miss, so an unmemoized closure pays
|
|
178
|
+
* a full structural rebuild, crypto digest included, for values it has already
|
|
179
|
+
* built -- and `narrowingReachesTarget` asks for the same closure twice, once
|
|
180
|
+
* up front and again inside a RECURSIVE `reaches`. Measured on the three.js app, the
|
|
181
|
+
* closure and the keying it forces were about 16% of a 58s compile.
|
|
182
|
+
*
|
|
183
|
+
* Sound to memo because the walk is a pure function of the representation: it
|
|
184
|
+
* reads `narrowingStepsOf` and nothing else, and representations are immutable
|
|
185
|
+
* value objects. Keyed structurally rather than by identity precisely so two
|
|
186
|
+
* equal-but-distinct mintings share one answer, which is the whole point.
|
|
187
|
+
*/
|
|
188
|
+
const narrowingClosures = new Map();
|
|
189
|
+
/** The closure's members' keys, which is all either caller actually tests. */
|
|
190
|
+
const narrowingClosureKeysOf = (source) => narrowingClosureEntryOf(source).keys;
|
|
191
|
+
const narrowingClosureOf = (source) => narrowingClosureEntryOf(source).values;
|
|
192
|
+
const narrowingClosureEntryOf = (source) => {
|
|
193
|
+
const sourceCacheKey = representationKey(source);
|
|
194
|
+
const remembered = narrowingClosures.get(sourceCacheKey);
|
|
195
|
+
if (remembered !== undefined)
|
|
196
|
+
return remembered;
|
|
197
|
+
const values = buildNarrowingClosure(source);
|
|
198
|
+
const entry = { values, keys: new Set(values.map(representationKey)) };
|
|
199
|
+
narrowingClosures.set(sourceCacheKey, entry);
|
|
200
|
+
return entry;
|
|
201
|
+
};
|
|
202
|
+
const buildNarrowingClosure = (source) => {
|
|
203
|
+
const found = new Map();
|
|
204
|
+
const sourceKey = representationKey(source);
|
|
205
|
+
let frontier = [source];
|
|
206
|
+
for (let level = 0; level < NARROWING_DEPTH; level++) {
|
|
207
|
+
const next = [];
|
|
208
|
+
for (const one of frontier) {
|
|
209
|
+
const steps = narrowingStepsOf(one);
|
|
210
|
+
for (const target of steps.nested) {
|
|
211
|
+
const key = representationKey(target);
|
|
212
|
+
if (key === sourceKey || found.has(key))
|
|
213
|
+
continue;
|
|
214
|
+
found.set(key, target);
|
|
215
|
+
next.push(target);
|
|
216
|
+
}
|
|
217
|
+
// A leaf: found, never stepped from again. See `NarrowingSteps`.
|
|
218
|
+
for (const target of steps.subsets) {
|
|
219
|
+
const key = representationKey(target);
|
|
220
|
+
if (key === sourceKey || found.has(key))
|
|
221
|
+
continue;
|
|
222
|
+
found.set(key, target);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
if (next.length === 0)
|
|
226
|
+
break;
|
|
227
|
+
frontier = next;
|
|
228
|
+
}
|
|
229
|
+
return [...found.values()];
|
|
230
|
+
};
|
|
231
|
+
/**
|
|
232
|
+
* Whether the supplied `target` is reachable from `source` by narrowing.
|
|
233
|
+
*
|
|
234
|
+
* The ordinary closure covers nested payload selection and the one-arm subset
|
|
235
|
+
* a single guard creates. A target already present in the program can also be
|
|
236
|
+
* the same outer sum with a smaller inner sum after several guards. Recognize
|
|
237
|
+
* that supplied shape recursively instead of enumerating its possible
|
|
238
|
+
* subsets: each target arm must have an exact, ordinarily narrowed, class-
|
|
239
|
+
* descendant, or recursively narrowed home in a source arm. Pair memoization
|
|
240
|
+
* keeps recursive representations finite. This one predicate is shared by
|
|
241
|
+
* graph proposal and backend admission so they cannot disagree.
|
|
242
|
+
*/
|
|
243
|
+
const reachesMemo = new Map();
|
|
244
|
+
export const narrowingReachesTarget = (source, target) => {
|
|
245
|
+
const targetKey = representationKey(target);
|
|
246
|
+
if (narrowingClosureKeysOf(source).has(targetKey))
|
|
247
|
+
return true;
|
|
248
|
+
// Module level for the same reason `narrowingClosureOf`'s cache above is:
|
|
249
|
+
// `reaches(from, to)` is a pure structural question about two immutable
|
|
250
|
+
// representations, so the answer is the same for every caller, and a memo
|
|
251
|
+
// minted per call throws away the whole table between questions that
|
|
252
|
+
// overwhelmingly repeat. `active` stays per call -- it is the cycle guard for
|
|
253
|
+
// THIS descent, not a fact about the graph, and sharing it would let one
|
|
254
|
+
// call's in-progress pair read as a settled `false` in another.
|
|
255
|
+
const active = new Set();
|
|
256
|
+
const reaches = (from, to) => {
|
|
257
|
+
const fromKey = representationKey(from);
|
|
258
|
+
const toKey = representationKey(to);
|
|
259
|
+
if (fromKey === toKey)
|
|
260
|
+
return true;
|
|
261
|
+
if (narrowingClosureKeysOf(from).has(toKey))
|
|
262
|
+
return true;
|
|
263
|
+
const pair = `${fromKey}->${toKey}`;
|
|
264
|
+
const known = reachesMemo.get(pair);
|
|
265
|
+
if (known !== undefined)
|
|
266
|
+
return known;
|
|
267
|
+
if (active.has(pair))
|
|
268
|
+
return false;
|
|
269
|
+
active.add(pair);
|
|
270
|
+
let result = from.kind === 'class-ref' && to.kind === 'class-ref' && from.ownership === to.ownership && to.ancestors.includes(from.declaration);
|
|
271
|
+
if (!result && from.kind === 'optional') {
|
|
272
|
+
result = to.kind === 'optional' && from.absence === to.absence ? reaches(from.payload, to.payload) : reaches(from.payload, to);
|
|
273
|
+
}
|
|
274
|
+
if (!result && from.kind === 'tagged-union') {
|
|
275
|
+
result =
|
|
276
|
+
to.kind === 'tagged-union'
|
|
277
|
+
? to.arms.length >= 2 &&
|
|
278
|
+
to.arms.length <= from.arms.length &&
|
|
279
|
+
to.arms.every((targetArm) => from.arms.some((sourceArm) => reaches(sourceArm.value, targetArm.value)))
|
|
280
|
+
: from.arms.some((arm) => reaches(arm.value, to));
|
|
281
|
+
}
|
|
282
|
+
active.delete(pair);
|
|
283
|
+
reachesMemo.set(pair, result);
|
|
284
|
+
return result;
|
|
285
|
+
};
|
|
286
|
+
return reaches(source, target);
|
|
287
|
+
};
|
|
288
|
+
/**
|
|
289
|
+
* Whether `target`'s arms are all drawn from `source`'s -- a proper, more
|
|
290
|
+
* than one arm dropped, subset -- so `target` is a live narrowing of `source`
|
|
291
|
+
* that ruling out one arm at a time (`dropOneArmUnionsOf`) cannot reach in a
|
|
292
|
+
* single step. Order-independent and duplicate-tolerant on purpose: this
|
|
293
|
+
* mirrors `targets/cpp/conversions.ts`'s own `registry.narrowing` admission
|
|
294
|
+
* test for a sub-union target exactly (`selected.arms.every(...source arm
|
|
295
|
+
* exists...)`), which is the render-side authority for whether the pairing
|
|
296
|
+
* this predicate approves actually gets a materializer. Duplicated rather
|
|
297
|
+
* than imported because `conversion/build.ts` is backend-agnostic and
|
|
298
|
+
* `conversions.ts` is the C++ target's own registry -- but the two must never
|
|
299
|
+
* answer differently about the same pair, so if one changes, the other must.
|
|
300
|
+
*/
|
|
301
|
+
/**
|
|
302
|
+
* A base-declared class handle read at one of its DESCENDANTS -- the narrowing
|
|
303
|
+
* `instanceof` performs, which `narrowingStepsOf` cannot enumerate.
|
|
304
|
+
*
|
|
305
|
+
* `narrowingStepsOf` answers "what can this carrier narrow to" from the
|
|
306
|
+
* carrier alone, and a `class-ref(Object3D)` states nothing about which
|
|
307
|
+
* classes descend from it -- that is a fact about each OTHER class. So this is
|
|
308
|
+
* a TEST, asked of the target, which does state its own ancestry. three's
|
|
309
|
+
* `getDepthMaterial` writes `result = cond ? _distanceMaterial : _depthMaterial`
|
|
310
|
+
* into a cell the checker widened to `undefined | null | Material` and reads
|
|
311
|
+
* it back at the two-class union the assignment proved: an arm subset whose
|
|
312
|
+
* arms are descendants of the source's own arm, and without this every read
|
|
313
|
+
* past that assignment reported a conversion with no node.
|
|
314
|
+
*
|
|
315
|
+
* `targets/cpp/conversions.ts`'s `downcastsToDerived` is the same predicate on
|
|
316
|
+
* the admission side, and `emit-narrowing.ts`'s `narrowedLoadText` renders it
|
|
317
|
+
* -- all three off the carrier's own `ancestors`, so there is one authority.
|
|
318
|
+
*/
|
|
319
|
+
const narrowsToDescendantClass = (source, target) => source.kind === 'class-ref' &&
|
|
320
|
+
target.kind === 'class-ref' &&
|
|
321
|
+
source.ownership === target.ownership &&
|
|
322
|
+
target.ancestors.includes(source.declaration);
|
|
323
|
+
/** The class handle a carrier holds outright, through at most one optional wrapper. */
|
|
324
|
+
const heldClassOf = (source) => {
|
|
325
|
+
if (source.kind === 'class-ref')
|
|
326
|
+
return source;
|
|
327
|
+
if (source.kind === 'optional' && source.payload.kind === 'class-ref')
|
|
328
|
+
return source.payload;
|
|
329
|
+
return null;
|
|
330
|
+
};
|
|
331
|
+
/**
|
|
332
|
+
* A base-class handle read at a UNION of its descendants -- `instanceof Mesh ||
|
|
333
|
+
* instanceof Line || instanceof Points`, which is the guard three's
|
|
334
|
+
* `WebGLShadowMap.renderObject` is written with once the gea plugin restores
|
|
335
|
+
* real class tests in place of three's duck-typed `isMesh` flags.
|
|
336
|
+
*
|
|
337
|
+
* `narrowsToDescendantClass` answers this one arm at a time and
|
|
338
|
+
* `subsetNarrowingTargetsOf`'s union branch answers it for a union SOURCE;
|
|
339
|
+
* neither covers a class source read at a union target, so twenty reads past
|
|
340
|
+
* that one guard carried an obligation nothing had proposed and the three.js app could
|
|
341
|
+
* not certify at all. The renderer has always been able to spell it --
|
|
342
|
+
* `targets/cpp/emit-narrowing.ts`'s `classFamilyLoadText` projects exactly
|
|
343
|
+
* this, testing the most-specific family first and rebuilding the arm -- so
|
|
344
|
+
* the gap was the capability side alone, which is the two-authorities shape:
|
|
345
|
+
* fix the side that is wrong, never the consumer.
|
|
346
|
+
*
|
|
347
|
+
* Asked of the target because a `class-ref(Object3D)` states nothing about
|
|
348
|
+
* which classes descend from it; each arm states its own ancestry.
|
|
349
|
+
* `targets/cpp/conversions.ts` imports this rather than restating it so the
|
|
350
|
+
* proposal and the admission cannot disagree about which pairs install.
|
|
351
|
+
*/
|
|
352
|
+
export const narrowsToDescendantClassUnion = (source, target) => {
|
|
353
|
+
const held = heldClassOf(source);
|
|
354
|
+
if (held === null)
|
|
355
|
+
return false;
|
|
356
|
+
// An optional target keeps the source's own absence around the projected
|
|
357
|
+
// union; it never invents one, and it never changes which absence is worn.
|
|
358
|
+
if (target.kind === 'optional' && source.kind === 'optional' && source.absence !== target.absence)
|
|
359
|
+
return false;
|
|
360
|
+
const union = target.kind === 'optional' ? target.payload : target;
|
|
361
|
+
if (union.kind !== 'tagged-union' || union.arms.length === 0)
|
|
362
|
+
return false;
|
|
363
|
+
return union.arms.every((arm) => narrowsToDescendantClass(held, arm.value));
|
|
364
|
+
};
|
|
365
|
+
/**
|
|
366
|
+
* Wraps a `registry.narrowing` pair as the capability the printer actually
|
|
367
|
+
* renders it with.
|
|
368
|
+
*
|
|
369
|
+
* Every narrowing pair is an `atom` except this one: a base handle narrowed
|
|
370
|
+
* to a union of descendants needs `class-family`
|
|
371
|
+
* (`conversion/algebra.ts`'s own doc on that kind says why -- its recipe,
|
|
372
|
+
* `targets/cpp/emit-narrowing.ts`'s `classFamilyLoadText`, orders its cascade
|
|
373
|
+
* over the whole-program class table, which the ctx-free chain every `atom`
|
|
374
|
+
* renders through cannot see). Re-asking `narrowsToDescendantClassUnion`
|
|
375
|
+
* here rather than having the caller remember which shape it minted keeps
|
|
376
|
+
* the proposal (this predicate) and the wrap from ever disagreeing about
|
|
377
|
+
* which pairs are which.
|
|
378
|
+
*/
|
|
379
|
+
export const narrowingCapabilityFor = (source, target, installed) => narrowsToDescendantClassUnion(source, target)
|
|
380
|
+
? { kind: 'class-family', materializer: installed.materializer }
|
|
381
|
+
: { kind: 'atom', classifier: installed.classifier, materializer: installed.materializer };
|
|
382
|
+
const isArmSubsetOf = (source, target) => {
|
|
383
|
+
if (target.arms.length < 2 || target.arms.length > source.arms.length)
|
|
384
|
+
return false;
|
|
385
|
+
// An arm's home may be an arm the target's own arm NARROWS OUT OF, not only
|
|
386
|
+
// one it equals -- which is also why the arm-count test is `>` and not `>=`.
|
|
387
|
+
// three's `?(string|number|boolean)` field is `undefined | null |
|
|
388
|
+
// (string|number|boolean)`, and a guard on the inner union leaves the SAME
|
|
389
|
+
// three-arm outer shape with a smaller union in its `present` arm: same arm
|
|
390
|
+
// count, genuinely narrower, and matching arms by key alone read it as a
|
|
391
|
+
// union with no such arm at all. `emit-narrowing.ts`'s
|
|
392
|
+
// `narrowedUnionSubsetText` already renders exactly this -- it searches for
|
|
393
|
+
// an exact home first and then asks `narrowedLoadText` one level in -- and
|
|
394
|
+
// had no obligation counterpart, so every such read reported a missing
|
|
395
|
+
// conversion for a recipe that was already built.
|
|
396
|
+
return target.arms.every((tarm) => source.arms.some((sarm) => representationKey(sarm.value) === representationKey(tarm.value) ||
|
|
397
|
+
narrowingReachesTarget(sarm.value, tarm.value) ||
|
|
398
|
+
narrowsToDescendantClass(sarm.value, tarm.value)));
|
|
399
|
+
};
|
|
400
|
+
/**
|
|
401
|
+
* Every tagged union reachable by selecting through nested sum arms.
|
|
402
|
+
*
|
|
403
|
+
* A nullable union is represented as an outer tagged union whose `present`
|
|
404
|
+
* arm can itself be a tagged union. Control flow may remove the two absence
|
|
405
|
+
* arms and then reorder the surviving inner union's arms, so the read target
|
|
406
|
+
* is a subset of the INNER union rather than of the published outer carrier.
|
|
407
|
+
* Keep the walk confined to sum nesting: records and collections do not
|
|
408
|
+
* become their contents when narrowed.
|
|
409
|
+
*/
|
|
410
|
+
const nestedTaggedUnionsOf = (source) => {
|
|
411
|
+
const found = new Map();
|
|
412
|
+
const queue = [source];
|
|
413
|
+
while (queue.length > 0) {
|
|
414
|
+
const one = queue.pop();
|
|
415
|
+
if (!one)
|
|
416
|
+
continue;
|
|
417
|
+
if (one.kind === 'optional') {
|
|
418
|
+
queue.push(one.payload);
|
|
419
|
+
continue;
|
|
420
|
+
}
|
|
421
|
+
if (one.kind !== 'tagged-union')
|
|
422
|
+
continue;
|
|
423
|
+
const key = representationKey(one);
|
|
424
|
+
if (found.has(key))
|
|
425
|
+
continue;
|
|
426
|
+
found.set(key, one);
|
|
427
|
+
queue.push(...one.arms.map((arm) => arm.value));
|
|
428
|
+
}
|
|
429
|
+
return [...found.values()];
|
|
430
|
+
};
|
|
431
|
+
/**
|
|
432
|
+
* Multi-arm narrowing targets `dropOneArmUnionsOf` cannot reach, found
|
|
433
|
+
* without enumerating a single subset: `target` is never invented here, it is
|
|
434
|
+
* always some OTHER representation `referencedRepresentations` already put in
|
|
435
|
+
* the plan -- an explicit `as`-cast's own asserted type, a declared return
|
|
436
|
+
* type, a parameter annotation, ... -- whose arms are a genuine subset of
|
|
437
|
+
* `source`'s. hono's `_getQueryParam(url, key, true) as string[] | undefined
|
|
438
|
+
* | Record<string, string[]>` (`utils/url.ts:314`) is the case: the cast
|
|
439
|
+
* narrows the callee's real 4-arm return union down to the 2 array-bearing
|
|
440
|
+
* arms, and the cast's own asserted type is what makes that 2-arm union a
|
|
441
|
+
* member of `referenced` in the first place -- this only has to notice it is
|
|
442
|
+
* already there, drawn one-for-one from `source`'s own arms.
|
|
443
|
+
*
|
|
444
|
+
* The cost this stays inside is `referenced.size` candidates examined once
|
|
445
|
+
* per source union, an arm-count-independent, program-bounded scan -- never
|
|
446
|
+
* the C(n,k) subsets a source union COULD narrow to, which is the
|
|
447
|
+
* combinatorial growth `dropOneArmUnionsOf`'s own doc comment stays clear of
|
|
448
|
+
* on purpose and this must too.
|
|
449
|
+
*/
|
|
450
|
+
const subsetNarrowingTargetsOf = (source, referenced) => {
|
|
451
|
+
// A class handle's descendant unions are drawn from `referenced` by the same
|
|
452
|
+
// one-scan rule the union branch below uses -- the target is never invented,
|
|
453
|
+
// it is a carrier the plan already contains. Disjoint from that branch: a
|
|
454
|
+
// carrier whose payload is a class-ref has no nested tagged union at all.
|
|
455
|
+
if (heldClassOf(source) !== null) {
|
|
456
|
+
return [...referenced.values()].filter((candidate) => narrowsToDescendantClassUnion(source, candidate));
|
|
457
|
+
}
|
|
458
|
+
if (source.kind === 'tagged-union' || source.kind === 'optional') {
|
|
459
|
+
const unions = nestedTaggedUnionsOf(source);
|
|
460
|
+
if (unions.length === 0)
|
|
461
|
+
return [];
|
|
462
|
+
return [...referenced.values()].filter((candidate) => {
|
|
463
|
+
// A BARE subset union is a candidate too, not only one that keeps the
|
|
464
|
+
// source's own absence tag. Presence and arm-narrowing are proven by
|
|
465
|
+
// separate guards and both proofs land on one read: mongodb's
|
|
466
|
+
// `formatSort` writes `if (sort == null) return` and then `if (typeof
|
|
467
|
+
// sort !== 'object') throw`, so the five reads after it are subsets with
|
|
468
|
+
// no optional wrapper left at all -- which this branch, matching only
|
|
469
|
+
// optional candidates, never offered. `targets/cpp/conversions.ts`'s
|
|
470
|
+
// `narrowing` already accepts the pairing (its `selected` stays optional
|
|
471
|
+
// only when the TARGET is); the recipe existed and was never asked for.
|
|
472
|
+
if (candidate.kind === 'tagged-union')
|
|
473
|
+
return unions.some((union) => isArmSubsetOf(union, candidate));
|
|
474
|
+
if (source.kind !== 'optional' || candidate.kind !== 'optional' || candidate.absence !== source.absence)
|
|
475
|
+
return false;
|
|
476
|
+
const payload = candidate.payload;
|
|
477
|
+
return payload.kind === 'tagged-union' && unions.some((union) => isArmSubsetOf(union, payload));
|
|
478
|
+
});
|
|
479
|
+
}
|
|
480
|
+
return [];
|
|
481
|
+
};
|
|
482
|
+
/**
|
|
483
|
+
* Every carrier that can widen into the one given, the mirror image of
|
|
484
|
+
* `narrowingStepsOf`.
|
|
485
|
+
*
|
|
486
|
+
* A tagged union's arms are exactly the values that can be stored as it --
|
|
487
|
+
* `gea::TaggedUnion::ofArm<Index>` is a real constructor for each one. An
|
|
488
|
+
* `optional` accepts two kinds of widening source: its bare payload, because
|
|
489
|
+
* `gea::Optional<T>` declares its own converting constructor from `T` with no
|
|
490
|
+
* union involved at all, and -- when the payload is itself a tagged union --
|
|
491
|
+
* that union's own arm values too, which pass through the payload's widening
|
|
492
|
+
* unchanged and then into the optional's.
|
|
493
|
+
*
|
|
494
|
+
* An arm still wearing its OWN optional widens too, into either shape of
|
|
495
|
+
* target: `a && a.b` keeps `a` -- still optional -- on the branch where `a`
|
|
496
|
+
* tested falsy, and the merge's own carrier can be the still-optional union
|
|
497
|
+
* (absence really can reach the merge, the same way it reaches `a`) or, for
|
|
498
|
+
* `a || b`/`a ?? b`'s truthy/present-kept branch, the bare union with no
|
|
499
|
+
* absence at all (the checker has already ruled absence out there). Both
|
|
500
|
+
* need the source's own presence read at the store, which is why
|
|
501
|
+
* `emit-narrowing.ts`'s widening store, not `gea::Optional`'s converting
|
|
502
|
+
* constructor, is what ends up performing it -- this only states that the
|
|
503
|
+
* pairing is a real, structural one and not a search that happens to fail.
|
|
504
|
+
*/
|
|
505
|
+
const optionalArmSourcesOf = (arms, absences) => arms.flatMap((arm) => absences.map((absence) => optionalOf(arm, absence))).filter((candidate) => candidate.kind === 'optional');
|
|
506
|
+
/**
|
|
507
|
+
* Every proper, PREFIX-shaped `function-value-dispatch` source a callable
|
|
508
|
+
* target can widen from -- structural candidates for `gea::CallableObject`'s
|
|
509
|
+
* prefix-dropping converting constructor (`targets/cpp/emit-narrowing.ts`'s
|
|
510
|
+
* `dropsUnboundParameters`, `gea_runtime.h`'s own `IsTypePrefix`-gated
|
|
511
|
+
* constructor). hono's own `Hono.getPath`: `this.getPath = (strict ?? true)
|
|
512
|
+
* ? (options.getPath ?? getPath) : getPathNoStrict` merges two
|
|
513
|
+
* `(request: Request) => string` values into a field declared
|
|
514
|
+
* `(request: Request, options?: {env?}) => string` -- a real value in the
|
|
515
|
+
* program is a callable with exactly the target's own LEADING run of
|
|
516
|
+
* parameters and nothing else.
|
|
517
|
+
*
|
|
518
|
+
* Derived purely from the target's own shape, the same discipline every
|
|
519
|
+
* other branch of this function follows: this is not a search over the
|
|
520
|
+
* plan's carriers, only every candidate the target's own arity admits, in
|
|
521
|
+
* order from zero parameters (`dropArguments`'s own case) up to one short of
|
|
522
|
+
* the full count. `buildConversionGraph`'s own intersection with the plan's
|
|
523
|
+
* referenced carriers is what decides whether any of them is a value the
|
|
524
|
+
* program actually holds -- exactly as it already does for every other
|
|
525
|
+
* branch here.
|
|
526
|
+
*
|
|
527
|
+
* Receiver-bearing and rest-taking callables are excluded: the runtime
|
|
528
|
+
* constructor's own proof is over a fixed `Arguments...` pack alone, so
|
|
529
|
+
* either one is not this shape (mirrors `dropsUnboundParameters`'s identical
|
|
530
|
+
* receiver exclusion).
|
|
531
|
+
*/
|
|
532
|
+
const callablePrefixSourcesOf = (target) => {
|
|
533
|
+
if ((target.kind !== 'function-value-dispatch' &&
|
|
534
|
+
target.kind !== 'function' &&
|
|
535
|
+
target.kind !== 'function-family' &&
|
|
536
|
+
target.kind !== 'function-value-family') ||
|
|
537
|
+
target.abi.receiver !== null ||
|
|
538
|
+
target.abi.restFrom !== null) {
|
|
539
|
+
return [];
|
|
540
|
+
}
|
|
541
|
+
const abi = target.abi;
|
|
542
|
+
const prefixes = [];
|
|
543
|
+
for (let length = 0; length < abi.parameters.length; length++) {
|
|
544
|
+
prefixes.push({
|
|
545
|
+
kind: 'function-value-dispatch',
|
|
546
|
+
abi: { parameters: abi.parameters.slice(0, length), result: abi.result, receiver: null, restFrom: null }
|
|
547
|
+
});
|
|
548
|
+
}
|
|
549
|
+
return prefixes;
|
|
550
|
+
};
|
|
551
|
+
/**
|
|
552
|
+
* Every zero-parameter `function-value-dispatch` source a callable target
|
|
553
|
+
* can widen from where its result is one ARM of the target's own tagged
|
|
554
|
+
* union result -- structural candidates for `gea_runtime.h`'s
|
|
555
|
+
* `ResultWidensIntoArm`-gated converting constructor
|
|
556
|
+
* (`targets/cpp/emit-narrowing.ts`'s `dropsAllParametersIntoResultArm`).
|
|
557
|
+
* hono's own `Context.notFound`: `this.#notFoundHandler ??=
|
|
558
|
+
* () => createResponseInstance()` merges a `() => Response` into a field
|
|
559
|
+
* declared `(c: Context) => Response | Promise<Response>` -- a real value in
|
|
560
|
+
* the program is a zero-parameter callable whose result is exactly the
|
|
561
|
+
* `Response` arm, never the union itself.
|
|
562
|
+
*
|
|
563
|
+
* Composes `callablePrefixSourcesOf`'s own zero-length case (arity alone)
|
|
564
|
+
* with one substitution neither that function nor `optionalArmSourcesOf`
|
|
565
|
+
* performs: the RESULT narrowed to a single arm rather than left at the
|
|
566
|
+
* target's own. Gated identically to `callablePrefixSourcesOf` -- no
|
|
567
|
+
* receiver, no rest -- plus the target actually declaring at least one
|
|
568
|
+
* parameter (a nullary target has no arity gap to fill this way at all,
|
|
569
|
+
* `dropsUnboundParameters`'s own case) and a tagged-union result to narrow
|
|
570
|
+
* into in the first place.
|
|
571
|
+
*/
|
|
572
|
+
const callableResultArmSourcesOf = (target) => {
|
|
573
|
+
if ((target.kind !== 'function-value-dispatch' &&
|
|
574
|
+
target.kind !== 'function' &&
|
|
575
|
+
target.kind !== 'function-family' &&
|
|
576
|
+
target.kind !== 'function-value-family') ||
|
|
577
|
+
target.abi.receiver !== null ||
|
|
578
|
+
target.abi.restFrom !== null ||
|
|
579
|
+
target.abi.parameters.length === 0 ||
|
|
580
|
+
target.abi.result.kind !== 'tagged-union') {
|
|
581
|
+
return [];
|
|
582
|
+
}
|
|
583
|
+
return target.abi.result.arms.map((arm) => ({
|
|
584
|
+
kind: 'function-value-dispatch',
|
|
585
|
+
abi: { parameters: [], result: arm.value, receiver: null, restFrom: null }
|
|
586
|
+
}));
|
|
587
|
+
};
|
|
588
|
+
const wideningSourcesOf = (target) => {
|
|
589
|
+
// These carriers encode T | null in their own empty state, without an
|
|
590
|
+
// optional wrapper. The backend must still license the actual store.
|
|
591
|
+
if (target.kind === 'native-handle' || (target.kind === 'class-ref' && target.ownership === 'shared-refcount')) {
|
|
592
|
+
return [{ kind: 'null' }];
|
|
593
|
+
}
|
|
594
|
+
const callablePrefixes = [...callablePrefixSourcesOf(target), ...callableResultArmSourcesOf(target)];
|
|
595
|
+
// A bare `Function` is the one dynamic carrier that itself promises
|
|
596
|
+
// callability. It can therefore be a structural source for an evaluated
|
|
597
|
+
// callable slot whose backend installs an ABI adapter. Keep the provenance
|
|
598
|
+
// exact: other dynamic reasons make no such source-level promise and reach
|
|
599
|
+
// a callable only through the generic checked dynamic materializer.
|
|
600
|
+
if (target.kind === 'function-value-dispatch') {
|
|
601
|
+
callablePrefixes.push({ kind: 'dynamic', reason: 'untyped-callable' });
|
|
602
|
+
}
|
|
603
|
+
if (callablePrefixes.length > 0)
|
|
604
|
+
return callablePrefixes;
|
|
605
|
+
if (target.kind === 'optional') {
|
|
606
|
+
// `gea::Optional<T>` itself declares a converting constructor from `T`, so
|
|
607
|
+
// the bare payload widens with no union involved at all -- the payload is
|
|
608
|
+
// always a widening source for its own optional, independent of whether
|
|
609
|
+
// the payload also happens to be a tagged union.
|
|
610
|
+
const payload = target.payload;
|
|
611
|
+
const arms = payload.kind === 'tagged-union' ? payload.arms.map((arm) => arm.value) : [];
|
|
612
|
+
// The target's own absence tag is the only one an arm's optional can wear
|
|
613
|
+
// here: an `&&` merge keeps `a`'s own optional unchanged, and `a`'s
|
|
614
|
+
// absence tag is exactly the merge's (`representation/optional.ts` never
|
|
615
|
+
// lets a carrier disagree with itself about which value means absent).
|
|
616
|
+
//
|
|
617
|
+
// The bare absence marker itself -- `{kind: target.absence}` -- is a
|
|
618
|
+
// source too, and a distinct one from the payload: a value whose own
|
|
619
|
+
// TYPE is exactly `undefined` (hono's `E['Bindings']` resolved for
|
|
620
|
+
// `BlankEnv`, which genuinely has no such field) stores as the optional's
|
|
621
|
+
// empty state with no payload conversion at all. `emit-narrowing.ts`'s
|
|
622
|
+
// `emptyOptionalText` already renders this (`written.kind === held.
|
|
623
|
+
// absence`); without offering the source here `registry.widening` is
|
|
624
|
+
// simply never asked, and a value that is honestly, statically absent
|
|
625
|
+
// refuses for a conversion the emitter could already perform.
|
|
626
|
+
// ...and every source the PAYLOAD itself widens from. The two rules
|
|
627
|
+
// already exist and simply did not compose: a callable target admits its
|
|
628
|
+
// own proper prefixes (`callablePrefixSourcesOf`), an optional target
|
|
629
|
+
// admits its own payload, and `((gl, v) => void)` written where
|
|
630
|
+
// `((gl, v, textures) => void) | undefined` is expected is both at once.
|
|
631
|
+
// three's `getSingularSetter` is 30 returns of exactly that shape --
|
|
632
|
+
// `setValueV1f( gl, v )` and `setValueT1( gl, v, textures )` returned from
|
|
633
|
+
// one `switch` whose fall-through makes the slot optional.
|
|
634
|
+
//
|
|
635
|
+
// The emitter renders it by constructing the payload EXPLICITLY
|
|
636
|
+
// (`convertedValueText`'s optional branch): C++ allows one user-defined
|
|
637
|
+
// conversion per implicit sequence, and `gea::CallableObject`'s
|
|
638
|
+
// prefix-dropping constructor followed by `gea::Optional<T>`'s converting
|
|
639
|
+
// constructor is two. Naming the payload type spends one of them
|
|
640
|
+
// explicitly, which is why offering this source here is safe rather than
|
|
641
|
+
// a claim the backend cannot honor.
|
|
642
|
+
const payloadSources = [
|
|
643
|
+
...callablePrefixSourcesOf(payload),
|
|
644
|
+
...callableResultArmSourcesOf(payload),
|
|
645
|
+
...(payload.kind === 'optional' || payload.kind === 'tagged-union' ? wideningSourcesOf(payload) : [])
|
|
646
|
+
];
|
|
647
|
+
return distinctByKey([{ kind: target.absence }, payload, ...arms, ...payloadSources, ...optionalArmSourcesOf(arms, [target.absence])]);
|
|
648
|
+
}
|
|
649
|
+
if (target.kind !== 'tagged-union')
|
|
650
|
+
return [];
|
|
651
|
+
// The bare mirror of the branch above: `||`/`??` prove presence before
|
|
652
|
+
// keeping the left side, so the merge's own carrier never needs an absence
|
|
653
|
+
// flag even though the kept operand's own carrier still has one. A bare
|
|
654
|
+
// target states no preference between the two absence spellings, so both
|
|
655
|
+
// are offered as real sources at the payload level.
|
|
656
|
+
return distinctByKey([
|
|
657
|
+
...target.arms.map((arm) => arm.value),
|
|
658
|
+
// Both-absence carriers group their present alternatives under a second
|
|
659
|
+
// sum. A bare value still reaches its exact leaf through that group;
|
|
660
|
+
// the installed materializer must prove and construct the entire path.
|
|
661
|
+
...target.arms.flatMap((arm) => arm.value.kind === 'optional' || arm.value.kind === 'tagged-union' ? wideningSourcesOf(arm.value) : []),
|
|
662
|
+
...optionalArmSourcesOf(target.arms.map((arm) => arm.value), ['null', 'undefined'])
|
|
663
|
+
]);
|
|
664
|
+
};
|
|
665
|
+
const distinctByKey = (representations) => {
|
|
666
|
+
const seen = new Map();
|
|
667
|
+
for (const representation of representations) {
|
|
668
|
+
const key = representationKey(representation);
|
|
669
|
+
if (!seen.has(key))
|
|
670
|
+
seen.set(key, representation);
|
|
671
|
+
}
|
|
672
|
+
return [...seen.values()];
|
|
673
|
+
};
|
|
674
|
+
/**
|
|
675
|
+
* Each distinct carrier once, paired with its key.
|
|
676
|
+
*
|
|
677
|
+
* The pair-wise loops below are quadratic by nature -- "which of these can
|
|
678
|
+
* convert into which" is a question about pairs -- so what decides whether they
|
|
679
|
+
* are affordable is the cost of one iteration and the size of `n`. Both were
|
|
680
|
+
* wrong when read straight off `plan.selected`:
|
|
681
|
+
*
|
|
682
|
+
* - `plan.selected` is keyed by RESULT, not by carrier. A program publishes
|
|
683
|
+
* one entry per SSA result, so `ios-metal-world-game` has 95,670 of them
|
|
684
|
+
* naming vastly fewer distinct carriers. Conversions are a fact about
|
|
685
|
+
* carriers, so every duplicate is an iteration that re-derives an answer
|
|
686
|
+
* already in `nodes`.
|
|
687
|
+
* - `representationKey` is a recursive string build over the whole carrier
|
|
688
|
+
* shape, with no memo. Calling it inside the inner loop -- twice per pair,
|
|
689
|
+
* once for an invariant target -- makes each iteration cost the depth of
|
|
690
|
+
* the representation rather than a comparison.
|
|
691
|
+
*
|
|
692
|
+
* Together those turned one merged loop into ~15x the corpus's whole compile
|
|
693
|
+
* time. Keying once up front makes the inner comparison a string equality and
|
|
694
|
+
* the outer bound the number of distinct carriers, which is what the question
|
|
695
|
+
* was ever about.
|
|
696
|
+
*/
|
|
697
|
+
const keyedDistinct = (representations) => {
|
|
698
|
+
const seen = new Map();
|
|
699
|
+
for (const representation of representations) {
|
|
700
|
+
const key = representationKey(representation);
|
|
701
|
+
if (!seen.has(key))
|
|
702
|
+
seen.set(key, representation);
|
|
703
|
+
}
|
|
704
|
+
return [...seen].map(([key, representation]) => [key, representation]);
|
|
705
|
+
};
|
|
706
|
+
/**
|
|
707
|
+
* A callable convention's own carriers -- every one of a conversion's
|
|
708
|
+
* candidate sources or targets, the same way any other representation is.
|
|
709
|
+
*/
|
|
710
|
+
const abiRepresentations = (abi) => [
|
|
711
|
+
...abi.parameters.map((parameter) => parameter.value),
|
|
712
|
+
abi.result,
|
|
713
|
+
...(abi.receiver ? [abi.receiver] : [])
|
|
714
|
+
];
|
|
715
|
+
/**
|
|
716
|
+
* The ABI identity for carriers that are physically a CallableObject. A
|
|
717
|
+
* declaration/family token changes how a callable was authenticated, not the
|
|
718
|
+
* frame it stores, so an exact frame can enter an evaluated-dispatch slot
|
|
719
|
+
* without an adapter. Keep constructors out: their C++ object has a distinct
|
|
720
|
+
* call/construct protocol even when one call ABI happens to look alike.
|
|
721
|
+
*/
|
|
722
|
+
const callableObjectAbiKey = (representation) => {
|
|
723
|
+
switch (representation.kind) {
|
|
724
|
+
case 'function':
|
|
725
|
+
case 'function-family':
|
|
726
|
+
case 'function-value-family':
|
|
727
|
+
case 'function-value-dispatch':
|
|
728
|
+
return abiKey(representation.abi);
|
|
729
|
+
default:
|
|
730
|
+
return null;
|
|
731
|
+
}
|
|
732
|
+
};
|
|
733
|
+
/**
|
|
734
|
+
* The `Representation`s nested one level inside another -- an ABI's
|
|
735
|
+
* parameters/result/receiver, a record's fields, a container's element, and
|
|
736
|
+
* so on. `class-ref`/`native-record-ref` deliberately contribute nothing:
|
|
737
|
+
* both name their layout by `shapeId` rather than nesting it, which is what
|
|
738
|
+
* keeps a self-referential named type finite, and closing over a name would
|
|
739
|
+
* need the deriver this module -- generic representation algebra, with no
|
|
740
|
+
* knowledge of the structural table -- does not have.
|
|
741
|
+
*
|
|
742
|
+
* This is what lets `referencedRepresentations` below see an ABI parameter
|
|
743
|
+
* type or a declared field type as a conversion target even when no OTHER
|
|
744
|
+
* result in the program happens to be selected as that exact carrier: see
|
|
745
|
+
* that function's own comment for why a carrier reachable only through
|
|
746
|
+
* nesting still needs a node.
|
|
747
|
+
*/
|
|
748
|
+
const nestedRepresentationsOf = (representation) => {
|
|
749
|
+
switch (representation.kind) {
|
|
750
|
+
case 'native-handle':
|
|
751
|
+
return [
|
|
752
|
+
...(representation.call ? abiRepresentations(representation.call) : []),
|
|
753
|
+
...(representation.construct ? abiRepresentations(representation.construct) : [])
|
|
754
|
+
];
|
|
755
|
+
case 'record':
|
|
756
|
+
return representation.fields.map((field) => field.value);
|
|
757
|
+
case 'record-with-index':
|
|
758
|
+
return [...representation.fields.map((field) => field.value), ...representation.indexes.map((index) => index.value)];
|
|
759
|
+
case 'proxy-object':
|
|
760
|
+
return [representation.target, representation.handler];
|
|
761
|
+
case 'borrowed-ref':
|
|
762
|
+
return [representation.referent];
|
|
763
|
+
case 'array-object':
|
|
764
|
+
return [representation.element, ...(representation.extension ?? []).map((field) => field.value)];
|
|
765
|
+
case 'dense-buffer':
|
|
766
|
+
case 'native-sequence':
|
|
767
|
+
case 'iterator':
|
|
768
|
+
return [representation.element];
|
|
769
|
+
case 'promise':
|
|
770
|
+
case 'dictionary':
|
|
771
|
+
return [representation.value];
|
|
772
|
+
case 'keyed-collection':
|
|
773
|
+
return representation.value ? [representation.key, representation.value] : [representation.key];
|
|
774
|
+
case 'function':
|
|
775
|
+
case 'function-family':
|
|
776
|
+
case 'constructor-family':
|
|
777
|
+
case 'constructor-value-dispatch':
|
|
778
|
+
case 'function-value-family':
|
|
779
|
+
case 'function-value-dispatch':
|
|
780
|
+
return abiRepresentations(representation.abi);
|
|
781
|
+
case 'function-and-constructor':
|
|
782
|
+
return [...abiRepresentations(representation.call), ...abiRepresentations(representation.construct)];
|
|
783
|
+
case 'optional':
|
|
784
|
+
return [representation.payload];
|
|
785
|
+
case 'tagged-union':
|
|
786
|
+
return representation.arms.map((arm) => arm.value);
|
|
787
|
+
default:
|
|
788
|
+
return [];
|
|
789
|
+
}
|
|
790
|
+
};
|
|
791
|
+
/**
|
|
792
|
+
* Every representation the plan's own selected carriers reference, directly
|
|
793
|
+
* or through nesting -- the closure `buildConversionGraph`'s four minting
|
|
794
|
+
* loops walk, in place of `plan.selected.values()` alone.
|
|
795
|
+
*
|
|
796
|
+
* A callable's declared parameter type, a record's declared field type, an
|
|
797
|
+
* array's element type -- none of these is necessarily itself the carrier
|
|
798
|
+
* some OTHER result in the program was independently selected to hold. A
|
|
799
|
+
* program whose only dynamic value is a caught `error` passed to `String`
|
|
800
|
+
* has no binding anywhere typed `optional(dynamic,undefined)` (`String`'s
|
|
801
|
+
* own `(value?: any)` parameter) -- so `plan.selected.values()` alone never
|
|
802
|
+
* visits that carrier, `buildConversionGraph` never asks the registry
|
|
803
|
+
* whether a dynamic value widens into it, and a conversion the registry
|
|
804
|
+
* (`targets/cpp/conversions.ts`'s `widening`) already proves -- the same
|
|
805
|
+
* `gea::Optional<T>` converting-constructor case `emit-narrowing.ts`'s
|
|
806
|
+
* `convertedValueText` renders at the call site -- reads back as "no
|
|
807
|
+
* conversion node" purely because nothing ever minted one, not because the
|
|
808
|
+
* backend cannot spell it. `preflight/invocation-arguments.ts`,
|
|
809
|
+
* `property-value.ts`, and `array-literal-elements.ts` all check a target
|
|
810
|
+
* exactly like this -- an ABI parameter, a declared field, an array element
|
|
811
|
+
* -- so all three need this closure to ever see a real answer instead of a
|
|
812
|
+
* permanent false "missing".
|
|
813
|
+
*
|
|
814
|
+
* Finite by construction: `nestedRepresentationsOf` never descends through
|
|
815
|
+
* `class-ref`/`native-record-ref` (both name their layout by `shapeId`
|
|
816
|
+
* rather than nesting it), so a self-referential declared type cannot loop
|
|
817
|
+
* here the same way it cannot loop at `representationKey`.
|
|
818
|
+
*/
|
|
819
|
+
const referencedRepresentations = (plan, constants) => {
|
|
820
|
+
const known = new Map();
|
|
821
|
+
const queue = [...plan.selected.values(), ...constants];
|
|
822
|
+
while (queue.length > 0) {
|
|
823
|
+
const representation = queue.pop();
|
|
824
|
+
if (!representation)
|
|
825
|
+
continue;
|
|
826
|
+
const key = representationKey(representation);
|
|
827
|
+
if (known.has(key))
|
|
828
|
+
continue;
|
|
829
|
+
known.set(key, representation);
|
|
830
|
+
queue.push(...nestedRepresentationsOf(representation));
|
|
831
|
+
}
|
|
832
|
+
return known;
|
|
833
|
+
};
|
|
834
|
+
export const buildConversionGraph = (plan, registry = emptyConversionRegistry, constants = []) => {
|
|
835
|
+
const context = createConversionDerivationContext(registry);
|
|
836
|
+
const nodes = new Map();
|
|
837
|
+
const referenced = referencedRepresentations(plan, constants);
|
|
838
|
+
const genericDynamicSource = { kind: 'dynamic', reason: 'declared-any-never-narrowed' };
|
|
839
|
+
const genericDynamicKey = representationKey(genericDynamicSource);
|
|
840
|
+
for (const representation of referenced.values()) {
|
|
841
|
+
const id = representationKey(representation);
|
|
842
|
+
if (nodes.has(id))
|
|
843
|
+
continue;
|
|
844
|
+
nodes.set(id, {
|
|
845
|
+
id,
|
|
846
|
+
// Conversion always starts from the dynamic carrier: it is the only
|
|
847
|
+
// source that needs classifying at all. A statically typed value already
|
|
848
|
+
// has its carrier, so there is nothing to decide.
|
|
849
|
+
source: genericDynamicSource,
|
|
850
|
+
target: representation,
|
|
851
|
+
capability: deriveConversionCapability(representation, context)
|
|
852
|
+
});
|
|
853
|
+
}
|
|
854
|
+
// Narrowing reads, the one conversion that does not start from the dynamic
|
|
855
|
+
// carrier.
|
|
856
|
+
//
|
|
857
|
+
// A cell holding `Optional<string>` read as `string` inside `if (tag)` is not
|
|
858
|
+
// a classification -- the checker already proved presence, and re-deciding it
|
|
859
|
+
// here would be a second authority answering a settled question. What it is,
|
|
860
|
+
// is a *load*: the payload out of the cell, or the live arm out of a union.
|
|
861
|
+
// That load still needs a recipe, because a backend that cannot spell one
|
|
862
|
+
// would otherwise certify and then refuse at emission, so it is minted as a
|
|
863
|
+
// node like any other and the registry is asked whether it is installed.
|
|
864
|
+
//
|
|
865
|
+
// Only referenced targets get a node -- the plan's own selected carriers,
|
|
866
|
+
// plus every carrier reachable by nesting from one (`referencedRepresentations`).
|
|
867
|
+
// A carrier the program does not contain, referenced or not, is one nothing
|
|
868
|
+
// can narrow to, and minting a node for it would claim a capability against
|
|
869
|
+
// a carrier the program never touches.
|
|
870
|
+
const referencedKeys = new Set(referenced.keys());
|
|
871
|
+
for (const [sourceKey, representation] of referenced) {
|
|
872
|
+
// `subsetNarrowingTargetsOf` draws every candidate straight from
|
|
873
|
+
// `referenced`, so each one is trivially already a `referencedKeys`
|
|
874
|
+
// member -- the filter below stays uniform across both sources rather
|
|
875
|
+
// than special-casing the one that cannot fail it.
|
|
876
|
+
for (const target of [...narrowingClosureOf(representation), ...subsetNarrowingTargetsOf(representation, referenced)]) {
|
|
877
|
+
const targetKey = representationKey(target);
|
|
878
|
+
if (!referencedKeys.has(targetKey))
|
|
879
|
+
continue;
|
|
880
|
+
const id = `${sourceKey}->${targetKey}`;
|
|
881
|
+
if (nodes.has(id))
|
|
882
|
+
continue;
|
|
883
|
+
const installed = registry.narrowing(representation, target);
|
|
884
|
+
// The same order `conversion/nodes.ts`'s `capabilityOf` asks in: an
|
|
885
|
+
// installed atom, else the registry's static recipe, else never. A
|
|
886
|
+
// `never` minted here is what `nodeFor` hands back for the pair, so a
|
|
887
|
+
// pair the static recipe answers must be answered here too or the
|
|
888
|
+
// eager graph would refuse what a late question would allow.
|
|
889
|
+
const recipe = installed ? null : registry.staticRecipe(representation, target);
|
|
890
|
+
nodes.set(id, {
|
|
891
|
+
id,
|
|
892
|
+
source: representation,
|
|
893
|
+
target,
|
|
894
|
+
capability: installed
|
|
895
|
+
? narrowingCapabilityFor(representation, target, installed)
|
|
896
|
+
: recipe
|
|
897
|
+
? { kind: 'static', materializer: recipe }
|
|
898
|
+
: { kind: 'never', reason: `no runtime narrowing is installed from ${sourceKey} to ${targetKey}` }
|
|
899
|
+
});
|
|
900
|
+
}
|
|
901
|
+
}
|
|
902
|
+
// An absent array proven present and then read as the interface that
|
|
903
|
+
// extends it -- tsc's `createNodeArray(elements?: readonly T[])` after
|
|
904
|
+
// `isNodeArray(elements)` -- lands on a referenced `array-object` whose only
|
|
905
|
+
// difference from the payload is the extension, one C++ type either way.
|
|
906
|
+
// Proposed here because neither closure above reaches it: the payload is
|
|
907
|
+
// not that carrier, and the target is not a subset of any sum.
|
|
908
|
+
const extendedArrayTargets = keyedDistinct(referenced.values()).filter(([, one]) => one.kind === 'array-object' && one.extension !== null);
|
|
909
|
+
for (const [sourceKey, source] of referenced) {
|
|
910
|
+
if (source.kind !== 'optional' || source.payload.kind !== 'array-object')
|
|
911
|
+
continue;
|
|
912
|
+
const payload = source.payload;
|
|
913
|
+
for (const [targetKey, target] of extendedArrayTargets) {
|
|
914
|
+
if (target.kind !== 'array-object' || target.ownership !== payload.ownership)
|
|
915
|
+
continue;
|
|
916
|
+
if (representationKey(target.element) !== representationKey(payload.element))
|
|
917
|
+
continue;
|
|
918
|
+
if (arrayExtensionKey(target.extension) === arrayExtensionKey(payload.extension))
|
|
919
|
+
continue;
|
|
920
|
+
const id = `${sourceKey}->${targetKey}`;
|
|
921
|
+
if (nodes.has(id))
|
|
922
|
+
continue;
|
|
923
|
+
const installed = registry.narrowing(source, target);
|
|
924
|
+
if (!installed)
|
|
925
|
+
continue;
|
|
926
|
+
nodes.set(id, {
|
|
927
|
+
id,
|
|
928
|
+
source,
|
|
929
|
+
target,
|
|
930
|
+
capability: { kind: 'atom', classifier: installed.classifier, materializer: installed.materializer }
|
|
931
|
+
});
|
|
932
|
+
}
|
|
933
|
+
}
|
|
934
|
+
// A sum arm holding a base-class Ref can narrow directly to a referenced
|
|
935
|
+
// descendant after `instanceof`. Descendants cannot be enumerated from the
|
|
936
|
+
// source carrier alone, so pair sums with the program's concrete class refs
|
|
937
|
+
// just as the class-to-class loop below does.
|
|
938
|
+
const descendantClassTargets = keyedDistinct(referenced.values()).filter(([, one]) => one.kind === 'class-ref');
|
|
939
|
+
for (const [sourceKey, source] of referenced) {
|
|
940
|
+
if (source.kind !== 'optional' && source.kind !== 'tagged-union')
|
|
941
|
+
continue;
|
|
942
|
+
for (const [targetKey, target] of descendantClassTargets) {
|
|
943
|
+
if (!narrowingReachesTarget(source, target))
|
|
944
|
+
continue;
|
|
945
|
+
const id = `${sourceKey}->${targetKey}`;
|
|
946
|
+
if (nodes.has(id))
|
|
947
|
+
continue;
|
|
948
|
+
const installed = registry.narrowing(source, target);
|
|
949
|
+
if (!installed)
|
|
950
|
+
continue;
|
|
951
|
+
nodes.set(id, {
|
|
952
|
+
id,
|
|
953
|
+
source,
|
|
954
|
+
target,
|
|
955
|
+
capability: { kind: 'atom', classifier: installed.classifier, materializer: installed.materializer }
|
|
956
|
+
});
|
|
957
|
+
}
|
|
958
|
+
}
|
|
959
|
+
// Widening stores, the mirror of the narrowing read above: `const x: boolean
|
|
960
|
+
// | number = someBoolean` puts a plain `scalar(boolean)` where a
|
|
961
|
+
// `TaggedUnion` is declared, and a control-flow merge does the identical
|
|
962
|
+
// thing when its two branches arrive with different carriers and the plan
|
|
963
|
+
// gives the merge itself the union. Gated strictly on `registry.widening`
|
|
964
|
+
// returning a real pair -- unlike the narrowing loop above, which always
|
|
965
|
+
// mints a node -- because an unregistered widening has no backend recipe at
|
|
966
|
+
// all, not merely an unproven one; minting it anyway would let a program
|
|
967
|
+
// certify on a backend that cannot spell the conversion it just claimed.
|
|
968
|
+
for (const [targetKey, target] of referenced) {
|
|
969
|
+
for (const source of wideningSourcesOf(target)) {
|
|
970
|
+
const sourceKey = representationKey(source);
|
|
971
|
+
if (!referencedKeys.has(sourceKey))
|
|
972
|
+
continue;
|
|
973
|
+
const id = `${sourceKey}->${targetKey}`;
|
|
974
|
+
if (nodes.has(id))
|
|
975
|
+
continue;
|
|
976
|
+
const installed = registry.widening(source, target);
|
|
977
|
+
if (!installed)
|
|
978
|
+
continue;
|
|
979
|
+
nodes.set(id, {
|
|
980
|
+
id,
|
|
981
|
+
source,
|
|
982
|
+
target,
|
|
983
|
+
capability: { kind: 'atom', classifier: installed.classifier, materializer: installed.materializer }
|
|
984
|
+
});
|
|
985
|
+
}
|
|
986
|
+
}
|
|
987
|
+
// A sum source is not derivable from a sum target: the target describes its
|
|
988
|
+
// own alternatives, while a source may keep an absence wrapper or a nested
|
|
989
|
+
// tag around an otherwise matching value. Ask the runtime only for those
|
|
990
|
+
// explicit sum-to-sum pairs. `nativeSumConversion` is deliberately stricter
|
|
991
|
+
// than a structural fallback: every live source alternative must reach one
|
|
992
|
+
// exact tag (or a proven class-base tag), so this never erases an array
|
|
993
|
+
// element shape, an opaque native handle, or an unmatched scalar.
|
|
994
|
+
const sumCarriers = keyedDistinct(referenced.values()).filter(([, one]) => one.kind === 'optional' || one.kind === 'tagged-union');
|
|
995
|
+
for (const [targetKey, target] of sumCarriers) {
|
|
996
|
+
for (const [sourceKey, source] of sumCarriers) {
|
|
997
|
+
if (sourceKey === targetKey)
|
|
998
|
+
continue;
|
|
999
|
+
const id = `${sourceKey}->${targetKey}`;
|
|
1000
|
+
if (nodes.has(id))
|
|
1001
|
+
continue;
|
|
1002
|
+
const installed = registry.widening(source, target);
|
|
1003
|
+
if (!installed)
|
|
1004
|
+
continue;
|
|
1005
|
+
nodes.set(id, {
|
|
1006
|
+
id,
|
|
1007
|
+
source,
|
|
1008
|
+
target,
|
|
1009
|
+
capability: { kind: 'atom', classifier: installed.classifier, materializer: installed.materializer }
|
|
1010
|
+
});
|
|
1011
|
+
}
|
|
1012
|
+
}
|
|
1013
|
+
// Function declarations and closed families retain authentication metadata
|
|
1014
|
+
// that an evaluated dispatch does not carry, but all four carriers use the
|
|
1015
|
+
// same CallableObject when their ABI keys match exactly. Index candidates
|
|
1016
|
+
// by that semantic ABI key rather than scanning every callable pair: no
|
|
1017
|
+
// parameter or result adaptation is licensed here.
|
|
1018
|
+
const callableSourcesByAbi = new Map();
|
|
1019
|
+
for (const [sourceKey, source] of keyedDistinct(referenced.values())) {
|
|
1020
|
+
const abi = callableObjectAbiKey(source);
|
|
1021
|
+
if (abi === null)
|
|
1022
|
+
continue;
|
|
1023
|
+
const members = callableSourcesByAbi.get(abi);
|
|
1024
|
+
if (members)
|
|
1025
|
+
members.push([sourceKey, source]);
|
|
1026
|
+
else
|
|
1027
|
+
callableSourcesByAbi.set(abi, [[sourceKey, source]]);
|
|
1028
|
+
}
|
|
1029
|
+
for (const [targetKey, target] of keyedDistinct(referenced.values())) {
|
|
1030
|
+
if (target.kind !== 'function-value-dispatch')
|
|
1031
|
+
continue;
|
|
1032
|
+
for (const [sourceKey, source] of callableSourcesByAbi.get(abiKey(target.abi)) ?? []) {
|
|
1033
|
+
if (sourceKey === targetKey)
|
|
1034
|
+
continue;
|
|
1035
|
+
const id = `${sourceKey}->${targetKey}`;
|
|
1036
|
+
if (nodes.has(id))
|
|
1037
|
+
continue;
|
|
1038
|
+
const installed = registry.widening(source, target);
|
|
1039
|
+
if (!installed)
|
|
1040
|
+
continue;
|
|
1041
|
+
nodes.set(id, {
|
|
1042
|
+
id,
|
|
1043
|
+
source,
|
|
1044
|
+
target,
|
|
1045
|
+
capability: { kind: 'atom', classifier: installed.classifier, materializer: installed.materializer }
|
|
1046
|
+
});
|
|
1047
|
+
}
|
|
1048
|
+
}
|
|
1049
|
+
// Boxing into `dynamic`: the one widening target `wideningSourcesOf` cannot
|
|
1050
|
+
// enumerate structurally. Everywhere else the function reads valid sources
|
|
1051
|
+
// straight off `target`'s own shape -- a tagged union's fixed arm list, an
|
|
1052
|
+
// optional's fixed payload -- but "everything this backend can box" is a
|
|
1053
|
+
// fact about each SOURCE's own kind, not something `target: { kind:
|
|
1054
|
+
// 'dynamic' }` states. So this asks every selected representation once,
|
|
1055
|
+
// gated the identical strict way widening already is: only a real backend
|
|
1056
|
+
// recipe (`registry.widening` recognizing the source's kind) mints a node.
|
|
1057
|
+
//
|
|
1058
|
+
// Enumerated from `referenced`, not from `plan.selected`, and this was the
|
|
1059
|
+
// one loop here that read the plan's TOP LEVEL only. A carrier that appears
|
|
1060
|
+
// solely NESTED inside another -- an ABI's result is the measured case: a
|
|
1061
|
+
// trap declared `get(...): unknown` puts `dynamic(declared-any-never-
|
|
1062
|
+
// narrowed)` in the callable's convention and nowhere else -- was never a
|
|
1063
|
+
// target, so `return <number>` into it refused for a capability the registry
|
|
1064
|
+
// was ready to install. Every sibling loop in this function already reads
|
|
1065
|
+
// `referenced` for exactly this reason.
|
|
1066
|
+
const referencedKeyed = keyedDistinct(referenced.values());
|
|
1067
|
+
const dynamicTargets = referencedKeyed.filter(([, target]) => target.kind === 'dynamic');
|
|
1068
|
+
for (const [targetKey, target] of dynamicTargets) {
|
|
1069
|
+
for (const [sourceKey, source] of referencedKeyed) {
|
|
1070
|
+
if (sourceKey === targetKey)
|
|
1071
|
+
continue;
|
|
1072
|
+
const id = `${sourceKey}->${targetKey}`;
|
|
1073
|
+
if (nodes.has(id))
|
|
1074
|
+
continue;
|
|
1075
|
+
const installed = registry.widening(source, target);
|
|
1076
|
+
if (!installed)
|
|
1077
|
+
continue;
|
|
1078
|
+
nodes.set(id, {
|
|
1079
|
+
id,
|
|
1080
|
+
source,
|
|
1081
|
+
target,
|
|
1082
|
+
capability: { kind: 'atom', classifier: installed.classifier, materializer: installed.materializer }
|
|
1083
|
+
});
|
|
1084
|
+
}
|
|
1085
|
+
}
|
|
1086
|
+
// Conversion into a function IDENTITY: its own loop for the same reason the
|
|
1087
|
+
// boxing loop above has one. `callable-identity` states no ABI -- that is
|
|
1088
|
+
// the whole point of the carrier -- so it cannot name its own sources the
|
|
1089
|
+
// way `function-value-dispatch` names them by matching ABI key; "every
|
|
1090
|
+
// carrier this backend spells as a CallableObject" is a fact about each
|
|
1091
|
+
// SOURCE. `stackCrawlMark || assertIsDefined` (tsc's `debug.ts`, and the
|
|
1092
|
+
// largest single family in its self-compile) is the shape: the merge target
|
|
1093
|
+
// is the identity and the right arm is an ordinary concrete function.
|
|
1094
|
+
const identityTargets = referencedKeyed.filter(([, target]) => target.kind === 'callable-identity');
|
|
1095
|
+
for (const [targetKey, target] of identityTargets) {
|
|
1096
|
+
for (const [sourceKey, source] of referencedKeyed) {
|
|
1097
|
+
if (sourceKey === targetKey)
|
|
1098
|
+
continue;
|
|
1099
|
+
const id = `${sourceKey}->${targetKey}`;
|
|
1100
|
+
if (nodes.has(id))
|
|
1101
|
+
continue;
|
|
1102
|
+
const installed = registry.widening(source, target);
|
|
1103
|
+
if (!installed)
|
|
1104
|
+
continue;
|
|
1105
|
+
nodes.set(id, {
|
|
1106
|
+
id,
|
|
1107
|
+
source,
|
|
1108
|
+
target,
|
|
1109
|
+
capability: { kind: 'atom', classifier: installed.classifier, materializer: installed.materializer }
|
|
1110
|
+
});
|
|
1111
|
+
}
|
|
1112
|
+
}
|
|
1113
|
+
// Class upcasts: a derived class-ref stored where a base class-ref is
|
|
1114
|
+
// declared. Its own loop for the same reason the boxing loop above has one
|
|
1115
|
+
// -- `wideningSourcesOf` reads valid sources off the TARGET's own shape, and
|
|
1116
|
+
// `class-ref(MongoError)` states nothing about which classes descend from
|
|
1117
|
+
// it; that is a fact about each SOURCE. So this asks every referenced pair
|
|
1118
|
+
// once and lets the registry's own heritage answer decide, gated the
|
|
1119
|
+
// identical strict way every widening is.
|
|
1120
|
+
//
|
|
1121
|
+
// `previousOperationError ?? new MongoRuntimeError(...)` (mongodb's
|
|
1122
|
+
// `execute_operation.ts`) is the shape: TypeScript reduces the merge to the
|
|
1123
|
+
// base `MongoError`, the freshly constructed arm carries the derived class,
|
|
1124
|
+
// and without this loop the two never meet and the merge refuses.
|
|
1125
|
+
const classRefs = keyedDistinct(referenced.values()).filter(([, one]) => one.kind === 'class-ref');
|
|
1126
|
+
for (const [targetKey, target] of classRefs) {
|
|
1127
|
+
for (const [sourceKey, source] of classRefs) {
|
|
1128
|
+
if (sourceKey === targetKey)
|
|
1129
|
+
continue;
|
|
1130
|
+
const id = `${sourceKey}->${targetKey}`;
|
|
1131
|
+
if (nodes.has(id))
|
|
1132
|
+
continue;
|
|
1133
|
+
// Both directions, from one enumeration. Upcast (a derived class stored
|
|
1134
|
+
// where a base is declared) is a widening; DOWNCAST -- a base-declared
|
|
1135
|
+
// handle read at a descendant, which is what `instanceof` narrows -- is
|
|
1136
|
+
// a narrowing, and it needs exactly the same pair enumeration for
|
|
1137
|
+
// exactly the same reason the comment above gives: which classes descend
|
|
1138
|
+
// from `class-ref(Object3D)` is a fact about each other class, not
|
|
1139
|
+
// something the carrier states. Asking only `widening` here left
|
|
1140
|
+
// `if ( part instanceof Mesh )`'s own reads with no node at all.
|
|
1141
|
+
const installed = registry.widening(source, target) ?? registry.narrowing(source, target);
|
|
1142
|
+
if (!installed)
|
|
1143
|
+
continue;
|
|
1144
|
+
nodes.set(id, {
|
|
1145
|
+
id,
|
|
1146
|
+
source,
|
|
1147
|
+
target,
|
|
1148
|
+
capability: { kind: 'atom', classifier: installed.classifier, materializer: installed.materializer }
|
|
1149
|
+
});
|
|
1150
|
+
}
|
|
1151
|
+
}
|
|
1152
|
+
// The constructor-side mirror: a derived class's constructor stored where a
|
|
1153
|
+
// family naming it is declared. A target family lists its members but not
|
|
1154
|
+
// which referenced single-class families are among them, so the pairs are
|
|
1155
|
+
// composed here and the registry decides, like the class-ref loop above.
|
|
1156
|
+
const constructorFamilies = keyedDistinct(referenced.values()).filter(([, one]) => one.kind === 'constructor-family');
|
|
1157
|
+
for (const [targetKey, target] of constructorFamilies) {
|
|
1158
|
+
if (target.kind !== 'constructor-family' || target.members.length < 2)
|
|
1159
|
+
continue;
|
|
1160
|
+
for (const [sourceKey, source] of constructorFamilies) {
|
|
1161
|
+
if (sourceKey === targetKey || source.kind !== 'constructor-family' || source.members.length !== 1)
|
|
1162
|
+
continue;
|
|
1163
|
+
if (!target.members.includes(source.members[0]))
|
|
1164
|
+
continue;
|
|
1165
|
+
const id = `${sourceKey}->${targetKey}`;
|
|
1166
|
+
if (nodes.has(id))
|
|
1167
|
+
continue;
|
|
1168
|
+
const installed = registry.widening(source, target);
|
|
1169
|
+
if (!installed)
|
|
1170
|
+
continue;
|
|
1171
|
+
nodes.set(id, {
|
|
1172
|
+
id,
|
|
1173
|
+
source,
|
|
1174
|
+
target,
|
|
1175
|
+
capability: { kind: 'atom', classifier: installed.classifier, materializer: installed.materializer }
|
|
1176
|
+
});
|
|
1177
|
+
}
|
|
1178
|
+
}
|
|
1179
|
+
// The same class upcast when the declared destination keeps absence or
|
|
1180
|
+
// another union arm around the base class. The target alone cannot enumerate
|
|
1181
|
+
// its derived sources, so compose the pair here from the same referenced
|
|
1182
|
+
// class set as the direct upcast loop above and let the backend registry
|
|
1183
|
+
// decide whether it has one unambiguous arm to construct.
|
|
1184
|
+
const classSumTargets = keyedDistinct(referenced.values()).filter(([, one]) => one.kind === 'optional' || one.kind === 'tagged-union');
|
|
1185
|
+
for (const [targetKey, target] of classSumTargets) {
|
|
1186
|
+
for (const [sourceKey, source] of classRefs) {
|
|
1187
|
+
const id = `${sourceKey}->${targetKey}`;
|
|
1188
|
+
if (nodes.has(id))
|
|
1189
|
+
continue;
|
|
1190
|
+
const installed = registry.widening(source, target);
|
|
1191
|
+
if (!installed)
|
|
1192
|
+
continue;
|
|
1193
|
+
nodes.set(id, {
|
|
1194
|
+
id,
|
|
1195
|
+
source,
|
|
1196
|
+
target,
|
|
1197
|
+
capability: { kind: 'atom', classifier: installed.classifier, materializer: installed.materializer }
|
|
1198
|
+
});
|
|
1199
|
+
}
|
|
1200
|
+
}
|
|
1201
|
+
// A choice among generic functions (`generic-function-set`, model.ts): a
|
|
1202
|
+
// member's own name -- read as the closed callable its one instantiation
|
|
1203
|
+
// gave its cell -- into the one-member set it denotes, and a set into every
|
|
1204
|
+
// superset a merge or a store widens it into. Neither closure above knows
|
|
1205
|
+
// the kind, and the registry answers both pairs (`conversions.ts`'s
|
|
1206
|
+
// `genericFunctionSetPair`), so they are proposed here explicitly.
|
|
1207
|
+
const genericFunctionSets = keyedDistinct(referenced.values()).filter(([, one]) => one.kind === 'generic-function-set');
|
|
1208
|
+
for (const [targetKey, target] of genericFunctionSets) {
|
|
1209
|
+
if (target.kind !== 'generic-function-set')
|
|
1210
|
+
continue;
|
|
1211
|
+
for (const [sourceKey, source] of referenced) {
|
|
1212
|
+
if (sourceKey === targetKey)
|
|
1213
|
+
continue;
|
|
1214
|
+
const widens = source.kind === 'generic-function-set'
|
|
1215
|
+
? source.members.every((member) => target.members.includes(member))
|
|
1216
|
+
: (source.kind === 'function' ||
|
|
1217
|
+
source.kind === 'function-family' ||
|
|
1218
|
+
source.kind === 'function-value-family' ||
|
|
1219
|
+
source.kind === 'function-value-dispatch') &&
|
|
1220
|
+
target.members.length === 1;
|
|
1221
|
+
if (!widens)
|
|
1222
|
+
continue;
|
|
1223
|
+
const id = `${sourceKey}->${targetKey}`;
|
|
1224
|
+
if (nodes.has(id))
|
|
1225
|
+
continue;
|
|
1226
|
+
const installed = registry.widening(source, target);
|
|
1227
|
+
if (!installed)
|
|
1228
|
+
continue;
|
|
1229
|
+
nodes.set(id, {
|
|
1230
|
+
id,
|
|
1231
|
+
source,
|
|
1232
|
+
target,
|
|
1233
|
+
capability: { kind: 'atom', classifier: installed.classifier, materializer: installed.materializer }
|
|
1234
|
+
});
|
|
1235
|
+
}
|
|
1236
|
+
}
|
|
1237
|
+
// Union recasts: two tagged unions that carry the same member set at
|
|
1238
|
+
// different tag orders, which happens whenever a merge's two branches
|
|
1239
|
+
// arrive through independently-declared unions (`boolean | number` on one
|
|
1240
|
+
// arm, `number | boolean` on the other). Neither narrowing nor widening
|
|
1241
|
+
// covers it -- the source is not one arm of the target, and the target is
|
|
1242
|
+
// not one arm of the source -- so it is its own loop over every pair of
|
|
1243
|
+
// selected unions, gated the same strict way widening is.
|
|
1244
|
+
//
|
|
1245
|
+
// Records join the same loop, and for the same reason one level out: two
|
|
1246
|
+
// records declaring the same fields under two shape ids -- `Named & { age:
|
|
1247
|
+
// number }` against the literal that satisfies it -- are one shape spelled as
|
|
1248
|
+
// two structs, and neither is an arm of the other either.
|
|
1249
|
+
//
|
|
1250
|
+
// Dictionaries join too, one level further out: a record's closed field set
|
|
1251
|
+
// poured into a dictionary's open one is a third shape of the same recast --
|
|
1252
|
+
// `return {}` reaching a `Record<string, V>`-declared result is the concrete
|
|
1253
|
+
// case (`emit-narrowing.ts`'s `recordCastableToDictionary` is the one
|
|
1254
|
+
// authority for which pairs actually rebuild; every other pairing a
|
|
1255
|
+
// `dictionary` could sit in this loop as source or target for, `registry.
|
|
1256
|
+
// recasting` answers `null` for, exactly as it already does for a record and
|
|
1257
|
+
// a union that do not share arms).
|
|
1258
|
+
// `optional` joins the same loop for a fourth reason, narrower than the
|
|
1259
|
+
// other three: `gea::Optional<T>` carries a presence bit and nothing else --
|
|
1260
|
+
// `cppTypeOf` never reads `.absence` -- so two optionals over the identical
|
|
1261
|
+
// payload that disagree only on which falsy JS value means "empty"
|
|
1262
|
+
// (`string | null` widened into a `string | undefined` slot, DOM `Headers.
|
|
1263
|
+
// get`'s own `null` reaching a fetch-shaped API that promises `undefined`)
|
|
1264
|
+
// are the SAME C++ type under two representation identities, the identical
|
|
1265
|
+
// fact `record`/`dictionary` state about a closed shape poured into an open
|
|
1266
|
+
// one. `registry.recasting` only admits the pair when the PAYLOADS already
|
|
1267
|
+
// match exactly; a payload that itself needs converting is two obligations,
|
|
1268
|
+
// not one, and stays outside this loop.
|
|
1269
|
+
//
|
|
1270
|
+
// `array-object` joins for a fifth reason, on the target side only in
|
|
1271
|
+
// practice: an unannotated rest parameter is two views of one binding --
|
|
1272
|
+
// `restParameterArrayElementAt` (semantics/normalize/structural.ts) already
|
|
1273
|
+
// resolves the binding's OWN read-type to a real array, but the callable's
|
|
1274
|
+
// ABI still publishes the closed positional record it was derived from
|
|
1275
|
+
// (`records.ts` never wraps a non-required field, so the record can't even
|
|
1276
|
+
// state which trailing arg was omitted -- see recordCastableToArray's own
|
|
1277
|
+
// comment). Without `array-object` in this filter the loop never calls
|
|
1278
|
+
// `registry.recasting(record, array-object)` at all, no matter what that
|
|
1279
|
+
// predicate answers: the pair is filtered out before the call happens.
|
|
1280
|
+
const recastable = keyedDistinct(referenced.values()).filter(([, one]) =>
|
|
1281
|
+
// `dynamic` joins for a sixth reason, and the narrowest of all: two
|
|
1282
|
+
// boxes that differ only in `reason` are the same `gea::Value` under two
|
|
1283
|
+
// representation identities, which is precisely what this loop is for.
|
|
1284
|
+
one.kind === 'dynamic' ||
|
|
1285
|
+
one.kind === 'tagged-union' ||
|
|
1286
|
+
one.kind === 'record' ||
|
|
1287
|
+
// An open structural record can satisfy a named open interface while
|
|
1288
|
+
// preserving the identical index sidecar. The target still has to prove
|
|
1289
|
+
// the fields and index carriers match in the runtime registry.
|
|
1290
|
+
one.kind === 'record-with-index' ||
|
|
1291
|
+
// `native-record-ref` joins on the TARGET side: it names a layout instead
|
|
1292
|
+
// of carrying one, so the pair `record -> native-record-ref` -- `return
|
|
1293
|
+
// options` out of a method declared to return a named overlapping shape,
|
|
1294
|
+
// which the mongodb driver is built out of -- was filtered out before
|
|
1295
|
+
// `registry.recasting` was ever asked what it thought.
|
|
1296
|
+
one.kind === 'native-record-ref' ||
|
|
1297
|
+
// A concrete generated class can be rebuilt as a structural interface
|
|
1298
|
+
// view. The registry proves its data fields and bound methods; including
|
|
1299
|
+
// the carrier here only makes that exact source/target pair visible.
|
|
1300
|
+
one.kind === 'class-ref' ||
|
|
1301
|
+
one.kind === 'dictionary' ||
|
|
1302
|
+
one.kind === 'optional' ||
|
|
1303
|
+
one.kind === 'array-object' ||
|
|
1304
|
+
// Promise state adoption converts the fulfillment payload while
|
|
1305
|
+
// preserving pending and rejected states. A String wrapper read as its
|
|
1306
|
+
// primitive value is the other source/target pair whose recipe is a
|
|
1307
|
+
// recast rather than a narrowing or a widening. The runtime registry
|
|
1308
|
+
// remains the authority for whether either exact pair is installed.
|
|
1309
|
+
one.kind === 'promise' ||
|
|
1310
|
+
one.kind === 'string');
|
|
1311
|
+
// Which pairs already have a node, read off `nodes` once and keyed by
|
|
1312
|
+
// target, so the loop below never builds an id only to test it. The loop
|
|
1313
|
+
// is every ordered pair of `recastable` -- 10,447 carriers on TypeScript's
|
|
1314
|
+
// own compiler, 109 million pairs -- and a CPU profile of that stage put
|
|
1315
|
+
// 41% in this loop body itself, the concatenated id and its Map probe, and
|
|
1316
|
+
// a further 16% in the collector reclaiming those strings. An id is built
|
|
1317
|
+
// only for a pair the registry installs. Only a pair-shaped id counts: the
|
|
1318
|
+
// dynamic-materialization nodes above are keyed by their target alone, and
|
|
1319
|
+
// the loop would have asked about those pairs before.
|
|
1320
|
+
const sourcesWithNodeInto = new Map();
|
|
1321
|
+
for (const node of nodes.values()) {
|
|
1322
|
+
const sourceKey = representationKey(node.source);
|
|
1323
|
+
const targetKey = representationKey(node.target);
|
|
1324
|
+
if (node.id !== `${sourceKey}->${targetKey}`)
|
|
1325
|
+
continue;
|
|
1326
|
+
let sources = sourcesWithNodeInto.get(targetKey);
|
|
1327
|
+
if (!sources) {
|
|
1328
|
+
sources = new Set();
|
|
1329
|
+
sourcesWithNodeInto.set(targetKey, sources);
|
|
1330
|
+
}
|
|
1331
|
+
sources.add(sourceKey);
|
|
1332
|
+
}
|
|
1333
|
+
for (const [targetKey, target] of recastable) {
|
|
1334
|
+
const existing = sourcesWithNodeInto.get(targetKey);
|
|
1335
|
+
for (const [sourceKey, source] of recastable) {
|
|
1336
|
+
if (sourceKey === targetKey || existing?.has(sourceKey))
|
|
1337
|
+
continue;
|
|
1338
|
+
const installed = registry.recasting(source, target);
|
|
1339
|
+
if (!installed)
|
|
1340
|
+
continue;
|
|
1341
|
+
const id = `${sourceKey}->${targetKey}`;
|
|
1342
|
+
nodes.set(id, {
|
|
1343
|
+
id,
|
|
1344
|
+
source,
|
|
1345
|
+
target,
|
|
1346
|
+
capability: { kind: 'atom', classifier: installed.classifier, materializer: installed.materializer }
|
|
1347
|
+
});
|
|
1348
|
+
}
|
|
1349
|
+
}
|
|
1350
|
+
// Dynamic reasons identify provenance, not distinct boxed ABIs. The generic
|
|
1351
|
+
// root above proves the declared-any source, but obligations name the
|
|
1352
|
+
// source's exact representation key. Every other selected dynamic source
|
|
1353
|
+
// therefore needs the same derived capability under its own key for every
|
|
1354
|
+
// referenced target. This is installation only: `deriveConversionCapability`
|
|
1355
|
+
// still decides whether the target is a checked extraction, a product/array
|
|
1356
|
+
// materialization, or a stated refusal. In particular, do not turn this
|
|
1357
|
+
// into an identity edge merely because both sources use gea::Value.
|
|
1358
|
+
for (const [sourceKey, source] of referenced) {
|
|
1359
|
+
if (sourceKey === genericDynamicKey || source.kind !== 'dynamic')
|
|
1360
|
+
continue;
|
|
1361
|
+
for (const [targetKey, target] of referenced) {
|
|
1362
|
+
const id = `${sourceKey}->${targetKey}`;
|
|
1363
|
+
if (nodes.has(id))
|
|
1364
|
+
continue;
|
|
1365
|
+
nodes.set(id, {
|
|
1366
|
+
id,
|
|
1367
|
+
source,
|
|
1368
|
+
target,
|
|
1369
|
+
capability: deriveConversionCapability(target, context)
|
|
1370
|
+
});
|
|
1371
|
+
}
|
|
1372
|
+
}
|
|
1373
|
+
// A graph whose recursive references never close is materializable in each
|
|
1374
|
+
// node taken alone and unrunnable taken together; the whole-graph check is
|
|
1375
|
+
// the only place that difference is visible.
|
|
1376
|
+
validateConversionGraph([...nodes.values()]);
|
|
1377
|
+
return { nodes };
|
|
1378
|
+
};
|