@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,1683 @@
|
|
|
1
|
+
import ts from 'typescript';
|
|
2
|
+
import { genericFunctionSetMembersOf, runtimeSymbolMemberIndexOf } from '../../model/structural-types.js';
|
|
3
|
+
import { isFabricatedSignatureShape } from '../structural-callable.js';
|
|
4
|
+
import { symbolPropertyKeyText } from '../../model/structural-types.js';
|
|
5
|
+
import { symbolKeyDeclarationOf } from '../structural-leaves.js';
|
|
6
|
+
import { blocked } from './mint.js';
|
|
7
|
+
import { citeExpressionResult } from './references.js';
|
|
8
|
+
import { isShortCircuitingCall, presentReturnTypeOf } from './optional-chain.js';
|
|
9
|
+
import { enclosingCallIfCallee } from './erasure.js';
|
|
10
|
+
import { implementationSignatureOf, physicalOverloadTypeAt } from '../structural-declarations.js';
|
|
11
|
+
export { unwrapErasedExpression as unwrapErased } from './erasure.js';
|
|
12
|
+
import { unwrapErasedExpression } from './erasure.js';
|
|
13
|
+
/**
|
|
14
|
+
* Helpers every producer needs, kept in one place.
|
|
15
|
+
*
|
|
16
|
+
* Each of these existed as three or four private copies, and the copies did not
|
|
17
|
+
* stay identical: one `resultEdge` published ordinal zero for every operand
|
|
18
|
+
* while another carried the real one, so two producers disagreed about which
|
|
19
|
+
* operand an edge described. A duplicated helper is not a style problem here --
|
|
20
|
+
* it is a second authority waiting to drift, and drift in this layer is silent
|
|
21
|
+
* (a wrong citation produces no error, just an operation that never appears).
|
|
22
|
+
*/
|
|
23
|
+
/** `blocked()` mints a `CensusBlocker`; a producer's `contribute` must return a `CandidateContribution`. */
|
|
24
|
+
export const asBlocked = (...args) => ({ kind: 'blocked', blocker: blocked(...args) });
|
|
25
|
+
/**
|
|
26
|
+
* The `ValueEdge` a cited result needs to stay visible to whole-program
|
|
27
|
+
* authority-connectivity analysis. A `constant`/`absent` source crosses no
|
|
28
|
+
* operation boundary, so it needs none.
|
|
29
|
+
*
|
|
30
|
+
* The ordinal is a parameter and not a constant: an operand's role and ordinal
|
|
31
|
+
* together name it, and an edge that always claimed ordinal zero would describe
|
|
32
|
+
* the first argument of a call no matter which argument it actually carried.
|
|
33
|
+
*/
|
|
34
|
+
export const resultEdge = (source, to, role, ordinal) => source.kind === 'result' ? { kind: 'value', result: source.result, to, role, ordinal } : null;
|
|
35
|
+
/** Every operand of an operation that cites a result, as edges into it. */
|
|
36
|
+
export const valueEdgesInto = (to, operands) => operands.flatMap((entry) => entry.source.kind === 'result' ? [{ kind: 'value', result: entry.source.result, to, role: entry.role, ordinal: entry.ordinal }] : []);
|
|
37
|
+
export const isAssignmentOperatorKind = (kind) => kind >= ts.SyntaxKind.FirstAssignment && kind <= ts.SyntaxKind.LastAssignment;
|
|
38
|
+
/**
|
|
39
|
+
* Whether this source position evaluates in ECMAScript strict mode.
|
|
40
|
+
*
|
|
41
|
+
* An ES MODULE is strict in its entirety, unconditionally (ECMA-262 11.2.2) --
|
|
42
|
+
* no prologue, no `export`, nothing else required.
|
|
43
|
+
*
|
|
44
|
+
* Established against real `node`, not argued: the same `delete` of a
|
|
45
|
+
* non-configurable property answers `false` when the emitted file is loaded as
|
|
46
|
+
* CommonJS and throws `TypeError` when it is loaded as an ES module. Both
|
|
47
|
+
* `strict-delete.ts` and `native-handle-computed-access.runtime.js` throw under
|
|
48
|
+
* the module setting their own tsconfig states.
|
|
49
|
+
*
|
|
50
|
+
* THE `module` SETTING IS NOT THE QUESTION. It used to short-circuit this walk
|
|
51
|
+
* -- `module: ESNext` was read as "every file is a module, so every file is
|
|
52
|
+
* strict" -- and that is false for a file with no import and no export, which
|
|
53
|
+
* is a Script whatever the emit setting says. What actually makes every file in
|
|
54
|
+
* a build strict is `alwaysStrict` (implied by `strict`): tsc parses strict and
|
|
55
|
+
* writes a `'use strict'` prologue into each emitted file. That is
|
|
56
|
+
* `buildIsStrict`, and it is the only whole-build fact this needs; the rest --
|
|
57
|
+
* external module, prologue, class body -- is per position and walked here.
|
|
58
|
+
*
|
|
59
|
+
* `test/runtime/tsconfig.json` sets `strict: true`, so the suite's answer does
|
|
60
|
+
* not change. A build with `module: CommonJS` and `strict: true` was the case
|
|
61
|
+
* this got wrong in both directions at once.
|
|
62
|
+
*/
|
|
63
|
+
export const isStrictContext = (node, buildIsStrict) => {
|
|
64
|
+
if (buildIsStrict)
|
|
65
|
+
return true;
|
|
66
|
+
const hasDirective = (statements) => {
|
|
67
|
+
for (const statement of statements) {
|
|
68
|
+
if (!ts.isExpressionStatement(statement) || !ts.isStringLiteral(statement.expression))
|
|
69
|
+
return false;
|
|
70
|
+
if (statement.expression.text === 'use strict')
|
|
71
|
+
return true;
|
|
72
|
+
}
|
|
73
|
+
return false;
|
|
74
|
+
};
|
|
75
|
+
for (let current = node; current; current = current.parent) {
|
|
76
|
+
// Every class definition and all code nested inside it is strict.
|
|
77
|
+
if (ts.isClassLike(current))
|
|
78
|
+
return true;
|
|
79
|
+
if (ts.isFunctionLike(current) &&
|
|
80
|
+
'body' in current &&
|
|
81
|
+
current.body !== undefined &&
|
|
82
|
+
ts.isBlock(current.body) &&
|
|
83
|
+
hasDirective(current.body.statements))
|
|
84
|
+
return true;
|
|
85
|
+
if (ts.isSourceFile(current))
|
|
86
|
+
return ts.isExternalModule(current) || hasDirective(current.statements);
|
|
87
|
+
}
|
|
88
|
+
return false;
|
|
89
|
+
};
|
|
90
|
+
/**
|
|
91
|
+
* A logical assignment writes only when the short-circuit does not fire, so it
|
|
92
|
+
* is not a read-operate-write at all; decomposing it as one would write a value
|
|
93
|
+
* the source program leaves untouched.
|
|
94
|
+
*/
|
|
95
|
+
export const logicalAssignmentOperators = new Set([
|
|
96
|
+
ts.SyntaxKind.AmpersandAmpersandEqualsToken,
|
|
97
|
+
ts.SyntaxKind.BarBarEqualsToken,
|
|
98
|
+
ts.SyntaxKind.QuestionQuestionEqualsToken
|
|
99
|
+
]);
|
|
100
|
+
/**
|
|
101
|
+
* A compound assignment reads its target, so the property and computation
|
|
102
|
+
* families must agree on exactly which operators those are. Derived from the
|
|
103
|
+
* assignment range minus the two forms that are not read-operate-write.
|
|
104
|
+
*/
|
|
105
|
+
export const isCompoundAssignmentOperator = (kind) => isAssignmentOperatorKind(kind) && kind !== ts.SyntaxKind.EqualsToken && !logicalAssignmentOperators.has(kind);
|
|
106
|
+
/**
|
|
107
|
+
* Where an expression's value comes from, as an operand source.
|
|
108
|
+
*
|
|
109
|
+
* The identity is predictive, not observed: the owning family's producer mints
|
|
110
|
+
* this exact id independently from the same node, so the graph is wired by
|
|
111
|
+
* agreement on identity and never by execution order. Citation has exactly one
|
|
112
|
+
* implementation for that agreement to be worth anything -- three private
|
|
113
|
+
* copies of this drifted from it, kept citing a name's Reference Record after
|
|
114
|
+
* the shared rule moved to the value GetValue publishes, and every operand they
|
|
115
|
+
* built named a result nobody published. The publication guard then withheld
|
|
116
|
+
* those operations silently: no error, no blocker, just missing operations.
|
|
117
|
+
*
|
|
118
|
+
* The throw is deliberate. Every runtime-producing expression is censused, a
|
|
119
|
+
* literal, or `this`/`super`; reaching it means a form exists that neither this
|
|
120
|
+
* layer nor the census knows about, which is an implementation gap to fix here
|
|
121
|
+
* rather than a missing capability to report about the program.
|
|
122
|
+
*/
|
|
123
|
+
export const sourceForValue = (context, expr, branch = 'expression') => {
|
|
124
|
+
const cited = citeExpressionResult(expr, context, branch);
|
|
125
|
+
if (cited.kind === 'unmodelled')
|
|
126
|
+
throw new Error(cited.reason);
|
|
127
|
+
return cited.source;
|
|
128
|
+
};
|
|
129
|
+
/**
|
|
130
|
+
* The type of an expression's value, resolved through the specific call it is
|
|
131
|
+
* invoked by when it is one's callee.
|
|
132
|
+
*
|
|
133
|
+
* `arr.map`'s own type carries `map`'s unbound `<U>`: nothing at that
|
|
134
|
+
* position has committed to a value for it. But when this exact expression is
|
|
135
|
+
* the callee of an enclosing call, the checker already committed -- resolving
|
|
136
|
+
* that call over its overload set and inferring its type arguments is what
|
|
137
|
+
* type-checking the call *is* -- so `getResolvedSignature` on the call reads
|
|
138
|
+
* back an answer the checker already computed, rather than this layer
|
|
139
|
+
* re-deriving one. Every other position keeps the plain property type: a
|
|
140
|
+
* value merely stored or passed around, never called from here, has made no
|
|
141
|
+
* such commitment for this layer to read back.
|
|
142
|
+
*
|
|
143
|
+
* `properties.ts` and `invocations.ts` both need this exact answer for the
|
|
144
|
+
* same expression -- the property access publishes it as its own result, and
|
|
145
|
+
* the call cites that result as its callee operand -- and they get it without
|
|
146
|
+
* coordinating: `StructuralTypeTable.intern` dedupes by the shape's own
|
|
147
|
+
* canonical key, so two independent calls into `resolvedSignatureTypeOf` with
|
|
148
|
+
* the same resolved signature converge on one id instead of two.
|
|
149
|
+
*/
|
|
150
|
+
/**
|
|
151
|
+
* TypeScript's own `anySignature`: what `getResolvedSignature` returns for a
|
|
152
|
+
* call it did not check.
|
|
153
|
+
*
|
|
154
|
+
* It stands for "this call was not checked", never for a convention anything
|
|
155
|
+
* has, so interning it produces a callable carrier whose ABI declares no
|
|
156
|
+
* parameters at all -- `fn(a, b, c)` acquires a callee that takes none.
|
|
157
|
+
* Recognized by all three of its properties together: a real signature always
|
|
158
|
+
* has a declaration, and testing parameter count alone would catch every
|
|
159
|
+
* genuinely nullary function.
|
|
160
|
+
*
|
|
161
|
+
* The checker's own type at the callee is required to be `any` as well. That
|
|
162
|
+
* is the fact that makes the fabricated signature meaningless -- and the fact
|
|
163
|
+
* `parameter-bindings.ts` was written to answer.
|
|
164
|
+
*/
|
|
165
|
+
// Deliberately checker-only, not a bypass: this detects exactly the case
|
|
166
|
+
// where the CHECKER committed to nothing (its raw answer is `any`) so the
|
|
167
|
+
// caller (`resolvedCalleeSignatureType` below, ~line 231's own comment) knows
|
|
168
|
+
// to prefer the census's answer over this fabricated signature instead of
|
|
169
|
+
// interning it. Routing this test itself through the census would defeat the
|
|
170
|
+
// test it exists to run.
|
|
171
|
+
const isFabricatedAnySignature = (checker, node, signature) => (checker.getTypeAtLocation(node).flags & ts.TypeFlags.Any) !== 0 && isFabricatedSignatureShape(checker, signature);
|
|
172
|
+
/**
|
|
173
|
+
* A property access whose member is annotated with an overload set and
|
|
174
|
+
* initialized with one physical function -- the member spelling of the
|
|
175
|
+
* binding case `physicalOverloadTypeAt` already answers.
|
|
176
|
+
*
|
|
177
|
+
* The declaration is reached through the member SYMBOL rather than through the
|
|
178
|
+
* access node, because the access has no declaration of its own; a symbol with
|
|
179
|
+
* no value declaration, or one the overload rule declines, answers `null` and
|
|
180
|
+
* the resolved signature stands as before.
|
|
181
|
+
*/
|
|
182
|
+
/**
|
|
183
|
+
* Where the callee VALUE is declared -- which is what says whose frame binds
|
|
184
|
+
* the type parameters its type mentions.
|
|
185
|
+
*
|
|
186
|
+
* Not the same question as where the signature's SYNTAX lives, and hono is
|
|
187
|
+
* where the two come apart: `type GetPath<E> = (request: Request, options?:
|
|
188
|
+
* { env?: E['Bindings'] }) => string` puts the signature node at hono-base's
|
|
189
|
+
* MODULE scope, while the value it types -- `readonly getPath: GetPath<E>` --
|
|
190
|
+
* is a member of the class whose `E` it names. Scoping the callee's view by
|
|
191
|
+
* the signature node truncated the specialization path to nothing, so `E` was
|
|
192
|
+
* answered by its own DEFAULT (`Env`) instead of by the copy's binding
|
|
193
|
+
* (`BlankEnv`), and the call published a record the class's own field layout
|
|
194
|
+
* -- built in that copy -- does not have.
|
|
195
|
+
*
|
|
196
|
+
* A plain identifier callee answers the same declaration either way, so the
|
|
197
|
+
* case `signature.declaration` was introduced for (`parseBody(this, options)`
|
|
198
|
+
* resolved under the caller's frame, minting a second `HonoRequest`) keeps its
|
|
199
|
+
* answer: an imported binding's value declaration is at module scope, and the
|
|
200
|
+
* prefix truncates there exactly as before.
|
|
201
|
+
*/
|
|
202
|
+
const calleeValueDeclarationAt = (context, node) => {
|
|
203
|
+
const name = ts.isPropertyAccessExpression(node) ? node.name : ts.isIdentifier(node) ? node : null;
|
|
204
|
+
if (!name)
|
|
205
|
+
return null;
|
|
206
|
+
const symbol = context.checker.getSymbolAtLocation(name);
|
|
207
|
+
return symbol ? context.identities.valueDeclarationOfSymbol(symbol) : null;
|
|
208
|
+
};
|
|
209
|
+
/**
|
|
210
|
+
* The member type, re-resolved on the receiver THIS COPY substituted -- or
|
|
211
|
+
* `null` when the receiver is not a parameter this copy binds.
|
|
212
|
+
*
|
|
213
|
+
* TypeScript resolves `operation.weight` on `T`'s apparent type, its
|
|
214
|
+
* CONSTRAINT, because that is all the language knows about `T` while checking
|
|
215
|
+
* one generic body. A monomorphized copy knows more: its receiver really is a
|
|
216
|
+
* `Heavy`, and the member that names is `Heavy`'s own override. So the member
|
|
217
|
+
* is looked up again on the bound type, which is not a second opinion but the
|
|
218
|
+
* same lookup asked with the fact the copy added.
|
|
219
|
+
*
|
|
220
|
+
* Scoped by the SUBSTITUTION rather than by "is this a type parameter": an
|
|
221
|
+
* uninstantiated parameter is one no copy answers for, and its
|
|
222
|
+
* constraint-resolved signature is the only answer there is.
|
|
223
|
+
*/
|
|
224
|
+
const substitutedReceiverMemberType = (context, node) => {
|
|
225
|
+
if (!ts.isPropertyAccessExpression(node))
|
|
226
|
+
return null;
|
|
227
|
+
const receiver = context.checker.getTypeAtLocation(node.expression);
|
|
228
|
+
if ((receiver.flags & ts.TypeFlags.TypeParameter) === 0)
|
|
229
|
+
return null;
|
|
230
|
+
const bound = context.types.substituteTypeParameter(receiver);
|
|
231
|
+
if (bound === receiver)
|
|
232
|
+
return null;
|
|
233
|
+
const member = bound.getProperty(node.name.text);
|
|
234
|
+
return member ? context.checker.getTypeOfSymbolAtLocation(member, node) : null;
|
|
235
|
+
};
|
|
236
|
+
const physicalMemberOverloadTypeAt = (context, node) => {
|
|
237
|
+
if (!ts.isPropertyAccessExpression(node))
|
|
238
|
+
return null;
|
|
239
|
+
const symbol = context.checker.getSymbolAtLocation(node.name);
|
|
240
|
+
const declaration = symbol?.valueDeclaration;
|
|
241
|
+
if (!declaration)
|
|
242
|
+
return null;
|
|
243
|
+
const physical = physicalOverloadTypeAt(context.checker, declaration);
|
|
244
|
+
if (physical !== null)
|
|
245
|
+
return physical;
|
|
246
|
+
// The same member, with NO initializer to name the one physical function.
|
|
247
|
+
// hono's `get!: HandlerInterface<...>` is filled in the constructor by
|
|
248
|
+
// `allMethods.forEach((method) => { this[method] = (args1, ...args) => ... })`,
|
|
249
|
+
// so the declaration carries only the overload set -- and that overload set
|
|
250
|
+
// is exactly what the class layout spelled for the cell (one `gea::Value`,
|
|
251
|
+
// since no single convention derives from an overloaded type).
|
|
252
|
+
//
|
|
253
|
+
// The reasoning is the paragraph above's, not a weaker version of it: an
|
|
254
|
+
// overload set is a type-level fiction over a single runtime function, so
|
|
255
|
+
// whichever overload THIS call site matched says nothing about the physical
|
|
256
|
+
// shape of the callable the cell holds. The only difference is which answer
|
|
257
|
+
// agrees with the layout: with an initializer it is the literal's own
|
|
258
|
+
// convention, without one it is the declared type itself. Believing the
|
|
259
|
+
// resolved overload instead published a `CallableObject<Sig>` for a member
|
|
260
|
+
// stored as `gea::Value`, and the unbox in between asserts a payload type
|
|
261
|
+
// the writer never wrote -- `app.get('/', handler)` aborted on the program's
|
|
262
|
+
// first statement rather than failing to compile.
|
|
263
|
+
//
|
|
264
|
+
// Gated to a PROPERTY with no initializer, so nothing that already resolves
|
|
265
|
+
// through the checker's overload resolution is re-derived: a METHOD is
|
|
266
|
+
// reached by name and rendered per signature with no cell involved, which
|
|
267
|
+
// is every `lib.d.ts` overload set (`Array.prototype.map`,
|
|
268
|
+
// `String.prototype.replace`), and those keep their answer.
|
|
269
|
+
if (!ts.isPropertyDeclaration(declaration) || declaration.initializer !== undefined)
|
|
270
|
+
return null;
|
|
271
|
+
const declared = context.checker.getTypeAtLocation(declaration);
|
|
272
|
+
return declared.getCallSignatures().length >= 2 ? declared : null;
|
|
273
|
+
};
|
|
274
|
+
/**
|
|
275
|
+
* `Object.getOwnPropertyDescriptor(receiver, key)`'s result, minted from the
|
|
276
|
+
* RECEIVER's own structural shape rather than the ambient `PropertyDescriptor`
|
|
277
|
+
* interface's own declared `value?: any` -- see `structural.ts`'s own
|
|
278
|
+
* `objectDescriptorReturnTypeAt` for the full reasoning and the actual
|
|
279
|
+
* decision. Delegates rather than re-deriving: `context.types.typeAt(call)`
|
|
280
|
+
* (the general per-node structural authority, asked by a property access's
|
|
281
|
+
* own receiver typing, a local binding's declared type, and everything else
|
|
282
|
+
* that asks "what is this node's type") already computes this exact answer
|
|
283
|
+
* for the bare CallExpression, and `validateInvocationResult`
|
|
284
|
+
* (`model/selected-signature.ts`) requires this producer's own
|
|
285
|
+
* `resultType`/`selectedSignature.returnType` to agree with it exactly --
|
|
286
|
+
* two independently-written copies of the same decision is precisely the
|
|
287
|
+
* shape that disagreement bit once already this session (a `buildSelectedSignature`-only
|
|
288
|
+
* version published a native record for the call's own SSA value while
|
|
289
|
+
* `context.types.typeAt` kept answering the old boxed one for every other
|
|
290
|
+
* reader of the same node).
|
|
291
|
+
*/
|
|
292
|
+
export const objectDescriptorReturnTypeAt = (context, call) => context.types.objectDescriptorReturnTypeAt(call);
|
|
293
|
+
/**
|
|
294
|
+
* The type of the ONE function a callee value physically is, when its
|
|
295
|
+
* declaration annotates it with an overload set and initializes it with a
|
|
296
|
+
* single function literal -- `structural-declarations.ts`'s
|
|
297
|
+
* `physicalOverloadTypeAt`, reached through either spelling a callee has.
|
|
298
|
+
*
|
|
299
|
+
* A bare binding reference is that function's own rule verbatim. A property
|
|
300
|
+
* access has no declaration of its own, so the member SYMBOL's is resolved
|
|
301
|
+
* first -- the identical indirection `physicalMemberOverloadTypeAt` below
|
|
302
|
+
* already performs, and deliberately the same rule rather than a second one:
|
|
303
|
+
* the two must agree about how many conventions one value has, or the member
|
|
304
|
+
* read and the call through it publish different carriers for one cell.
|
|
305
|
+
*/
|
|
306
|
+
const physicalCalleeValueTypeOf = (checker, callee) => {
|
|
307
|
+
if (ts.isPropertyAccessExpression(callee)) {
|
|
308
|
+
const declaration = checker.getSymbolAtLocation(callee.name)?.valueDeclaration;
|
|
309
|
+
return declaration ? physicalOverloadTypeAt(checker, declaration) : null;
|
|
310
|
+
}
|
|
311
|
+
return physicalOverloadTypeAt(checker, callee);
|
|
312
|
+
};
|
|
313
|
+
/**
|
|
314
|
+
* Whether a resolved signature's type parameters belong to no body this
|
|
315
|
+
* compiler copies: they are declared by a function TYPE, or were propagated
|
|
316
|
+
* onto a signature whose own declaration writes none.
|
|
317
|
+
*/
|
|
318
|
+
const isGenericCallableValue = (checker, callee) => {
|
|
319
|
+
// The VALUE's type, not the call's resolved signature: an instantiated
|
|
320
|
+
// signature has no type parameters left to see.
|
|
321
|
+
//
|
|
322
|
+
// And the value's PHYSICAL type wherever the declaration names one, not the
|
|
323
|
+
// annotation the checker answers with. hono's `Context.text: TextRespond =
|
|
324
|
+
// (text, arg, headers) => {...}` and `Context.json: JSONRespond = <T, U>
|
|
325
|
+
// (object, arg, headers) => {...}` (`context.ts`) are the shape: the
|
|
326
|
+
// annotation is an interface of GENERIC call signatures, so the test below
|
|
327
|
+
// saw a non-ambient `CallSignatureDeclaration` and said "generic callable
|
|
328
|
+
// value" -- which publishes the ANNOTATION as the callee carrier. Those
|
|
329
|
+
// overloads disagree at parameter 1 and join into no single convention, so
|
|
330
|
+
// the carrier settled on `callable-identity` and the call had no invoke
|
|
331
|
+
// path at all (`call-abi:no-invoke-path:callable-identity`), while the
|
|
332
|
+
// class LAYOUT -- which reads the same declaration through
|
|
333
|
+
// `physicalInitializerTypeOf` -- had stored the one arrow's real
|
|
334
|
+
// convention all along. Two authorities over one cell, and the one with no
|
|
335
|
+
// runtime referent was winning.
|
|
336
|
+
//
|
|
337
|
+
// Asking the literal is not a weaker question, it is the same question
|
|
338
|
+
// asked of the thing that exists: whether the FUNCTION THAT WAS ALLOCATED
|
|
339
|
+
// writes type parameters of its own decides whether a copy per call is
|
|
340
|
+
// owed, and an annotation's overload set never does (ECMA-262 has no
|
|
341
|
+
// overloads). A generic literal (`respond: Respond = <T, U>(value, arg) =>
|
|
342
|
+
// {...}`, `test/runtime/generic-field-initializer.ts`) still answers
|
|
343
|
+
// through the ordinary body rule below, on its own declaration.
|
|
344
|
+
const valueType = physicalCalleeValueTypeOf(checker, callee) ?? checker.getTypeAtLocation(callee);
|
|
345
|
+
const generic = valueType.getCallSignatures().find((one) => (one.getTypeParameters()?.length ?? 0) > 0);
|
|
346
|
+
const declaration = generic?.declaration;
|
|
347
|
+
if (!declaration)
|
|
348
|
+
return false;
|
|
349
|
+
if (ts.isFunctionTypeNode(declaration) || ts.isConstructorTypeNode(declaration))
|
|
350
|
+
return true;
|
|
351
|
+
// A call signature an interface or type literal declares (`interface
|
|
352
|
+
// NodeVisitor { <TIn, TOut>(node: TIn, ...): TOut; ... }`, TypeScript's own)
|
|
353
|
+
// is the same thing as a function type node -- a callable TYPE, with no
|
|
354
|
+
// body of its own to copy -- and a value of it is one function at runtime
|
|
355
|
+
// over the set's joined convention (`representation/host-abi.ts`'s
|
|
356
|
+
// `widestSubsumingAbi`). An ambient one keeps the checker's answer: a host
|
|
357
|
+
// handle's overload set is rendered per selected signature, never through a
|
|
358
|
+
// cell holding the joined frame.
|
|
359
|
+
if (ts.isCallSignatureDeclaration(declaration) || ts.isConstructSignatureDeclaration(declaration)) {
|
|
360
|
+
return !declaration.getSourceFile().isDeclarationFile;
|
|
361
|
+
}
|
|
362
|
+
// A body that writes its own parameters is copied per call; an ambient one
|
|
363
|
+
// is the host's, instantiated by the checker at each call. Propagated
|
|
364
|
+
// parameters on a declaration that writes none are the closure case.
|
|
365
|
+
return (declaration.typeParameters?.length ?? 0) === 0 && !declaration.getSourceFile().isDeclarationFile;
|
|
366
|
+
};
|
|
367
|
+
/**
|
|
368
|
+
* The one overload of `plain` a call with this many arguments admits, when
|
|
369
|
+
* `plain` is an overload set and exactly one member admits the count -- else
|
|
370
|
+
* `plain` unchanged.
|
|
371
|
+
*
|
|
372
|
+
* A receiver the checker carries as `any` resolves every call to its
|
|
373
|
+
* fabricated no-parameter signature; the callee's PLAIN type is then the
|
|
374
|
+
* census's own answer for the member, and for a library method that is the
|
|
375
|
+
* whole declared overload set. Publishing the set leaves the carrier to pick
|
|
376
|
+
* a frame by joining the overloads, and the joined `Array.prototype.splice`
|
|
377
|
+
* frame is the two-parameter one: `levels.splice( l, 0, level )` in three's
|
|
378
|
+
* `LOD.addLevel` (`levels` read through a descriptor-defined field the
|
|
379
|
+
* checker cannot see) then reached the emitter with its item UNPACKED, since
|
|
380
|
+
* the joined convention declared no rest slot to pack it into. Overload
|
|
381
|
+
* resolution by arity is the checker's own first step (ECMA-262 has no
|
|
382
|
+
* overloads; TypeScript's `chooseOverload` discards candidates the argument
|
|
383
|
+
* count rules out before it compares a single type), so it is the part that
|
|
384
|
+
* can be repeated here without a receiver the checker will type; when more
|
|
385
|
+
* than one overload survives the count, the set stays whole rather than
|
|
386
|
+
* guessing.
|
|
387
|
+
*/
|
|
388
|
+
const arityResolvedOverload = (context, plain, call) => {
|
|
389
|
+
const shape = context.table.get(plain).shape;
|
|
390
|
+
if (shape.kind !== 'signature' || shape.generic !== undefined)
|
|
391
|
+
return plain;
|
|
392
|
+
if (!ts.isCallExpression(call) && !ts.isNewExpression(call))
|
|
393
|
+
return plain;
|
|
394
|
+
const construct = ts.isNewExpression(call);
|
|
395
|
+
const overloads = construct ? shape.construct : shape.call;
|
|
396
|
+
if (overloads.length < 2)
|
|
397
|
+
return plain;
|
|
398
|
+
const supplied = call.arguments ?? [];
|
|
399
|
+
if (supplied.some((argument) => ts.isSpreadElement(argument)))
|
|
400
|
+
return plain;
|
|
401
|
+
const count = supplied.length;
|
|
402
|
+
const admitted = overloads.filter((overload) => {
|
|
403
|
+
if (count < overload.minimumArity)
|
|
404
|
+
return false;
|
|
405
|
+
const last = overload.parameters[overload.parameters.length - 1];
|
|
406
|
+
return (last?.rest ?? false) || count <= overload.parameters.length;
|
|
407
|
+
});
|
|
408
|
+
if (admitted.length !== 1)
|
|
409
|
+
return plain;
|
|
410
|
+
return context.table.intern({
|
|
411
|
+
kind: 'signature',
|
|
412
|
+
call: construct ? [] : admitted,
|
|
413
|
+
construct: construct ? admitted : []
|
|
414
|
+
});
|
|
415
|
+
};
|
|
416
|
+
/**
|
|
417
|
+
* The class copy a method call's receiver is an instance of, as the path the
|
|
418
|
+
* callee's frame should be typed under, or `null` when the callee is not a
|
|
419
|
+
* member of a generic class whose copies can differ in layout, or the
|
|
420
|
+
* receiver names no copy of that class.
|
|
421
|
+
*/
|
|
422
|
+
/** The generic class a `new` constructs, when its copies can differ in layout; `null` otherwise. */
|
|
423
|
+
const constructedGenericClassOf = (context, declaration) => {
|
|
424
|
+
const owner = declaration === undefined
|
|
425
|
+
? null
|
|
426
|
+
: ts.isClassLike(declaration)
|
|
427
|
+
? declaration
|
|
428
|
+
: ts.isConstructorDeclaration(declaration)
|
|
429
|
+
? declaration.parent
|
|
430
|
+
: null;
|
|
431
|
+
return owner && ts.isClassLike(owner) && context.specializations.copiesMayDifferInLayout(owner) ? owner : null;
|
|
432
|
+
};
|
|
433
|
+
const instanceCopyOfMethodReceiver = (context, node, declaration) => {
|
|
434
|
+
const callee = unwrapErasedExpression(node);
|
|
435
|
+
if (!ts.isPropertyAccessExpression(callee) && !ts.isElementAccessExpression(callee))
|
|
436
|
+
return null;
|
|
437
|
+
const owner = declaration.parent;
|
|
438
|
+
if (!owner || !ts.isClassLike(owner) || !context.specializations.copiesMayDifferInLayout(owner))
|
|
439
|
+
return null;
|
|
440
|
+
if (!(ts.isMethodDeclaration(declaration) || ts.isGetAccessorDeclaration(declaration) || ts.isPropertyDeclaration(declaration)))
|
|
441
|
+
return null;
|
|
442
|
+
if (ts.getCombinedModifierFlags(declaration) & ts.ModifierFlags.Static)
|
|
443
|
+
return null;
|
|
444
|
+
const receiver = context.types.rawTypeAt(callee.expression);
|
|
445
|
+
const copy = context.specializations.specializationOfInstance(receiver, context.types.substituteTypeParameter);
|
|
446
|
+
if (!copy || copy.declaration !== owner)
|
|
447
|
+
return null;
|
|
448
|
+
const enclosing = context.identities.prefixFor(owner, context.path).filter((step) => step.owner !== owner);
|
|
449
|
+
return [...enclosing, { owner, ordinal: copy.ordinal }];
|
|
450
|
+
};
|
|
451
|
+
export const resolvedCalleeSignatureType = (context, node) => {
|
|
452
|
+
const call = enclosingCallIfCallee(node);
|
|
453
|
+
const signature = call ? context.checker.getResolvedSignature(call) : undefined;
|
|
454
|
+
if (!call || !signature)
|
|
455
|
+
return null;
|
|
456
|
+
const mutableMethod = context.types.mutableMethodReadTypeAt(node);
|
|
457
|
+
if (mutableMethod !== null)
|
|
458
|
+
return mutableMethod;
|
|
459
|
+
// `xs.push(v)` on an evolving `var xs = []`: the checker resolves the call
|
|
460
|
+
// over the receiver's stale `any[]`/`never[]`, and publishing that here
|
|
461
|
+
// would box every argument on its way into an array whose storage the
|
|
462
|
+
// census already narrowed. The member read's own answer (`structural.ts`'s
|
|
463
|
+
// `evolvingArrayMemberTypeAt`) carries the census's element; it is the same
|
|
464
|
+
// authority the receiver's storage was chosen by, so it wins here too.
|
|
465
|
+
const evolvingMember = context.types.evolvingArrayMemberTypeAt(node);
|
|
466
|
+
if (evolvingMember !== null)
|
|
467
|
+
return evolvingMember;
|
|
468
|
+
// A callee that is a CHOICE of generic functions keeps its own type: the
|
|
469
|
+
// signature the checker resolved is one it combined from the members, and
|
|
470
|
+
// no callable of that frame exists -- the value is the set's tag, and the
|
|
471
|
+
// call's `closed-family` target names the copy each member runs
|
|
472
|
+
// (`producers/invocations.ts`'s `genericSetFamilyTarget`).
|
|
473
|
+
const plainType = context.types.typeAt(node);
|
|
474
|
+
if (genericFunctionSetMembersOf((id) => context.table.get(id).shape, context.table.get(plainType).shape))
|
|
475
|
+
return plainType;
|
|
476
|
+
// A callee whose VALUE is a generic callable with no copies of its own -- a
|
|
477
|
+
// parameter or field typed `<T extends Node>(node: T) => void`
|
|
478
|
+
// (emitter.ts's `EmitFunction`), or the closure a higher-order call
|
|
479
|
+
// returned with a generic argument's parameters propagated into it
|
|
480
|
+
// (`memoizeOne(<T extends JSDocType>(kind) => ...)`) -- is ONE function at
|
|
481
|
+
// runtime, over its constraints (`structural.ts`'s callable-owned rule).
|
|
482
|
+
// The checker instantiates such a signature afresh at every call
|
|
483
|
+
// (`emitFn(child)` reads its `T` as `Child`), and publishing that here made
|
|
484
|
+
// the callee's carrier disagree with the cell it was just read from at every
|
|
485
|
+
// call. The value's own type is the frame; the call converts to it.
|
|
486
|
+
if (isGenericCallableValue(context.checker, unwrapErasedExpression(node)))
|
|
487
|
+
return plainType;
|
|
488
|
+
// `node`'s own declared type is a property of ITS declaration, not of the
|
|
489
|
+
// caller's specialization frame -- the same leak `buildSelectedSignature`
|
|
490
|
+
// (`producers/invocations.ts`) fixes for a signature's parameters/return,
|
|
491
|
+
// here for the callee VALUE itself. Resolving `parseBody`'s type through
|
|
492
|
+
// `context.types` unfiltered mints `HonoRequest` (nested in `parseBody`'s
|
|
493
|
+
// own declared parameter type, `utils/body.ts`) under the CALLER's frame
|
|
494
|
+
// whenever the call site happens to sit inside a same-named class's own
|
|
495
|
+
// copy -- `HonoRequest.parseBody`'s body calling `parseBody(this,
|
|
496
|
+
// options)` is exactly that, and it is what left `request.ts:217`'s
|
|
497
|
+
// binding-read-conversion stuck even after the guard below (comment
|
|
498
|
+
// above `physicalOverloadTypeAt`) fixed the overloaded-signature gap: the
|
|
499
|
+
// guard changed WHICH shape `plain` resolves as, not WHICH VIEW resolves
|
|
500
|
+
// it. `signature.declaration` is absent only for a fabricated signature
|
|
501
|
+
// (no physical function backs it), where there is no callee declaration
|
|
502
|
+
// to scope by and the caller's own view is the only one that applies.
|
|
503
|
+
//
|
|
504
|
+
// The CALLER's path goes in as the binding path, because a resolved
|
|
505
|
+
// signature is a hybrid and the two halves come from different frames: its
|
|
506
|
+
// SHAPE is the callee's declaration -- which is what the scoping above is
|
|
507
|
+
// for -- while its type ARGUMENTS are whatever the checker substituted from
|
|
508
|
+
// the caller's own. `outer<T>(op: T) { inner(op) }` resolves `inner` to
|
|
509
|
+
// `(operation: T) => number` over the CALLER's `T`, and scoping that wholly
|
|
510
|
+
// to the callee left the parameter with nothing to bind it: the callee
|
|
511
|
+
// carrier published `function-value-dispatch((unresolved(type parameter T))
|
|
512
|
+
// -> number)` in every copy, identically, which is the naked hole
|
|
513
|
+
// monomorphization exists to remove reappearing at the callee. Scoping it
|
|
514
|
+
// wholly to the caller instead is what the `HonoRequest` comment above
|
|
515
|
+
// rules out. Neither path answers both halves, so each half is taken from
|
|
516
|
+
// the frame that owns it.
|
|
517
|
+
const declaration = calleeValueDeclarationAt(context, node) ?? signature.declaration;
|
|
518
|
+
// A method of a generic class whose copies can differ in layout, called
|
|
519
|
+
// on a receiver that is one instantiation of it (`numbers.pick('a')`,
|
|
520
|
+
// `numbers: Box<number>`): the frame is the copy's, because its implicit
|
|
521
|
+
// receiver is `Box<T>` and only the copy binds `T` to the layout the
|
|
522
|
+
// receiver carries -- the generic-function branch below does the same for
|
|
523
|
+
// a call the census keyed on a copy, and this is the class-shaped half of
|
|
524
|
+
// it. A class with one layout is left on the caller's view exactly as
|
|
525
|
+
// before (`SpecializationCensus.copiesMayDifferInLayout`).
|
|
526
|
+
const receiverCopy = declaration ? instanceCopyOfMethodReceiver(context, node, declaration) : null;
|
|
527
|
+
const calleeTypes = receiverCopy
|
|
528
|
+
? context.types.forSpecialization(receiverCopy, [...context.path, receiverCopy[receiverCopy.length - 1]])
|
|
529
|
+
: declaration
|
|
530
|
+
? context.types.forSpecialization(context.identities.prefixFor(declaration, context.path), context.path)
|
|
531
|
+
: context.types;
|
|
532
|
+
// A `new` on a generic CLASS whose copies can differ in layout: the
|
|
533
|
+
// constructor declares no type parameters of its OWN -- `T` belongs to the
|
|
534
|
+
// class -- so the generic-implementation branch below never fires for one,
|
|
535
|
+
// and the callee was typed in whatever copy of the class the SITE happens to
|
|
536
|
+
// sit inside. Inside `Box<T>.map<R>`, `new Box<R>(...)` was therefore
|
|
537
|
+
// typed as `Box<T>`: the copy the site is IN rather than the copy it
|
|
538
|
+
// NAMES, which is only invisible while every copy shares one struct. The
|
|
539
|
+
// census keys a new-expression on the class (`specialization.ts`), so the
|
|
540
|
+
// site names its own copy exactly as a generic function's call site does.
|
|
541
|
+
const constructedClass = ts.isNewExpression(call) ? constructedGenericClassOf(context, declaration) : null;
|
|
542
|
+
if (constructedClass) {
|
|
543
|
+
const site = context.specializations.specializationAt(call, context.types.substituteTypeParameter);
|
|
544
|
+
if (site && site.declaration === constructedClass) {
|
|
545
|
+
const enclosing = context.identities.prefixFor(constructedClass, context.path).filter((step) => step.owner !== constructedClass);
|
|
546
|
+
const copyTypes = context.types.forSpecialization([...enclosing, { owner: constructedClass, ordinal: site.ordinal }]);
|
|
547
|
+
// The callee EXPRESSION's own type in that copy, not the constructor's
|
|
548
|
+
// resolved signature: `declaration` here is the CLASS (that is what
|
|
549
|
+
// `new Box(...)`'s callee names), which has no implementation
|
|
550
|
+
// signature of its own, and the class's constructor object read in the
|
|
551
|
+
// copy is exactly the `typeof Box` the ordinary path would have read
|
|
552
|
+
// in the wrong one.
|
|
553
|
+
const constructorSignature = declaration && !ts.isClassLike(declaration) ? implementationSignatureOf(context.checker, declaration) : null;
|
|
554
|
+
return constructorSignature ? copyTypes.resolvedSignatureTypeOf(constructorSignature, 'construct') : copyTypes.typeAt(node);
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
// Overload resolution constrains the expression's result, but the callable
|
|
558
|
+
// still implements its body's one physical frame. Publish that frame here;
|
|
559
|
+
// the existing invocation conversion reconciles it with the selected result.
|
|
560
|
+
const implementation = declaration ? implementationSignatureOf(context.checker, declaration) : null;
|
|
561
|
+
if (implementation) {
|
|
562
|
+
// A GENERIC implementation's frame is open, and the view above is the
|
|
563
|
+
// caller's: `some<T>`'s `readonly T[]` read there is the naked hole
|
|
564
|
+
// monomorphization removes, republished at every callee. The copy this
|
|
565
|
+
// call instantiates is the view that binds it -- the specialization
|
|
566
|
+
// census keys the call on the implementation (`specialization.ts`'s
|
|
567
|
+
// `implementationOf`), so the site names the copy and the copy's own
|
|
568
|
+
// substitution closes the frame. A call whose copy was never minted
|
|
569
|
+
// falls back to the checker's instantiated overload, which is closed
|
|
570
|
+
// over the declared overload's frame rather than the body's.
|
|
571
|
+
if ((implementation.getTypeParameters()?.length ?? 0) > 0) {
|
|
572
|
+
const site = context.specializations.specializationAt(call, context.types.substituteTypeParameter);
|
|
573
|
+
if (!site)
|
|
574
|
+
return calleeTypes.resolvedSignatureTypeOf(signature, ts.isNewExpression(call) ? 'construct' : 'call');
|
|
575
|
+
// A generic METHOD of a generic class is copied per (class copy, method
|
|
576
|
+
// copy): `Box<T>.map<R>` has one body per pair. `prefixFor` can only
|
|
577
|
+
// answer with copies the CALL SITE is inside, which for `s.map(...)`
|
|
578
|
+
// written outside the class is none -- so the method's copy was walked
|
|
579
|
+
// with no class copy under it and `this.value` had `T` unbound. The
|
|
580
|
+
// receiver names the class copy; the site names the method's.
|
|
581
|
+
const enclosing = receiverCopy ?? context.identities.prefixFor(site.declaration, context.path);
|
|
582
|
+
const last = enclosing[enclosing.length - 1];
|
|
583
|
+
const isSelfReference = last !== undefined && last.owner === site.declaration && last.ordinal === site.ordinal;
|
|
584
|
+
const copyPath = isSelfReference ? enclosing : [...enclosing, { owner: site.declaration, ordinal: site.ordinal }];
|
|
585
|
+
// The copy is BOTH halves here: the frame is the implementation's and
|
|
586
|
+
// the type arguments are what the copy binds, so the binding path is
|
|
587
|
+
// the copy's own rather than the caller's.
|
|
588
|
+
return context.types
|
|
589
|
+
.forSpecialization(copyPath)
|
|
590
|
+
.resolvedSignatureTypeOf(implementation, ts.isNewExpression(call) ? 'construct' : 'call');
|
|
591
|
+
}
|
|
592
|
+
return calleeTypes.resolvedSignatureTypeOf(implementation, ts.isNewExpression(call) ? 'construct' : 'call');
|
|
593
|
+
}
|
|
594
|
+
// A declaration a host BINDS (`semantics/host-protocols.ts`'s census, read
|
|
595
|
+
// here through `context.hostProtocols`) is a closed, non-generic native
|
|
596
|
+
// protocol -- `Math`, `StringConstructor`, `DateConstructor`, ... -- so its
|
|
597
|
+
// resolved call signature substitutes nothing the plain type does not already
|
|
598
|
+
// state; `deriveShape`'s own `declared`-with-`bound` case
|
|
599
|
+
// (`representation/derive.ts`) reads exactly this plain shape to publish
|
|
600
|
+
// `native-handle`, never the resolved-signature one. Reading the resolved
|
|
601
|
+
// signature back here anyway would lose the one fact the plain type carries
|
|
602
|
+
// that a bare signature cannot: which protocol the declaration is bound to.
|
|
603
|
+
// That loss is not academic -- `String(code)` and `String.fromCharCode(code)`
|
|
604
|
+
// both read the SAME declaration, and `projectBindingPlacements`
|
|
605
|
+
// (`projection/bindings.ts`) places one cell for it from whichever read it
|
|
606
|
+
// sees first. Whichever placement lost, the OTHER read then asks the cell for
|
|
607
|
+
// a load it cannot give. The check is keyed on the PLAIN TYPE AT THE CALLEE
|
|
608
|
+
// NODE and never on the resolved signature's own declaration: a signature is
|
|
609
|
+
// one overload member inside `StringConstructor`, not the `String` binding,
|
|
610
|
+
// so `hostProtocols` -- keyed by binding declaration -- would never match it.
|
|
611
|
+
const plain = calleeTypes.typeAt(node);
|
|
612
|
+
const plainShape = context.table.get(plain).shape;
|
|
613
|
+
// An unchecked call placeholder has no declaration and cannot establish
|
|
614
|
+
// that its callee is callable. Preserve the actual value even when it is
|
|
615
|
+
// nullish/non-callable, so the runtime throws instead of boxing it as an
|
|
616
|
+
// invented function with an `any` result.
|
|
617
|
+
if (isFabricatedSignatureShape(context.checker, signature))
|
|
618
|
+
return arityResolvedOverload(context, plain, call);
|
|
619
|
+
if (plainShape.kind === 'declared' && context.hostProtocols.has(plainShape.declaration))
|
|
620
|
+
return plain;
|
|
621
|
+
// A callee bound to ONE physical function but DECLARED with an overloaded
|
|
622
|
+
// type -- `structural-declarations.ts`'s `physicalOverloadTypeAt`, hono's
|
|
623
|
+
// `export const parseBody: ParseBody = async (request, options = ...) =>
|
|
624
|
+
// {...}` being the exact case that showed it apart. `typeAt` (above, as
|
|
625
|
+
// `plain`) already collapses a REFERENCE to such a binding onto the one
|
|
626
|
+
// physical signature the value actually has at runtime -- the same
|
|
627
|
+
// collapse the binding's own CELL uses, so every plain read of `parseBody`
|
|
628
|
+
// agrees. `getResolvedSignature` does not know about that collapse: TS
|
|
629
|
+
// never resolves an external call to an overloaded declaration's
|
|
630
|
+
// implementation signature, only to one of its declared OVERLOAD
|
|
631
|
+
// signatures (`ParseBody`'s `options?: Partial<ParseBodyOptions>` member,
|
|
632
|
+
// here) -- a real, different ABI from the physical function that actually
|
|
633
|
+
// runs. Reading that resolved overload back below would build a callee
|
|
634
|
+
// carrier the binding's own cell disagrees with: two authorities citing
|
|
635
|
+
// the same one-function value, and the checker's is the one with no
|
|
636
|
+
// runtime referent to back it (`request.ts:217`'s stuck
|
|
637
|
+
// binding-read-conversion obligation was exactly this gap). `plain` is
|
|
638
|
+
// already the answer that matches, so prefer it whenever it exists.
|
|
639
|
+
if (plainShape.kind === 'signature' && physicalOverloadTypeAt(context.checker, node) !== null)
|
|
640
|
+
return plain;
|
|
641
|
+
// The same fact one level out, reached through a MEMBER instead of a
|
|
642
|
+
// binding. `Context.text: TextRespond = (text, arg, headers) => {...}`
|
|
643
|
+
// (hono's `context.ts`) annotates the property with an overload set and
|
|
644
|
+
// initializes it with ONE arrow function -- so the class layout stores one
|
|
645
|
+
// physical convention while `getResolvedSignature` hands back whichever
|
|
646
|
+
// declared overload this call site matched. That is not a narrowing of the
|
|
647
|
+
// stored value: overload resolution is a type-level fiction over a single
|
|
648
|
+
// runtime function (ECMA-262 has no notion of overloads at all), and
|
|
649
|
+
// believing it here mints a second callable carrier for a field the layout
|
|
650
|
+
// already spelled -- which is the `field "text" is stored as ... and this
|
|
651
|
+
// read publishes ...` refusal, verbatim, in `emit-properties.ts`.
|
|
652
|
+
//
|
|
653
|
+
// `physicalOverloadTypeAt` already admits `isPropertyDeclaration` and
|
|
654
|
+
// `isPropertyAssignment`; what it never saw was a property ACCESS, because
|
|
655
|
+
// this is the only caller that holds one. So the member's own declaration is
|
|
656
|
+
// resolved and the existing rule is asked about it -- no new rule, and no
|
|
657
|
+
// second opinion about how many conventions one value has.
|
|
658
|
+
//
|
|
659
|
+
// Deliberately NOT a blanket "a member callee publishes its declared type":
|
|
660
|
+
// `arr.map`'s declared type carries an unbound `<U>` that the enclosing call
|
|
661
|
+
// is what commits, and that commitment is real. An overload set is not a
|
|
662
|
+
// commitment -- there is one function either way.
|
|
663
|
+
const physicalMember = physicalMemberOverloadTypeAt(context, node);
|
|
664
|
+
if (physicalMember !== null)
|
|
665
|
+
return calleeTypes.typeOf(physicalMember);
|
|
666
|
+
// A member reached through a RECEIVER whose type is a parameter this copy
|
|
667
|
+
// binds. TypeScript resolves `operation.weight` on `T`'s apparent type --
|
|
668
|
+
// its CONSTRAINT -- because that is all the language knows about `T` while
|
|
669
|
+
// checking one generic body, so the resolved signature is written over
|
|
670
|
+
// `Operation` however `T` was instantiated. This copy knows more: its
|
|
671
|
+
// receiver really is a `Heavy`, and the member it names is `Heavy`'s own
|
|
672
|
+
// override. Believing the checker here publishes a callee carrier whose
|
|
673
|
+
// receiver is the BASE while the call it accompanies dispatches to the
|
|
674
|
+
// DERIVED body -- `CallableObject<double(Ref<Operation>)>` initialized from
|
|
675
|
+
// `Heavy::weight`'s thunk, two authorities over one value, and clang refuses
|
|
676
|
+
// the pair outright.
|
|
677
|
+
//
|
|
678
|
+
// `typeAt` is the exact answer instead, and not a second opinion: it
|
|
679
|
+
// resolves the member through the receiver's own SUBSTITUTED shape, which is
|
|
680
|
+
// the same walk that chose the derived body. Scoped to a receiver the copy
|
|
681
|
+
// actually binds, so an ordinary member call on a non-generic receiver keeps
|
|
682
|
+
// the checker's answer exactly as before.
|
|
683
|
+
const substitutedMember = substitutedReceiverMemberType(context, node);
|
|
684
|
+
if (substitutedMember !== null)
|
|
685
|
+
return calleeTypes.typeOf(substitutedMember);
|
|
686
|
+
// A callee the program left `any` (or `unknown`) is the one case where the
|
|
687
|
+
// checker committed to NOTHING and still answers. `getResolvedSignature`
|
|
688
|
+
// returns TypeScript's own `anySignature` there -- a fabricated
|
|
689
|
+
// zero-parameter, `any`-returning signature that stands for "this call was
|
|
690
|
+
// not checked", not for a convention anything has. Interning it produces a
|
|
691
|
+
// callable carrier whose ABI declares no parameters at all, so
|
|
692
|
+
// `fn(a, b, c)` acquires a callee that takes none: preflight cannot classify
|
|
693
|
+
// arguments 0..2 against slots that do not exist, and an emitter that got
|
|
694
|
+
// past it would render a three-argument call through a
|
|
695
|
+
// `CallableObject<Value()>`.
|
|
696
|
+
//
|
|
697
|
+
// The plain type is the honest answer: `any` is `dynamic`, the call is a
|
|
698
|
+
// dynamic call, and `gea::Value::callAsFunction` is what performs it. This
|
|
699
|
+
// is a citation of the same rule the function's own header states -- the
|
|
700
|
+
// resolved signature is read back only where the checker really did commit.
|
|
701
|
+
if (plainShape.kind === 'primitive' && (plainShape.primitive === 'any' || plainShape.primitive === 'unknown'))
|
|
702
|
+
return plain;
|
|
703
|
+
// The same rule, reached by the other road, and the guard above cannot see
|
|
704
|
+
// it. That one asks whether the PLAIN type is `any` -- but the plain type is
|
|
705
|
+
// `context.types.typeAt`, which consults the call-site parameter census, and
|
|
706
|
+
// the census exists precisely to answer where the checker did not. So for a
|
|
707
|
+
// callee whose receiver is an unannotated JS parameter -- three.js's ES5
|
|
708
|
+
// factory modules throughout -- the census hands back the real signature
|
|
709
|
+
// while `getResolvedSignature` still hands back TypeScript's fabricated
|
|
710
|
+
// `anySignature`, the guard above misses, and the fabricated one is interned
|
|
711
|
+
// over the top of the real answer. Two authorities, and the wrong one won.
|
|
712
|
+
//
|
|
713
|
+
// Keyed on the CHECKER's own answer, not on the plain type: "the checker
|
|
714
|
+
// committed to nothing here" is the fact that makes its resolved signature
|
|
715
|
+
// meaningless, and it is exactly the fact the census was built to fill in.
|
|
716
|
+
// The fabrication is identified by what it is -- no declaration, no
|
|
717
|
+
// parameters, `any` return -- rather than by parameter count alone, because
|
|
718
|
+
// a genuinely nullary function has all of those but a declaration.
|
|
719
|
+
//
|
|
720
|
+
// Measured: the three.js app 950 -> 714 mandatory missing obligations, of which the
|
|
721
|
+
// unclassified `conversion-role:invocation:call:argument` bucket 538 -> 237.
|
|
722
|
+
if (isFabricatedAnySignature(context.checker, node, signature) && plainShape.kind === 'signature' && plainShape.call.length > 0) {
|
|
723
|
+
return plain;
|
|
724
|
+
}
|
|
725
|
+
// The same fabrication over a callee the program did not declare `any`.
|
|
726
|
+
// TypeScript also declines to check a call whose callee is the global
|
|
727
|
+
// `Function` -- ECMAScript's "some callable, arguments and result unknown"
|
|
728
|
+
// -- and answers with the identical fabricated signature. hono's `compose`
|
|
729
|
+
// is built on exactly that: `middleware: [[Function, unknown], unknown][]`,
|
|
730
|
+
// and `handler(context, () => dispatch(i + 1))` is a two-argument call
|
|
731
|
+
// whose resolved callee declares no parameters at all.
|
|
732
|
+
//
|
|
733
|
+
// Neither guard above can take it: the checker's type is not `any`, and the
|
|
734
|
+
// callee's own shape carries no call signature to prefer over the
|
|
735
|
+
// fabrication -- `Function` declares `apply`/`call`/`bind` and no call
|
|
736
|
+
// signature, so it interns as a record. Interning the fabrication anyway
|
|
737
|
+
// puts a `CallableObject<Value()>` where a two-argument call is, and
|
|
738
|
+
// preflight has no slots to classify the arguments against.
|
|
739
|
+
//
|
|
740
|
+
// `any` is the honest answer, and it is the same one the `any`-callee guard
|
|
741
|
+
// above reaches: the checker committed to nothing, the callee is an
|
|
742
|
+
// arbitrary callable, and what the language performs is a dynamic call.
|
|
743
|
+
if (isFabricatedSignatureShape(context.checker, signature) && !(plainShape.kind === 'signature' && plainShape.call.length > 0)) {
|
|
744
|
+
return context.table.intern({ kind: 'primitive', primitive: 'any' });
|
|
745
|
+
}
|
|
746
|
+
// An optional call's resolved signature carries the chain's `undefined` in
|
|
747
|
+
// its return, which is a fact about the call expression rather than about
|
|
748
|
+
// this callee: the method returns what it declares, and does not run at all
|
|
749
|
+
// on the other branch. Believing the augmented return here would build a
|
|
750
|
+
// callee carrier the real method has no store into.
|
|
751
|
+
const presentReturn = isShortCircuitingCall(call) ? presentReturnTypeOf(context.checker, signature) : undefined;
|
|
752
|
+
return calleeTypes.resolvedSignatureTypeOf(signature, ts.isNewExpression(call) ? 'construct' : 'call', presentReturn);
|
|
753
|
+
};
|
|
754
|
+
export const calleeAwareTypeAt = (context, node) => {
|
|
755
|
+
const call = enclosingCallIfCallee(node);
|
|
756
|
+
// A callee that is its own call's short-circuit guard keeps its own type.
|
|
757
|
+
// `host.raf?.(cb)` tests `host.raf`, whose value genuinely is `fn |
|
|
758
|
+
// undefined`, and collapsing it to the signature it would have *if it ran*
|
|
759
|
+
// erases the very thing the operator branches on: the presence test then has
|
|
760
|
+
// nothing optional to ask about, folds to a constant `true`, and the call
|
|
761
|
+
// runs unconditionally. The narrowed, callable shape is a fact about the
|
|
762
|
+
// call's own operand -- `resolvedCalleeSignatureType`, which the invocation
|
|
763
|
+
// producer asks for directly -- not about what this expression evaluates to.
|
|
764
|
+
if (call && ts.isCallExpression(call) && call.questionDotToken !== undefined)
|
|
765
|
+
return context.types.typeAt(node);
|
|
766
|
+
return resolvedCalleeSignatureType(context, node) ?? context.types.typeAt(node);
|
|
767
|
+
};
|
|
768
|
+
/**
|
|
769
|
+
* Whether a structural type is a plain `T[]`/`Array<T>` -- never a tuple,
|
|
770
|
+
* never a union, never an interned `unresolved`.
|
|
771
|
+
*
|
|
772
|
+
* This is the one predicate that decides whether a spread or a destructuring
|
|
773
|
+
* pattern's source may take the array/string fast path (index reads,
|
|
774
|
+
* `appendRange`) instead of needing the general iterator protocol. A tuple's
|
|
775
|
+
* elements are individually typed and keyed by position, not a single
|
|
776
|
+
* repeated element type, so it is deliberately excluded even though it is
|
|
777
|
+
* also array-shaped at runtime -- `lower-allocation.ts`'s own tuple-vs-array
|
|
778
|
+
* carrier split already draws this exact line, and this predicate answers it
|
|
779
|
+
* from the same source of truth (the interned shape), not a second opinion.
|
|
780
|
+
*/
|
|
781
|
+
export const isPlainArrayType = (context, type) => {
|
|
782
|
+
const shape = context.table.get(type).shape;
|
|
783
|
+
if (shape.kind === 'array')
|
|
784
|
+
return true;
|
|
785
|
+
// A named array -- `NodeArray<T> extends ReadonlyArray<T>`, whose declared
|
|
786
|
+
// body `structural.ts`'s `arrayHeritageShapeOf` lays out as the array it is
|
|
787
|
+
// -- iterates exactly as the array does: the fields it adds live beside the
|
|
788
|
+
// elements (`gea::ArrayObject::extension`), not in them. Read through the
|
|
789
|
+
// anchor rather than answered `false`, which minted a `get-method` step no
|
|
790
|
+
// manifest claims and refused every `for (const p of parameters)` in tsc.
|
|
791
|
+
if (shape.kind !== 'declared' || shape.body === null)
|
|
792
|
+
return false;
|
|
793
|
+
return context.table.get(shape.body).shape.kind === 'array';
|
|
794
|
+
};
|
|
795
|
+
/**
|
|
796
|
+
* The members an object spread copies, when the source's own-property set is
|
|
797
|
+
* statically known -- or the reason it is not.
|
|
798
|
+
*
|
|
799
|
+
* `{ ...a }` is `CopyDataProperties` (ECMA-262 7.3.25) over the source's OWN
|
|
800
|
+
* ENUMERABLE properties, and for a data-only object shape that set is exactly
|
|
801
|
+
* its members. This is the one authority on when that holds, asked by BOTH
|
|
802
|
+
* halves that must agree about it: `producers/allocations.ts` copies the
|
|
803
|
+
* members field by field, and `producers/protocol.ts` publishes its generic
|
|
804
|
+
* `spread` protocol operation only when this says no -- the same bypass shape,
|
|
805
|
+
* and for the same reason, that `isPlainArrayType` gives an array-literal
|
|
806
|
+
* spread. Two independent predicates here would let one half copy the fields
|
|
807
|
+
* while the other published a protocol step nothing lowers.
|
|
808
|
+
*
|
|
809
|
+
* A named interface interns as `declared` around its body; the BODY carries the
|
|
810
|
+
* members, so one level is unwrapped. Every other shape -- and every member
|
|
811
|
+
* this cannot copy correctly -- answers with a reason instead:
|
|
812
|
+
*
|
|
813
|
+
* - an INDEX SIGNATURE: the own-property set is not known until runtime, and
|
|
814
|
+
* copying only the declared members would silently drop the rest;
|
|
815
|
+
* - an ACCESSOR: `{ ...o }` copies a getter's RETURNED value, so it must be
|
|
816
|
+
* called, which is user code this layer does not invoke;
|
|
817
|
+
* - a `signature`-shaped member: a method on a class instance lives on the
|
|
818
|
+
* prototype and is not own-enumerable at all, and the shape alone cannot
|
|
819
|
+
* tell that from an own function-valued field;
|
|
820
|
+
* - `membersDropped`: a projection already filtered this body, so its member
|
|
821
|
+
* list is not the source's own-property set (see `representation/object-shape.ts`);
|
|
822
|
+
* - a SYMBOL key: `CopyDataProperties` skips a non-enumerable one, and the
|
|
823
|
+
* shape does not record enumerability.
|
|
824
|
+
*/
|
|
825
|
+
export const staticSpreadMembersOf = (context, type) => {
|
|
826
|
+
const outer = context.table.get(type).shape;
|
|
827
|
+
const shape = outer.kind === 'declared' && outer.body !== null ? context.table.get(outer.body).shape : outer;
|
|
828
|
+
// `...(parsed ? { resolutionMode: parsed } : {})` (tsc's parser.ts, and an
|
|
829
|
+
// idiom everywhere): the source is a UNION of object literals, and the
|
|
830
|
+
// checker has already normalized it so every arm carries every key --
|
|
831
|
+
// `{ resolutionMode: string } | { resolutionMode?: undefined }`. Whichever
|
|
832
|
+
// arm is live, `CopyDataProperties` copies that arm's own members, so the
|
|
833
|
+
// union's static member set is the union of the arms': a key every arm
|
|
834
|
+
// states with one type keeps it, a key whose arms disagree reads as the
|
|
835
|
+
// union of their types, and a key some arm lacks is optional and carries
|
|
836
|
+
// `undefined` for that arm. Every arm is held to the same conditions as a
|
|
837
|
+
// lone object source; one arm this cannot copy blocks the whole spread.
|
|
838
|
+
if (shape.kind === 'union') {
|
|
839
|
+
const merged = new Map();
|
|
840
|
+
const arms = [];
|
|
841
|
+
for (const arm of shape.members) {
|
|
842
|
+
const admitted = staticSpreadMembersOf(context, arm);
|
|
843
|
+
if ('blocked' in admitted)
|
|
844
|
+
return admitted;
|
|
845
|
+
arms.push(admitted.members);
|
|
846
|
+
}
|
|
847
|
+
for (const members of arms) {
|
|
848
|
+
for (const member of members) {
|
|
849
|
+
if (member.key.kind === 'symbol')
|
|
850
|
+
continue;
|
|
851
|
+
const key = String(member.key.value);
|
|
852
|
+
const entry = merged.get(key);
|
|
853
|
+
if (entry === undefined) {
|
|
854
|
+
merged.set(key, { member, types: [member.type], optional: member.optional, seen: 1 });
|
|
855
|
+
continue;
|
|
856
|
+
}
|
|
857
|
+
if (!entry.types.includes(member.type))
|
|
858
|
+
entry.types.push(member.type);
|
|
859
|
+
entry.optional ||= member.optional;
|
|
860
|
+
entry.seen += 1;
|
|
861
|
+
}
|
|
862
|
+
}
|
|
863
|
+
const undefinedType = context.table.intern({ kind: 'primitive', primitive: 'undefined' });
|
|
864
|
+
const members = [];
|
|
865
|
+
for (const entry of merged.values()) {
|
|
866
|
+
const absentSomewhere = entry.seen < arms.length;
|
|
867
|
+
const types = absentSomewhere && !entry.types.includes(undefinedType) ? [...entry.types, undefinedType] : entry.types;
|
|
868
|
+
const sole = types.length === 1 ? types[0] : undefined;
|
|
869
|
+
const memberType = sole ?? context.table.intern({ kind: 'union', members: types });
|
|
870
|
+
members.push({ ...entry.member, type: memberType, optional: entry.optional || absentSomewhere });
|
|
871
|
+
}
|
|
872
|
+
return { members };
|
|
873
|
+
}
|
|
874
|
+
if (shape.kind !== 'object') {
|
|
875
|
+
return { blocked: `an object spread of a "${shape.kind}"-shaped source has no statically known own-property set` };
|
|
876
|
+
}
|
|
877
|
+
if (shape.membersDropped) {
|
|
878
|
+
return { blocked: "an object spread of a projected (data-only) body cannot state the source's own-property set" };
|
|
879
|
+
}
|
|
880
|
+
if (shape.index.length > 0) {
|
|
881
|
+
return { blocked: 'an object spread of a source with an index signature needs the runtime own-property enumeration' };
|
|
882
|
+
}
|
|
883
|
+
for (const member of shape.members) {
|
|
884
|
+
const key = member.key.kind === 'symbol' ? `symbol ${member.key.declaration}` : String(member.key.value);
|
|
885
|
+
if (member.accessor !== null) {
|
|
886
|
+
return { blocked: `an object spread of a source with the accessor "${key}" must call it, which is not modelled` };
|
|
887
|
+
}
|
|
888
|
+
if (context.table.get(member.type).shape.kind === 'signature') {
|
|
889
|
+
return {
|
|
890
|
+
blocked: `an object spread of a source whose member "${key}" is callable cannot tell an own function-valued field ` +
|
|
891
|
+
'from a prototype method, and only the first is copied'
|
|
892
|
+
};
|
|
893
|
+
}
|
|
894
|
+
if (member.key.kind === 'symbol') {
|
|
895
|
+
return { blocked: `an object spread of a source with the symbol-keyed member "${key}" needs its enumerability` };
|
|
896
|
+
}
|
|
897
|
+
}
|
|
898
|
+
return { members: shape.members };
|
|
899
|
+
};
|
|
900
|
+
/**
|
|
901
|
+
* Whether a structural type is the standard `Set<T>` -- the second source
|
|
902
|
+
* whose iteration needs no dynamic `@@iterator` lookup.
|
|
903
|
+
*
|
|
904
|
+
* The sibling of `isPlainArrayType` above, answering the same question about a
|
|
905
|
+
* shape whose answer is a DECLARATION identity rather than a shape kind. It
|
|
906
|
+
* reads `context.keyedCollections`, the frontend's one census
|
|
907
|
+
* (`host-protocols.ts`'s `keyedCollectionDeclarationsOf`), which is also what
|
|
908
|
+
* `representation/derive.ts` selects the collection carrier from -- so the
|
|
909
|
+
* producer's "skip the method lookup" decision and the carrier's "this is a
|
|
910
|
+
* `keyed-collection`" decision can never be made about different declarations.
|
|
911
|
+
*
|
|
912
|
+
* `'set'` ONLY -- `isNativeIterableMapType` below answers the Map half, which
|
|
913
|
+
* needs a different fact from the carrier side and so cannot share one
|
|
914
|
+
* predicate. The weak families have no iteration at all (ECMA-262 24.3/24.4)
|
|
915
|
+
* and are covered by neither.
|
|
916
|
+
*/
|
|
917
|
+
export const isNativeIterableSetType = (context, type) => {
|
|
918
|
+
const shape = context.table.get(type).shape;
|
|
919
|
+
return shape.kind === 'declared' && context.keyedCollections.get(shape.declaration) === 'set';
|
|
920
|
+
};
|
|
921
|
+
/**
|
|
922
|
+
* Whether a structural type is the standard `Map<K, V>` -- the fourth source
|
|
923
|
+
* whose iteration needs no dynamic `@@iterator` lookup, and the only one whose
|
|
924
|
+
* element is not storage the source already holds.
|
|
925
|
+
*
|
|
926
|
+
* ECMA-262 24.1.5.1 `%MapIteratorPrototype%.next` yields a `[K, V]` PAIR, and
|
|
927
|
+
* this compiler carries a tuple as a record of "0"/"1" fields. That is why the
|
|
928
|
+
* decision has two halves that must agree: this one, which says the census may
|
|
929
|
+
* skip the method lookup, and `representation/publish.ts`'s
|
|
930
|
+
* `nativeCursorIteratorOf`, which must be able to publish a cursor over the
|
|
931
|
+
* pair's own carrier. The carrier side is the stricter of the two -- it reads
|
|
932
|
+
* the pair's record layout back out of the iterator record's declared element
|
|
933
|
+
* type and refuses unless the fields really are "0"/"1" carrying the
|
|
934
|
+
* collection's own key and value -- so a Map whose pair this compiler cannot
|
|
935
|
+
* lay out publishes no cursor, keys as the unclaimed
|
|
936
|
+
* `protocol:iterator:next:record`, and refuses at preflight. Skipping the
|
|
937
|
+
* method lookup for it is therefore safe in the one direction that matters:
|
|
938
|
+
* it can only ever cost a refusal, never a wrong lowering.
|
|
939
|
+
*/
|
|
940
|
+
export const isNativeIterableMapType = (context, type) => {
|
|
941
|
+
const shape = context.table.get(type).shape;
|
|
942
|
+
return shape.kind === 'declared' && context.keyedCollections.get(shape.declaration) === 'map';
|
|
943
|
+
};
|
|
944
|
+
/** A `Map.prototype.entries()` result is already the native pair cursor. */
|
|
945
|
+
const isNativeMapIteratorType = (context, type) => {
|
|
946
|
+
const shape = context.table.get(type).shape;
|
|
947
|
+
return shape.kind === 'declared' && shape.declaration === context.mapIteratorDeclaration;
|
|
948
|
+
};
|
|
949
|
+
/**
|
|
950
|
+
* Whether a structural type is a `string` -- the third source whose iteration
|
|
951
|
+
* needs no dynamic `@@iterator` lookup.
|
|
952
|
+
*
|
|
953
|
+
* ECMA-262 22.1.3.36 `String.prototype[@@iterator]` walks the receiver by CODE
|
|
954
|
+
* POINT, and a String is an immutable primitive, so the step sequence is fixed
|
|
955
|
+
* the moment the loop starts: there is nothing for `GetIterator` to resolve
|
|
956
|
+
* that the value itself does not already answer. `gea::Iterator<std::string>`'s
|
|
957
|
+
* string source (`runtime/gea_runtime.h`) is that walk.
|
|
958
|
+
*
|
|
959
|
+
* Deliberately narrower than "everything that CARRIES as `string`": a union of
|
|
960
|
+
* string literals collapses to the `string` carrier in `derive.ts`, and this
|
|
961
|
+
* answers `false` for it. That asymmetry is safe in exactly one direction --
|
|
962
|
+
* `publish.ts` would publish the cursor, this producer would still mint the
|
|
963
|
+
* `get-method` step, and `protocol:iterator:get-method:string` is claimed by no
|
|
964
|
+
* manifest, so the program refuses at preflight by name. The reverse (claiming
|
|
965
|
+
* the fast path for a shape whose carrier is not `string`) would emit a
|
|
966
|
+
* constructor call that does not exist, so the predicate is written to fail in
|
|
967
|
+
* the safe direction rather than to re-derive `deriveUnion`'s collapse rule as
|
|
968
|
+
* a second authority.
|
|
969
|
+
*/
|
|
970
|
+
export const isNativeIterableStringType = (context, type) => {
|
|
971
|
+
const shape = context.table.get(type).shape;
|
|
972
|
+
if (shape.kind === 'primitive')
|
|
973
|
+
return shape.primitive === 'string';
|
|
974
|
+
return shape.kind === 'literal' && shape.primitive === 'string';
|
|
975
|
+
};
|
|
976
|
+
/**
|
|
977
|
+
* Whether a source is a tuple with a fixed arity -- every element at a known
|
|
978
|
+
* position, none of them rest or variadic.
|
|
979
|
+
*
|
|
980
|
+
* A tuple IS an Array at runtime, so `for (const x of ['a', 'b'] as const)` is
|
|
981
|
+
* ordinary TypeScript that every JavaScript engine iterates through
|
|
982
|
+
* `Array.prototype[Symbol.iterator]`. This compiler carries a tuple as "a
|
|
983
|
+
* record whose keys are its indices" (`derive.ts`'s `deriveTuple`), which has
|
|
984
|
+
* no `@@iterator` FIELD, so the general dynamic protocol correctly refused
|
|
985
|
+
* every such loop -- nine of them in the mongodb driver alone, each over a
|
|
986
|
+
* `const [...] as const` option list.
|
|
987
|
+
*
|
|
988
|
+
* A fixed arity is what makes the walk settled: the elements are the record's
|
|
989
|
+
* own fields, in order, known before the program runs. Whether they also share
|
|
990
|
+
* ONE element carrier is a question about representations, which this layer
|
|
991
|
+
* cannot ask -- `preflight/runtime-helper-key.ts`'s `iteratorMethodCarrierKind`
|
|
992
|
+
* refines the carrier per site and leaves a heterogeneous tuple on an
|
|
993
|
+
* unclaimed key, so it refuses at preflight rather than reaching an emitter
|
|
994
|
+
* with nothing to build.
|
|
995
|
+
*/
|
|
996
|
+
export const isFixedArityTupleType = (context, type) => {
|
|
997
|
+
const shape = context.table.get(type).shape;
|
|
998
|
+
return shape.kind === 'tuple' && shape.elements.every((element) => !element.rest && !element.variadic);
|
|
999
|
+
};
|
|
1000
|
+
/**
|
|
1001
|
+
* A tuple with a `rest` position and no variadic one -- `[A, ...B[]]`. Its
|
|
1002
|
+
* carrier is an ARRAY (`representation/derive.ts`'s `deriveTuple`: the array
|
|
1003
|
+
* carrier over the union of its positions), so iterating it is the array's
|
|
1004
|
+
* own native cursor, the same one a plain `T[]` has.
|
|
1005
|
+
*/
|
|
1006
|
+
export const isOpenTupleType = (context, type) => {
|
|
1007
|
+
const shape = context.table.get(type).shape;
|
|
1008
|
+
return shape.kind === 'tuple' && shape.elements.some((element) => element.rest) && !shape.elements.some((element) => element.variadic);
|
|
1009
|
+
};
|
|
1010
|
+
/**
|
|
1011
|
+
* Whether a source's iteration is settled before the program runs -- an
|
|
1012
|
+
* `array`, a `Set<T>`, a `Map<K, V>`, a `string`, a `Generator<T, ...>`, a
|
|
1013
|
+
* fixed-arity tuple, or a union whose every present arm is one of those.
|
|
1014
|
+
*
|
|
1015
|
+
* The ONE predicate every consumer of the native iterator cursor asks, so that
|
|
1016
|
+
* `for`-`of` (`control.ts`), array-literal spread (`allocations.ts`),
|
|
1017
|
+
* call-argument spread (`spread-arguments.ts`, `protocol.ts`) and array
|
|
1018
|
+
* destructuring (`destructuring.ts`) can never disagree about which sources it
|
|
1019
|
+
* covers. They did disagree before it existed: a `for`-`of` over a `Set` took
|
|
1020
|
+
* the fast path while `[...set]` in the same program minted a `get-method`
|
|
1021
|
+
* step for the identical value and refused.
|
|
1022
|
+
*/
|
|
1023
|
+
/**
|
|
1024
|
+
* The one PRESENT arm of a union whose only other arms are absent -- `T[] |
|
|
1025
|
+
* undefined`, `Set<T> | null` -- or `null` for every other shape.
|
|
1026
|
+
*
|
|
1027
|
+
* Iterating an absent value is a runtime `TypeError` in ECMA-262 (7.4.2
|
|
1028
|
+
* `GetIterator` calls `GetMethod` on `undefined`, which throws), never a
|
|
1029
|
+
* static impossibility, so `T[] | undefined` iterates through exactly the
|
|
1030
|
+
* cursor `T[]` does with a presence assertion in front of it. The ONLY thing
|
|
1031
|
+
* absence changes is whether the walk starts.
|
|
1032
|
+
*
|
|
1033
|
+
* That distinction is the reason this looks through the wrapper rather than
|
|
1034
|
+
* `hasNativeIterationCursor` growing an arm per absent-shaped source: the
|
|
1035
|
+
* cursor, its element and every capability claim behind it are the payload's,
|
|
1036
|
+
* and the absence is a separate, single fact the backend spells once
|
|
1037
|
+
* (`targets/cpp/emit-iterator.ts`'s presence assertion) for whichever payload
|
|
1038
|
+
* shape it wraps.
|
|
1039
|
+
*
|
|
1040
|
+
* Exactly one present arm, deliberately. Two would be a real union needing a
|
|
1041
|
+
* discriminated walk -- a question about representations this layer cannot
|
|
1042
|
+
* ask -- and zero is `never`, which iterates nothing.
|
|
1043
|
+
*/
|
|
1044
|
+
export const presentIterationArm = (context, type) => {
|
|
1045
|
+
const shape = context.table.get(type).shape;
|
|
1046
|
+
if (shape.kind !== 'union')
|
|
1047
|
+
return null;
|
|
1048
|
+
const present = [];
|
|
1049
|
+
for (const member of shape.members) {
|
|
1050
|
+
const arm = context.table.get(member).shape;
|
|
1051
|
+
if (arm.kind === 'primitive' && (arm.primitive === 'undefined' || arm.primitive === 'null'))
|
|
1052
|
+
continue;
|
|
1053
|
+
present.push(member);
|
|
1054
|
+
}
|
|
1055
|
+
const only = present.length === 1 ? present[0] : undefined;
|
|
1056
|
+
return only !== undefined && present.length < shape.members.length ? only : null;
|
|
1057
|
+
};
|
|
1058
|
+
export const hasNativeIterationCursor = (context, type) => {
|
|
1059
|
+
if (isPlainArrayType(context, type) ||
|
|
1060
|
+
isNativeIterableSetType(context, type) ||
|
|
1061
|
+
isNativeIterableMapType(context, type) ||
|
|
1062
|
+
isNativeIterableStringType(context, type) ||
|
|
1063
|
+
isGeneratorType(context, type) ||
|
|
1064
|
+
isNativeMapIteratorType(context, type) ||
|
|
1065
|
+
isFixedArityTupleType(context, type) ||
|
|
1066
|
+
isOpenTupleType(context, type)) {
|
|
1067
|
+
return true;
|
|
1068
|
+
}
|
|
1069
|
+
// An absent source does not lose the cursor its payload has; see
|
|
1070
|
+
// `presentIterationArm`. Asked here, in THE predicate every consumer of the
|
|
1071
|
+
// native cursor shares, so `for`-`of`, spread and array destructuring can no
|
|
1072
|
+
// more disagree about `T[] | undefined` than they can about a bare `Set`.
|
|
1073
|
+
const payload = iterationPayloadArm(context, type);
|
|
1074
|
+
if (payload !== null)
|
|
1075
|
+
return hasNativeIterationCursor(context, payload);
|
|
1076
|
+
// Every present arm is an array, though not the same one: `name.elements`
|
|
1077
|
+
// over `ObjectBindingPattern | ArrayBindingPattern` is `NodeArray<
|
|
1078
|
+
// BindingElement> | NodeArray<ArrayBindingElement>`. Whether those are one
|
|
1079
|
+
// carrier is the deriver's question, not this one's: when the element
|
|
1080
|
+
// layouts agree (tsc's `Node` family is ONE layout) it collapses the union
|
|
1081
|
+
// to one `array-object`, and answering "no cursor" here minted a
|
|
1082
|
+
// `get-method` step no manifest claims -- 19 `for (const element of
|
|
1083
|
+
// name.elements)` rows on the self-compile. When they do not agree the
|
|
1084
|
+
// carrier is a tagged union, and the native path refuses that BY NAME at
|
|
1085
|
+
// the manifest (`get-iterator:tagged-union`), so saying "cursor" never
|
|
1086
|
+
// certifies a discriminated walk this backend has not built.
|
|
1087
|
+
const arms = presentUnionArms(context, type);
|
|
1088
|
+
if (arms === null)
|
|
1089
|
+
return false;
|
|
1090
|
+
if (arms.every((arm) => isPlainArrayType(context, arm)))
|
|
1091
|
+
return true;
|
|
1092
|
+
// Every present arm a FIXED-ARITY TUPLE -- hono's `Result<T> = [[T,
|
|
1093
|
+
// ParamIndexMap][], ParamStash] | [[T, Params][]]`, whose `.map` callback
|
|
1094
|
+
// binds `[T, ParamIndexMap] | [T, Params]`. Each arm's shape is closed and
|
|
1095
|
+
// known at compile time, which is the whole of what "settled before the
|
|
1096
|
+
// program runs" asks, so the union is as settled as the lone tuple two
|
|
1097
|
+
// lines up: `ir/lower-destructuring.ts`'s `isTupleUnionCarrier` already
|
|
1098
|
+
// reads position `i` off whichever arm is live, with no iterator record in
|
|
1099
|
+
// between. Answering "no cursor" here sent the pattern through the general
|
|
1100
|
+
// protocol instead, and its element steps then read position 0 of the
|
|
1101
|
+
// ITERATOR RECORD the protocol published -- a `record` whose layout has no
|
|
1102
|
+
// field keyed "0", which is how `request.ts`'s `routePath` refused.
|
|
1103
|
+
// A union mixing arms of different KINDS stays false: the carrier is a
|
|
1104
|
+
// tagged union the native path refuses by name, exactly as above.
|
|
1105
|
+
return arms.every((arm) => isFixedArityTupleType(context, arm));
|
|
1106
|
+
};
|
|
1107
|
+
const presentUnionArms = (context, type) => {
|
|
1108
|
+
const shape = context.table.get(type).shape;
|
|
1109
|
+
if (shape.kind !== 'union')
|
|
1110
|
+
return null;
|
|
1111
|
+
const present = [];
|
|
1112
|
+
for (const member of shape.members) {
|
|
1113
|
+
const arm = context.table.get(member).shape;
|
|
1114
|
+
if (arm.kind === 'primitive' && (arm.primitive === 'undefined' || arm.primitive === 'null'))
|
|
1115
|
+
continue;
|
|
1116
|
+
present.push(member);
|
|
1117
|
+
}
|
|
1118
|
+
return present.length > 1 ? present : null;
|
|
1119
|
+
};
|
|
1120
|
+
/**
|
|
1121
|
+
* A union with exactly one DISTINCT present arm is that arm.
|
|
1122
|
+
*
|
|
1123
|
+
* `presentIterationArm` answers only the absence-wrapped shape, and refuses a
|
|
1124
|
+
* union it removed nothing from. A union the checker built from a property
|
|
1125
|
+
* read over a union receiver -- `name.elements` over `ObjectBindingPattern |
|
|
1126
|
+
* ArrayBindingPattern` -- interns to a one-member union when the arms intern
|
|
1127
|
+
* alike, a shape `isPlainArrayType` does not see through, and the refused rows
|
|
1128
|
+
* read `protocol:iterator:get-method:array-object`: an operand the deriver
|
|
1129
|
+
* had called one array while this predicate had called a union.
|
|
1130
|
+
*
|
|
1131
|
+
* Exactly one distinct arm, deliberately, and NOT "every arm is an array":
|
|
1132
|
+
* two arrays over different elements are two C++ carriers, the union of them
|
|
1133
|
+
* is a tagged union, and iterating it is a discriminated walk this backend
|
|
1134
|
+
* has not built -- that source reaches the manifest under
|
|
1135
|
+
* `get-iterator:tagged-union`, which nothing claims, and refuses there by
|
|
1136
|
+
* name. Saying "cursor" for it here would only move the same refusal.
|
|
1137
|
+
*/
|
|
1138
|
+
const soleDistinctPresentArm = (context, type) => {
|
|
1139
|
+
const shape = context.table.get(type).shape;
|
|
1140
|
+
if (shape.kind !== 'union')
|
|
1141
|
+
return null;
|
|
1142
|
+
const present = new Set();
|
|
1143
|
+
for (const member of shape.members) {
|
|
1144
|
+
const arm = context.table.get(member).shape;
|
|
1145
|
+
if (arm.kind === 'primitive' && (arm.primitive === 'undefined' || arm.primitive === 'null'))
|
|
1146
|
+
continue;
|
|
1147
|
+
present.add(member);
|
|
1148
|
+
}
|
|
1149
|
+
const [only, ...rest] = present;
|
|
1150
|
+
return only !== undefined && rest.length === 0 ? only : null;
|
|
1151
|
+
};
|
|
1152
|
+
/**
|
|
1153
|
+
* The type an iteration actually reads FROM, once a union that names one real
|
|
1154
|
+
* iterable has been peeled to it.
|
|
1155
|
+
*
|
|
1156
|
+
* ONE authority, because two questions are asked about this same peeled type
|
|
1157
|
+
* and they must not be able to disagree: `hasNativeIterationCursor` below asks
|
|
1158
|
+
* whether it has a native cursor, and `producers/protocol.ts`'s
|
|
1159
|
+
* `iterationElementType` asks what that cursor yields. Those are the two
|
|
1160
|
+
* callers, and they are the only two.
|
|
1161
|
+
*
|
|
1162
|
+
* They HAD disagreed, in three different spellings of the same peel:
|
|
1163
|
+
* `presentIterationArm` answers only when something nullish was actually
|
|
1164
|
+
* removed, `soleDistinctPresentArm` dedupes members first, and
|
|
1165
|
+
* `iterationElementType` carried a third, inline copy that did neither. A
|
|
1166
|
+
* union whose arms intern to ONE id (`NodeArray<BindingElement> |
|
|
1167
|
+
* NodeArray<ArrayBindingElement>`, tsc's `Node` family being one layout) is
|
|
1168
|
+
* peeled by the deduping spelling and not by the inline one -- so the cursor
|
|
1169
|
+
* predicate said "native cursor, no dynamic `Symbol.iterator` lookup needed"
|
|
1170
|
+
* while the element reader fell through to the checker walk and refused with
|
|
1171
|
+
* `the source declares no @@iterator/next/IteratorResult chain this can read
|
|
1172
|
+
* an element type from`. That is `nested-array-assignment-pattern.runtime.js`'s
|
|
1173
|
+
* for-`of` arm: a certified cursor whose element type nothing could state.
|
|
1174
|
+
*
|
|
1175
|
+
* Returns `null` when the type is not such a union at all -- the caller then
|
|
1176
|
+
* uses the type it already had, which is what both callers did before.
|
|
1177
|
+
*/
|
|
1178
|
+
export const iterationPayloadArm = (context, type) => {
|
|
1179
|
+
const nullishPeeled = presentIterationArm(context, type) ?? soleDistinctPresentArm(context, type);
|
|
1180
|
+
if (nullishPeeled !== null)
|
|
1181
|
+
return nullishPeeled;
|
|
1182
|
+
// SEVERAL present arms, exactly ONE of them iterable. `[, [g, h]] = pair`
|
|
1183
|
+
// over an untyped `var pairs = [[1, [2, 3]], ...]` reads a position typed
|
|
1184
|
+
// `number | number[] | undefined`: peeling the nullish arm still leaves two,
|
|
1185
|
+
// so the spellings above decline -- and every shape check downstream then
|
|
1186
|
+
// fails to recognize `union` at all.
|
|
1187
|
+
//
|
|
1188
|
+
// The representation and IR layers already committed to reading that one
|
|
1189
|
+
// arm: `representation/publish.ts`'s `patternSourceArmOf` publishes
|
|
1190
|
+
// `soleArrayPatternCapableArm`, and `ir/lower-destructuring.ts` emits the
|
|
1191
|
+
// `require-tagged-union-arm` guard that makes the read sound at runtime.
|
|
1192
|
+
// Answering `null` here left the two halves disagreeing in the worst
|
|
1193
|
+
// direction: the element type refused, and once it did not, the cursor
|
|
1194
|
+
// predicate still said "no native cursor" and minted a fully dynamic
|
|
1195
|
+
// `get-method` step that no IR primitive lowers. One arm, one answer, both
|
|
1196
|
+
// callers.
|
|
1197
|
+
//
|
|
1198
|
+
// Strictly one: two iterable arms is a real question about which applies,
|
|
1199
|
+
// and the caller's own refusal stays the honest answer. Recursion through
|
|
1200
|
+
// `hasNativeIterationCursor` terminates because a union's members are
|
|
1201
|
+
// interned flattened, so an arm is never the union it came from.
|
|
1202
|
+
const shape = context.table.get(type).shape;
|
|
1203
|
+
if (shape.kind !== 'union')
|
|
1204
|
+
return null;
|
|
1205
|
+
const iterable = new Set(shape.members.filter((member) => hasNativeIterationCursor(context, member)));
|
|
1206
|
+
const [only, ...rest] = iterable;
|
|
1207
|
+
return only !== undefined && rest.length === 0 ? only : null;
|
|
1208
|
+
};
|
|
1209
|
+
/**
|
|
1210
|
+
* Whether an object body's own member list is a COMPLETE, safe field-name
|
|
1211
|
+
* snapshot -- the one question every branch of `hasNativeEnumerationCursor`
|
|
1212
|
+
* below asks once it has a body to look at.
|
|
1213
|
+
*
|
|
1214
|
+
* Two shapes of MEMBER LOSS have to be refused, because either one would make
|
|
1215
|
+
* a static field-name walk enumerate fewer keys than the value actually has
|
|
1216
|
+
* -- a silently WRONG answer once compiled and run, not a crash:
|
|
1217
|
+
*
|
|
1218
|
+
* - `membersDropped`: `structural.ts`'s own `MemberMode` filtering (an
|
|
1219
|
+
* ambient/host declaration's methods, or an object-literal anchor's own
|
|
1220
|
+
* callable members) already dropped some of the type's own properties
|
|
1221
|
+
* from this body before it ever reached here, so the compile-time field
|
|
1222
|
+
* list this walk would build is incomplete by construction.
|
|
1223
|
+
* - an ACCESSOR member: `representation/derive.ts`'s `recordFieldsOf` filters
|
|
1224
|
+
* `member.accessor !== null` out of the record's own `fields` (a getter's
|
|
1225
|
+
* value must be CALLED, which `records.ts`'s static dispatcher does not
|
|
1226
|
+
* do), so a getter's key would silently vanish from the enumeration the
|
|
1227
|
+
* same way a dropped method's would.
|
|
1228
|
+
*
|
|
1229
|
+
* A SYMBOL-keyed member needs no such exclusion: ECMA-262 14.7.5.9
|
|
1230
|
+
* `EnumerateObjectProperties` walks STRING keys only, so a symbol member is
|
|
1231
|
+
* correctly invisible to `for`-`in` regardless of whether the static
|
|
1232
|
+
* dispatcher lists it. A body with zero members (after the dictionary case
|
|
1233
|
+
* above has already claimed the one shape that means) is a legitimate,
|
|
1234
|
+
* trivially-complete snapshot -- an empty record enumerates no keys, which is
|
|
1235
|
+
* exactly right, not a reason to refuse.
|
|
1236
|
+
*/
|
|
1237
|
+
const isCompleteRecordBody = (body) => !body.membersDropped && body.members.every((member) => member.accessor === null);
|
|
1238
|
+
/**
|
|
1239
|
+
* Whether a `for`-`in` over this source enumerates one of the NATIVE cursors
|
|
1240
|
+
* `targets/cpp/emit-iterator.ts` renders: a runtime key TABLE
|
|
1241
|
+
* (`gea::Dictionary<V>`), a STATIC field-name snapshot built from a
|
|
1242
|
+
* statically shaped receiver's own compile-time member set
|
|
1243
|
+
* (`emitStaticEnumerateIterator`, over `gea::nativeDynamicKeys`), or a
|
|
1244
|
+
* genuinely DYNAMIC receiver's real own-enumerable-key walk
|
|
1245
|
+
* (`emitDynamicEnumerateIterator`, over `Value::ownEnumerableStringKeys`).
|
|
1246
|
+
*
|
|
1247
|
+
* The enumerate sibling of `hasNativeIterationCursor`, and the same kind of
|
|
1248
|
+
* fact for the first two: the keys are storage the receiver already holds
|
|
1249
|
+
* (a runtime table, or a compile-time field list), so `for (const k in t)`
|
|
1250
|
+
* needs no `[[OwnPropertyKeys]]` machinery and no dynamic protocol.
|
|
1251
|
+
*
|
|
1252
|
+
* The dictionary test mirrors `representation/object-shape.ts`'s
|
|
1253
|
+
* `dictionaryIndexOf` exactly -- no members, exactly one index signature,
|
|
1254
|
+
* string-keyed -- because the two have to agree: this decides the LOOP SHAPE
|
|
1255
|
+
* and that decides the CARRIER, and a loop reshaped for a cursor the deriver
|
|
1256
|
+
* then does not produce would refuse with a key naming neither. It is a
|
|
1257
|
+
* structural test rather than a call into `representation/`, which normalize
|
|
1258
|
+
* runs before and must not depend on -- `producer-context.ts`'s own doc says
|
|
1259
|
+
* as much: a question this predicate cannot answer from the sealed structural
|
|
1260
|
+
* table alone needs a NEW primitive threaded onto `ProducerContext`, never a
|
|
1261
|
+
* second derivation of a representation-layer policy.
|
|
1262
|
+
*
|
|
1263
|
+
* A NAMED type (`'declared'`: an interface or type alias) COULD be
|
|
1264
|
+
* intercepted by a declaration-identity policy in `representation/derive.ts`
|
|
1265
|
+
* before ever reaching a plain `record`/`record-with-index` carrier --
|
|
1266
|
+
* `Date`, `RegExp`, `Promise`, a data-only host-bound plugin struct via
|
|
1267
|
+
* `nativeTypes` (`GeaEmbeddedImage`, `FetchResponse`, ...) -- and none of
|
|
1268
|
+
* those policies' censuses (`DateDeclarationPolicy`, `RegExpDeclarationPolicy`,
|
|
1269
|
+
* the host binding table, ...) are threaded onto `ProducerContext`, so this
|
|
1270
|
+
* predicate cannot ask the identity question `derive.ts` asks and get the
|
|
1271
|
+
* same answer; it can only ask the STRUCTURAL question (is the body a
|
|
1272
|
+
* complete record) that `object-anchor` and bare `'object'` already answer
|
|
1273
|
+
* below. The host-binding case is the one that matters: `derive.ts`'s own
|
|
1274
|
+
* `'declared'` case hardcodes `{ kind: 'native-record-ref', ownership:
|
|
1275
|
+
* 'owned', native: bound.native }` for a data-only bound type -- the EXACT
|
|
1276
|
+
* `native !== null` combination `emitStaticEnumerateIterator` refuses -- and
|
|
1277
|
+
* it shares its `.kind` (`'native-record-ref'`) with the safe,
|
|
1278
|
+
* compiler-defined case (a plain interface derives the identical kind with
|
|
1279
|
+
* `native: null`), so a carrier-kind obligation keyed only on `.kind` cannot
|
|
1280
|
+
* tell the two apart. That is not a reason to keep `'declared'` OUT of this
|
|
1281
|
+
* widening, though -- it is a reason the DISTINGUISHING question has to be
|
|
1282
|
+
* asked somewhere that still has the full representation to inspect.
|
|
1283
|
+
* `'declared'` is therefore treated exactly like `object-anchor` below (both
|
|
1284
|
+
* unwrap to their body and take the identical dictionary/record checks), and
|
|
1285
|
+
* the host-bound sub-case is caught downstream instead, at preflight:
|
|
1286
|
+
* `runtime-helper-key.ts`'s `enumerateGetIteratorCarrierKind` re-resolves the
|
|
1287
|
+
* `get-iterator` target's own representation (not just its bare kind, which
|
|
1288
|
+
* is all this structural predicate has) and reports a host-bound
|
|
1289
|
+
* `native-record-ref` under its own, deliberately unclaimed key --
|
|
1290
|
+
* `native-record-ref(host-bound)` -- the same "refine the receiver key" move
|
|
1291
|
+
* `preflight/property-access.ts`'s `nativeRecordRefHasIndexSidecar` makes for
|
|
1292
|
+
* a `native-record-ref` property read. So a host-bound `for`-`in` is still
|
|
1293
|
+
* refused by NAME, still at preflight, still before either loop shape is
|
|
1294
|
+
* lowered -- it is just a different file that owns the distinction, because
|
|
1295
|
+
* that file is the one still holding the representation once normalize's own
|
|
1296
|
+
* structural view of it has been discarded.
|
|
1297
|
+
*
|
|
1298
|
+
* A compiler-defined CLASS instance (`'class-instance'` with a non-null
|
|
1299
|
+
* `body`) does not share that risk, for a reason specific to it:
|
|
1300
|
+
* `derive.ts`'s `'class-instance'` case checks the SAME host-binding census
|
|
1301
|
+
* before ever looking at `shape.body`, but a bound class -- data-only or not
|
|
1302
|
+
* -- resolves to a DIFFERENT kind there, `native-handle`, never `class-ref`;
|
|
1303
|
+
* there is no shared-kind trap for the carrier-kind obligation to miss. And
|
|
1304
|
+
* `class-ref`'s ownership is never the value-record `'owned'` override either
|
|
1305
|
+
* -- `compiler.ts`'s own policy only overrides `shape.kind === 'object'`,
|
|
1306
|
+
* never `'class-instance'` -- so it is always `shared-refcount`. A bound
|
|
1307
|
+
* class is caught cleanly (unclaimed `native-handle` key); an unbound one is
|
|
1308
|
+
* exactly the `class-ref` `emitStaticEnumerateIterator` renders.
|
|
1309
|
+
*
|
|
1310
|
+
* `'object'` (bare, or unwrapped from a callable-bearing object-literal
|
|
1311
|
+
* anchor) needs none of that caution either: it names no declaration a policy
|
|
1312
|
+
* could intercept by identity, so a plain, non-generic `record`/
|
|
1313
|
+
* `record-with-index` is the only carrier `derive.ts`'s `deriveObject` can
|
|
1314
|
+
* ever produce for it.
|
|
1315
|
+
*/
|
|
1316
|
+
export const hasNativeEnumerationCursor = (context, type) => {
|
|
1317
|
+
const shape = context.table.get(type).shape;
|
|
1318
|
+
// `any`/`unknown`, never narrowed: the one genuinely DYNAMIC receiver this
|
|
1319
|
+
// enumeration protocol admits (see `emitDynamicEnumerateIterator`'s own
|
|
1320
|
+
// header comment in `emit-iterator.ts`) -- a real runtime walk of the box's
|
|
1321
|
+
// own enumerable keys, with no compile-time key set to state at all, and no
|
|
1322
|
+
// declaration for a policy to have intercepted by identity.
|
|
1323
|
+
if (shape.kind === 'primitive' && (shape.primitive === 'any' || shape.primitive === 'unknown'))
|
|
1324
|
+
return true;
|
|
1325
|
+
// A compiler-defined class instance -- see this function's own doc for why
|
|
1326
|
+
// this is safe where a named `'declared'` type is not. `class-ref` is
|
|
1327
|
+
// claimed regardless of the body's member/index shape (unlike the object
|
|
1328
|
+
// path below, which has a distinct `dictionary` carrier to consider), so
|
|
1329
|
+
// this only has to ask whether the field snapshot would be complete.
|
|
1330
|
+
if (shape.kind === 'class-instance' && shape.body !== null) {
|
|
1331
|
+
const classBody = context.table.get(shape.body).shape;
|
|
1332
|
+
return classBody.kind === 'object' && isCompleteRecordBody(classBody);
|
|
1333
|
+
}
|
|
1334
|
+
// A named interface/type-alias (`'declared'`) and a callable-bearing object
|
|
1335
|
+
// literal (`object-anchor`) both hold their body behind an id, and
|
|
1336
|
+
// `derive.ts` routes both through the identical dictionary/sidecar check on
|
|
1337
|
+
// it -- so the body is what the DICTIONARY test and the RECORD test below
|
|
1338
|
+
// both ask about, exactly as the deriver does for either shape. `'declared'`
|
|
1339
|
+
// is unwrapped and widened past the dictionary test the same way
|
|
1340
|
+
// `object-anchor` already is -- see this function's own doc for where the
|
|
1341
|
+
// one case that widening is unsafe for (a host-bound `native-record-ref`)
|
|
1342
|
+
// is caught instead.
|
|
1343
|
+
const body = shape.kind === 'declared' || shape.kind === 'object-anchor' ? (shape.body === null ? null : context.table.get(shape.body).shape) : shape;
|
|
1344
|
+
if (!body || body.kind !== 'object')
|
|
1345
|
+
return false;
|
|
1346
|
+
const [only] = body.index;
|
|
1347
|
+
if (body.members.length === 0 && body.index.length === 1 && only !== undefined) {
|
|
1348
|
+
// A string table yields its keys. A symbol table also has a complete
|
|
1349
|
+
// native answer: zero keys, because EnumerateObjectProperties excludes
|
|
1350
|
+
// symbols. Numeric tables remain refused until their ToString ordering is
|
|
1351
|
+
// represented exactly rather than falling through as a generic record.
|
|
1352
|
+
return only.key === 'string' || only.key === 'symbol';
|
|
1353
|
+
}
|
|
1354
|
+
return isCompleteRecordBody(body);
|
|
1355
|
+
};
|
|
1356
|
+
/**
|
|
1357
|
+
* Whether a structural type is the standard `Generator<T, TReturn, TNext>` --
|
|
1358
|
+
* what a `function*` returns, and the fifth source with no `@@iterator` lookup
|
|
1359
|
+
* behind it.
|
|
1360
|
+
*
|
|
1361
|
+
* A generator IS its own iterator: ECMA-262 27.5.1.2
|
|
1362
|
+
* `%GeneratorPrototype%[@@iterator]` returns `this`, so `GetIterator` over one
|
|
1363
|
+
* resolves to the value already in hand and there is nothing dynamic to look
|
|
1364
|
+
* up. `representation/derive.ts`'s `GeneratorDeclarationPolicy` carries it as
|
|
1365
|
+
* the same `iterator(T)` cursor for exactly that reason -- one value, one
|
|
1366
|
+
* carrier, whether it is being called or being walked.
|
|
1367
|
+
*
|
|
1368
|
+
* Keyed on the declaration the frontend resolved, never on the name, for the
|
|
1369
|
+
* reason `isNativeIterableSetType` states about `Set`: the deriver reads the
|
|
1370
|
+
* SAME identity, so the two cannot disagree about which declaration is meant.
|
|
1371
|
+
*/
|
|
1372
|
+
export const isGeneratorType = (context, type) => {
|
|
1373
|
+
const shape = context.table.get(type).shape;
|
|
1374
|
+
if (shape.kind !== 'declared')
|
|
1375
|
+
return false;
|
|
1376
|
+
const generators = [context.generatorDeclaration, context.asyncGeneratorDeclaration];
|
|
1377
|
+
return generators.some((declaration) => declaration !== null && shape.declaration === declaration);
|
|
1378
|
+
};
|
|
1379
|
+
/**
|
|
1380
|
+
* The canonical *static* key text a bracketed key expression resolves to when
|
|
1381
|
+
* it names a `unique symbol`, or `null` when it does not.
|
|
1382
|
+
*
|
|
1383
|
+
* `this[GEA_STATIC_ELEMENT]` is not a dynamic property access. The checker
|
|
1384
|
+
* resolves it to a declared member exactly as it resolves `this.rendered`: a
|
|
1385
|
+
* `unique symbol` is a compile-time identity, `class C { [S]: T }` declares a
|
|
1386
|
+
* member named by it, and `keyof C` includes it. So the key here is static in
|
|
1387
|
+
* the only sense this layer's `computed` flag means -- "the key resolved to a
|
|
1388
|
+
* constant text" -- which is already why `o["0"]` and `o[0]` are reported
|
|
1389
|
+
* non-computed despite being written in brackets.
|
|
1390
|
+
*
|
|
1391
|
+
* The text is `structural-types.ts`'s `symbolPropertyKeyText`, which is also
|
|
1392
|
+
* what `representation/object-shape.ts` names the record field by, so the
|
|
1393
|
+
* access and the layout cannot disagree about which member is meant. The
|
|
1394
|
+
* `unique-symbol` shape is read back out of the interned table rather than
|
|
1395
|
+
* asked of the checker a second time: `structural.ts` already resolved the
|
|
1396
|
+
* declaration anchor (and already answered `unresolved` for a symbol that has
|
|
1397
|
+
* none), and a second resolution here would be a second authority over one
|
|
1398
|
+
* fact.
|
|
1399
|
+
*/
|
|
1400
|
+
export const uniqueSymbolKeyTextOf = (context, type) => {
|
|
1401
|
+
const shape = context.table.get(type).shape;
|
|
1402
|
+
return shape.kind === 'unique-symbol' ? symbolPropertyKeyText(shape.declaration) : null;
|
|
1403
|
+
};
|
|
1404
|
+
/** The shared layout fact that requires retaining a symbol's evaluated identity. */
|
|
1405
|
+
export const isRuntimeSymbolMember = (context, receiver, keyType) => {
|
|
1406
|
+
const key = context.table.get(keyType).shape;
|
|
1407
|
+
if (key.kind !== 'unique-symbol')
|
|
1408
|
+
return false;
|
|
1409
|
+
const visited = new Set();
|
|
1410
|
+
let current = receiver;
|
|
1411
|
+
while (!visited.has(current)) {
|
|
1412
|
+
visited.add(current);
|
|
1413
|
+
const shape = context.table.get(current).shape;
|
|
1414
|
+
if (shape.kind === 'object')
|
|
1415
|
+
return runtimeSymbolMemberIndexOf(shape, { kind: 'symbol', declaration: key.declaration }) !== null;
|
|
1416
|
+
if ((shape.kind === 'declared' || shape.kind === 'object-anchor') && shape.body !== null)
|
|
1417
|
+
current = shape.body;
|
|
1418
|
+
else if (shape.kind === 'intersection' && shape.resolved !== null)
|
|
1419
|
+
current = shape.resolved;
|
|
1420
|
+
else
|
|
1421
|
+
return false;
|
|
1422
|
+
}
|
|
1423
|
+
return false;
|
|
1424
|
+
};
|
|
1425
|
+
/**
|
|
1426
|
+
* `ToPropertyKey` of a key whose value is fixed at compile time, or `null` when
|
|
1427
|
+
* it is not.
|
|
1428
|
+
*
|
|
1429
|
+
* `{ [K]: v }` is not a dynamic property definition when `K`'s *type* pins the
|
|
1430
|
+
* key: the checker itself types `{ [K]: 1 }` as `{ a: number }` for
|
|
1431
|
+
* `const K = 'a'`, lists `a` in `keyof`, and resolves `o.a` against it. So the
|
|
1432
|
+
* key is static in the only sense this layer's `computed` flag means -- the
|
|
1433
|
+
* same sense in which `o["0"]` and `o[0]` are already reported non-computed --
|
|
1434
|
+
* and lowering it as anything else would put a member the layout declares into
|
|
1435
|
+
* a dictionary the layout does not have.
|
|
1436
|
+
*
|
|
1437
|
+
* The answer is read out of the interned shape rather than off the key's
|
|
1438
|
+
* syntax, which is what makes `const K = 'a'` and `'a'` one case: a
|
|
1439
|
+
* declaration's literal type is exactly as fixed as a literal written in place,
|
|
1440
|
+
* and `structural-leaves.ts` has already interned both as the same shape.
|
|
1441
|
+
* Reading syntax would see two different programs.
|
|
1442
|
+
*
|
|
1443
|
+
* Every literal shape resolves, because ECMA-262 7.1.19 `ToPropertyKey` is
|
|
1444
|
+
* total over them and `structural-leaves.ts` already interned each one's text
|
|
1445
|
+
* in the exact spelling `ToString` produces: a number through `String(value)`
|
|
1446
|
+
* (which is `Number::toString`, and answers `"0"` for `-0` as the language
|
|
1447
|
+
* does), a bigint in decimal, a boolean as `"true"`/`"false"`. A `unique
|
|
1448
|
+
* symbol` needs no `ToString` at all -- it is already a property key -- and
|
|
1449
|
+
* shares `uniqueSymbolKeyTextOf`'s spelling so a computed definition and a
|
|
1450
|
+
* `receiver[K]` read name one member.
|
|
1451
|
+
*/
|
|
1452
|
+
export const staticPropertyKeyTextOf = (context, type) => {
|
|
1453
|
+
const shape = context.table.get(type).shape;
|
|
1454
|
+
if (shape.kind === 'unique-symbol')
|
|
1455
|
+
return symbolPropertyKeyText(shape.declaration);
|
|
1456
|
+
return shape.kind === 'literal' ? shape.text : null;
|
|
1457
|
+
};
|
|
1458
|
+
/**
|
|
1459
|
+
* The static member key `receiver[SOME_SYMBOL]` names, or `null` when the
|
|
1460
|
+
* access is not a declared-member read at all.
|
|
1461
|
+
*
|
|
1462
|
+
* This is the whole difference between two accesses that look identical:
|
|
1463
|
+
*
|
|
1464
|
+
* this[GEA_STATIC_ELEMENT] // a declared class member
|
|
1465
|
+
* (obj as Record<symbol, unknown>)[GEA_DIRTY] // an index signature
|
|
1466
|
+
*
|
|
1467
|
+
* The first is a struct member load with a compile-time name -- the checker
|
|
1468
|
+
* resolves it to a declared member exactly as it resolves `this.rendered`. The
|
|
1469
|
+
* second is a genuine dynamic-table lookup keyed by the symbol's RUNTIME
|
|
1470
|
+
* value, and spelling it as a static text would file it under the string half
|
|
1471
|
+
* of the object's key space, where `Object.keys` would list a property whose
|
|
1472
|
+
* whole purpose is not being enumerated.
|
|
1473
|
+
*
|
|
1474
|
+
* The RECEIVER'S MEMBER LIST decides, and it is asked of the checker rather
|
|
1475
|
+
* than of the already-interned shape: `structural.ts` interns some bodies
|
|
1476
|
+
* data-only (its `MemberMode`), so a symbol-named METHOD -- which
|
|
1477
|
+
* `this[GEA_STATIC_TEMPLATE]()` is -- is absent from the interned body while
|
|
1478
|
+
* being a perfectly ordinary declared member. Reading the interned body would
|
|
1479
|
+
* therefore answer "dynamic" for a member the class really declares.
|
|
1480
|
+
*
|
|
1481
|
+
* Matching is by DECLARATION IDENTITY, never by spelling:
|
|
1482
|
+
* `symbolKeyDeclarationOf` resolves a member's key to the `const` the symbol
|
|
1483
|
+
* was bound to, which is the identical anchor `structural.ts`'s
|
|
1484
|
+
* `UniqueESSymbol` branch gives the key expression's own type, so the two
|
|
1485
|
+
* sides compare one fact.
|
|
1486
|
+
*/
|
|
1487
|
+
export const symbolMemberKeyOf = (context, receiver, keyType) => {
|
|
1488
|
+
const key = context.table.get(keyType).shape;
|
|
1489
|
+
if (key.kind !== 'unique-symbol')
|
|
1490
|
+
return null;
|
|
1491
|
+
if (isRuntimeSymbolMember(context, context.types.typeAt(receiver), keyType))
|
|
1492
|
+
return null;
|
|
1493
|
+
// HOLDS: the receiver's own member list, read the census-aware way
|
|
1494
|
+
// (`context.types.rawTypeAt`) so an under-typed receiver the census
|
|
1495
|
+
// resolved to a real class does not silently fail this symbol-member match.
|
|
1496
|
+
const receiverType = context.checker.getNonNullableType(context.types.rawTypeAt(receiver));
|
|
1497
|
+
for (const member of receiverType.getProperties()) {
|
|
1498
|
+
// Only a symbol-named member can match, and the checker spells those with
|
|
1499
|
+
// its own `__@` prefix -- the same test `keyOfSymbol` uses to decide a key
|
|
1500
|
+
// is a symbol at all.
|
|
1501
|
+
if (!member.getName().startsWith('__@'))
|
|
1502
|
+
continue;
|
|
1503
|
+
const declaration = symbolKeyDeclarationOf(context.checker, context.identities, member);
|
|
1504
|
+
if (declaration && context.identities.declarationIdOf(declaration) === key.declaration) {
|
|
1505
|
+
return symbolPropertyKeyText(key.declaration);
|
|
1506
|
+
}
|
|
1507
|
+
}
|
|
1508
|
+
return null;
|
|
1509
|
+
};
|
|
1510
|
+
/** A callable's own declared property key as `SetFunctionName` would spell it: no leading `#` for a private name. */
|
|
1511
|
+
const declaredCallableKeyTextOf = (name) => {
|
|
1512
|
+
if (ts.isIdentifier(name))
|
|
1513
|
+
return name.text;
|
|
1514
|
+
if (ts.isPrivateIdentifier(name))
|
|
1515
|
+
return name.text.replace(/^#/, '');
|
|
1516
|
+
if (ts.isStringLiteral(name) || ts.isNumericLiteral(name))
|
|
1517
|
+
return name.text;
|
|
1518
|
+
if (ts.isComputedPropertyName(name)) {
|
|
1519
|
+
const expression = name.expression;
|
|
1520
|
+
if (ts.isStringLiteralLike(expression) || ts.isNumericLiteral(expression))
|
|
1521
|
+
return expression.text;
|
|
1522
|
+
}
|
|
1523
|
+
return null;
|
|
1524
|
+
};
|
|
1525
|
+
/**
|
|
1526
|
+
* The name an anonymous function/arrow expression inherits from the exact
|
|
1527
|
+
* syntax position it was defined at, per ECMA-262 `NamedEvaluation`
|
|
1528
|
+
* (14.4.13's own runs of it, 8.6.2 `SingleNameBinding`, 13.2.5.5 property
|
|
1529
|
+
* definition, 13.15.2 simple assignment) -- or `''` when the position gives
|
|
1530
|
+
* it none, which IS the anonymous function's real `[[Name]]`
|
|
1531
|
+
* (`(function(){}).name === ''`).
|
|
1532
|
+
*
|
|
1533
|
+
* Every branch is one grammar production the spec runs `NamedEvaluation`
|
|
1534
|
+
* from: a variable/binding-element/parameter's own plain-identifier
|
|
1535
|
+
* Initializer (covers `const f = () => {}`, destructuring and default-parameter
|
|
1536
|
+
* defaults alike -- `[arrow = () => {}]` is a `BindingElement` exactly as
|
|
1537
|
+
* `function f(x = () => {})` is a `ParameterDeclaration`), an
|
|
1538
|
+
* object-literal/class-field property's own value, a simple assignment's
|
|
1539
|
+
* right-hand side, and a bare default export. `parent` is always populated:
|
|
1540
|
+
* every caller reaches this only after the checker has bound the file.
|
|
1541
|
+
*/
|
|
1542
|
+
const namedEvaluationNameOf = (node) => {
|
|
1543
|
+
const parent = node.parent;
|
|
1544
|
+
if (ts.isVariableDeclaration(parent) && parent.initializer === node && ts.isIdentifier(parent.name))
|
|
1545
|
+
return parent.name.text;
|
|
1546
|
+
if (ts.isBindingElement(parent) && parent.initializer === node && ts.isIdentifier(parent.name))
|
|
1547
|
+
return parent.name.text;
|
|
1548
|
+
if (ts.isParameter(parent) && parent.initializer === node && ts.isIdentifier(parent.name))
|
|
1549
|
+
return parent.name.text;
|
|
1550
|
+
if (ts.isPropertyDeclaration(parent) && parent.initializer === node) {
|
|
1551
|
+
const key = declaredCallableKeyTextOf(parent.name);
|
|
1552
|
+
if (key !== null)
|
|
1553
|
+
return key;
|
|
1554
|
+
}
|
|
1555
|
+
if (ts.isPropertyAssignment(parent) && parent.initializer === node) {
|
|
1556
|
+
const key = declaredCallableKeyTextOf(parent.name);
|
|
1557
|
+
if (key !== null)
|
|
1558
|
+
return key;
|
|
1559
|
+
}
|
|
1560
|
+
if (ts.isBinaryExpression(parent) &&
|
|
1561
|
+
parent.operatorToken.kind === ts.SyntaxKind.EqualsToken &&
|
|
1562
|
+
parent.right === node &&
|
|
1563
|
+
ts.isIdentifier(parent.left)) {
|
|
1564
|
+
return parent.left.text;
|
|
1565
|
+
}
|
|
1566
|
+
if (ts.isExportAssignment(parent) && !parent.isExportEquals && parent.expression === node)
|
|
1567
|
+
return 'default';
|
|
1568
|
+
return '';
|
|
1569
|
+
};
|
|
1570
|
+
/**
|
|
1571
|
+
* ECMA-262's `[[Name]]` internal slot for a callable, decided entirely at
|
|
1572
|
+
* compile time from its syntax: a function/method/accessor's own written
|
|
1573
|
+
* name (with `get `/`set ` prefixed for an accessor, exactly as
|
|
1574
|
+
* `MethodDefinitionEvaluation`'s own `SetFunctionName` calls do), or --
|
|
1575
|
+
* for an anonymous function/arrow expression -- the `NamedEvaluation` name
|
|
1576
|
+
* from wherever it was defined (`namedEvaluationNameOf`).
|
|
1577
|
+
*
|
|
1578
|
+
* Both halves are pure syntax facts, independent of any value the callable
|
|
1579
|
+
* ever carries at runtime, which is what makes this safe to decide once per
|
|
1580
|
+
* allocation site and register in the runtime's static `SourceRegistration`
|
|
1581
|
+
* table exactly as `functionSource` already is -- see
|
|
1582
|
+
* `producers/allocations.ts`'s and `producers/class-lifecycle.ts`'s own
|
|
1583
|
+
* `functionName` fields.
|
|
1584
|
+
*/
|
|
1585
|
+
/**
|
|
1586
|
+
* ECMA-262's `[[Name]]` for a class constructor, the same way
|
|
1587
|
+
* `staticFunctionNameOf` below decides it for a function: the class's own
|
|
1588
|
+
* written name, or -- for an anonymous class expression -- the
|
|
1589
|
+
* `NamedEvaluation` name of the position it was written in (`const A = class
|
|
1590
|
+
* {}` is `"A"`, `[cls = class {}]` is `"cls"`), or `"default"` for an
|
|
1591
|
+
* anonymous `export default class`. A class that declares its own static
|
|
1592
|
+
* `name` member shadows this at the read site, which is the reader's rule
|
|
1593
|
+
* (`emit-class-properties.ts`'s static-member walk runs first), not this one's.
|
|
1594
|
+
*/
|
|
1595
|
+
export const staticClassNameOf = (node) => {
|
|
1596
|
+
if (node.name)
|
|
1597
|
+
return node.name.text;
|
|
1598
|
+
if (ts.isClassExpression(node))
|
|
1599
|
+
return namedEvaluationNameOf(node);
|
|
1600
|
+
return node.modifiers?.some((modifier) => modifier.kind === ts.SyntaxKind.DefaultKeyword) ? 'default' : '';
|
|
1601
|
+
};
|
|
1602
|
+
/**
|
|
1603
|
+
* `Function.prototype.length` for a class constructor: the written
|
|
1604
|
+
* constructor's `ExpectedArgumentCount` (`expectedParameterCountOf`), or 0
|
|
1605
|
+
* for a class relying on the implicit one -- the default constructor of a
|
|
1606
|
+
* base class takes no parameters, and a derived class's `(...args)` has a
|
|
1607
|
+
* rest parameter first, so both count 0.
|
|
1608
|
+
*/
|
|
1609
|
+
export const staticClassLengthOf = (node) => {
|
|
1610
|
+
const written = node.members.find((member) => ts.isConstructorDeclaration(member) && member.body !== undefined);
|
|
1611
|
+
return written ? expectedParameterCountOf(written) : 0;
|
|
1612
|
+
};
|
|
1613
|
+
export const staticFunctionNameOf = (node) => {
|
|
1614
|
+
if (ts.isMethodDeclaration(node) || ts.isGetAccessorDeclaration(node) || ts.isSetAccessorDeclaration(node)) {
|
|
1615
|
+
const key = declaredCallableKeyTextOf(node.name);
|
|
1616
|
+
if (key === null)
|
|
1617
|
+
return '';
|
|
1618
|
+
return (ts.isGetAccessorDeclaration(node) ? 'get ' : ts.isSetAccessorDeclaration(node) ? 'set ' : '') + key;
|
|
1619
|
+
}
|
|
1620
|
+
if (ts.isFunctionDeclaration(node)) {
|
|
1621
|
+
if (node.name)
|
|
1622
|
+
return node.name.text;
|
|
1623
|
+
// `export default function () {}`: an anonymous HoistableDeclaration whose
|
|
1624
|
+
// default export IS its `NamedEvaluation` position (ECMA-262 `ExportDeclaration
|
|
1625
|
+
// : export default HoistableDeclaration`), so it names 'default' even though
|
|
1626
|
+
// there is no assignment expression for `namedEvaluationNameOf` to walk up to.
|
|
1627
|
+
return node.modifiers?.some((modifier) => modifier.kind === ts.SyntaxKind.DefaultKeyword) ? 'default' : '';
|
|
1628
|
+
}
|
|
1629
|
+
if (ts.isFunctionExpression(node) && node.name)
|
|
1630
|
+
return node.name.text;
|
|
1631
|
+
return namedEvaluationNameOf(node);
|
|
1632
|
+
};
|
|
1633
|
+
/**
|
|
1634
|
+
* ECMA-262 `ExpectedArgumentCount`: the leading run of a callable's own
|
|
1635
|
+
* written parameters, up to (and excluding) the first one that has a default
|
|
1636
|
+
* initializer or is a rest parameter. This is `Function.prototype.length`,
|
|
1637
|
+
* and it is a fact about the written parameter list alone -- independent of
|
|
1638
|
+
* `NamedEvaluation`, and independent of the calling convention this compiler
|
|
1639
|
+
* projects, which erases exactly the "has a default" bit this needs (a
|
|
1640
|
+
* defaulted parameter is narrowed to its own storage type same as a required
|
|
1641
|
+
* one). So it is read directly off the syntax here, once, the same way
|
|
1642
|
+
* `functionSource` is.
|
|
1643
|
+
*
|
|
1644
|
+
* TypeScript's synthetic `this` parameter (`function f(this: Foo, x: number)`)
|
|
1645
|
+
* binds no argument position and is invisible to `.length`; the grammar
|
|
1646
|
+
* allows it only in leading position, so skipping index 0 when it names
|
|
1647
|
+
* `this` is exhaustive.
|
|
1648
|
+
*/
|
|
1649
|
+
export const expectedParameterCountOf = (node) => {
|
|
1650
|
+
let count = 0;
|
|
1651
|
+
for (const [index, parameter] of node.parameters.entries()) {
|
|
1652
|
+
if (index === 0 && ts.isIdentifier(parameter.name) && parameter.name.text === 'this')
|
|
1653
|
+
continue;
|
|
1654
|
+
if (parameter.initializer !== undefined || parameter.dotDotDotToken !== undefined)
|
|
1655
|
+
break;
|
|
1656
|
+
count++;
|
|
1657
|
+
}
|
|
1658
|
+
return count;
|
|
1659
|
+
};
|
|
1660
|
+
/**
|
|
1661
|
+
* Whether the declaration performs ECMA-262 10.2.5 `MakeConstructor`, and so
|
|
1662
|
+
* owns a `prototype` object, or `null` where the answer exists but this
|
|
1663
|
+
* compiler does not model it.
|
|
1664
|
+
*
|
|
1665
|
+
* A syntax fact decided once per allocation site, exactly as
|
|
1666
|
+
* `expectedParameterCountOf` above is: an ordinary `function` declaration or
|
|
1667
|
+
* expression makes a constructor, while an arrow, a method, an accessor and
|
|
1668
|
+
* an `async function` are created by `OrdinaryFunctionCreate` with no such
|
|
1669
|
+
* step and own no `prototype` at all.
|
|
1670
|
+
*
|
|
1671
|
+
* A generator answers `null` rather than `true`. It does own a `prototype`,
|
|
1672
|
+
* but 27.3.1's object inherits `%GeneratorFunction.prototype.prototype%`,
|
|
1673
|
+
* which this runtime has no object for -- and reporting `true` would hand a
|
|
1674
|
+
* read a plain object whose `constructor` chain is wrong. `null` keeps the
|
|
1675
|
+
* read refused, which is the honest answer while that intrinsic is missing.
|
|
1676
|
+
*/
|
|
1677
|
+
export const ownPrototypePropertyOf = (node) => {
|
|
1678
|
+
if ('asteriskToken' in node && node.asteriskToken !== undefined)
|
|
1679
|
+
return null;
|
|
1680
|
+
if (!ts.isFunctionDeclaration(node) && !ts.isFunctionExpression(node))
|
|
1681
|
+
return false;
|
|
1682
|
+
return node.modifiers?.some((modifier) => modifier.kind === ts.SyntaxKind.AsyncKeyword) !== true;
|
|
1683
|
+
};
|