@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,1468 @@
|
|
|
1
|
+
import { annotationStatesNothing, censusedTypeAt, containsUnstatedPosition, narrowsOnlyUnstatedPositions, singleConventionAt, impliedPatternElementRootOf, impliedPatternParameterOf, impliedPatternTargetOf, objectAssignFreshTargetType, nominalConstructorChoiceTypeAt } from './derived-expression-type.js';
|
|
2
|
+
import { isUnreducedTypeForm } from './unreduced-type-form.js';
|
|
3
|
+
import ts from 'typescript';
|
|
4
|
+
import { emptyAbsentGlobalCensus } from './absent-globals.js';
|
|
5
|
+
import { emptyParameterBindingCensus } from './parameter-bindings.js';
|
|
6
|
+
/**
|
|
7
|
+
* Which type an object or array literal is laid out as.
|
|
8
|
+
*
|
|
9
|
+
* Split out of `structural.ts` -- it closes over nothing but the checker, and
|
|
10
|
+
* that file's own subject is the walk that interns a type, not the question of
|
|
11
|
+
* which type to walk.
|
|
12
|
+
*/
|
|
13
|
+
export const createLayoutTypeResolver = (checker, parameters = emptyParameterBindingCensus, absent = emptyAbsentGlobalCensus) => {
|
|
14
|
+
/**
|
|
15
|
+
* An array-pattern element read past the end of a plain array binds
|
|
16
|
+
* `undefined`, and the checker's own type for the name omits it: `var [a,
|
|
17
|
+
* b, c] = xs` over a `number[]` types `c` as `number` (the same unsound
|
|
18
|
+
* index read `noUncheckedIndexedAccess` exists to correct). The pattern
|
|
19
|
+
* census reads the position WITH its absence (`patternReadTypeAt`, tuple
|
|
20
|
+
* holders excepted, since a tuple states its length), and where the two
|
|
21
|
+
* disagree the census is the one that can be true: laying `c` out as a bare
|
|
22
|
+
* number made its initialization dereference an empty optional, and the
|
|
23
|
+
* program printed `0` where the language answers `undefined`.
|
|
24
|
+
*
|
|
25
|
+
* A defaulted element is left alone -- the name is bound to the joined
|
|
26
|
+
* type once the default has run, which is what the checker answers.
|
|
27
|
+
*/
|
|
28
|
+
const arrayPatternReadOutranking = (node, own) => {
|
|
29
|
+
// An `any` here is the census's own gate below, and the census already
|
|
30
|
+
// reads the element with its absence; answering first would hand it the
|
|
31
|
+
// checker's nothing widened by `undefined`, which is still nothing.
|
|
32
|
+
if ((own.flags & (ts.TypeFlags.Any | ts.TypeFlags.Unknown)) !== 0 || containsUndefined(own))
|
|
33
|
+
return null;
|
|
34
|
+
const element = ts.isBindingElement(node) ? node : ts.isIdentifier(node) ? arrayPatternElementDeclaring(node) : null;
|
|
35
|
+
// An OBJECT pattern's numeric key over an array is the same read spelled
|
|
36
|
+
// differently (`[...{ 3: y }] = [7, 8, 9]`), and the census publishes it
|
|
37
|
+
// through the same channel; the `containsUndefined(read)` test below is
|
|
38
|
+
// what keeps every ordinary member read out of this rule.
|
|
39
|
+
if (!element || element.initializer || element.dotDotDotToken)
|
|
40
|
+
return null;
|
|
41
|
+
const read = parameters.patternReadTypeAt?.(element) ?? null;
|
|
42
|
+
if (!read || !containsUndefined(read))
|
|
43
|
+
return null;
|
|
44
|
+
// A reference keeps whatever the checker narrowed the payload to at that
|
|
45
|
+
// site and regains only the absence the declaration lost: the checker
|
|
46
|
+
// narrowed from the unsound `number`, so a guard it credited cannot be
|
|
47
|
+
// told from no guard at all, and the absence has to stay in the carrier
|
|
48
|
+
// until a test the program actually wrote removes it.
|
|
49
|
+
return ts.isBindingElement(node) ? read : checker.getNullableType(own, ts.TypeFlags.Undefined);
|
|
50
|
+
};
|
|
51
|
+
const arrayPatternElementDeclaring = (node) => {
|
|
52
|
+
const declaration = checker.getSymbolAtLocation(node)?.valueDeclaration;
|
|
53
|
+
return declaration && ts.isBindingElement(declaration) ? declaration : null;
|
|
54
|
+
};
|
|
55
|
+
const containsUndefined = (type) => (type.flags & ts.TypeFlags.Undefined) !== 0 || (type.isUnion() && type.types.some((arm) => (arm.flags & ts.TypeFlags.Undefined) !== 0));
|
|
56
|
+
/** The single arm of a union that could have been written as a literal, or nothing when the choice is genuinely ambiguous. */
|
|
57
|
+
const soleShapedArm = (union) => {
|
|
58
|
+
const shaped = union.types.filter((member) => (member.flags & ts.TypeFlags.Object) !== 0);
|
|
59
|
+
return shaped.length === 1 ? (shaped[0] ?? null) : null;
|
|
60
|
+
};
|
|
61
|
+
/**
|
|
62
|
+
* The property names every object already carries, declared shape or not --
|
|
63
|
+
* resolved from the checker's own global `Object` type rather than
|
|
64
|
+
* hardcoded, so it tracks whatever lib version this program actually
|
|
65
|
+
* compiles against.
|
|
66
|
+
*
|
|
67
|
+
* Memoized once: `Object`'s own members do not vary by call site, and
|
|
68
|
+
* `resolveName` walks scope from whatever node is handed to it, which is
|
|
69
|
+
* wasted work to repeat per literal.
|
|
70
|
+
*/
|
|
71
|
+
let objectBaselineMembers = null;
|
|
72
|
+
const objectBaselineMembersOf = (node) => {
|
|
73
|
+
if (objectBaselineMembers)
|
|
74
|
+
return objectBaselineMembers;
|
|
75
|
+
const symbol = checker.resolveName('Object', node, ts.SymbolFlags.Type, false);
|
|
76
|
+
const baseline = symbol ? checker.getDeclaredTypeOfSymbol(symbol).getProperties() : [];
|
|
77
|
+
objectBaselineMembers = new Set(baseline.map((property) => property.getName()));
|
|
78
|
+
return objectBaselineMembers;
|
|
79
|
+
};
|
|
80
|
+
/**
|
|
81
|
+
* Whether a contextual candidate adds nothing beyond what `Object` itself
|
|
82
|
+
* already carries -- the JSDoc `{Object}` escape hatch (`Object` is
|
|
83
|
+
* assignable from any non-nullish value, precisely because it declares
|
|
84
|
+
* nothing) and its structural twin, the anonymous `{}`/top type, whose own
|
|
85
|
+
* property list is empty for the identical reason.
|
|
86
|
+
*
|
|
87
|
+
* Both are `TypeFlags.Object` and both pass every check above, but neither
|
|
88
|
+
* is "the declared shape a literal was checked against" the way `Point` or
|
|
89
|
+
* `CameraCaptureOptions` is: substituting one in throws the literal's own
|
|
90
|
+
* real fields away for a handful of methods (or nothing) every value
|
|
91
|
+
* already has. `three/src/core/EventDispatcher.js`'s own `@param {Object}
|
|
92
|
+
* event` is the concrete case -- `{ type, handedness, target }` contextually
|
|
93
|
+
* types as `Object`, and adopting that as the layout produced a record
|
|
94
|
+
* whose only fields were `Object.prototype`'s, with `handedness` nowhere
|
|
95
|
+
* in it. A type that genuinely adds members (`EventInit`, also declared in
|
|
96
|
+
* a lib file) does not match this test, because its own properties are not
|
|
97
|
+
* a subset of the baseline.
|
|
98
|
+
*/
|
|
99
|
+
const isVacuousObjectType = (node, type) => {
|
|
100
|
+
// An INDEX SIGNATURE is a declared shape, and it declares no named members
|
|
101
|
+
// at all -- so a test that reads only `getProperties()` calls
|
|
102
|
+
// `Record<string, string>` vacuous for exactly the reason it is not.
|
|
103
|
+
// `voice-notes` proved it: `{ Authorization, 'Content-Type' }` written into
|
|
104
|
+
// a `Record<string, string> | undefined` header field stopped adopting the
|
|
105
|
+
// dictionary and minted its own struct, and `Optional<Ref<Dictionary<...>>>
|
|
106
|
+
// = gea_record_type_974` has no viable assignment. One value, two layouts,
|
|
107
|
+
// and no conversion between them -- which is the very thing the contextual
|
|
108
|
+
// rule above exists to prevent.
|
|
109
|
+
if (checker.getIndexInfosOfType(type).length > 0)
|
|
110
|
+
return false;
|
|
111
|
+
const baseline = objectBaselineMembersOf(node);
|
|
112
|
+
return type.getProperties().every((property) => baseline.has(property.getName()));
|
|
113
|
+
};
|
|
114
|
+
/**
|
|
115
|
+
* Whether a type is TypeScript's own evolving-array placeholder: an array
|
|
116
|
+
* whose element the checker has not finalized yet at this location.
|
|
117
|
+
*
|
|
118
|
+
* `let arr = []` is `any[]` at its own declaration, and at every mutating
|
|
119
|
+
* reference reachable from it, because ECMA-262 says nothing about the
|
|
120
|
+
* elements an empty array literal will ever hold and the checker widens the
|
|
121
|
+
* element type across every `push`/index write it can still see ahead of
|
|
122
|
+
* that point. It only settles a first-class element type -- `number[]`,
|
|
123
|
+
* `BufferAttribute[]` -- once flow analysis knows no more assignments
|
|
124
|
+
* follow, typically where the array escapes (a `return`, an argument, a
|
|
125
|
+
* property write). Treating the placeholder as the cell's PHYSICAL storage
|
|
126
|
+
* type is a defect in this compiler, not a fact about the program: the
|
|
127
|
+
* checker HAS the finalized element type, this call is simply asking for
|
|
128
|
+
* it at the one location -- the declaration, or an intermediate mutation --
|
|
129
|
+
* where the checker has not computed it yet.
|
|
130
|
+
*/
|
|
131
|
+
const isEvolvingArrayType = (type) => {
|
|
132
|
+
if (!checker.isArrayType(type))
|
|
133
|
+
return false;
|
|
134
|
+
const [element] = checker.getTypeArguments(type);
|
|
135
|
+
return element !== undefined && (element.flags & ts.TypeFlags.Any) !== 0;
|
|
136
|
+
};
|
|
137
|
+
/**
|
|
138
|
+
* The declaration symbol a node's checker type should be asked on behalf
|
|
139
|
+
* of, when that node is not itself the read of a binding.
|
|
140
|
+
*
|
|
141
|
+
* An identifier reference already names its own symbol. A `let`/`const`
|
|
142
|
+
* declaration's name does too, one level down. An array literal is neither
|
|
143
|
+
* -- it is the RHS of exactly one declaration when it initializes one
|
|
144
|
+
* (`let arr = []`), and that declaration's symbol is the one whose whole
|
|
145
|
+
* lifetime this literal's placeholder needs to be resolved against, not the
|
|
146
|
+
* literal's own (symbol-less) identity.
|
|
147
|
+
*/
|
|
148
|
+
const boundSymbolOf = (node) => {
|
|
149
|
+
if (ts.isIdentifier(node))
|
|
150
|
+
return checker.getSymbolAtLocation(node) ?? null;
|
|
151
|
+
if (ts.isVariableDeclaration(node) && ts.isIdentifier(node.name))
|
|
152
|
+
return checker.getSymbolAtLocation(node.name) ?? null;
|
|
153
|
+
const parent = node.parent;
|
|
154
|
+
if (parent && ts.isVariableDeclaration(parent) && parent.initializer === node && ts.isIdentifier(parent.name)) {
|
|
155
|
+
return checker.getSymbolAtLocation(parent.name) ?? null;
|
|
156
|
+
}
|
|
157
|
+
return null;
|
|
158
|
+
};
|
|
159
|
+
/**
|
|
160
|
+
* The last reachable reference to a symbol in the file that declares it.
|
|
161
|
+
*
|
|
162
|
+
* Only a real reference -- an `Identifier` the checker can resolve back to
|
|
163
|
+
* this exact symbol -- makes the checker compute a flow-narrowed answer at
|
|
164
|
+
* all: asking at an unrelated later node (a sibling statement, the
|
|
165
|
+
* function's closing brace) reports the identical unsettled placeholder the
|
|
166
|
+
* declaration does, verified directly against the checker. Comparing by
|
|
167
|
+
* the RESOLVED symbol rather than the name's text is what keeps a
|
|
168
|
+
* same-spelled binding in a nested, shadowing scope from ever being
|
|
169
|
+
* mistaken for a reference to this one -- two identifiers spelled alike
|
|
170
|
+
* resolve to two different symbols, and only a match on the resolved
|
|
171
|
+
* symbol is admitted. Lexical scoping already guarantees every real
|
|
172
|
+
* reference to a local symbol lives in the file that declares it, so
|
|
173
|
+
* walking that whole file, rather than hunting for the nearest enclosing
|
|
174
|
+
* function, costs nothing in correctness.
|
|
175
|
+
*/
|
|
176
|
+
const lastReferenceTo = (symbol, file) => {
|
|
177
|
+
let last = null;
|
|
178
|
+
const visit = (node) => {
|
|
179
|
+
if (ts.isIdentifier(node) && checker.getSymbolAtLocation(node) === symbol) {
|
|
180
|
+
if (!last || node.getStart() > last.getStart())
|
|
181
|
+
last = node;
|
|
182
|
+
}
|
|
183
|
+
ts.forEachChild(node, visit);
|
|
184
|
+
};
|
|
185
|
+
visit(file);
|
|
186
|
+
return last;
|
|
187
|
+
};
|
|
188
|
+
// Memoized per symbol: every mutation site and the declaration itself ask
|
|
189
|
+
// this question about the SAME binding, and finding its last reference
|
|
190
|
+
// walks the whole declaring file, so paying that cost once per symbol
|
|
191
|
+
// rather than once per reference is what keeps a file with many evolving
|
|
192
|
+
// arrays from re-walking itself once per `push` call.
|
|
193
|
+
const settledEvolvingType = new Map();
|
|
194
|
+
/**
|
|
195
|
+
* `own`, unless it is an evolving-array placeholder this call can settle.
|
|
196
|
+
*
|
|
197
|
+
* Settling means resolving the SAME symbol's checker type at its last
|
|
198
|
+
* reachable reference instead -- exactly the technique that already
|
|
199
|
+
* distinguishes an intermediate `arr.push(x)` (still placeholder, nothing
|
|
200
|
+
* to substitute) from the escaping use that finalized it. Substituting only
|
|
201
|
+
* when the alternative is ITSELF no longer a placeholder is what keeps
|
|
202
|
+
* this idempotent and total: a binding that never finishes evolving within
|
|
203
|
+
* the visible program keeps its honest, still-placeholder answer, the same
|
|
204
|
+
* one every reference to it already agreed on.
|
|
205
|
+
*/
|
|
206
|
+
const settleEvolving = (node, own) => {
|
|
207
|
+
if (!isEvolvingArrayType(own))
|
|
208
|
+
return own;
|
|
209
|
+
const symbol = boundSymbolOf(node);
|
|
210
|
+
if (!symbol)
|
|
211
|
+
return own;
|
|
212
|
+
let settled = settledEvolvingType.get(symbol);
|
|
213
|
+
if (settled === undefined) {
|
|
214
|
+
const last = lastReferenceTo(symbol, node.getSourceFile());
|
|
215
|
+
// HOLDS, not stated: what does this reference actually evaluate to.
|
|
216
|
+
// Asking the shared authority rather than the checker directly lets a
|
|
217
|
+
// census answer settle the reference the identical way it would settle
|
|
218
|
+
// any other read of this symbol -- the census has no reason to answer
|
|
219
|
+
// differently at the last reference than it would anywhere else this
|
|
220
|
+
// binding is read.
|
|
221
|
+
const candidate = last ? censusedTypeAt(checker, parameters, last) : null;
|
|
222
|
+
settled = candidate && !isEvolvingArrayType(candidate) ? candidate : null;
|
|
223
|
+
settledEvolvingType.set(symbol, settled);
|
|
224
|
+
}
|
|
225
|
+
return settled ?? own;
|
|
226
|
+
};
|
|
227
|
+
/**
|
|
228
|
+
* The type an expression's value physically is.
|
|
229
|
+
*
|
|
230
|
+
* For an object or array literal this is its *contextual* type when the
|
|
231
|
+
* language gives it one: `const p: Point = { x: 0, y: 1 }` has one value, and
|
|
232
|
+
* letting the literal keep its own fresh anonymous type would give that value
|
|
233
|
+
* two structural identities, two C++ layouts, and a conversion between them
|
|
234
|
+
* that describes nothing real. TypeScript's fresh literal type exists for
|
|
235
|
+
* excess-property checking, not for layout.
|
|
236
|
+
*
|
|
237
|
+
* A union contextual type contributes its arm only when exactly ONE arm has
|
|
238
|
+
* a layout at all. `capture(options?: CameraCaptureOptions)` gives the
|
|
239
|
+
* literal a contextual type of `CameraCaptureOptions | undefined`, and
|
|
240
|
+
* `undefined` is not a shape a literal could have been written as -- there is
|
|
241
|
+
* one candidate, so choosing it is reading the program, not guessing at it.
|
|
242
|
+
* Refusing the whole union instead left `Camera.capture({ mirror: true })`
|
|
243
|
+
* allocating a fresh anonymous `record(mirror: boolean)` and handing it to a
|
|
244
|
+
* slot carrying `optional(native-record-ref(CameraCaptureOptions),
|
|
245
|
+
* undefined)`: two layouts for one value, and no conversion between them
|
|
246
|
+
* because there is no real conversion to write.
|
|
247
|
+
*
|
|
248
|
+
* Two or more object arms stay refused, unchanged: that is a genuine decision
|
|
249
|
+
* about which shape was meant, and picking one would silently give the value
|
|
250
|
+
* a layout the program never asked for. An intersection stays refused for the
|
|
251
|
+
* same reason.
|
|
252
|
+
*
|
|
253
|
+
* An array literal narrows the whole rule further: it accepts a candidate
|
|
254
|
+
* only when that type is *itself* array- or tuple-shaped. The "one value,
|
|
255
|
+
* one identity" argument above only holds when the contextual type describes
|
|
256
|
+
* the same physical thing the literal's own type already does -- true of a
|
|
257
|
+
* tuple assigned by position (`readonly [number, number]`, whose own
|
|
258
|
+
* inferred type is already the identical tuple), false of an arbitrary
|
|
259
|
+
* Object-flagged interface an overloaded call's parameter happens to name
|
|
260
|
+
* (`new Uint8Array([68, 73, 65, 71])` contextually types the argument
|
|
261
|
+
* against `Iterable<number>`, a symbol-keyed protocol with no data layout at
|
|
262
|
+
* all). Substituting that in would hand a 4-element literal a 0-field struct
|
|
263
|
+
* to write into -- not a gap this compiler has not built yet, but a layout
|
|
264
|
+
* that was never this value's shape to begin with. `checker.isArrayType`/
|
|
265
|
+
* `isTupleType` is the same pair `typeOf` above already dispatches an array
|
|
266
|
+
* literal's own (uncontextualized) type through, so an array literal that
|
|
267
|
+
* keeps `own` here still normalizes exactly the way it always did.
|
|
268
|
+
*/
|
|
269
|
+
/**
|
|
270
|
+
* The type of a property/element access whose RECEIVER a census bound but the
|
|
271
|
+
* checker did not, or `null` when that does not apply.
|
|
272
|
+
*
|
|
273
|
+
* Refuses whenever the answer would be `any` again, so this can only ever
|
|
274
|
+
* replace a box with a real carrier -- never widen one thing into another.
|
|
275
|
+
*/
|
|
276
|
+
/** An element access's key when the program wrote it down literally, else `null`. */
|
|
277
|
+
const literalKeyOf = (node) => {
|
|
278
|
+
if (!ts.isElementAccessExpression(node))
|
|
279
|
+
return null;
|
|
280
|
+
const argument = node.argumentExpression;
|
|
281
|
+
if (ts.isStringLiteral(argument) || ts.isNoSubstitutionTemplateLiteral(argument))
|
|
282
|
+
return argument.text;
|
|
283
|
+
if (ts.isNumericLiteral(argument))
|
|
284
|
+
return argument.text;
|
|
285
|
+
return null;
|
|
286
|
+
};
|
|
287
|
+
/**
|
|
288
|
+
* The member of a union receiver only ONE arm declares.
|
|
289
|
+
*
|
|
290
|
+
* `getPropertyOfType` answers for a union only when EVERY arm declares the
|
|
291
|
+
* key, which is the right rule for a type the program must be able to use
|
|
292
|
+
* without knowing which arm it holds. It is not the only readable case.
|
|
293
|
+
* three's `Matrix4.makeTranslation( x, y, z )` takes `{number|Vector3} x` and
|
|
294
|
+
* reads `x.x`, `x.y`, `x.z` after its own `if ( x.isVector3 )` brand check --
|
|
295
|
+
* a check TypeScript cannot narrow on, because `isVector3` is not declared on
|
|
296
|
+
* `number` either, so `x` stays the union and all three reads come back `any`
|
|
297
|
+
* with no symbol. Ten of the prototype's unmet obligations are those reads.
|
|
298
|
+
*
|
|
299
|
+
* ECMA-262 10.1.8 says what the other arms answer: `[[Get]]` walks the
|
|
300
|
+
* prototype chain, finds no property, and returns `undefined` at step 3 --
|
|
301
|
+
* it does not throw. So the honest type of such a read is the owning arm's
|
|
302
|
+
* member type OR `undefined`, and that is what this returns. Nothing here
|
|
303
|
+
* assumes the guard: the tagged-union emitter already dispatches on the arm
|
|
304
|
+
* tag and renders `undefined` for an arm without the key
|
|
305
|
+
* (`emit-union-properties.ts`'s `taggedUnionGetText`), so the emitted read is
|
|
306
|
+
* correct on every arm, not only the branded one.
|
|
307
|
+
*
|
|
308
|
+
* Refused when any arm is `any`/`unknown` -- such an arm declares every key
|
|
309
|
+
* and no key, so "exactly one owner" would be counting an answer nobody gave.
|
|
310
|
+
*/
|
|
311
|
+
const memberThroughSingleUnionArm = (receiver, key, node) => {
|
|
312
|
+
if (!receiver.isUnion())
|
|
313
|
+
return null;
|
|
314
|
+
if (receiver.types.some((arm) => (arm.flags & (ts.TypeFlags.Any | ts.TypeFlags.Unknown)) !== 0))
|
|
315
|
+
return null;
|
|
316
|
+
const owners = receiver.types.filter((arm) => checker.getPropertyOfType(arm, key) !== undefined);
|
|
317
|
+
const only = owners.length === 1 ? owners[0] : undefined;
|
|
318
|
+
if (!only)
|
|
319
|
+
return null;
|
|
320
|
+
const member = checker.getPropertyOfType(only, key);
|
|
321
|
+
if (!member)
|
|
322
|
+
return null;
|
|
323
|
+
const resolved = checker.getTypeOfSymbolAtLocation(member, node);
|
|
324
|
+
if ((resolved.flags & (ts.TypeFlags.Any | ts.TypeFlags.Unknown)) !== 0)
|
|
325
|
+
return null;
|
|
326
|
+
return checker.getNullableType(resolved, ts.TypeFlags.Undefined);
|
|
327
|
+
};
|
|
328
|
+
/**
|
|
329
|
+
* Whether a property/element access chain bottoms out at a parameter whose
|
|
330
|
+
* STATED annotation the census narrowed -- see `statedTypeAt`
|
|
331
|
+
* (`parameter-bindings.ts`). The gate on following a member read through
|
|
332
|
+
* that narrowing, and deliberately not a general "follow every member read
|
|
333
|
+
* through the census" rule: this file's own header records what happened
|
|
334
|
+
* the last time this resolver answered ahead of the checker for nodes other
|
|
335
|
+
* producers derive independently.
|
|
336
|
+
*/
|
|
337
|
+
const receiverChainWasNarrowedByStatement = (node) => {
|
|
338
|
+
let current = node;
|
|
339
|
+
for (let depth = 0; depth < 8; depth += 1) {
|
|
340
|
+
if (!ts.isPropertyAccessExpression(current) && !ts.isElementAccessExpression(current))
|
|
341
|
+
return false;
|
|
342
|
+
const receiver = current.expression;
|
|
343
|
+
if (parameters.statedTypeAt(receiver))
|
|
344
|
+
return true;
|
|
345
|
+
current = receiver;
|
|
346
|
+
}
|
|
347
|
+
return false;
|
|
348
|
+
};
|
|
349
|
+
/**
|
|
350
|
+
* A member symbol's type, asked again from the CLASS FIELD CENSUS -- and,
|
|
351
|
+
* failing that, again of the checker at the member's own declaration --
|
|
352
|
+
* when the checker's answer for the actual READ location is `any`/`unknown`.
|
|
353
|
+
*
|
|
354
|
+
* Measured on the three.js app: `renderer.shadowMap` off the IDENTICAL receiver
|
|
355
|
+
* carrier (`class-ref` for `WebGLRenderer`, proven by
|
|
356
|
+
* `_this.shadowMap = shadowMap` at `WebGLRenderer.js:516`) answers
|
|
357
|
+
* `native-record-ref` when read from the app's entry module and `dynamic` when
|
|
358
|
+
* read from `WebGLPrograms.js:439` -- the same `getPropertyOfType` +
|
|
359
|
+
* `getTypeOfSymbolAtLocation` pair, on the same property symbol,
|
|
360
|
+
* disagreeing only by which node is handed to `getTypeOfSymbolAtLocation`
|
|
361
|
+
* as `at`. `shadowMap` is a `this`-property whose type TypeScript derives
|
|
362
|
+
* by control-flow analysis of its assignment(s) inside `WebGLRenderer`'s
|
|
363
|
+
* own constructor; asking for that type "at" a node with no flow edge to
|
|
364
|
+
* the assignment is not guaranteed to reach the same settled answer a
|
|
365
|
+
* read from at or near the declaring scope gets.
|
|
366
|
+
*
|
|
367
|
+
* `structural-parts.ts`'s `memberOf` already has the fix for the
|
|
368
|
+
* IDENTICAL split on the field's STORAGE side (what the class layout
|
|
369
|
+
* holds): past its own `isUnusableEvidence` gate, it asks `parameters` --
|
|
370
|
+
* "the fully composed parameter+return+local+field census, despite the
|
|
371
|
+
* name" -- at the member's declaration, because `field-bindings.ts`
|
|
372
|
+
* "already joins every write reaching the FIELD's symbol under one
|
|
373
|
+
* answer". This function is the READ side of the same field, in a
|
|
374
|
+
* different file, and it had no equivalent fallback at all -- it asked
|
|
375
|
+
* the checker once, at the read site, and gave up. `parameters` is the
|
|
376
|
+
* same composed census both files close over, so this asks it the exact
|
|
377
|
+
* same way `memberOf` does, at the exact same node.
|
|
378
|
+
*
|
|
379
|
+
* The plain re-ask of the checker at the declaration is kept as a second,
|
|
380
|
+
* narrower fallback for a member the field census does not cover (an
|
|
381
|
+
* ordinary TypeScript field or interface member, which the checker alone
|
|
382
|
+
* can still answer correctly from its own declaration even where the read
|
|
383
|
+
* site could not) -- gated to a receiver that is NOT a generic
|
|
384
|
+
* instantiation, since a generic class's member type read at its bare
|
|
385
|
+
* declaration is open in the class's own type parameters, unsubstituted
|
|
386
|
+
* for this particular receiver, and publishing that would be a
|
|
387
|
+
* different, wider defect than the one this exists to fix. The census
|
|
388
|
+
* fallback carries no such risk: it answers what a WRITE'S OWN VALUE
|
|
389
|
+
* resolved to, not a re-derivation of the member's declared type, so it
|
|
390
|
+
* is asked unconditionally.
|
|
391
|
+
*
|
|
392
|
+
* Purely additive throughout -- every fallback here only replaces a
|
|
393
|
+
* `null` `memberThroughBoundReceiver` was already about to return (the
|
|
394
|
+
* checker had nothing usable at the read site), so a program where the
|
|
395
|
+
* read-site answer was already usable is untouched, and a field that is
|
|
396
|
+
* genuinely dynamic even to the census and at its own declaration still
|
|
397
|
+
* answers `null` here exactly as before -- the negative control this
|
|
398
|
+
* fix's own test asserts.
|
|
399
|
+
*/
|
|
400
|
+
const declaredMemberTypeOf = (property, receiver, node) => {
|
|
401
|
+
const atReadSite = checker.getTypeOfSymbolAtLocation(property, node);
|
|
402
|
+
if ((atReadSite.flags & (ts.TypeFlags.Any | ts.TypeFlags.Unknown)) === 0)
|
|
403
|
+
return atReadSite;
|
|
404
|
+
const declaration = property.valueDeclaration ?? property.declarations?.[0];
|
|
405
|
+
if (!declaration)
|
|
406
|
+
return null;
|
|
407
|
+
// An object-literal property's own census answer is published against
|
|
408
|
+
// its INITIALIZER/shorthand name, exactly as `structural-parts.ts`'s
|
|
409
|
+
// `censusValueNodeOf` reads it -- a class field's is published against
|
|
410
|
+
// the declaration (one of its own writes) directly.
|
|
411
|
+
const censusNode = ts.isPropertyAssignment(declaration)
|
|
412
|
+
? declaration.initializer
|
|
413
|
+
: ts.isShorthandPropertyAssignment(declaration)
|
|
414
|
+
? declaration.name
|
|
415
|
+
: declaration;
|
|
416
|
+
const fromCensus = parameters.typeAt(censusNode);
|
|
417
|
+
if (fromCensus && !isUnreducedTypeForm(fromCensus) && (fromCensus.flags & (ts.TypeFlags.Any | ts.TypeFlags.Unknown)) === 0)
|
|
418
|
+
return fromCensus;
|
|
419
|
+
const objectFlags = receiver.objectFlags ?? 0;
|
|
420
|
+
const isGenericInstantiation = (objectFlags & ts.ObjectFlags.Reference) !== 0 && receiver.target !== receiver;
|
|
421
|
+
if (isGenericInstantiation)
|
|
422
|
+
return null;
|
|
423
|
+
const atDeclaration = checker.getTypeOfSymbolAtLocation(property, declaration);
|
|
424
|
+
return (atDeclaration.flags & (ts.TypeFlags.Any | ts.TypeFlags.Unknown)) === 0 ? atDeclaration : null;
|
|
425
|
+
};
|
|
426
|
+
const memberThroughBoundReceiver = (node) => {
|
|
427
|
+
const isProperty = ts.isPropertyAccessExpression(node);
|
|
428
|
+
// An ELEMENT access is the same read with the key written differently, and
|
|
429
|
+
// it has to follow the receiver for the identical reason: `v[ i ]`,
|
|
430
|
+
// `units[ i ]` and `this[ key ]` are 749 of the three.js app's boxed nodes. A
|
|
431
|
+
// string-literal key is a named member and resolves exactly as `.name`
|
|
432
|
+
// does; any other key resolves through the receiver's INDEX signature,
|
|
433
|
+
// which is the only thing that can answer a key not known until runtime.
|
|
434
|
+
if (!isProperty && !ts.isElementAccessExpression(node))
|
|
435
|
+
return null;
|
|
436
|
+
const receiver = checker.getNonNullableType(layoutTypeAt(node.expression));
|
|
437
|
+
if ((receiver.flags & (ts.TypeFlags.Any | ts.TypeFlags.Unknown)) !== 0)
|
|
438
|
+
return null;
|
|
439
|
+
const key = isProperty ? node.name.text : literalKeyOf(node);
|
|
440
|
+
if (key === null) {
|
|
441
|
+
const argument = ts.isElementAccessExpression(node) ? node.argumentExpression : undefined;
|
|
442
|
+
if (!argument)
|
|
443
|
+
return null;
|
|
444
|
+
const argumentType = layoutTypeAt(argument);
|
|
445
|
+
const numeric = (argumentType.flags & (ts.TypeFlags.Number | ts.TypeFlags.NumberLiteral)) !== 0;
|
|
446
|
+
const indexed = checker.getIndexTypeOfType(receiver, numeric ? ts.IndexKind.Number : ts.IndexKind.String);
|
|
447
|
+
if (!indexed)
|
|
448
|
+
return null;
|
|
449
|
+
return (indexed.flags & (ts.TypeFlags.Any | ts.TypeFlags.Unknown)) !== 0 ? null : indexed;
|
|
450
|
+
}
|
|
451
|
+
const property = checker.getPropertyOfType(receiver, key);
|
|
452
|
+
if (!property)
|
|
453
|
+
return memberThroughSingleUnionArm(receiver, key, node);
|
|
454
|
+
// STATED, deliberately: `property` is a member SYMBOL of `receiver`,
|
|
455
|
+
// which this whole function exists to resolve past the census/checker
|
|
456
|
+
// split above -- the receiver is already the best answer available (the
|
|
457
|
+
// census's, when it had one). Asking the DECLARED type of a member the
|
|
458
|
+
// receiver's own shape names is the correct, and only, question here;
|
|
459
|
+
// there is no expression node this member read could hand to a second
|
|
460
|
+
// census lookup that would not just be re-deriving `receiver` itself.
|
|
461
|
+
// `declaredMemberTypeOf` is that same question asked TWICE at most --
|
|
462
|
+
// once at this read site, and once at the property's own declaration
|
|
463
|
+
// when the read site came back with nothing -- see its header.
|
|
464
|
+
const resolved = declaredMemberTypeOf(property, receiver, node);
|
|
465
|
+
if (!resolved)
|
|
466
|
+
return null;
|
|
467
|
+
// An overload set has no single calling convention -- the shared rule in
|
|
468
|
+
// `derived-expression-type.ts` asks the CALL which one this site selected.
|
|
469
|
+
return singleConventionAt(checker, resolved, node);
|
|
470
|
+
};
|
|
471
|
+
/**
|
|
472
|
+
* A LITERAL TOKEN'S TYPE IS THE VALUE IT SPELLS. IT IS NOT A QUESTION ABOUT
|
|
473
|
+
* WHERE THE TOKEN SITS.
|
|
474
|
+
*
|
|
475
|
+
* `getTypeAtLocation` answers a *positional* question: it types a node as an
|
|
476
|
+
* expression only when the node's parent is one of the parent kinds it
|
|
477
|
+
* enumerates as putting a literal in expression position. That enumeration is
|
|
478
|
+
* incomplete for the three literal kinds that are lexical TOKENS rather than
|
|
479
|
+
* expression nodes -- `StringLiteral`, `NumericLiteral` and
|
|
480
|
+
* `NoSubstitutionTemplateLiteral` -- and when the parent is not on the list
|
|
481
|
+
* the checker declines and hands back the error type, which reads as `any`.
|
|
482
|
+
*
|
|
483
|
+
* `export default <literal>` is one such position, and it is not a rare one:
|
|
484
|
+
* measured on the three.js app, 110 modules are exactly `export default \`...\``, a
|
|
485
|
+
* plain string with no substitutions in it, and every one of them boxed. The
|
|
486
|
+
* same decline is reproducible in five lines of ordinary TypeScript --
|
|
487
|
+
* `export default "hello"` and `export default 42` both answer `any`, while
|
|
488
|
+
* `export default true` (a keyword, not a literal token) and `export default
|
|
489
|
+
* \`a${1}b\`` (a `TemplateExpression`, an expression node) both answer
|
|
490
|
+
* correctly. Nothing about it is specific to any library or any host.
|
|
491
|
+
*
|
|
492
|
+
* So this is not a second guess at a value the program left open, the way the
|
|
493
|
+
* parameter census below is: a literal token can never *genuinely* be `any`,
|
|
494
|
+
* because the token states its own value. Asked before every other question
|
|
495
|
+
* for that reason. The `any` guard at the call site keeps it to the case
|
|
496
|
+
* where the checker declined -- wherever the checker does answer, its answer
|
|
497
|
+
* (including a widened or contextually-narrowed one) still wins.
|
|
498
|
+
*
|
|
499
|
+
* Positions where a literal token is deliberately not a value at all -- a
|
|
500
|
+
* module specifier, a literal type node, a declared property name -- are
|
|
501
|
+
* excluded rather than answered, so this only ever fills in a value the
|
|
502
|
+
* program really does evaluate.
|
|
503
|
+
*/
|
|
504
|
+
const literalTokenType = (node) => {
|
|
505
|
+
const parent = node.parent;
|
|
506
|
+
if (parent) {
|
|
507
|
+
if (ts.isImportDeclaration(parent) || ts.isExportDeclaration(parent) || ts.isModuleDeclaration(parent))
|
|
508
|
+
return null;
|
|
509
|
+
if (ts.isLiteralTypeNode(parent) || ts.isImportTypeNode(parent) || ts.isExternalModuleReference(parent))
|
|
510
|
+
return null;
|
|
511
|
+
if (ts.isImportAttribute(parent) || ts.isJsxNamespacedName(parent))
|
|
512
|
+
return null;
|
|
513
|
+
if ((ts.isPropertyDeclaration(parent) ||
|
|
514
|
+
ts.isPropertySignature(parent) ||
|
|
515
|
+
ts.isPropertyAssignment(parent) ||
|
|
516
|
+
ts.isMethodDeclaration(parent) ||
|
|
517
|
+
ts.isMethodSignature(parent) ||
|
|
518
|
+
ts.isEnumMember(parent) ||
|
|
519
|
+
ts.isParameter(parent) ||
|
|
520
|
+
ts.isVariableDeclaration(parent)) &&
|
|
521
|
+
parent.name === node)
|
|
522
|
+
return null;
|
|
523
|
+
}
|
|
524
|
+
if (ts.isStringLiteral(node) || node.kind === ts.SyntaxKind.NoSubstitutionTemplateLiteral)
|
|
525
|
+
return checker.getStringLiteralType(node.text);
|
|
526
|
+
if (ts.isNumericLiteral(node)) {
|
|
527
|
+
const value = Number(node.text);
|
|
528
|
+
return Number.isNaN(value) ? null : checker.getNumberLiteralType(value);
|
|
529
|
+
}
|
|
530
|
+
if (ts.isBigIntLiteral(node)) {
|
|
531
|
+
const text = node.text.replace(/n$/, '');
|
|
532
|
+
const negative = text.startsWith('-');
|
|
533
|
+
return checker.getBigIntLiteralType({ negative, base10Value: negative ? text.slice(1) : text });
|
|
534
|
+
}
|
|
535
|
+
return null;
|
|
536
|
+
};
|
|
537
|
+
/** `type`'s own generic target -- `Promise` for `Promise<Response>` -- or `null` when `type` is not an instantiation of one. */
|
|
538
|
+
const genericTargetOf = (type) => {
|
|
539
|
+
if ((type.flags & ts.TypeFlags.Object) === 0)
|
|
540
|
+
return null;
|
|
541
|
+
if ((type.objectFlags & ts.ObjectFlags.Reference) === 0)
|
|
542
|
+
return null;
|
|
543
|
+
return type.target;
|
|
544
|
+
};
|
|
545
|
+
/**
|
|
546
|
+
* The declared union arm CFA narrowing lost, when narrowing itself is the
|
|
547
|
+
* defect rather than the value.
|
|
548
|
+
*
|
|
549
|
+
* `res instanceof Promise` on a `res` the checker can only call `any` before
|
|
550
|
+
* the guard (hono's `let res: ReturnType<H>`, `H` a type parameter the
|
|
551
|
+
* checker cannot resolve at this call) narrows to `Promise<any>`, not
|
|
552
|
+
* `Promise<Response>` -- TypeScript's own `instanceof` narrowing against a
|
|
553
|
+
* *generic* ambient class has no union arm to match against when the
|
|
554
|
+
* pre-narrow type carries no type argument of its own to preserve, so it
|
|
555
|
+
* fills the class's own type parameter with `any` rather than inventing one.
|
|
556
|
+
* That loses information the checker already had: `res`'s DECLARED type,
|
|
557
|
+
* resolved the identical way this whole resolver resolves `any` elsewhere
|
|
558
|
+
* (the census composed in `parameters`, reached by asking `layoutTypeAt`
|
|
559
|
+
* at the declaration's own name), is the real `Response |
|
|
560
|
+
* Promise<Response>` -- and `Promise<Response>` is not a guess, it is the
|
|
561
|
+
* one arm of that union built from the SAME generic target the narrowed
|
|
562
|
+
* type names, so recovering it is reading a fact the checker already
|
|
563
|
+
* proved, never bridging a genuinely dynamic value into a typed one.
|
|
564
|
+
*
|
|
565
|
+
* Gated strictly to when the narrowed type's OWN type argument is `any`:
|
|
566
|
+
* a real narrowing to a concrete instantiation (`x instanceof MySubclass`
|
|
567
|
+
* where `MySubclass` fixes its own type argument) never reaches this,
|
|
568
|
+
* because there is nothing lost for it to recover.
|
|
569
|
+
*/
|
|
570
|
+
const declaredGenericArmAt = (node, narrowed) => {
|
|
571
|
+
const target = genericTargetOf(narrowed);
|
|
572
|
+
if (!target)
|
|
573
|
+
return null;
|
|
574
|
+
const lostArgument = checker
|
|
575
|
+
.getTypeArguments(narrowed)
|
|
576
|
+
.some((argument) => (argument.flags & ts.TypeFlags.Any) !== 0);
|
|
577
|
+
if (!lostArgument)
|
|
578
|
+
return null;
|
|
579
|
+
if (!ts.isIdentifier(node))
|
|
580
|
+
return null;
|
|
581
|
+
const symbol = checker.getSymbolAtLocation(node);
|
|
582
|
+
const declaration = symbol?.valueDeclaration;
|
|
583
|
+
if (!declaration)
|
|
584
|
+
return null;
|
|
585
|
+
const declaredAt = ts.isVariableDeclaration(declaration) && ts.isIdentifier(declaration.name) ? declaration.name : declaration;
|
|
586
|
+
if (declaredAt === node)
|
|
587
|
+
return null;
|
|
588
|
+
const declared = layoutTypeAt(declaredAt);
|
|
589
|
+
// A real UNION only: a declaration with no union at all offers nothing
|
|
590
|
+
// narrowing could have lost -- `declared` would just be `own` reached
|
|
591
|
+
// through a different node, and treating that trivial self-match as a
|
|
592
|
+
// "recovered arm" changes nothing about a real narrowing while still
|
|
593
|
+
// paying a recursive lookup, and measurably churned an UNRELATED
|
|
594
|
+
// rest-parameter tuple's own derivation once tried ungated. Requiring a
|
|
595
|
+
// union is what keeps this to the one shape it exists for: an arm CFA
|
|
596
|
+
// narrowing actually discarded.
|
|
597
|
+
if (!declared.isUnion())
|
|
598
|
+
return null;
|
|
599
|
+
const matches = declared.types.filter((arm) => genericTargetOf(arm) === target);
|
|
600
|
+
return matches.length === 1 ? (matches[0] ?? null) : null;
|
|
601
|
+
};
|
|
602
|
+
/**
|
|
603
|
+
* The type an EMPTY array literal fills, read off the enclosing literal's
|
|
604
|
+
* own resolved layout rather than off the empty literal's own inference.
|
|
605
|
+
*
|
|
606
|
+
* Narrow by construction: only an array literal with no elements at all,
|
|
607
|
+
* only when its own inferred element is the `never` that says nothing, and
|
|
608
|
+
* only inside another array literal. Everything else keeps the contextual
|
|
609
|
+
* resolution below, which is both more general and already measured. The
|
|
610
|
+
* recursion into `layoutTypeAt` is what makes a chain compose, and it
|
|
611
|
+
* terminates because it always moves strictly outward through the AST.
|
|
612
|
+
*/
|
|
613
|
+
const emptyArrayPositionTypeOf = (node) => {
|
|
614
|
+
if (!ts.isArrayLiteralExpression(node) || node.elements.length > 0)
|
|
615
|
+
return null;
|
|
616
|
+
const own = checker.getTypeAtLocation(node);
|
|
617
|
+
if (!checker.isArrayType(own))
|
|
618
|
+
return null;
|
|
619
|
+
const [ownElement] = checker.getTypeArguments(own);
|
|
620
|
+
if (!ownElement || (ownElement.flags & ts.TypeFlags.Never) === 0)
|
|
621
|
+
return null;
|
|
622
|
+
const parent = node.parent;
|
|
623
|
+
if (!ts.isArrayLiteralExpression(parent))
|
|
624
|
+
return null;
|
|
625
|
+
const index = parent.elements.indexOf(node);
|
|
626
|
+
if (index < 0)
|
|
627
|
+
return null;
|
|
628
|
+
const outer = layoutTypeAt(parent);
|
|
629
|
+
if (checker.isTupleType(outer))
|
|
630
|
+
return checker.getTypeArguments(outer)[index] ?? null;
|
|
631
|
+
if (checker.isArrayType(outer))
|
|
632
|
+
return checker.getTypeArguments(outer)[0] ?? null;
|
|
633
|
+
return null;
|
|
634
|
+
};
|
|
635
|
+
/**
|
|
636
|
+
* The one array carrier a spread-only conditional requires when one arm is
|
|
637
|
+
* syntactically empty: `...(condition ? [value] : [])`.
|
|
638
|
+
*
|
|
639
|
+
* The empty arm contributes no element that could disagree with the other
|
|
640
|
+
* arm, and the conditional is consumed immediately as an iterable, so both
|
|
641
|
+
* allocations can use the populated arm's array type. Keeping the check on
|
|
642
|
+
* the enclosing SpreadElement matters: a conditional stored for later can
|
|
643
|
+
* retain its union identity and be narrowed or mutated as either arm, while
|
|
644
|
+
* this value has no operation between selection and iteration.
|
|
645
|
+
*/
|
|
646
|
+
const spreadConditionalArrayTypeOf = (node) => {
|
|
647
|
+
const conditional = ts.isConditionalExpression(node)
|
|
648
|
+
? node
|
|
649
|
+
: ts.isArrayLiteralExpression(node) && ts.isConditionalExpression(node.parent)
|
|
650
|
+
? node.parent
|
|
651
|
+
: null;
|
|
652
|
+
if (!conditional)
|
|
653
|
+
return null;
|
|
654
|
+
let consumed = conditional;
|
|
655
|
+
while (ts.isParenthesizedExpression(consumed.parent) && consumed.parent.expression === consumed)
|
|
656
|
+
consumed = consumed.parent;
|
|
657
|
+
if (!ts.isSpreadElement(consumed.parent) || consumed.parent.expression !== consumed)
|
|
658
|
+
return null;
|
|
659
|
+
const trueEmpty = ts.isArrayLiteralExpression(conditional.whenTrue) && conditional.whenTrue.elements.length === 0;
|
|
660
|
+
const falseEmpty = ts.isArrayLiteralExpression(conditional.whenFalse) && conditional.whenFalse.elements.length === 0;
|
|
661
|
+
if (trueEmpty === falseEmpty)
|
|
662
|
+
return null;
|
|
663
|
+
if (ts.isArrayLiteralExpression(node) && node.elements.length !== 0)
|
|
664
|
+
return null;
|
|
665
|
+
const populated = trueEmpty ? conditional.whenFalse : conditional.whenTrue;
|
|
666
|
+
const type = layoutTypeAt(populated);
|
|
667
|
+
return checker.isArrayType(type) ? type : null;
|
|
668
|
+
};
|
|
669
|
+
/**
|
|
670
|
+
* The declared carrier behind TypeScript's `Array.isArray` narrowing.
|
|
671
|
+
*
|
|
672
|
+
* The standard predicate deliberately narrows every array-shaped value to
|
|
673
|
+
* `any[]`; it does not retain the element type of an array arm inside a
|
|
674
|
+
* union. That is sufficient for checking JavaScript, but it is not a new
|
|
675
|
+
* allocation and therefore cannot change `Material[]` into an
|
|
676
|
+
* `Array<any>` physical carrier. When the binding's declared type contains
|
|
677
|
+
* exactly one arm assignable to the checker's narrowed `any[]`, that arm is
|
|
678
|
+
* the only carrier the predicate can have selected. Returning it preserves
|
|
679
|
+
* the existing array and its element identity.
|
|
680
|
+
*
|
|
681
|
+
* More than one compatible arm is a real ambiguity (for example a tuple
|
|
682
|
+
* beside an array) and stays with the checker. An `any[]` that was itself
|
|
683
|
+
* declared as such also returns the same type, so genuinely dynamic arrays
|
|
684
|
+
* remain dynamic.
|
|
685
|
+
*/
|
|
686
|
+
const soleDeclaredArrayArm = (node, own) => {
|
|
687
|
+
if (!checker.isArrayType(own))
|
|
688
|
+
return null;
|
|
689
|
+
const [element] = checker.getTypeArguments(own);
|
|
690
|
+
if (!element || (element.flags & ts.TypeFlags.Any) === 0)
|
|
691
|
+
return null;
|
|
692
|
+
const symbol = ts.isIdentifier(node)
|
|
693
|
+
? checker.getSymbolAtLocation(node)
|
|
694
|
+
: ts.isPropertyAccessExpression(node)
|
|
695
|
+
? checker.getSymbolAtLocation(node.name)
|
|
696
|
+
: undefined;
|
|
697
|
+
const declaration = symbol?.valueDeclaration ?? symbol?.declarations?.[0];
|
|
698
|
+
if (!symbol || !declaration)
|
|
699
|
+
return null;
|
|
700
|
+
const declared = checker.getTypeOfSymbolAtLocation(symbol, declaration);
|
|
701
|
+
// `Array.isArray(value)` narrows a value declared `any`/`unknown` to
|
|
702
|
+
// `any[]`. That is a control-flow fact about the ONE dynamic value, not
|
|
703
|
+
// an allocation or an element-wise conversion. Returning the declared
|
|
704
|
+
// dynamic type keeps its `gea::Value` carrier, so the predicate's live
|
|
705
|
+
// branch uses Value's recorded Array exotic hooks in place. Deriving the
|
|
706
|
+
// checker's `any[]` here would instead select `ArrayObject<Value>` and
|
|
707
|
+
// force a dynamic-to-native array materialization: a differently typed
|
|
708
|
+
// native array would be copied, and aliases through the original dynamic
|
|
709
|
+
// value would stop observing indexed writes, deletes, and length changes.
|
|
710
|
+
//
|
|
711
|
+
// This is deliberately limited to a declared dynamic source AND the
|
|
712
|
+
// checker's `any[]` result above. A typed union's sole Array arm still
|
|
713
|
+
// takes the arm-selection path below and remains a native array; no
|
|
714
|
+
// statically typed array is routed through Value.
|
|
715
|
+
if ((declared.flags & (ts.TypeFlags.Any | ts.TypeFlags.Unknown)) !== 0)
|
|
716
|
+
return declared;
|
|
717
|
+
const arms = declared.isUnion() ? declared.types : [declared];
|
|
718
|
+
const compatible = arms.filter((arm) => (arm.flags & (ts.TypeFlags.Any | ts.TypeFlags.Unknown)) === 0 && checker.isTypeAssignableTo(arm, own));
|
|
719
|
+
return compatible.length === 1 ? (compatible[0] ?? null) : null;
|
|
720
|
+
};
|
|
721
|
+
/**
|
|
722
|
+
* The dictionary a const binding aliases through a closed structural view.
|
|
723
|
+
*
|
|
724
|
+
* `const attrs: { position?: T; normal?: T } = geometry.morphAttributes`
|
|
725
|
+
* does not allocate or copy an object. The annotation proves which named
|
|
726
|
+
* reads are valid, but the value in the cell is still the initializer's
|
|
727
|
+
* string-indexed dictionary. Placing the cell as the closed record would
|
|
728
|
+
* require a snapshot conversion and lose both dictionary identity and later
|
|
729
|
+
* mutations. Keeping the initializer carrier lets ordinary dictionary
|
|
730
|
+
* property reads materialize each optional named value at its use.
|
|
731
|
+
*
|
|
732
|
+
* Restricted to a const variable, a source with a string index, a target
|
|
733
|
+
* with named fields and no index/call/construct convention, and the
|
|
734
|
+
* checker's own assignability proof. A mutable binding can later receive a
|
|
735
|
+
* different implementation of the view and therefore cannot reuse this
|
|
736
|
+
* argument.
|
|
737
|
+
*/
|
|
738
|
+
const constDictionaryAliasType = (node, own) => {
|
|
739
|
+
const declaration = ts.isVariableDeclaration(node)
|
|
740
|
+
? node
|
|
741
|
+
: ts.isIdentifier(node)
|
|
742
|
+
? checker.getSymbolAtLocation(node)?.valueDeclaration
|
|
743
|
+
: undefined;
|
|
744
|
+
if (!declaration || !ts.isVariableDeclaration(declaration) || !declaration.initializer)
|
|
745
|
+
return null;
|
|
746
|
+
const declarationList = declaration.parent;
|
|
747
|
+
if (!ts.isVariableDeclarationList(declarationList) || (declarationList.flags & ts.NodeFlags.Const) === 0)
|
|
748
|
+
return null;
|
|
749
|
+
if ((own.flags & ts.TypeFlags.Object) === 0)
|
|
750
|
+
return null;
|
|
751
|
+
if (checker.getIndexInfosOfType(own).length > 0 || own.getProperties().length === 0)
|
|
752
|
+
return null;
|
|
753
|
+
if (own.getCallSignatures().length > 0 || own.getConstructSignatures().length > 0)
|
|
754
|
+
return null;
|
|
755
|
+
const physical = checker.getTypeAtLocation(declaration.initializer);
|
|
756
|
+
const stringIndex = checker.getIndexInfosOfType(physical).some((index) => (index.keyType.flags & ts.TypeFlags.StringLike) !== 0);
|
|
757
|
+
if (!stringIndex || !checker.isTypeAssignableTo(physical, own))
|
|
758
|
+
return null;
|
|
759
|
+
return physical;
|
|
760
|
+
};
|
|
761
|
+
/**
|
|
762
|
+
* The nominal class carrier behind a control-flow view of one member.
|
|
763
|
+
*
|
|
764
|
+
* After `Array.isArray(source.material)`, TypeScript can describe `source`
|
|
765
|
+
* itself as an anonymous/intersection view whose `material` member is
|
|
766
|
+
* narrowed. The object was not rebuilt into that record: it remains the
|
|
767
|
+
* class instance bound to the parameter, while the subsequent property read
|
|
768
|
+
* independently publishes the narrowed member type. Keeping the anonymous
|
|
769
|
+
* receiver as a second physical layout forces a class-to-record snapshot and
|
|
770
|
+
* can require an impossible `Array<T> -> Array<any>` element conversion.
|
|
771
|
+
*
|
|
772
|
+
* A real class or union narrowing is left intact. This only recovers a class
|
|
773
|
+
* declaration when the current checker view has no class symbol of its own,
|
|
774
|
+
* is not a union, and is assignable to the declared class.
|
|
775
|
+
*/
|
|
776
|
+
const declaredClassCarrier = (node, own) => {
|
|
777
|
+
if (!ts.isIdentifier(node) || own.isUnion())
|
|
778
|
+
return null;
|
|
779
|
+
const symbol = checker.getSymbolAtLocation(node);
|
|
780
|
+
const declaration = symbol?.valueDeclaration ?? symbol?.declarations?.[0];
|
|
781
|
+
if (!symbol || !declaration)
|
|
782
|
+
return null;
|
|
783
|
+
const declared = checker.getTypeOfSymbolAtLocation(symbol, declaration);
|
|
784
|
+
const declaredSymbol = declared.getSymbol();
|
|
785
|
+
if (!declaredSymbol || (declaredSymbol.flags & ts.SymbolFlags.Class) === 0)
|
|
786
|
+
return null;
|
|
787
|
+
const ownSymbol = own.getSymbol();
|
|
788
|
+
if (ownSymbol && (ownSymbol.flags & ts.SymbolFlags.Class) !== 0)
|
|
789
|
+
return null;
|
|
790
|
+
return checker.isTypeAssignableTo(own, declared) ? declared : null;
|
|
791
|
+
};
|
|
792
|
+
/**
|
|
793
|
+
* The dynamic carrier behind an `in`-refined structural view.
|
|
794
|
+
*
|
|
795
|
+
* TypeScript describes successive `"key" in value` checks over an
|
|
796
|
+
* explicitly `any`/`unknown` binding as intersections such as
|
|
797
|
+
* `object & Record<"key", unknown>`. Those intersections are facts about
|
|
798
|
+
* which reads are now legal; they do not rebuild the runtime value into a
|
|
799
|
+
* native record. Giving the view a record layout therefore changes the
|
|
800
|
+
* physical carrier in the middle of one binding and makes later dynamic
|
|
801
|
+
* property operations read a box as a struct.
|
|
802
|
+
*
|
|
803
|
+
* Preserve the declared dynamic carrier only for the checker's purely
|
|
804
|
+
* structural intersection: `object` plus anonymous `Record` views. A real
|
|
805
|
+
* narrowing contributes a concrete arm (`ArrayBuffer`, Array, a class, a
|
|
806
|
+
* host object, and so on), whose symbol is neither the anonymous `__type`
|
|
807
|
+
* nor the `Record` alias and therefore remains the layout answer.
|
|
808
|
+
*/
|
|
809
|
+
const declaredDynamicStructuralCarrier = (node, own) => {
|
|
810
|
+
if (!ts.isIdentifier(node) || !own.isIntersection())
|
|
811
|
+
return null;
|
|
812
|
+
const symbol = checker.getSymbolAtLocation(node);
|
|
813
|
+
const declaration = symbol?.valueDeclaration ?? symbol?.declarations?.[0];
|
|
814
|
+
if (!symbol || !declaration)
|
|
815
|
+
return null;
|
|
816
|
+
const declared = checker.getTypeOfSymbolAtLocation(symbol, declaration);
|
|
817
|
+
if ((declared.flags & (ts.TypeFlags.Any | ts.TypeFlags.Unknown)) === 0)
|
|
818
|
+
return null;
|
|
819
|
+
const structuralOnly = own.types.every((part) => {
|
|
820
|
+
if ((part.flags & ts.TypeFlags.NonPrimitive) !== 0)
|
|
821
|
+
return true;
|
|
822
|
+
if ((part.flags & ts.TypeFlags.Object) === 0)
|
|
823
|
+
return false;
|
|
824
|
+
const alias = part.aliasSymbol?.getName();
|
|
825
|
+
const name = part.getSymbol()?.getName();
|
|
826
|
+
return alias === 'Record' || (alias === undefined && (name === undefined || name === '__type'));
|
|
827
|
+
});
|
|
828
|
+
return structuralOnly ? declared : null;
|
|
829
|
+
};
|
|
830
|
+
const layoutTypeOf = (node) => {
|
|
831
|
+
// Asked FIRST, and unconditionally. A host stating that it does not provide
|
|
832
|
+
// an ambient global contradicts an answer the checker is confident about --
|
|
833
|
+
// `VideoFrame` types as a perfectly good constructor object -- so unlike the
|
|
834
|
+
// parameter census below there is no `any` for this to fill in. The
|
|
835
|
+
// declaration and every reference are answered from one table, because they
|
|
836
|
+
// are one cell. See `absent-globals.ts`.
|
|
837
|
+
const absentType = absent.typeAt(node);
|
|
838
|
+
if (absentType)
|
|
839
|
+
return absentType;
|
|
840
|
+
const constructorChoice = nominalConstructorChoiceTypeAt(checker, node, layoutTypeAt);
|
|
841
|
+
if (constructorChoice)
|
|
842
|
+
return constructorChoice;
|
|
843
|
+
// A narrowly scoped construction proof can outrank a checker answer that
|
|
844
|
+
// is usable but wider than every value the initializer can produce. The
|
|
845
|
+
// local-binding census currently publishes only the authenticated
|
|
846
|
+
// `Array.isArray(slot) ? slot : [slot]` invariant through this channel.
|
|
847
|
+
const preferred = parameters.preferredTypeAt?.(node);
|
|
848
|
+
if (preferred)
|
|
849
|
+
return preferred;
|
|
850
|
+
// A STATED ANNOTATION THAT WAS ONLY EVER AN UPPER BOUND, and the one
|
|
851
|
+
// census answer this resolver takes over a checker answer it is happy
|
|
852
|
+
// with. The guarded fallback below cannot serve it: the guard fires only
|
|
853
|
+
// where the checker had `any` or a vacuous type, and the whole point here
|
|
854
|
+
// is that the checker's answer is a perfectly good structure whose one
|
|
855
|
+
// unstated leaf the program's only caller filled in concretely (hono's
|
|
856
|
+
// `matchResult: Result<[unknown, RouterRoute]>`). Narrow by construction
|
|
857
|
+
// -- `statedTypeAt` answers only for a parameter the census admitted
|
|
858
|
+
// under `statedUpperBound` and for identifiers that read it -- and taken
|
|
859
|
+
// FIRST for the reason the file's own header gives about splits: the ABI
|
|
860
|
+
// slot (`structural-parts.ts`'s `parameterOf`) already reads the census,
|
|
861
|
+
// so a body read answered from the checker here would be the second
|
|
862
|
+
// authority, not a safer one.
|
|
863
|
+
const narrowedByStatement = parameters.statedTypeAt(node);
|
|
864
|
+
if (narrowedByStatement)
|
|
865
|
+
return narrowedByStatement;
|
|
866
|
+
const spreadConditionalArray = spreadConditionalArrayTypeOf(node);
|
|
867
|
+
if (spreadConditionalArray)
|
|
868
|
+
return spreadConditionalArray;
|
|
869
|
+
// ...and the member reads THROUGH it. A narrowed parameter that nothing
|
|
870
|
+
// follows is half a narrowing: `compose( middleware )` reads
|
|
871
|
+
// `middleware[ i ][ 0 ]`, and the checker answers those from the
|
|
872
|
+
// annotation whatever the census did to the parameter itself -- so the
|
|
873
|
+
// cell held the concrete element while every read of it published the
|
|
874
|
+
// stated one, which is the same two-authority split `statedTypeAt`'s own
|
|
875
|
+
// doc records at the ABI. `memberThroughBoundReceiver` already resolves a
|
|
876
|
+
// member off the best receiver answer available (and recurses through
|
|
877
|
+
// `layoutTypeAt`, so a chain composes); this only decides WHEN to ask it,
|
|
878
|
+
// and asks only where the chain bottoms out at a statement the census
|
|
879
|
+
// narrowed -- never for an ordinary read, whose checker answer stands.
|
|
880
|
+
if (receiverChainWasNarrowedByStatement(node)) {
|
|
881
|
+
const throughStatement = memberThroughBoundReceiver(node);
|
|
882
|
+
if (throughStatement)
|
|
883
|
+
return throughStatement;
|
|
884
|
+
}
|
|
885
|
+
// HOLDS, and yet deliberately asked of the checker FIRST, not through
|
|
886
|
+
// `censusedTypeAt`. Tried census-first here and measured it directly
|
|
887
|
+
// (isolated build, three.js app): boxed fell (20181->19852) but `withheld`
|
|
888
|
+
// rose 6->14, all fourteen "cites result ... which no installed producer
|
|
889
|
+
// publishes" -- a real disagreement, not noise. This is the ONE place in
|
|
890
|
+
// the file that answers `own` for every node kind `layoutTypeAt` is ever
|
|
891
|
+
// asked about, including nodes OTHER producers derive their own answer
|
|
892
|
+
// for independently (an invocation's own result, a binding's own read);
|
|
893
|
+
// substituting the census's answer here changes what those nodes publish
|
|
894
|
+
// out from under producers that still key off the checker's own type,
|
|
895
|
+
// and the two stop agreeing. The file's EXISTING design already
|
|
896
|
+
// consults the census correctly for this same `own` -- conditionally,
|
|
897
|
+
// a few lines down, only once `own` is `any`/vacuous (`parameters.
|
|
898
|
+
// typeAt(node)` at the `bound` lookup) -- which is safe for the identical
|
|
899
|
+
// reason `censusedTypeAt`'s own contract is: it only ever fires where the
|
|
900
|
+
// checker had nothing. Keep asking the checker here; let the guarded
|
|
901
|
+
// fallback below be the one census consultation for this value.
|
|
902
|
+
const own = settleEvolving(node, checker.getTypeAtLocation(node));
|
|
903
|
+
const dynamicCarrier = declaredDynamicStructuralCarrier(node, own);
|
|
904
|
+
if (dynamicCarrier)
|
|
905
|
+
return dynamicCarrier;
|
|
906
|
+
const classCarrier = declaredClassCarrier(node, own);
|
|
907
|
+
if (classCarrier)
|
|
908
|
+
return classCarrier;
|
|
909
|
+
const dictionaryAlias = constDictionaryAliasType(node, own);
|
|
910
|
+
if (dictionaryAlias)
|
|
911
|
+
return dictionaryAlias;
|
|
912
|
+
const declaredArrayArm = soleDeclaredArrayArm(node, own);
|
|
913
|
+
if (declaredArrayArm)
|
|
914
|
+
return declaredArrayArm;
|
|
915
|
+
const patternRead = arrayPatternReadOutranking(node, own);
|
|
916
|
+
if (patternRead)
|
|
917
|
+
return patternRead;
|
|
918
|
+
// An `any` here is one of exactly two answers worth a second question. It
|
|
919
|
+
// is the only shape the checker produces that can mean "nothing was
|
|
920
|
+
// written down" rather than "this is what it is, and it is dynamic" -- and
|
|
921
|
+
// for a parameter the program never annotated, the call site wrote it
|
|
922
|
+
// down. The census answers `null` for everything else, including a value
|
|
923
|
+
// the program genuinely declared `any`, so this changes nothing about a
|
|
924
|
+
// program that states its own types. See `parameter-bindings.ts`.
|
|
925
|
+
//
|
|
926
|
+
// The second is a type that was written down and states NOTHING --
|
|
927
|
+
// `object`, `{}`, `Object`. `annotationStatesNothing` is the ONE rule that
|
|
928
|
+
// decides this, shared with the two censuses (`derived-expression-type.
|
|
929
|
+
// ts`); it must be asked HERE too or the two authorities split. Measured
|
|
930
|
+
// exactly that: a call to `function makesBag(): object { return { a: 1, b:
|
|
931
|
+
// 2 } }` had its selected signature's return type answered by the return
|
|
932
|
+
// census (a real record) while this resolver, seeing a checker type that
|
|
933
|
+
// is not `any`, still answered the annotation's empty record for the CALL
|
|
934
|
+
// -- and `model/selected-signature.ts`'s `validateInvocationResult` fired
|
|
935
|
+
// exactly as it should, taking the invocation AND the binding it
|
|
936
|
+
// initialized out of the plan as withheld. The guard was right; the split
|
|
937
|
+
// was here.
|
|
938
|
+
// A destructured parameter's implied pattern type is the third spelling
|
|
939
|
+
// of "the program stated nothing here" -- see `impliedPatternParameterOf`.
|
|
940
|
+
if ((own.flags & ts.TypeFlags.Any) !== 0 ||
|
|
941
|
+
annotationStatesNothing(checker, node, own) ||
|
|
942
|
+
impliedPatternParameterOf(checker, node) !== null ||
|
|
943
|
+
impliedPatternElementRootOf(checker, node) !== null) {
|
|
944
|
+
// Asked before the parameter census: a literal token is not a value the
|
|
945
|
+
// program left open for its callers to write down. See above.
|
|
946
|
+
const literal = literalTokenType(node);
|
|
947
|
+
if (literal)
|
|
948
|
+
return literal;
|
|
949
|
+
const bound = parameters.typeAt(node);
|
|
950
|
+
// A census answer that is an OPEN FORM is not an answer -- the same rule
|
|
951
|
+
// the censuses themselves apply to what they publish, asked once more
|
|
952
|
+
// here because this resolver is where a census answer BECOMES a layout
|
|
953
|
+
// type, and three censuses compose into the one `parameters` view. The
|
|
954
|
+
// checker's own `own` (already reduced at this site) is what stands when
|
|
955
|
+
// it declines. See `isUnreducedTypeForm`.
|
|
956
|
+
if (bound && !isUnreducedTypeForm(bound))
|
|
957
|
+
return bound;
|
|
958
|
+
// THE CENSUS ANSWER HAS TO FOLLOW THE MEMBER READ.
|
|
959
|
+
//
|
|
960
|
+
// `parameters.typeAt` answers about the node a census BOUND -- a
|
|
961
|
+
// parameter declaration, a cell, a field. A property access off that
|
|
962
|
+
// binding is a DIFFERENT node, and the checker still answers it `any`
|
|
963
|
+
// because the checker never learned what the receiver holds. So a
|
|
964
|
+
// receiver the census typed perfectly well produced a boxed member read,
|
|
965
|
+
// and every value derived from that read boxed in turn.
|
|
966
|
+
//
|
|
967
|
+
// Measured: `WebGLTextures.js`'s `_gl` parameter is bound to
|
|
968
|
+
// `NativeWebGL2RenderingContext | null` -- and ALL 421 `_gl.<member>`
|
|
969
|
+
// reads in that file were boxed anyway. That file carries 4435 of
|
|
970
|
+
// the three.js app's 27902 boxed carriers, and 6836 of them program-wide are
|
|
971
|
+
// property accesses; the 14349 identifier reads are largely what those
|
|
972
|
+
// accesses flow into. One unfollowed edge, not thousands of decisions.
|
|
973
|
+
//
|
|
974
|
+
// Resolving the receiver through `layoutTypeAt` itself rather than
|
|
975
|
+
// through the checker is what makes this compose: a chain
|
|
976
|
+
// `a.b.c` resolves `a` from the census, `a.b` from `a`, and `a.b.c` from
|
|
977
|
+
// `a.b`. `getNonNullableType` because a censused receiver routinely
|
|
978
|
+
// carries the `| null` its own writes justify (`_gl` does) while every
|
|
979
|
+
// read of it is guarded.
|
|
980
|
+
//
|
|
981
|
+
// Same shape, and the same cure, as `absent-globals.ts`'s collapse
|
|
982
|
+
// needing to recurse through the receiver: reading a property of a value
|
|
983
|
+
// whose type only ONE authority knows must ask that authority.
|
|
984
|
+
const throughReceiver = memberThroughBoundReceiver(node);
|
|
985
|
+
if (throughReceiver)
|
|
986
|
+
return throughReceiver;
|
|
987
|
+
}
|
|
988
|
+
// `own` is not `any` itself, but may still be a generic instantiation
|
|
989
|
+
// whose OWN type argument is -- CFA narrowing an `any`-typed value against
|
|
990
|
+
// a generic ambient class (`res instanceof Promise`) produces exactly this
|
|
991
|
+
// shape. See `declaredGenericArmAt`.
|
|
992
|
+
const recovered = declaredGenericArmAt(node, own);
|
|
993
|
+
if (recovered)
|
|
994
|
+
return recovered;
|
|
995
|
+
// The same statement, made about the CELL rather than about the value: an
|
|
996
|
+
// annotation that states no storage its own initializer already states
|
|
997
|
+
// cannot be the carrier either, or the store into it is exactly the
|
|
998
|
+
// conversion the literal rule below exists to avoid --
|
|
999
|
+
// `const fieldSource: Iterable<string> = { [Symbol.iterator](): FieldCursor
|
|
1000
|
+
// { ... } }`, where the cursor's `this.label` lives or dies on which of the
|
|
1001
|
+
// two the cell holds. One rule, three callers, because a cell, its
|
|
1002
|
+
// initializer and every read of it are ONE cell: answering the read from
|
|
1003
|
+
// the annotation while the cell holds the literal is the two-authority
|
|
1004
|
+
// split this file's own header describes.
|
|
1005
|
+
if (ts.isVariableDeclaration(node)) {
|
|
1006
|
+
const deferred = annotationDeferringToInitializer(node);
|
|
1007
|
+
if (deferred)
|
|
1008
|
+
return deferred;
|
|
1009
|
+
}
|
|
1010
|
+
// The third caller of that same rule: the literal's own members read the
|
|
1011
|
+
// value through `this`, and a read answered from the annotation while the
|
|
1012
|
+
// value IS the literal is the identical two-authority split. Asked here,
|
|
1013
|
+
// where the checker's answer for the keyword would otherwise stand.
|
|
1014
|
+
const literalReceiver = objectLiteralMemberReceiverAt(node);
|
|
1015
|
+
if (literalReceiver)
|
|
1016
|
+
return literalReceiver;
|
|
1017
|
+
const declaringCell = ts.isIdentifier(node) ? boundSymbolOf(node)?.valueDeclaration : undefined;
|
|
1018
|
+
if (declaringCell && ts.isVariableDeclaration(declaringCell) && declaringCell.name !== node) {
|
|
1019
|
+
const deferred = annotationDeferringToInitializer(declaringCell);
|
|
1020
|
+
if (deferred)
|
|
1021
|
+
return deferred;
|
|
1022
|
+
}
|
|
1023
|
+
if (!ts.isObjectLiteralExpression(node) && !ts.isArrayLiteralExpression(node))
|
|
1024
|
+
return own;
|
|
1025
|
+
// The `{}` of `Object.assign( {}, ...sources )` is laid out as what the
|
|
1026
|
+
// call makes of it, from the same authority the call's result reads.
|
|
1027
|
+
if (ts.isObjectLiteralExpression(node)) {
|
|
1028
|
+
const freshTarget = objectAssignFreshTargetType(checker, node);
|
|
1029
|
+
if (freshTarget)
|
|
1030
|
+
return freshTarget;
|
|
1031
|
+
}
|
|
1032
|
+
// AN EMPTY ARRAY LITERAL NESTED IN ANOTHER LITERAL takes its element from
|
|
1033
|
+
// the position it fills, not from its own inference. `[]` alone infers
|
|
1034
|
+
// `never[]` (see `structural-array-element.ts`'s header for why that is a
|
|
1035
|
+
// mis-inference and not a statement), and its own contextual type is no
|
|
1036
|
+
// help when the outer literal's contextual type is a union: the checker
|
|
1037
|
+
// reports the union of what EVERY arm's element could be, while the outer
|
|
1038
|
+
// literal has already committed to one arm. hono's
|
|
1039
|
+
// `matchResult: Result<[unknown, RouterRoute]> = [[]]` is the case -- the
|
|
1040
|
+
// outer `[[]]` resolves to `Result`'s one-element arm by arity below, and
|
|
1041
|
+
// the inner `[]` then has exactly one thing it can be.
|
|
1042
|
+
const nestedPosition = emptyArrayPositionTypeOf(node);
|
|
1043
|
+
if (nestedPosition)
|
|
1044
|
+
return nestedPosition;
|
|
1045
|
+
// A DEFAULT VALUE is contextually typed by the cell it fills, and when the
|
|
1046
|
+
// census narrowed that cell the annotation is no longer what it fills.
|
|
1047
|
+
// hono's `matchResult: Result<[unknown, RouterRoute]> = [[]]` is the pair:
|
|
1048
|
+
// the annotation states `unknown` where the only caller passes `H`, so the
|
|
1049
|
+
// slot carries the caller's `Result<[H, RouterRoute]>` and a literal
|
|
1050
|
+
// resolved against the annotation instead builds the one shape the slot
|
|
1051
|
+
// cannot hold. Asked here rather than left to a conversion for the reason
|
|
1052
|
+
// the arity rule below states -- reconciling the two rebuilds arrays.
|
|
1053
|
+
const parameterOfInitializer = ts.isParameter(node.parent) && node.parent.initializer === node ? node.parent : null;
|
|
1054
|
+
const narrowedSlot = parameterOfInitializer ? parameters.statedTypeAt(parameterOfInitializer) : null;
|
|
1055
|
+
const checkerContext = checker.getContextualType(node);
|
|
1056
|
+
// A call argument fills the same parameter cell as its default does.
|
|
1057
|
+
// In particular [] contributes no element evidence of its own; its
|
|
1058
|
+
// allocation must use the native element type the caller census proved
|
|
1059
|
+
// for that cell, rather than the erased Function/unknown annotation.
|
|
1060
|
+
const call = ts.isCallExpression(node.parent) || ts.isNewExpression(node.parent) ? node.parent : null;
|
|
1061
|
+
const argumentIndex = call?.arguments?.indexOf(node) ?? -1;
|
|
1062
|
+
const selectedParameter = call && argumentIndex >= 0 && !call.arguments?.slice(0, argumentIndex).some(ts.isSpreadElement)
|
|
1063
|
+
? checker.getResolvedSignature(call)?.getParameters()[argumentIndex]?.valueDeclaration
|
|
1064
|
+
: undefined;
|
|
1065
|
+
const parameterContext = selectedParameter && ts.isParameter(selectedParameter) && !selectedParameter.dotDotDotToken
|
|
1066
|
+
? (parameters.statedTypeAt(selectedParameter) ?? parameters.typeAt(selectedParameter))
|
|
1067
|
+
: null;
|
|
1068
|
+
const narrowedCallSlot = checkerContext &&
|
|
1069
|
+
parameterContext &&
|
|
1070
|
+
containsUnstatedPosition(checker, node, checkerContext) &&
|
|
1071
|
+
narrowsOnlyUnstatedPositions(checker, node, checkerContext, parameterContext)
|
|
1072
|
+
? parameterContext
|
|
1073
|
+
: null;
|
|
1074
|
+
// JavaScript expando inference attaches the completed object shape to the
|
|
1075
|
+
// declaration while the fresh `{}` initializer itself remains the empty
|
|
1076
|
+
// object type and has no contextual type. That makes one allocation use
|
|
1077
|
+
// an empty struct and the cell receiving it use the completed struct,
|
|
1078
|
+
// even though later `data.attribute = ...` writes are mutations of this
|
|
1079
|
+
// very same fresh object. Allocate the declaration's inferred shape from
|
|
1080
|
+
// the start. This is restricted to a direct, unannotated empty-literal
|
|
1081
|
+
// initializer: no alias can observe a distinct object before the binding
|
|
1082
|
+
// is established, and a stated TypeScript annotation remains the normal
|
|
1083
|
+
// checker context rather than being reinterpreted here.
|
|
1084
|
+
const inferredDeclarationContext = (() => {
|
|
1085
|
+
if (!ts.isObjectLiteralExpression(node) || node.properties.length !== 0)
|
|
1086
|
+
return null;
|
|
1087
|
+
const declaration = node.parent;
|
|
1088
|
+
if (!ts.isVariableDeclaration(declaration) || declaration.initializer !== node || declaration.type !== undefined)
|
|
1089
|
+
return null;
|
|
1090
|
+
const inferred = checker.getTypeAtLocation(declaration);
|
|
1091
|
+
if ((inferred.flags & ts.TypeFlags.Object) === 0 || isVacuousObjectType(declaration, inferred))
|
|
1092
|
+
return null;
|
|
1093
|
+
return inferred;
|
|
1094
|
+
})();
|
|
1095
|
+
// A literal written against a pattern whose type the checker merely
|
|
1096
|
+
// implied from the pattern's shape has no stated context at all: `{ x:
|
|
1097
|
+
// any }` for `({ x } = { x: 23 })` is the pattern's silhouette, and laying
|
|
1098
|
+
// the literal out by it made every field of the default dynamic where the
|
|
1099
|
+
// literal itself wrote a number. The literal's own type is the value.
|
|
1100
|
+
if (impliedPatternTargetOf(checker, node))
|
|
1101
|
+
return own;
|
|
1102
|
+
const contextual = narrowedSlot ?? narrowedCallSlot ?? checkerContext ?? inferredDeclarationContext;
|
|
1103
|
+
if (!contextual || contextual.isIntersection())
|
|
1104
|
+
return own;
|
|
1105
|
+
let candidate = contextual.isUnion() ? soleShapedArm(contextual) : contextual;
|
|
1106
|
+
if (candidate === null && contextual.isUnion() && ts.isObjectLiteralExpression(node)) {
|
|
1107
|
+
// A union can contain several object shapes while this literal satisfies
|
|
1108
|
+
// exactly one of them. TypeScript has already checked that relation; ask
|
|
1109
|
+
// its assignability rather than rebuilding a key discriminator here.
|
|
1110
|
+
// BSON's legacy/modern EJSON records are the concrete case: both arms
|
|
1111
|
+
// are objects, while `$binary: string` and `$binary: { ... }` each fit
|
|
1112
|
+
// only one. Allocating that declared arm directly preserves the fresh
|
|
1113
|
+
// object's identity and avoids a later shared-record reconstruction.
|
|
1114
|
+
const assignable = contextual.types.filter((member) => (member.flags & ts.TypeFlags.Object) !== 0 && checker.isTypeAssignableTo(own, member));
|
|
1115
|
+
candidate = assignable.length === 1 ? (assignable[0] ?? null) : null;
|
|
1116
|
+
}
|
|
1117
|
+
if (candidate === null && contextual.isUnion() && ts.isObjectLiteralExpression(node)) {
|
|
1118
|
+
// A literal that SPREADS a source with no statically known own-property
|
|
1119
|
+
// set (a union, or a type with an index signature) is the one case
|
|
1120
|
+
// where `own` -- the checker's OWN inference of the literal's result --
|
|
1121
|
+
// cannot be trusted even as a fallback. `CopyDataProperties` copies
|
|
1122
|
+
// whatever keys the source holds at runtime, but the checker's
|
|
1123
|
+
// inference of `{ 'Content-Type': x, ...headers }` for `headers:
|
|
1124
|
+
// Record<'Content-Type', BaseMime> | Record<ResponseHeader, string> |
|
|
1125
|
+
// Record<string, string>` unions one shape per contextually-possible
|
|
1126
|
+
// arm of the SOURCE and drops every arm's index signature entirely --
|
|
1127
|
+
// `own` ends up a plain multi-arm record union with no sign the
|
|
1128
|
+
// dictionary keys were ever copied. A layout built from that type can
|
|
1129
|
+
// only ever hold the literal's own written keys, silently dropping
|
|
1130
|
+
// whatever the spread copies at runtime.
|
|
1131
|
+
//
|
|
1132
|
+
// The one member of `HeaderRecord`'s own arms that can genuinely hold
|
|
1133
|
+
// ANY key the spread might copy is its INDEX-SIGNATURE arm -- every
|
|
1134
|
+
// other arm is a fixed, narrower key set that a dynamic copy could
|
|
1135
|
+
// overflow. So when the union has EXACTLY one such arm, that arm --
|
|
1136
|
+
// not the whole ambiguous union, and not `own` -- is this literal's
|
|
1137
|
+
// layout: it is both a real member of the declared type (so the value
|
|
1138
|
+
// this literal builds still needs no conversion to be a `HeaderRecord`)
|
|
1139
|
+
// and the one shape wide enough for a runtime-enumerated copy to write
|
|
1140
|
+
// into. Scoped tightly to exactly the circumstance `own` cannot answer
|
|
1141
|
+
// -- a spread of a dynamic source is why `own` lost the index
|
|
1142
|
+
// signature in the first place, and a literal with no such spread
|
|
1143
|
+
// keeps `soleShapedArm`'s existing, deliberately conservative refusal.
|
|
1144
|
+
// `checker.getTypeAtLocation` directly, NOT a recursive `layoutTypeAt`
|
|
1145
|
+
// call: this closure is already inside `layoutTypeAt`'s own body, and a
|
|
1146
|
+
// spread source that is itself an object/array literal with a
|
|
1147
|
+
// deeply-generic contextual type (hono's router chains, measured) can
|
|
1148
|
+
// drive the checker's own resolution deep enough that a second,
|
|
1149
|
+
// mutually-recursive entry into this function overflows the call
|
|
1150
|
+
// stack. The raw checker type is exactly what `own` above is already
|
|
1151
|
+
// built from, so this loses only the parameter-census/`any`-follow
|
|
1152
|
+
// refinement `layoutTypeAt` layers on top -- immaterial here, since
|
|
1153
|
+
// this test only asks "is this shape a union or does it carry an index
|
|
1154
|
+
// signature", which the raw checker answer already carries correctly for a
|
|
1155
|
+
// union or index-signature source (this test never fires for an `any`).
|
|
1156
|
+
const spreadsDynamicSource = node.properties.some((property) => {
|
|
1157
|
+
if (!ts.isSpreadAssignment(property))
|
|
1158
|
+
return false;
|
|
1159
|
+
const sourceType = checker.getTypeAtLocation(property.expression);
|
|
1160
|
+
if (sourceType.isUnion())
|
|
1161
|
+
return true;
|
|
1162
|
+
if ((sourceType.flags & ts.TypeFlags.Object) === 0)
|
|
1163
|
+
return true;
|
|
1164
|
+
return checker.getIndexInfosOfType(sourceType).length > 0;
|
|
1165
|
+
});
|
|
1166
|
+
if (spreadsDynamicSource) {
|
|
1167
|
+
const indexed = contextual.types.filter((member) => (member.flags & ts.TypeFlags.Object) !== 0 && checker.getIndexInfosOfType(member).length > 0);
|
|
1168
|
+
candidate = indexed.length === 1 ? (indexed[0] ?? null) : null;
|
|
1169
|
+
}
|
|
1170
|
+
}
|
|
1171
|
+
if (candidate === null && contextual.isUnion() && ts.isArrayLiteralExpression(node)) {
|
|
1172
|
+
// A TUPLE LITERAL PICKS ITS ARM BY LENGTH, which is the language's own
|
|
1173
|
+
// rule and not a preference invented here: `[[]]` against
|
|
1174
|
+
// `[[T, ParamIndexMap][], ParamStash] | [[T, Params][]]` can only be
|
|
1175
|
+
// the second, because the first states two elements and the literal
|
|
1176
|
+
// writes one. `soleShapedArm`'s refusal above is deliberately
|
|
1177
|
+
// conservative about picking between arms of a union and has no notion
|
|
1178
|
+
// of arity to refuse on, so hono's `Result<T>` fell back to the
|
|
1179
|
+
// literal's own `[never[]]` -- a carrier the declared parameter cannot
|
|
1180
|
+
// hold, and the conversion that would fix it up rebuilds two arrays,
|
|
1181
|
+
// which is a COPY of an array the caller may still hold.
|
|
1182
|
+
//
|
|
1183
|
+
// Only when exactly one arm fits. Two arms of the same length is a
|
|
1184
|
+
// choice this cannot make, and the fallback stays.
|
|
1185
|
+
const fitted = contextual.types.filter((member) => checker.isTupleType(member) && checker.getTypeArguments(member).length === node.elements.length);
|
|
1186
|
+
candidate = fitted.length === 1 ? (fitted[0] ?? null) : null;
|
|
1187
|
+
}
|
|
1188
|
+
if (candidate === null || !(candidate.flags & ts.TypeFlags.Object))
|
|
1189
|
+
return own;
|
|
1190
|
+
if (isVacuousObjectType(node, candidate))
|
|
1191
|
+
return own;
|
|
1192
|
+
if (statesNoStorageBeyondTheLiteral(node, candidate, own))
|
|
1193
|
+
return own;
|
|
1194
|
+
if (discardsLiteralAccessor(node, candidate, own))
|
|
1195
|
+
return own;
|
|
1196
|
+
if (ts.isArrayLiteralExpression(node) && !checker.isArrayType(candidate) && !checker.isTupleType(candidate))
|
|
1197
|
+
return own;
|
|
1198
|
+
// Context can state the tuple shape without stating the callable stored
|
|
1199
|
+
// inside it: [Function][] must not erase a literal's concrete signature.
|
|
1200
|
+
// The same upper-bound test the parameter census uses proves that only
|
|
1201
|
+
// unstated positions narrow. Empty literals supply no such evidence.
|
|
1202
|
+
if (ts.isArrayLiteralExpression(node) &&
|
|
1203
|
+
node.elements.length > 0 &&
|
|
1204
|
+
containsUnstatedPosition(checker, node, candidate) &&
|
|
1205
|
+
narrowsOnlyUnstatedPositions(checker, node, candidate, own))
|
|
1206
|
+
return own;
|
|
1207
|
+
return candidate;
|
|
1208
|
+
};
|
|
1209
|
+
/**
|
|
1210
|
+
* Whether a contextual type from a lib declaration states no storage this
|
|
1211
|
+
* literal does not already state, and states it LESS precisely.
|
|
1212
|
+
*
|
|
1213
|
+
* `const fieldSource: Iterable<string> = { [Symbol.iterator](): FieldCursor
|
|
1214
|
+
* { ... } }`. ECMA-262 27.1 defines Iterable and Iterator as *protocols* --
|
|
1215
|
+
* the set of methods a value must answer to -- with no internal slot and no
|
|
1216
|
+
* allocation of their own, so `Iterable<string>` is a statement about how
|
|
1217
|
+
* this value may be USED, never about how it is stored. Adopting it as the
|
|
1218
|
+
* layout replaces the literal's own `[Symbol.iterator](): FieldCursor` with
|
|
1219
|
+
* the protocol's widened `(): Iterator<string>`, and the store of one
|
|
1220
|
+
* callable convention into the other has no conversion -- worse, a sliced
|
|
1221
|
+
* copy would rebind `next`'s receiver to the sliced record and lose the
|
|
1222
|
+
* `this.label` the cursor's whole body reads.
|
|
1223
|
+
*
|
|
1224
|
+
* Stated as the general property rather than by naming the iteration types,
|
|
1225
|
+
* because it IS the general reason a contextual type is worth adopting: a
|
|
1226
|
+
* declared shape earns the layout when it ADDS storage (`RequestInit`'s
|
|
1227
|
+
* optional members, which the literal omits and the record must still carry
|
|
1228
|
+
* a presence bit for) or when it supplies an identity the literal has none
|
|
1229
|
+
* of. One that declares only members the literal itself declares, more
|
|
1230
|
+
* loosely than the literal declares them, supplies neither -- it can only
|
|
1231
|
+
* cost precision. Lib-declared only: a PROGRAM interface is a nominal
|
|
1232
|
+
* identity this compiler keeps deliberately (`interface-families.ts`), and
|
|
1233
|
+
* the member-result census already keeps its members in agreement.
|
|
1234
|
+
*/
|
|
1235
|
+
/**
|
|
1236
|
+
* Whether adopting a CONTEXTUAL candidate would strand one of the literal's
|
|
1237
|
+
* own accessor bodies with nowhere to be installed.
|
|
1238
|
+
*
|
|
1239
|
+
* An index signature is a statement about what a READ of an unnamed key
|
|
1240
|
+
* yields, not about how a NAMED member the literal itself declares is
|
|
1241
|
+
* physically stored. `@hono/node-server`'s `request.ts` types its whole
|
|
1242
|
+
* prototype object `Record<string | symbol, any>` -- an escape hatch for
|
|
1243
|
+
* attaching private state under keys the declared type cannot enumerate --
|
|
1244
|
+
* and then declares `get method() { return this[methodKey] }` as a real
|
|
1245
|
+
* accessor. `Record<K, V>` instantiated over a non-literal key (`string |
|
|
1246
|
+
* symbol`) has no named property at all -- `getProperties()` is empty, only
|
|
1247
|
+
* `getIndexInfosOfType()` answers -- so adopting it as this literal's layout
|
|
1248
|
+
* carries the getter's own declaration nowhere: `structural.ts`'s member
|
|
1249
|
+
* walk (`objectShapeOf`) enumerates the CANDIDATE's own properties, not the
|
|
1250
|
+
* literal's, and a key the candidate never names as a property is never
|
|
1251
|
+
* visited, so the accessor body is dropped before `structural-parts.ts`'s
|
|
1252
|
+
* `literalAccessorOf` ever gets a symbol to ask about.
|
|
1253
|
+
* `producers/allocations.ts` then correctly refuses ("...has nowhere to
|
|
1254
|
+
* install its body") -- that guard is fail-closed and right to fire; the
|
|
1255
|
+
* defect is here, at the choice of layout, not at that guard.
|
|
1256
|
+
*
|
|
1257
|
+
* Narrow by construction: only fires for a key the literal declares as an
|
|
1258
|
+
* ACCESSOR. Ordinary data needs no named slot to be installed into a
|
|
1259
|
+
* dictionary -- `CreateDataPropertyOrThrow` writes through the index the
|
|
1260
|
+
* same way regardless, which is exactly why `isVacuousObjectType` above
|
|
1261
|
+
* deliberately treats an index-signature type as non-vacuous (voice-notes'
|
|
1262
|
+
* `Record<string, string>` header literal). And a candidate that DOES name
|
|
1263
|
+
* the key, even as plain data (`interface C { get next(): T }`, spelled as
|
|
1264
|
+
* data on purpose -- see `typed-custom-iterator-close.ts`), is untouched:
|
|
1265
|
+
* that case already has its own path, `structural-parts.ts`'s
|
|
1266
|
+
* `declaredMembers.accessorBodiesOf`, which needs the candidate's own
|
|
1267
|
+
* property SYMBOL to attach the literal's body to, and still gets one
|
|
1268
|
+
* there. Only a key with NO named property in the candidate at all -- an
|
|
1269
|
+
* index-only escape hatch, not a declared-but-untyped-as-accessor member --
|
|
1270
|
+
* reaches this refusal.
|
|
1271
|
+
*/
|
|
1272
|
+
const discardsLiteralAccessor = (node, candidate, own) => {
|
|
1273
|
+
if (!ts.isObjectLiteralExpression(node))
|
|
1274
|
+
return false;
|
|
1275
|
+
return own.getProperties().some((property) => {
|
|
1276
|
+
if ((property.getFlags() & (ts.SymbolFlags.GetAccessor | ts.SymbolFlags.SetAccessor)) === 0)
|
|
1277
|
+
return false;
|
|
1278
|
+
return checker.getPropertyOfType(candidate, property.getName()) === undefined;
|
|
1279
|
+
});
|
|
1280
|
+
};
|
|
1281
|
+
const statesNoStorageBeyondTheLiteral = (node, candidate, own) => {
|
|
1282
|
+
if (!ts.isObjectLiteralExpression(node))
|
|
1283
|
+
return false;
|
|
1284
|
+
const declarations = candidate.getSymbol()?.declarations ?? [];
|
|
1285
|
+
if (declarations.length === 0 || !declarations.every((declaration) => declaration.getSourceFile().hasNoDefaultLib))
|
|
1286
|
+
return false;
|
|
1287
|
+
const members = candidate.getProperties();
|
|
1288
|
+
if (members.length === 0)
|
|
1289
|
+
return false;
|
|
1290
|
+
const mine = own.getProperties();
|
|
1291
|
+
let widened = false;
|
|
1292
|
+
for (const member of members) {
|
|
1293
|
+
const implemented = mine.find((property) => property.escapedName === member.escapedName);
|
|
1294
|
+
if (!implemented)
|
|
1295
|
+
return false;
|
|
1296
|
+
const declaredType = checker.getTypeOfSymbolAtLocation(member, node);
|
|
1297
|
+
const ownType = checker.getTypeOfSymbolAtLocation(implemented, node);
|
|
1298
|
+
if (declaredType === ownType)
|
|
1299
|
+
continue;
|
|
1300
|
+
// Narrower in the literal is the only direction this rule may fire on:
|
|
1301
|
+
// a literal member the declaration does NOT accept is a mis-inference
|
|
1302
|
+
// the declared shape is there to correct, and must keep correcting.
|
|
1303
|
+
if (!checker.isTypeAssignableTo(ownType, declaredType))
|
|
1304
|
+
return false;
|
|
1305
|
+
if (!checker.isTypeAssignableTo(declaredType, ownType))
|
|
1306
|
+
widened = true;
|
|
1307
|
+
}
|
|
1308
|
+
return widened;
|
|
1309
|
+
};
|
|
1310
|
+
/**
|
|
1311
|
+
* The carrier of an annotated cell whose annotation is one the literal
|
|
1312
|
+
* filling it already refused -- `null` for every other cell.
|
|
1313
|
+
*
|
|
1314
|
+
* Two reasons, both of them the literal's own rule asked a second time
|
|
1315
|
+
* about the CELL, because a cell, its initializer and every read of it are
|
|
1316
|
+
* one cell: `statesNoStorageBeyondTheLiteral` (the annotation adds nothing
|
|
1317
|
+
* and loses precision) and `discardsLiteralAccessor` (the annotation names
|
|
1318
|
+
* no property the literal declares as an accessor, so adopting it would
|
|
1319
|
+
* strand the body). Sharing the predicates rather than restating them is
|
|
1320
|
+
* what keeps the cell and the value one answer: an annotation the literal
|
|
1321
|
+
* declined, left standing on the cell, IS the store the literal rule exists
|
|
1322
|
+
* to avoid -- `@hono/node-server`'s `requestPrototype` built a
|
|
1323
|
+
* `native-record-ref` while its `Record<string | symbol, any>` cell
|
|
1324
|
+
* declared a `record-with-index`, and there is no conversion between them.
|
|
1325
|
+
*/
|
|
1326
|
+
const annotationDeferringToInitializer = (declaration) => {
|
|
1327
|
+
if (!declaration.type || !declaration.initializer || !ts.isObjectLiteralExpression(declaration.initializer))
|
|
1328
|
+
return null;
|
|
1329
|
+
const stated = layoutTypeOf(declaration.initializer);
|
|
1330
|
+
const annotation = checker.getTypeAtLocation(declaration);
|
|
1331
|
+
if (statesNoStorageBeyondTheLiteral(declaration.initializer, annotation, stated))
|
|
1332
|
+
return stated;
|
|
1333
|
+
return discardsLiteralAccessor(declaration.initializer, annotation, stated) ? stated : null;
|
|
1334
|
+
};
|
|
1335
|
+
/**
|
|
1336
|
+
* `this`, read inside a member of an object literal whose LAYOUT refused
|
|
1337
|
+
* that literal's contextual type.
|
|
1338
|
+
*
|
|
1339
|
+
* ECMA-262 binds an object literal method's `this` to the object the call
|
|
1340
|
+
* resolved on, and TypeScript types the keyword from the literal's
|
|
1341
|
+
* CONTEXTUAL type (`getContextualThisParameterType` widens the literal's
|
|
1342
|
+
* context when no `ThisType<T>` overrides it). That is the same question
|
|
1343
|
+
* this resolver answers for the literal itself -- and where it answers
|
|
1344
|
+
* differently (`discardsLiteralAccessor` above, which refuses an
|
|
1345
|
+
* index-signature annotation that would strand a getter body), the two
|
|
1346
|
+
* answers describe ONE value: the frame's receiver, which
|
|
1347
|
+
* `structural-receiver.ts`'s `implicitReceiverOf` takes from
|
|
1348
|
+
* `layoutTypeAt(literal)`, and the read of it inside the body. Leaving the
|
|
1349
|
+
* read on the refused annotation is that split, and `ir/verify.ts` names it
|
|
1350
|
+
* exactly -- `@hono/node-server`'s `get method() { return this[methodKey] }`
|
|
1351
|
+
* reported nine bodies whose `this` operand expected the annotation's
|
|
1352
|
+
* `record-with-index` while its definition selected the literal's own
|
|
1353
|
+
* `native-record-ref`. The layout is the authority for what the value
|
|
1354
|
+
* physically is, so it answers the read too.
|
|
1355
|
+
*
|
|
1356
|
+
* Fires ONLY where the two already disagree, so it cannot move a program
|
|
1357
|
+
* whose literal adopted its context: the identity test demands that the
|
|
1358
|
+
* checker resolved this very keyword FROM that contextual type (a
|
|
1359
|
+
* descriptor literal's `ThisType<any>` answers `any` instead, and the
|
|
1360
|
+
* vacuous guard refuses it outright -- its receiver is the defineProperty
|
|
1361
|
+
* TARGET, which no contextual type here spells), and the final test
|
|
1362
|
+
* returns nothing when the layout adopted the context.
|
|
1363
|
+
*/
|
|
1364
|
+
const objectLiteralMemberReceiverAt = (node) => {
|
|
1365
|
+
if (node.kind !== ts.SyntaxKind.ThisKeyword)
|
|
1366
|
+
return null;
|
|
1367
|
+
// An arrow closes over the enclosing frame's `this` rather than binding
|
|
1368
|
+
// one, so it is walked THROUGH -- the same scoping `bodyReadsThis` and
|
|
1369
|
+
// `implicitReceiverOf` use to decide whose receiver this keyword reads.
|
|
1370
|
+
const frame = ts.findAncestor(node, (candidate) => ts.isFunctionLike(candidate) && !ts.isArrowFunction(candidate));
|
|
1371
|
+
const literal = frame && ts.isFunctionLike(frame) ? objectLiteralOwningMember(frame) : null;
|
|
1372
|
+
if (!literal)
|
|
1373
|
+
return null;
|
|
1374
|
+
const contextual = checker.getContextualType(literal);
|
|
1375
|
+
if (!contextual || (contextual.flags & (ts.TypeFlags.Any | ts.TypeFlags.Unknown)) !== 0)
|
|
1376
|
+
return null;
|
|
1377
|
+
if (checker.getTypeAtLocation(node) !== contextual)
|
|
1378
|
+
return null;
|
|
1379
|
+
const layout = layoutTypeAt(literal);
|
|
1380
|
+
return layout === contextual ? null : layout;
|
|
1381
|
+
};
|
|
1382
|
+
/**
|
|
1383
|
+
* The object literal this function-like is a member of -- both spellings
|
|
1384
|
+
* `getContainingObjectLiteral` accepts, since `o.m()` binds the literal as
|
|
1385
|
+
* the receiver either way and `structural-receiver.ts` already gives both
|
|
1386
|
+
* the same implicit receiver.
|
|
1387
|
+
*/
|
|
1388
|
+
const objectLiteralOwningMember = (frame) => {
|
|
1389
|
+
const parent = frame.parent;
|
|
1390
|
+
if (ts.isMethodDeclaration(frame) || ts.isGetAccessorDeclaration(frame) || ts.isSetAccessorDeclaration(frame))
|
|
1391
|
+
return ts.isObjectLiteralExpression(parent) ? parent : null;
|
|
1392
|
+
if (ts.isFunctionExpression(frame) && ts.isPropertyAssignment(parent) && ts.isObjectLiteralExpression(parent.parent))
|
|
1393
|
+
return parent.parent;
|
|
1394
|
+
return null;
|
|
1395
|
+
};
|
|
1396
|
+
/** Whether two types have any value in common at all, tested the only way a type system can: assignability, in BOTH directions, so a subset overlaps its superset. */
|
|
1397
|
+
const overlaps = (left, right) => checker.isTypeAssignableTo(left, right) || checker.isTypeAssignableTo(right, left);
|
|
1398
|
+
/**
|
|
1399
|
+
* A UNION NARROWED BY A NARROWING OF ONE OF ITS MEMBERS.
|
|
1400
|
+
*
|
|
1401
|
+
* `arg: ResponseInit | Response`, and hono's `#newResponse` writes
|
|
1402
|
+
*
|
|
1403
|
+
* const argHeaders = arg.headers instanceof Headers ? arg.headers : new Headers( arg.headers )
|
|
1404
|
+
*
|
|
1405
|
+
* In the else arm the checker types `arg.headers` as everything BUT
|
|
1406
|
+
* `Headers` -- and leaves `arg` itself alone, because TypeScript narrows an
|
|
1407
|
+
* object from a discriminant LITERAL check and not from an `instanceof` on
|
|
1408
|
+
* one of its members. So the receiver's carrier still had both arms while
|
|
1409
|
+
* the read published a union with no `Headers` in it, and the emitter's
|
|
1410
|
+
* arm dispatch reached the `Response` arm, whose `headers` field IS a
|
|
1411
|
+
* `Headers`, with nothing sound to convert it into. Failing closed there is
|
|
1412
|
+
* right (`emit-union-properties.ts` says so at both of its refusals) --
|
|
1413
|
+
* the defect is that the receiver lost a narrowing the program made.
|
|
1414
|
+
*
|
|
1415
|
+
* The inference is the language's own contrapositive, and does not need
|
|
1416
|
+
* TypeScript to make it: if the value read out of `p` cannot be anything
|
|
1417
|
+
* this arm's `p` can hold, this arm is not what the receiver holds here.
|
|
1418
|
+
* Both directions of assignability have to fail before an arm is dropped,
|
|
1419
|
+
* so an arm whose member is a SUPERSET of the narrowing (or a subset of it)
|
|
1420
|
+
* stays -- only a genuinely disjoint one goes. An arm that lacks the
|
|
1421
|
+
* property entirely also stays: the language answers that read `undefined`
|
|
1422
|
+
* (10.1.8 step 3) and the emitter already renders exactly that.
|
|
1423
|
+
*
|
|
1424
|
+
* `any`/`unknown` on either side is not a narrowing and stops this: those
|
|
1425
|
+
* are the absences the censuses exist to fill, and every arm "overlaps"
|
|
1426
|
+
* them.
|
|
1427
|
+
*/
|
|
1428
|
+
const armsLiveUnderMemberNarrowing = (node, answer) => {
|
|
1429
|
+
const read = node.parent;
|
|
1430
|
+
if (!read || !ts.isPropertyAccessExpression(read) || read.expression !== node)
|
|
1431
|
+
return null;
|
|
1432
|
+
if (!answer.isUnion())
|
|
1433
|
+
return null;
|
|
1434
|
+
const vacuous = ts.TypeFlags.Any | ts.TypeFlags.Unknown;
|
|
1435
|
+
const narrowed = checker.getTypeAtLocation(read);
|
|
1436
|
+
if ((narrowed.flags & vacuous) !== 0)
|
|
1437
|
+
return null;
|
|
1438
|
+
const live = answer.types.filter((arm) => {
|
|
1439
|
+
const property = checker.getPropertyOfType(arm, read.name.text);
|
|
1440
|
+
if (!property)
|
|
1441
|
+
return true;
|
|
1442
|
+
const held = checker.getTypeOfSymbolAtLocation(property, read);
|
|
1443
|
+
if ((held.flags & vacuous) !== 0)
|
|
1444
|
+
return true;
|
|
1445
|
+
return overlaps(held, narrowed);
|
|
1446
|
+
});
|
|
1447
|
+
if (live.length === answer.types.length || live.length === 0)
|
|
1448
|
+
return null;
|
|
1449
|
+
const sole = live.length === 1 ? live[0] : undefined;
|
|
1450
|
+
if (sole)
|
|
1451
|
+
return sole;
|
|
1452
|
+
const constructing = checker;
|
|
1453
|
+
return typeof constructing.getUnionType === 'function' ? constructing.getUnionType(live) : null;
|
|
1454
|
+
};
|
|
1455
|
+
// A resolver closes over one checker and one census snapshot. Reusing an
|
|
1456
|
+
// answer here cannot cross binding-fixpoint rounds or checker lifetimes.
|
|
1457
|
+
const answers = new WeakMap();
|
|
1458
|
+
const layoutTypeAt = (node) => {
|
|
1459
|
+
const known = answers.get(node);
|
|
1460
|
+
if (known)
|
|
1461
|
+
return known;
|
|
1462
|
+
const answer = layoutTypeOf(node);
|
|
1463
|
+
const selected = armsLiveUnderMemberNarrowing(node, answer) ?? answer;
|
|
1464
|
+
answers.set(node, selected);
|
|
1465
|
+
return selected;
|
|
1466
|
+
};
|
|
1467
|
+
return layoutTypeAt;
|
|
1468
|
+
};
|