@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,1527 @@
|
|
|
1
|
+
import { dirname, resolve } from 'node:path';
|
|
2
|
+
import ts from 'typescript';
|
|
3
|
+
import { createCommonJsWrapperIdentity } from '../commonjs-wrapper.js';
|
|
4
|
+
import { isAssignmentOperatorKind } from './producers/shared.js';
|
|
5
|
+
const unreachable = 0;
|
|
6
|
+
const originalDefinition = 1;
|
|
7
|
+
const unknownDefinition = 2;
|
|
8
|
+
const writesRequire = 1;
|
|
9
|
+
const writesExportsBinding = 2;
|
|
10
|
+
const writesModuleBinding = 4;
|
|
11
|
+
const writesModuleExports = 8;
|
|
12
|
+
const join = (...states) => states.reduce((result, state) => result | state, unreachable);
|
|
13
|
+
const completion = (normal) => ({
|
|
14
|
+
normal,
|
|
15
|
+
returned: unreachable,
|
|
16
|
+
thrown: unreachable,
|
|
17
|
+
broken: unreachable,
|
|
18
|
+
continued: unreachable
|
|
19
|
+
});
|
|
20
|
+
const mergeCompletion = (...flows) => ({
|
|
21
|
+
normal: join(...flows.map((flow) => flow.normal)),
|
|
22
|
+
returned: join(...flows.map((flow) => flow.returned)),
|
|
23
|
+
thrown: join(...flows.map((flow) => flow.thrown)),
|
|
24
|
+
broken: join(...flows.map((flow) => flow.broken)),
|
|
25
|
+
continued: join(...flows.map((flow) => flow.continued))
|
|
26
|
+
});
|
|
27
|
+
const withNormal = (flow, normal) => ({ ...flow, normal });
|
|
28
|
+
const allExits = (flow) => join(flow.normal, flow.returned, flow.thrown, flow.broken, flow.continued);
|
|
29
|
+
const resolvedSymbol = (checker, symbol) => (symbol.flags & ts.SymbolFlags.Alias) !== 0 ? checker.getAliasedSymbol(symbol) : symbol;
|
|
30
|
+
const resolvedSymbolAt = (checker, node) => {
|
|
31
|
+
const local = checker.getSymbolAtLocation(node);
|
|
32
|
+
return local ? resolvedSymbol(checker, local) : null;
|
|
33
|
+
};
|
|
34
|
+
const unwrapExpression = (expression) => {
|
|
35
|
+
let current = expression;
|
|
36
|
+
while (ts.isParenthesizedExpression(current) ||
|
|
37
|
+
ts.isAsExpression(current) ||
|
|
38
|
+
ts.isTypeAssertionExpression(current) ||
|
|
39
|
+
ts.isNonNullExpression(current) ||
|
|
40
|
+
ts.isSatisfiesExpression(current) ||
|
|
41
|
+
ts.isPartiallyEmittedExpression(current)) {
|
|
42
|
+
current = current.expression;
|
|
43
|
+
}
|
|
44
|
+
return current;
|
|
45
|
+
};
|
|
46
|
+
const constantTruthiness = (expression) => {
|
|
47
|
+
const node = unwrapExpression(expression);
|
|
48
|
+
if (node.kind === ts.SyntaxKind.TrueKeyword)
|
|
49
|
+
return true;
|
|
50
|
+
if (node.kind === ts.SyntaxKind.FalseKeyword || node.kind === ts.SyntaxKind.NullKeyword)
|
|
51
|
+
return false;
|
|
52
|
+
if (ts.isStringLiteralLike(node) || ts.isNoSubstitutionTemplateLiteral(node))
|
|
53
|
+
return node.text.length > 0;
|
|
54
|
+
if (ts.isNumericLiteral(node))
|
|
55
|
+
return Number(node.text) !== 0;
|
|
56
|
+
if (ts.isBigIntLiteral(node))
|
|
57
|
+
return node.text !== '0n';
|
|
58
|
+
if (ts.isPrefixUnaryExpression(node) && node.operator === ts.SyntaxKind.ExclamationToken) {
|
|
59
|
+
const value = constantTruthiness(node.operand);
|
|
60
|
+
return value === null ? null : !value;
|
|
61
|
+
}
|
|
62
|
+
if (ts.isVoidExpression(node))
|
|
63
|
+
return false;
|
|
64
|
+
return null;
|
|
65
|
+
};
|
|
66
|
+
const isFunctionNode = (node) => {
|
|
67
|
+
if (!ts.isFunctionLike(node))
|
|
68
|
+
return false;
|
|
69
|
+
const bodyBearing = node;
|
|
70
|
+
return bodyBearing.body !== undefined;
|
|
71
|
+
};
|
|
72
|
+
const staticPropertyName = (node) => {
|
|
73
|
+
if (ts.isIdentifier(node) || ts.isStringLiteralLike(node) || ts.isNumericLiteral(node))
|
|
74
|
+
return node.text;
|
|
75
|
+
return null;
|
|
76
|
+
};
|
|
77
|
+
const staticElementPropertyName = (node) => ts.isStringLiteralLike(node) || ts.isNumericLiteral(node) ? node.text : null;
|
|
78
|
+
const standardFunctionInterfaces = new Set(['Function', 'CallableFunction', 'NewableFunction']);
|
|
79
|
+
const standardFunctionDeclarationFile = resolve(dirname(ts.getDefaultLibFilePath({ target: ts.ScriptTarget.ES5 })), 'lib.es5.d.ts');
|
|
80
|
+
const functionPrototypeMethodName = (node, computed = false) => {
|
|
81
|
+
const name = computed && ts.isExpression(node) ? staticElementPropertyName(node) : staticPropertyName(node);
|
|
82
|
+
return name === 'call' || name === 'apply' || name === 'bind' ? name : null;
|
|
83
|
+
};
|
|
84
|
+
const createFunctionResolutionTraversal = () => ({
|
|
85
|
+
functionSymbols: [new Set(), new Set()],
|
|
86
|
+
functionNodes: [new Set(), new Set()],
|
|
87
|
+
prototypeSymbols: { call: new Set(), apply: new Set(), bind: new Set() },
|
|
88
|
+
prototypeNodes: { call: new Set(), apply: new Set(), bind: new Set() }
|
|
89
|
+
});
|
|
90
|
+
function callableMethodTaintOf(receiver, method, context, traversal = createFunctionResolutionTraversal()) {
|
|
91
|
+
const globallyTainted = context.callableMethodTaints.global.has(method);
|
|
92
|
+
const functions = new Set();
|
|
93
|
+
let tainted = globallyTainted;
|
|
94
|
+
let unknown = globallyTainted;
|
|
95
|
+
const receiverResolution = functionValuesOf(receiver, context, false, traversal);
|
|
96
|
+
if (receiverResolution.unknown) {
|
|
97
|
+
tainted = true;
|
|
98
|
+
unknown = true;
|
|
99
|
+
}
|
|
100
|
+
for (const receiverFunction of receiverResolution.functions) {
|
|
101
|
+
const own = context.callableMethodTaints.own.get(receiverFunction)?.get(method);
|
|
102
|
+
if (own) {
|
|
103
|
+
tainted = true;
|
|
104
|
+
for (const fn of own)
|
|
105
|
+
functions.add(fn);
|
|
106
|
+
}
|
|
107
|
+
if (context.callableMethodTaints.ownUnknown.get(receiverFunction)?.has(method)) {
|
|
108
|
+
tainted = true;
|
|
109
|
+
unknown = true;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
return { tainted, unknown, functions };
|
|
113
|
+
}
|
|
114
|
+
const declaredStandardFunctionPrototypeMember = (receiver, method, context) => {
|
|
115
|
+
const receiverType = context.checker.getTypeAtLocation(receiver);
|
|
116
|
+
if (receiverType.getCallSignatures().length === 0)
|
|
117
|
+
return false;
|
|
118
|
+
const member = context.checker.getPropertyOfType(receiverType, method);
|
|
119
|
+
const declarations = member?.declarations ?? [];
|
|
120
|
+
if (declarations.length === 0)
|
|
121
|
+
return false;
|
|
122
|
+
if (context.checker.getTypeOfSymbolAtLocation(member, receiver).getCallSignatures().length === 0)
|
|
123
|
+
return false;
|
|
124
|
+
return declarations.every((declaration) => ts.isMethodSignature(declaration) &&
|
|
125
|
+
ts.isInterfaceDeclaration(declaration.parent) &&
|
|
126
|
+
standardFunctionInterfaces.has(declaration.parent.name.text) &&
|
|
127
|
+
declaration.getSourceFile().hasNoDefaultLib &&
|
|
128
|
+
resolve(declaration.getSourceFile().fileName) === standardFunctionDeclarationFile);
|
|
129
|
+
};
|
|
130
|
+
const standardFunctionPrototypeMember = (receiver, method, context, traversal) => !callableMethodTaintOf(receiver, method, context, traversal).tainted && declaredStandardFunctionPrototypeMember(receiver, method, context);
|
|
131
|
+
const directFunctionPrototypeReceiver = (expression, method, context, traversal) => {
|
|
132
|
+
const node = unwrapExpression(expression);
|
|
133
|
+
if (ts.isPropertyAccessExpression(node) && node.name.text === method) {
|
|
134
|
+
return standardFunctionPrototypeMember(node.expression, method, context, traversal) ? node.expression : null;
|
|
135
|
+
}
|
|
136
|
+
if (ts.isElementAccessExpression(node) && staticElementPropertyName(node.argumentExpression) === method) {
|
|
137
|
+
return standardFunctionPrototypeMember(node.expression, method, context, traversal) ? node.expression : null;
|
|
138
|
+
}
|
|
139
|
+
return null;
|
|
140
|
+
};
|
|
141
|
+
function functionValuesOfSymbol(symbol, context, deep, traversal) {
|
|
142
|
+
const resolved = resolvedSymbol(context.checker, symbol);
|
|
143
|
+
const activeSymbols = traversal.functionSymbols[deep ? 1 : 0];
|
|
144
|
+
if (activeSymbols.has(resolved))
|
|
145
|
+
return { functions: new Set(), unknown: true };
|
|
146
|
+
activeSymbols.add(resolved);
|
|
147
|
+
try {
|
|
148
|
+
const container = context.containerFunctions.get(resolved);
|
|
149
|
+
const found = new Set(container?.functions ?? []);
|
|
150
|
+
let unknown = container?.unknown ?? false;
|
|
151
|
+
const add = (resolution) => {
|
|
152
|
+
for (const fn of resolution.functions)
|
|
153
|
+
found.add(fn);
|
|
154
|
+
unknown ||= resolution.unknown;
|
|
155
|
+
};
|
|
156
|
+
const declaration = resolved.valueDeclaration ?? resolved.declarations?.[0];
|
|
157
|
+
if (declaration) {
|
|
158
|
+
if (isFunctionNode(declaration))
|
|
159
|
+
found.add(declaration);
|
|
160
|
+
else if (ts.isVariableDeclaration(declaration) && declaration.initializer) {
|
|
161
|
+
add(functionValuesOf(declaration.initializer, context, deep, traversal));
|
|
162
|
+
}
|
|
163
|
+
else if (ts.isPropertyAssignment(declaration)) {
|
|
164
|
+
add(functionValuesOf(declaration.initializer, context, deep, traversal));
|
|
165
|
+
}
|
|
166
|
+
else if (ts.isShorthandPropertyAssignment(declaration)) {
|
|
167
|
+
const value = context.checker.getShorthandAssignmentValueSymbol(declaration);
|
|
168
|
+
if (value)
|
|
169
|
+
add(functionValuesOfSymbol(value, context, deep, traversal));
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
for (const value of context.functionAssignments.get(resolved) ?? [])
|
|
173
|
+
add(functionValuesOf(value, context, deep, traversal));
|
|
174
|
+
for (const value of context.destructuredFunctionAssignments.get(resolved) ?? []) {
|
|
175
|
+
add(functionValuesOf(value, context, true, traversal));
|
|
176
|
+
}
|
|
177
|
+
return { functions: found, unknown };
|
|
178
|
+
}
|
|
179
|
+
finally {
|
|
180
|
+
activeSymbols.delete(resolved);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
/** Whether a symbol's own declaration carries the value `functionValuesOfSymbol` resolves through. */
|
|
184
|
+
const declaresValue = (symbol) => {
|
|
185
|
+
const declaration = symbol.valueDeclaration ?? symbol.declarations?.[0];
|
|
186
|
+
if (!declaration)
|
|
187
|
+
return false;
|
|
188
|
+
if (isFunctionNode(declaration) || ts.isPropertyAssignment(declaration) || ts.isShorthandPropertyAssignment(declaration))
|
|
189
|
+
return true;
|
|
190
|
+
return ts.isVariableDeclaration(declaration) && declaration.initializer !== undefined;
|
|
191
|
+
};
|
|
192
|
+
function shorthandFunctionValuesOf(node, context, deep, traversal) {
|
|
193
|
+
const value = context.checker.getShorthandAssignmentValueSymbol(node);
|
|
194
|
+
return value ? functionValuesOfSymbol(value, context, deep, traversal) : { functions: new Set(), unknown: true };
|
|
195
|
+
}
|
|
196
|
+
function functionValuesOf(expression, context, deep = false, traversal = createFunctionResolutionTraversal()) {
|
|
197
|
+
const node = unwrapExpression(expression);
|
|
198
|
+
const activeNodes = traversal.functionNodes[deep ? 1 : 0];
|
|
199
|
+
if (activeNodes.has(node))
|
|
200
|
+
return { functions: new Set(), unknown: true };
|
|
201
|
+
activeNodes.add(node);
|
|
202
|
+
try {
|
|
203
|
+
if (ts.isFunctionExpression(node) || ts.isArrowFunction(node))
|
|
204
|
+
return { functions: new Set([node]), unknown: false };
|
|
205
|
+
if (ts.isIdentifier(node)) {
|
|
206
|
+
const symbol = resolvedSymbolAt(context.checker, node);
|
|
207
|
+
return symbol ? functionValuesOfSymbol(symbol, context, deep, traversal) : { functions: new Set(), unknown: true };
|
|
208
|
+
}
|
|
209
|
+
if (ts.isPropertyAccessExpression(node) || ts.isElementAccessExpression(node)) {
|
|
210
|
+
const name = ts.isPropertyAccessExpression(node) ? node.name : node.argumentExpression;
|
|
211
|
+
const method = functionPrototypeMethodName(name, ts.isElementAccessExpression(node));
|
|
212
|
+
if (method) {
|
|
213
|
+
const taint = callableMethodTaintOf(node.expression, method, context, traversal);
|
|
214
|
+
if (taint.tainted)
|
|
215
|
+
return { functions: taint.functions, unknown: taint.unknown };
|
|
216
|
+
}
|
|
217
|
+
const symbol = resolvedSymbolAt(context.checker, name);
|
|
218
|
+
if (symbol) {
|
|
219
|
+
const resolution = functionValuesOfSymbol(symbol, context, deep, traversal);
|
|
220
|
+
// A member that DECLARES a value -- a property assignment, an
|
|
221
|
+
// initialized variable, a function -- has been resolved through that
|
|
222
|
+
// value and every assignment recorded against it, so an empty answer
|
|
223
|
+
// is a proof, not a gap. The receiver walk below is the conservative
|
|
224
|
+
// over-approximation for a member the checker types without a value
|
|
225
|
+
// (an interface signature, an unresolvable name), where the object
|
|
226
|
+
// literal's own matching property is the only evidence left. Taking
|
|
227
|
+
// it for a valued member turned every `Diagnostics.X` argument in
|
|
228
|
+
// tsc into a deep walk of the whole 2,000-entry `Diagnostics` literal
|
|
229
|
+
// -- `getSymbolAtLocation` on every `diag(...)` call, per use site,
|
|
230
|
+
// per analysis pass: the frontend never finished (profiled at 98% in
|
|
231
|
+
// this resolver, 45 minutes in).
|
|
232
|
+
if (resolution.functions.size > 0 || resolution.unknown || declaresValue(symbol))
|
|
233
|
+
return resolution;
|
|
234
|
+
}
|
|
235
|
+
const receiver = unwrapExpression(node.expression);
|
|
236
|
+
if (ts.isObjectLiteralExpression(receiver)) {
|
|
237
|
+
const key = ts.isElementAccessExpression(node) ? staticElementPropertyName(name) : staticPropertyName(name);
|
|
238
|
+
if (key !== null) {
|
|
239
|
+
for (const property of receiver.properties) {
|
|
240
|
+
if (ts.isSpreadAssignment(property) || staticPropertyName(property.name) !== key)
|
|
241
|
+
continue;
|
|
242
|
+
if (isFunctionNode(property))
|
|
243
|
+
return { functions: new Set([property]), unknown: false };
|
|
244
|
+
if (ts.isPropertyAssignment(property))
|
|
245
|
+
return functionValuesOf(property.initializer, context, deep, traversal);
|
|
246
|
+
if (ts.isShorthandPropertyAssignment(property))
|
|
247
|
+
return shorthandFunctionValuesOf(property, context, deep, traversal);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
return functionValuesOf(receiver, context, deep, traversal);
|
|
252
|
+
}
|
|
253
|
+
if (ts.isConditionalExpression(node)) {
|
|
254
|
+
const whenTrue = functionValuesOf(node.whenTrue, context, deep, traversal);
|
|
255
|
+
const whenFalse = functionValuesOf(node.whenFalse, context, deep, traversal);
|
|
256
|
+
return {
|
|
257
|
+
functions: new Set([...whenTrue.functions, ...whenFalse.functions]),
|
|
258
|
+
unknown: whenTrue.unknown || whenFalse.unknown
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
if (ts.isBinaryExpression(node) && node.operatorToken.kind === ts.SyntaxKind.CommaToken) {
|
|
262
|
+
return functionValuesOf(node.right, context, deep, traversal);
|
|
263
|
+
}
|
|
264
|
+
if (ts.isCallExpression(node)) {
|
|
265
|
+
const callee = unwrapExpression(node.expression);
|
|
266
|
+
const bindSource = ts.isCallExpression(callee) ? callee.expression : node.expression;
|
|
267
|
+
const boundTargets = functionPrototypeReceiversOf(bindSource, 'bind', context, traversal);
|
|
268
|
+
if (boundTargets.expressions.size > 0) {
|
|
269
|
+
const found = new Set();
|
|
270
|
+
let unknown = boundTargets.unknown;
|
|
271
|
+
for (const boundTarget of boundTargets.expressions) {
|
|
272
|
+
const resolution = functionValuesOf(boundTarget, context, deep, traversal);
|
|
273
|
+
for (const fn of resolution.functions)
|
|
274
|
+
found.add(fn);
|
|
275
|
+
unknown ||= resolution.unknown;
|
|
276
|
+
}
|
|
277
|
+
return { functions: found, unknown };
|
|
278
|
+
}
|
|
279
|
+
if (boundTargets.unknown)
|
|
280
|
+
return { functions: new Set(), unknown: true };
|
|
281
|
+
const invocation = invocationFunctionsOf(node.expression, context, traversal);
|
|
282
|
+
const returned = new Set();
|
|
283
|
+
let unknown = invocation.unknown;
|
|
284
|
+
for (const fn of invocation.functions) {
|
|
285
|
+
const summary = context.summaries.get(fn);
|
|
286
|
+
if (!summary)
|
|
287
|
+
unknown = true;
|
|
288
|
+
else {
|
|
289
|
+
for (const value of summary.returns)
|
|
290
|
+
returned.add(value);
|
|
291
|
+
unknown ||= summary.returnsUnknown;
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
return { functions: returned, unknown };
|
|
295
|
+
}
|
|
296
|
+
if (deep && ts.isObjectLiteralExpression(node)) {
|
|
297
|
+
const found = new Set();
|
|
298
|
+
let unknown = false;
|
|
299
|
+
for (const property of node.properties) {
|
|
300
|
+
if (isFunctionNode(property))
|
|
301
|
+
found.add(property);
|
|
302
|
+
else {
|
|
303
|
+
const resolution = ts.isPropertyAssignment(property)
|
|
304
|
+
? functionValuesOf(property.initializer, context, true, traversal)
|
|
305
|
+
: ts.isShorthandPropertyAssignment(property)
|
|
306
|
+
? shorthandFunctionValuesOf(property, context, true, traversal)
|
|
307
|
+
: ts.isSpreadAssignment(property)
|
|
308
|
+
? functionValuesOf(property.expression, context, true, traversal)
|
|
309
|
+
: { functions: new Set(), unknown: true };
|
|
310
|
+
for (const fn of resolution.functions)
|
|
311
|
+
found.add(fn);
|
|
312
|
+
unknown ||= resolution.unknown;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
return { functions: found, unknown };
|
|
316
|
+
}
|
|
317
|
+
if (deep && ts.isArrayLiteralExpression(node)) {
|
|
318
|
+
const found = new Set();
|
|
319
|
+
let unknown = false;
|
|
320
|
+
for (const element of node.elements) {
|
|
321
|
+
if (ts.isOmittedExpression(element))
|
|
322
|
+
continue;
|
|
323
|
+
const value = ts.isSpreadElement(element) ? element.expression : element;
|
|
324
|
+
const resolution = functionValuesOf(value, context, true, traversal);
|
|
325
|
+
for (const fn of resolution.functions)
|
|
326
|
+
found.add(fn);
|
|
327
|
+
unknown ||= resolution.unknown;
|
|
328
|
+
}
|
|
329
|
+
return { functions: found, unknown };
|
|
330
|
+
}
|
|
331
|
+
return { functions: new Set(), unknown: false };
|
|
332
|
+
}
|
|
333
|
+
finally {
|
|
334
|
+
activeNodes.delete(node);
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
/**
|
|
338
|
+
* Function.prototype's invocation methods preserve their receiver identity
|
|
339
|
+
* even when a program stores the method in a mutable alias. Follow only
|
|
340
|
+
* checker-resolved declarations and assignments observed in this source; an
|
|
341
|
+
* unproven property never becomes a callable origin.
|
|
342
|
+
*/
|
|
343
|
+
function functionPrototypeReceiversOf(expression, method, context, traversal = createFunctionResolutionTraversal()) {
|
|
344
|
+
const node = unwrapExpression(expression);
|
|
345
|
+
const activeNodes = traversal.prototypeNodes[method];
|
|
346
|
+
if (activeNodes.has(node))
|
|
347
|
+
return { expressions: new Set(), unknown: true };
|
|
348
|
+
activeNodes.add(node);
|
|
349
|
+
try {
|
|
350
|
+
// The standard-member authentication asks which functions the receiver
|
|
351
|
+
// can hold, and that walk may arrive back at this exact `.call`/`.apply`/
|
|
352
|
+
// `.bind` expression through a variable initializer or assignment. Keep
|
|
353
|
+
// the one active traversal: starting a fresh one here loses both node and
|
|
354
|
+
// symbol recursion guards and turns a conservative unknown into an
|
|
355
|
+
// unbounded mutual recursion.
|
|
356
|
+
const direct = directFunctionPrototypeReceiver(node, method, context, traversal);
|
|
357
|
+
if (direct)
|
|
358
|
+
return { expressions: new Set([direct]), unknown: false };
|
|
359
|
+
if (ts.isIdentifier(node)) {
|
|
360
|
+
const symbol = resolvedSymbolAt(context.checker, node);
|
|
361
|
+
if (!symbol)
|
|
362
|
+
return { expressions: new Set(), unknown: true };
|
|
363
|
+
const resolved = resolvedSymbol(context.checker, symbol);
|
|
364
|
+
const activeSymbols = traversal.prototypeSymbols[method];
|
|
365
|
+
if (activeSymbols.has(resolved))
|
|
366
|
+
return { expressions: new Set(), unknown: true };
|
|
367
|
+
activeSymbols.add(resolved);
|
|
368
|
+
try {
|
|
369
|
+
const declaration = resolved.valueDeclaration ?? resolved.declarations?.[0];
|
|
370
|
+
const values = [];
|
|
371
|
+
if (declaration && ts.isVariableDeclaration(declaration) && declaration.initializer)
|
|
372
|
+
values.push(declaration.initializer);
|
|
373
|
+
for (const assigned of context.functionAssignments.get(resolved) ?? [])
|
|
374
|
+
values.push(assigned);
|
|
375
|
+
const expressions = new Set();
|
|
376
|
+
let unknown = false;
|
|
377
|
+
for (const value of values) {
|
|
378
|
+
const resolution = functionPrototypeReceiversOf(value, method, context, traversal);
|
|
379
|
+
for (const receiver of resolution.expressions)
|
|
380
|
+
expressions.add(receiver);
|
|
381
|
+
unknown ||= resolution.unknown;
|
|
382
|
+
}
|
|
383
|
+
return { expressions, unknown };
|
|
384
|
+
}
|
|
385
|
+
finally {
|
|
386
|
+
activeSymbols.delete(resolved);
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
if (ts.isConditionalExpression(node)) {
|
|
390
|
+
const whenTrue = functionPrototypeReceiversOf(node.whenTrue, method, context, traversal);
|
|
391
|
+
const whenFalse = functionPrototypeReceiversOf(node.whenFalse, method, context, traversal);
|
|
392
|
+
return {
|
|
393
|
+
expressions: new Set([...whenTrue.expressions, ...whenFalse.expressions]),
|
|
394
|
+
unknown: whenTrue.unknown || whenFalse.unknown
|
|
395
|
+
};
|
|
396
|
+
}
|
|
397
|
+
if (ts.isBinaryExpression(node) && node.operatorToken.kind === ts.SyntaxKind.CommaToken) {
|
|
398
|
+
return functionPrototypeReceiversOf(node.right, method, context, traversal);
|
|
399
|
+
}
|
|
400
|
+
return { expressions: new Set(), unknown: false };
|
|
401
|
+
}
|
|
402
|
+
finally {
|
|
403
|
+
activeNodes.delete(node);
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
function unknownTaintedMethodOrigin(expression, context, activeSymbols = new Set(), activeNodes = new Set()) {
|
|
407
|
+
const node = unwrapExpression(expression);
|
|
408
|
+
if (activeNodes.has(node))
|
|
409
|
+
return true;
|
|
410
|
+
activeNodes.add(node);
|
|
411
|
+
try {
|
|
412
|
+
if (ts.isPropertyAccessExpression(node) || ts.isElementAccessExpression(node)) {
|
|
413
|
+
const property = ts.isPropertyAccessExpression(node) ? node.name : node.argumentExpression;
|
|
414
|
+
const method = functionPrototypeMethodName(property, ts.isElementAccessExpression(node));
|
|
415
|
+
return method ? callableMethodTaintOf(node.expression, method, context).unknown : false;
|
|
416
|
+
}
|
|
417
|
+
if (ts.isIdentifier(node)) {
|
|
418
|
+
const symbol = resolvedSymbolAt(context.checker, node);
|
|
419
|
+
if (!symbol)
|
|
420
|
+
return true;
|
|
421
|
+
const resolved = resolvedSymbol(context.checker, symbol);
|
|
422
|
+
if (activeSymbols.has(resolved))
|
|
423
|
+
return true;
|
|
424
|
+
activeSymbols.add(resolved);
|
|
425
|
+
try {
|
|
426
|
+
for (const method of context.functionPrototypeMethodAssignments.get(resolved) ?? []) {
|
|
427
|
+
if (context.callableMethodTaints.global.has(method))
|
|
428
|
+
return true;
|
|
429
|
+
}
|
|
430
|
+
const declaration = resolved.valueDeclaration ?? resolved.declarations?.[0];
|
|
431
|
+
const expressions = [];
|
|
432
|
+
if (declaration && ts.isVariableDeclaration(declaration) && declaration.initializer)
|
|
433
|
+
expressions.push(declaration.initializer);
|
|
434
|
+
for (const assigned of context.functionAssignments.get(resolved) ?? [])
|
|
435
|
+
expressions.push(assigned);
|
|
436
|
+
for (const assigned of context.destructuredFunctionAssignments.get(resolved) ?? [])
|
|
437
|
+
expressions.push(assigned);
|
|
438
|
+
return expressions.some((value) => unknownTaintedMethodOrigin(value, context, activeSymbols, activeNodes));
|
|
439
|
+
}
|
|
440
|
+
finally {
|
|
441
|
+
activeSymbols.delete(resolved);
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
if (ts.isConditionalExpression(node)) {
|
|
445
|
+
return (unknownTaintedMethodOrigin(node.whenTrue, context, activeSymbols, activeNodes) ||
|
|
446
|
+
unknownTaintedMethodOrigin(node.whenFalse, context, activeSymbols, activeNodes));
|
|
447
|
+
}
|
|
448
|
+
if (ts.isBinaryExpression(node) && node.operatorToken.kind === ts.SyntaxKind.CommaToken) {
|
|
449
|
+
return unknownTaintedMethodOrigin(node.right, context, activeSymbols, activeNodes);
|
|
450
|
+
}
|
|
451
|
+
if (ts.isCallExpression(node))
|
|
452
|
+
return unknownTaintedMethodOrigin(node.expression, context, activeSymbols, activeNodes);
|
|
453
|
+
return false;
|
|
454
|
+
}
|
|
455
|
+
finally {
|
|
456
|
+
activeNodes.delete(node);
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
const invocationFunctionsOf = (expression, context, traversal = createFunctionResolutionTraversal()) => {
|
|
460
|
+
const call = functionPrototypeReceiversOf(expression, 'call', context, traversal);
|
|
461
|
+
const apply = functionPrototypeReceiversOf(expression, 'apply', context, traversal);
|
|
462
|
+
const receivers = new Set([...call.expressions, ...apply.expressions]);
|
|
463
|
+
if (receivers.size > 0) {
|
|
464
|
+
const found = new Set();
|
|
465
|
+
let unknown = call.unknown || apply.unknown;
|
|
466
|
+
for (const receiver of receivers) {
|
|
467
|
+
const resolution = functionValuesOf(receiver, context, false, traversal);
|
|
468
|
+
for (const fn of resolution.functions)
|
|
469
|
+
found.add(fn);
|
|
470
|
+
unknown ||= resolution.unknown;
|
|
471
|
+
}
|
|
472
|
+
return { functions: found, unknown };
|
|
473
|
+
}
|
|
474
|
+
if (call.unknown || apply.unknown)
|
|
475
|
+
return { functions: new Set(), unknown: true };
|
|
476
|
+
// Calling `bind` only creates a callable. Its target executes when that
|
|
477
|
+
// result is invoked, which functionValuesOf models above.
|
|
478
|
+
const bind = functionPrototypeReceiversOf(expression, 'bind', context, traversal);
|
|
479
|
+
if (bind.expressions.size > 0)
|
|
480
|
+
return { functions: new Set(), unknown: bind.unknown };
|
|
481
|
+
if (bind.unknown)
|
|
482
|
+
return { functions: new Set(), unknown: true };
|
|
483
|
+
return functionValuesOf(expression, context, false, traversal);
|
|
484
|
+
};
|
|
485
|
+
const recordRead = (node, state, context) => {
|
|
486
|
+
if (state === unreachable || context.reads === null)
|
|
487
|
+
return;
|
|
488
|
+
context.reads.set(node, join(context.reads.get(node) ?? unreachable, state));
|
|
489
|
+
};
|
|
490
|
+
const classify = (node, context) => context.identity.classify(node);
|
|
491
|
+
const wrapperWrite = (node, state, context) => {
|
|
492
|
+
const identity = classify(node, context);
|
|
493
|
+
if (identity.kind !== 'wrapper' || state === unreachable)
|
|
494
|
+
return state;
|
|
495
|
+
if (identity.global === 'require') {
|
|
496
|
+
context.observedEffects.value |= writesRequire;
|
|
497
|
+
return unknownDefinition;
|
|
498
|
+
}
|
|
499
|
+
context.observedEffects.value |= identity.global === 'exports' ? writesExportsBinding : writesModuleBinding;
|
|
500
|
+
return state;
|
|
501
|
+
};
|
|
502
|
+
const isModuleExportsAccess = (expression, context) => {
|
|
503
|
+
const node = unwrapExpression(expression);
|
|
504
|
+
if (!ts.isPropertyAccessExpression(node) && !ts.isElementAccessExpression(node))
|
|
505
|
+
return false;
|
|
506
|
+
const name = ts.isPropertyAccessExpression(node) ? node.name.text : staticElementPropertyName(node.argumentExpression);
|
|
507
|
+
if (name !== 'exports')
|
|
508
|
+
return false;
|
|
509
|
+
const receiver = unwrapExpression(node.expression);
|
|
510
|
+
if (!ts.isIdentifier(receiver))
|
|
511
|
+
return false;
|
|
512
|
+
const identity = classify(receiver, context);
|
|
513
|
+
return identity.kind === 'wrapper' && identity.global === 'module';
|
|
514
|
+
};
|
|
515
|
+
const containsModuleExportsAccess = (expression, context) => {
|
|
516
|
+
let current = unwrapExpression(expression);
|
|
517
|
+
while (ts.isPropertyAccessExpression(current) || ts.isElementAccessExpression(current)) {
|
|
518
|
+
if (isModuleExportsAccess(current, context))
|
|
519
|
+
return true;
|
|
520
|
+
current = unwrapExpression(current.expression);
|
|
521
|
+
}
|
|
522
|
+
return false;
|
|
523
|
+
};
|
|
524
|
+
const containerRootSymbol = (expression, context) => {
|
|
525
|
+
let current = unwrapExpression(expression);
|
|
526
|
+
while (ts.isPropertyAccessExpression(current) || ts.isElementAccessExpression(current))
|
|
527
|
+
current = unwrapExpression(current.expression);
|
|
528
|
+
return ts.isIdentifier(current) ? resolvedSymbolAt(context.checker, current) : null;
|
|
529
|
+
};
|
|
530
|
+
const isStandardFunctionPrototypeObject = (expression, context, seenSymbols = new Set(), seenNodes = new Set()) => {
|
|
531
|
+
const node = unwrapExpression(expression);
|
|
532
|
+
if (seenNodes.has(node))
|
|
533
|
+
return false;
|
|
534
|
+
seenNodes.add(node);
|
|
535
|
+
if (ts.isPropertyAccessExpression(node) || ts.isElementAccessExpression(node)) {
|
|
536
|
+
const property = ts.isPropertyAccessExpression(node) ? node.name : node.argumentExpression;
|
|
537
|
+
const propertyName = ts.isPropertyAccessExpression(node) ? staticPropertyName(property) : staticElementPropertyName(property);
|
|
538
|
+
if (propertyName !== 'prototype')
|
|
539
|
+
return false;
|
|
540
|
+
const constructor = unwrapExpression(node.expression);
|
|
541
|
+
if (!ts.isIdentifier(constructor) || constructor.text !== 'Function')
|
|
542
|
+
return false;
|
|
543
|
+
const symbol = resolvedSymbolAt(context.checker, constructor);
|
|
544
|
+
const declaration = symbol?.valueDeclaration;
|
|
545
|
+
return (declaration !== undefined &&
|
|
546
|
+
ts.isVariableDeclaration(declaration) &&
|
|
547
|
+
ts.isIdentifier(declaration.name) &&
|
|
548
|
+
declaration.name.text === 'Function' &&
|
|
549
|
+
resolve(declaration.getSourceFile().fileName) === standardFunctionDeclarationFile);
|
|
550
|
+
}
|
|
551
|
+
if (ts.isIdentifier(node)) {
|
|
552
|
+
const symbol = resolvedSymbolAt(context.checker, node);
|
|
553
|
+
if (!symbol || seenSymbols.has(symbol))
|
|
554
|
+
return false;
|
|
555
|
+
seenSymbols.add(symbol);
|
|
556
|
+
const declaration = symbol.valueDeclaration ?? symbol.declarations?.[0];
|
|
557
|
+
const values = [];
|
|
558
|
+
if (declaration && ts.isVariableDeclaration(declaration) && declaration.initializer)
|
|
559
|
+
values.push(declaration.initializer);
|
|
560
|
+
for (const assigned of context.functionAssignments.get(symbol) ?? [])
|
|
561
|
+
values.push(assigned);
|
|
562
|
+
for (const assigned of context.destructuredFunctionAssignments.get(symbol) ?? [])
|
|
563
|
+
values.push(assigned);
|
|
564
|
+
return values.some((value) => isStandardFunctionPrototypeObject(value, context, new Set(seenSymbols), new Set(seenNodes)));
|
|
565
|
+
}
|
|
566
|
+
if (ts.isConditionalExpression(node)) {
|
|
567
|
+
return (isStandardFunctionPrototypeObject(node.whenTrue, context, new Set(seenSymbols), new Set(seenNodes)) ||
|
|
568
|
+
isStandardFunctionPrototypeObject(node.whenFalse, context, new Set(seenSymbols), new Set(seenNodes)));
|
|
569
|
+
}
|
|
570
|
+
if (ts.isBinaryExpression(node) && node.operatorToken.kind === ts.SyntaxKind.CommaToken) {
|
|
571
|
+
return isStandardFunctionPrototypeObject(node.right, context, seenSymbols, seenNodes);
|
|
572
|
+
}
|
|
573
|
+
return false;
|
|
574
|
+
};
|
|
575
|
+
const callableMethodTarget = (expression, context) => {
|
|
576
|
+
const node = unwrapExpression(expression);
|
|
577
|
+
if (!ts.isPropertyAccessExpression(node) && !ts.isElementAccessExpression(node))
|
|
578
|
+
return null;
|
|
579
|
+
const property = ts.isPropertyAccessExpression(node) ? node.name : node.argumentExpression;
|
|
580
|
+
const method = functionPrototypeMethodName(property, ts.isElementAccessExpression(node));
|
|
581
|
+
if (!method)
|
|
582
|
+
return null;
|
|
583
|
+
return { receiver: node.expression, method, global: isStandardFunctionPrototypeObject(node.expression, context) };
|
|
584
|
+
};
|
|
585
|
+
const recordCallableMethodTaint = (receiver, method, value, global, context) => {
|
|
586
|
+
if (global) {
|
|
587
|
+
// A prototype write can be an accessor, proxy-observable operation, or an
|
|
588
|
+
// unresolved descriptor. Once observed, never recover an intrinsic by
|
|
589
|
+
// guessing the replacement value's behavior.
|
|
590
|
+
context.callableMethodTaints.global.add(method);
|
|
591
|
+
return;
|
|
592
|
+
}
|
|
593
|
+
const replacementResolution = value
|
|
594
|
+
? isFunctionNode(value)
|
|
595
|
+
? { functions: new Set([value]), unknown: false }
|
|
596
|
+
: functionValuesOf(value, context, true)
|
|
597
|
+
: { functions: new Set(), unknown: true };
|
|
598
|
+
const receiverResolution = functionValuesOf(receiver, context);
|
|
599
|
+
if (receiverResolution.unknown)
|
|
600
|
+
context.callableMethodTaints.global.add(method);
|
|
601
|
+
for (const receiverFunction of receiverResolution.functions) {
|
|
602
|
+
const methods = context.callableMethodTaints.own.get(receiverFunction) ?? new Map();
|
|
603
|
+
const functions = methods.get(method) ?? new Set();
|
|
604
|
+
for (const fn of replacementResolution.functions)
|
|
605
|
+
functions.add(fn);
|
|
606
|
+
methods.set(method, functions);
|
|
607
|
+
context.callableMethodTaints.own.set(receiverFunction, methods);
|
|
608
|
+
if (replacementResolution.unknown || replacementResolution.functions.size === 0) {
|
|
609
|
+
const unknown = context.callableMethodTaints.ownUnknown.get(receiverFunction) ?? new Set();
|
|
610
|
+
unknown.add(method);
|
|
611
|
+
context.callableMethodTaints.ownUnknown.set(receiverFunction, unknown);
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
};
|
|
615
|
+
const recordCallableMethodWrite = (target, value, context) => {
|
|
616
|
+
const methodTarget = callableMethodTarget(target, context);
|
|
617
|
+
if (methodTarget) {
|
|
618
|
+
recordCallableMethodTaint(methodTarget.receiver, methodTarget.method, value, methodTarget.global, context);
|
|
619
|
+
return;
|
|
620
|
+
}
|
|
621
|
+
const node = unwrapExpression(target);
|
|
622
|
+
if (!ts.isElementAccessExpression(node) || staticElementPropertyName(node.argumentExpression) !== null)
|
|
623
|
+
return;
|
|
624
|
+
const global = isStandardFunctionPrototypeObject(node.expression, context);
|
|
625
|
+
const receiverResolution = functionValuesOf(node.expression, context);
|
|
626
|
+
if (!global && receiverResolution.functions.size === 0 && !receiverResolution.unknown)
|
|
627
|
+
return;
|
|
628
|
+
for (const method of ['call', 'apply', 'bind'])
|
|
629
|
+
recordCallableMethodTaint(node.expression, method, value, global, context);
|
|
630
|
+
};
|
|
631
|
+
const objectLiteralPropertyValue = (expression, name) => {
|
|
632
|
+
const node = unwrapExpression(expression);
|
|
633
|
+
if (!ts.isObjectLiteralExpression(node))
|
|
634
|
+
return null;
|
|
635
|
+
for (const property of node.properties) {
|
|
636
|
+
if (ts.isPropertyAssignment(property) && staticPropertyName(property.name) === name)
|
|
637
|
+
return property.initializer;
|
|
638
|
+
if (ts.isShorthandPropertyAssignment(property) && property.name.text === name)
|
|
639
|
+
return property.name;
|
|
640
|
+
}
|
|
641
|
+
return null;
|
|
642
|
+
};
|
|
643
|
+
const recordCallBasedMethodTaint = (callee, argumentsArray, context) => {
|
|
644
|
+
const node = unwrapExpression(callee);
|
|
645
|
+
if (!ts.isPropertyAccessExpression(node) && !ts.isElementAccessExpression(node))
|
|
646
|
+
return;
|
|
647
|
+
const operation = ts.isPropertyAccessExpression(node) ? staticPropertyName(node.name) : staticElementPropertyName(node.argumentExpression);
|
|
648
|
+
const target = argumentsArray[0];
|
|
649
|
+
if (!target)
|
|
650
|
+
return;
|
|
651
|
+
const global = isStandardFunctionPrototypeObject(target, context);
|
|
652
|
+
const taint = (method, value) => {
|
|
653
|
+
const methods = method ? [method] : ['call', 'apply', 'bind'];
|
|
654
|
+
for (const current of methods)
|
|
655
|
+
recordCallableMethodTaint(target, current, value, global, context);
|
|
656
|
+
};
|
|
657
|
+
if (operation === 'defineProperty' || operation === 'set' || operation === 'deleteProperty') {
|
|
658
|
+
const method = argumentsArray[1] ? functionPrototypeMethodName(argumentsArray[1], true) : null;
|
|
659
|
+
if (method === null && argumentsArray[1] && staticElementPropertyName(argumentsArray[1]) !== null)
|
|
660
|
+
return;
|
|
661
|
+
const value = operation === 'set'
|
|
662
|
+
? (argumentsArray[2] ?? null)
|
|
663
|
+
: operation === 'defineProperty' && argumentsArray[2]
|
|
664
|
+
? objectLiteralPropertyValue(argumentsArray[2], 'value')
|
|
665
|
+
: null;
|
|
666
|
+
taint(method, value);
|
|
667
|
+
return;
|
|
668
|
+
}
|
|
669
|
+
if (operation === 'defineProperties' && argumentsArray[1]) {
|
|
670
|
+
const descriptors = unwrapExpression(argumentsArray[1]);
|
|
671
|
+
if (!ts.isObjectLiteralExpression(descriptors)) {
|
|
672
|
+
taint(null, null);
|
|
673
|
+
return;
|
|
674
|
+
}
|
|
675
|
+
for (const property of descriptors.properties) {
|
|
676
|
+
if (!ts.isPropertyAssignment(property))
|
|
677
|
+
continue;
|
|
678
|
+
const method = functionPrototypeMethodName(property.name);
|
|
679
|
+
if (method)
|
|
680
|
+
taint(method, objectLiteralPropertyValue(property.initializer, 'value'));
|
|
681
|
+
}
|
|
682
|
+
return;
|
|
683
|
+
}
|
|
684
|
+
if (operation === 'assign') {
|
|
685
|
+
for (const source of argumentsArray.slice(1)) {
|
|
686
|
+
const object = unwrapExpression(source);
|
|
687
|
+
if (!ts.isObjectLiteralExpression(object)) {
|
|
688
|
+
taint(null, null);
|
|
689
|
+
continue;
|
|
690
|
+
}
|
|
691
|
+
for (const property of object.properties) {
|
|
692
|
+
if (!ts.isPropertyAssignment(property) && !ts.isShorthandPropertyAssignment(property) && !isFunctionNode(property))
|
|
693
|
+
continue;
|
|
694
|
+
const method = functionPrototypeMethodName(property.name);
|
|
695
|
+
if (!method)
|
|
696
|
+
continue;
|
|
697
|
+
const value = ts.isPropertyAssignment(property)
|
|
698
|
+
? property.initializer
|
|
699
|
+
: ts.isShorthandPropertyAssignment(property)
|
|
700
|
+
? property.name
|
|
701
|
+
: property;
|
|
702
|
+
taint(method, value);
|
|
703
|
+
}
|
|
704
|
+
}
|
|
705
|
+
}
|
|
706
|
+
};
|
|
707
|
+
const recordContainerFunctions = (target, value, context) => {
|
|
708
|
+
const symbol = containerRootSymbol(target, context);
|
|
709
|
+
if (!symbol)
|
|
710
|
+
return;
|
|
711
|
+
const resolution = functionValuesOf(value, context, true);
|
|
712
|
+
const functions = [...resolution.functions].filter((fn) => fn.getSourceFile() === context.sourceFile);
|
|
713
|
+
if (functions.length === 0 && !resolution.unknown)
|
|
714
|
+
return;
|
|
715
|
+
const facts = context.containerFunctions.get(symbol) ?? { functions: new Set(), unknown: false };
|
|
716
|
+
for (const fn of functions)
|
|
717
|
+
facts.functions.add(fn);
|
|
718
|
+
facts.unknown ||= resolution.unknown;
|
|
719
|
+
context.containerFunctions.set(symbol, facts);
|
|
720
|
+
};
|
|
721
|
+
function functionPrototypeMethodsIn(expression, context, deep, seenSymbols = new Set(), seenNodes = new Set()) {
|
|
722
|
+
const node = unwrapExpression(expression);
|
|
723
|
+
if (seenNodes.has(node))
|
|
724
|
+
return new Set();
|
|
725
|
+
seenNodes.add(node);
|
|
726
|
+
if (ts.isPropertyAccessExpression(node) || ts.isElementAccessExpression(node)) {
|
|
727
|
+
const property = ts.isPropertyAccessExpression(node) ? node.name : node.argumentExpression;
|
|
728
|
+
const method = functionPrototypeMethodName(property, ts.isElementAccessExpression(node));
|
|
729
|
+
if (method && declaredStandardFunctionPrototypeMember(node.expression, method, context))
|
|
730
|
+
return new Set([method]);
|
|
731
|
+
}
|
|
732
|
+
if (ts.isIdentifier(node)) {
|
|
733
|
+
const symbol = resolvedSymbolAt(context.checker, node);
|
|
734
|
+
if (!symbol || seenSymbols.has(symbol))
|
|
735
|
+
return new Set();
|
|
736
|
+
seenSymbols.add(symbol);
|
|
737
|
+
const methods = new Set(context.functionPrototypeMethodAssignments.get(symbol) ?? []);
|
|
738
|
+
const declaration = symbol.valueDeclaration ?? symbol.declarations?.[0];
|
|
739
|
+
const values = [];
|
|
740
|
+
if (declaration && ts.isVariableDeclaration(declaration) && declaration.initializer)
|
|
741
|
+
values.push(declaration.initializer);
|
|
742
|
+
for (const assigned of context.functionAssignments.get(symbol) ?? [])
|
|
743
|
+
values.push(assigned);
|
|
744
|
+
for (const assigned of context.destructuredFunctionAssignments.get(symbol) ?? [])
|
|
745
|
+
values.push(assigned);
|
|
746
|
+
for (const value of values)
|
|
747
|
+
for (const method of functionPrototypeMethodsIn(value, context, deep, new Set(seenSymbols), new Set(seenNodes)))
|
|
748
|
+
methods.add(method);
|
|
749
|
+
return methods;
|
|
750
|
+
}
|
|
751
|
+
if (ts.isConditionalExpression(node)) {
|
|
752
|
+
return new Set([
|
|
753
|
+
...functionPrototypeMethodsIn(node.whenTrue, context, deep, new Set(seenSymbols), new Set(seenNodes)),
|
|
754
|
+
...functionPrototypeMethodsIn(node.whenFalse, context, deep, new Set(seenSymbols), new Set(seenNodes))
|
|
755
|
+
]);
|
|
756
|
+
}
|
|
757
|
+
if (ts.isBinaryExpression(node) && node.operatorToken.kind === ts.SyntaxKind.CommaToken) {
|
|
758
|
+
return functionPrototypeMethodsIn(node.right, context, deep, seenSymbols, seenNodes);
|
|
759
|
+
}
|
|
760
|
+
if (deep && ts.isObjectLiteralExpression(node)) {
|
|
761
|
+
const methods = new Set();
|
|
762
|
+
for (const property of node.properties) {
|
|
763
|
+
const value = ts.isPropertyAssignment(property)
|
|
764
|
+
? property.initializer
|
|
765
|
+
: ts.isShorthandPropertyAssignment(property)
|
|
766
|
+
? property.name
|
|
767
|
+
: ts.isSpreadAssignment(property)
|
|
768
|
+
? property.expression
|
|
769
|
+
: null;
|
|
770
|
+
if (value)
|
|
771
|
+
for (const method of functionPrototypeMethodsIn(value, context, true, new Set(seenSymbols), new Set(seenNodes)))
|
|
772
|
+
methods.add(method);
|
|
773
|
+
}
|
|
774
|
+
return methods;
|
|
775
|
+
}
|
|
776
|
+
if (deep && ts.isArrayLiteralExpression(node)) {
|
|
777
|
+
const methods = new Set();
|
|
778
|
+
for (const element of node.elements) {
|
|
779
|
+
if (ts.isOmittedExpression(element))
|
|
780
|
+
continue;
|
|
781
|
+
const value = ts.isSpreadElement(element) ? element.expression : element;
|
|
782
|
+
for (const method of functionPrototypeMethodsIn(value, context, true, new Set(seenSymbols), new Set(seenNodes)))
|
|
783
|
+
methods.add(method);
|
|
784
|
+
}
|
|
785
|
+
return methods;
|
|
786
|
+
}
|
|
787
|
+
return new Set();
|
|
788
|
+
}
|
|
789
|
+
const recordFunctionPrototypeMethods = (target, methods, context) => {
|
|
790
|
+
if (methods.size === 0)
|
|
791
|
+
return;
|
|
792
|
+
if (ts.isIdentifier(target)) {
|
|
793
|
+
const shorthandValue = ts.isShorthandPropertyAssignment(target.parent)
|
|
794
|
+
? context.checker.getShorthandAssignmentValueSymbol(target.parent)
|
|
795
|
+
: undefined;
|
|
796
|
+
const symbol = shorthandValue ? resolvedSymbol(context.checker, shorthandValue) : resolvedSymbolAt(context.checker, target);
|
|
797
|
+
if (!symbol)
|
|
798
|
+
return;
|
|
799
|
+
const assigned = context.functionPrototypeMethodAssignments.get(symbol) ?? new Set();
|
|
800
|
+
for (const method of methods)
|
|
801
|
+
assigned.add(method);
|
|
802
|
+
context.functionPrototypeMethodAssignments.set(symbol, assigned);
|
|
803
|
+
return;
|
|
804
|
+
}
|
|
805
|
+
if (ts.isObjectBindingPattern(target) || ts.isArrayBindingPattern(target)) {
|
|
806
|
+
for (const element of target.elements)
|
|
807
|
+
if (!ts.isOmittedExpression(element))
|
|
808
|
+
recordFunctionPrototypeMethods(element.name, methods, context);
|
|
809
|
+
return;
|
|
810
|
+
}
|
|
811
|
+
const node = unwrapExpression(target);
|
|
812
|
+
if (ts.isBinaryExpression(node) && node.operatorToken.kind === ts.SyntaxKind.EqualsToken) {
|
|
813
|
+
recordFunctionPrototypeMethods(node.left, methods, context);
|
|
814
|
+
return;
|
|
815
|
+
}
|
|
816
|
+
if (ts.isObjectLiteralExpression(node)) {
|
|
817
|
+
for (const property of node.properties) {
|
|
818
|
+
if (ts.isSpreadAssignment(property))
|
|
819
|
+
recordFunctionPrototypeMethods(property.expression, methods, context);
|
|
820
|
+
else if (ts.isShorthandPropertyAssignment(property))
|
|
821
|
+
recordFunctionPrototypeMethods(property.name, methods, context);
|
|
822
|
+
else if (ts.isPropertyAssignment(property))
|
|
823
|
+
recordFunctionPrototypeMethods(property.initializer, methods, context);
|
|
824
|
+
}
|
|
825
|
+
return;
|
|
826
|
+
}
|
|
827
|
+
if (ts.isArrayLiteralExpression(node)) {
|
|
828
|
+
for (const element of node.elements)
|
|
829
|
+
if (!ts.isOmittedExpression(element))
|
|
830
|
+
recordFunctionPrototypeMethods(ts.isSpreadElement(element) ? element.expression : element, methods, context);
|
|
831
|
+
}
|
|
832
|
+
};
|
|
833
|
+
const recordFunctionAssignment = (target, value, context, destructured = false) => {
|
|
834
|
+
recordFunctionPrototypeMethods(target, functionPrototypeMethodsIn(value, context, destructured), context);
|
|
835
|
+
const valueType = context.checker.getTypeAtLocation(value);
|
|
836
|
+
const callableSource = valueType.getCallSignatures().length > 0 || (valueType.flags & (ts.TypeFlags.Any | ts.TypeFlags.Unknown)) !== 0;
|
|
837
|
+
if (ts.isIdentifier(target)) {
|
|
838
|
+
const shorthandValue = ts.isShorthandPropertyAssignment(target.parent)
|
|
839
|
+
? context.checker.getShorthandAssignmentValueSymbol(target.parent)
|
|
840
|
+
: undefined;
|
|
841
|
+
const symbol = shorthandValue ? resolvedSymbol(context.checker, shorthandValue) : resolvedSymbolAt(context.checker, target);
|
|
842
|
+
if (!symbol)
|
|
843
|
+
return;
|
|
844
|
+
const facts = destructured ? context.destructuredFunctionAssignments : context.functionAssignments;
|
|
845
|
+
const assignments = facts.get(symbol) ?? new Set();
|
|
846
|
+
assignments.add(value);
|
|
847
|
+
facts.set(symbol, assignments);
|
|
848
|
+
return;
|
|
849
|
+
}
|
|
850
|
+
if (ts.isObjectBindingPattern(target) || ts.isArrayBindingPattern(target)) {
|
|
851
|
+
for (const element of target.elements) {
|
|
852
|
+
if (ts.isOmittedExpression(element))
|
|
853
|
+
continue;
|
|
854
|
+
if (callableSource && ts.isObjectBindingPattern(target)) {
|
|
855
|
+
const property = element.propertyName ?? (ts.isIdentifier(element.name) ? element.name : null);
|
|
856
|
+
const method = property ? functionPrototypeMethodName(property) : null;
|
|
857
|
+
if (method)
|
|
858
|
+
recordFunctionPrototypeMethods(element.name, new Set([method]), context);
|
|
859
|
+
}
|
|
860
|
+
recordFunctionAssignment(element.name, value, context, true);
|
|
861
|
+
if (element.initializer)
|
|
862
|
+
recordFunctionAssignment(element.name, element.initializer, context, true);
|
|
863
|
+
}
|
|
864
|
+
return;
|
|
865
|
+
}
|
|
866
|
+
const node = unwrapExpression(target);
|
|
867
|
+
if (ts.isBinaryExpression(node) && node.operatorToken.kind === ts.SyntaxKind.EqualsToken) {
|
|
868
|
+
recordFunctionAssignment(node.left, value, context, true);
|
|
869
|
+
recordFunctionAssignment(node.left, node.right, context, true);
|
|
870
|
+
return;
|
|
871
|
+
}
|
|
872
|
+
if (ts.isObjectLiteralExpression(node)) {
|
|
873
|
+
for (const property of node.properties) {
|
|
874
|
+
if (ts.isSpreadAssignment(property))
|
|
875
|
+
recordFunctionAssignment(property.expression, value, context, true);
|
|
876
|
+
else if (ts.isShorthandPropertyAssignment(property)) {
|
|
877
|
+
const method = callableSource ? functionPrototypeMethodName(property.name) : null;
|
|
878
|
+
if (method)
|
|
879
|
+
recordFunctionPrototypeMethods(property.name, new Set([method]), context);
|
|
880
|
+
recordFunctionAssignment(property.name, value, context, true);
|
|
881
|
+
if (property.objectAssignmentInitializer)
|
|
882
|
+
recordFunctionAssignment(property.name, property.objectAssignmentInitializer, context, true);
|
|
883
|
+
}
|
|
884
|
+
else if (ts.isPropertyAssignment(property)) {
|
|
885
|
+
const method = callableSource ? functionPrototypeMethodName(property.name) : null;
|
|
886
|
+
if (method)
|
|
887
|
+
recordFunctionPrototypeMethods(property.initializer, new Set([method]), context);
|
|
888
|
+
recordFunctionAssignment(property.initializer, value, context, true);
|
|
889
|
+
}
|
|
890
|
+
}
|
|
891
|
+
return;
|
|
892
|
+
}
|
|
893
|
+
if (ts.isArrayLiteralExpression(node)) {
|
|
894
|
+
for (const element of node.elements) {
|
|
895
|
+
if (ts.isOmittedExpression(element))
|
|
896
|
+
continue;
|
|
897
|
+
recordFunctionAssignment(ts.isSpreadElement(element) ? element.expression : element, value, context, true);
|
|
898
|
+
}
|
|
899
|
+
}
|
|
900
|
+
};
|
|
901
|
+
const readTarget = (target, state, context) => {
|
|
902
|
+
const node = unwrapExpression(target);
|
|
903
|
+
if (ts.isIdentifier(node)) {
|
|
904
|
+
const identity = classify(node, context);
|
|
905
|
+
if (identity.kind === 'wrapper' && identity.global === 'require')
|
|
906
|
+
recordRead(node, state, context);
|
|
907
|
+
return state;
|
|
908
|
+
}
|
|
909
|
+
return evaluateExpression(node, state, context);
|
|
910
|
+
};
|
|
911
|
+
const writeAssignmentTarget = (target, state, context) => {
|
|
912
|
+
const node = unwrapExpression(target);
|
|
913
|
+
if (ts.isIdentifier(node))
|
|
914
|
+
return wrapperWrite(node, state, context);
|
|
915
|
+
if (containsModuleExportsAccess(node, context) && state !== unreachable)
|
|
916
|
+
context.observedEffects.value |= writesModuleExports;
|
|
917
|
+
if (ts.isArrayLiteralExpression(node)) {
|
|
918
|
+
let next = state;
|
|
919
|
+
for (const element of node.elements) {
|
|
920
|
+
if (ts.isOmittedExpression(element))
|
|
921
|
+
continue;
|
|
922
|
+
const targetExpression = ts.isSpreadElement(element) ? element.expression : element;
|
|
923
|
+
if (ts.isBinaryExpression(targetExpression) && targetExpression.operatorToken.kind === ts.SyntaxKind.EqualsToken) {
|
|
924
|
+
next = join(next, evaluateExpression(targetExpression.right, next, context));
|
|
925
|
+
next = writeAssignmentTarget(targetExpression.left, next, context);
|
|
926
|
+
}
|
|
927
|
+
else
|
|
928
|
+
next = writeAssignmentTarget(targetExpression, next, context);
|
|
929
|
+
}
|
|
930
|
+
return next;
|
|
931
|
+
}
|
|
932
|
+
if (ts.isObjectLiteralExpression(node)) {
|
|
933
|
+
let next = state;
|
|
934
|
+
for (const property of node.properties) {
|
|
935
|
+
if (ts.isSpreadAssignment(property))
|
|
936
|
+
next = writeAssignmentTarget(property.expression, next, context);
|
|
937
|
+
else if (ts.isShorthandPropertyAssignment(property))
|
|
938
|
+
next = writeAssignmentTarget(property.name, next, context);
|
|
939
|
+
else if (ts.isPropertyAssignment(property))
|
|
940
|
+
next = writeAssignmentTarget(property.initializer, next, context);
|
|
941
|
+
}
|
|
942
|
+
return next;
|
|
943
|
+
}
|
|
944
|
+
return evaluateExpression(node, state, context);
|
|
945
|
+
};
|
|
946
|
+
const writeBindingName = (name, state, context) => {
|
|
947
|
+
if (ts.isIdentifier(name))
|
|
948
|
+
return wrapperWrite(name, state, context);
|
|
949
|
+
let next = state;
|
|
950
|
+
for (const element of name.elements) {
|
|
951
|
+
if (ts.isOmittedExpression(element))
|
|
952
|
+
continue;
|
|
953
|
+
if (element.initializer)
|
|
954
|
+
next = join(next, evaluateExpression(element.initializer, next, context));
|
|
955
|
+
next = writeBindingName(element.name, next, context);
|
|
956
|
+
}
|
|
957
|
+
return next;
|
|
958
|
+
};
|
|
959
|
+
const recordFunctionEntry = (fn, state, context) => {
|
|
960
|
+
if (state === unreachable || context.entries === null)
|
|
961
|
+
return;
|
|
962
|
+
context.entries.set(fn, join(context.entries.get(fn) ?? unreachable, state));
|
|
963
|
+
};
|
|
964
|
+
const deferFunctionValues = (expression, state, context) => {
|
|
965
|
+
const resolution = functionValuesOf(expression, context, true);
|
|
966
|
+
const functions = [...resolution.functions].filter((fn) => fn.getSourceFile() === context.sourceFile);
|
|
967
|
+
for (const fn of functions) {
|
|
968
|
+
context.deferred?.add(fn);
|
|
969
|
+
recordFunctionEntry(fn, state, context);
|
|
970
|
+
}
|
|
971
|
+
const effects = functions.reduce((result, fn) => result | (context.summaries.get(fn)?.effects ?? 0), resolution.unknown ? writesRequire : 0);
|
|
972
|
+
return effects;
|
|
973
|
+
};
|
|
974
|
+
const evaluateCall = (expression, argumentsArray, state, context) => {
|
|
975
|
+
let next = evaluateExpression(expression, state, context);
|
|
976
|
+
for (const argument of argumentsArray)
|
|
977
|
+
next = evaluateExpression(argument, next, context);
|
|
978
|
+
recordCallBasedMethodTaint(expression, argumentsArray, context);
|
|
979
|
+
const invocation = invocationFunctionsOf(expression, context);
|
|
980
|
+
const callees = [...invocation.functions].filter((fn) => fn.getSourceFile() === context.sourceFile);
|
|
981
|
+
const unknownMethod = unknownTaintedMethodOrigin(expression, context);
|
|
982
|
+
const unknownInvocation = invocation.unknown || unknownMethod;
|
|
983
|
+
if (unknownInvocation)
|
|
984
|
+
context.observedEffects.value |= writesRequire;
|
|
985
|
+
if (callees.length > 0) {
|
|
986
|
+
let effects = unknownInvocation ? writesRequire : 0;
|
|
987
|
+
for (const callee of callees) {
|
|
988
|
+
recordFunctionEntry(callee, next, context);
|
|
989
|
+
effects |= context.summaries.get(callee)?.effects ?? 0;
|
|
990
|
+
}
|
|
991
|
+
context.observedEffects.value |= effects;
|
|
992
|
+
return (effects & writesRequire) !== 0 ? join(next, unknownDefinition) : next;
|
|
993
|
+
}
|
|
994
|
+
const raw = unwrapExpression(expression);
|
|
995
|
+
const identity = ts.isIdentifier(raw) ? classify(raw, context) : null;
|
|
996
|
+
if (identity?.kind === 'wrapper' && identity.global === 'require')
|
|
997
|
+
return next;
|
|
998
|
+
if (unknownInvocation) {
|
|
999
|
+
return join(next, unknownDefinition);
|
|
1000
|
+
}
|
|
1001
|
+
let reachableEffects = 0;
|
|
1002
|
+
for (const argument of argumentsArray)
|
|
1003
|
+
reachableEffects |= deferFunctionValues(argument, next, context);
|
|
1004
|
+
context.observedEffects.value |= reachableEffects;
|
|
1005
|
+
return (reachableEffects & writesRequire) !== 0 ? join(next, unknownDefinition) : next;
|
|
1006
|
+
};
|
|
1007
|
+
const evaluateChildren = (node, state, context) => {
|
|
1008
|
+
let next = state;
|
|
1009
|
+
const visit = (child) => {
|
|
1010
|
+
if (isFunctionNode(child))
|
|
1011
|
+
return;
|
|
1012
|
+
if (ts.isExpression(child))
|
|
1013
|
+
next = evaluateExpression(child, next, context);
|
|
1014
|
+
else
|
|
1015
|
+
ts.forEachChild(child, visit);
|
|
1016
|
+
};
|
|
1017
|
+
ts.forEachChild(node, visit);
|
|
1018
|
+
return next;
|
|
1019
|
+
};
|
|
1020
|
+
const evaluateExpression = (expression, state, context) => {
|
|
1021
|
+
if (state === unreachable)
|
|
1022
|
+
return unreachable;
|
|
1023
|
+
const node = unwrapExpression(expression);
|
|
1024
|
+
if (ts.isIdentifier(node)) {
|
|
1025
|
+
const identity = classify(node, context);
|
|
1026
|
+
if (identity.kind === 'wrapper' && identity.global === 'require')
|
|
1027
|
+
recordRead(node, state, context);
|
|
1028
|
+
return state;
|
|
1029
|
+
}
|
|
1030
|
+
if (ts.isFunctionExpression(node) || ts.isArrowFunction(node))
|
|
1031
|
+
return state;
|
|
1032
|
+
if (ts.isCallExpression(node))
|
|
1033
|
+
return evaluateCall(node.expression, node.arguments, state, context);
|
|
1034
|
+
if (ts.isNewExpression(node))
|
|
1035
|
+
return evaluateCall(node.expression, node.arguments ?? [], state, context);
|
|
1036
|
+
if (ts.isPropertyAccessExpression(node))
|
|
1037
|
+
return evaluateExpression(node.expression, state, context);
|
|
1038
|
+
if (ts.isElementAccessExpression(node)) {
|
|
1039
|
+
const receiver = evaluateExpression(node.expression, state, context);
|
|
1040
|
+
return evaluateExpression(node.argumentExpression, receiver, context);
|
|
1041
|
+
}
|
|
1042
|
+
if (ts.isBinaryExpression(node)) {
|
|
1043
|
+
const operator = node.operatorToken.kind;
|
|
1044
|
+
if (operator === ts.SyntaxKind.CommaToken)
|
|
1045
|
+
return evaluateExpression(node.right, evaluateExpression(node.left, state, context), context);
|
|
1046
|
+
if (operator === ts.SyntaxKind.AmpersandAmpersandToken ||
|
|
1047
|
+
operator === ts.SyntaxKind.BarBarToken ||
|
|
1048
|
+
operator === ts.SyntaxKind.QuestionQuestionToken) {
|
|
1049
|
+
const left = evaluateExpression(node.left, state, context);
|
|
1050
|
+
const truth = constantTruthiness(node.left);
|
|
1051
|
+
const alwaysRight = (operator === ts.SyntaxKind.AmpersandAmpersandToken && truth === true) ||
|
|
1052
|
+
(operator === ts.SyntaxKind.BarBarToken && truth === false);
|
|
1053
|
+
const neverRight = (operator === ts.SyntaxKind.AmpersandAmpersandToken && truth === false) ||
|
|
1054
|
+
(operator === ts.SyntaxKind.BarBarToken && truth === true);
|
|
1055
|
+
if (alwaysRight)
|
|
1056
|
+
return evaluateExpression(node.right, left, context);
|
|
1057
|
+
if (neverRight)
|
|
1058
|
+
return left;
|
|
1059
|
+
return join(left, evaluateExpression(node.right, left, context));
|
|
1060
|
+
}
|
|
1061
|
+
if (isAssignmentOperatorKind(operator)) {
|
|
1062
|
+
const logical = operator === ts.SyntaxKind.AmpersandAmpersandEqualsToken ||
|
|
1063
|
+
operator === ts.SyntaxKind.BarBarEqualsToken ||
|
|
1064
|
+
operator === ts.SyntaxKind.QuestionQuestionEqualsToken;
|
|
1065
|
+
let next = operator === ts.SyntaxKind.EqualsToken ? state : readTarget(node.left, state, context);
|
|
1066
|
+
next = evaluateExpression(node.right, next, context);
|
|
1067
|
+
const written = writeAssignmentTarget(node.left, next, context);
|
|
1068
|
+
recordCallableMethodWrite(node.left, operator === ts.SyntaxKind.EqualsToken ? node.right : null, context);
|
|
1069
|
+
if (logical)
|
|
1070
|
+
return join(state, written);
|
|
1071
|
+
if (operator === ts.SyntaxKind.EqualsToken) {
|
|
1072
|
+
recordFunctionAssignment(node.left, node.right, context);
|
|
1073
|
+
recordContainerFunctions(node.left, node.right, context);
|
|
1074
|
+
if (containsModuleExportsAccess(node.left, context))
|
|
1075
|
+
deferFunctionValues(node.right, written, context);
|
|
1076
|
+
}
|
|
1077
|
+
return written;
|
|
1078
|
+
}
|
|
1079
|
+
return evaluateExpression(node.right, evaluateExpression(node.left, state, context), context);
|
|
1080
|
+
}
|
|
1081
|
+
if (ts.isConditionalExpression(node)) {
|
|
1082
|
+
const afterCondition = evaluateExpression(node.condition, state, context);
|
|
1083
|
+
const truth = constantTruthiness(node.condition);
|
|
1084
|
+
if (truth === true)
|
|
1085
|
+
return evaluateExpression(node.whenTrue, afterCondition, context);
|
|
1086
|
+
if (truth === false)
|
|
1087
|
+
return evaluateExpression(node.whenFalse, afterCondition, context);
|
|
1088
|
+
return join(evaluateExpression(node.whenTrue, afterCondition, context), evaluateExpression(node.whenFalse, afterCondition, context));
|
|
1089
|
+
}
|
|
1090
|
+
if (ts.isPrefixUnaryExpression(node) || ts.isPostfixUnaryExpression(node)) {
|
|
1091
|
+
if (node.operator === ts.SyntaxKind.PlusPlusToken || node.operator === ts.SyntaxKind.MinusMinusToken) {
|
|
1092
|
+
return writeAssignmentTarget(node.operand, readTarget(node.operand, state, context), context);
|
|
1093
|
+
}
|
|
1094
|
+
return evaluateExpression(node.operand, state, context);
|
|
1095
|
+
}
|
|
1096
|
+
if (ts.isDeleteExpression(node)) {
|
|
1097
|
+
if (containsModuleExportsAccess(node.expression, context))
|
|
1098
|
+
context.observedEffects.value |= writesModuleExports;
|
|
1099
|
+
recordCallableMethodWrite(node.expression, null, context);
|
|
1100
|
+
return evaluateExpression(node.expression, state, context);
|
|
1101
|
+
}
|
|
1102
|
+
if (ts.isTypeOfExpression(node) || ts.isVoidExpression(node) || ts.isAwaitExpression(node)) {
|
|
1103
|
+
return evaluateExpression(node.expression, state, context);
|
|
1104
|
+
}
|
|
1105
|
+
if (ts.isYieldExpression(node))
|
|
1106
|
+
return node.expression ? evaluateExpression(node.expression, state, context) : state;
|
|
1107
|
+
if (ts.isTaggedTemplateExpression(node)) {
|
|
1108
|
+
const tag = evaluateExpression(node.tag, state, context);
|
|
1109
|
+
return evaluateChildren(node.template, tag, context);
|
|
1110
|
+
}
|
|
1111
|
+
return evaluateChildren(node, state, context);
|
|
1112
|
+
};
|
|
1113
|
+
const analyzeVariableDeclaration = (node, state, context) => {
|
|
1114
|
+
if (!node.initializer)
|
|
1115
|
+
return state;
|
|
1116
|
+
const initialized = evaluateExpression(node.initializer, state, context);
|
|
1117
|
+
const written = writeBindingName(node.name, initialized, context);
|
|
1118
|
+
recordFunctionAssignment(node.name, node.initializer, context, !ts.isIdentifier(node.name));
|
|
1119
|
+
if (ts.isIdentifier(node.name)) {
|
|
1120
|
+
const statement = node.parent.parent;
|
|
1121
|
+
if (ts.isVariableStatement(statement) && statement.modifiers?.some((modifier) => modifier.kind === ts.SyntaxKind.ExportKeyword)) {
|
|
1122
|
+
deferFunctionValues(node.initializer, written, context);
|
|
1123
|
+
}
|
|
1124
|
+
}
|
|
1125
|
+
return written;
|
|
1126
|
+
};
|
|
1127
|
+
const analyzeStatements = (statements, state, context) => {
|
|
1128
|
+
let result = completion(state);
|
|
1129
|
+
for (const statement of statements) {
|
|
1130
|
+
const next = analyzeStatement(statement, result.normal, context);
|
|
1131
|
+
result = {
|
|
1132
|
+
normal: next.normal,
|
|
1133
|
+
returned: join(result.returned, next.returned),
|
|
1134
|
+
thrown: join(result.thrown, next.thrown),
|
|
1135
|
+
broken: join(result.broken, next.broken),
|
|
1136
|
+
continued: join(result.continued, next.continued)
|
|
1137
|
+
};
|
|
1138
|
+
}
|
|
1139
|
+
return result;
|
|
1140
|
+
};
|
|
1141
|
+
const analyzeLoop = (initial, condition, body, incrementor, atLeastOnce, context) => {
|
|
1142
|
+
let head = initial;
|
|
1143
|
+
let returned = unreachable;
|
|
1144
|
+
let thrown = unreachable;
|
|
1145
|
+
for (;;) {
|
|
1146
|
+
const conditioned = condition ? evaluateExpression(condition, head, context) : head;
|
|
1147
|
+
const truth = condition ? constantTruthiness(condition) : true;
|
|
1148
|
+
const bodyFlow = truth === false ? completion(unreachable) : analyzeStatement(body, conditioned, context);
|
|
1149
|
+
returned = join(returned, bodyFlow.returned);
|
|
1150
|
+
thrown = join(thrown, bodyFlow.thrown);
|
|
1151
|
+
const backInput = join(bodyFlow.normal, bodyFlow.continued);
|
|
1152
|
+
const back = incrementor ? evaluateExpression(incrementor, backInput, context) : backInput;
|
|
1153
|
+
const nextHead = join(initial, back);
|
|
1154
|
+
if (nextHead === head) {
|
|
1155
|
+
const conditionExit = truth === true ? unreachable : conditioned;
|
|
1156
|
+
return {
|
|
1157
|
+
normal: join(conditionExit, bodyFlow.broken, atLeastOnce ? unreachable : conditionExit),
|
|
1158
|
+
returned,
|
|
1159
|
+
thrown,
|
|
1160
|
+
broken: unreachable,
|
|
1161
|
+
continued: unreachable
|
|
1162
|
+
};
|
|
1163
|
+
}
|
|
1164
|
+
head = nextHead;
|
|
1165
|
+
}
|
|
1166
|
+
};
|
|
1167
|
+
const applyFinally = (flow, block, context) => {
|
|
1168
|
+
const result = {
|
|
1169
|
+
normal: unreachable,
|
|
1170
|
+
returned: unreachable,
|
|
1171
|
+
thrown: unreachable,
|
|
1172
|
+
broken: unreachable,
|
|
1173
|
+
continued: unreachable
|
|
1174
|
+
};
|
|
1175
|
+
const channels = ['normal', 'returned', 'thrown', 'broken', 'continued'];
|
|
1176
|
+
for (const channel of channels) {
|
|
1177
|
+
const incoming = flow[channel];
|
|
1178
|
+
if (incoming === unreachable)
|
|
1179
|
+
continue;
|
|
1180
|
+
const finalized = analyzeStatements(block.statements, incoming, context);
|
|
1181
|
+
result[channel] = join(result[channel], finalized.normal);
|
|
1182
|
+
result.returned = join(result.returned, finalized.returned);
|
|
1183
|
+
result.thrown = join(result.thrown, finalized.thrown);
|
|
1184
|
+
result.broken = join(result.broken, finalized.broken);
|
|
1185
|
+
result.continued = join(result.continued, finalized.continued);
|
|
1186
|
+
}
|
|
1187
|
+
return result;
|
|
1188
|
+
};
|
|
1189
|
+
const analyzeSwitch = (node, state, context) => {
|
|
1190
|
+
const discriminant = evaluateExpression(node.expression, state, context);
|
|
1191
|
+
let fallthrough = unreachable;
|
|
1192
|
+
let exits = completion(unreachable);
|
|
1193
|
+
let hasDefault = false;
|
|
1194
|
+
for (const clause of node.caseBlock.clauses) {
|
|
1195
|
+
let entry = join(discriminant, fallthrough);
|
|
1196
|
+
if (ts.isCaseClause(clause))
|
|
1197
|
+
entry = evaluateExpression(clause.expression, entry, context);
|
|
1198
|
+
else
|
|
1199
|
+
hasDefault = true;
|
|
1200
|
+
const branch = analyzeStatements(clause.statements, entry, context);
|
|
1201
|
+
fallthrough = branch.normal;
|
|
1202
|
+
exits = mergeCompletion(exits, withNormal(branch, branch.broken));
|
|
1203
|
+
}
|
|
1204
|
+
return withNormal(exits, join(exits.normal, fallthrough, hasDefault ? unreachable : discriminant));
|
|
1205
|
+
};
|
|
1206
|
+
const analyzeStatement = (node, state, context) => {
|
|
1207
|
+
if (state === unreachable)
|
|
1208
|
+
return completion(unreachable);
|
|
1209
|
+
if (ts.isBlock(node))
|
|
1210
|
+
return analyzeStatements(node.statements, state, context);
|
|
1211
|
+
if (ts.isVariableStatement(node)) {
|
|
1212
|
+
let next = state;
|
|
1213
|
+
for (const declaration of node.declarationList.declarations)
|
|
1214
|
+
next = analyzeVariableDeclaration(declaration, next, context);
|
|
1215
|
+
return completion(next);
|
|
1216
|
+
}
|
|
1217
|
+
if (ts.isExpressionStatement(node))
|
|
1218
|
+
return completion(evaluateExpression(node.expression, state, context));
|
|
1219
|
+
if (ts.isIfStatement(node)) {
|
|
1220
|
+
const conditioned = evaluateExpression(node.expression, state, context);
|
|
1221
|
+
const truth = constantTruthiness(node.expression);
|
|
1222
|
+
const whenTrue = truth === false ? completion(unreachable) : analyzeStatement(node.thenStatement, conditioned, context);
|
|
1223
|
+
const whenFalse = truth === true
|
|
1224
|
+
? completion(unreachable)
|
|
1225
|
+
: node.elseStatement
|
|
1226
|
+
? analyzeStatement(node.elseStatement, conditioned, context)
|
|
1227
|
+
: completion(conditioned);
|
|
1228
|
+
return mergeCompletion(whenTrue, whenFalse);
|
|
1229
|
+
}
|
|
1230
|
+
if (ts.isWhileStatement(node))
|
|
1231
|
+
return analyzeLoop(state, node.expression, node.statement, null, false, context);
|
|
1232
|
+
if (ts.isDoStatement(node))
|
|
1233
|
+
return analyzeLoop(state, node.expression, node.statement, null, true, context);
|
|
1234
|
+
if (ts.isForStatement(node)) {
|
|
1235
|
+
let initialized = state;
|
|
1236
|
+
if (node.initializer) {
|
|
1237
|
+
if (ts.isVariableDeclarationList(node.initializer)) {
|
|
1238
|
+
for (const declaration of node.initializer.declarations)
|
|
1239
|
+
initialized = analyzeVariableDeclaration(declaration, initialized, context);
|
|
1240
|
+
}
|
|
1241
|
+
else
|
|
1242
|
+
initialized = evaluateExpression(node.initializer, initialized, context);
|
|
1243
|
+
}
|
|
1244
|
+
return analyzeLoop(initialized, node.condition ?? null, node.statement, node.incrementor ?? null, false, context);
|
|
1245
|
+
}
|
|
1246
|
+
if (ts.isForOfStatement(node) || ts.isForInStatement(node)) {
|
|
1247
|
+
const iterable = evaluateExpression(node.expression, state, context);
|
|
1248
|
+
let head = iterable;
|
|
1249
|
+
let returned = unreachable;
|
|
1250
|
+
let thrown = unreachable;
|
|
1251
|
+
for (;;) {
|
|
1252
|
+
let iteration = head;
|
|
1253
|
+
if (ts.isVariableDeclarationList(node.initializer)) {
|
|
1254
|
+
for (const declaration of node.initializer.declarations) {
|
|
1255
|
+
iteration = writeBindingName(declaration.name, iteration, context);
|
|
1256
|
+
recordFunctionAssignment(declaration.name, node.expression, context, true);
|
|
1257
|
+
if (declaration.initializer)
|
|
1258
|
+
recordFunctionAssignment(declaration.name, declaration.initializer, context, true);
|
|
1259
|
+
}
|
|
1260
|
+
}
|
|
1261
|
+
else {
|
|
1262
|
+
iteration = writeAssignmentTarget(node.initializer, iteration, context);
|
|
1263
|
+
recordFunctionAssignment(node.initializer, node.expression, context, true);
|
|
1264
|
+
}
|
|
1265
|
+
const body = analyzeStatement(node.statement, iteration, context);
|
|
1266
|
+
returned = join(returned, body.returned);
|
|
1267
|
+
thrown = join(thrown, body.thrown);
|
|
1268
|
+
const nextHead = join(iterable, body.normal, body.continued);
|
|
1269
|
+
if (nextHead === head) {
|
|
1270
|
+
return {
|
|
1271
|
+
normal: join(head, body.broken),
|
|
1272
|
+
returned,
|
|
1273
|
+
thrown,
|
|
1274
|
+
broken: unreachable,
|
|
1275
|
+
continued: unreachable
|
|
1276
|
+
};
|
|
1277
|
+
}
|
|
1278
|
+
head = nextHead;
|
|
1279
|
+
}
|
|
1280
|
+
}
|
|
1281
|
+
if (ts.isReturnStatement(node)) {
|
|
1282
|
+
const next = node.expression ? evaluateExpression(node.expression, state, context) : state;
|
|
1283
|
+
if (node.expression) {
|
|
1284
|
+
const resolution = functionValuesOf(node.expression, context, true);
|
|
1285
|
+
for (const fn of resolution.functions)
|
|
1286
|
+
context.returnedFunctions?.add(fn);
|
|
1287
|
+
if (resolution.unknown && context.returnedFunctionsUnknown)
|
|
1288
|
+
context.returnedFunctionsUnknown.value = true;
|
|
1289
|
+
deferFunctionValues(node.expression, next, context);
|
|
1290
|
+
}
|
|
1291
|
+
return { ...completion(unreachable), returned: next };
|
|
1292
|
+
}
|
|
1293
|
+
if (ts.isThrowStatement(node))
|
|
1294
|
+
return { ...completion(unreachable), thrown: evaluateExpression(node.expression, state, context) };
|
|
1295
|
+
if (ts.isBreakStatement(node))
|
|
1296
|
+
return { ...completion(unreachable), broken: state };
|
|
1297
|
+
if (ts.isContinueStatement(node))
|
|
1298
|
+
return { ...completion(unreachable), continued: state };
|
|
1299
|
+
if (ts.isTryStatement(node)) {
|
|
1300
|
+
const attempted = analyzeStatements(node.tryBlock.statements, state, context);
|
|
1301
|
+
let caught = completion(unreachable);
|
|
1302
|
+
if (node.catchClause && attempted.thrown !== unreachable) {
|
|
1303
|
+
let catchState = attempted.thrown;
|
|
1304
|
+
if (node.catchClause.variableDeclaration)
|
|
1305
|
+
catchState = writeBindingName(node.catchClause.variableDeclaration.name, catchState, context);
|
|
1306
|
+
caught = analyzeStatements(node.catchClause.block.statements, catchState, context);
|
|
1307
|
+
}
|
|
1308
|
+
const combined = {
|
|
1309
|
+
normal: join(attempted.normal, caught.normal),
|
|
1310
|
+
returned: join(attempted.returned, caught.returned),
|
|
1311
|
+
thrown: node.catchClause ? caught.thrown : attempted.thrown,
|
|
1312
|
+
broken: join(attempted.broken, caught.broken),
|
|
1313
|
+
continued: join(attempted.continued, caught.continued)
|
|
1314
|
+
};
|
|
1315
|
+
return node.finallyBlock ? applyFinally(combined, node.finallyBlock, context) : combined;
|
|
1316
|
+
}
|
|
1317
|
+
if (ts.isSwitchStatement(node))
|
|
1318
|
+
return analyzeSwitch(node, state, context);
|
|
1319
|
+
if (ts.isLabeledStatement(node)) {
|
|
1320
|
+
const labelled = analyzeStatement(node.statement, state, context);
|
|
1321
|
+
return { ...labelled, normal: join(labelled.normal, labelled.broken), broken: unreachable };
|
|
1322
|
+
}
|
|
1323
|
+
if (ts.isFunctionDeclaration(node))
|
|
1324
|
+
return completion(state);
|
|
1325
|
+
if (ts.isClassDeclaration(node))
|
|
1326
|
+
return completion(evaluateChildren(node, state, context));
|
|
1327
|
+
if (ts.isExportAssignment(node))
|
|
1328
|
+
return completion(evaluateExpression(node.expression, state, context));
|
|
1329
|
+
return completion(evaluateChildren(node, state, context));
|
|
1330
|
+
};
|
|
1331
|
+
const analyzeFunction = (node, state, context) => {
|
|
1332
|
+
if (ts.isBlock(node.body))
|
|
1333
|
+
return analyzeStatements(node.body.statements, state, context);
|
|
1334
|
+
const result = evaluateExpression(node.body, state, context);
|
|
1335
|
+
const resolution = functionValuesOf(node.body, context, true);
|
|
1336
|
+
for (const fn of resolution.functions)
|
|
1337
|
+
context.returnedFunctions?.add(fn);
|
|
1338
|
+
if (resolution.unknown && context.returnedFunctionsUnknown)
|
|
1339
|
+
context.returnedFunctionsUnknown.value = true;
|
|
1340
|
+
deferFunctionValues(node.body, result, context);
|
|
1341
|
+
return { ...completion(unreachable), returned: result };
|
|
1342
|
+
};
|
|
1343
|
+
const collectFunctions = (files) => {
|
|
1344
|
+
const functions = [];
|
|
1345
|
+
const visit = (node) => {
|
|
1346
|
+
if (isFunctionNode(node))
|
|
1347
|
+
functions.push(node);
|
|
1348
|
+
ts.forEachChild(node, visit);
|
|
1349
|
+
};
|
|
1350
|
+
for (const file of files)
|
|
1351
|
+
if (!file.isDeclarationFile)
|
|
1352
|
+
visit(file);
|
|
1353
|
+
return functions;
|
|
1354
|
+
};
|
|
1355
|
+
/**
|
|
1356
|
+
* CommonJS static dispatch is a reaching-definition proof over one wrapper
|
|
1357
|
+
* cell per source module. The cell starts at Node's original loader and every
|
|
1358
|
+
* possible write replaces that proof with unknown. Const aliases snapshot the
|
|
1359
|
+
* definition at their own initializer; later cell writes cannot alter them.
|
|
1360
|
+
*/
|
|
1361
|
+
export const createCommonJsRequireCensus = (checker, files, globals) => {
|
|
1362
|
+
// Without any installed wrapper declarations, no identifier can authenticate
|
|
1363
|
+
// as Node's loader. Ordinary user functions need no wrapper-effect analysis.
|
|
1364
|
+
if (globals.size === 0)
|
|
1365
|
+
return { statusOf: () => 'ordinary' };
|
|
1366
|
+
const identity = createCommonJsWrapperIdentity(checker, files, globals);
|
|
1367
|
+
const implementationFiles = files.filter((file) => !file.isDeclarationFile);
|
|
1368
|
+
const functions = collectFunctions(implementationFiles);
|
|
1369
|
+
const containerFunctions = new Map();
|
|
1370
|
+
const functionAssignments = new Map();
|
|
1371
|
+
const destructuredFunctionAssignments = new Map();
|
|
1372
|
+
const functionPrototypeMethodAssignments = new Map();
|
|
1373
|
+
const callableMethodTaints = {
|
|
1374
|
+
global: new Set(),
|
|
1375
|
+
own: new Map(),
|
|
1376
|
+
ownUnknown: new Map()
|
|
1377
|
+
};
|
|
1378
|
+
const emptySummaries = new Map(functions.map((fn) => [fn, { effects: 0, returns: new Set(), returnsUnknown: false }]));
|
|
1379
|
+
// Alias and mutation facts are monotone and whole-program. The first pass
|
|
1380
|
+
// discovers assignments; the second resolves shadows through those aliases
|
|
1381
|
+
// before any effect summary is trusted.
|
|
1382
|
+
for (let pass = 0; pass < 2; pass += 1) {
|
|
1383
|
+
for (const fn of functions) {
|
|
1384
|
+
analyzeFunction(fn, originalDefinition, {
|
|
1385
|
+
checker,
|
|
1386
|
+
sourceFile: fn.getSourceFile(),
|
|
1387
|
+
identity,
|
|
1388
|
+
summaries: emptySummaries,
|
|
1389
|
+
reads: null,
|
|
1390
|
+
entries: null,
|
|
1391
|
+
deferred: null,
|
|
1392
|
+
observedEffects: { value: 0 },
|
|
1393
|
+
returnedFunctions: null,
|
|
1394
|
+
returnedFunctionsUnknown: null,
|
|
1395
|
+
containerFunctions,
|
|
1396
|
+
functionAssignments,
|
|
1397
|
+
destructuredFunctionAssignments,
|
|
1398
|
+
functionPrototypeMethodAssignments,
|
|
1399
|
+
callableMethodTaints
|
|
1400
|
+
});
|
|
1401
|
+
}
|
|
1402
|
+
for (const file of implementationFiles) {
|
|
1403
|
+
analyzeStatements(file.statements, originalDefinition, {
|
|
1404
|
+
checker,
|
|
1405
|
+
sourceFile: file,
|
|
1406
|
+
identity,
|
|
1407
|
+
summaries: emptySummaries,
|
|
1408
|
+
reads: null,
|
|
1409
|
+
entries: null,
|
|
1410
|
+
deferred: null,
|
|
1411
|
+
observedEffects: { value: 0 },
|
|
1412
|
+
returnedFunctions: null,
|
|
1413
|
+
returnedFunctionsUnknown: null,
|
|
1414
|
+
containerFunctions,
|
|
1415
|
+
functionAssignments,
|
|
1416
|
+
destructuredFunctionAssignments,
|
|
1417
|
+
functionPrototypeMethodAssignments,
|
|
1418
|
+
callableMethodTaints
|
|
1419
|
+
});
|
|
1420
|
+
}
|
|
1421
|
+
}
|
|
1422
|
+
const summaries = new Map(functions.map((fn) => [fn, { effects: 0, returns: new Set(), returnsUnknown: false }]));
|
|
1423
|
+
for (;;) {
|
|
1424
|
+
let changed = false;
|
|
1425
|
+
for (const fn of functions) {
|
|
1426
|
+
const observedEffects = { value: 0 };
|
|
1427
|
+
const returnedFunctions = new Set();
|
|
1428
|
+
const returnedFunctionsUnknown = { value: false };
|
|
1429
|
+
const context = {
|
|
1430
|
+
checker,
|
|
1431
|
+
sourceFile: fn.getSourceFile(),
|
|
1432
|
+
identity,
|
|
1433
|
+
summaries,
|
|
1434
|
+
reads: null,
|
|
1435
|
+
entries: null,
|
|
1436
|
+
deferred: null,
|
|
1437
|
+
observedEffects,
|
|
1438
|
+
returnedFunctions,
|
|
1439
|
+
returnedFunctionsUnknown,
|
|
1440
|
+
containerFunctions,
|
|
1441
|
+
functionAssignments,
|
|
1442
|
+
destructuredFunctionAssignments,
|
|
1443
|
+
functionPrototypeMethodAssignments,
|
|
1444
|
+
callableMethodTaints
|
|
1445
|
+
};
|
|
1446
|
+
analyzeFunction(fn, originalDefinition, context);
|
|
1447
|
+
const previous = summaries.get(fn);
|
|
1448
|
+
const returnsChanged = previous === undefined ||
|
|
1449
|
+
previous.returns.size !== returnedFunctions.size ||
|
|
1450
|
+
[...returnedFunctions].some((returned) => !previous.returns.has(returned));
|
|
1451
|
+
if (previous?.effects !== observedEffects.value || previous.returnsUnknown !== returnedFunctionsUnknown.value || returnsChanged) {
|
|
1452
|
+
summaries.set(fn, { effects: observedEffects.value, returns: returnedFunctions, returnsUnknown: returnedFunctionsUnknown.value });
|
|
1453
|
+
changed = true;
|
|
1454
|
+
}
|
|
1455
|
+
}
|
|
1456
|
+
if (!changed)
|
|
1457
|
+
break;
|
|
1458
|
+
}
|
|
1459
|
+
const reads = new Map();
|
|
1460
|
+
for (const file of implementationFiles) {
|
|
1461
|
+
const entries = new Map();
|
|
1462
|
+
const deferred = new Set();
|
|
1463
|
+
const context = {
|
|
1464
|
+
checker,
|
|
1465
|
+
sourceFile: file,
|
|
1466
|
+
identity,
|
|
1467
|
+
summaries,
|
|
1468
|
+
reads,
|
|
1469
|
+
entries,
|
|
1470
|
+
deferred,
|
|
1471
|
+
observedEffects: { value: 0 },
|
|
1472
|
+
returnedFunctions: null,
|
|
1473
|
+
returnedFunctionsUnknown: null,
|
|
1474
|
+
containerFunctions,
|
|
1475
|
+
functionAssignments,
|
|
1476
|
+
destructuredFunctionAssignments,
|
|
1477
|
+
functionPrototypeMethodAssignments,
|
|
1478
|
+
callableMethodTaints
|
|
1479
|
+
};
|
|
1480
|
+
for (;;) {
|
|
1481
|
+
const beforeEntries = new Map(entries);
|
|
1482
|
+
const beforeDeferred = new Set(deferred);
|
|
1483
|
+
const moduleFlow = analyzeStatements(file.statements, originalDefinition, context);
|
|
1484
|
+
let deferredEntry = moduleFlow.normal;
|
|
1485
|
+
for (const [fn, entry] of [...entries]) {
|
|
1486
|
+
if (fn.getSourceFile() !== file)
|
|
1487
|
+
continue;
|
|
1488
|
+
deferredEntry = join(deferredEntry, allExits(analyzeFunction(fn, entry, context)));
|
|
1489
|
+
}
|
|
1490
|
+
for (const fn of deferred) {
|
|
1491
|
+
if (fn.getSourceFile() === file)
|
|
1492
|
+
entries.set(fn, join(entries.get(fn) ?? unreachable, deferredEntry));
|
|
1493
|
+
}
|
|
1494
|
+
const entriesChanged = entries.size !== beforeEntries.size || [...entries].some(([fn, state]) => beforeEntries.get(fn) !== state);
|
|
1495
|
+
const deferredChanged = deferred.size !== beforeDeferred.size || [...deferred].some((fn) => !beforeDeferred.has(fn));
|
|
1496
|
+
if (!entriesChanged && !deferredChanged)
|
|
1497
|
+
break;
|
|
1498
|
+
}
|
|
1499
|
+
}
|
|
1500
|
+
const statusOf = (expression, seen = new Set()) => {
|
|
1501
|
+
const node = unwrapExpression(expression);
|
|
1502
|
+
if (!ts.isIdentifier(node))
|
|
1503
|
+
return 'ordinary';
|
|
1504
|
+
const identityAtNode = identity.classify(node);
|
|
1505
|
+
if (identityAtNode.kind === 'provenance-failure')
|
|
1506
|
+
return 'provenance-failure';
|
|
1507
|
+
if (identityAtNode.kind === 'wrapper') {
|
|
1508
|
+
if (identityAtNode.global !== 'require')
|
|
1509
|
+
return 'ordinary';
|
|
1510
|
+
const definitions = reads.get(node) ?? unreachable;
|
|
1511
|
+
if (definitions === originalDefinition)
|
|
1512
|
+
return 'static';
|
|
1513
|
+
return definitions === unreachable ? 'ordinary' : 'possibly-reassigned';
|
|
1514
|
+
}
|
|
1515
|
+
const symbol = resolvedSymbolAt(checker, node);
|
|
1516
|
+
if (!symbol || seen.has(symbol))
|
|
1517
|
+
return 'ordinary';
|
|
1518
|
+
seen.add(symbol);
|
|
1519
|
+
const declaration = symbol.valueDeclaration;
|
|
1520
|
+
if (!declaration || !ts.isVariableDeclaration(declaration) || !declaration.initializer)
|
|
1521
|
+
return 'ordinary';
|
|
1522
|
+
if (!ts.isVariableDeclarationList(declaration.parent) || (declaration.parent.flags & ts.NodeFlags.Const) === 0)
|
|
1523
|
+
return 'ordinary';
|
|
1524
|
+
return statusOf(declaration.initializer, seen);
|
|
1525
|
+
};
|
|
1526
|
+
return { statusOf };
|
|
1527
|
+
};
|