From c09bfff04cbee6e7810010d6401f0adfe81243c7 Mon Sep 17 00:00:00 2001 From: Joe Savona Date: Tue, 1 Aug 2023 13:55:17 -0700 Subject: [PATCH] [rust] Tests for HermesParser->ESTree conversion --- compiler/forget/Cargo.lock | 2 + .../crates/forget_estree/src/generated.rs | 1553 ++++++++++- ...e__tests__fixtures@for-statement.json.snap | 9 + ...t_estree__tests__fixtures@import.json.snap | 1 + ...t_estree__tests__fixtures@simple.json.snap | 4 + ...get_estree__tests__fixtures@test.json.snap | 1 + .../forget/crates/forget_estree/src/visit.rs | 45 +- .../forget_estree_codegen/src/codegen.rs | 28 +- .../forget_estree_codegen/src/ecmascript.json | 141 +- .../crates/forget_estree_swc/src/lib.rs | 28 +- .../crates/forget_hermes_parser/Cargo.toml | 2 + .../forget_hermes_parser/src/generated.rs | 1083 +++++++- .../src/generated_extension.rs | 13 +- ...s-capture-in-method-receiver-and-mutate.js | 11 + .../alias-capture-in-method-receiver.js | 10 + .../tests/fixtures/alias-computed-load.js | 8 + .../alias-nested-member-path-mutate.js | 9 + .../fixtures/alias-nested-member-path.js | 8 + .../tests/fixtures/alias-while.js | 18 + ...llocating-primitive-as-dep-nested-scope.js | 11 + .../fixtures/allocating-primitive-as-dep.js | 8 + .../fixtures/allow-passing-refs-as-props.js | 4 + .../tests/fixtures/array-access-assignment.js | 8 + .../tests/fixtures/array-at-closure.js | 9 + .../tests/fixtures/array-at-effect.js | 9 + .../fixtures/array-at-mutate-after-capture.js | 10 + .../tests/fixtures/array-expression-spread.js | 4 + .../tests/fixtures/array-join.js | 6 + .../tests/fixtures/array-map-frozen-array.js | 6 + ...array-map-mutable-array-mutating-lambda.js | 8 + .../tests/fixtures/array-pattern-params.js | 5 + .../tests/fixtures/array-properties.js | 6 + .../tests/fixtures/array-property-call.js | 7 + .../tests/fixtures/array-push-effect.js | 11 + .../arrow-function-expr-gating-test.js | 4 + .../assignment-expression-computed.js | 7 + .../assignment-expression-nested-path.js | 6 + .../tests/fixtures/assignment-in-nested-if.js | 11 + ...ignment-variations-complex-lvalue-array.js | 6 + .../assignment-variations-complex-lvalue.js | 6 + .../tests/fixtures/assignment-variations.js | 7 + .../fixtures/await-side-effecting-promise.js | 5 + .../tests/fixtures/await.js | 4 + .../fixtures/babel-existing-react-import.js | 15 + ...babel-existing-react-kitchensink-import.js | 16 + .../bug.useMemo-deps-array-not-cleared.js | 9 + .../tests/fixtures/bug_object-pattern.js | 5 + ...iltin-jsx-tag-lowered-between-mutations.js | 4 + .../tests/fixtures/call-args-assignment.js | 5 + .../call-args-destructuring-assignment.js | 5 + .../tests/fixtures/call-spread.js | 4 + .../call-with-independently-memoizable-arg.js | 9 + .../tests/fixtures/call.js | 10 + .../fixtures/capture-indirect-mutate-alias.js | 11 + .../tests/fixtures/capture-param-mutate.js | 37 + .../fixtures/capture_mutate-across-fns.js | 9 + .../fixtures/capturing-arrow-function-1.js | 7 + .../capturing-fun-alias-captured-mutate-2.js | 11 + ...pturing-fun-alias-captured-mutate-arr-2.js | 11 + ...apturing-func-alias-captured-mutate-arr.js | 11 + .../capturing-func-alias-captured-mutate.js | 11 + .../capturing-func-alias-computed-mutate.js | 9 + .../fixtures/capturing-func-alias-mutate.js | 9 + ...ing-func-alias-receiver-computed-mutate.js | 10 + .../capturing-func-alias-receiver-mutate.js | 10 + .../tests/fixtures/capturing-func-mutate-2.js | 10 + .../tests/fixtures/capturing-func-mutate-3.js | 9 + .../fixtures/capturing-func-mutate-nested.js | 8 + .../tests/fixtures/capturing-func-mutate.js | 10 + .../fixtures/capturing-func-simple-alias.js | 9 + .../tests/fixtures/capturing-function-1.js | 7 + ...apturing-function-alias-computed-load-2.js | 9 + ...apturing-function-alias-computed-load-3.js | 11 + ...apturing-function-alias-computed-load-4.js | 9 + .../capturing-function-alias-computed-load.js | 9 + ...ring-function-capture-ref-before-rename.js | 14 + ...ing-function-conditional-capture-mutate.js | 14 + .../tests/fixtures/capturing-function-decl.js | 8 + ...apturing-function-member-expr-arguments.js | 10 + .../capturing-function-member-expr-call.js | 11 + .../capturing-function-renamed-ref.js | 10 + .../capturing-function-runs-inference.js | 5 + .../capturing-function-shadow-captured.js | 8 + .../capturing-function-skip-computed-path.js | 4 + .../capturing-function-within-block.js | 10 + .../tests/fixtures/capturing-member-expr.js | 7 + .../fixtures/capturing-nested-member-call.js | 7 + ...uring-nested-member-expr-in-nested-func.js | 9 + .../fixtures/capturing-nested-member-expr.js | 7 + .../capturing-reference-changes-type.js | 9 + .../capturing-variable-in-nested-block.js | 9 + .../capturing-variable-in-nested-function.js | 9 + .../chained-assignment-context-variable.js | 9 + .../chained-assignment-expressions.js | 8 + .../codegen-emit-imports-same-source.js | 5 + .../fixtures/codegen-emit-make-read-only.js | 11 + .../codegen-instrument-forget-gating-test.js | 15 + .../codegen-instrument-forget-test.js | 15 + .../tests/fixtures/complex-while.js | 10 + .../tests/fixtures/component.js | 26 + .../computed-call-evaluation-order.js | 14 + .../tests/fixtures/computed-call-spread.js | 4 + .../computed-load-primitive-as-dependency.js | 9 + .../tests/fixtures/computed-store-alias.js | 7 + .../tests/fixtures/concise-arrow-expr.js | 5 + .../cond-deps-conditional-member-expr.js | 9 + .../fixtures/conditional-break-labeled.js | 15 + .../tests/fixtures/conditional-break.js | 53 + .../tests/fixtures/conditional-on-mutable.js | 26 + .../conditional-set-state-in-render.js | 14 + .../tests/fixtures/console-readonly.js | 11 + ...agation-into-function-expression-global.js | 8 + ...tion-into-function-expression-primitive.js | 8 + .../tests/fixtures/constant-computed.js | 7 + .../fixtures/constant-propagation-for.js | 7 + ...t-propagation-into-function-expressions.js | 7 + .../fixtures/constant-propagation-phi.js | 13 + .../fixtures/constant-propagation-while.js | 8 + .../tests/fixtures/constant-propagation.js | 18 + .../tests/fixtures/constructor.js | 10 + ...t-variable-reassigned-outside-of-lambda.js | 9 + .../tests/fixtures/controlled-input.js | 5 + .../tests/fixtures/dce-loop.js | 9 + .../tests/fixtures/debugger-memoized.js | 6 + .../tests/fixtures/debugger.js | 11 + .../declare-reassign-variable-in-closure.js | 9 + ...assign-variable-in-function-declaration.js | 8 + .../fixtures/delete-computed-property.js | 6 + .../tests/fixtures/delete-property.js | 5 + .../tests/fixtures/dependencies-outputs.js | 14 + .../tests/fixtures/dependencies.js | 15 + .../fixtures/destructure-capture-global.js | 5 + .../destructure-direct-reassignment.js | 7 + .../fixtures/destructuring-array-default.js | 4 + .../destructuring-array-param-default.js | 3 + .../destructuring-assignment-array-default.js | 9 + .../fixtures/destructuring-assignment.js | 18 + ...-scope-and-local-variables-with-default.js | 20 + ...ing-mixed-scope-declarations-and-locals.js | 20 + .../fixtures/destructuring-object-default.js | 4 + .../destructuring-object-param-default.js | 3 + .../destructuring-property-inference.js | 7 + .../tests/fixtures/destructuring.js | 19 + .../tests/fixtures/disable-jsx-memoization.js | 12 + .../tests/fixtures/do-while-break.js | 6 + .../tests/fixtures/do-while-compound-test.js | 9 + .../fixtures/do-while-conditional-break.js | 10 + .../tests/fixtures/do-while-continue.js | 13 + .../do-while-early-unconditional-break.js | 8 + .../tests/fixtures/do-while-simple.js | 9 + .../tests/fixtures/dominator.js | 33 + .../tests/fixtures/early-return.js | 8 + ...rror._todo.computed-lval-in-destructure.js | 6 + ...i-arrow-expr-export-default-gating-test.js | 9 + ...r.babel-existing-react-namespace-import.js | 15 + ...ot-all-mutable-range-extensions-are-bad.js | 24 + ...ll-args-destructuring-asignment-complex.js | 5 + ...or.codegen-error-on-conflicting-imports.js | 6 + .../error.hoisted-function-declaration.js | 8 + .../error.hooks-with-React-namespace.js | 4 + .../error.invalid-access-ref-during-render.js | 6 + .../error.invalid-array-push-frozen.js | 6 + .../error.invalid-assign-hook-to-local.js | 5 + ...rror.invalid-capture-func-passed-to-jsx.js | 11 + ....invalid-computed-store-to-frozen-value.js | 7 + ...elete-computed-property-of-frozen-value.js | 7 + ...invalid-delete-property-of-frozen-value.js | 7 + ...nvalid-destructure-assignment-to-global.js | 4 + ...d-destructure-to-local-global-variables.js | 6 + ...lid-freeze-conditionally-mutable-lambda.js | 16 + ...alid-freeze-mutable-lambda-mutate-local.js | 9 + ...id-freeze-mutable-lambda-reassign-local.js | 7 + ...tion-expression-mutates-immutable-value.js | 9 + ...ror.invalid-mutate-after-aliased-freeze.js | 16 + .../error.invalid-mutate-after-freeze.js | 10 + .../error.invalid-pass-hook-as-call-arg.js | 3 + .../error.invalid-pass-hook-as-prop.js | 3 + .../error.invalid-pass-ref-to-function.js | 5 + ....invalid-property-store-to-frozen-value.js | 7 + ...d-ref-in-callback-invoked-during-render.js | 9 + .../error.invalid-ref-value-as-props.js | 4 + ....invalid-set-and-read-ref-during-render.js | 5 + .../error.invalid-sketchy-code-use-forget.js | 7 + .../error.invalid-ternary-with-hook-values.js | 4 + ...valid-unconditional-set-state-in-render.js | 9 + ...-use-ref-added-to-dep-without-type-info.js | 12 + .../error.invalid-useMemo-async-callback.js | 6 + .../error.invalid-useMemo-callback-args.js | 4 + .../error.mutate-captured-arg-separately.js | 10 + ...utate-global-increment-op-invalid-react.js | 6 + .../fixtures/error.reassignment-to-global.js | 5 + .../tests/fixtures/error.todo-kitchensink.js | 70 + ...ror.todo-unconditional-set-state-lambda.js | 12 + ...o.destructure-assignment-to-context-var.js | 9 + .../error.useMemo-callback-generator.js | 9 + .../error.while-with-assignment-in-test.js | 10 + ...cape-analysis-destructured-rest-element.js | 7 + .../fixtures/escape-analysis-jsx-child.js | 11 + .../tests/fixtures/escape-analysis-logical.js | 8 + ...aping-interleaved-allocating-dependency.js | 15 + ...nterleaved-allocating-nested-dependency.js | 24 + ...caping-interleaved-primitive-dependency.js | 17 + .../escape-analysis-not-conditional-test.js | 5 + .../fixtures/escape-analysis-not-if-test.js | 10 + .../escape-analysis-not-switch-case.js | 10 + .../escape-analysis-not-switch-test.js | 10 + .../expression-with-assignment-dynamic.js | 4 + .../fixtures/expression-with-assignment.js | 4 + .../tests/fixtures/extend-scopes-if.js | 14 + .../fixtures/fbt-call-complex-param-value.js | 9 + .../tests/fixtures/fbt-call.js | 9 + .../fbt-params-complex-param-value.js | 9 + .../tests/fixtures/fbt-params.js | 9 + .../fbt-template-string-same-scope.js | 17 + .../for-empty-update-with-continue.js | 9 + .../tests/fixtures/for-empty-update.js | 10 + .../tests/fixtures/for-logical.js | 12 + .../tests/fixtures/for-of-break.js | 7 + .../fixtures/for-of-conditional-break.js | 10 + .../tests/fixtures/for-of-continue.js | 11 + .../tests/fixtures/for-of-destructure.js | 8 + .../tests/fixtures/for-of-mutate.js | 8 + .../tests/fixtures/for-of-simple.js | 8 + .../tests/fixtures/for-return.js | 5 + .../tests/fixtures/frozen-after-alias.js | 10 + .../fixtures/function-declaration-reassign.js | 7 + .../function-declaration-redeclare.js | 7 + .../fixtures/function-declaration-simple.js | 8 + ...ression-captures-value-later-frozen-jsx.js | 12 + ...ression-maybe-mutates-hook-return-value.js | 12 + ...tion-expression-with-store-to-parameter.js | 9 + .../function-param-assignment-pattern.js | 3 + .../gating-test-export-default-function.js | 14 + ...gating-test-export-function-and-default.js | 14 + .../fixtures/gating-test-export-function.js | 14 + .../tests/fixtures/gating-test.js | 14 + ...lobal-jsx-tag-lowered-between-mutations.js | 15 + .../tests/fixtures/globals-Boolean.js | 5 + .../tests/fixtures/globals-Number.js | 5 + .../tests/fixtures/globals-String.js | 5 + .../tests/fixtures/holey-array-expr.js | 4 + .../fixtures/holey-array-pattern-dce-2.js | 4 + .../tests/fixtures/holey-array-pattern-dce.js | 4 + .../tests/fixtures/holey-array.js | 5 + .../tests/fixtures/hook-call.js | 14 + .../hook-inside-logical-expression.js | 4 + .../tests/fixtures/hooks-freeze-arguments.js | 10 + ...hooks-freeze-possibly-mutable-arguments.js | 17 + .../tests/fixtures/immutable-hooks.js | 9 + .../inadvertent-mutability-readonly-class.js | 15 + .../inadvertent-mutability-readonly-lambda.js | 13 + .../tests/fixtures/independent-across-if.js | 28 + .../tests/fixtures/independent.js | 19 + .../independently-memoize-object-property.js | 7 + .../tests/fixtures/infer-computed-delete.js | 6 + .../tests/fixtures/infer-global-object.js | 13 + .../tests/fixtures/infer-phi-primitive.js | 11 + .../tests/fixtures/infer-property-delete.js | 5 + .../infer-types-through-type-cast.flow.js | 9 + ...lue-not-promoted-to-outer-scope-dynamic.js | 14 + ...alue-not-promoted-to-outer-scope-static.js | 11 + .../fixtures/interdependent-across-if.js | 22 + .../tests/fixtures/interdependent.js | 19 + .../tests/fixtures/inverted-if-else.js | 11 + .../tests/fixtures/inverted-if.js | 11 + .../tests/fixtures/issue852.js | 6 + .../issue933-disjoint-set-infinite-loop.js | 8 + .../tests/fixtures/jsx-empty-expression.js | 8 + .../tests/fixtures/jsx-fragment.js | 10 + .../jsx-member-expression-tag-grouping.js | 4 + .../tests/fixtures/jsx-member-expression.js | 7 + .../tests/fixtures/jsx-namespaced-name.js | 3 + .../tests/fixtures/jsx-spread.js | 5 + .../jsx-tag-evaluation-order-non-global.js | 13 + .../fixtures/jsx-tag-evaluation-order.js | 9 + .../fixtures/lambda-capture-returned-alias.js | 18 + .../fixtures/lambda-mutate-shadowed-object.js | 11 + ...lambda-mutated-non-reactive-to-reactive.js | 7 + .../lambda-mutated-ref-non-reactive.js | 8 + .../fixtures/lambda-reassign-primitive.js | 14 + .../lambda-reassign-shadowed-primitive.js | 11 + .../tests/fixtures/lambda-with-fbt.js | 30 + .../fixtures/logical-expression-object.js | 10 + .../tests/fixtures/logical-expression.js | 5 + .../tests/fixtures/method-call-computed.js | 13 + .../tests/fixtures/method-call-fn-call.js | 10 + .../tests/fixtures/method-call.js | 9 + .../multi-arrow-expr-export-gating-test.js | 9 + .../fixtures/multi-arrow-expr-gating-test.js | 11 + .../tests/fixtures/mutable-lifetime-loops.js | 34 + .../mutable-lifetime-with-aliasing.js | 30 + .../tests/fixtures/mutable-liverange-loop.js | 29 + .../nested-function-shadowed-identifiers.js | 10 + .../fixtures/nested-optional-member-expr.js | 6 + .../tests/fixtures/nested-scopes-hook-call.js | 7 + .../tests/fixtures/new-spread.js | 4 + ...noptional-load-from-optional-memberexpr.js | 8 + .../fixtures/obj-literal-cached-in-if-else.js | 10 + .../obj-literal-mutated-after-if-else.js | 11 + .../obj-mutated-after-if-else-with-alias.js | 13 + .../fixtures/obj-mutated-after-if-else.js | 11 + ...mutated-after-nested-if-else-with-alias.js | 19 + .../object-computed-access-assignment.js | 5 + .../object-expression-string-literal-key.js | 4 + .../fixtures/object-literal-spread-element.js | 4 + .../tests/fixtures/object-pattern-params.js | 5 + .../tests/fixtures/object-properties.js | 7 + .../tests/fixtures/optional-call-chained.js | 3 + .../tests/fixtures/optional-call-logical.js | 4 + .../tests/fixtures/optional-call-simple.js | 3 + ...-call-with-independently-memoizable-arg.js | 13 + ...tional-call-with-optional-property-load.js | 3 + .../tests/fixtures/optional-call.js | 6 + .../fixtures/optional-computed-load-static.js | 4 + .../optional-computed-member-expression.js | 4 + ...onal-member-expression-call-as-property.js | 4 + .../optional-member-expression-chain.js | 7 + ...n-with-optional-member-expr-as-property.js | 4 + .../fixtures/optional-member-expression.js | 7 + .../tests/fixtures/optional-method-call.js | 6 + .../fixtures/optional-receiver-method-call.js | 6 + .../optional-receiver-optional-method.js | 6 + ...rlapping-scopes-interleaved-by-terminal.js | 10 + .../overlapping-scopes-interleaved.js | 6 + .../fixtures/overlapping-scopes-shadowed.js | 6 + ...erlapping-scopes-shadowing-within-block.js | 12 + .../fixtures/overlapping-scopes-while.js | 8 + .../overlapping-scopes-within-block.js | 12 + .../tests/fixtures/primitive-alias-mutate.js | 11 + .../fixtures/primitive-as-dep-nested-scope.js | 12 + .../tests/fixtures/primitive-as-dep.js | 9 + .../fixtures/prop-capturing-function-1.js | 7 + .../tests/fixtures/property-assignment.js | 8 + .../property-call-evaluation-order.js | 13 + .../tests/fixtures/property-call-spread.js | 4 + ...tional-properties-inside-optional-chain.js | 3 + .../tests/fixtures/reactive-scope-grouping.js | 9 + .../tests/fixtures/reactive-scopes-if.js | 11 + .../tests/fixtures/reactive-scopes.js | 10 + ...ctivity-analysis-interleaved-reactivity.js | 19 + ...-reactive-via-mutation-of-computed-load.js | 8 + ...-reactive-via-mutation-of-property-load.js | 8 + .../fixtures/reassign-object-in-context.js | 8 + .../fixtures/reassign-primitive-in-context.js | 8 + ...ned-phi-in-returned-function-expression.js | 11 + .../fixtures/reassignment-conditional.js | 13 + .../fixtures/reassignment-separate-scopes.js | 25 + .../tests/fixtures/reassignment.js | 12 + .../tests/fixtures/recursive-function-expr.js | 3 + .../reduce-reactive-cond-deps-cfg-condexpr.js | 8 + .../reduce-reactive-cond-deps-cfg-ifelse.js | 13 + ...ive-cond-deps-cfg-nested-ifelse-missing.js | 14 + ...ce-reactive-cond-deps-cfg-nested-ifelse.js | 19 + ...ctive-cond-deps-cfg-switch-missing-case.js | 18 + ...ve-cond-deps-cfg-switch-missing-default.js | 15 + .../reduce-reactive-cond-deps-cfg-switch.js | 18 + .../reduce-reactive-cond-deps-no-uncond.js | 10 + ...educe-reactive-cond-deps-promote-uncond.js | 11 + ...educe-reactive-cond-deps-subpath-order1.js | 13 + ...educe-reactive-cond-deps-subpath-order2.js | 13 + ...uce-reactive-cond-deps-superpath-order1.js | 12 + ...uce-reactive-cond-deps-superpath-order2.js | 12 + .../reduce-reactive-cond-memberexpr-join.js | 17 + ...dependencies-optional-member-expression.js | 6 + .../reduce-reactive-deps-cond-scope.js | 26 + ...ctive-deps-join-uncond-scopes-cond-deps.js | 26 + ...ctive-uncond-deps-nonoverlap-descendant.js | 9 + ...-reactive-uncond-deps-nonoverlap-direct.js | 8 + ...reactive-uncond-deps-overlap-descendant.js | 9 + ...uce-reactive-uncond-deps-overlap-direct.js | 9 + ...uce-reactive-uncond-deps-subpath-order1.js | 9 + ...uce-reactive-uncond-deps-subpath-order2.js | 9 + ...uce-reactive-uncond-deps-subpath-order3.js | 9 + .../ref-current-aliased-no-added-to-dep.js | 10 + .../ref-current-aliased-not-added-to-dep-2.js | 8 + .../ref-current-field-not-added-to-dep.js | 9 + .../ref-current-not-added-to-dep-2.js | 7 + .../fixtures/ref-current-not-added-to-dep.js | 8 + ...-current-optional-field-no-added-to-dep.js | 8 + .../ref-current-write-not-added-to-dep.js | 8 + .../tests/fixtures/ref-in-effect.js | 11 + .../tests/fixtures/regexp-literal.js | 10 + .../remove-memoization-kitchen-sink.js | 12 + ...ssign-to-variable-without-mutable-range.js | 11 + .../repro-scope-missing-mutable-range.js | 10 + .../tests/fixtures/repro.js | 14 + .../tests/fixtures/return-conditional.js | 7 + .../tests/fixtures/return-undefined.js | 6 + .../tests/fixtures/reverse-postorder.js | 27 + ...iable-as-dep-and-redeclare-maybe-frozen.js | 35 + .../same-variable-as-dep-and-redeclare.js | 35 + .../tests/fixtures/sequence-expression.js | 9 + ...onstant-progagatable-if-test-conditions.js | 34 + .../tests/fixtures/simple-alias.js | 11 + .../tests/fixtures/simple-function-1.js | 6 + .../tests/fixtures/simple-scope.js | 4 + .../tests/fixtures/simple.js | 6 + .../fixtures/sketchy-code-exhaustive-deps.js | 11 + .../fixtures/sketchy-code-rules-of-hooks.js | 6 + .../tests/fixtures/ssa-arrayexpression.js | 6 + .../tests/fixtures/ssa-call-jsx-2.js | 13 + .../tests/fixtures/ssa-call-jsx.js | 10 + .../fixtures/ssa-cascading-eliminated-phis.js | 15 + .../tests/fixtures/ssa-complex-multiple-if.js | 12 + .../tests/fixtures/ssa-complex-single-if.js | 9 + .../tests/fixtures/ssa-for-of.js | 10 + .../tests/fixtures/ssa-for-trivial-update.js | 7 + .../tests/fixtures/ssa-for.js | 7 + .../tests/fixtures/ssa-if-else.js | 10 + .../tests/fixtures/ssa-leave-case.js | 14 + .../tests/fixtures/ssa-multiple-phis.js | 19 + .../fixtures/ssa-nested-loops-no-reassign.js | 12 + .../tests/fixtures/ssa-nested-partial-phi.js | 10 + .../ssa-nested-partial-reassignment.js | 11 + .../tests/fixtures/ssa-newexpression.js | 8 + .../fixtures/ssa-non-empty-initializer.js | 9 + .../fixtures/ssa-objectexpression-phi.js | 13 + .../tests/fixtures/ssa-objectexpression.js | 6 + .../ssa-property-alias-alias-mutate-if.js | 13 + .../tests/fixtures/ssa-property-alias-if.js | 11 + .../fixtures/ssa-property-alias-mutate-if.js | 12 + .../ssa-property-alias-mutate-inside-if.js | 12 + .../fixtures/ssa-property-alias-mutate.js | 10 + .../tests/fixtures/ssa-property-call.js | 6 + .../tests/fixtures/ssa-property-mutate-2.js | 7 + .../fixtures/ssa-property-mutate-alias.js | 10 + .../tests/fixtures/ssa-property-mutate.js | 7 + .../tests/fixtures/ssa-property.js | 6 + .../tests/fixtures/ssa-reassign-in-rval.js | 6 + .../tests/fixtures/ssa-reassign.js | 7 + ...aming-ternary-destruction-with-mutation.js | 7 + .../ssa-renaming-ternary-destruction.js | 6 + .../ssa-renaming-ternary-with-mutation.js | 7 + .../tests/fixtures/ssa-renaming-ternary.js | 6 + ...ing-unconditional-ternary-with-mutation.js | 9 + .../ssa-renaming-unconditional-ternary.js | 8 + ...sa-renaming-unconditional-with-mutation.js | 15 + ...enaming-via-destructuring-with-mutation.js | 11 + .../ssa-renaming-via-destructuring.js | 10 + .../fixtures/ssa-renaming-with-mutation.js | 11 + .../tests/fixtures/ssa-renaming.js | 10 + .../tests/fixtures/ssa-return.js | 8 + .../tests/fixtures/ssa-shadowing.js | 12 + .../tests/fixtures/ssa-sibling-phis.js | 19 + .../tests/fixtures/ssa-simple-phi.js | 11 + .../tests/fixtures/ssa-simple.js | 4 + .../tests/fixtures/ssa-single-if.js | 8 + .../tests/fixtures/ssa-switch.js | 19 + .../tests/fixtures/ssa-throw.js | 7 + .../tests/fixtures/ssa-while-no-reassign.js | 8 + .../tests/fixtures/ssa-while.js | 8 + .../tests/fixtures/store-via-call.js | 6 + .../tests/fixtures/store-via-new.js | 6 + .../switch-global-propertyload-case-test.js | 10 + .../fixtures/switch-non-final-default.js | 23 + .../tests/fixtures/switch-with-fallthrough.js | 27 + .../tests/fixtures/switch.js | 18 + .../tests/fixtures/tagged-template-in-hook.js | 4 + .../tests/fixtures/tagged-template-literal.js | 16 + .../tests/fixtures/template-literal.js | 10 + .../temporary-accessed-outside-scope.js | 5 + .../temporary-at-start-of-value-block.js | 5 + ...ry-property-load-accessed-outside-scope.js | 5 + .../fixtures/ternary-assignment-expression.js | 5 + .../tests/fixtures/ternary-expression.js | 5 + .../tests/fixtures/timers.js | 10 + ...-expression-captures-value-later-frozen.js | 14 + .../todo.unnecessary-lambda-memoization.js | 14 + .../tests/fixtures/transitive-alias-fields.js | 12 + .../tests/fixtures/trivial.js | 3 + .../type-args-test-binary-operator.js | 5 + .../tests/fixtures/type-binary-operator.js | 7 + .../fixtures/type-cast-expression.flow.js | 9 + .../tests/fixtures/type-field-load.js | 5 + .../type-test-field-load-binary-op.js | 11 + .../tests/fixtures/type-test-field-store.js | 7 + .../tests/fixtures/type-test-polymorphic.js | 14 + .../tests/fixtures/type-test-primitive.js | 6 + .../type-test-return-type-inference.js | 10 + .../tests/fixtures/unary-expr.js | 11 + .../fixtures/unconditional-break-label.js | 8 + ...itialized-declaration-in-reactive-scope.js | 6 + .../fixtures/unknown-hooks-do-not-assert.js | 11 + .../fixtures/unused-array-middle-element.js | 4 + .../fixtures/unused-array-rest-element.js | 4 + .../tests/fixtures/unused-conditional.js | 5 + .../unused-logical-assigned-to-variable.js | 7 + .../tests/fixtures/unused-logical.js | 5 + .../unused-object-element-with-rest.js | 5 + .../tests/fixtures/unused-object-element.js | 4 + ...ed-optional-method-assigned-to-variable.js | 6 + .../unused-ternary-assigned-to-variable.js | 6 + .../tests/fixtures/update-expression.js | 6 + .../tests/fixtures/use-callback-simple.js | 6 + .../tests/fixtures/useEffect-arg-memoized.js | 16 + .../fixtures/useEffect-nested-lambdas.js | 22 + .../useMemo-if-else-multiple-return.js | 9 + .../useMemo-independently-memoizeable.js | 9 + .../fixtures/useMemo-inlining-block-return.js | 8 + .../tests/fixtures/useMemo-inverted-if.js | 12 + ...-labeled-statement-unconditional-return.js | 8 + .../tests/fixtures/useMemo-logical.js | 4 + .../fixtures/useMemo-multiple-if-else.js | 14 + .../tests/fixtures/useMemo-named-function.js | 4 + .../tests/fixtures/useMemo-nested-ifs.js | 9 + .../tests/fixtures/useMemo-return-empty.js | 6 + .../tests/fixtures/useMemo-simple.js | 4 + .../fixtures/useMemo-switch-no-fallthrough.js | 13 + .../tests/fixtures/useMemo-switch-return.js | 19 + .../tests/fixtures/while-break.js | 6 + .../fixtures/while-conditional-continue.js | 10 + .../tests/fixtures/while-logical.js | 7 + .../tests/fixtures/while-property.js | 7 + .../forget_hermes_parser/tests/parser_test.rs | 17 + ...ture-in-method-receiver-and-mutate.js.snap | 288 ++ ...s@alias-capture-in-method-receiver.js.snap | 248 ++ ...test__fixtures@alias-computed-load.js.snap | 316 +++ ...es@alias-nested-member-path-mutate.js.snap | 388 +++ ..._fixtures@alias-nested-member-path.js.snap | 310 +++ .../parser_test__fixtures@alias-while.js.snap | 560 ++++ ...ting-primitive-as-dep-nested-scope.js.snap | 377 +++ ...xtures@allocating-primitive-as-dep.js.snap | 209 ++ ...xtures@allow-passing-refs-as-props.js.snap | 201 ++ ...__fixtures@array-access-assignment.js.snap | 482 ++++ ...er_test__fixtures@array-at-closure.js.snap | 410 +++ ...ser_test__fixtures@array-at-effect.js.snap | 299 +++ ...ures@array-at-mutate-after-capture.js.snap | 347 +++ ...__fixtures@array-expression-spread.js.snap | 228 ++ .../parser_test__fixtures@array-join.js.snap | 331 +++ ...t__fixtures@array-map-frozen-array.js.snap | 329 +++ ...-map-mutable-array-mutating-lambda.js.snap | 332 +++ ...est__fixtures@array-pattern-params.js.snap | 272 ++ ...er_test__fixtures@array-properties.js.snap | 460 ++++ ...test__fixtures@array-property-call.js.snap | 468 ++++ ...r_test__fixtures@array-push-effect.js.snap | 427 +++ ...es@arrow-function-expr-gating-test.js.snap | 191 ++ ...res@assignment-expression-computed.js.snap | 309 +++ ...@assignment-expression-nested-path.js.snap | 420 +++ ...__fixtures@assignment-in-nested-if.js.snap | 269 ++ ...nt-variations-complex-lvalue-array.js.snap | 281 ++ ...signment-variations-complex-lvalue.js.snap | 389 +++ ...st__fixtures@assignment-variations.js.snap | 249 ++ ...tures@await-side-effecting-promise.js.snap | 204 ++ .../parser_test__fixtures@await.js.snap | 248 ++ ...xtures@babel-existing-react-import.js.snap | 718 +++++ ...-existing-react-kitchensink-import.js.snap | 756 ++++++ ...bug.useMemo-deps-array-not-cleared.js.snap | 323 +++ ..._test__fixtures@bug_object-pattern.js.snap | 230 ++ ...-jsx-tag-lowered-between-mutations.js.snap | 211 ++ ...est__fixtures@call-args-assignment.js.snap | 224 ++ ...call-args-destructuring-assignment.js.snap | 234 ++ .../parser_test__fixtures@call-spread.js.snap | 220 ++ ...-with-independently-memoizable-arg.js.snap | 351 +++ .../parser_test__fixtures@call.js.snap | 478 ++++ ...ures@capture-indirect-mutate-alias.js.snap | 352 +++ ...est__fixtures@capture-param-mutate.js.snap | 1381 ++++++++++ ...fixtures@capture_mutate-across-fns.js.snap | 311 +++ ...ixtures@capturing-arrow-function-1.js.snap | 278 ++ ...turing-fun-alias-captured-mutate-2.js.snap | 499 ++++ ...ng-fun-alias-captured-mutate-arr-2.js.snap | 477 ++++ ...ing-func-alias-captured-mutate-arr.js.snap | 477 ++++ ...pturing-func-alias-captured-mutate.js.snap | 499 ++++ ...pturing-func-alias-computed-mutate.js.snap | 343 +++ ...xtures@capturing-func-alias-mutate.js.snap | 344 +++ ...unc-alias-receiver-computed-mutate.js.snap | 383 +++ ...pturing-func-alias-receiver-mutate.js.snap | 384 +++ ...__fixtures@capturing-func-mutate-2.js.snap | 425 +++ ...__fixtures@capturing-func-mutate-3.js.snap | 396 +++ ...tures@capturing-func-mutate-nested.js.snap | 355 +++ ...st__fixtures@capturing-func-mutate.js.snap | 464 ++++ ...xtures@capturing-func-simple-alias.js.snap | 325 +++ ...est__fixtures@capturing-function-1.js.snap | 277 ++ ...ing-function-alias-computed-load-2.js.snap | 300 +++ ...ing-function-alias-computed-load-3.js.snap | 434 +++ ...ing-function-alias-computed-load-4.js.snap | 319 +++ ...uring-function-alias-computed-load.js.snap | 282 ++ ...function-capture-ref-before-rename.js.snap | 486 ++++ ...unction-conditional-capture-mutate.js.snap | 343 +++ ...__fixtures@capturing-function-decl.js.snap | 286 ++ ...ing-function-member-expr-arguments.js.snap | 318 +++ ...apturing-function-member-expr-call.js.snap | 459 ++++ ...res@capturing-function-renamed-ref.js.snap | 341 +++ ...@capturing-function-runs-inference.js.snap | 291 ++ ...capturing-function-shadow-captured.js.snap | 289 ++ ...turing-function-skip-computed-path.js.snap | 282 ++ ...es@capturing-function-within-block.js.snap | 319 +++ ...st__fixtures@capturing-member-expr.js.snap | 296 +++ ...tures@capturing-nested-member-call.js.snap | 317 +++ ...-nested-member-expr-in-nested-func.js.snap | 394 +++ ...tures@capturing-nested-member-expr.js.snap | 347 +++ ...s@capturing-reference-changes-type.js.snap | 325 +++ ...capturing-variable-in-nested-block.js.snap | 289 ++ ...turing-variable-in-nested-function.js.snap | 324 +++ ...hained-assignment-context-variable.js.snap | 311 +++ ...res@chained-assignment-expressions.js.snap | 518 ++++ ...s@codegen-emit-imports-same-source.js.snap | 129 + ...xtures@codegen-emit-make-read-only.js.snap | 366 +++ ...egen-instrument-forget-gating-test.js.snap | 485 ++++ ...res@codegen-instrument-forget-test.js.snap | 485 ++++ ...arser_test__fixtures@complex-while.js.snap | 237 ++ .../parser_test__fixtures@component.js.snap | 1185 +++++++++ ...res@computed-call-evaluation-order.js.snap | 656 +++++ ...est__fixtures@computed-call-spread.js.snap | 258 ++ ...puted-load-primitive-as-dependency.js.snap | 330 +++ ...est__fixtures@computed-store-alias.js.snap | 339 +++ ..._test__fixtures@concise-arrow-expr.js.snap | 316 +++ ...@cond-deps-conditional-member-expr.js.snap | 229 ++ ...fixtures@conditional-break-labeled.js.snap | 463 ++++ ...r_test__fixtures@conditional-break.js.snap | 1574 +++++++++++ ...t__fixtures@conditional-on-mutable.js.snap | 1060 ++++++++ ...es@conditional-set-state-in-render.js.snap | 386 +++ ...er_test__fixtures@console-readonly.js.snap | 503 ++++ ...on-into-function-expression-global.js.snap | 315 +++ ...into-function-expression-primitive.js.snap | 263 ++ ...r_test__fixtures@constant-computed.js.snap | 358 +++ ..._fixtures@constant-propagation-for.js.snap | 269 ++ ...pagation-into-function-expressions.js.snap | 300 +++ ..._fixtures@constant-propagation-phi.js.snap | 370 +++ ...ixtures@constant-propagation-while.js.snap | 241 ++ ...est__fixtures@constant-propagation.js.snap | 641 +++++ .../parser_test__fixtures@constructor.js.snap | 478 ++++ ...iable-reassigned-outside-of-lambda.js.snap | 349 +++ ...er_test__fixtures@controlled-input.js.snap | 373 +++ .../parser_test__fixtures@dce-loop.js.snap | 294 ++ ...r_test__fixtures@debugger-memoized.js.snap | 214 ++ .../parser_test__fixtures@debugger.js.snap | 214 ++ ...clare-reassign-variable-in-closure.js.snap | 246 ++ ...n-variable-in-function-declaration.js.snap | 306 +++ ..._fixtures@delete-computed-property.js.snap | 318 +++ ...ser_test__fixtures@delete-property.js.snap | 279 ++ ...est__fixtures@dependencies-outputs.js.snap | 509 ++++ ...parser_test__fixtures@dependencies.js.snap | 439 +++ ...ixtures@destructure-capture-global.js.snap | 231 ++ ...es@destructure-direct-reassignment.js.snap | 475 ++++ ...xtures@destructuring-array-default.js.snap | 194 ++ ...@destructuring-array-param-default.js.snap | 115 + ...ructuring-assignment-array-default.js.snap | 342 +++ ..._fixtures@destructuring-assignment.js.snap | 614 +++++ ...e-and-local-variables-with-default.js.snap | 810 ++++++ ...ixed-scope-declarations-and-locals.js.snap | 760 ++++++ ...tures@destructuring-object-default.js.snap | 256 ++ ...destructuring-object-param-default.js.snap | 135 + ...s@destructuring-property-inference.js.snap | 335 +++ ...arser_test__fixtures@destructuring.js.snap | 526 ++++ ...__fixtures@disable-jsx-memoization.js.snap | 474 ++++ ...rser_test__fixtures@do-while-break.js.snap | 147 + ...t__fixtures@do-while-compound-test.js.snap | 426 +++ ...ixtures@do-while-conditional-break.js.snap | 312 +++ ...r_test__fixtures@do-while-continue.js.snap | 446 ++++ ...do-while-early-unconditional-break.js.snap | 254 ++ ...ser_test__fixtures@do-while-simple.js.snap | 377 +++ .../parser_test__fixtures@dominator.js.snap | 784 ++++++ ...parser_test__fixtures@early-return.js.snap | 208 ++ ..._todo.computed-lval-in-destructure.js.snap | 237 ++ ...ow-expr-export-default-gating-test.js.snap | 400 +++ ...el-existing-react-namespace-import.js.snap | 756 ++++++ ...l-mutable-range-extensions-are-bad.js.snap | 813 ++++++ ...gs-destructuring-asignment-complex.js.snap | 244 ++ ...degen-error-on-conflicting-imports.js.snap | 168 ++ ...error.hoisted-function-declaration.js.snap | 297 +++ ...s@error.hooks-with-React-namespace.js.snap | 175 ++ ...r.invalid-access-ref-during-render.js.snap | 206 ++ ...es@error.invalid-array-push-frozen.js.snap | 279 ++ ...error.invalid-assign-hook-to-local.js.snap | 204 ++ ...invalid-capture-func-passed-to-jsx.js.snap | 547 ++++ ...lid-computed-store-to-frozen-value.js.snap | 268 ++ ...-computed-property-of-frozen-value.js.snap | 261 ++ ...id-delete-property-of-frozen-value.js.snap | 261 ++ ...d-destructure-assignment-to-global.js.snap | 169 ++ ...tructure-to-local-global-variables.js.snap | 218 ++ ...reeze-conditionally-mutable-lambda.js.snap | 452 ++++ ...freeze-mutable-lambda-mutate-local.js.snap | 443 ++++ ...eeze-mutable-lambda-reassign-local.js.snap | 364 +++ ...expression-mutates-immutable-value.js.snap | 515 ++++ ...nvalid-mutate-after-aliased-freeze.js.snap | 524 ++++ ...@error.invalid-mutate-after-freeze.js.snap | 358 +++ ...rror.invalid-pass-hook-as-call-arg.js.snap | 108 + ...es@error.invalid-pass-hook-as-prop.js.snap | 143 + ...error.invalid-pass-ref-to-function.js.snap | 225 ++ ...lid-property-store-to-frozen-value.js.snap | 269 ++ ...-in-callback-invoked-during-render.js.snap | 546 ++++ ...s@error.invalid-ref-value-as-props.js.snap | 220 ++ ...lid-set-and-read-ref-during-render.js.snap | 242 ++ ...or.invalid-sketchy-code-use-forget.js.snap | 191 ++ ...r.invalid-ternary-with-hook-values.js.snap | 184 ++ ...-unconditional-set-state-in-render.js.snap | 287 ++ ...ref-added-to-dep-without-type-info.js.snap | 442 ++++ ...ror.invalid-useMemo-async-callback.js.snap | 214 ++ ...rror.invalid-useMemo-callback-args.js.snap | 196 ++ ...ror.mutate-captured-arg-separately.js.snap | 300 +++ ...-global-increment-op-invalid-react.js.snap | 166 ++ ...tures@error.reassignment-to-global.js.snap | 135 + ...t__fixtures@error.todo-kitchensink.js.snap | 2355 +++++++++++++++++ ...odo-unconditional-set-state-lambda.js.snap | 393 +++ ...tructure-assignment-to-context-var.js.snap | 347 +++ ...s@error.useMemo-callback-generator.js.snap | 217 ++ ...rror.while-with-assignment-in-test.js.snap | 367 +++ ...analysis-destructured-rest-element.js.snap | 390 +++ ...fixtures@escape-analysis-jsx-child.js.snap | 420 +++ ...__fixtures@escape-analysis-logical.js.snap | 335 +++ ...-interleaved-allocating-dependency.js.snap | 378 +++ ...eaved-allocating-nested-dependency.js.snap | 436 +++ ...g-interleaved-primitive-dependency.js.snap | 408 +++ ...cape-analysis-not-conditional-test.js.snap | 263 ++ ...xtures@escape-analysis-not-if-test.js.snap | 345 +++ ...es@escape-analysis-not-switch-case.js.snap | 347 +++ ...es@escape-analysis-not-switch-test.js.snap | 327 +++ ...expression-with-assignment-dynamic.js.snap | 184 ++ ...ixtures@expression-with-assignment.js.snap | 172 ++ ...er_test__fixtures@extend-scopes-if.js.snap | 365 +++ ...tures@fbt-call-complex-param-value.js.snap | 378 +++ .../parser_test__fixtures@fbt-call.js.snap | 358 +++ ...res@fbt-params-complex-param-value.js.snap | 387 +++ .../parser_test__fixtures@fbt-params.js.snap | 367 +++ ...res@fbt-template-string-same-scope.js.snap | 556 ++++ ...res@for-empty-update-with-continue.js.snap | 321 +++ ...er_test__fixtures@for-empty-update.js.snap | 332 +++ .../parser_test__fixtures@for-logical.js.snap | 465 ++++ ...parser_test__fixtures@for-of-break.js.snap | 205 ++ ..._fixtures@for-of-conditional-break.js.snap | 313 +++ ...ser_test__fixtures@for-of-continue.js.snap | 389 +++ ..._test__fixtures@for-of-destructure.js.snap | 447 ++++ ...arser_test__fixtures@for-of-mutate.js.snap | 434 +++ ...arser_test__fixtures@for-of-simple.js.snap | 321 +++ .../parser_test__fixtures@for-return.js.snap | 205 ++ ..._test__fixtures@frozen-after-alias.js.snap | 320 +++ ...ures@function-declaration-reassign.js.snap | 212 ++ ...res@function-declaration-redeclare.js.snap | 210 ++ ...xtures@function-declaration-simple.js.snap | 297 +++ ...on-captures-value-later-frozen-jsx.js.snap | 501 ++++ ...on-maybe-mutates-hook-return-value.js.snap | 296 +++ ...expression-with-store-to-parameter.js.snap | 393 +++ ...@function-param-assignment-pattern.js.snap | 162 ++ ...ating-test-export-default-function.js.snap | 492 ++++ ...g-test-export-function-and-default.js.snap | 502 ++++ ...xtures@gating-test-export-function.js.snap | 514 ++++ .../parser_test__fixtures@gating-test.js.snap | 484 ++++ ...-jsx-tag-lowered-between-mutations.js.snap | 222 ++ ...ser_test__fixtures@globals-Boolean.js.snap | 207 ++ ...rser_test__fixtures@globals-Number.js.snap | 207 ++ ...rser_test__fixtures@globals-String.js.snap | 207 ++ ...er_test__fixtures@holey-array-expr.js.snap | 149 ++ ...fixtures@holey-array-pattern-dce-2.js.snap | 149 ++ ...__fixtures@holey-array-pattern-dce.js.snap | 149 ++ .../parser_test__fixtures@holey-array.js.snap | 206 ++ .../parser_test__fixtures@hook-call.js.snap | 417 +++ ...res@hook-inside-logical-expression.js.snap | 246 ++ ...t__fixtures@hooks-freeze-arguments.js.snap | 331 +++ ...-freeze-possibly-mutable-arguments.js.snap | 570 ++++ ...ser_test__fixtures@immutable-hooks.js.snap | 260 ++ ...dvertent-mutability-readonly-class.js.snap | 350 +++ ...vertent-mutability-readonly-lambda.js.snap | 464 ++++ ...st__fixtures@independent-across-if.js.snap | 625 +++++ .../parser_test__fixtures@independent.js.snap | 455 ++++ ...ependently-memoize-object-property.js.snap | 260 ++ ...st__fixtures@infer-computed-delete.js.snap | 226 ++ ...test__fixtures@infer-global-object.js.snap | 554 ++++ ...test__fixtures@infer-phi-primitive.js.snap | 287 ++ ...st__fixtures@infer-property-delete.js.snap | 206 ++ ...infer-types-through-type-cast.flow.js.snap | 233 ++ ...ot-promoted-to-outer-scope-dynamic.js.snap | 573 ++++ ...not-promoted-to-outer-scope-static.js.snap | 432 +++ ..._fixtures@interdependent-across-if.js.snap | 555 ++++ ...rser_test__fixtures@interdependent.js.snap | 504 ++++ ...er_test__fixtures@inverted-if-else.js.snap | 304 +++ .../parser_test__fixtures@inverted-if.js.snap | 374 +++ .../parser_test__fixtures@issue852.js.snap | 261 ++ ...ssue933-disjoint-set-infinite-loop.js.snap | 315 +++ ...est__fixtures@jsx-empty-expression.js.snap | 222 ++ ...parser_test__fixtures@jsx-fragment.js.snap | 297 +++ ...jsx-member-expression-tag-grouping.js.snap | 245 ++ ...st__fixtures@jsx-member-expression.js.snap | 279 ++ ...test__fixtures@jsx-namespaced-name.js.snap | 196 ++ .../parser_test__fixtures@jsx-spread.js.snap | 263 ++ ...sx-tag-evaluation-order-non-global.js.snap | 395 +++ ..._fixtures@jsx-tag-evaluation-order.js.snap | 304 +++ ...ures@lambda-capture-returned-alias.js.snap | 510 ++++ ...ures@lambda-mutate-shadowed-object.js.snap | 294 ++ ...a-mutated-non-reactive-to-reactive.js.snap | 293 ++ ...es@lambda-mutated-ref-non-reactive.js.snap | 261 ++ ...fixtures@lambda-reassign-primitive.js.snap | 266 ++ ...lambda-reassign-shadowed-primitive.js.snap | 292 ++ ...ser_test__fixtures@lambda-with-fbt.js.snap | 1130 ++++++++ ...fixtures@logical-expression-object.js.snap | 503 ++++ ..._test__fixtures@logical-expression.js.snap | 481 ++++ ...est__fixtures@method-call-computed.js.snap | 454 ++++ ...test__fixtures@method-call-fn-call.js.snap | 393 +++ .../parser_test__fixtures@method-call.js.snap | 324 +++ ...ulti-arrow-expr-export-gating-test.js.snap | 412 +++ ...tures@multi-arrow-expr-gating-test.js.snap | 422 +++ ...t__fixtures@mutable-lifetime-loops.js.snap | 839 ++++++ ...res@mutable-lifetime-with-aliasing.js.snap | 700 +++++ ...t__fixtures@mutable-liverange-loop.js.snap | 611 +++++ ...sted-function-shadowed-identifiers.js.snap | 454 ++++ ...xtures@nested-optional-member-expr.js.snap | 229 ++ ...__fixtures@nested-scopes-hook-call.js.snap | 323 +++ .../parser_test__fixtures@new-spread.js.snap | 230 ++ ...onal-load-from-optional-memberexpr.js.snap | 171 ++ ...ures@obj-literal-cached-in-if-else.js.snap | 341 +++ ...@obj-literal-mutated-after-if-else.js.snap | 398 +++ ...j-mutated-after-if-else-with-alias.js.snap | 442 ++++ ...fixtures@obj-mutated-after-if-else.js.snap | 362 +++ ...ed-after-nested-if-else-with-alias.js.snap | 601 +++++ ...@object-computed-access-assignment.js.snap | 336 +++ ...ject-expression-string-literal-key.js.snap | 178 ++ ...ures@object-literal-spread-element.js.snap | 165 ++ ...st__fixtures@object-pattern-params.js.snap | 356 +++ ...r_test__fixtures@object-properties.js.snap | 486 ++++ ...st__fixtures@optional-call-chained.js.snap | 208 ++ ...st__fixtures@optional-call-logical.js.snap | 336 +++ ...est__fixtures@optional-call-simple.js.snap | 109 + ...-with-independently-memoizable-arg.js.snap | 356 +++ ...l-call-with-optional-property-load.js.snap | 208 ++ ...arser_test__fixtures@optional-call.js.snap | 415 +++ ...ures@optional-computed-load-static.js.snap | 187 ++ ...ptional-computed-member-expression.js.snap | 187 ++ ...member-expression-call-as-property.js.snap | 196 ++ ...s@optional-member-expression-chain.js.snap | 414 +++ ...h-optional-member-expr-as-property.js.snap | 273 ++ ...ixtures@optional-member-expression.js.snap | 288 ++ ...est__fixtures@optional-method-call.js.snap | 434 +++ ...ures@optional-receiver-method-call.js.snap | 435 +++ ...@optional-receiver-optional-method.js.snap | 435 +++ ...ing-scopes-interleaved-by-terminal.js.snap | 317 +++ ...res@overlapping-scopes-interleaved.js.snap | 275 ++ ...xtures@overlapping-scopes-shadowed.js.snap | 275 ++ ...ping-scopes-shadowing-within-block.js.snap | 421 +++ ..._fixtures@overlapping-scopes-while.js.snap | 315 +++ ...es@overlapping-scopes-within-block.js.snap | 367 +++ ...t__fixtures@primitive-alias-mutate.js.snap | 324 +++ ...ures@primitive-as-dep-nested-scope.js.snap | 358 +++ ...er_test__fixtures@primitive-as-dep.js.snap | 190 ++ ...fixtures@prop-capturing-function-1.js.snap | 319 +++ ...test__fixtures@property-assignment.js.snap | 506 ++++ ...res@property-call-evaluation-order.js.snap | 598 +++++ ...est__fixtures@property-call-spread.js.snap | 239 ++ ...l-properties-inside-optional-chain.js.snap | 206 ++ ...__fixtures@reactive-scope-grouping.js.snap | 312 +++ ..._test__fixtures@reactive-scopes-if.js.snap | 458 ++++ ...ser_test__fixtures@reactive-scopes.js.snap | 350 +++ ...ty-analysis-interleaved-reactivity.js.snap | 381 +++ ...tive-via-mutation-of-computed-load.js.snap | 407 +++ ...tive-via-mutation-of-property-load.js.snap | 388 +++ ...ixtures@reassign-object-in-context.js.snap | 253 ++ ...ures@reassign-primitive-in-context.js.snap | 253 ++ ...hi-in-returned-function-expression.js.snap | 372 +++ ..._fixtures@reassignment-conditional.js.snap | 504 ++++ ...tures@reassignment-separate-scopes.js.snap | 719 +++++ ...parser_test__fixtures@reassignment.js.snap | 549 ++++ ...__fixtures@recursive-function-expr.js.snap | 114 + ...ce-reactive-cond-deps-cfg-condexpr.js.snap | 306 +++ ...duce-reactive-cond-deps-cfg-ifelse.js.snap | 394 +++ ...ond-deps-cfg-nested-ifelse-missing.js.snap | 433 +++ ...active-cond-deps-cfg-nested-ifelse.js.snap | 685 +++++ ...-cond-deps-cfg-switch-missing-case.js.snap | 513 ++++ ...nd-deps-cfg-switch-missing-default.js.snap | 434 +++ ...duce-reactive-cond-deps-cfg-switch.js.snap | 543 ++++ ...educe-reactive-cond-deps-no-uncond.js.snap | 401 +++ ...-reactive-cond-deps-promote-uncond.js.snap | 421 +++ ...-reactive-cond-deps-subpath-order1.js.snap | 366 +++ ...-reactive-cond-deps-subpath-order2.js.snap | 366 +++ ...eactive-cond-deps-superpath-order1.js.snap | 365 +++ ...eactive-cond-deps-superpath-order2.js.snap | 365 +++ ...duce-reactive-cond-memberexpr-join.js.snap | 352 +++ ...dencies-optional-member-expression.js.snap | 423 +++ ...es@reduce-reactive-deps-cond-scope.js.snap | 332 +++ ...-deps-join-uncond-scopes-cond-deps.js.snap | 410 +++ ...-uncond-deps-nonoverlap-descendant.js.snap | 474 ++++ ...tive-uncond-deps-nonoverlap-direct.js.snap | 321 +++ ...ive-uncond-deps-overlap-descendant.js.snap | 474 ++++ ...eactive-uncond-deps-overlap-direct.js.snap | 398 +++ ...eactive-uncond-deps-subpath-order1.js.snap | 417 +++ ...eactive-uncond-deps-subpath-order2.js.snap | 417 +++ ...eactive-uncond-deps-subpath-order3.js.snap | 417 +++ ...ef-current-aliased-no-added-to-dep.js.snap | 360 +++ ...current-aliased-not-added-to-dep-2.js.snap | 387 +++ ...ref-current-field-not-added-to-dep.js.snap | 339 +++ ...res@ref-current-not-added-to-dep-2.js.snap | 347 +++ ...tures@ref-current-not-added-to-dep.js.snap | 319 +++ ...ent-optional-field-no-added-to-dep.js.snap | 300 +++ ...ref-current-write-not-added-to-dep.js.snap | 298 +++ ...arser_test__fixtures@ref-in-effect.js.snap | 582 ++++ ...rser_test__fixtures@regexp-literal.js.snap | 368 +++ ...es@remove-memoization-kitchen-sink.js.snap | 747 ++++++ ...-to-variable-without-mutable-range.js.snap | 406 +++ ...@repro-scope-missing-mutable-range.js.snap | 474 ++++ .../parser_test__fixtures@repro.js.snap | 684 +++++ ..._test__fixtures@return-conditional.js.snap | 173 ++ ...er_test__fixtures@return-undefined.js.snap | 176 ++ ...r_test__fixtures@reverse-postorder.js.snap | 706 +++++ ...-as-dep-and-redeclare-maybe-frozen.js.snap | 836 ++++++ ...same-variable-as-dep-and-redeclare.js.snap | 791 ++++++ ...test__fixtures@sequence-expression.js.snap | 374 +++ ...nt-progagatable-if-test-conditions.js.snap | 767 ++++++ ...parser_test__fixtures@simple-alias.js.snap | 397 +++ ...r_test__fixtures@simple-function-1.js.snap | 194 ++ ...parser_test__fixtures@simple-scope.js.snap | 157 ++ .../parser_test__fixtures@simple.js.snap | 213 ++ ...tures@sketchy-code-exhaustive-deps.js.snap | 321 +++ ...xtures@sketchy-code-rules-of-hooks.js.snap | 172 ++ ...test__fixtures@ssa-arrayexpression.js.snap | 226 ++ ...rser_test__fixtures@ssa-call-jsx-2.js.snap | 529 ++++ ...parser_test__fixtures@ssa-call-jsx.js.snap | 488 ++++ ...ures@ssa-cascading-eliminated-phis.js.snap | 616 +++++ ...__fixtures@ssa-complex-multiple-if.js.snap | 350 +++ ...st__fixtures@ssa-complex-single-if.js.snap | 263 ++ .../parser_test__fixtures@ssa-for-of.js.snap | 296 +++ ...t__fixtures@ssa-for-trivial-update.js.snap | 250 ++ .../parser_test__fixtures@ssa-for.js.snap | 260 ++ .../parser_test__fixtures@ssa-if-else.js.snap | 277 ++ ...rser_test__fixtures@ssa-leave-case.js.snap | 432 +++ ...r_test__fixtures@ssa-multiple-phis.js.snap | 473 ++++ ...tures@ssa-nested-loops-no-reassign.js.snap | 276 ++ ...t__fixtures@ssa-nested-partial-phi.js.snap | 250 ++ ...es@ssa-nested-partial-reassignment.js.snap | 316 +++ ...r_test__fixtures@ssa-newexpression.js.snap | 273 ++ ...fixtures@ssa-non-empty-initializer.js.snap | 247 ++ ..._fixtures@ssa-objectexpression-phi.js.snap | 396 +++ ...est__fixtures@ssa-objectexpression.js.snap | 270 ++ ...ssa-property-alias-alias-mutate-if.js.snap | 442 ++++ ...st__fixtures@ssa-property-alias-if.js.snap | 362 +++ ...tures@ssa-property-alias-mutate-if.js.snap | 402 +++ ...sa-property-alias-mutate-inside-if.js.snap | 402 +++ ...fixtures@ssa-property-alias-mutate.js.snap | 295 +++ ...r_test__fixtures@ssa-property-call.js.snap | 265 ++ ...st__fixtures@ssa-property-mutate-2.js.snap | 253 ++ ...fixtures@ssa-property-mutate-alias.js.snap | 295 +++ ...test__fixtures@ssa-property-mutate.js.snap | 253 ++ ...parser_test__fixtures@ssa-property.js.snap | 213 ++ ...est__fixtures@ssa-reassign-in-rval.js.snap | 244 ++ ...parser_test__fixtures@ssa-reassign.js.snap | 264 ++ ...-ternary-destruction-with-mutation.js.snap | 516 ++++ ...s@ssa-renaming-ternary-destruction.js.snap | 476 ++++ ...ssa-renaming-ternary-with-mutation.js.snap | 434 +++ ...est__fixtures@ssa-renaming-ternary.js.snap | 394 +++ ...nconditional-ternary-with-mutation.js.snap | 562 ++++ ...ssa-renaming-unconditional-ternary.js.snap | 522 ++++ ...naming-unconditional-with-mutation.js.snap | 613 +++++ ...ng-via-destructuring-with-mutation.js.snap | 635 +++++ ...res@ssa-renaming-via-destructuring.js.snap | 595 +++++ ...ixtures@ssa-renaming-with-mutation.js.snap | 449 ++++ ...parser_test__fixtures@ssa-renaming.js.snap | 409 +++ .../parser_test__fixtures@ssa-return.js.snap | 204 ++ ...arser_test__fixtures@ssa-shadowing.js.snap | 343 +++ ...er_test__fixtures@ssa-sibling-phis.js.snap | 455 ++++ ...rser_test__fixtures@ssa-simple-phi.js.snap | 274 ++ .../parser_test__fixtures@ssa-simple.js.snap | 136 + ...arser_test__fixtures@ssa-single-if.js.snap | 227 ++ .../parser_test__fixtures@ssa-switch.js.snap | 437 +++ .../parser_test__fixtures@ssa-throw.js.snap | 203 ++ ...st__fixtures@ssa-while-no-reassign.js.snap | 203 ++ .../parser_test__fixtures@ssa-while.js.snap | 222 ++ ...rser_test__fixtures@store-via-call.js.snap | 224 ++ ...arser_test__fixtures@store-via-new.js.snap | 224 ++ ...itch-global-propertyload-case-test.js.snap | 220 ++ ..._fixtures@switch-non-final-default.js.snap | 763 ++++++ ...__fixtures@switch-with-fallthrough.js.snap | 579 ++++ .../parser_test__fixtures@switch.js.snap | 767 ++++++ ...__fixtures@tagged-template-in-hook.js.snap | 228 ++ ...__fixtures@tagged-template-literal.js.snap | 161 ++ ...er_test__fixtures@template-literal.js.snap | 466 ++++ ...s@temporary-accessed-outside-scope.js.snap | 217 ++ ...@temporary-at-start-of-value-block.js.snap | 304 +++ ...operty-load-accessed-outside-scope.js.snap | 236 ++ ...ures@ternary-assignment-expression.js.snap | 269 ++ ..._test__fixtures@ternary-expression.js.snap | 582 ++++ .../parser_test__fixtures@timers.js.snap | 417 +++ ...ession-captures-value-later-frozen.js.snap | 496 ++++ ...odo.unnecessary-lambda-memoization.js.snap | 382 +++ ...__fixtures@transitive-alias-fields.js.snap | 468 ++++ .../parser_test__fixtures@trivial.js.snap | 88 + ...res@type-args-test-binary-operator.js.snap | 168 ++ ...est__fixtures@type-binary-operator.js.snap | 245 ++ ...fixtures@type-cast-expression.flow.js.snap | 357 +++ ...ser_test__fixtures@type-field-load.js.snap | 207 ++ ...res@type-test-field-load-binary-op.js.snap | 485 ++++ ...st__fixtures@type-test-field-store.js.snap | 272 ++ ...st__fixtures@type-test-polymorphic.js.snap | 480 ++++ ...test__fixtures@type-test-primitive.js.snap | 156 ++ ...es@type-test-return-type-inference.js.snap | 314 +++ .../parser_test__fixtures@unary-expr.js.snap | 867 ++++++ ...fixtures@unconditional-break-label.js.snap | 233 ++ ...ized-declaration-in-reactive-scope.js.snap | 228 ++ ...xtures@unknown-hooks-do-not-assert.js.snap | 214 ++ ...xtures@unused-array-middle-element.js.snap | 196 ++ ...fixtures@unused-array-rest-element.js.snap | 204 ++ ..._test__fixtures@unused-conditional.js.snap | 202 ++ ...nused-logical-assigned-to-variable.js.snap | 320 +++ ...rser_test__fixtures@unused-logical.js.snap | 230 ++ ...es@unused-object-element-with-rest.js.snap | 196 ++ ...st__fixtures@unused-object-element.js.snap | 225 ++ ...tional-method-assigned-to-variable.js.snap | 255 ++ ...nused-ternary-assigned-to-variable.js.snap | 261 ++ ...r_test__fixtures@update-expression.js.snap | 343 +++ ...test__fixtures@use-callback-simple.js.snap | 344 +++ ...t__fixtures@useEffect-arg-memoized.js.snap | 439 +++ ..._fixtures@useEffect-nested-lambdas.js.snap | 807 ++++++ ...es@useMemo-if-else-multiple-return.js.snap | 333 +++ ...@useMemo-independently-memoizeable.js.snap | 443 ++++ ...ures@useMemo-inlining-block-return.js.snap | 289 ++ ...test__fixtures@useMemo-inverted-if.js.snap | 342 +++ ...led-statement-unconditional-return.js.snap | 235 ++ ...ser_test__fixtures@useMemo-logical.js.snap | 223 ++ ..._fixtures@useMemo-multiple-if-else.js.snap | 500 ++++ ...t__fixtures@useMemo-named-function.js.snap | 157 ++ ..._test__fixtures@useMemo-nested-ifs.js.snap | 305 +++ ...est__fixtures@useMemo-return-empty.js.snap | 216 ++ ...rser_test__fixtures@useMemo-simple.js.snap | 267 ++ ...ures@useMemo-switch-no-fallthrough.js.snap | 338 +++ ...st__fixtures@useMemo-switch-return.js.snap | 467 ++++ .../parser_test__fixtures@while-break.js.snap | 138 + ...ixtures@while-conditional-continue.js.snap | 238 ++ ...arser_test__fixtures@while-logical.js.snap | 290 ++ ...rser_test__fixtures@while-property.js.snap | 244 ++ 1014 files changed, 191022 insertions(+), 52 deletions(-) create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/alias-capture-in-method-receiver-and-mutate.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/alias-capture-in-method-receiver.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/alias-computed-load.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/alias-nested-member-path-mutate.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/alias-nested-member-path.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/alias-while.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/allocating-primitive-as-dep-nested-scope.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/allocating-primitive-as-dep.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/allow-passing-refs-as-props.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/array-access-assignment.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/array-at-closure.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/array-at-effect.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/array-at-mutate-after-capture.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/array-expression-spread.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/array-join.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/array-map-frozen-array.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/array-map-mutable-array-mutating-lambda.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/array-pattern-params.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/array-properties.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/array-property-call.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/array-push-effect.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/arrow-function-expr-gating-test.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/assignment-expression-computed.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/assignment-expression-nested-path.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/assignment-in-nested-if.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/assignment-variations-complex-lvalue-array.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/assignment-variations-complex-lvalue.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/assignment-variations.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/await-side-effecting-promise.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/await.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/babel-existing-react-import.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/babel-existing-react-kitchensink-import.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/bug.useMemo-deps-array-not-cleared.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/bug_object-pattern.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/builtin-jsx-tag-lowered-between-mutations.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/call-args-assignment.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/call-args-destructuring-assignment.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/call-spread.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/call-with-independently-memoizable-arg.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/call.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/capture-indirect-mutate-alias.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/capture-param-mutate.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/capture_mutate-across-fns.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-arrow-function-1.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-fun-alias-captured-mutate-2.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-fun-alias-captured-mutate-arr-2.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-func-alias-captured-mutate-arr.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-func-alias-captured-mutate.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-func-alias-computed-mutate.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-func-alias-mutate.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-func-alias-receiver-computed-mutate.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-func-alias-receiver-mutate.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-func-mutate-2.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-func-mutate-3.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-func-mutate-nested.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-func-mutate.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-func-simple-alias.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-function-1.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-function-alias-computed-load-2.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-function-alias-computed-load-3.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-function-alias-computed-load-4.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-function-alias-computed-load.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-function-capture-ref-before-rename.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-function-conditional-capture-mutate.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-function-decl.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-function-member-expr-arguments.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-function-member-expr-call.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-function-renamed-ref.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-function-runs-inference.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-function-shadow-captured.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-function-skip-computed-path.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-function-within-block.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-member-expr.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-nested-member-call.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-nested-member-expr-in-nested-func.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-nested-member-expr.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-reference-changes-type.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-variable-in-nested-block.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-variable-in-nested-function.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/chained-assignment-context-variable.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/chained-assignment-expressions.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/codegen-emit-imports-same-source.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/codegen-emit-make-read-only.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/codegen-instrument-forget-gating-test.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/codegen-instrument-forget-test.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/complex-while.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/component.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/computed-call-evaluation-order.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/computed-call-spread.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/computed-load-primitive-as-dependency.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/computed-store-alias.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/concise-arrow-expr.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/cond-deps-conditional-member-expr.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/conditional-break-labeled.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/conditional-break.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/conditional-on-mutable.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/conditional-set-state-in-render.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/console-readonly.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/const-propagation-into-function-expression-global.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/const-propagation-into-function-expression-primitive.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/constant-computed.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/constant-propagation-for.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/constant-propagation-into-function-expressions.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/constant-propagation-phi.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/constant-propagation-while.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/constant-propagation.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/constructor.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/context-variable-reassigned-outside-of-lambda.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/controlled-input.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/dce-loop.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/debugger-memoized.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/debugger.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/declare-reassign-variable-in-closure.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/declare-reassign-variable-in-function-declaration.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/delete-computed-property.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/delete-property.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/dependencies-outputs.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/dependencies.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/destructure-capture-global.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/destructure-direct-reassignment.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/destructuring-array-default.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/destructuring-array-param-default.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/destructuring-assignment-array-default.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/destructuring-assignment.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/destructuring-mixed-scope-and-local-variables-with-default.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/destructuring-mixed-scope-declarations-and-locals.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/destructuring-object-default.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/destructuring-object-param-default.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/destructuring-property-inference.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/destructuring.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/disable-jsx-memoization.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/do-while-break.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/do-while-compound-test.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/do-while-conditional-break.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/do-while-continue.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/do-while-early-unconditional-break.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/do-while-simple.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/dominator.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/early-return.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/error._todo.computed-lval-in-destructure.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/error._todo.multi-arrow-expr-export-default-gating-test.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.babel-existing-react-namespace-import.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.bug-validate-no-set-state-not-all-mutable-range-extensions-are-bad.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.call-args-destructuring-asignment-complex.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.codegen-error-on-conflicting-imports.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.hoisted-function-declaration.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.hooks-with-React-namespace.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-access-ref-during-render.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-array-push-frozen.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-assign-hook-to-local.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-capture-func-passed-to-jsx.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-computed-store-to-frozen-value.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-delete-computed-property-of-frozen-value.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-delete-property-of-frozen-value.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-destructure-assignment-to-global.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-destructure-to-local-global-variables.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-freeze-conditionally-mutable-lambda.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-freeze-mutable-lambda-mutate-local.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-freeze-mutable-lambda-reassign-local.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-function-expression-mutates-immutable-value.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-mutate-after-aliased-freeze.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-mutate-after-freeze.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-pass-hook-as-call-arg.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-pass-hook-as-prop.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-pass-ref-to-function.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-property-store-to-frozen-value.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-ref-in-callback-invoked-during-render.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-ref-value-as-props.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-set-and-read-ref-during-render.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-sketchy-code-use-forget.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-ternary-with-hook-values.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-unconditional-set-state-in-render.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-use-ref-added-to-dep-without-type-info.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-useMemo-async-callback.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-useMemo-callback-args.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.mutate-captured-arg-separately.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.mutate-global-increment-op-invalid-react.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.reassignment-to-global.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.todo-kitchensink.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.todo-unconditional-set-state-lambda.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.todo.destructure-assignment-to-context-var.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.useMemo-callback-generator.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.while-with-assignment-in-test.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/escape-analysis-destructured-rest-element.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/escape-analysis-jsx-child.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/escape-analysis-logical.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/escape-analysis-non-escaping-interleaved-allocating-dependency.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/escape-analysis-non-escaping-interleaved-allocating-nested-dependency.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/escape-analysis-non-escaping-interleaved-primitive-dependency.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/escape-analysis-not-conditional-test.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/escape-analysis-not-if-test.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/escape-analysis-not-switch-case.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/escape-analysis-not-switch-test.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/expression-with-assignment-dynamic.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/expression-with-assignment.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/extend-scopes-if.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/fbt-call-complex-param-value.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/fbt-call.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/fbt-params-complex-param-value.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/fbt-params.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/fbt-template-string-same-scope.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/for-empty-update-with-continue.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/for-empty-update.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/for-logical.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/for-of-break.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/for-of-conditional-break.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/for-of-continue.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/for-of-destructure.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/for-of-mutate.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/for-of-simple.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/for-return.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/frozen-after-alias.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/function-declaration-reassign.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/function-declaration-redeclare.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/function-declaration-simple.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/function-expression-captures-value-later-frozen-jsx.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/function-expression-maybe-mutates-hook-return-value.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/function-expression-with-store-to-parameter.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/function-param-assignment-pattern.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/gating-test-export-default-function.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/gating-test-export-function-and-default.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/gating-test-export-function.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/gating-test.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/global-jsx-tag-lowered-between-mutations.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/globals-Boolean.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/globals-Number.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/globals-String.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/holey-array-expr.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/holey-array-pattern-dce-2.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/holey-array-pattern-dce.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/holey-array.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/hook-call.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/hook-inside-logical-expression.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/hooks-freeze-arguments.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/hooks-freeze-possibly-mutable-arguments.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/immutable-hooks.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/inadvertent-mutability-readonly-class.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/inadvertent-mutability-readonly-lambda.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/independent-across-if.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/independent.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/independently-memoize-object-property.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/infer-computed-delete.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/infer-global-object.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/infer-phi-primitive.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/infer-property-delete.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/infer-types-through-type-cast.flow.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/inner-memo-value-not-promoted-to-outer-scope-dynamic.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/inner-memo-value-not-promoted-to-outer-scope-static.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/interdependent-across-if.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/interdependent.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/inverted-if-else.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/inverted-if.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/issue852.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/issue933-disjoint-set-infinite-loop.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/jsx-empty-expression.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/jsx-fragment.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/jsx-member-expression-tag-grouping.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/jsx-member-expression.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/jsx-namespaced-name.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/jsx-spread.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/jsx-tag-evaluation-order-non-global.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/jsx-tag-evaluation-order.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/lambda-capture-returned-alias.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/lambda-mutate-shadowed-object.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/lambda-mutated-non-reactive-to-reactive.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/lambda-mutated-ref-non-reactive.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/lambda-reassign-primitive.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/lambda-reassign-shadowed-primitive.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/lambda-with-fbt.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/logical-expression-object.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/logical-expression.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/method-call-computed.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/method-call-fn-call.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/method-call.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/multi-arrow-expr-export-gating-test.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/multi-arrow-expr-gating-test.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/mutable-lifetime-loops.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/mutable-lifetime-with-aliasing.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/mutable-liverange-loop.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/nested-function-shadowed-identifiers.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/nested-optional-member-expr.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/nested-scopes-hook-call.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/new-spread.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/nonoptional-load-from-optional-memberexpr.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/obj-literal-cached-in-if-else.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/obj-literal-mutated-after-if-else.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/obj-mutated-after-if-else-with-alias.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/obj-mutated-after-if-else.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/obj-mutated-after-nested-if-else-with-alias.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/object-computed-access-assignment.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/object-expression-string-literal-key.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/object-literal-spread-element.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/object-pattern-params.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/object-properties.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/optional-call-chained.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/optional-call-logical.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/optional-call-simple.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/optional-call-with-independently-memoizable-arg.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/optional-call-with-optional-property-load.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/optional-call.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/optional-computed-load-static.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/optional-computed-member-expression.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/optional-member-expression-call-as-property.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/optional-member-expression-chain.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/optional-member-expression-with-optional-member-expr-as-property.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/optional-member-expression.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/optional-method-call.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/optional-receiver-method-call.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/optional-receiver-optional-method.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/overlapping-scopes-interleaved-by-terminal.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/overlapping-scopes-interleaved.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/overlapping-scopes-shadowed.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/overlapping-scopes-shadowing-within-block.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/overlapping-scopes-while.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/overlapping-scopes-within-block.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/primitive-alias-mutate.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/primitive-as-dep-nested-scope.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/primitive-as-dep.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/prop-capturing-function-1.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/property-assignment.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/property-call-evaluation-order.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/property-call-spread.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/reactive-dependencies-non-optional-properties-inside-optional-chain.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/reactive-scope-grouping.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/reactive-scopes-if.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/reactive-scopes.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/reactivity-analysis-interleaved-reactivity.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/reactivity-analysis-reactive-via-mutation-of-computed-load.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/reactivity-analysis-reactive-via-mutation-of-property-load.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/reassign-object-in-context.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/reassign-primitive-in-context.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/reassigned-phi-in-returned-function-expression.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/reassignment-conditional.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/reassignment-separate-scopes.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/reassignment.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/recursive-function-expr.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/reduce-reactive-cond-deps-cfg-condexpr.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/reduce-reactive-cond-deps-cfg-ifelse.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/reduce-reactive-cond-deps-cfg-nested-ifelse-missing.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/reduce-reactive-cond-deps-cfg-nested-ifelse.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/reduce-reactive-cond-deps-cfg-switch-missing-case.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/reduce-reactive-cond-deps-cfg-switch-missing-default.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/reduce-reactive-cond-deps-cfg-switch.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/reduce-reactive-cond-deps-no-uncond.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/reduce-reactive-cond-deps-promote-uncond.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/reduce-reactive-cond-deps-subpath-order1.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/reduce-reactive-cond-deps-subpath-order2.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/reduce-reactive-cond-deps-superpath-order1.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/reduce-reactive-cond-deps-superpath-order2.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/reduce-reactive-cond-memberexpr-join.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/reduce-reactive-dependencies-optional-member-expression.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/reduce-reactive-deps-cond-scope.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/reduce-reactive-deps-join-uncond-scopes-cond-deps.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/reduce-reactive-uncond-deps-nonoverlap-descendant.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/reduce-reactive-uncond-deps-nonoverlap-direct.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/reduce-reactive-uncond-deps-overlap-descendant.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/reduce-reactive-uncond-deps-overlap-direct.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/reduce-reactive-uncond-deps-subpath-order1.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/reduce-reactive-uncond-deps-subpath-order2.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/reduce-reactive-uncond-deps-subpath-order3.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/ref-current-aliased-no-added-to-dep.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/ref-current-aliased-not-added-to-dep-2.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/ref-current-field-not-added-to-dep.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/ref-current-not-added-to-dep-2.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/ref-current-not-added-to-dep.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/ref-current-optional-field-no-added-to-dep.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/ref-current-write-not-added-to-dep.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/ref-in-effect.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/regexp-literal.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/remove-memoization-kitchen-sink.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/repro-reassign-to-variable-without-mutable-range.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/repro-scope-missing-mutable-range.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/repro.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/return-conditional.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/return-undefined.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/reverse-postorder.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/same-variable-as-dep-and-redeclare-maybe-frozen.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/same-variable-as-dep-and-redeclare.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/sequence-expression.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/sequentially-constant-progagatable-if-test-conditions.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/simple-alias.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/simple-function-1.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/simple-scope.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/simple.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/sketchy-code-exhaustive-deps.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/sketchy-code-rules-of-hooks.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/ssa-arrayexpression.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/ssa-call-jsx-2.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/ssa-call-jsx.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/ssa-cascading-eliminated-phis.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/ssa-complex-multiple-if.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/ssa-complex-single-if.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/ssa-for-of.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/ssa-for-trivial-update.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/ssa-for.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/ssa-if-else.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/ssa-leave-case.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/ssa-multiple-phis.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/ssa-nested-loops-no-reassign.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/ssa-nested-partial-phi.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/ssa-nested-partial-reassignment.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/ssa-newexpression.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/ssa-non-empty-initializer.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/ssa-objectexpression-phi.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/ssa-objectexpression.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/ssa-property-alias-alias-mutate-if.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/ssa-property-alias-if.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/ssa-property-alias-mutate-if.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/ssa-property-alias-mutate-inside-if.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/ssa-property-alias-mutate.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/ssa-property-call.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/ssa-property-mutate-2.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/ssa-property-mutate-alias.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/ssa-property-mutate.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/ssa-property.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/ssa-reassign-in-rval.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/ssa-reassign.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/ssa-renaming-ternary-destruction-with-mutation.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/ssa-renaming-ternary-destruction.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/ssa-renaming-ternary-with-mutation.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/ssa-renaming-ternary.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/ssa-renaming-unconditional-ternary-with-mutation.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/ssa-renaming-unconditional-ternary.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/ssa-renaming-unconditional-with-mutation.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/ssa-renaming-via-destructuring-with-mutation.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/ssa-renaming-via-destructuring.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/ssa-renaming-with-mutation.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/ssa-renaming.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/ssa-return.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/ssa-shadowing.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/ssa-sibling-phis.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/ssa-simple-phi.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/ssa-simple.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/ssa-single-if.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/ssa-switch.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/ssa-throw.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/ssa-while-no-reassign.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/ssa-while.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/store-via-call.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/store-via-new.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/switch-global-propertyload-case-test.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/switch-non-final-default.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/switch-with-fallthrough.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/switch.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/tagged-template-in-hook.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/tagged-template-literal.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/template-literal.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/temporary-accessed-outside-scope.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/temporary-at-start-of-value-block.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/temporary-property-load-accessed-outside-scope.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/ternary-assignment-expression.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/ternary-expression.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/timers.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/todo-function-expression-captures-value-later-frozen.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/todo.unnecessary-lambda-memoization.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/transitive-alias-fields.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/trivial.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/type-args-test-binary-operator.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/type-binary-operator.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/type-cast-expression.flow.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/type-field-load.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/type-test-field-load-binary-op.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/type-test-field-store.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/type-test-polymorphic.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/type-test-primitive.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/type-test-return-type-inference.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/unary-expr.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/unconditional-break-label.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/uninitialized-declaration-in-reactive-scope.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/unknown-hooks-do-not-assert.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/unused-array-middle-element.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/unused-array-rest-element.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/unused-conditional.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/unused-logical-assigned-to-variable.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/unused-logical.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/unused-object-element-with-rest.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/unused-object-element.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/unused-optional-method-assigned-to-variable.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/unused-ternary-assigned-to-variable.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/update-expression.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/use-callback-simple.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/useEffect-arg-memoized.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/useEffect-nested-lambdas.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/useMemo-if-else-multiple-return.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/useMemo-independently-memoizeable.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/useMemo-inlining-block-return.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/useMemo-inverted-if.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/useMemo-labeled-statement-unconditional-return.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/useMemo-logical.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/useMemo-multiple-if-else.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/useMemo-named-function.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/useMemo-nested-ifs.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/useMemo-return-empty.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/useMemo-simple.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/useMemo-switch-no-fallthrough.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/useMemo-switch-return.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/while-break.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/while-conditional-continue.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/while-logical.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/fixtures/while-property.js create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/parser_test.rs create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@alias-capture-in-method-receiver-and-mutate.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@alias-capture-in-method-receiver.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@alias-computed-load.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@alias-nested-member-path-mutate.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@alias-nested-member-path.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@alias-while.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@allocating-primitive-as-dep-nested-scope.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@allocating-primitive-as-dep.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@allow-passing-refs-as-props.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@array-access-assignment.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@array-at-closure.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@array-at-effect.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@array-at-mutate-after-capture.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@array-expression-spread.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@array-join.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@array-map-frozen-array.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@array-map-mutable-array-mutating-lambda.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@array-pattern-params.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@array-properties.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@array-property-call.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@array-push-effect.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@arrow-function-expr-gating-test.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@assignment-expression-computed.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@assignment-expression-nested-path.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@assignment-in-nested-if.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@assignment-variations-complex-lvalue-array.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@assignment-variations-complex-lvalue.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@assignment-variations.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@await-side-effecting-promise.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@await.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@babel-existing-react-import.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@babel-existing-react-kitchensink-import.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@bug.useMemo-deps-array-not-cleared.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@bug_object-pattern.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@builtin-jsx-tag-lowered-between-mutations.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@call-args-assignment.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@call-args-destructuring-assignment.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@call-spread.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@call-with-independently-memoizable-arg.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@call.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@capture-indirect-mutate-alias.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@capture-param-mutate.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@capture_mutate-across-fns.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@capturing-arrow-function-1.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@capturing-fun-alias-captured-mutate-2.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@capturing-fun-alias-captured-mutate-arr-2.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@capturing-func-alias-captured-mutate-arr.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@capturing-func-alias-captured-mutate.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@capturing-func-alias-computed-mutate.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@capturing-func-alias-mutate.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@capturing-func-alias-receiver-computed-mutate.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@capturing-func-alias-receiver-mutate.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@capturing-func-mutate-2.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@capturing-func-mutate-3.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@capturing-func-mutate-nested.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@capturing-func-mutate.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@capturing-func-simple-alias.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@capturing-function-1.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@capturing-function-alias-computed-load-2.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@capturing-function-alias-computed-load-3.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@capturing-function-alias-computed-load-4.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@capturing-function-alias-computed-load.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@capturing-function-capture-ref-before-rename.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@capturing-function-conditional-capture-mutate.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@capturing-function-decl.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@capturing-function-member-expr-arguments.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@capturing-function-member-expr-call.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@capturing-function-renamed-ref.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@capturing-function-runs-inference.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@capturing-function-shadow-captured.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@capturing-function-skip-computed-path.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@capturing-function-within-block.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@capturing-member-expr.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@capturing-nested-member-call.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@capturing-nested-member-expr-in-nested-func.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@capturing-nested-member-expr.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@capturing-reference-changes-type.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@capturing-variable-in-nested-block.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@capturing-variable-in-nested-function.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@chained-assignment-context-variable.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@chained-assignment-expressions.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@codegen-emit-imports-same-source.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@codegen-emit-make-read-only.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@codegen-instrument-forget-gating-test.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@codegen-instrument-forget-test.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@complex-while.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@component.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@computed-call-evaluation-order.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@computed-call-spread.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@computed-load-primitive-as-dependency.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@computed-store-alias.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@concise-arrow-expr.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@cond-deps-conditional-member-expr.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@conditional-break-labeled.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@conditional-break.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@conditional-on-mutable.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@conditional-set-state-in-render.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@console-readonly.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@const-propagation-into-function-expression-global.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@const-propagation-into-function-expression-primitive.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@constant-computed.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@constant-propagation-for.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@constant-propagation-into-function-expressions.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@constant-propagation-phi.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@constant-propagation-while.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@constant-propagation.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@constructor.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@context-variable-reassigned-outside-of-lambda.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@controlled-input.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@dce-loop.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@debugger-memoized.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@debugger.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@declare-reassign-variable-in-closure.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@declare-reassign-variable-in-function-declaration.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@delete-computed-property.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@delete-property.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@dependencies-outputs.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@dependencies.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@destructure-capture-global.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@destructure-direct-reassignment.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@destructuring-array-default.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@destructuring-array-param-default.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@destructuring-assignment-array-default.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@destructuring-assignment.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@destructuring-mixed-scope-and-local-variables-with-default.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@destructuring-mixed-scope-declarations-and-locals.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@destructuring-object-default.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@destructuring-object-param-default.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@destructuring-property-inference.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@destructuring.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@disable-jsx-memoization.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@do-while-break.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@do-while-compound-test.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@do-while-conditional-break.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@do-while-continue.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@do-while-early-unconditional-break.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@do-while-simple.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@dominator.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@early-return.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@error._todo.computed-lval-in-destructure.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@error._todo.multi-arrow-expr-export-default-gating-test.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@error.babel-existing-react-namespace-import.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@error.bug-validate-no-set-state-not-all-mutable-range-extensions-are-bad.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@error.call-args-destructuring-asignment-complex.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@error.codegen-error-on-conflicting-imports.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@error.hoisted-function-declaration.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@error.hooks-with-React-namespace.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@error.invalid-access-ref-during-render.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@error.invalid-array-push-frozen.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@error.invalid-assign-hook-to-local.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@error.invalid-capture-func-passed-to-jsx.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@error.invalid-computed-store-to-frozen-value.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@error.invalid-delete-computed-property-of-frozen-value.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@error.invalid-delete-property-of-frozen-value.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@error.invalid-destructure-assignment-to-global.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@error.invalid-destructure-to-local-global-variables.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@error.invalid-freeze-conditionally-mutable-lambda.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@error.invalid-freeze-mutable-lambda-mutate-local.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@error.invalid-freeze-mutable-lambda-reassign-local.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@error.invalid-function-expression-mutates-immutable-value.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@error.invalid-mutate-after-aliased-freeze.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@error.invalid-mutate-after-freeze.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@error.invalid-pass-hook-as-call-arg.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@error.invalid-pass-hook-as-prop.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@error.invalid-pass-ref-to-function.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@error.invalid-property-store-to-frozen-value.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@error.invalid-ref-in-callback-invoked-during-render.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@error.invalid-ref-value-as-props.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@error.invalid-set-and-read-ref-during-render.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@error.invalid-sketchy-code-use-forget.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@error.invalid-ternary-with-hook-values.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@error.invalid-unconditional-set-state-in-render.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@error.invalid-use-ref-added-to-dep-without-type-info.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@error.invalid-useMemo-async-callback.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@error.invalid-useMemo-callback-args.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@error.mutate-captured-arg-separately.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@error.mutate-global-increment-op-invalid-react.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@error.reassignment-to-global.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@error.todo-kitchensink.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@error.todo-unconditional-set-state-lambda.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@error.todo.destructure-assignment-to-context-var.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@error.useMemo-callback-generator.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@error.while-with-assignment-in-test.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@escape-analysis-destructured-rest-element.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@escape-analysis-jsx-child.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@escape-analysis-logical.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@escape-analysis-non-escaping-interleaved-allocating-dependency.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@escape-analysis-non-escaping-interleaved-allocating-nested-dependency.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@escape-analysis-non-escaping-interleaved-primitive-dependency.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@escape-analysis-not-conditional-test.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@escape-analysis-not-if-test.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@escape-analysis-not-switch-case.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@escape-analysis-not-switch-test.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@expression-with-assignment-dynamic.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@expression-with-assignment.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@extend-scopes-if.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@fbt-call-complex-param-value.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@fbt-call.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@fbt-params-complex-param-value.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@fbt-params.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@fbt-template-string-same-scope.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@for-empty-update-with-continue.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@for-empty-update.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@for-logical.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@for-of-break.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@for-of-conditional-break.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@for-of-continue.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@for-of-destructure.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@for-of-mutate.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@for-of-simple.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@for-return.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@frozen-after-alias.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@function-declaration-reassign.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@function-declaration-redeclare.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@function-declaration-simple.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@function-expression-captures-value-later-frozen-jsx.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@function-expression-maybe-mutates-hook-return-value.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@function-expression-with-store-to-parameter.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@function-param-assignment-pattern.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@gating-test-export-default-function.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@gating-test-export-function-and-default.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@gating-test-export-function.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@gating-test.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@global-jsx-tag-lowered-between-mutations.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@globals-Boolean.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@globals-Number.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@globals-String.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@holey-array-expr.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@holey-array-pattern-dce-2.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@holey-array-pattern-dce.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@holey-array.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@hook-call.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@hook-inside-logical-expression.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@hooks-freeze-arguments.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@hooks-freeze-possibly-mutable-arguments.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@immutable-hooks.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@inadvertent-mutability-readonly-class.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@inadvertent-mutability-readonly-lambda.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@independent-across-if.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@independent.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@independently-memoize-object-property.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@infer-computed-delete.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@infer-global-object.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@infer-phi-primitive.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@infer-property-delete.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@infer-types-through-type-cast.flow.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@inner-memo-value-not-promoted-to-outer-scope-dynamic.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@inner-memo-value-not-promoted-to-outer-scope-static.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@interdependent-across-if.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@interdependent.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@inverted-if-else.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@inverted-if.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@issue852.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@issue933-disjoint-set-infinite-loop.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@jsx-empty-expression.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@jsx-fragment.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@jsx-member-expression-tag-grouping.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@jsx-member-expression.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@jsx-namespaced-name.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@jsx-spread.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@jsx-tag-evaluation-order-non-global.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@jsx-tag-evaluation-order.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@lambda-capture-returned-alias.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@lambda-mutate-shadowed-object.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@lambda-mutated-non-reactive-to-reactive.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@lambda-mutated-ref-non-reactive.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@lambda-reassign-primitive.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@lambda-reassign-shadowed-primitive.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@lambda-with-fbt.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@logical-expression-object.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@logical-expression.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@method-call-computed.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@method-call-fn-call.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@method-call.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@multi-arrow-expr-export-gating-test.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@multi-arrow-expr-gating-test.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@mutable-lifetime-loops.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@mutable-lifetime-with-aliasing.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@mutable-liverange-loop.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@nested-function-shadowed-identifiers.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@nested-optional-member-expr.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@nested-scopes-hook-call.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@new-spread.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@nonoptional-load-from-optional-memberexpr.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@obj-literal-cached-in-if-else.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@obj-literal-mutated-after-if-else.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@obj-mutated-after-if-else-with-alias.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@obj-mutated-after-if-else.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@obj-mutated-after-nested-if-else-with-alias.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@object-computed-access-assignment.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@object-expression-string-literal-key.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@object-literal-spread-element.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@object-pattern-params.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@object-properties.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@optional-call-chained.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@optional-call-logical.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@optional-call-simple.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@optional-call-with-independently-memoizable-arg.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@optional-call-with-optional-property-load.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@optional-call.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@optional-computed-load-static.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@optional-computed-member-expression.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@optional-member-expression-call-as-property.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@optional-member-expression-chain.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@optional-member-expression-with-optional-member-expr-as-property.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@optional-member-expression.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@optional-method-call.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@optional-receiver-method-call.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@optional-receiver-optional-method.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@overlapping-scopes-interleaved-by-terminal.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@overlapping-scopes-interleaved.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@overlapping-scopes-shadowed.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@overlapping-scopes-shadowing-within-block.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@overlapping-scopes-while.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@overlapping-scopes-within-block.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@primitive-alias-mutate.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@primitive-as-dep-nested-scope.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@primitive-as-dep.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@prop-capturing-function-1.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@property-assignment.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@property-call-evaluation-order.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@property-call-spread.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@reactive-dependencies-non-optional-properties-inside-optional-chain.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@reactive-scope-grouping.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@reactive-scopes-if.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@reactive-scopes.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@reactivity-analysis-interleaved-reactivity.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@reactivity-analysis-reactive-via-mutation-of-computed-load.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@reactivity-analysis-reactive-via-mutation-of-property-load.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@reassign-object-in-context.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@reassign-primitive-in-context.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@reassigned-phi-in-returned-function-expression.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@reassignment-conditional.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@reassignment-separate-scopes.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@reassignment.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@recursive-function-expr.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@reduce-reactive-cond-deps-cfg-condexpr.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@reduce-reactive-cond-deps-cfg-ifelse.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@reduce-reactive-cond-deps-cfg-nested-ifelse-missing.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@reduce-reactive-cond-deps-cfg-nested-ifelse.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@reduce-reactive-cond-deps-cfg-switch-missing-case.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@reduce-reactive-cond-deps-cfg-switch-missing-default.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@reduce-reactive-cond-deps-cfg-switch.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@reduce-reactive-cond-deps-no-uncond.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@reduce-reactive-cond-deps-promote-uncond.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@reduce-reactive-cond-deps-subpath-order1.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@reduce-reactive-cond-deps-subpath-order2.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@reduce-reactive-cond-deps-superpath-order1.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@reduce-reactive-cond-deps-superpath-order2.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@reduce-reactive-cond-memberexpr-join.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@reduce-reactive-dependencies-optional-member-expression.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@reduce-reactive-deps-cond-scope.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@reduce-reactive-deps-join-uncond-scopes-cond-deps.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@reduce-reactive-uncond-deps-nonoverlap-descendant.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@reduce-reactive-uncond-deps-nonoverlap-direct.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@reduce-reactive-uncond-deps-overlap-descendant.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@reduce-reactive-uncond-deps-overlap-direct.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@reduce-reactive-uncond-deps-subpath-order1.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@reduce-reactive-uncond-deps-subpath-order2.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@reduce-reactive-uncond-deps-subpath-order3.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@ref-current-aliased-no-added-to-dep.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@ref-current-aliased-not-added-to-dep-2.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@ref-current-field-not-added-to-dep.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@ref-current-not-added-to-dep-2.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@ref-current-not-added-to-dep.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@ref-current-optional-field-no-added-to-dep.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@ref-current-write-not-added-to-dep.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@ref-in-effect.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@regexp-literal.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@remove-memoization-kitchen-sink.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@repro-reassign-to-variable-without-mutable-range.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@repro-scope-missing-mutable-range.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@repro.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@return-conditional.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@return-undefined.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@reverse-postorder.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@same-variable-as-dep-and-redeclare-maybe-frozen.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@same-variable-as-dep-and-redeclare.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@sequence-expression.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@sequentially-constant-progagatable-if-test-conditions.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@simple-alias.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@simple-function-1.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@simple-scope.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@simple.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@sketchy-code-exhaustive-deps.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@sketchy-code-rules-of-hooks.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@ssa-arrayexpression.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@ssa-call-jsx-2.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@ssa-call-jsx.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@ssa-cascading-eliminated-phis.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@ssa-complex-multiple-if.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@ssa-complex-single-if.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@ssa-for-of.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@ssa-for-trivial-update.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@ssa-for.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@ssa-if-else.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@ssa-leave-case.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@ssa-multiple-phis.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@ssa-nested-loops-no-reassign.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@ssa-nested-partial-phi.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@ssa-nested-partial-reassignment.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@ssa-newexpression.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@ssa-non-empty-initializer.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@ssa-objectexpression-phi.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@ssa-objectexpression.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@ssa-property-alias-alias-mutate-if.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@ssa-property-alias-if.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@ssa-property-alias-mutate-if.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@ssa-property-alias-mutate-inside-if.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@ssa-property-alias-mutate.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@ssa-property-call.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@ssa-property-mutate-2.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@ssa-property-mutate-alias.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@ssa-property-mutate.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@ssa-property.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@ssa-reassign-in-rval.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@ssa-reassign.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@ssa-renaming-ternary-destruction-with-mutation.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@ssa-renaming-ternary-destruction.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@ssa-renaming-ternary-with-mutation.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@ssa-renaming-ternary.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@ssa-renaming-unconditional-ternary-with-mutation.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@ssa-renaming-unconditional-ternary.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@ssa-renaming-unconditional-with-mutation.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@ssa-renaming-via-destructuring-with-mutation.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@ssa-renaming-via-destructuring.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@ssa-renaming-with-mutation.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@ssa-renaming.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@ssa-return.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@ssa-shadowing.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@ssa-sibling-phis.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@ssa-simple-phi.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@ssa-simple.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@ssa-single-if.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@ssa-switch.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@ssa-throw.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@ssa-while-no-reassign.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@ssa-while.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@store-via-call.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@store-via-new.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@switch-global-propertyload-case-test.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@switch-non-final-default.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@switch-with-fallthrough.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@switch.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@tagged-template-in-hook.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@tagged-template-literal.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@template-literal.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@temporary-accessed-outside-scope.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@temporary-at-start-of-value-block.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@temporary-property-load-accessed-outside-scope.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@ternary-assignment-expression.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@ternary-expression.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@timers.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@todo-function-expression-captures-value-later-frozen.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@todo.unnecessary-lambda-memoization.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@transitive-alias-fields.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@trivial.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@type-args-test-binary-operator.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@type-binary-operator.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@type-cast-expression.flow.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@type-field-load.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@type-test-field-load-binary-op.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@type-test-field-store.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@type-test-polymorphic.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@type-test-primitive.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@type-test-return-type-inference.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@unary-expr.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@unconditional-break-label.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@uninitialized-declaration-in-reactive-scope.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@unknown-hooks-do-not-assert.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@unused-array-middle-element.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@unused-array-rest-element.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@unused-conditional.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@unused-logical-assigned-to-variable.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@unused-logical.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@unused-object-element-with-rest.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@unused-object-element.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@unused-optional-method-assigned-to-variable.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@unused-ternary-assigned-to-variable.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@update-expression.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@use-callback-simple.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@useEffect-arg-memoized.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@useEffect-nested-lambdas.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@useMemo-if-else-multiple-return.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@useMemo-independently-memoizeable.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@useMemo-inlining-block-return.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@useMemo-inverted-if.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@useMemo-labeled-statement-unconditional-return.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@useMemo-logical.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@useMemo-multiple-if-else.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@useMemo-named-function.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@useMemo-nested-ifs.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@useMemo-return-empty.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@useMemo-simple.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@useMemo-switch-no-fallthrough.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@useMemo-switch-return.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@while-break.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@while-conditional-continue.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@while-logical.js.snap create mode 100644 compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@while-property.js.snap diff --git a/compiler/forget/Cargo.lock b/compiler/forget/Cargo.lock index 1f04973fe9..bc8ffea0f2 100644 --- a/compiler/forget/Cargo.lock +++ b/compiler/forget/Cargo.lock @@ -530,7 +530,9 @@ dependencies = [ "forget_estree", "forget_estree_codegen", "hermes", + "insta", "juno_support", + "serde_json", ] [[package]] diff --git a/compiler/forget/crates/forget_estree/src/generated.rs b/compiler/forget/crates/forget_estree/src/generated.rs index fa2bf7eb9e..ff3ca630fc 100644 --- a/compiler/forget/crates/forget_estree/src/generated.rs +++ b/compiler/forget/crates/forget_estree/src/generated.rs @@ -60,6 +60,9 @@ pub struct Identifier { #[serde(skip)] #[serde(default)] pub binding: Option, + #[serde(rename = "typeAnnotation")] + #[serde(default)] + pub type_annotation: Option, #[serde(default)] pub loc: Option, #[serde(default)] @@ -73,6 +76,7 @@ impl Serialize for Identifier { let mut state = serializer.serialize_map(None)?; state.serialize_entry("type", "Identifier")?; state.serialize_entry("name", &self.name)?; + state.serialize_entry("typeAnnotation", &self.type_annotation)?; state.serialize_entry("loc", &self.loc)?; state.serialize_entry("range", &self.range)?; state.end() @@ -191,6 +195,29 @@ impl Serialize for StringLiteral { } } #[derive(Deserialize, Clone, Debug)] +pub struct RegExpLiteral { + pub pattern: String, + pub flags: String, + #[serde(default)] + pub loc: Option, + #[serde(default)] + pub range: Option, +} +impl Serialize for RegExpLiteral { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + let mut state = serializer.serialize_map(None)?; + state.serialize_entry("type", "RegExpLiteral")?; + state.serialize_entry("pattern", &self.pattern)?; + state.serialize_entry("flags", &self.flags)?; + state.serialize_entry("loc", &self.loc)?; + state.serialize_entry("range", &self.range)?; + state.end() + } +} +#[derive(Deserialize, Clone, Debug)] pub struct Program { pub body: Vec, #[serde(rename = "sourceType")] @@ -751,7 +778,7 @@ impl Serialize for ClassExpression { } #[derive(Deserialize, Clone, Debug)] pub struct ClassBody { - pub body: Vec, + pub body: Vec, #[serde(default)] pub loc: Option, #[serde(default)] @@ -1123,7 +1150,7 @@ impl Serialize for LogicalExpression { #[derive(Deserialize, Clone, Debug)] pub struct MemberExpression { pub object: ExpressionOrSuper, - pub property: Expression, + pub property: ExpressionOrPrivateIdentifier, #[serde(rename = "computed")] pub is_computed: bool, #[serde(default)] @@ -1439,7 +1466,7 @@ impl Serialize for ExportSpecifier { } #[derive(Deserialize, Clone, Debug)] pub struct ExportDefaultDeclaration { - pub declaration: Declaration, + pub declaration: DeclarationOrExpression, #[serde(default)] pub loc: Option, #[serde(default)] @@ -1728,6 +1755,29 @@ impl Serialize for JSXText { } } #[derive(Deserialize, Clone, Debug)] +pub struct JSXStringLiteral { + pub value: String, + pub raw: String, + #[serde(default)] + pub loc: Option, + #[serde(default)] + pub range: Option, +} +impl Serialize for JSXStringLiteral { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + let mut state = serializer.serialize_map(None)?; + state.serialize_entry("type", "JSXStringLiteral")?; + state.serialize_entry("value", &self.value)?; + state.serialize_entry("raw", &self.raw)?; + state.serialize_entry("loc", &self.loc)?; + state.serialize_entry("range", &self.range)?; + state.end() + } +} +#[derive(Deserialize, Clone, Debug)] pub struct JSXElement { #[serde(rename = "openingElement")] pub opening_element: JSXOpeningElement, @@ -2144,6 +2194,187 @@ impl Serialize for ImportExpression { state.end() } } +#[derive(Deserialize, Clone, Debug)] +pub struct ClassProperty { + pub key: Expression, + #[serde(default)] + pub value: Option, + #[serde(rename = "computed")] + pub is_computed: bool, + #[serde(rename = "static")] + pub is_static: bool, + #[serde(default)] + pub loc: Option, + #[serde(default)] + pub range: Option, +} +impl Serialize for ClassProperty { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + let mut state = serializer.serialize_map(None)?; + state.serialize_entry("type", "ClassProperty")?; + state.serialize_entry("key", &self.key)?; + state.serialize_entry("value", &self.value)?; + state.serialize_entry("computed", &self.is_computed)?; + state.serialize_entry("static", &self.is_static)?; + state.serialize_entry("loc", &self.loc)?; + state.serialize_entry("range", &self.range)?; + state.end() + } +} +#[derive(Deserialize, Clone, Debug)] +pub struct ClassPrivateProperty { + pub key: ExpressionOrPrivateIdentifier, + #[serde(default)] + pub value: Option, + #[serde(rename = "static")] + pub is_static: bool, + #[serde(default)] + pub loc: Option, + #[serde(default)] + pub range: Option, +} +impl Serialize for ClassPrivateProperty { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + let mut state = serializer.serialize_map(None)?; + state.serialize_entry("type", "ClassPrivateProperty")?; + state.serialize_entry("key", &self.key)?; + state.serialize_entry("value", &self.value)?; + state.serialize_entry("static", &self.is_static)?; + state.serialize_entry("loc", &self.loc)?; + state.serialize_entry("range", &self.range)?; + state.end() + } +} +#[derive(Deserialize, Clone, Debug)] +pub struct PrivateName { + pub id: Identifier, + #[serde(default)] + pub loc: Option, + #[serde(default)] + pub range: Option, +} +impl Serialize for PrivateName { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + let mut state = serializer.serialize_map(None)?; + state.serialize_entry("type", "PrivateName")?; + state.serialize_entry("id", &self.id)?; + state.serialize_entry("loc", &self.loc)?; + state.serialize_entry("range", &self.range)?; + state.end() + } +} +#[derive(Deserialize, Clone, Debug)] +pub struct PrivateIdentifier { + pub name: String, + #[serde(default)] + pub loc: Option, + #[serde(default)] + pub range: Option, +} +impl Serialize for PrivateIdentifier { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + let mut state = serializer.serialize_map(None)?; + state.serialize_entry("type", "PrivateIdentifier")?; + state.serialize_entry("name", &self.name)?; + state.serialize_entry("loc", &self.loc)?; + state.serialize_entry("range", &self.range)?; + state.end() + } +} +#[derive(Deserialize, Clone, Debug)] +pub struct StaticBlock { + pub body: Vec, + #[serde(default)] + pub loc: Option, + #[serde(default)] + pub range: Option, +} +impl Serialize for StaticBlock { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + let mut state = serializer.serialize_map(None)?; + state.serialize_entry("type", "StaticBlock")?; + state.serialize_entry("body", &self.body)?; + state.serialize_entry("loc", &self.loc)?; + state.serialize_entry("range", &self.range)?; + state.end() + } +} +#[derive(Deserialize, Clone, Debug)] +pub struct CoverTypedIdentifier { + pub left: Identifier, + pub right: Option, + #[serde(default)] + pub loc: Option, + #[serde(default)] + pub range: Option, +} +impl Serialize for CoverTypedIdentifier { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + let mut state = serializer.serialize_map(None)?; + state.serialize_entry("type", "CoverTypedIdentifier")?; + state.serialize_entry("left", &self.left)?; + state.serialize_entry("right", &self.right)?; + state.serialize_entry("loc", &self.loc)?; + state.serialize_entry("range", &self.range)?; + state.end() + } +} +#[derive(Deserialize, Clone, Debug)] +pub struct TSTypeAnnotation { + #[serde(default)] + pub loc: Option, + #[serde(default)] + pub range: Option, +} +impl Serialize for TSTypeAnnotation { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + let mut state = serializer.serialize_map(None)?; + state.serialize_entry("type", "TSTypeAnnotation")?; + state.serialize_entry("loc", &self.loc)?; + state.serialize_entry("range", &self.range)?; + state.end() + } +} +#[derive(Deserialize, Clone, Debug)] +pub struct TSTypeAliasDeclaration { + #[serde(default)] + pub loc: Option, + #[serde(default)] + pub range: Option, +} +impl Serialize for TSTypeAliasDeclaration { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + let mut state = serializer.serialize_map(None)?; + state.serialize_entry("type", "TSTypeAliasDeclaration")?; + state.serialize_entry("loc", &self.loc)?; + state.serialize_entry("range", &self.range)?; + state.end() + } +} #[derive(Serialize, Clone, Debug)] #[serde(untagged)] pub enum Statement { @@ -2163,6 +2394,7 @@ pub enum Statement { LabeledStatement(Box), ReturnStatement(Box), SwitchStatement(Box), + TSTypeAliasDeclaration(Box), ThrowStatement(Box), TryStatement(Box), VariableDeclaration(Box), @@ -2189,6 +2421,7 @@ enum __StatementTag { SwitchStatement, ThrowStatement, TryStatement, + TSTypeAliasDeclaration, VariableDeclaration, WhileStatement, WithStatement, @@ -2349,6 +2582,14 @@ impl<'de> serde::Deserialize<'de> for Statement { )?; Ok(Statement::TryStatement(node)) } + __StatementTag::TSTypeAliasDeclaration => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok(Statement::TSTypeAliasDeclaration(node)) + } __StatementTag::VariableDeclaration => { let node: Box = ), ClassExpression(Box), ConditionalExpression(Box), + CoverTypedIdentifier(Box), FunctionExpression(Box), Identifier(Box), ImportExpression(Box), JSXElement(Box), + JSXFragment(Box), Literal(Box), LogicalExpression(Box), MemberExpression(Box), @@ -2403,6 +2646,7 @@ pub enum Expression { ObjectExpression(Box), OptionalCallExpression(Box), OptionalMemberExpression(Box), + RegExpLiteral(Box), SequenceExpression(Box), StringLiteral(Box), TaggedTemplateExpression(Box), @@ -2424,10 +2668,12 @@ enum __ExpressionTag { ChainExpression, ClassExpression, ConditionalExpression, + CoverTypedIdentifier, FunctionExpression, Identifier, ImportExpression, JSXElement, + JSXFragment, Literal, LogicalExpression, MemberExpression, @@ -2438,6 +2684,7 @@ enum __ExpressionTag { ObjectExpression, OptionalCallExpression, OptionalMemberExpression, + RegExpLiteral, SequenceExpression, StringLiteral, TaggedTemplateExpression, @@ -2539,6 +2786,14 @@ impl<'de> serde::Deserialize<'de> for Expression { )?; Ok(Expression::ConditionalExpression(node)) } + __ExpressionTag::CoverTypedIdentifier => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok(Expression::CoverTypedIdentifier(node)) + } __ExpressionTag::FunctionExpression => { let node: Box = serde::Deserialize<'de> for Expression { )?; Ok(Expression::JSXElement(node)) } + __ExpressionTag::JSXFragment => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok(Expression::JSXFragment(node)) + } __ExpressionTag::Literal => { let node: Box = serde::Deserialize<'de> for Expression { )?; Ok(Expression::OptionalMemberExpression(node)) } + __ExpressionTag::RegExpLiteral => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok(Expression::RegExpLiteral(node)) + } __ExpressionTag::SequenceExpression => { let node: Box = serde::Deserialize<'de> for _Literal { pub enum Declaration { ClassDeclaration(Box), FunctionDeclaration(Box), + TSTypeAliasDeclaration(Box), VariableDeclaration(Box), } #[derive(Deserialize, Debug)] @@ -2802,6 +3074,7 @@ enum __DeclarationTag { ClassDeclaration, FunctionDeclaration, VariableDeclaration, + TSTypeAliasDeclaration, } impl<'de> serde::Deserialize<'de> for Declaration { fn deserialize(deserializer: D) -> Result @@ -2839,6 +3112,14 @@ impl<'de> serde::Deserialize<'de> for Declaration { )?; Ok(Declaration::VariableDeclaration(node)) } + __DeclarationTag::TSTypeAliasDeclaration => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok(Declaration::TSTypeAliasDeclaration(node)) + } } } } @@ -2924,6 +3205,7 @@ enum __ModuleItemTag { SwitchStatement, ThrowStatement, TryStatement, + TSTypeAliasDeclaration, VariableDeclaration, WhileStatement, WithStatement, @@ -3132,6 +3414,14 @@ impl<'de> serde::Deserialize<'de> for ModuleItem { )?; Ok(ModuleItem::Statement(Statement::TryStatement(node))) } + __ModuleItemTag::TSTypeAliasDeclaration => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok(ModuleItem::Statement(Statement::TSTypeAliasDeclaration(node))) + } __ModuleItemTag::VariableDeclaration => { let node: Box = serde::Deserialize<'de> for ExpressionOrSuper { ), ) } + __ExpressionOrSuperTag::CoverTypedIdentifier => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok(ExpressionOrSuper::Expression(Expression::CoverTypedIdentifier(node))) + } __ExpressionOrSuperTag::FunctionExpression => { let node: Box = serde::Deserialize<'de> for ExpressionOrSuper { )?; Ok(ExpressionOrSuper::Expression(Expression::JSXElement(node))) } + __ExpressionOrSuperTag::JSXFragment => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok(ExpressionOrSuper::Expression(Expression::JSXFragment(node))) + } __ExpressionOrSuperTag::Literal => { let node: Box = serde::Deserialize<'de> for ExpressionOrSuper { ), ) } + __ExpressionOrSuperTag::RegExpLiteral => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok(ExpressionOrSuper::Expression(Expression::RegExpLiteral(node))) + } __ExpressionOrSuperTag::SequenceExpression => { let node: Box = serde::Deserialize<'de> for ExpressionOrSpread { ), ) } + __ExpressionOrSpreadTag::CoverTypedIdentifier => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok( + ExpressionOrSpread::Expression( + Expression::CoverTypedIdentifier(node), + ), + ) + } __ExpressionOrSpreadTag::FunctionExpression => { let node: Box = serde::Deserialize<'de> for ExpressionOrSpread { )?; Ok(ExpressionOrSpread::Expression(Expression::JSXElement(node))) } + __ExpressionOrSpreadTag::JSXFragment => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok(ExpressionOrSpread::Expression(Expression::JSXFragment(node))) + } __ExpressionOrSpreadTag::Literal => { let node: Box = serde::Deserialize<'de> for ExpressionOrSpread { ), ) } + __ExpressionOrSpreadTag::RegExpLiteral => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok(ExpressionOrSpread::Expression(Expression::RegExpLiteral(node))) + } __ExpressionOrSpreadTag::SequenceExpression => { let node: Box = serde::Deserialize<'de> for FunctionBody { )?; Ok(FunctionBody::Expression(Expression::ConditionalExpression(node))) } + __FunctionBodyTag::CoverTypedIdentifier => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok(FunctionBody::Expression(Expression::CoverTypedIdentifier(node))) + } __FunctionBodyTag::FunctionExpression => { let node: Box = serde::Deserialize<'de> for FunctionBody { )?; Ok(FunctionBody::Expression(Expression::JSXElement(node))) } + __FunctionBodyTag::JSXFragment => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok(FunctionBody::Expression(Expression::JSXFragment(node))) + } __FunctionBodyTag::Literal => { let node: Box = serde::Deserialize<'de> for FunctionBody { )?; Ok(FunctionBody::Expression(Expression::OptionalMemberExpression(node))) } + __FunctionBodyTag::RegExpLiteral => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok(FunctionBody::Expression(Expression::RegExpLiteral(node))) + } __FunctionBodyTag::SequenceExpression => { let node: Box = serde::Deserialize<'de> for ForInit { )?; Ok(ForInit::Expression(Expression::ConditionalExpression(node))) } + __ForInitTag::CoverTypedIdentifier => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok(ForInit::Expression(Expression::CoverTypedIdentifier(node))) + } __ForInitTag::FunctionExpression => { let node: Box = serde::Deserialize<'de> for ForInit { )?; Ok(ForInit::Expression(Expression::JSXElement(node))) } + __ForInitTag::JSXFragment => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok(ForInit::Expression(Expression::JSXFragment(node))) + } __ForInitTag::Literal => { let node: Box = serde::Deserialize<'de> for ForInit { )?; Ok(ForInit::Expression(Expression::OptionalMemberExpression(node))) } + __ForInitTag::RegExpLiteral => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok(ForInit::Expression(Expression::RegExpLiteral(node))) + } __ForInitTag::SequenceExpression => { let node: Box = serde::Deserialize<'de> for AssignmentTarget { )?; Ok(AssignmentTarget::Expression(Expression::ConditionalExpression(node))) } + __AssignmentTargetTag::CoverTypedIdentifier => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok(AssignmentTarget::Expression(Expression::CoverTypedIdentifier(node))) + } __AssignmentTargetTag::FunctionExpression => { let node: Box = serde::Deserialize<'de> for AssignmentTarget { )?; Ok(AssignmentTarget::Expression(Expression::JSXElement(node))) } + __AssignmentTargetTag::JSXFragment => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok(AssignmentTarget::Expression(Expression::JSXFragment(node))) + } __AssignmentTargetTag::Literal => { let node: Box = serde::Deserialize<'de> for AssignmentTarget { ), ) } + __AssignmentTargetTag::RegExpLiteral => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok(AssignmentTarget::Expression(Expression::RegExpLiteral(node))) + } __AssignmentTargetTag::SequenceExpression => { let node: Box = serde::Deserialize<'de> for JSXExpressionOrEmpty { ), ) } + __JSXExpressionOrEmptyTag::CoverTypedIdentifier => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok( + JSXExpressionOrEmpty::Expression( + Expression::CoverTypedIdentifier(node), + ), + ) + } __JSXExpressionOrEmptyTag::FunctionExpression => { let node: Box = serde::Deserialize<'de> for JSXExpressionOrEmpty { )?; Ok(JSXExpressionOrEmpty::Expression(Expression::JSXElement(node))) } + __JSXExpressionOrEmptyTag::JSXFragment => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok(JSXExpressionOrEmpty::Expression(Expression::JSXFragment(node))) + } __JSXExpressionOrEmptyTag::Literal => { let node: Box = serde::Deserialize<'de> for JSXExpressionOrEmpty { ), ) } + __JSXExpressionOrEmptyTag::RegExpLiteral => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok(JSXExpressionOrEmpty::Expression(Expression::RegExpLiteral(node))) + } __JSXExpressionOrEmptyTag::SequenceExpression => { let node: Box = ), JSXExpressionContainer(Box), JSXFragment(Box), + JSXStringLiteral(Box), Literal(Box), } #[derive(Deserialize, Debug)] @@ -5682,6 +6143,7 @@ enum __JSXAttributeValueTag { JSXExpressionContainer, JSXElement, JSXFragment, + JSXStringLiteral, } impl<'de> serde::Deserialize<'de> for JSXAttributeValue { fn deserialize(deserializer: D) -> Result @@ -5727,6 +6189,14 @@ impl<'de> serde::Deserialize<'de> for JSXAttributeValue { )?; Ok(JSXAttributeValue::JSXFragment(node)) } + __JSXAttributeValueTag::JSXStringLiteral => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok(JSXAttributeValue::JSXStringLiteral(node)) + } } } } @@ -5831,11 +6301,13 @@ pub enum JSXChildItem { JSXExpressionContainer(Box), JSXFragment(Box), JSXSpreadChild(Box), + JSXStringLiteral(Box), JSXText(Box), } #[derive(Deserialize, Debug)] enum __JSXChildItemTag { JSXText, + JSXStringLiteral, JSXExpressionContainer, JSXSpreadChild, JSXElement, @@ -5861,6 +6333,14 @@ impl<'de> serde::Deserialize<'de> for JSXChildItem { )?; Ok(JSXChildItem::JSXText(node)) } + __JSXChildItemTag::JSXStringLiteral => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok(JSXChildItem::JSXStringLiteral(node)) + } __JSXChildItemTag::JSXExpressionContainer => { let node: Box = serde::Deserialize<'de> for JSXChildItem { } } } +#[derive(Serialize, Clone, Debug)] +#[serde(untagged)] +pub enum DeclarationOrExpression { + Declaration(Declaration), + Expression(Expression), +} +#[derive(Deserialize, Debug)] +enum __DeclarationOrExpressionTag { + ClassDeclaration, + FunctionDeclaration, + VariableDeclaration, + TSTypeAliasDeclaration, + ArrayExpression, + ArrowFunctionExpression, + AssignmentExpression, + AwaitExpression, + BinaryExpression, + BooleanLiteral, + CallExpression, + ChainExpression, + ClassExpression, + ConditionalExpression, + CoverTypedIdentifier, + FunctionExpression, + Identifier, + ImportExpression, + JSXElement, + JSXFragment, + Literal, + LogicalExpression, + MemberExpression, + MetaProperty, + NewExpression, + NullLiteral, + NumericLiteral, + ObjectExpression, + OptionalCallExpression, + OptionalMemberExpression, + RegExpLiteral, + SequenceExpression, + StringLiteral, + TaggedTemplateExpression, + TemplateLiteral, + ThisExpression, + UnaryExpression, + UpdateExpression, + YieldExpression, +} +impl<'de> serde::Deserialize<'de> for DeclarationOrExpression { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + let tagged = serde::Deserializer::deserialize_any( + deserializer, + serde::__private::de::TaggedContentVisitor::< + __DeclarationOrExpressionTag, + >::new("type", "DeclarationOrExpression"), + )?; + match tagged.0 { + __DeclarationOrExpressionTag::ClassDeclaration => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok( + DeclarationOrExpression::Declaration( + Declaration::ClassDeclaration(node), + ), + ) + } + __DeclarationOrExpressionTag::FunctionDeclaration => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok( + DeclarationOrExpression::Declaration( + Declaration::FunctionDeclaration(node), + ), + ) + } + __DeclarationOrExpressionTag::VariableDeclaration => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok( + DeclarationOrExpression::Declaration( + Declaration::VariableDeclaration(node), + ), + ) + } + __DeclarationOrExpressionTag::TSTypeAliasDeclaration => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok( + DeclarationOrExpression::Declaration( + Declaration::TSTypeAliasDeclaration(node), + ), + ) + } + __DeclarationOrExpressionTag::ArrayExpression => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok( + DeclarationOrExpression::Expression( + Expression::ArrayExpression(node), + ), + ) + } + __DeclarationOrExpressionTag::ArrowFunctionExpression => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok( + DeclarationOrExpression::Expression( + Expression::ArrowFunctionExpression(node), + ), + ) + } + __DeclarationOrExpressionTag::AssignmentExpression => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok( + DeclarationOrExpression::Expression( + Expression::AssignmentExpression(node), + ), + ) + } + __DeclarationOrExpressionTag::AwaitExpression => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok( + DeclarationOrExpression::Expression( + Expression::AwaitExpression(node), + ), + ) + } + __DeclarationOrExpressionTag::BinaryExpression => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok( + DeclarationOrExpression::Expression( + Expression::BinaryExpression(node), + ), + ) + } + __DeclarationOrExpressionTag::BooleanLiteral => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok(DeclarationOrExpression::Expression(Expression::BooleanLiteral(node))) + } + __DeclarationOrExpressionTag::CallExpression => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok(DeclarationOrExpression::Expression(Expression::CallExpression(node))) + } + __DeclarationOrExpressionTag::ChainExpression => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok( + DeclarationOrExpression::Expression( + Expression::ChainExpression(node), + ), + ) + } + __DeclarationOrExpressionTag::ClassExpression => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok( + DeclarationOrExpression::Expression( + Expression::ClassExpression(node), + ), + ) + } + __DeclarationOrExpressionTag::ConditionalExpression => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok( + DeclarationOrExpression::Expression( + Expression::ConditionalExpression(node), + ), + ) + } + __DeclarationOrExpressionTag::CoverTypedIdentifier => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok( + DeclarationOrExpression::Expression( + Expression::CoverTypedIdentifier(node), + ), + ) + } + __DeclarationOrExpressionTag::FunctionExpression => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok( + DeclarationOrExpression::Expression( + Expression::FunctionExpression(node), + ), + ) + } + __DeclarationOrExpressionTag::Identifier => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok(DeclarationOrExpression::Expression(Expression::Identifier(node))) + } + __DeclarationOrExpressionTag::ImportExpression => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok( + DeclarationOrExpression::Expression( + Expression::ImportExpression(node), + ), + ) + } + __DeclarationOrExpressionTag::JSXElement => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok(DeclarationOrExpression::Expression(Expression::JSXElement(node))) + } + __DeclarationOrExpressionTag::JSXFragment => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok(DeclarationOrExpression::Expression(Expression::JSXFragment(node))) + } + __DeclarationOrExpressionTag::Literal => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok(DeclarationOrExpression::Expression(Expression::Literal(node))) + } + __DeclarationOrExpressionTag::LogicalExpression => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok( + DeclarationOrExpression::Expression( + Expression::LogicalExpression(node), + ), + ) + } + __DeclarationOrExpressionTag::MemberExpression => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok( + DeclarationOrExpression::Expression( + Expression::MemberExpression(node), + ), + ) + } + __DeclarationOrExpressionTag::MetaProperty => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok(DeclarationOrExpression::Expression(Expression::MetaProperty(node))) + } + __DeclarationOrExpressionTag::NewExpression => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok(DeclarationOrExpression::Expression(Expression::NewExpression(node))) + } + __DeclarationOrExpressionTag::NullLiteral => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok(DeclarationOrExpression::Expression(Expression::NullLiteral(node))) + } + __DeclarationOrExpressionTag::NumericLiteral => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok(DeclarationOrExpression::Expression(Expression::NumericLiteral(node))) + } + __DeclarationOrExpressionTag::ObjectExpression => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok( + DeclarationOrExpression::Expression( + Expression::ObjectExpression(node), + ), + ) + } + __DeclarationOrExpressionTag::OptionalCallExpression => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok( + DeclarationOrExpression::Expression( + Expression::OptionalCallExpression(node), + ), + ) + } + __DeclarationOrExpressionTag::OptionalMemberExpression => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok( + DeclarationOrExpression::Expression( + Expression::OptionalMemberExpression(node), + ), + ) + } + __DeclarationOrExpressionTag::RegExpLiteral => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok(DeclarationOrExpression::Expression(Expression::RegExpLiteral(node))) + } + __DeclarationOrExpressionTag::SequenceExpression => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok( + DeclarationOrExpression::Expression( + Expression::SequenceExpression(node), + ), + ) + } + __DeclarationOrExpressionTag::StringLiteral => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok(DeclarationOrExpression::Expression(Expression::StringLiteral(node))) + } + __DeclarationOrExpressionTag::TaggedTemplateExpression => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok( + DeclarationOrExpression::Expression( + Expression::TaggedTemplateExpression(node), + ), + ) + } + __DeclarationOrExpressionTag::TemplateLiteral => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok( + DeclarationOrExpression::Expression( + Expression::TemplateLiteral(node), + ), + ) + } + __DeclarationOrExpressionTag::ThisExpression => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok(DeclarationOrExpression::Expression(Expression::ThisExpression(node))) + } + __DeclarationOrExpressionTag::UnaryExpression => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok( + DeclarationOrExpression::Expression( + Expression::UnaryExpression(node), + ), + ) + } + __DeclarationOrExpressionTag::UpdateExpression => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok( + DeclarationOrExpression::Expression( + Expression::UpdateExpression(node), + ), + ) + } + __DeclarationOrExpressionTag::YieldExpression => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok( + DeclarationOrExpression::Expression( + Expression::YieldExpression(node), + ), + ) + } + } + } +} +#[derive(Serialize, Clone, Debug)] +#[serde(untagged)] +pub enum ClassItem { + ClassPrivateProperty(Box), + ClassProperty(Box), + MethodDefinition(Box), + StaticBlock(Box), +} +#[derive(Deserialize, Debug)] +enum __ClassItemTag { + MethodDefinition, + ClassProperty, + ClassPrivateProperty, + StaticBlock, +} +impl<'de> serde::Deserialize<'de> for ClassItem { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + let tagged = serde::Deserializer::deserialize_any( + deserializer, + serde::__private::de::TaggedContentVisitor::< + __ClassItemTag, + >::new("type", "ClassItem"), + )?; + match tagged.0 { + __ClassItemTag::MethodDefinition => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok(ClassItem::MethodDefinition(node)) + } + __ClassItemTag::ClassProperty => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok(ClassItem::ClassProperty(node)) + } + __ClassItemTag::ClassPrivateProperty => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok(ClassItem::ClassPrivateProperty(node)) + } + __ClassItemTag::StaticBlock => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok(ClassItem::StaticBlock(node)) + } + } + } +} +#[derive(Serialize, Clone, Debug)] +#[serde(untagged)] +pub enum ExpressionOrPrivateIdentifier { + Expression(Expression), + PrivateIdentifier(Box), + PrivateName(Box), +} +#[derive(Deserialize, Debug)] +enum __ExpressionOrPrivateIdentifierTag { + ArrayExpression, + ArrowFunctionExpression, + AssignmentExpression, + AwaitExpression, + BinaryExpression, + BooleanLiteral, + CallExpression, + ChainExpression, + ClassExpression, + ConditionalExpression, + CoverTypedIdentifier, + FunctionExpression, + Identifier, + ImportExpression, + JSXElement, + JSXFragment, + Literal, + LogicalExpression, + MemberExpression, + MetaProperty, + NewExpression, + NullLiteral, + NumericLiteral, + ObjectExpression, + OptionalCallExpression, + OptionalMemberExpression, + RegExpLiteral, + SequenceExpression, + StringLiteral, + TaggedTemplateExpression, + TemplateLiteral, + ThisExpression, + UnaryExpression, + UpdateExpression, + YieldExpression, + PrivateIdentifier, + PrivateName, +} +impl<'de> serde::Deserialize<'de> for ExpressionOrPrivateIdentifier { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + let tagged = serde::Deserializer::deserialize_any( + deserializer, + serde::__private::de::TaggedContentVisitor::< + __ExpressionOrPrivateIdentifierTag, + >::new("type", "ExpressionOrPrivateIdentifier"), + )?; + match tagged.0 { + __ExpressionOrPrivateIdentifierTag::ArrayExpression => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok( + ExpressionOrPrivateIdentifier::Expression( + Expression::ArrayExpression(node), + ), + ) + } + __ExpressionOrPrivateIdentifierTag::ArrowFunctionExpression => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok( + ExpressionOrPrivateIdentifier::Expression( + Expression::ArrowFunctionExpression(node), + ), + ) + } + __ExpressionOrPrivateIdentifierTag::AssignmentExpression => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok( + ExpressionOrPrivateIdentifier::Expression( + Expression::AssignmentExpression(node), + ), + ) + } + __ExpressionOrPrivateIdentifierTag::AwaitExpression => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok( + ExpressionOrPrivateIdentifier::Expression( + Expression::AwaitExpression(node), + ), + ) + } + __ExpressionOrPrivateIdentifierTag::BinaryExpression => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok( + ExpressionOrPrivateIdentifier::Expression( + Expression::BinaryExpression(node), + ), + ) + } + __ExpressionOrPrivateIdentifierTag::BooleanLiteral => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok( + ExpressionOrPrivateIdentifier::Expression( + Expression::BooleanLiteral(node), + ), + ) + } + __ExpressionOrPrivateIdentifierTag::CallExpression => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok( + ExpressionOrPrivateIdentifier::Expression( + Expression::CallExpression(node), + ), + ) + } + __ExpressionOrPrivateIdentifierTag::ChainExpression => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok( + ExpressionOrPrivateIdentifier::Expression( + Expression::ChainExpression(node), + ), + ) + } + __ExpressionOrPrivateIdentifierTag::ClassExpression => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok( + ExpressionOrPrivateIdentifier::Expression( + Expression::ClassExpression(node), + ), + ) + } + __ExpressionOrPrivateIdentifierTag::ConditionalExpression => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok( + ExpressionOrPrivateIdentifier::Expression( + Expression::ConditionalExpression(node), + ), + ) + } + __ExpressionOrPrivateIdentifierTag::CoverTypedIdentifier => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok( + ExpressionOrPrivateIdentifier::Expression( + Expression::CoverTypedIdentifier(node), + ), + ) + } + __ExpressionOrPrivateIdentifierTag::FunctionExpression => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok( + ExpressionOrPrivateIdentifier::Expression( + Expression::FunctionExpression(node), + ), + ) + } + __ExpressionOrPrivateIdentifierTag::Identifier => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok( + ExpressionOrPrivateIdentifier::Expression( + Expression::Identifier(node), + ), + ) + } + __ExpressionOrPrivateIdentifierTag::ImportExpression => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok( + ExpressionOrPrivateIdentifier::Expression( + Expression::ImportExpression(node), + ), + ) + } + __ExpressionOrPrivateIdentifierTag::JSXElement => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok( + ExpressionOrPrivateIdentifier::Expression( + Expression::JSXElement(node), + ), + ) + } + __ExpressionOrPrivateIdentifierTag::JSXFragment => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok( + ExpressionOrPrivateIdentifier::Expression( + Expression::JSXFragment(node), + ), + ) + } + __ExpressionOrPrivateIdentifierTag::Literal => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok(ExpressionOrPrivateIdentifier::Expression(Expression::Literal(node))) + } + __ExpressionOrPrivateIdentifierTag::LogicalExpression => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok( + ExpressionOrPrivateIdentifier::Expression( + Expression::LogicalExpression(node), + ), + ) + } + __ExpressionOrPrivateIdentifierTag::MemberExpression => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok( + ExpressionOrPrivateIdentifier::Expression( + Expression::MemberExpression(node), + ), + ) + } + __ExpressionOrPrivateIdentifierTag::MetaProperty => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok( + ExpressionOrPrivateIdentifier::Expression( + Expression::MetaProperty(node), + ), + ) + } + __ExpressionOrPrivateIdentifierTag::NewExpression => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok( + ExpressionOrPrivateIdentifier::Expression( + Expression::NewExpression(node), + ), + ) + } + __ExpressionOrPrivateIdentifierTag::NullLiteral => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok( + ExpressionOrPrivateIdentifier::Expression( + Expression::NullLiteral(node), + ), + ) + } + __ExpressionOrPrivateIdentifierTag::NumericLiteral => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok( + ExpressionOrPrivateIdentifier::Expression( + Expression::NumericLiteral(node), + ), + ) + } + __ExpressionOrPrivateIdentifierTag::ObjectExpression => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok( + ExpressionOrPrivateIdentifier::Expression( + Expression::ObjectExpression(node), + ), + ) + } + __ExpressionOrPrivateIdentifierTag::OptionalCallExpression => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok( + ExpressionOrPrivateIdentifier::Expression( + Expression::OptionalCallExpression(node), + ), + ) + } + __ExpressionOrPrivateIdentifierTag::OptionalMemberExpression => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok( + ExpressionOrPrivateIdentifier::Expression( + Expression::OptionalMemberExpression(node), + ), + ) + } + __ExpressionOrPrivateIdentifierTag::RegExpLiteral => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok( + ExpressionOrPrivateIdentifier::Expression( + Expression::RegExpLiteral(node), + ), + ) + } + __ExpressionOrPrivateIdentifierTag::SequenceExpression => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok( + ExpressionOrPrivateIdentifier::Expression( + Expression::SequenceExpression(node), + ), + ) + } + __ExpressionOrPrivateIdentifierTag::StringLiteral => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok( + ExpressionOrPrivateIdentifier::Expression( + Expression::StringLiteral(node), + ), + ) + } + __ExpressionOrPrivateIdentifierTag::TaggedTemplateExpression => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok( + ExpressionOrPrivateIdentifier::Expression( + Expression::TaggedTemplateExpression(node), + ), + ) + } + __ExpressionOrPrivateIdentifierTag::TemplateLiteral => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok( + ExpressionOrPrivateIdentifier::Expression( + Expression::TemplateLiteral(node), + ), + ) + } + __ExpressionOrPrivateIdentifierTag::ThisExpression => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok( + ExpressionOrPrivateIdentifier::Expression( + Expression::ThisExpression(node), + ), + ) + } + __ExpressionOrPrivateIdentifierTag::UnaryExpression => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok( + ExpressionOrPrivateIdentifier::Expression( + Expression::UnaryExpression(node), + ), + ) + } + __ExpressionOrPrivateIdentifierTag::UpdateExpression => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok( + ExpressionOrPrivateIdentifier::Expression( + Expression::UpdateExpression(node), + ), + ) + } + __ExpressionOrPrivateIdentifierTag::YieldExpression => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok( + ExpressionOrPrivateIdentifier::Expression( + Expression::YieldExpression(node), + ), + ) + } + __ExpressionOrPrivateIdentifierTag::PrivateIdentifier => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok(ExpressionOrPrivateIdentifier::PrivateIdentifier(node)) + } + __ExpressionOrPrivateIdentifierTag::PrivateName => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok(ExpressionOrPrivateIdentifier::PrivateName(node)) + } + } + } +} +#[derive(Serialize, Clone, Debug)] +#[serde(untagged)] +pub enum TypeAnnotation { + TSTypeAnnotation(Box), +} +#[derive(Deserialize, Debug)] +enum __TypeAnnotationTag { + TSTypeAnnotation, +} +impl<'de> serde::Deserialize<'de> for TypeAnnotation { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + let tagged = serde::Deserializer::deserialize_any( + deserializer, + serde::__private::de::TaggedContentVisitor::< + __TypeAnnotationTag, + >::new("type", "TypeAnnotation"), + )?; + match tagged.0 { + __TypeAnnotationTag::TSTypeAnnotation => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok(TypeAnnotation::TSTypeAnnotation(node)) + } + } + } +} #[derive( Serialize, Deserialize, diff --git a/compiler/forget/crates/forget_estree/src/snapshots/forget_estree__tests__fixtures@for-statement.json.snap b/compiler/forget/crates/forget_estree/src/snapshots/forget_estree__tests__fixtures@for-statement.json.snap index 8e2042d61d..7a3dc79c2f 100644 --- a/compiler/forget/crates/forget_estree/src/snapshots/forget_estree__tests__fixtures@for-statement.json.snap +++ b/compiler/forget/crates/forget_estree/src/snapshots/forget_estree__tests__fixtures@for-statement.json.snap @@ -542,6 +542,7 @@ Output: "id": { "type": "Identifier", "name": "Component", + "typeAnnotation": null, "loc": { "source": null, "start": { @@ -562,6 +563,7 @@ Output: { "type": "Identifier", "name": "props", + "typeAnnotation": null, "loc": { "source": null, "start": { @@ -591,6 +593,7 @@ Output: "id": { "type": "Identifier", "name": "x", + "typeAnnotation": null, "loc": { "source": null, "start": { @@ -675,6 +678,7 @@ Output: "id": { "type": "Identifier", "name": "i", + "typeAnnotation": null, "loc": { "source": null, "start": { @@ -753,6 +757,7 @@ Output: "left": { "type": "Identifier", "name": "i", + "typeAnnotation": null, "loc": { "source": null, "start": { @@ -816,6 +821,7 @@ Output: "argument": { "type": "Identifier", "name": "i", + "typeAnnotation": null, "loc": { "source": null, "start": { @@ -860,6 +866,7 @@ Output: "left": { "type": "Identifier", "name": "x", + "typeAnnotation": null, "loc": { "source": null, "start": { @@ -879,6 +886,7 @@ Output: "right": { "type": "Identifier", "name": "i", + "typeAnnotation": null, "loc": { "source": null, "start": { @@ -966,6 +974,7 @@ Output: "argument": { "type": "Identifier", "name": "x", + "typeAnnotation": null, "loc": { "source": null, "start": { diff --git a/compiler/forget/crates/forget_estree/src/snapshots/forget_estree__tests__fixtures@import.json.snap b/compiler/forget/crates/forget_estree/src/snapshots/forget_estree__tests__fixtures@import.json.snap index a5b4da7754..dd08fcfdf2 100644 --- a/compiler/forget/crates/forget_estree/src/snapshots/forget_estree__tests__fixtures@import.json.snap +++ b/compiler/forget/crates/forget_estree/src/snapshots/forget_estree__tests__fixtures@import.json.snap @@ -121,6 +121,7 @@ Output: "local": { "type": "Identifier", "name": "React", + "typeAnnotation": null, "loc": { "source": null, "start": { diff --git a/compiler/forget/crates/forget_estree/src/snapshots/forget_estree__tests__fixtures@simple.json.snap b/compiler/forget/crates/forget_estree/src/snapshots/forget_estree__tests__fixtures@simple.json.snap index 852ff5f588..b1d3ef551f 100644 --- a/compiler/forget/crates/forget_estree/src/snapshots/forget_estree__tests__fixtures@simple.json.snap +++ b/compiler/forget/crates/forget_estree/src/snapshots/forget_estree__tests__fixtures@simple.json.snap @@ -203,6 +203,7 @@ Output: "id": { "type": "Identifier", "name": "Component", + "typeAnnotation": null, "loc": { "source": null, "start": { @@ -223,6 +224,7 @@ Output: { "type": "Identifier", "name": "props", + "typeAnnotation": null, "loc": { "source": null, "start": { @@ -250,6 +252,7 @@ Output: "object": { "type": "Identifier", "name": "props", + "typeAnnotation": null, "loc": { "source": null, "start": { @@ -269,6 +272,7 @@ Output: "property": { "type": "Identifier", "name": "value", + "typeAnnotation": null, "loc": { "source": null, "start": { diff --git a/compiler/forget/crates/forget_estree/src/snapshots/forget_estree__tests__fixtures@test.json.snap b/compiler/forget/crates/forget_estree/src/snapshots/forget_estree__tests__fixtures@test.json.snap index 4b87ee2f85..ca325475a3 100644 --- a/compiler/forget/crates/forget_estree/src/snapshots/forget_estree__tests__fixtures@test.json.snap +++ b/compiler/forget/crates/forget_estree/src/snapshots/forget_estree__tests__fixtures@test.json.snap @@ -365,6 +365,7 @@ Output: "id": { "type": "Identifier", "name": "foo", + "typeAnnotation": null, "loc": { "source": null, "start": { diff --git a/compiler/forget/crates/forget_estree/src/visit.rs b/compiler/forget/crates/forget_estree/src/visit.rs index 2027e07304..7b609a62c0 100644 --- a/compiler/forget/crates/forget_estree/src/visit.rs +++ b/compiler/forget/crates/forget_estree/src/visit.rs @@ -1,6 +1,7 @@ use crate::{ - AssignmentPropertyOrRestElement, AssignmentTarget, Class, Declaration, ExportAllDeclaration, - ExportDefaultDeclaration, ExportNamedDeclaration, Expression, ExpressionOrSpread, + AssignmentPropertyOrRestElement, AssignmentTarget, Class, ClassItem, Declaration, + DeclarationOrExpression, ExportAllDeclaration, ExportDefaultDeclaration, + ExportNamedDeclaration, Expression, ExpressionOrPrivateIdentifier, ExpressionOrSpread, ExpressionOrSuper, ForInInit, ForInit, Function, FunctionBody, Identifier, ImportDeclaration, ImportDeclarationSpecifier, ImportOrExportDeclaration, Literal, MethodDefinition, ModuleItem, Pattern, Program, Statement, SwitchCase, VariableDeclarator, _Literal, @@ -82,7 +83,12 @@ pub trait Visitor<'ast> { } fn visit_export_default_declaration(&mut self, declaration: &'ast ExportDefaultDeclaration) { - self.visit_declaration(&declaration.declaration); + match &declaration.declaration { + DeclarationOrExpression::Declaration(declaration) => { + self.visit_declaration(declaration) + } + DeclarationOrExpression::Expression(declaration) => self.visit_expression(declaration), + } } fn visit_export_named_declaration(&mut self, declaration: &'ast ExportNamedDeclaration) { @@ -129,6 +135,9 @@ pub trait Visitor<'ast> { self.visit_variable_declarator(declarator) } } + Declaration::TSTypeAliasDeclaration(declaration) => { + todo!("visit TSTypeAliasDeclaration") + } } } @@ -245,6 +254,9 @@ pub trait Visitor<'ast> { self.visit_expression(&stmt.object); self.visit_statement(&stmt.body); } + Statement::TSTypeAliasDeclaration(stmt) => { + todo!("visit TSTypeAliasDeclaration") + } } } @@ -255,8 +267,19 @@ pub trait Visitor<'ast> { if let Some(super_class) = &class.super_class { self.visit_expression(super_class); } - for method in &class.body.body { - self.visit_method_definition(class, method) + for item in &class.body.body { + match item { + ClassItem::MethodDefinition(item) => self.visit_method_definition(class, item), + ClassItem::ClassProperty(item) => { + todo!("visit ClassProperty") + } + ClassItem::ClassPrivateProperty(item) => { + todo!("visit ClassPrivateProperty") + } + ClassItem::StaticBlock(item) => { + todo!("visit StaticBlock") + } + } } } @@ -395,7 +418,17 @@ pub trait Visitor<'ast> { ExpressionOrSuper::Expression(object) => self.visit_expression(object), }; if !expr.is_computed { - self.visit_expression(&expr.property) + match &expr.property { + ExpressionOrPrivateIdentifier::Expression(property) => { + self.visit_expression(property) + } + ExpressionOrPrivateIdentifier::PrivateIdentifier(property) => { + todo!("visit PrivateIdentifier property") + } + ExpressionOrPrivateIdentifier::PrivateName(property) => { + todo!("visit PrivateName property") + } + } } } _ => { diff --git a/compiler/forget/crates/forget_estree_codegen/src/codegen.rs b/compiler/forget/crates/forget_estree_codegen/src/codegen.rs index 217da8587d..31886d704b 100644 --- a/compiler/forget/crates/forget_estree_codegen/src/codegen.rs +++ b/compiler/forget/crates/forget_estree_codegen/src/codegen.rs @@ -164,6 +164,10 @@ pub struct Node { #[serde(default)] pub skip_hermes_enum_variant: bool, + + #[serde(default)] + #[serde(rename = "TODO")] + pub todo: Option, } impl Node { @@ -258,7 +262,9 @@ impl Node { if let Some(convert_with) = &field.hermes_convert_with { let convert_with = format_ident!("{}", convert_with); return quote! { + // println!("read {}.{}", #name_str, #name); let #field_name = #convert_with(cx, unsafe { hermes::parser::#helper(node) } ); + // println!("ok"); } } match type_kind { @@ -266,22 +272,30 @@ impl Node { match type_name_str.as_ref() { "bool" => { quote! { + // println!("read {}.{}", #name_str, #name); let #field_name = unsafe { hermes::parser::#helper(node) }; + // println!("ok"); } } "Number" => { quote! { + // println!("read {}.{}", #name_str, #name); let #field_name = convert_number(unsafe { hermes::parser::#helper(node) }); + // println!("ok"); } } "String" => { quote! { + // println!("read {}.{}", #name_str, #name); let #field_name = convert_string(cx, unsafe { hermes::parser::#helper(node) }); + // println!("ok"); } } _ => { quote! { + // println!("read {}.{}", #name_str, #name); let #field_name = #type_name::convert(cx, unsafe { hermes::parser::#helper(node) }); + // println!("ok"); } } } @@ -290,33 +304,44 @@ impl Node { match type_name_str.as_ref() { "String" => { quote! { + // println!("read {}.{}", #name_str, #name); let #field_name = convert_option_string(cx, unsafe { hermes::parser::#helper(node) }); + // println!("ok"); } } _ => { quote! { + // println!("read {}.{}", #name_str, #name); let #field_name = convert_option(unsafe { hermes::parser::#helper(node) }, |node| #type_name::convert(cx, node)); + // println!("ok"); } } } } TypeKind::Vec => { quote! { + // println!("read {}.{}", #name_str, #name); let #field_name = convert_vec(unsafe { hermes::parser::#helper(node) }, |node| #type_name::convert(cx, node)); + // println!("ok"); } } TypeKind::VecOfOption => { quote! { + // println!("read {}.{}", #name_str, #name); let #field_name = convert_vec_of_option(unsafe { hermes::parser::#helper(node) }, |node| #type_name::convert(cx, node)); + // println!("ok"); } } } }) .collect(); + let type_ = format_ident!("{}", self.type_.as_ref().unwrap_or(&name_str.to_string())); quote! { impl FromHermes for #name { fn convert(cx: &mut Context, node: NodePtr) -> Self { + let node_ref = node.as_ref(); + assert_eq!(node_ref.kind, NodeKind::#type_); let range = convert_range(node); #(#fields)* Self { @@ -550,6 +575,7 @@ impl Enum { } pub fn codegen_hermes(&self, name: &str, grammar: &Grammar) -> TokenStream { + let name_str = name; let name = format_ident!("{}", name); let mut tag_matches = Vec::new(); @@ -622,7 +648,7 @@ impl Enum { let node_ref = node.as_ref(); match node_ref.kind { #(#tag_matches),* - _ => panic!("Unexpected node") + _ => panic!("Unexpected node kind `{:?}` for `{}`", node_ref.kind, #name_str) } } } diff --git a/compiler/forget/crates/forget_estree_codegen/src/ecmascript.json b/compiler/forget/crates/forget_estree_codegen/src/ecmascript.json index e13e6b9153..f5de26d7e1 100644 --- a/compiler/forget/crates/forget_estree_codegen/src/ecmascript.json +++ b/compiler/forget/crates/forget_estree_codegen/src/ecmascript.json @@ -99,6 +99,13 @@ "type": "Option", "optional": true, "skip": true + }, + "type_annotation": { + "type": "Option", + "optional": true, + "rename": "typeAnnotation", + "hermes_default": true, + "TODO": "support HermesParser" } } }, @@ -146,6 +153,16 @@ } } }, + "RegExpLiteral": { + "fields": { + "pattern": { + "type": "String" + }, + "flags": { + "type": "String" + } + } + }, "Program": { "fields": { "body": { @@ -381,7 +398,7 @@ "ClassBody": { "fields": { "body": { - "type": "Vec" + "type": "Vec" } } }, @@ -560,7 +577,7 @@ "type": "ExpressionOrSuper" }, "property": { - "type": "Expression" + "type": "ExpressionOrPrivateIdentifier" }, "is_computed": { "type": "bool", @@ -685,7 +702,7 @@ "ExportDefaultDeclaration": { "fields": { "declaration": { - "type": "Declaration" + "type": "DeclarationOrExpression" } } }, @@ -797,6 +814,18 @@ } } }, + "JSXStringLiteral": { + "fields": { + "value": { + "type": "String", + "hermes_convert_with": "convert_string_value" + }, + "raw": { + "type": "String" + } + }, + "TODO": "Non-standard HermesParser node" + }, "JSXElement": { "fields": { "opening_element": { @@ -977,7 +1006,82 @@ "type": "Expression" } } - } + }, + "ClassProperty": { + "fields": { + "key": { + "type": "Expression" + }, + "value": { + "type": "Option", + "optional": true + }, + "is_computed": { + "type": "bool", + "rename": "computed" + }, + "is_static": { + "type": "bool", + "rename": "static" + } + } + }, + "ClassPrivateProperty": { + "fields": { + "key": { + "type": "ExpressionOrPrivateIdentifier" + }, + "value": { + "type": "Option", + "optional": true + }, + "is_static": { + "type": "bool", + "rename": "static" + } + }, + "TODO": "Non-standard HermesParser node" + }, + "PrivateName": { + "fields": { + "id": { + "type": "Identifier" + } + }, + "TODO": "Non-standard HermesParser node" + }, + "PrivateIdentifier": { + "skip_hermes_codegen": true, + "skip_hermes_enum_variant": true, + "fields": { + "name": { + "type": "String" + } + } + }, + "StaticBlock": { + "skip_hermes_codegen": true, + "skip_hermes_enum_variant": true, + "fields": { + "body": { + "type": "Vec" + } + }, + "TODO": "not yet supported in HermesParser" + }, + "CoverTypedIdentifier": { + "fields": { + "left": { + "type": "Identifier" + }, + "right": { + "type": "Option" + } + }, + "TODO": "Non-standard HermesParser node" + }, + "TSTypeAnnotation": {}, + "TSTypeAliasDeclaration": {} }, "enums": { "Statement": [ @@ -999,6 +1103,7 @@ "SwitchStatement", "ThrowStatement", "TryStatement", + "TSTypeAliasDeclaration", "VariableDeclaration", "WhileStatement", "WithStatement" @@ -1014,10 +1119,12 @@ "ChainExpression", "ClassExpression", "ConditionalExpression", + "CoverTypedIdentifier", "FunctionExpression", "Identifier", "ImportExpression", "JSXElement", + "JSXFragment", "Literal", "LogicalExpression", "MemberExpression", @@ -1028,6 +1135,7 @@ "ObjectExpression", "OptionalCallExpression", "OptionalMemberExpression", + "RegExpLiteral", "SequenceExpression", "StringLiteral", "TaggedTemplateExpression", @@ -1047,7 +1155,8 @@ "Declaration": [ "ClassDeclaration", "FunctionDeclaration", - "VariableDeclaration" + "VariableDeclaration", + "TSTypeAliasDeclaration" ], "ImportDeclarationSpecifier": [ "ImportSpecifier", @@ -1127,7 +1236,8 @@ "Literal", "JSXExpressionContainer", "JSXElement", - "JSXFragment" + "JSXFragment", + "JSXStringLiteral" ], "JSXElementName": [ "JSXIdentifier", @@ -1140,10 +1250,29 @@ ], "JSXChildItem": [ "JSXText", + "JSXStringLiteral", "JSXExpressionContainer", "JSXSpreadChild", "JSXElement", "JSXFragment" + ], + "DeclarationOrExpression": [ + "Declaration", + "Expression" + ], + "ClassItem": [ + "MethodDefinition", + "ClassProperty", + "ClassPrivateProperty", + "StaticBlock" + ], + "ExpressionOrPrivateIdentifier": [ + "Expression", + "PrivateIdentifier", + "PrivateName" + ], + "TypeAnnotation": [ + "TSTypeAnnotation" ] }, "operators": { diff --git a/compiler/forget/crates/forget_estree_swc/src/lib.rs b/compiler/forget/crates/forget_estree_swc/src/lib.rs index ab0f32e3cb..43d5b23307 100644 --- a/compiler/forget/crates/forget_estree_swc/src/lib.rs +++ b/compiler/forget/crates/forget_estree_swc/src/lib.rs @@ -140,6 +140,7 @@ fn convert_function(cx: &Context, id: Option<&Ident>, fun: &Function) -> forget_ id: id.map(|id| forget_estree::Identifier { name: id.sym.to_string(), binding: convert_binding(cx, id.span.ctxt), + type_annotation: None, loc: None, range: convert_span(&id.span), }), @@ -767,11 +768,28 @@ fn convert_member_expression(cx: &Context, expr: &MemberExpr) -> forget_estree:: let (is_computed, property) = match &expr.prop { MemberProp::Ident(prop) => ( false, - forget_estree::Expression::Identifier(Box::new(convert_identifier(cx, prop))), + forget_estree::ExpressionOrPrivateIdentifier::Expression( + forget_estree::Expression::Identifier(Box::new(convert_identifier(cx, prop))), + ), ), - MemberProp::Computed(prop) => (true, convert_expression(cx, &prop.expr)), - _ => { - panic!("PrivateName member expression properties are not supported") + MemberProp::Computed(prop) => ( + true, + forget_estree::ExpressionOrPrivateIdentifier::Expression(convert_expression( + cx, &prop.expr, + )), + ), + MemberProp::PrivateName(prop) => { + let name = prop.id.sym.as_ref().to_string(); + ( + false, + forget_estree::ExpressionOrPrivateIdentifier::PrivateIdentifier(Box::new( + forget_estree::PrivateIdentifier { + name, + loc: None, + range: convert_span(&prop.span), + }, + )), + ) } }; forget_estree::MemberExpression { @@ -873,6 +891,7 @@ fn convert_pattern(cx: &Context, pat: &Pat) -> forget_estree::Pattern { forget_estree::Pattern::Identifier(Box::new(forget_estree::Identifier { name: pat.id.sym.to_string(), binding: convert_binding(cx, pat.id.span.ctxt), + type_annotation: None, loc: None, range: convert_span(&pat.span), })) @@ -897,6 +916,7 @@ fn convert_identifier(cx: &Context, identifier: &Ident) -> forget_estree::Identi forget_estree::Identifier { name, binding: convert_binding(cx, identifier.span.ctxt), + type_annotation: None, loc: None, range: convert_span(&identifier.span), } diff --git a/compiler/forget/crates/forget_hermes_parser/Cargo.toml b/compiler/forget/crates/forget_hermes_parser/Cargo.toml index 58a84ea1f4..dc6de6a716 100644 --- a/compiler/forget/crates/forget_hermes_parser/Cargo.toml +++ b/compiler/forget/crates/forget_hermes_parser/Cargo.toml @@ -12,10 +12,12 @@ repository.workspace = true # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +insta = { workspace = true } forget_diagnostics = { workspace = true } forget_estree = { workspace = true } hermes = { workspace = true } juno_support = { workspace = true } +serde_json = { workspace = true } [build-dependencies] forget_estree_codegen = { workspace = true } \ No newline at end of file diff --git a/compiler/forget/crates/forget_hermes_parser/src/generated.rs b/compiler/forget/crates/forget_hermes_parser/src/generated.rs index 04abb0984d..5b97360787 100644 --- a/compiler/forget/crates/forget_hermes_parser/src/generated.rs +++ b/compiler/forget/crates/forget_hermes_parser/src/generated.rs @@ -9,15 +9,19 @@ use hermes::utf::utf8_with_surrogates_to_string; use crate::generated_extension::*; impl FromHermes for Identifier { fn convert(cx: &mut Context, node: NodePtr) -> Self { + let node_ref = node.as_ref(); + assert_eq!(node_ref.kind, NodeKind::Identifier); let range = convert_range(node); let name = convert_string( cx, unsafe { hermes::parser::hermes_get_Identifier_name(node) }, ); let binding = Default::default(); + let type_annotation = Default::default(); Self { name, binding, + type_annotation, loc: None, range: Some(range), } @@ -25,6 +29,8 @@ impl FromHermes for Identifier { } impl FromHermes for NumericLiteral { fn convert(cx: &mut Context, node: NodePtr) -> Self { + let node_ref = node.as_ref(); + assert_eq!(node_ref.kind, NodeKind::NumericLiteral); let range = convert_range(node); let value = convert_number(unsafe { hermes::parser::hermes_get_NumericLiteral_value(node) @@ -38,6 +44,8 @@ impl FromHermes for NumericLiteral { } impl FromHermes for BooleanLiteral { fn convert(cx: &mut Context, node: NodePtr) -> Self { + let node_ref = node.as_ref(); + assert_eq!(node_ref.kind, NodeKind::BooleanLiteral); let range = convert_range(node); let value = unsafe { hermes::parser::hermes_get_BooleanLiteral_value(node) }; Self { @@ -49,6 +57,8 @@ impl FromHermes for BooleanLiteral { } impl FromHermes for NullLiteral { fn convert(cx: &mut Context, node: NodePtr) -> Self { + let node_ref = node.as_ref(); + assert_eq!(node_ref.kind, NodeKind::NullLiteral); let range = convert_range(node); Self { loc: None, @@ -58,6 +68,8 @@ impl FromHermes for NullLiteral { } impl FromHermes for StringLiteral { fn convert(cx: &mut Context, node: NodePtr) -> Self { + let node_ref = node.as_ref(); + assert_eq!(node_ref.kind, NodeKind::StringLiteral); let range = convert_range(node); let value = convert_string_value( cx, @@ -70,8 +82,31 @@ impl FromHermes for StringLiteral { } } } +impl FromHermes for RegExpLiteral { + fn convert(cx: &mut Context, node: NodePtr) -> Self { + let node_ref = node.as_ref(); + assert_eq!(node_ref.kind, NodeKind::RegExpLiteral); + let range = convert_range(node); + let pattern = convert_string( + cx, + unsafe { hermes::parser::hermes_get_RegExpLiteral_pattern(node) }, + ); + let flags = convert_string( + cx, + unsafe { hermes::parser::hermes_get_RegExpLiteral_flags(node) }, + ); + Self { + pattern, + flags, + loc: None, + range: Some(range), + } + } +} impl FromHermes for Program { fn convert(cx: &mut Context, node: NodePtr) -> Self { + let node_ref = node.as_ref(); + assert_eq!(node_ref.kind, NodeKind::Program); let range = convert_range(node); let body = convert_vec( unsafe { hermes::parser::hermes_get_Program_body(node) }, @@ -88,6 +123,8 @@ impl FromHermes for Program { } impl FromHermes for ExpressionStatement { fn convert(cx: &mut Context, node: NodePtr) -> Self { + let node_ref = node.as_ref(); + assert_eq!(node_ref.kind, NodeKind::ExpressionStatement); let range = convert_range(node); let expression = Expression::convert( cx, @@ -104,6 +141,8 @@ impl FromHermes for ExpressionStatement { } impl FromHermes for BlockStatement { fn convert(cx: &mut Context, node: NodePtr) -> Self { + let node_ref = node.as_ref(); + assert_eq!(node_ref.kind, NodeKind::BlockStatement); let range = convert_range(node); let body = convert_vec( unsafe { hermes::parser::hermes_get_BlockStatement_body(node) }, @@ -118,6 +157,8 @@ impl FromHermes for BlockStatement { } impl FromHermes for EmptyStatement { fn convert(cx: &mut Context, node: NodePtr) -> Self { + let node_ref = node.as_ref(); + assert_eq!(node_ref.kind, NodeKind::EmptyStatement); let range = convert_range(node); Self { loc: None, @@ -127,6 +168,8 @@ impl FromHermes for EmptyStatement { } impl FromHermes for DebuggerStatement { fn convert(cx: &mut Context, node: NodePtr) -> Self { + let node_ref = node.as_ref(); + assert_eq!(node_ref.kind, NodeKind::DebuggerStatement); let range = convert_range(node); Self { loc: None, @@ -136,6 +179,8 @@ impl FromHermes for DebuggerStatement { } impl FromHermes for WithStatement { fn convert(cx: &mut Context, node: NodePtr) -> Self { + let node_ref = node.as_ref(); + assert_eq!(node_ref.kind, NodeKind::WithStatement); let range = convert_range(node); let object = Expression::convert( cx, @@ -155,6 +200,8 @@ impl FromHermes for WithStatement { } impl FromHermes for ReturnStatement { fn convert(cx: &mut Context, node: NodePtr) -> Self { + let node_ref = node.as_ref(); + assert_eq!(node_ref.kind, NodeKind::ReturnStatement); let range = convert_range(node); let argument = convert_option( unsafe { hermes::parser::hermes_get_ReturnStatement_argument(node) }, @@ -169,6 +216,8 @@ impl FromHermes for ReturnStatement { } impl FromHermes for LabeledStatement { fn convert(cx: &mut Context, node: NodePtr) -> Self { + let node_ref = node.as_ref(); + assert_eq!(node_ref.kind, NodeKind::LabeledStatement); let range = convert_range(node); let label = Identifier::convert( cx, @@ -188,6 +237,8 @@ impl FromHermes for LabeledStatement { } impl FromHermes for BreakStatement { fn convert(cx: &mut Context, node: NodePtr) -> Self { + let node_ref = node.as_ref(); + assert_eq!(node_ref.kind, NodeKind::BreakStatement); let range = convert_range(node); let label = convert_option( unsafe { hermes::parser::hermes_get_BreakStatement_label(node) }, @@ -202,6 +253,8 @@ impl FromHermes for BreakStatement { } impl FromHermes for ContinueStatement { fn convert(cx: &mut Context, node: NodePtr) -> Self { + let node_ref = node.as_ref(); + assert_eq!(node_ref.kind, NodeKind::ContinueStatement); let range = convert_range(node); let label = convert_option( unsafe { hermes::parser::hermes_get_ContinueStatement_label(node) }, @@ -216,6 +269,8 @@ impl FromHermes for ContinueStatement { } impl FromHermes for IfStatement { fn convert(cx: &mut Context, node: NodePtr) -> Self { + let node_ref = node.as_ref(); + assert_eq!(node_ref.kind, NodeKind::IfStatement); let range = convert_range(node); let test = Expression::convert( cx, @@ -240,6 +295,8 @@ impl FromHermes for IfStatement { } impl FromHermes for SwitchStatement { fn convert(cx: &mut Context, node: NodePtr) -> Self { + let node_ref = node.as_ref(); + assert_eq!(node_ref.kind, NodeKind::SwitchStatement); let range = convert_range(node); let discriminant = Expression::convert( cx, @@ -259,6 +316,8 @@ impl FromHermes for SwitchStatement { } impl FromHermes for SwitchCase { fn convert(cx: &mut Context, node: NodePtr) -> Self { + let node_ref = node.as_ref(); + assert_eq!(node_ref.kind, NodeKind::SwitchCase); let range = convert_range(node); let test = convert_option( unsafe { hermes::parser::hermes_get_SwitchCase_test(node) }, @@ -278,6 +337,8 @@ impl FromHermes for SwitchCase { } impl FromHermes for ThrowStatement { fn convert(cx: &mut Context, node: NodePtr) -> Self { + let node_ref = node.as_ref(); + assert_eq!(node_ref.kind, NodeKind::ThrowStatement); let range = convert_range(node); let argument = Expression::convert( cx, @@ -292,6 +353,8 @@ impl FromHermes for ThrowStatement { } impl FromHermes for TryStatement { fn convert(cx: &mut Context, node: NodePtr) -> Self { + let node_ref = node.as_ref(); + assert_eq!(node_ref.kind, NodeKind::TryStatement); let range = convert_range(node); let block = BlockStatement::convert( cx, @@ -316,6 +379,8 @@ impl FromHermes for TryStatement { } impl FromHermes for CatchClause { fn convert(cx: &mut Context, node: NodePtr) -> Self { + let node_ref = node.as_ref(); + assert_eq!(node_ref.kind, NodeKind::CatchClause); let range = convert_range(node); let param = convert_option( unsafe { hermes::parser::hermes_get_CatchClause_param(node) }, @@ -335,6 +400,8 @@ impl FromHermes for CatchClause { } impl FromHermes for WhileStatement { fn convert(cx: &mut Context, node: NodePtr) -> Self { + let node_ref = node.as_ref(); + assert_eq!(node_ref.kind, NodeKind::WhileStatement); let range = convert_range(node); let test = Expression::convert( cx, @@ -354,6 +421,8 @@ impl FromHermes for WhileStatement { } impl FromHermes for DoWhileStatement { fn convert(cx: &mut Context, node: NodePtr) -> Self { + let node_ref = node.as_ref(); + assert_eq!(node_ref.kind, NodeKind::DoWhileStatement); let range = convert_range(node); let body = Statement::convert( cx, @@ -373,6 +442,8 @@ impl FromHermes for DoWhileStatement { } impl FromHermes for ForStatement { fn convert(cx: &mut Context, node: NodePtr) -> Self { + let node_ref = node.as_ref(); + assert_eq!(node_ref.kind, NodeKind::ForStatement); let range = convert_range(node); let init = convert_option( unsafe { hermes::parser::hermes_get_ForStatement_init(node) }, @@ -402,6 +473,8 @@ impl FromHermes for ForStatement { } impl FromHermes for ForInStatement { fn convert(cx: &mut Context, node: NodePtr) -> Self { + let node_ref = node.as_ref(); + assert_eq!(node_ref.kind, NodeKind::ForInStatement); let range = convert_range(node); let left = ForInInit::convert( cx, @@ -426,6 +499,8 @@ impl FromHermes for ForInStatement { } impl FromHermes for ForOfStatement { fn convert(cx: &mut Context, node: NodePtr) -> Self { + let node_ref = node.as_ref(); + assert_eq!(node_ref.kind, NodeKind::ForOfStatement); let range = convert_range(node); let is_await = unsafe { hermes::parser::hermes_get_ForOfStatement_await(node) }; let left = ForInInit::convert( @@ -452,10 +527,12 @@ impl FromHermes for ForOfStatement { } impl FromHermes for ClassBody { fn convert(cx: &mut Context, node: NodePtr) -> Self { + let node_ref = node.as_ref(); + assert_eq!(node_ref.kind, NodeKind::ClassBody); let range = convert_range(node); let body = convert_vec( unsafe { hermes::parser::hermes_get_ClassBody_body(node) }, - |node| MethodDefinition::convert(cx, node), + |node| ClassItem::convert(cx, node), ); Self { body, @@ -466,6 +543,8 @@ impl FromHermes for ClassBody { } impl FromHermes for MethodDefinition { fn convert(cx: &mut Context, node: NodePtr) -> Self { + let node_ref = node.as_ref(); + assert_eq!(node_ref.kind, NodeKind::MethodDefinition); let range = convert_range(node); let key = Expression::convert( cx, @@ -498,6 +577,8 @@ impl FromHermes for MethodDefinition { } impl FromHermes for VariableDeclaration { fn convert(cx: &mut Context, node: NodePtr) -> Self { + let node_ref = node.as_ref(); + assert_eq!(node_ref.kind, NodeKind::VariableDeclaration); let range = convert_range(node); let kind = VariableDeclarationKind::convert( cx, @@ -517,6 +598,8 @@ impl FromHermes for VariableDeclaration { } impl FromHermes for VariableDeclarator { fn convert(cx: &mut Context, node: NodePtr) -> Self { + let node_ref = node.as_ref(); + assert_eq!(node_ref.kind, NodeKind::VariableDeclarator); let range = convert_range(node); let id = Pattern::convert( cx, @@ -536,6 +619,8 @@ impl FromHermes for VariableDeclarator { } impl FromHermes for ThisExpression { fn convert(cx: &mut Context, node: NodePtr) -> Self { + let node_ref = node.as_ref(); + assert_eq!(node_ref.kind, NodeKind::ThisExpression); let range = convert_range(node); Self { loc: None, @@ -545,6 +630,8 @@ impl FromHermes for ThisExpression { } impl FromHermes for ArrayExpression { fn convert(cx: &mut Context, node: NodePtr) -> Self { + let node_ref = node.as_ref(); + assert_eq!(node_ref.kind, NodeKind::ArrayExpression); let range = convert_range(node); let elements = convert_array_expression_elements( cx, @@ -559,6 +646,8 @@ impl FromHermes for ArrayExpression { } impl FromHermes for ObjectExpression { fn convert(cx: &mut Context, node: NodePtr) -> Self { + let node_ref = node.as_ref(); + assert_eq!(node_ref.kind, NodeKind::ObjectExpression); let range = convert_range(node); let properties = convert_vec( unsafe { hermes::parser::hermes_get_ObjectExpression_properties(node) }, @@ -573,6 +662,8 @@ impl FromHermes for ObjectExpression { } impl FromHermes for Property { fn convert(cx: &mut Context, node: NodePtr) -> Self { + let node_ref = node.as_ref(); + assert_eq!(node_ref.kind, NodeKind::Property); let range = convert_range(node); let key = Expression::convert( cx, @@ -605,6 +696,8 @@ impl FromHermes for Property { } impl FromHermes for UnaryExpression { fn convert(cx: &mut Context, node: NodePtr) -> Self { + let node_ref = node.as_ref(); + assert_eq!(node_ref.kind, NodeKind::UnaryExpression); let range = convert_range(node); let operator = UnaryOperator::convert( cx, @@ -626,6 +719,8 @@ impl FromHermes for UnaryExpression { } impl FromHermes for UpdateExpression { fn convert(cx: &mut Context, node: NodePtr) -> Self { + let node_ref = node.as_ref(); + assert_eq!(node_ref.kind, NodeKind::UpdateExpression); let range = convert_range(node); let operator = UpdateOperator::convert( cx, @@ -647,6 +742,8 @@ impl FromHermes for UpdateExpression { } impl FromHermes for BinaryExpression { fn convert(cx: &mut Context, node: NodePtr) -> Self { + let node_ref = node.as_ref(); + assert_eq!(node_ref.kind, NodeKind::BinaryExpression); let range = convert_range(node); let left = Expression::convert( cx, @@ -671,6 +768,8 @@ impl FromHermes for BinaryExpression { } impl FromHermes for AssignmentExpression { fn convert(cx: &mut Context, node: NodePtr) -> Self { + let node_ref = node.as_ref(); + assert_eq!(node_ref.kind, NodeKind::AssignmentExpression); let range = convert_range(node); let operator = AssignmentOperator::convert( cx, @@ -695,6 +794,8 @@ impl FromHermes for AssignmentExpression { } impl FromHermes for LogicalExpression { fn convert(cx: &mut Context, node: NodePtr) -> Self { + let node_ref = node.as_ref(); + assert_eq!(node_ref.kind, NodeKind::LogicalExpression); let range = convert_range(node); let operator = LogicalOperator::convert( cx, @@ -719,12 +820,14 @@ impl FromHermes for LogicalExpression { } impl FromHermes for MemberExpression { fn convert(cx: &mut Context, node: NodePtr) -> Self { + let node_ref = node.as_ref(); + assert_eq!(node_ref.kind, NodeKind::MemberExpression); let range = convert_range(node); let object = ExpressionOrSuper::convert( cx, unsafe { hermes::parser::hermes_get_MemberExpression_object(node) }, ); - let property = Expression::convert( + let property = ExpressionOrPrivateIdentifier::convert( cx, unsafe { hermes::parser::hermes_get_MemberExpression_property(node) }, ); @@ -742,6 +845,8 @@ impl FromHermes for MemberExpression { } impl FromHermes for ConditionalExpression { fn convert(cx: &mut Context, node: NodePtr) -> Self { + let node_ref = node.as_ref(); + assert_eq!(node_ref.kind, NodeKind::ConditionalExpression); let range = convert_range(node); let test = Expression::convert( cx, @@ -766,6 +871,8 @@ impl FromHermes for ConditionalExpression { } impl FromHermes for CallExpression { fn convert(cx: &mut Context, node: NodePtr) -> Self { + let node_ref = node.as_ref(); + assert_eq!(node_ref.kind, NodeKind::CallExpression); let range = convert_range(node); let callee = ExpressionOrSuper::convert( cx, @@ -785,6 +892,8 @@ impl FromHermes for CallExpression { } impl FromHermes for NewExpression { fn convert(cx: &mut Context, node: NodePtr) -> Self { + let node_ref = node.as_ref(); + assert_eq!(node_ref.kind, NodeKind::NewExpression); let range = convert_range(node); let callee = Expression::convert( cx, @@ -804,6 +913,8 @@ impl FromHermes for NewExpression { } impl FromHermes for SequenceExpression { fn convert(cx: &mut Context, node: NodePtr) -> Self { + let node_ref = node.as_ref(); + assert_eq!(node_ref.kind, NodeKind::SequenceExpression); let range = convert_range(node); let expressions = convert_vec( unsafe { hermes::parser::hermes_get_SequenceExpression_expressions(node) }, @@ -818,6 +929,8 @@ impl FromHermes for SequenceExpression { } impl FromHermes for Super { fn convert(cx: &mut Context, node: NodePtr) -> Self { + let node_ref = node.as_ref(); + assert_eq!(node_ref.kind, NodeKind::Super); let range = convert_range(node); Self { loc: None, @@ -827,6 +940,8 @@ impl FromHermes for Super { } impl FromHermes for SpreadElement { fn convert(cx: &mut Context, node: NodePtr) -> Self { + let node_ref = node.as_ref(); + assert_eq!(node_ref.kind, NodeKind::SpreadElement); let range = convert_range(node); let argument = Expression::convert( cx, @@ -841,6 +956,8 @@ impl FromHermes for SpreadElement { } impl FromHermes for YieldExpression { fn convert(cx: &mut Context, node: NodePtr) -> Self { + let node_ref = node.as_ref(); + assert_eq!(node_ref.kind, NodeKind::YieldExpression); let range = convert_range(node); let argument = convert_option( unsafe { hermes::parser::hermes_get_YieldExpression_argument(node) }, @@ -859,6 +976,8 @@ impl FromHermes for YieldExpression { } impl FromHermes for ImportDeclaration { fn convert(cx: &mut Context, node: NodePtr) -> Self { + let node_ref = node.as_ref(); + assert_eq!(node_ref.kind, NodeKind::ImportDeclaration); let range = convert_range(node); let specifiers = convert_vec( unsafe { hermes::parser::hermes_get_ImportDeclaration_specifiers(node) }, @@ -878,6 +997,8 @@ impl FromHermes for ImportDeclaration { } impl FromHermes for ImportSpecifier { fn convert(cx: &mut Context, node: NodePtr) -> Self { + let node_ref = node.as_ref(); + assert_eq!(node_ref.kind, NodeKind::ImportSpecifier); let range = convert_range(node); let imported = Identifier::convert( cx, @@ -897,6 +1018,8 @@ impl FromHermes for ImportSpecifier { } impl FromHermes for ImportDefaultSpecifier { fn convert(cx: &mut Context, node: NodePtr) -> Self { + let node_ref = node.as_ref(); + assert_eq!(node_ref.kind, NodeKind::ImportDefaultSpecifier); let range = convert_range(node); let local = Identifier::convert( cx, @@ -911,6 +1034,8 @@ impl FromHermes for ImportDefaultSpecifier { } impl FromHermes for ImportNamespaceSpecifier { fn convert(cx: &mut Context, node: NodePtr) -> Self { + let node_ref = node.as_ref(); + assert_eq!(node_ref.kind, NodeKind::ImportNamespaceSpecifier); let range = convert_range(node); let local = Identifier::convert( cx, @@ -925,6 +1050,8 @@ impl FromHermes for ImportNamespaceSpecifier { } impl FromHermes for ExportNamedDeclaration { fn convert(cx: &mut Context, node: NodePtr) -> Self { + let node_ref = node.as_ref(); + assert_eq!(node_ref.kind, NodeKind::ExportNamedDeclaration); let range = convert_range(node); let declaration = convert_option( unsafe { @@ -953,6 +1080,8 @@ impl FromHermes for ExportNamedDeclaration { } impl FromHermes for ExportSpecifier { fn convert(cx: &mut Context, node: NodePtr) -> Self { + let node_ref = node.as_ref(); + assert_eq!(node_ref.kind, NodeKind::ExportSpecifier); let range = convert_range(node); let exported = Identifier::convert( cx, @@ -967,8 +1096,10 @@ impl FromHermes for ExportSpecifier { } impl FromHermes for ExportDefaultDeclaration { fn convert(cx: &mut Context, node: NodePtr) -> Self { + let node_ref = node.as_ref(); + assert_eq!(node_ref.kind, NodeKind::ExportDefaultDeclaration); let range = convert_range(node); - let declaration = Declaration::convert( + let declaration = DeclarationOrExpression::convert( cx, unsafe { hermes::parser::hermes_get_ExportDefaultDeclaration_declaration(node) @@ -983,6 +1114,8 @@ impl FromHermes for ExportDefaultDeclaration { } impl FromHermes for ExportAllDeclaration { fn convert(cx: &mut Context, node: NodePtr) -> Self { + let node_ref = node.as_ref(); + assert_eq!(node_ref.kind, NodeKind::ExportAllDeclaration); let range = convert_range(node); let source = _Literal::convert( cx, @@ -999,6 +1132,8 @@ impl FromHermes for ExportAllDeclaration { } impl FromHermes for JSXIdentifier { fn convert(cx: &mut Context, node: NodePtr) -> Self { + let node_ref = node.as_ref(); + assert_eq!(node_ref.kind, NodeKind::JSXIdentifier); let range = convert_range(node); let name = convert_string( cx, @@ -1015,6 +1150,8 @@ impl FromHermes for JSXIdentifier { } impl FromHermes for JSXNamespacedName { fn convert(cx: &mut Context, node: NodePtr) -> Self { + let node_ref = node.as_ref(); + assert_eq!(node_ref.kind, NodeKind::JSXNamespacedName); let range = convert_range(node); let namespace = JSXIdentifier::convert( cx, @@ -1034,6 +1171,8 @@ impl FromHermes for JSXNamespacedName { } impl FromHermes for JSXMemberExpression { fn convert(cx: &mut Context, node: NodePtr) -> Self { + let node_ref = node.as_ref(); + assert_eq!(node_ref.kind, NodeKind::JSXMemberExpression); let range = convert_range(node); let object = JSXMemberExpressionOrIdentifier::convert( cx, @@ -1053,6 +1192,8 @@ impl FromHermes for JSXMemberExpression { } impl FromHermes for JSXEmptyExpression { fn convert(cx: &mut Context, node: NodePtr) -> Self { + let node_ref = node.as_ref(); + assert_eq!(node_ref.kind, NodeKind::JSXEmptyExpression); let range = convert_range(node); Self { loc: None, @@ -1062,6 +1203,8 @@ impl FromHermes for JSXEmptyExpression { } impl FromHermes for JSXExpressionContainer { fn convert(cx: &mut Context, node: NodePtr) -> Self { + let node_ref = node.as_ref(); + assert_eq!(node_ref.kind, NodeKind::JSXExpressionContainer); let range = convert_range(node); let expression = JSXExpressionOrEmpty::convert( cx, @@ -1076,6 +1219,8 @@ impl FromHermes for JSXExpressionContainer { } impl FromHermes for JSXSpreadChild { fn convert(cx: &mut Context, node: NodePtr) -> Self { + let node_ref = node.as_ref(); + assert_eq!(node_ref.kind, NodeKind::JSXSpreadChild); let range = convert_range(node); let expression = Expression::convert( cx, @@ -1090,6 +1235,8 @@ impl FromHermes for JSXSpreadChild { } impl FromHermes for JSXOpeningElement { fn convert(cx: &mut Context, node: NodePtr) -> Self { + let node_ref = node.as_ref(); + assert_eq!(node_ref.kind, NodeKind::JSXOpeningElement); let range = convert_range(node); let name = JSXElementName::convert( cx, @@ -1113,6 +1260,8 @@ impl FromHermes for JSXOpeningElement { } impl FromHermes for JSXClosingElement { fn convert(cx: &mut Context, node: NodePtr) -> Self { + let node_ref = node.as_ref(); + assert_eq!(node_ref.kind, NodeKind::JSXClosingElement); let range = convert_range(node); let name = JSXElementName::convert( cx, @@ -1127,6 +1276,8 @@ impl FromHermes for JSXClosingElement { } impl FromHermes for JSXAttribute { fn convert(cx: &mut Context, node: NodePtr) -> Self { + let node_ref = node.as_ref(); + assert_eq!(node_ref.kind, NodeKind::JSXAttribute); let range = convert_range(node); let name = JSXIdentifierOrNamespacedName::convert( cx, @@ -1146,6 +1297,8 @@ impl FromHermes for JSXAttribute { } impl FromHermes for JSXSpreadAttribute { fn convert(cx: &mut Context, node: NodePtr) -> Self { + let node_ref = node.as_ref(); + assert_eq!(node_ref.kind, NodeKind::JSXSpreadAttribute); let range = convert_range(node); let argument = Expression::convert( cx, @@ -1160,6 +1313,8 @@ impl FromHermes for JSXSpreadAttribute { } impl FromHermes for JSXText { fn convert(cx: &mut Context, node: NodePtr) -> Self { + let node_ref = node.as_ref(); + assert_eq!(node_ref.kind, NodeKind::JSXText); let range = convert_range(node); let value = convert_string_value( cx, @@ -1177,8 +1332,31 @@ impl FromHermes for JSXText { } } } +impl FromHermes for JSXStringLiteral { + fn convert(cx: &mut Context, node: NodePtr) -> Self { + let node_ref = node.as_ref(); + assert_eq!(node_ref.kind, NodeKind::JSXStringLiteral); + let range = convert_range(node); + let value = convert_string_value( + cx, + unsafe { hermes::parser::hermes_get_JSXStringLiteral_value(node) }, + ); + let raw = convert_string( + cx, + unsafe { hermes::parser::hermes_get_JSXStringLiteral_raw(node) }, + ); + Self { + value, + raw, + loc: None, + range: Some(range), + } + } +} impl FromHermes for JSXElement { fn convert(cx: &mut Context, node: NodePtr) -> Self { + let node_ref = node.as_ref(); + assert_eq!(node_ref.kind, NodeKind::JSXElement); let range = convert_range(node); let opening_element = JSXOpeningElement::convert( cx, @@ -1203,6 +1381,8 @@ impl FromHermes for JSXElement { } impl FromHermes for JSXFragment { fn convert(cx: &mut Context, node: NodePtr) -> Self { + let node_ref = node.as_ref(); + assert_eq!(node_ref.kind, NodeKind::JSXFragment); let range = convert_range(node); let opening_fragment = JSXOpeningFragment::convert( cx, @@ -1227,6 +1407,8 @@ impl FromHermes for JSXFragment { } impl FromHermes for JSXOpeningFragment { fn convert(cx: &mut Context, node: NodePtr) -> Self { + let node_ref = node.as_ref(); + assert_eq!(node_ref.kind, NodeKind::JSXOpeningFragment); let range = convert_range(node); Self { loc: None, @@ -1236,6 +1418,8 @@ impl FromHermes for JSXOpeningFragment { } impl FromHermes for JSXClosingFragment { fn convert(cx: &mut Context, node: NodePtr) -> Self { + let node_ref = node.as_ref(); + assert_eq!(node_ref.kind, NodeKind::JSXClosingFragment); let range = convert_range(node); Self { loc: None, @@ -1245,6 +1429,8 @@ impl FromHermes for JSXClosingFragment { } impl FromHermes for ArrayPattern { fn convert(cx: &mut Context, node: NodePtr) -> Self { + let node_ref = node.as_ref(); + assert_eq!(node_ref.kind, NodeKind::ArrayPattern); let range = convert_range(node); let elements = convert_vec_of_option( unsafe { hermes::parser::hermes_get_ArrayPattern_elements(node) }, @@ -1259,6 +1445,8 @@ impl FromHermes for ArrayPattern { } impl FromHermes for ObjectPattern { fn convert(cx: &mut Context, node: NodePtr) -> Self { + let node_ref = node.as_ref(); + assert_eq!(node_ref.kind, NodeKind::ObjectPattern); let range = convert_range(node); let properties = convert_vec( unsafe { hermes::parser::hermes_get_ObjectPattern_properties(node) }, @@ -1273,6 +1461,8 @@ impl FromHermes for ObjectPattern { } impl FromHermes for RestElement { fn convert(cx: &mut Context, node: NodePtr) -> Self { + let node_ref = node.as_ref(); + assert_eq!(node_ref.kind, NodeKind::RestElement); let range = convert_range(node); let argument = Pattern::convert( cx, @@ -1287,6 +1477,8 @@ impl FromHermes for RestElement { } impl FromHermes for AssignmentPattern { fn convert(cx: &mut Context, node: NodePtr) -> Self { + let node_ref = node.as_ref(); + assert_eq!(node_ref.kind, NodeKind::AssignmentPattern); let range = convert_range(node); let left = Pattern::convert( cx, @@ -1306,6 +1498,8 @@ impl FromHermes for AssignmentPattern { } impl FromHermes for TemplateLiteral { fn convert(cx: &mut Context, node: NodePtr) -> Self { + let node_ref = node.as_ref(); + assert_eq!(node_ref.kind, NodeKind::TemplateLiteral); let range = convert_range(node); let quasis = convert_vec( unsafe { hermes::parser::hermes_get_TemplateLiteral_quasis(node) }, @@ -1325,6 +1519,8 @@ impl FromHermes for TemplateLiteral { } impl FromHermes for TaggedTemplateExpression { fn convert(cx: &mut Context, node: NodePtr) -> Self { + let node_ref = node.as_ref(); + assert_eq!(node_ref.kind, NodeKind::TaggedTemplateExpression); let range = convert_range(node); let tag = Expression::convert( cx, @@ -1344,6 +1540,8 @@ impl FromHermes for TaggedTemplateExpression { } impl FromHermes for MetaProperty { fn convert(cx: &mut Context, node: NodePtr) -> Self { + let node_ref = node.as_ref(); + assert_eq!(node_ref.kind, NodeKind::MetaProperty); let range = convert_range(node); let meta = Identifier::convert( cx, @@ -1363,6 +1561,8 @@ impl FromHermes for MetaProperty { } impl FromHermes for AwaitExpression { fn convert(cx: &mut Context, node: NodePtr) -> Self { + let node_ref = node.as_ref(); + assert_eq!(node_ref.kind, NodeKind::AwaitExpression); let range = convert_range(node); let argument = Expression::convert( cx, @@ -1377,6 +1577,8 @@ impl FromHermes for AwaitExpression { } impl FromHermes for OptionalMemberExpression { fn convert(cx: &mut Context, node: NodePtr) -> Self { + let node_ref = node.as_ref(); + assert_eq!(node_ref.kind, NodeKind::OptionalMemberExpression); let range = convert_range(node); let object = Expression::convert( cx, @@ -1404,6 +1606,8 @@ impl FromHermes for OptionalMemberExpression { } impl FromHermes for OptionalCallExpression { fn convert(cx: &mut Context, node: NodePtr) -> Self { + let node_ref = node.as_ref(); + assert_eq!(node_ref.kind, NodeKind::OptionalCallExpression); let range = convert_range(node); let callee = ExpressionOrSuper::convert( cx, @@ -1427,6 +1631,8 @@ impl FromHermes for OptionalCallExpression { } impl FromHermes for ImportExpression { fn convert(cx: &mut Context, node: NodePtr) -> Self { + let node_ref = node.as_ref(); + assert_eq!(node_ref.kind, NodeKind::ImportExpression); let range = convert_range(node); let source = Expression::convert( cx, @@ -1439,6 +1645,117 @@ impl FromHermes for ImportExpression { } } } +impl FromHermes for ClassProperty { + fn convert(cx: &mut Context, node: NodePtr) -> Self { + let node_ref = node.as_ref(); + assert_eq!(node_ref.kind, NodeKind::ClassProperty); + let range = convert_range(node); + let key = Expression::convert( + cx, + unsafe { hermes::parser::hermes_get_ClassProperty_key(node) }, + ); + let value = convert_option( + unsafe { hermes::parser::hermes_get_ClassProperty_value(node) }, + |node| Expression::convert(cx, node), + ); + let is_computed = unsafe { + hermes::parser::hermes_get_ClassProperty_computed(node) + }; + let is_static = unsafe { hermes::parser::hermes_get_ClassProperty_static(node) }; + Self { + key, + value, + is_computed, + is_static, + loc: None, + range: Some(range), + } + } +} +impl FromHermes for ClassPrivateProperty { + fn convert(cx: &mut Context, node: NodePtr) -> Self { + let node_ref = node.as_ref(); + assert_eq!(node_ref.kind, NodeKind::ClassPrivateProperty); + let range = convert_range(node); + let key = ExpressionOrPrivateIdentifier::convert( + cx, + unsafe { hermes::parser::hermes_get_ClassPrivateProperty_key(node) }, + ); + let value = convert_option( + unsafe { hermes::parser::hermes_get_ClassPrivateProperty_value(node) }, + |node| Expression::convert(cx, node), + ); + let is_static = unsafe { + hermes::parser::hermes_get_ClassPrivateProperty_static(node) + }; + Self { + key, + value, + is_static, + loc: None, + range: Some(range), + } + } +} +impl FromHermes for PrivateName { + fn convert(cx: &mut Context, node: NodePtr) -> Self { + let node_ref = node.as_ref(); + assert_eq!(node_ref.kind, NodeKind::PrivateName); + let range = convert_range(node); + let id = Identifier::convert( + cx, + unsafe { hermes::parser::hermes_get_PrivateName_id(node) }, + ); + Self { + id, + loc: None, + range: Some(range), + } + } +} +impl FromHermes for CoverTypedIdentifier { + fn convert(cx: &mut Context, node: NodePtr) -> Self { + let node_ref = node.as_ref(); + assert_eq!(node_ref.kind, NodeKind::CoverTypedIdentifier); + let range = convert_range(node); + let left = Identifier::convert( + cx, + unsafe { hermes::parser::hermes_get_CoverTypedIdentifier_left(node) }, + ); + let right = convert_option( + unsafe { hermes::parser::hermes_get_CoverTypedIdentifier_right(node) }, + |node| TypeAnnotation::convert(cx, node), + ); + Self { + left, + right, + loc: None, + range: Some(range), + } + } +} +impl FromHermes for TSTypeAnnotation { + fn convert(cx: &mut Context, node: NodePtr) -> Self { + let node_ref = node.as_ref(); + assert_eq!(node_ref.kind, NodeKind::TSTypeAnnotation); + let range = convert_range(node); + Self { + loc: None, + range: Some(range), + } + } +} +impl FromHermes for TSTypeAliasDeclaration { + fn convert(cx: &mut Context, node: NodePtr) -> Self { + let node_ref = node.as_ref(); + assert_eq!(node_ref.kind, NodeKind::TSTypeAliasDeclaration); + let range = convert_range(node); + Self { + loc: None, + range: Some(range), + } + } +} impl FromHermes for Statement { fn convert(cx: &mut Context, node: NodePtr) -> Self { let node_ref = node.as_ref(); @@ -1515,6 +1832,10 @@ impl FromHermes for Statement { let node = TryStatement::convert(cx, node); Statement::TryStatement(Box::new(node)) } + NodeKind::TSTypeAliasDeclaration => { + let node = TSTypeAliasDeclaration::convert(cx, node); + Statement::TSTypeAliasDeclaration(Box::new(node)) + } NodeKind::VariableDeclaration => { let node = VariableDeclaration::convert(cx, node); Statement::VariableDeclaration(Box::new(node)) @@ -1527,7 +1848,11 @@ impl FromHermes for Statement { let node = WithStatement::convert(cx, node); Statement::WithStatement(Box::new(node)) } - _ => panic!("Unexpected node"), + _ => { + panic!( + "Unexpected node kind `{:?}` for `{}`", node_ref.kind, "Statement" + ) + } } } } @@ -1571,6 +1896,10 @@ impl FromHermes for Expression { let node = ConditionalExpression::convert(cx, node); Expression::ConditionalExpression(Box::new(node)) } + NodeKind::CoverTypedIdentifier => { + let node = CoverTypedIdentifier::convert(cx, node); + Expression::CoverTypedIdentifier(Box::new(node)) + } NodeKind::FunctionExpression => { let node = FunctionExpression::convert(cx, node); Expression::FunctionExpression(Box::new(node)) @@ -1587,6 +1916,10 @@ impl FromHermes for Expression { let node = JSXElement::convert(cx, node); Expression::JSXElement(Box::new(node)) } + NodeKind::JSXFragment => { + let node = JSXFragment::convert(cx, node); + Expression::JSXFragment(Box::new(node)) + } NodeKind::LogicalExpression => { let node = LogicalExpression::convert(cx, node); Expression::LogicalExpression(Box::new(node)) @@ -1623,6 +1956,10 @@ impl FromHermes for Expression { let node = OptionalMemberExpression::convert(cx, node); Expression::OptionalMemberExpression(Box::new(node)) } + NodeKind::RegExpLiteral => { + let node = RegExpLiteral::convert(cx, node); + Expression::RegExpLiteral(Box::new(node)) + } NodeKind::SequenceExpression => { let node = SequenceExpression::convert(cx, node); Expression::SequenceExpression(Box::new(node)) @@ -1655,7 +1992,11 @@ impl FromHermes for Expression { let node = YieldExpression::convert(cx, node); Expression::YieldExpression(Box::new(node)) } - _ => panic!("Unexpected node"), + _ => { + panic!( + "Unexpected node kind `{:?}` for `{}`", node_ref.kind, "Expression" + ) + } } } } @@ -1679,7 +2020,9 @@ impl FromHermes for _Literal { let node = NumericLiteral::convert(cx, node); _Literal::NumericLiteral(Box::new(node)) } - _ => panic!("Unexpected node"), + _ => { + panic!("Unexpected node kind `{:?}` for `{}`", node_ref.kind, "_Literal") + } } } } @@ -1699,7 +2042,15 @@ impl FromHermes for Declaration { let node = VariableDeclaration::convert(cx, node); Declaration::VariableDeclaration(Box::new(node)) } - _ => panic!("Unexpected node"), + NodeKind::TSTypeAliasDeclaration => { + let node = TSTypeAliasDeclaration::convert(cx, node); + Declaration::TSTypeAliasDeclaration(Box::new(node)) + } + _ => { + panic!( + "Unexpected node kind `{:?}` for `{}`", node_ref.kind, "Declaration" + ) + } } } } @@ -1719,7 +2070,12 @@ impl FromHermes for ImportDeclarationSpecifier { let node = ImportNamespaceSpecifier::convert(cx, node); ImportDeclarationSpecifier::ImportNamespaceSpecifier(Box::new(node)) } - _ => panic!("Unexpected node"), + _ => { + panic!( + "Unexpected node kind `{:?}` for `{}`", node_ref.kind, + "ImportDeclarationSpecifier" + ) + } } } } @@ -1823,6 +2179,10 @@ impl FromHermes for ModuleItem { let node = TryStatement::convert(cx, node); ModuleItem::Statement(Statement::TryStatement(Box::new(node))) } + NodeKind::TSTypeAliasDeclaration => { + let node = TSTypeAliasDeclaration::convert(cx, node); + ModuleItem::Statement(Statement::TSTypeAliasDeclaration(Box::new(node))) + } NodeKind::VariableDeclaration => { let node = VariableDeclaration::convert(cx, node); ModuleItem::Statement(Statement::VariableDeclaration(Box::new(node))) @@ -1835,7 +2195,11 @@ impl FromHermes for ModuleItem { let node = WithStatement::convert(cx, node); ModuleItem::Statement(Statement::WithStatement(Box::new(node))) } - _ => panic!("Unexpected node"), + _ => { + panic!( + "Unexpected node kind `{:?}` for `{}`", node_ref.kind, "ModuleItem" + ) + } } } } @@ -1859,7 +2223,12 @@ impl FromHermes for ImportOrExportDeclaration { let node = ExportAllDeclaration::convert(cx, node); ImportOrExportDeclaration::ExportAllDeclaration(Box::new(node)) } - _ => panic!("Unexpected node"), + _ => { + panic!( + "Unexpected node kind `{:?}` for `{}`", node_ref.kind, + "ImportOrExportDeclaration" + ) + } } } } @@ -1917,6 +2286,12 @@ impl FromHermes for ExpressionOrSuper { Expression::ConditionalExpression(Box::new(node)), ) } + NodeKind::CoverTypedIdentifier => { + let node = CoverTypedIdentifier::convert(cx, node); + ExpressionOrSuper::Expression( + Expression::CoverTypedIdentifier(Box::new(node)), + ) + } NodeKind::FunctionExpression => { let node = FunctionExpression::convert(cx, node); ExpressionOrSuper::Expression( @@ -1937,6 +2312,10 @@ impl FromHermes for ExpressionOrSuper { let node = JSXElement::convert(cx, node); ExpressionOrSuper::Expression(Expression::JSXElement(Box::new(node))) } + NodeKind::JSXFragment => { + let node = JSXFragment::convert(cx, node); + ExpressionOrSuper::Expression(Expression::JSXFragment(Box::new(node))) + } NodeKind::LogicalExpression => { let node = LogicalExpression::convert(cx, node); ExpressionOrSuper::Expression( @@ -1983,6 +2362,10 @@ impl FromHermes for ExpressionOrSuper { Expression::OptionalMemberExpression(Box::new(node)), ) } + NodeKind::RegExpLiteral => { + let node = RegExpLiteral::convert(cx, node); + ExpressionOrSuper::Expression(Expression::RegExpLiteral(Box::new(node))) + } NodeKind::SequenceExpression => { let node = SequenceExpression::convert(cx, node); ExpressionOrSuper::Expression( @@ -2031,7 +2414,12 @@ impl FromHermes for ExpressionOrSuper { let node = Super::convert(cx, node); ExpressionOrSuper::Super(Box::new(node)) } - _ => panic!("Unexpected node"), + _ => { + panic!( + "Unexpected node kind `{:?}` for `{}`", node_ref.kind, + "ExpressionOrSuper" + ) + } } } } @@ -2093,6 +2481,12 @@ impl FromHermes for ExpressionOrSpread { Expression::ConditionalExpression(Box::new(node)), ) } + NodeKind::CoverTypedIdentifier => { + let node = CoverTypedIdentifier::convert(cx, node); + ExpressionOrSpread::Expression( + Expression::CoverTypedIdentifier(Box::new(node)), + ) + } NodeKind::FunctionExpression => { let node = FunctionExpression::convert(cx, node); ExpressionOrSpread::Expression( @@ -2113,6 +2507,10 @@ impl FromHermes for ExpressionOrSpread { let node = JSXElement::convert(cx, node); ExpressionOrSpread::Expression(Expression::JSXElement(Box::new(node))) } + NodeKind::JSXFragment => { + let node = JSXFragment::convert(cx, node); + ExpressionOrSpread::Expression(Expression::JSXFragment(Box::new(node))) + } NodeKind::LogicalExpression => { let node = LogicalExpression::convert(cx, node); ExpressionOrSpread::Expression( @@ -2161,6 +2559,10 @@ impl FromHermes for ExpressionOrSpread { Expression::OptionalMemberExpression(Box::new(node)), ) } + NodeKind::RegExpLiteral => { + let node = RegExpLiteral::convert(cx, node); + ExpressionOrSpread::Expression(Expression::RegExpLiteral(Box::new(node))) + } NodeKind::SequenceExpression => { let node = SequenceExpression::convert(cx, node); ExpressionOrSpread::Expression( @@ -2211,7 +2613,12 @@ impl FromHermes for ExpressionOrSpread { let node = SpreadElement::convert(cx, node); ExpressionOrSpread::SpreadElement(Box::new(node)) } - _ => panic!("Unexpected node"), + _ => { + panic!( + "Unexpected node kind `{:?}` for `{}`", node_ref.kind, + "ExpressionOrSpread" + ) + } } } } @@ -2265,6 +2672,12 @@ impl FromHermes for FunctionBody { Expression::ConditionalExpression(Box::new(node)), ) } + NodeKind::CoverTypedIdentifier => { + let node = CoverTypedIdentifier::convert(cx, node); + FunctionBody::Expression( + Expression::CoverTypedIdentifier(Box::new(node)), + ) + } NodeKind::FunctionExpression => { let node = FunctionExpression::convert(cx, node); FunctionBody::Expression(Expression::FunctionExpression(Box::new(node))) @@ -2281,6 +2694,10 @@ impl FromHermes for FunctionBody { let node = JSXElement::convert(cx, node); FunctionBody::Expression(Expression::JSXElement(Box::new(node))) } + NodeKind::JSXFragment => { + let node = JSXFragment::convert(cx, node); + FunctionBody::Expression(Expression::JSXFragment(Box::new(node))) + } NodeKind::LogicalExpression => { let node = LogicalExpression::convert(cx, node); FunctionBody::Expression(Expression::LogicalExpression(Box::new(node))) @@ -2321,6 +2738,10 @@ impl FromHermes for FunctionBody { Expression::OptionalMemberExpression(Box::new(node)), ) } + NodeKind::RegExpLiteral => { + let node = RegExpLiteral::convert(cx, node); + FunctionBody::Expression(Expression::RegExpLiteral(Box::new(node))) + } NodeKind::SequenceExpression => { let node = SequenceExpression::convert(cx, node); FunctionBody::Expression(Expression::SequenceExpression(Box::new(node))) @@ -2355,7 +2776,11 @@ impl FromHermes for FunctionBody { let node = YieldExpression::convert(cx, node); FunctionBody::Expression(Expression::YieldExpression(Box::new(node))) } - _ => panic!("Unexpected node"), + _ => { + panic!( + "Unexpected node kind `{:?}` for `{}`", node_ref.kind, "FunctionBody" + ) + } } } } @@ -2383,7 +2808,7 @@ impl FromHermes for Pattern { let node = AssignmentPattern::convert(cx, node); Pattern::AssignmentPattern(Box::new(node)) } - _ => panic!("Unexpected node"), + _ => panic!("Unexpected node kind `{:?}` for `{}`", node_ref.kind, "Pattern"), } } } @@ -2427,6 +2852,10 @@ impl FromHermes for ForInit { let node = ConditionalExpression::convert(cx, node); ForInit::Expression(Expression::ConditionalExpression(Box::new(node))) } + NodeKind::CoverTypedIdentifier => { + let node = CoverTypedIdentifier::convert(cx, node); + ForInit::Expression(Expression::CoverTypedIdentifier(Box::new(node))) + } NodeKind::FunctionExpression => { let node = FunctionExpression::convert(cx, node); ForInit::Expression(Expression::FunctionExpression(Box::new(node))) @@ -2443,6 +2872,10 @@ impl FromHermes for ForInit { let node = JSXElement::convert(cx, node); ForInit::Expression(Expression::JSXElement(Box::new(node))) } + NodeKind::JSXFragment => { + let node = JSXFragment::convert(cx, node); + ForInit::Expression(Expression::JSXFragment(Box::new(node))) + } NodeKind::LogicalExpression => { let node = LogicalExpression::convert(cx, node); ForInit::Expression(Expression::LogicalExpression(Box::new(node))) @@ -2479,6 +2912,10 @@ impl FromHermes for ForInit { let node = OptionalMemberExpression::convert(cx, node); ForInit::Expression(Expression::OptionalMemberExpression(Box::new(node))) } + NodeKind::RegExpLiteral => { + let node = RegExpLiteral::convert(cx, node); + ForInit::Expression(Expression::RegExpLiteral(Box::new(node))) + } NodeKind::SequenceExpression => { let node = SequenceExpression::convert(cx, node); ForInit::Expression(Expression::SequenceExpression(Box::new(node))) @@ -2515,7 +2952,7 @@ impl FromHermes for ForInit { let node = VariableDeclaration::convert(cx, node); ForInit::VariableDeclaration(Box::new(node)) } - _ => panic!("Unexpected node"), + _ => panic!("Unexpected node kind `{:?}` for `{}`", node_ref.kind, "ForInit"), } } } @@ -2547,7 +2984,11 @@ impl FromHermes for ForInInit { let node = VariableDeclaration::convert(cx, node); ForInInit::VariableDeclaration(Box::new(node)) } - _ => panic!("Unexpected node"), + _ => { + panic!( + "Unexpected node kind `{:?}` for `{}`", node_ref.kind, "ForInInit" + ) + } } } } @@ -2563,7 +3004,12 @@ impl FromHermes for PropertyOrSpreadElement { let node = SpreadElement::convert(cx, node); PropertyOrSpreadElement::SpreadElement(Box::new(node)) } - _ => panic!("Unexpected node"), + _ => { + panic!( + "Unexpected node kind `{:?}` for `{}`", node_ref.kind, + "PropertyOrSpreadElement" + ) + } } } } @@ -2579,7 +3025,12 @@ impl FromHermes for AssignmentPropertyOrRestElement { let node = RestElement::convert(cx, node); AssignmentPropertyOrRestElement::RestElement(Box::new(node)) } - _ => panic!("Unexpected node"), + _ => { + panic!( + "Unexpected node kind `{:?}` for `{}`", node_ref.kind, + "AssignmentPropertyOrRestElement" + ) + } } } } @@ -2591,7 +3042,11 @@ impl FromHermes for PropertyKey { let node = Identifier::convert(cx, node); PropertyKey::Identifier(Box::new(node)) } - _ => panic!("Unexpected node"), + _ => { + panic!( + "Unexpected node kind `{:?}` for `{}`", node_ref.kind, "PropertyKey" + ) + } } } } @@ -2643,6 +3098,12 @@ impl FromHermes for AssignmentTarget { Expression::ConditionalExpression(Box::new(node)), ) } + NodeKind::CoverTypedIdentifier => { + let node = CoverTypedIdentifier::convert(cx, node); + AssignmentTarget::Expression( + Expression::CoverTypedIdentifier(Box::new(node)), + ) + } NodeKind::FunctionExpression => { let node = FunctionExpression::convert(cx, node); AssignmentTarget::Expression( @@ -2663,6 +3124,10 @@ impl FromHermes for AssignmentTarget { let node = JSXElement::convert(cx, node); AssignmentTarget::Expression(Expression::JSXElement(Box::new(node))) } + NodeKind::JSXFragment => { + let node = JSXFragment::convert(cx, node); + AssignmentTarget::Expression(Expression::JSXFragment(Box::new(node))) + } NodeKind::LogicalExpression => { let node = LogicalExpression::convert(cx, node); AssignmentTarget::Expression( @@ -2709,6 +3174,10 @@ impl FromHermes for AssignmentTarget { Expression::OptionalMemberExpression(Box::new(node)), ) } + NodeKind::RegExpLiteral => { + let node = RegExpLiteral::convert(cx, node); + AssignmentTarget::Expression(Expression::RegExpLiteral(Box::new(node))) + } NodeKind::SequenceExpression => { let node = SequenceExpression::convert(cx, node); AssignmentTarget::Expression( @@ -2763,7 +3232,12 @@ impl FromHermes for AssignmentTarget { let node = AssignmentPattern::convert(cx, node); AssignmentTarget::Pattern(Pattern::AssignmentPattern(Box::new(node))) } - _ => panic!("Unexpected node"), + _ => { + panic!( + "Unexpected node kind `{:?}` for `{}`", node_ref.kind, + "AssignmentTarget" + ) + } } } } @@ -2779,7 +3253,11 @@ impl FromHermes for ChainElement { let node = MemberExpression::convert(cx, node); ChainElement::MemberExpression(Box::new(node)) } - _ => panic!("Unexpected node"), + _ => { + panic!( + "Unexpected node kind `{:?}` for `{}`", node_ref.kind, "ChainElement" + ) + } } } } @@ -2795,7 +3273,12 @@ impl FromHermes for JSXMemberExpressionOrIdentifier { let node = JSXIdentifier::convert(cx, node); JSXMemberExpressionOrIdentifier::JSXIdentifier(Box::new(node)) } - _ => panic!("Unexpected node"), + _ => { + panic!( + "Unexpected node kind `{:?}` for `{}`", node_ref.kind, + "JSXMemberExpressionOrIdentifier" + ) + } } } } @@ -2857,6 +3340,12 @@ impl FromHermes for JSXExpressionOrEmpty { Expression::ConditionalExpression(Box::new(node)), ) } + NodeKind::CoverTypedIdentifier => { + let node = CoverTypedIdentifier::convert(cx, node); + JSXExpressionOrEmpty::Expression( + Expression::CoverTypedIdentifier(Box::new(node)), + ) + } NodeKind::FunctionExpression => { let node = FunctionExpression::convert(cx, node); JSXExpressionOrEmpty::Expression( @@ -2877,6 +3366,10 @@ impl FromHermes for JSXExpressionOrEmpty { let node = JSXElement::convert(cx, node); JSXExpressionOrEmpty::Expression(Expression::JSXElement(Box::new(node))) } + NodeKind::JSXFragment => { + let node = JSXFragment::convert(cx, node); + JSXExpressionOrEmpty::Expression(Expression::JSXFragment(Box::new(node))) + } NodeKind::LogicalExpression => { let node = LogicalExpression::convert(cx, node); JSXExpressionOrEmpty::Expression( @@ -2929,6 +3422,12 @@ impl FromHermes for JSXExpressionOrEmpty { Expression::OptionalMemberExpression(Box::new(node)), ) } + NodeKind::RegExpLiteral => { + let node = RegExpLiteral::convert(cx, node); + JSXExpressionOrEmpty::Expression( + Expression::RegExpLiteral(Box::new(node)), + ) + } NodeKind::SequenceExpression => { let node = SequenceExpression::convert(cx, node); JSXExpressionOrEmpty::Expression( @@ -2981,7 +3480,12 @@ impl FromHermes for JSXExpressionOrEmpty { let node = JSXEmptyExpression::convert(cx, node); JSXExpressionOrEmpty::JSXEmptyExpression(Box::new(node)) } - _ => panic!("Unexpected node"), + _ => { + panic!( + "Unexpected node kind `{:?}` for `{}`", node_ref.kind, + "JSXExpressionOrEmpty" + ) + } } } } @@ -2997,7 +3501,12 @@ impl FromHermes for JSXAttributeOrSpread { let node = JSXSpreadAttribute::convert(cx, node); JSXAttributeOrSpread::JSXSpreadAttribute(Box::new(node)) } - _ => panic!("Unexpected node"), + _ => { + panic!( + "Unexpected node kind `{:?}` for `{}`", node_ref.kind, + "JSXAttributeOrSpread" + ) + } } } } @@ -3017,7 +3526,16 @@ impl FromHermes for JSXAttributeValue { let node = JSXFragment::convert(cx, node); JSXAttributeValue::JSXFragment(Box::new(node)) } - _ => panic!("Unexpected node"), + NodeKind::JSXStringLiteral => { + let node = JSXStringLiteral::convert(cx, node); + JSXAttributeValue::JSXStringLiteral(Box::new(node)) + } + _ => { + panic!( + "Unexpected node kind `{:?}` for `{}`", node_ref.kind, + "JSXAttributeValue" + ) + } } } } @@ -3037,7 +3555,12 @@ impl FromHermes for JSXElementName { let node = JSXNamespacedName::convert(cx, node); JSXElementName::JSXNamespacedName(Box::new(node)) } - _ => panic!("Unexpected node"), + _ => { + panic!( + "Unexpected node kind `{:?}` for `{}`", node_ref.kind, + "JSXElementName" + ) + } } } } @@ -3053,7 +3576,12 @@ impl FromHermes for JSXIdentifierOrNamespacedName { let node = JSXNamespacedName::convert(cx, node); JSXIdentifierOrNamespacedName::JSXNamespacedName(Box::new(node)) } - _ => panic!("Unexpected node"), + _ => { + panic!( + "Unexpected node kind `{:?}` for `{}`", node_ref.kind, + "JSXIdentifierOrNamespacedName" + ) + } } } } @@ -3065,6 +3593,10 @@ impl FromHermes for JSXChildItem { let node = JSXText::convert(cx, node); JSXChildItem::JSXText(Box::new(node)) } + NodeKind::JSXStringLiteral => { + let node = JSXStringLiteral::convert(cx, node); + JSXChildItem::JSXStringLiteral(Box::new(node)) + } NodeKind::JSXExpressionContainer => { let node = JSXExpressionContainer::convert(cx, node); JSXChildItem::JSXExpressionContainer(Box::new(node)) @@ -3081,7 +3613,502 @@ impl FromHermes for JSXChildItem { let node = JSXFragment::convert(cx, node); JSXChildItem::JSXFragment(Box::new(node)) } - _ => panic!("Unexpected node"), + _ => { + panic!( + "Unexpected node kind `{:?}` for `{}`", node_ref.kind, "JSXChildItem" + ) + } + } + } +} +impl FromHermes for DeclarationOrExpression { + fn convert(cx: &mut Context, node: NodePtr) -> Self { + let node_ref = node.as_ref(); + match node_ref.kind { + NodeKind::ClassDeclaration => { + let node = ClassDeclaration::convert(cx, node); + DeclarationOrExpression::Declaration( + Declaration::ClassDeclaration(Box::new(node)), + ) + } + NodeKind::FunctionDeclaration => { + let node = FunctionDeclaration::convert(cx, node); + DeclarationOrExpression::Declaration( + Declaration::FunctionDeclaration(Box::new(node)), + ) + } + NodeKind::VariableDeclaration => { + let node = VariableDeclaration::convert(cx, node); + DeclarationOrExpression::Declaration( + Declaration::VariableDeclaration(Box::new(node)), + ) + } + NodeKind::TSTypeAliasDeclaration => { + let node = TSTypeAliasDeclaration::convert(cx, node); + DeclarationOrExpression::Declaration( + Declaration::TSTypeAliasDeclaration(Box::new(node)), + ) + } + NodeKind::ArrayExpression => { + let node = ArrayExpression::convert(cx, node); + DeclarationOrExpression::Expression( + Expression::ArrayExpression(Box::new(node)), + ) + } + NodeKind::ArrowFunctionExpression => { + let node = ArrowFunctionExpression::convert(cx, node); + DeclarationOrExpression::Expression( + Expression::ArrowFunctionExpression(Box::new(node)), + ) + } + NodeKind::AssignmentExpression => { + let node = AssignmentExpression::convert(cx, node); + DeclarationOrExpression::Expression( + Expression::AssignmentExpression(Box::new(node)), + ) + } + NodeKind::AwaitExpression => { + let node = AwaitExpression::convert(cx, node); + DeclarationOrExpression::Expression( + Expression::AwaitExpression(Box::new(node)), + ) + } + NodeKind::BinaryExpression => { + let node = BinaryExpression::convert(cx, node); + DeclarationOrExpression::Expression( + Expression::BinaryExpression(Box::new(node)), + ) + } + NodeKind::BooleanLiteral => { + let node = BooleanLiteral::convert(cx, node); + DeclarationOrExpression::Expression( + Expression::BooleanLiteral(Box::new(node)), + ) + } + NodeKind::CallExpression => { + let node = CallExpression::convert(cx, node); + DeclarationOrExpression::Expression( + Expression::CallExpression(Box::new(node)), + ) + } + NodeKind::ClassExpression => { + let node = ClassExpression::convert(cx, node); + DeclarationOrExpression::Expression( + Expression::ClassExpression(Box::new(node)), + ) + } + NodeKind::ConditionalExpression => { + let node = ConditionalExpression::convert(cx, node); + DeclarationOrExpression::Expression( + Expression::ConditionalExpression(Box::new(node)), + ) + } + NodeKind::CoverTypedIdentifier => { + let node = CoverTypedIdentifier::convert(cx, node); + DeclarationOrExpression::Expression( + Expression::CoverTypedIdentifier(Box::new(node)), + ) + } + NodeKind::FunctionExpression => { + let node = FunctionExpression::convert(cx, node); + DeclarationOrExpression::Expression( + Expression::FunctionExpression(Box::new(node)), + ) + } + NodeKind::Identifier => { + let node = Identifier::convert(cx, node); + DeclarationOrExpression::Expression( + Expression::Identifier(Box::new(node)), + ) + } + NodeKind::ImportExpression => { + let node = ImportExpression::convert(cx, node); + DeclarationOrExpression::Expression( + Expression::ImportExpression(Box::new(node)), + ) + } + NodeKind::JSXElement => { + let node = JSXElement::convert(cx, node); + DeclarationOrExpression::Expression( + Expression::JSXElement(Box::new(node)), + ) + } + NodeKind::JSXFragment => { + let node = JSXFragment::convert(cx, node); + DeclarationOrExpression::Expression( + Expression::JSXFragment(Box::new(node)), + ) + } + NodeKind::LogicalExpression => { + let node = LogicalExpression::convert(cx, node); + DeclarationOrExpression::Expression( + Expression::LogicalExpression(Box::new(node)), + ) + } + NodeKind::MemberExpression => { + let node = MemberExpression::convert(cx, node); + DeclarationOrExpression::Expression( + Expression::MemberExpression(Box::new(node)), + ) + } + NodeKind::MetaProperty => { + let node = MetaProperty::convert(cx, node); + DeclarationOrExpression::Expression( + Expression::MetaProperty(Box::new(node)), + ) + } + NodeKind::NewExpression => { + let node = NewExpression::convert(cx, node); + DeclarationOrExpression::Expression( + Expression::NewExpression(Box::new(node)), + ) + } + NodeKind::NullLiteral => { + let node = NullLiteral::convert(cx, node); + DeclarationOrExpression::Expression( + Expression::NullLiteral(Box::new(node)), + ) + } + NodeKind::NumericLiteral => { + let node = NumericLiteral::convert(cx, node); + DeclarationOrExpression::Expression( + Expression::NumericLiteral(Box::new(node)), + ) + } + NodeKind::ObjectExpression => { + let node = ObjectExpression::convert(cx, node); + DeclarationOrExpression::Expression( + Expression::ObjectExpression(Box::new(node)), + ) + } + NodeKind::OptionalCallExpression => { + let node = OptionalCallExpression::convert(cx, node); + DeclarationOrExpression::Expression( + Expression::OptionalCallExpression(Box::new(node)), + ) + } + NodeKind::OptionalMemberExpression => { + let node = OptionalMemberExpression::convert(cx, node); + DeclarationOrExpression::Expression( + Expression::OptionalMemberExpression(Box::new(node)), + ) + } + NodeKind::RegExpLiteral => { + let node = RegExpLiteral::convert(cx, node); + DeclarationOrExpression::Expression( + Expression::RegExpLiteral(Box::new(node)), + ) + } + NodeKind::SequenceExpression => { + let node = SequenceExpression::convert(cx, node); + DeclarationOrExpression::Expression( + Expression::SequenceExpression(Box::new(node)), + ) + } + NodeKind::StringLiteral => { + let node = StringLiteral::convert(cx, node); + DeclarationOrExpression::Expression( + Expression::StringLiteral(Box::new(node)), + ) + } + NodeKind::TaggedTemplateExpression => { + let node = TaggedTemplateExpression::convert(cx, node); + DeclarationOrExpression::Expression( + Expression::TaggedTemplateExpression(Box::new(node)), + ) + } + NodeKind::TemplateLiteral => { + let node = TemplateLiteral::convert(cx, node); + DeclarationOrExpression::Expression( + Expression::TemplateLiteral(Box::new(node)), + ) + } + NodeKind::ThisExpression => { + let node = ThisExpression::convert(cx, node); + DeclarationOrExpression::Expression( + Expression::ThisExpression(Box::new(node)), + ) + } + NodeKind::UnaryExpression => { + let node = UnaryExpression::convert(cx, node); + DeclarationOrExpression::Expression( + Expression::UnaryExpression(Box::new(node)), + ) + } + NodeKind::UpdateExpression => { + let node = UpdateExpression::convert(cx, node); + DeclarationOrExpression::Expression( + Expression::UpdateExpression(Box::new(node)), + ) + } + NodeKind::YieldExpression => { + let node = YieldExpression::convert(cx, node); + DeclarationOrExpression::Expression( + Expression::YieldExpression(Box::new(node)), + ) + } + _ => { + panic!( + "Unexpected node kind `{:?}` for `{}`", node_ref.kind, + "DeclarationOrExpression" + ) + } + } + } +} +impl FromHermes for ClassItem { + fn convert(cx: &mut Context, node: NodePtr) -> Self { + let node_ref = node.as_ref(); + match node_ref.kind { + NodeKind::MethodDefinition => { + let node = MethodDefinition::convert(cx, node); + ClassItem::MethodDefinition(Box::new(node)) + } + NodeKind::ClassProperty => { + let node = ClassProperty::convert(cx, node); + ClassItem::ClassProperty(Box::new(node)) + } + NodeKind::ClassPrivateProperty => { + let node = ClassPrivateProperty::convert(cx, node); + ClassItem::ClassPrivateProperty(Box::new(node)) + } + _ => { + panic!( + "Unexpected node kind `{:?}` for `{}`", node_ref.kind, "ClassItem" + ) + } + } + } +} +impl FromHermes for ExpressionOrPrivateIdentifier { + fn convert(cx: &mut Context, node: NodePtr) -> Self { + let node_ref = node.as_ref(); + match node_ref.kind { + NodeKind::ArrayExpression => { + let node = ArrayExpression::convert(cx, node); + ExpressionOrPrivateIdentifier::Expression( + Expression::ArrayExpression(Box::new(node)), + ) + } + NodeKind::ArrowFunctionExpression => { + let node = ArrowFunctionExpression::convert(cx, node); + ExpressionOrPrivateIdentifier::Expression( + Expression::ArrowFunctionExpression(Box::new(node)), + ) + } + NodeKind::AssignmentExpression => { + let node = AssignmentExpression::convert(cx, node); + ExpressionOrPrivateIdentifier::Expression( + Expression::AssignmentExpression(Box::new(node)), + ) + } + NodeKind::AwaitExpression => { + let node = AwaitExpression::convert(cx, node); + ExpressionOrPrivateIdentifier::Expression( + Expression::AwaitExpression(Box::new(node)), + ) + } + NodeKind::BinaryExpression => { + let node = BinaryExpression::convert(cx, node); + ExpressionOrPrivateIdentifier::Expression( + Expression::BinaryExpression(Box::new(node)), + ) + } + NodeKind::BooleanLiteral => { + let node = BooleanLiteral::convert(cx, node); + ExpressionOrPrivateIdentifier::Expression( + Expression::BooleanLiteral(Box::new(node)), + ) + } + NodeKind::CallExpression => { + let node = CallExpression::convert(cx, node); + ExpressionOrPrivateIdentifier::Expression( + Expression::CallExpression(Box::new(node)), + ) + } + NodeKind::ClassExpression => { + let node = ClassExpression::convert(cx, node); + ExpressionOrPrivateIdentifier::Expression( + Expression::ClassExpression(Box::new(node)), + ) + } + NodeKind::ConditionalExpression => { + let node = ConditionalExpression::convert(cx, node); + ExpressionOrPrivateIdentifier::Expression( + Expression::ConditionalExpression(Box::new(node)), + ) + } + NodeKind::CoverTypedIdentifier => { + let node = CoverTypedIdentifier::convert(cx, node); + ExpressionOrPrivateIdentifier::Expression( + Expression::CoverTypedIdentifier(Box::new(node)), + ) + } + NodeKind::FunctionExpression => { + let node = FunctionExpression::convert(cx, node); + ExpressionOrPrivateIdentifier::Expression( + Expression::FunctionExpression(Box::new(node)), + ) + } + NodeKind::Identifier => { + let node = Identifier::convert(cx, node); + ExpressionOrPrivateIdentifier::Expression( + Expression::Identifier(Box::new(node)), + ) + } + NodeKind::ImportExpression => { + let node = ImportExpression::convert(cx, node); + ExpressionOrPrivateIdentifier::Expression( + Expression::ImportExpression(Box::new(node)), + ) + } + NodeKind::JSXElement => { + let node = JSXElement::convert(cx, node); + ExpressionOrPrivateIdentifier::Expression( + Expression::JSXElement(Box::new(node)), + ) + } + NodeKind::JSXFragment => { + let node = JSXFragment::convert(cx, node); + ExpressionOrPrivateIdentifier::Expression( + Expression::JSXFragment(Box::new(node)), + ) + } + NodeKind::LogicalExpression => { + let node = LogicalExpression::convert(cx, node); + ExpressionOrPrivateIdentifier::Expression( + Expression::LogicalExpression(Box::new(node)), + ) + } + NodeKind::MemberExpression => { + let node = MemberExpression::convert(cx, node); + ExpressionOrPrivateIdentifier::Expression( + Expression::MemberExpression(Box::new(node)), + ) + } + NodeKind::MetaProperty => { + let node = MetaProperty::convert(cx, node); + ExpressionOrPrivateIdentifier::Expression( + Expression::MetaProperty(Box::new(node)), + ) + } + NodeKind::NewExpression => { + let node = NewExpression::convert(cx, node); + ExpressionOrPrivateIdentifier::Expression( + Expression::NewExpression(Box::new(node)), + ) + } + NodeKind::NullLiteral => { + let node = NullLiteral::convert(cx, node); + ExpressionOrPrivateIdentifier::Expression( + Expression::NullLiteral(Box::new(node)), + ) + } + NodeKind::NumericLiteral => { + let node = NumericLiteral::convert(cx, node); + ExpressionOrPrivateIdentifier::Expression( + Expression::NumericLiteral(Box::new(node)), + ) + } + NodeKind::ObjectExpression => { + let node = ObjectExpression::convert(cx, node); + ExpressionOrPrivateIdentifier::Expression( + Expression::ObjectExpression(Box::new(node)), + ) + } + NodeKind::OptionalCallExpression => { + let node = OptionalCallExpression::convert(cx, node); + ExpressionOrPrivateIdentifier::Expression( + Expression::OptionalCallExpression(Box::new(node)), + ) + } + NodeKind::OptionalMemberExpression => { + let node = OptionalMemberExpression::convert(cx, node); + ExpressionOrPrivateIdentifier::Expression( + Expression::OptionalMemberExpression(Box::new(node)), + ) + } + NodeKind::RegExpLiteral => { + let node = RegExpLiteral::convert(cx, node); + ExpressionOrPrivateIdentifier::Expression( + Expression::RegExpLiteral(Box::new(node)), + ) + } + NodeKind::SequenceExpression => { + let node = SequenceExpression::convert(cx, node); + ExpressionOrPrivateIdentifier::Expression( + Expression::SequenceExpression(Box::new(node)), + ) + } + NodeKind::StringLiteral => { + let node = StringLiteral::convert(cx, node); + ExpressionOrPrivateIdentifier::Expression( + Expression::StringLiteral(Box::new(node)), + ) + } + NodeKind::TaggedTemplateExpression => { + let node = TaggedTemplateExpression::convert(cx, node); + ExpressionOrPrivateIdentifier::Expression( + Expression::TaggedTemplateExpression(Box::new(node)), + ) + } + NodeKind::TemplateLiteral => { + let node = TemplateLiteral::convert(cx, node); + ExpressionOrPrivateIdentifier::Expression( + Expression::TemplateLiteral(Box::new(node)), + ) + } + NodeKind::ThisExpression => { + let node = ThisExpression::convert(cx, node); + ExpressionOrPrivateIdentifier::Expression( + Expression::ThisExpression(Box::new(node)), + ) + } + NodeKind::UnaryExpression => { + let node = UnaryExpression::convert(cx, node); + ExpressionOrPrivateIdentifier::Expression( + Expression::UnaryExpression(Box::new(node)), + ) + } + NodeKind::UpdateExpression => { + let node = UpdateExpression::convert(cx, node); + ExpressionOrPrivateIdentifier::Expression( + Expression::UpdateExpression(Box::new(node)), + ) + } + NodeKind::YieldExpression => { + let node = YieldExpression::convert(cx, node); + ExpressionOrPrivateIdentifier::Expression( + Expression::YieldExpression(Box::new(node)), + ) + } + NodeKind::PrivateName => { + let node = PrivateName::convert(cx, node); + ExpressionOrPrivateIdentifier::PrivateName(Box::new(node)) + } + _ => { + panic!( + "Unexpected node kind `{:?}` for `{}`", node_ref.kind, + "ExpressionOrPrivateIdentifier" + ) + } + } + } +} +impl FromHermes for TypeAnnotation { + fn convert(cx: &mut Context, node: NodePtr) -> Self { + let node_ref = node.as_ref(); + match node_ref.kind { + NodeKind::TSTypeAnnotation => { + let node = TSTypeAnnotation::convert(cx, node); + TypeAnnotation::TSTypeAnnotation(Box::new(node)) + } + _ => { + panic!( + "Unexpected node kind `{:?}` for `{}`", node_ref.kind, + "TypeAnnotation" + ) + } } } } diff --git a/compiler/forget/crates/forget_hermes_parser/src/generated_extension.rs b/compiler/forget/crates/forget_hermes_parser/src/generated_extension.rs index 6b30d456d5..34ea4bb274 100644 --- a/compiler/forget/crates/forget_hermes_parser/src/generated_extension.rs +++ b/compiler/forget/crates/forget_hermes_parser/src/generated_extension.rs @@ -1,8 +1,10 @@ +use std::num::NonZeroU32; + use forget_estree::{ ArrowFunctionExpression, AssignmentProperty, Class, ClassBody, ClassDeclaration, - ClassExpression, Expression, ExpressionOrSpread, Function, FunctionBody, FunctionDeclaration, - FunctionExpression, Identifier, Number, Pattern, SourceRange, TemplateElement, - TemplateElementValue, + ClassExpression, ClassPrivateProperty, Expression, ExpressionOrSpread, Function, FunctionBody, + FunctionDeclaration, FunctionExpression, Identifier, Number, Pattern, SourceRange, + TemplateElement, TemplateElementValue, }; use hermes::parser::{ hermes_get_ArrowFunctionExpression_async, hermes_get_ArrowFunctionExpression_body, @@ -68,7 +70,10 @@ where pub fn convert_range(node: NodePtr) -> SourceRange { let _range = node.as_ref().source_range; - todo!() + SourceRange { + start: 0, + end: NonZeroU32::new(1).unwrap(), + } } #[allow(dead_code)] diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/alias-capture-in-method-receiver-and-mutate.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/alias-capture-in-method-receiver-and-mutate.js new file mode 100644 index 0000000000..13470813eb --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/alias-capture-in-method-receiver-and-mutate.js @@ -0,0 +1,11 @@ +function Component() { + // a's mutable range should be the same as x's mutable range, + // since a is captured into x (which gets mutated later) + let a = someObj(); + + let x = []; + x.push(a); + + mutate(x); + return [x, a]; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/alias-capture-in-method-receiver.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/alias-capture-in-method-receiver.js new file mode 100644 index 0000000000..9b2dbbdd1b --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/alias-capture-in-method-receiver.js @@ -0,0 +1,10 @@ +function Component() { + // a's mutable range should be limited + // the following line + let a = someObj(); + + let x = []; + x.push(a); + + return [x, a]; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/alias-computed-load.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/alias-computed-load.js new file mode 100644 index 0000000000..1bd930dbcf --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/alias-computed-load.js @@ -0,0 +1,8 @@ +function component(a) { + let x = { a }; + let y = {}; + + y.x = x["a"]; + mutate(y); + return x; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/alias-nested-member-path-mutate.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/alias-nested-member-path-mutate.js new file mode 100644 index 0000000000..fb35630038 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/alias-nested-member-path-mutate.js @@ -0,0 +1,9 @@ +function component() { + let z = []; + let y = {}; + y.z = z; + let x = {}; + x.y = y; + mutate(x.y.z); + return x; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/alias-nested-member-path.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/alias-nested-member-path.js new file mode 100644 index 0000000000..11ab613cb7 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/alias-nested-member-path.js @@ -0,0 +1,8 @@ +function component() { + let z = []; + let y = {}; + y.z = z; + let x = {}; + x.y = y; + return x; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/alias-while.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/alias-while.js new file mode 100644 index 0000000000..34aa4c93aa --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/alias-while.js @@ -0,0 +1,18 @@ +function foo(cond) { + let a = {}; + let b = {}; + let c = {}; + while (cond) { + let z = a; + a = b; + b = c; + c = z; + mutate(a, b); + } + a; + b; + c; + return a; +} + +function mutate(x, y) {} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/allocating-primitive-as-dep-nested-scope.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/allocating-primitive-as-dep-nested-scope.js new file mode 100644 index 0000000000..765c7ef79f --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/allocating-primitive-as-dep-nested-scope.js @@ -0,0 +1,11 @@ +// bar(props.b) is an allocating expression that produces a primitive, which means +// that Forget should memoize it. +// Correctness: +// - y depends on either bar(props.b) or bar(props.b) + 1 +function AllocatingPrimitiveAsDepNested(props) { + let x = {}; + mutate(x); + let y = foo(bar(props.b) + 1); + mutate(x, props.a); + return [x, y]; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/allocating-primitive-as-dep.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/allocating-primitive-as-dep.js new file mode 100644 index 0000000000..c7ef86f7c2 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/allocating-primitive-as-dep.js @@ -0,0 +1,8 @@ +// bar(props.b) is an allocating expression that produces a primitive, which means +// that Forget should memoize it. +// Correctness: +// - y depends on either bar(props.b) or bar(props.b) + 1 +function AllocatingPrimitiveAsDep(props) { + let y = foo(bar(props).b + 1); + return y; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/allow-passing-refs-as-props.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/allow-passing-refs-as-props.js new file mode 100644 index 0000000000..a820b0d60e --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/allow-passing-refs-as-props.js @@ -0,0 +1,4 @@ +function Component(props) { + const ref = useRef(null); + return ; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/array-access-assignment.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/array-access-assignment.js new file mode 100644 index 0000000000..10e52dd8f0 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/array-access-assignment.js @@ -0,0 +1,8 @@ +function foo(a, b, c) { + const x = [a]; + const y = [null, b]; + const z = [[], [], [c]]; + x[0] = y[1]; + z[0][0] = x[0]; + return [x, z]; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/array-at-closure.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/array-at-closure.js new file mode 100644 index 0000000000..244b834756 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/array-at-closure.js @@ -0,0 +1,9 @@ +function Component(props) { + const x = foo(props.x); + const fn = function () { + const arr = [...bar(props)]; + return arr.at(x); + }; + const fnResult = fn(); + return fnResult; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/array-at-effect.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/array-at-effect.js new file mode 100644 index 0000000000..2e2e78e50e --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/array-at-effect.js @@ -0,0 +1,9 @@ +// arrayInstance.at should have the following effects: +// - read on arg0 +// - read on receiver +// - mutate on lvalue +function ArrayAtTest(props) { + const arr = [foo(props.x)]; + const result = arr.at(bar(props.y)); + return result; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/array-at-mutate-after-capture.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/array-at-mutate-after-capture.js new file mode 100644 index 0000000000..9553132e1a --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/array-at-mutate-after-capture.js @@ -0,0 +1,10 @@ +// x's mutable range should extend to `mutate(y)` + +function Component(props) { + let x = [42, {}]; + const idx = foo(props.b); + let y = x.at(idx); + mutate(y); + + return x; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/array-expression-spread.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/array-expression-spread.js new file mode 100644 index 0000000000..74a101b11d --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/array-expression-spread.js @@ -0,0 +1,4 @@ +function Component(props) { + const x = [0, ...props.foo, null, ...props.bar, "z"]; + return x; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/array-join.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/array-join.js new file mode 100644 index 0000000000..2637db4ec8 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/array-join.js @@ -0,0 +1,6 @@ +function Component(props) { + const x = [{}, [], props.value]; + const y = x.join(() => "this closure gets stringified, not called"); + foo(y); + return [x, y]; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/array-map-frozen-array.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/array-map-frozen-array.js new file mode 100644 index 0000000000..a236657cb4 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/array-map-frozen-array.js @@ -0,0 +1,6 @@ +function Component(props) { + const x = []; + {x}; + const y = x.map((item) => item); + return [x, y]; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/array-map-mutable-array-mutating-lambda.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/array-map-mutable-array-mutating-lambda.js new file mode 100644 index 0000000000..e893b8d518 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/array-map-mutable-array-mutating-lambda.js @@ -0,0 +1,8 @@ +function Component(props) { + const x = []; + const y = x.map((item) => { + item.updated = true; + return item; + }); + return [x, y]; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/array-pattern-params.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/array-pattern-params.js new file mode 100644 index 0000000000..5444d98405 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/array-pattern-params.js @@ -0,0 +1,5 @@ +function component([a, b]) { + let y = { a }; + let z = { b }; + return [y, z]; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/array-properties.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/array-properties.js new file mode 100644 index 0000000000..8d314feb33 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/array-properties.js @@ -0,0 +1,6 @@ +function Component(props) { + const a = [props.a, props.b, "hello"]; + const x = a.length; + const y = a.push; + return { a, x, y, z: a.concat }; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/array-property-call.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/array-property-call.js new file mode 100644 index 0000000000..3356a23cd6 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/array-property-call.js @@ -0,0 +1,7 @@ +function Component(props) { + const a = [props.a, props.b, "hello"]; + const x = a.push(42); + const y = a.at(props.c); + + return { a, x, y }; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/array-push-effect.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/array-push-effect.js new file mode 100644 index 0000000000..b91eff8642 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/array-push-effect.js @@ -0,0 +1,11 @@ +// arrayInstance.push should have the following effects: +// - read on all args (rest parameter) +// - mutate on receiver +function Component(props) { + const x = foo(props.x); + const y = { y: props.y }; + const arr = []; + arr.push({}); + arr.push(x, y); + return arr; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/arrow-function-expr-gating-test.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/arrow-function-expr-gating-test.js new file mode 100644 index 0000000000..3debc725be --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/arrow-function-expr-gating-test.js @@ -0,0 +1,4 @@ +// @gating +const ErrorView = (error, _retry) => ; + +export default ErrorView; diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/assignment-expression-computed.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/assignment-expression-computed.js new file mode 100644 index 0000000000..da5881a6c8 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/assignment-expression-computed.js @@ -0,0 +1,7 @@ +function Component(props) { + const x = [props.x]; + const index = 0; + x[index] *= 2; + x["0"] += 3; + return x; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/assignment-expression-nested-path.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/assignment-expression-nested-path.js new file mode 100644 index 0000000000..7a6a304185 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/assignment-expression-nested-path.js @@ -0,0 +1,6 @@ +function g(props) { + const a = { b: { c: props.c } }; + a.b.c = a.b.c + 1; + a.b.c *= 2; + return a; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/assignment-in-nested-if.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/assignment-in-nested-if.js new file mode 100644 index 0000000000..b55579a36d --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/assignment-in-nested-if.js @@ -0,0 +1,11 @@ +function useBar(props) { + let z; + + if (props.a) { + if (props.b) { + z = baz(); + } + } + + return z; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/assignment-variations-complex-lvalue-array.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/assignment-variations-complex-lvalue-array.js new file mode 100644 index 0000000000..c396f86547 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/assignment-variations-complex-lvalue-array.js @@ -0,0 +1,6 @@ +function foo() { + const a = [[1]]; + const first = a.at(0); + first.set(0, 2); + return a; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/assignment-variations-complex-lvalue.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/assignment-variations-complex-lvalue.js new file mode 100644 index 0000000000..44db6c38f5 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/assignment-variations-complex-lvalue.js @@ -0,0 +1,6 @@ +function g() { + const x = { y: { z: 1 } }; + x.y.z = x.y.z + 1; + x.y.z *= 2; + return x; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/assignment-variations.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/assignment-variations.js new file mode 100644 index 0000000000..af39d33a9b --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/assignment-variations.js @@ -0,0 +1,7 @@ +function f() { + let x = 1; + x = x + 1; + x += 1; + x >>>= 1; + return x; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/await-side-effecting-promise.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/await-side-effecting-promise.js new file mode 100644 index 0000000000..8b5a45e608 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/await-side-effecting-promise.js @@ -0,0 +1,5 @@ +async function Component(props) { + const x = []; + await populateData(props.id, x); + return x; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/await.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/await.js new file mode 100644 index 0000000000..3d021138fe --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/await.js @@ -0,0 +1,4 @@ +async function Component(props) { + const user = await load(props.id); + return
{user.name}
; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/babel-existing-react-import.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/babel-existing-react-import.js new file mode 100644 index 0000000000..007f4bdfe1 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/babel-existing-react-import.js @@ -0,0 +1,15 @@ +import { useState, useMemo } from "react"; + +function Component(props) { + const [x] = useState(0); + const expensiveNumber = useMemo(() => calculateExpensiveNumber(x), [x]); + + return
{expensiveNumber}
; +} + +function Component2(props) { + const [x] = useState(0); + const expensiveNumber = useMemo(() => calculateExpensiveNumber(x), [x]); + + return
{expensiveNumber}
; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/babel-existing-react-kitchensink-import.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/babel-existing-react-kitchensink-import.js new file mode 100644 index 0000000000..39bcae9d69 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/babel-existing-react-kitchensink-import.js @@ -0,0 +1,16 @@ +import * as React from "react"; +import { useState, useMemo } from "react"; + +function Component(props) { + const [x] = useState(0); + const expensiveNumber = useMemo(() => calculateExpensiveNumber(x), [x]); + + return
{expensiveNumber}
; +} + +function Component2(props) { + const [x] = useState(0); + const expensiveNumber = useMemo(() => calculateExpensiveNumber(x), [x]); + + return
{expensiveNumber}
; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/bug.useMemo-deps-array-not-cleared.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/bug.useMemo-deps-array-not-cleared.js new file mode 100644 index 0000000000..711783d4f9 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/bug.useMemo-deps-array-not-cleared.js @@ -0,0 +1,9 @@ +function App({ text, hasDeps }) { + const resolvedText = useMemo( + () => { + return text.toUpperCase(); + }, + hasDeps ? null : [text] // should be DCE'd + ); + return resolvedText; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/bug_object-pattern.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/bug_object-pattern.js new file mode 100644 index 0000000000..dd7ac9f415 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/bug_object-pattern.js @@ -0,0 +1,5 @@ +function component(t) { + let { a } = t; + let y = { a }; + return y; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/builtin-jsx-tag-lowered-between-mutations.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/builtin-jsx-tag-lowered-between-mutations.js new file mode 100644 index 0000000000..8b3fd76ca6 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/builtin-jsx-tag-lowered-between-mutations.js @@ -0,0 +1,4 @@ +function Component(props) { + const maybeMutable = new MaybeMutable(); + return
{maybeMutate(maybeMutable)}
; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/call-args-assignment.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/call-args-assignment.js new file mode 100644 index 0000000000..dc686eea9e --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/call-args-assignment.js @@ -0,0 +1,5 @@ +function Component(props) { + let x = makeObject(); + x.foo((x = makeObject())); + return x; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/call-args-destructuring-assignment.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/call-args-destructuring-assignment.js new file mode 100644 index 0000000000..e87fb49c34 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/call-args-destructuring-assignment.js @@ -0,0 +1,5 @@ +function Component(props) { + let x = makeObject(); + x.foo(([x] = makeObject())); + return x; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/call-spread.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/call-spread.js new file mode 100644 index 0000000000..5e73773bd1 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/call-spread.js @@ -0,0 +1,4 @@ +function Component(props) { + const x = foo(...props.a, null, ...props.b); + return x; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/call-with-independently-memoizable-arg.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/call-with-independently-memoizable-arg.js new file mode 100644 index 0000000000..0675b44287 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/call-with-independently-memoizable-arg.js @@ -0,0 +1,9 @@ +function Component(props) { + const x = makeFunction(props); + const y = x( +
+ {props.text} +
+ ); + return y; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/call.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/call.js new file mode 100644 index 0000000000..d0c79ac766 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/call.js @@ -0,0 +1,10 @@ +function foo() {} + +function Component(props) { + const a = []; + const b = {}; + foo(a, b); + let _ =
; + foo(b); + return
; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capture-indirect-mutate-alias.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capture-indirect-mutate-alias.js new file mode 100644 index 0000000000..9123c960ad --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capture-indirect-mutate-alias.js @@ -0,0 +1,11 @@ +function component(a) { + let x = { a }; + (function () { + let q = x; + (function () { + q.b = 1; + })(); + })(); + + return x; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capture-param-mutate.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capture-param-mutate.js new file mode 100644 index 0000000000..4ffdaa410f --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capture-param-mutate.js @@ -0,0 +1,37 @@ +function getNativeLogFunction(level) { + return function () { + let str; + if (arguments.length === 1 && typeof arguments[0] === "string") { + str = arguments[0]; + } else { + str = Array.prototype.map + .call(arguments, function (arg) { + return inspect(arg, { + depth: 10, + }); + }) + .join(", "); + } + const firstArg = arguments[0]; + let logLevel = level; + if ( + typeof firstArg === "string" && + firstArg.slice(0, 9) === "Warning: " && + logLevel >= LOG_LEVELS.error + ) { + logLevel = LOG_LEVELS.warn; + } + if (global.__inspectorLog) { + global.__inspectorLog( + INSPECTOR_LEVELS[logLevel], + str, + [].slice.call(arguments), + INSPECTOR_FRAMES_TO_SKIP + ); + } + if (groupStack.length) { + str = groupFormat("", str); + } + global.nativeLoggingHook(str, logLevel); + }; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capture_mutate-across-fns.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capture_mutate-across-fns.js new file mode 100644 index 0000000000..295d7434e8 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capture_mutate-across-fns.js @@ -0,0 +1,9 @@ +function component(a) { + let z = { a }; + (function () { + (function () { + z.b = 1; + })(); + })(); + return z; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-arrow-function-1.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-arrow-function-1.js new file mode 100644 index 0000000000..1974b68dd6 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-arrow-function-1.js @@ -0,0 +1,7 @@ +function component(a) { + let z = { a }; + let x = () => { + console.log(z); + }; + return x; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-fun-alias-captured-mutate-2.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-fun-alias-captured-mutate-2.js new file mode 100644 index 0000000000..d00593e420 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-fun-alias-captured-mutate-2.js @@ -0,0 +1,11 @@ +function component(foo, bar) { + let x = { foo }; + let y = { bar }; + (function () { + let a = { y }; + let b = x; + a.x = b; + })(); + mutate(y); + return x; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-fun-alias-captured-mutate-arr-2.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-fun-alias-captured-mutate-arr-2.js new file mode 100644 index 0000000000..de0c6bce45 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-fun-alias-captured-mutate-arr-2.js @@ -0,0 +1,11 @@ +function component(foo, bar) { + let x = { foo }; + let y = { bar }; + (function () { + let a = [y]; + let b = x; + a.x = b; + })(); + mutate(y); + return x; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-func-alias-captured-mutate-arr.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-func-alias-captured-mutate-arr.js new file mode 100644 index 0000000000..91dd760b6f --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-func-alias-captured-mutate-arr.js @@ -0,0 +1,11 @@ +function component(foo, bar) { + let x = { foo }; + let y = { bar }; + (function () { + let a = [y]; + let b = x; + a.x = b; + })(); + mutate(y); + return y; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-func-alias-captured-mutate.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-func-alias-captured-mutate.js new file mode 100644 index 0000000000..fc1954b554 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-func-alias-captured-mutate.js @@ -0,0 +1,11 @@ +function component(foo, bar) { + let x = { foo }; + let y = { bar }; + (function () { + let a = { y }; + let b = x; + a.x = b; + })(); + mutate(y); + return y; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-func-alias-computed-mutate.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-func-alias-computed-mutate.js new file mode 100644 index 0000000000..f8a365a283 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-func-alias-computed-mutate.js @@ -0,0 +1,9 @@ +function component(a) { + let x = { a }; + let y = {}; + (function () { + y["x"] = x; + })(); + mutate(y); + return y; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-func-alias-mutate.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-func-alias-mutate.js new file mode 100644 index 0000000000..8ea83e13bc --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-func-alias-mutate.js @@ -0,0 +1,9 @@ +function component(a) { + let x = { a }; + let y = {}; + (function () { + y.x = x; + })(); + mutate(y); + return y; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-func-alias-receiver-computed-mutate.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-func-alias-receiver-computed-mutate.js new file mode 100644 index 0000000000..dba7a25cf1 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-func-alias-receiver-computed-mutate.js @@ -0,0 +1,10 @@ +function component(a) { + let x = { a }; + let y = {}; + (function () { + let a = y; + a["x"] = x; + })(); + mutate(y); + return y; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-func-alias-receiver-mutate.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-func-alias-receiver-mutate.js new file mode 100644 index 0000000000..0599917f1b --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-func-alias-receiver-mutate.js @@ -0,0 +1,10 @@ +function component(a) { + let x = { a }; + let y = {}; + (function () { + let a = y; + a.x = x; + })(); + mutate(y); + return y; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-func-mutate-2.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-func-mutate-2.js new file mode 100644 index 0000000000..91b600968d --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-func-mutate-2.js @@ -0,0 +1,10 @@ +function component(a, b) { + let y = { b }; + let z = { a }; + let x = function () { + z.a = 2; + y.b; + }; + x(); + return z; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-func-mutate-3.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-func-mutate-3.js new file mode 100644 index 0000000000..92d4343642 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-func-mutate-3.js @@ -0,0 +1,9 @@ +function component(a, b) { + let y = { b }; + let z = { a }; + let x = function () { + z.a = 2; + y.b; + }; + return z; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-func-mutate-nested.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-func-mutate-nested.js new file mode 100644 index 0000000000..8d01fd0c10 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-func-mutate-nested.js @@ -0,0 +1,8 @@ +function component(a) { + let y = { b: { a } }; + let x = function () { + y.b.a = 2; + }; + x(); + return y; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-func-mutate.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-func-mutate.js new file mode 100644 index 0000000000..84e88a0328 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-func-mutate.js @@ -0,0 +1,10 @@ +function component(a, b) { + let z = { a }; + let y = { b }; + let x = function () { + z.a = 2; + console.log(y.b); + }; + x(); + return z; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-func-simple-alias.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-func-simple-alias.js new file mode 100644 index 0000000000..68848ba7e3 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-func-simple-alias.js @@ -0,0 +1,9 @@ +function component(a) { + let x = { a }; + let y = {}; + (function () { + y = x; + })(); + mutate(y); + return y; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-function-1.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-function-1.js new file mode 100644 index 0000000000..c885885069 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-function-1.js @@ -0,0 +1,7 @@ +function component(a) { + let z = { a }; + let x = function () { + console.log(z); + }; + return x; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-function-alias-computed-load-2.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-function-alias-computed-load-2.js new file mode 100644 index 0000000000..e2de4e1be4 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-function-alias-computed-load-2.js @@ -0,0 +1,9 @@ +function bar(a) { + let x = [a]; + let y = {}; + (function () { + y = x[0][1]; + })(); + + return y; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-function-alias-computed-load-3.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-function-alias-computed-load-3.js new file mode 100644 index 0000000000..c9ecd39960 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-function-alias-computed-load-3.js @@ -0,0 +1,11 @@ +function bar(a, b) { + let x = [a, b]; + let y = {}; + let t = {}; + (function () { + y = x[0][1]; + t = x[1][0]; + })(); + + return y; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-function-alias-computed-load-4.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-function-alias-computed-load-4.js new file mode 100644 index 0000000000..ef52aa19e8 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-function-alias-computed-load-4.js @@ -0,0 +1,9 @@ +function bar(a) { + let x = [a]; + let y = {}; + (function () { + y = x[0].a[1]; + })(); + + return y; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-function-alias-computed-load.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-function-alias-computed-load.js new file mode 100644 index 0000000000..1811e87081 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-function-alias-computed-load.js @@ -0,0 +1,9 @@ +function bar(a) { + let x = [a]; + let y = {}; + (function () { + y = x[0]; + })(); + + return y; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-function-capture-ref-before-rename.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-function-capture-ref-before-rename.js new file mode 100644 index 0000000000..6abd7c8612 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-function-capture-ref-before-rename.js @@ -0,0 +1,14 @@ +function component(a, b) { + let z = { a }; + (function () { + mutate(z); + })(); + let y = z; + + { + // z is shadowed & renamed but the lambda is unaffected. + let z = { b }; + y = { y, z }; + } + return y; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-function-conditional-capture-mutate.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-function-conditional-capture-mutate.js new file mode 100644 index 0000000000..5e9234b1fc --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-function-conditional-capture-mutate.js @@ -0,0 +1,14 @@ +// @debug +function component(a, b) { + let z = { a }; + let y = b; + let x = function () { + if (y) { + // we don't know for sure this mutates, so we should assume + // that there is no mutation so long as `x` isn't called + // during render + maybeMutate(z); + } + }; + return x; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-function-decl.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-function-decl.js new file mode 100644 index 0000000000..e7cb39a153 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-function-decl.js @@ -0,0 +1,8 @@ +function component(a) { + let t = { a }; + function x() { + t.foo(); + } + x(t); + return t; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-function-member-expr-arguments.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-function-member-expr-arguments.js new file mode 100644 index 0000000000..5eeb6bf8f2 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-function-member-expr-arguments.js @@ -0,0 +1,10 @@ +function Foo(props) { + const onFoo = useCallback( + (reason) => { + log(props.router.location); + }, + [props.router.location] + ); + + return onFoo; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-function-member-expr-call.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-function-member-expr-call.js new file mode 100644 index 0000000000..1b58c578bc --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-function-member-expr-call.js @@ -0,0 +1,11 @@ +function component({ mutator }) { + const poke = () => { + mutator.poke(); + }; + + const hide = () => { + mutator.user.hide(); + }; + + return ; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-function-renamed-ref.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-function-renamed-ref.js new file mode 100644 index 0000000000..5ad8300381 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-function-renamed-ref.js @@ -0,0 +1,10 @@ +function component(a, b) { + let z = { a }; + { + let z = { b }; + (function () { + mutate(z); + })(); + } + return z; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-function-runs-inference.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-function-runs-inference.js new file mode 100644 index 0000000000..1482ae4594 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-function-runs-inference.js @@ -0,0 +1,5 @@ +function component(a, b) { + let z = { a }; + let p = () => {z}; + return p(); +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-function-shadow-captured.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-function-shadow-captured.js new file mode 100644 index 0000000000..1249264e8b --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-function-shadow-captured.js @@ -0,0 +1,8 @@ +function component(a) { + let z = { a }; + let x = function () { + let z; + mutate(z); + }; + return x; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-function-skip-computed-path.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-function-skip-computed-path.js new file mode 100644 index 0000000000..75a5bc0473 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-function-skip-computed-path.js @@ -0,0 +1,4 @@ +function StoreLandingUnseenGiftModalContainer(a) { + const giftsSeen = { a }; + return ((gift) => (gift.id ? giftsSeen[gift.id] : false))(); +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-function-within-block.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-function-within-block.js new file mode 100644 index 0000000000..4c0975595f --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-function-within-block.js @@ -0,0 +1,10 @@ +function component(a) { + let z = { a }; + let x; + { + x = function () { + console.log(z); + }; + } + return x; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-member-expr.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-member-expr.js new file mode 100644 index 0000000000..07f5a90ce5 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-member-expr.js @@ -0,0 +1,7 @@ +function component(a) { + let z = { a }; + let x = function () { + console.log(z.a); + }; + return x; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-nested-member-call.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-nested-member-call.js new file mode 100644 index 0000000000..5d0c832556 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-nested-member-call.js @@ -0,0 +1,7 @@ +function component(a) { + let z = { a: { a } }; + let x = function () { + z.a.a(); + }; + return z; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-nested-member-expr-in-nested-func.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-nested-member-expr-in-nested-func.js new file mode 100644 index 0000000000..aa03be2d34 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-nested-member-expr-in-nested-func.js @@ -0,0 +1,9 @@ +function component(a) { + let z = { a: { a } }; + let x = function () { + (function () { + console.log(z.a.a); + })(); + }; + return x; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-nested-member-expr.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-nested-member-expr.js new file mode 100644 index 0000000000..f836620745 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-nested-member-expr.js @@ -0,0 +1,7 @@ +function component(a) { + let z = { a: { a } }; + let x = function () { + console.log(z.a.a); + }; + return x; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-reference-changes-type.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-reference-changes-type.js new file mode 100644 index 0000000000..7c56dde4be --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-reference-changes-type.js @@ -0,0 +1,9 @@ +function component(a) { + let x = { a }; + let y = 1; + (function () { + y = x; + })(); + mutate(y); + return y; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-variable-in-nested-block.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-variable-in-nested-block.js new file mode 100644 index 0000000000..0c95eaf093 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-variable-in-nested-block.js @@ -0,0 +1,9 @@ +function component(a) { + let z = { a }; + let x = function () { + { + console.log(z); + } + }; + return x; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-variable-in-nested-function.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-variable-in-nested-function.js new file mode 100644 index 0000000000..b4e3379f95 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/capturing-variable-in-nested-function.js @@ -0,0 +1,9 @@ +function component(a) { + let z = { a }; + let x = function () { + (function () { + console.log(z); + })(); + }; + return x; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/chained-assignment-context-variable.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/chained-assignment-context-variable.js new file mode 100644 index 0000000000..24a48fb378 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/chained-assignment-context-variable.js @@ -0,0 +1,9 @@ +function Component() { + let x, + y = (x = {}); + const foo = () => { + x = getObject(); + }; + foo(); + return [y, x]; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/chained-assignment-expressions.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/chained-assignment-expressions.js new file mode 100644 index 0000000000..fb4f27844c --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/chained-assignment-expressions.js @@ -0,0 +1,8 @@ +function foo() { + const x = { x: 0 }; + const y = { z: 0 }; + const z = { z: 0 }; + x.x += y.y *= 1; + z.z += y.y *= x.x &= 3; + return z; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/codegen-emit-imports-same-source.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/codegen-emit-imports-same-source.js new file mode 100644 index 0000000000..4edff1c3fc --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/codegen-emit-imports-same-source.js @@ -0,0 +1,5 @@ +// @enableEmitFreeze @instrumentForget + +function useFoo(props) { + return foo(props.x); +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/codegen-emit-make-read-only.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/codegen-emit-make-read-only.js new file mode 100644 index 0000000000..8ad3e859e6 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/codegen-emit-make-read-only.js @@ -0,0 +1,11 @@ +// @enableEmitFreeze true + +function MyComponentName(props) { + let x = {}; + foo(x, props.a); + foo(x, props.b); + + let y = []; + y.push(x); + return y; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/codegen-instrument-forget-gating-test.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/codegen-instrument-forget-gating-test.js new file mode 100644 index 0000000000..61eb62269e --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/codegen-instrument-forget-gating-test.js @@ -0,0 +1,15 @@ +// @instrumentForget @forgetDirective @gating + +function Bar(props) { + "use forget"; + return
{props.bar}
; +} + +function NoForget(props) { + return {props.noForget}; +} + +function Foo(props) { + "use forget"; + return {props.bar}; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/codegen-instrument-forget-test.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/codegen-instrument-forget-test.js new file mode 100644 index 0000000000..95076cf30c --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/codegen-instrument-forget-test.js @@ -0,0 +1,15 @@ +// @instrumentForget @forgetDirective + +function Bar(props) { + "use forget"; + return
{props.bar}
; +} + +function NoForget(props) { + return {props.noForget}; +} + +function Foo(props) { + "use forget"; + return {props.bar}; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/complex-while.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/complex-while.js new file mode 100644 index 0000000000..50a77acc49 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/complex-while.js @@ -0,0 +1,10 @@ +function foo(a, b, c) { + label: if (a) { + while (b) { + if (c) { + break label; + } + } + } + return c; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/component.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/component.js new file mode 100644 index 0000000000..86336ff14f --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/component.js @@ -0,0 +1,26 @@ +function Component(props) { + const items = props.items; + const maxItems = props.maxItems; + + const renderedItems = []; + const seen = new Set(); + const max = Math.max(0, maxItems); + for (let i = 0; i < items.length; i += 1) { + const item = items.at(i); + if (item == null || seen.has(item)) { + continue; + } + seen.add(item); + renderedItems.push(
{item}
); + if (renderedItems.length >= max) { + break; + } + } + const count = renderedItems.length; + return ( +
+

{count} Items

+ {renderedItems} +
+ ); +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/computed-call-evaluation-order.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/computed-call-evaluation-order.js new file mode 100644 index 0000000000..1d0a31b46c --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/computed-call-evaluation-order.js @@ -0,0 +1,14 @@ +// Should print A, B, arg, original +function Component() { + const changeF = (o) => { + o.f = () => console.log("new"); + }; + const x = { + f: () => console.log("original"), + }; + + (console.log("A"), x)[(console.log("B"), "f")]( + (changeF(x), console.log("arg"), 1) + ); + return x; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/computed-call-spread.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/computed-call-spread.js new file mode 100644 index 0000000000..b933b65d4e --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/computed-call-spread.js @@ -0,0 +1,4 @@ +function Component(props) { + const x = foo[props.method](...props.a, null, ...props.b); + return x; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/computed-load-primitive-as-dependency.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/computed-load-primitive-as-dependency.js new file mode 100644 index 0000000000..e6d2c795c3 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/computed-load-primitive-as-dependency.js @@ -0,0 +1,9 @@ +function Component(props) { + let a = foo(); + // freeze `a` so we know the next line cannot mutate it +
{a}
; + + // b should be dependent on `props.a` + let b = bar(a[props.a] + 1); + return b; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/computed-store-alias.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/computed-store-alias.js new file mode 100644 index 0000000000..66dc3e4943 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/computed-store-alias.js @@ -0,0 +1,7 @@ +function component(a, b) { + let y = { a }; + let x = { b }; + x["y"] = y; + mutate(x); + return x; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/concise-arrow-expr.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/concise-arrow-expr.js new file mode 100644 index 0000000000..d04270e3ac --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/concise-arrow-expr.js @@ -0,0 +1,5 @@ +function component() { + let [x, setX] = useState(0); + const handler = (v) => setX(v); + return ; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/cond-deps-conditional-member-expr.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/cond-deps-conditional-member-expr.js new file mode 100644 index 0000000000..c7bb2cd3c0 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/cond-deps-conditional-member-expr.js @@ -0,0 +1,9 @@ +// To preserve the nullthrows behavior and reactive deps of this code, +// Forget needs to add `props.a` as a dependency (since `props.a.b` is +// a conditional dependency, i.e. gated behind control flow) + +function Component(props) { + let x = []; + x.push(props.a?.b); + return x; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/conditional-break-labeled.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/conditional-break-labeled.js new file mode 100644 index 0000000000..0028ebbc9a --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/conditional-break-labeled.js @@ -0,0 +1,15 @@ +/** + * props.b *does* influence `a` + */ +function Component(props) { + const a = []; + a.push(props.a); + label: { + if (props.b) { + break label; + } + a.push(props.c); + } + a.push(props.d); + return a; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/conditional-break.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/conditional-break.js new file mode 100644 index 0000000000..7b5baa9ea5 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/conditional-break.js @@ -0,0 +1,53 @@ +/** + * props.b does *not* influence `a` + */ +function ComponentA(props) { + const a_DEBUG = []; + a_DEBUG.push(props.a); + if (props.b) { + return null; + } + a_DEBUG.push(props.d); + return a_DEBUG; +} + +/** + * props.b *does* influence `a` + */ +function ComponentB(props) { + const a = []; + a.push(props.a); + if (props.b) { + a.push(props.c); + } + a.push(props.d); + return a; +} + +/** + * props.b *does* influence `a`, but only in a way that is never observable + */ +function ComponentC(props) { + const a = []; + a.push(props.a); + if (props.b) { + a.push(props.c); + return null; + } + a.push(props.d); + return a; +} + +/** + * props.b *does* influence `a` + */ +function ComponentD(props) { + const a = []; + a.push(props.a); + if (props.b) { + a.push(props.c); + return a; + } + a.push(props.d); + return a; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/conditional-on-mutable.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/conditional-on-mutable.js new file mode 100644 index 0000000000..0378ab655c --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/conditional-on-mutable.js @@ -0,0 +1,26 @@ +function ComponentA(props) { + const a = []; + const b = []; + if (b) { + a.push(props.p0); + } + if (props.p1) { + b.push(props.p2); + } + return ; +} + +function ComponentB(props) { + const a = []; + const b = []; + if (mayMutate(b)) { + a.push(props.p0); + } + if (props.p1) { + b.push(props.p2); + } + return ; +} + +function Foo() {} +function mayMutate() {} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/conditional-set-state-in-render.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/conditional-set-state-in-render.js new file mode 100644 index 0000000000..772649c1f9 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/conditional-set-state-in-render.js @@ -0,0 +1,14 @@ +function Component(props) { + const [x, setX] = useState(0); + + const foo = () => { + setX(1); + }; + + if (props.cond) { + setX(2); + foo(); + } + + return x; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/console-readonly.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/console-readonly.js new file mode 100644 index 0000000000..e2486ba7fe --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/console-readonly.js @@ -0,0 +1,11 @@ +function Component(props) { + const x = makeObject(props); + // These calls should view x as readonly and be grouped outside of the reactive scope for x: + console.log(x); + console.info(x); + console.warn(x); + console.error(x); + console.trace(x); + console.table(x); + return x; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/const-propagation-into-function-expression-global.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/const-propagation-into-function-expression-global.js new file mode 100644 index 0000000000..ca1f4023ac --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/const-propagation-into-function-expression-global.js @@ -0,0 +1,8 @@ +function foo() { + const isX = GLOBAL_IS_X; + const getJSX = () => { + return ; + }; + const result = getJSX(); + return result; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/const-propagation-into-function-expression-primitive.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/const-propagation-into-function-expression-primitive.js new file mode 100644 index 0000000000..c50ddfc6fb --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/const-propagation-into-function-expression-primitive.js @@ -0,0 +1,8 @@ +function foo() { + const x = 42; + const f = () => { + console.log(x); + }; + f(); + return x; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/constant-computed.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/constant-computed.js new file mode 100644 index 0000000000..2ffe50fef5 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/constant-computed.js @@ -0,0 +1,7 @@ +function Component(props) { + const index = "foo"; + const x = {}; + x[index] = x[index] + x["bar"]; + x[index](props.foo); + return x; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/constant-propagation-for.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/constant-propagation-for.js new file mode 100644 index 0000000000..e7822c5c43 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/constant-propagation-for.js @@ -0,0 +1,7 @@ +function foo() { + let y = 0; + for (const x = 100; x < 10; x) { + y = y + 1; + } + return y; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/constant-propagation-into-function-expressions.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/constant-propagation-into-function-expressions.js new file mode 100644 index 0000000000..c98bd9b670 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/constant-propagation-into-function-expressions.js @@ -0,0 +1,7 @@ +function Component(props) { + const x = 42; + const onEvent = () => { + console.log(x); + }; + return ; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/constant-propagation-phi.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/constant-propagation-phi.js new file mode 100644 index 0000000000..e2d7c9114c --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/constant-propagation-phi.js @@ -0,0 +1,13 @@ +function foo(a, b, c) { + let x; + if (a) { + x = 2 - 1; + } else { + x = 0 + 1; + } + if (x === 1) { + return b; + } else { + return c; + } +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/constant-propagation-while.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/constant-propagation-while.js new file mode 100644 index 0000000000..1a4d3bf6ec --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/constant-propagation-while.js @@ -0,0 +1,8 @@ +function foo() { + let x = 100; + let y = 0; + while (x < 10) { + y += 1; + } + return y; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/constant-propagation.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/constant-propagation.js new file mode 100644 index 0000000000..ff370584bd --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/constant-propagation.js @@ -0,0 +1,18 @@ +function foo() { + const a = 1; + const b = 2; + const c = 3; + const d = a + b; + const e = d * c; + const f = e / d; + const g = f - e; + + if (g) { + console.log("foo"); + } + + const h = g; + const i = h; + const j = i; + return j; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/constructor.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/constructor.js new file mode 100644 index 0000000000..ed1df01d2a --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/constructor.js @@ -0,0 +1,10 @@ +function Foo() {} + +function Component(props) { + const a = []; + const b = {}; + new Foo(a, b); + let _ =
; + new Foo(b); + return
; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/context-variable-reassigned-outside-of-lambda.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/context-variable-reassigned-outside-of-lambda.js new file mode 100644 index 0000000000..2624dc562f --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/context-variable-reassigned-outside-of-lambda.js @@ -0,0 +1,9 @@ +// @debug +function Component(props) { + let x = null; + const onChange = (e) => { + console.log(x); + }; + x = {}; + return ; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/controlled-input.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/controlled-input.js new file mode 100644 index 0000000000..6a18b2d0ea --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/controlled-input.js @@ -0,0 +1,5 @@ +function component() { + let [x, setX] = useState(0); + const handler = (event) => setX(event.target.value); + return ; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/dce-loop.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/dce-loop.js new file mode 100644 index 0000000000..6e43595e4d --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/dce-loop.js @@ -0,0 +1,9 @@ +function foo(props) { + let x = 0; + let y = 0; + while (y < props.max) { + x++; + y++; + } + return y; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/debugger-memoized.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/debugger-memoized.js new file mode 100644 index 0000000000..bf8923dce0 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/debugger-memoized.js @@ -0,0 +1,6 @@ +function Component(props) { + const x = []; + debugger; + x.push(props.value); + return x; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/debugger.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/debugger.js new file mode 100644 index 0000000000..a5779466e7 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/debugger.js @@ -0,0 +1,11 @@ +function Component(props) { + debugger; + if (props.cond) { + debugger; + } else { + while (props.cond) { + debugger; + } + } + debugger; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/declare-reassign-variable-in-closure.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/declare-reassign-variable-in-closure.js new file mode 100644 index 0000000000..52eb7c5bdc --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/declare-reassign-variable-in-closure.js @@ -0,0 +1,9 @@ +function Component(p) { + let x; + const foo = () => { + x = {}; + }; + foo(); + + return x; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/declare-reassign-variable-in-function-declaration.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/declare-reassign-variable-in-function-declaration.js new file mode 100644 index 0000000000..ca3ff47860 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/declare-reassign-variable-in-function-declaration.js @@ -0,0 +1,8 @@ +function Component() { + let x = null; + function foo() { + x = 9; + } + const y = bar(foo); + return ; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/delete-computed-property.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/delete-computed-property.js new file mode 100644 index 0000000000..79bfdfd237 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/delete-computed-property.js @@ -0,0 +1,6 @@ +function Component(props) { + const x = { a: props.a, b: props.b }; + const key = "b"; + delete x[key]; + return x; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/delete-property.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/delete-property.js new file mode 100644 index 0000000000..84d0de961d --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/delete-property.js @@ -0,0 +1,5 @@ +function Component(props) { + const x = { a: props.a, b: props.b }; + delete x.b; + return x; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/dependencies-outputs.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/dependencies-outputs.js new file mode 100644 index 0000000000..a5e6152c8a --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/dependencies-outputs.js @@ -0,0 +1,14 @@ +function foo(a, b) { + const x = []; + x.push(a); +
{x}
; + + const y = []; + if (x.length) { + y.push(x); + } + if (b) { + y.push(b); + } + return y; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/dependencies.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/dependencies.js new file mode 100644 index 0000000000..c93c3b0d24 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/dependencies.js @@ -0,0 +1,15 @@ +function foo(x, y, z) { + const items = [z]; + items.push(x); + + const items2 = []; + if (x) { + items2.push(y); + } + + if (y) { + items.push(x); + } + + return items2; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/destructure-capture-global.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/destructure-capture-global.js new file mode 100644 index 0000000000..1d0e4ce350 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/destructure-capture-global.js @@ -0,0 +1,5 @@ +let someGlobal = {}; +function component(a) { + let x = { a, someGlobal }; + return x; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/destructure-direct-reassignment.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/destructure-direct-reassignment.js new file mode 100644 index 0000000000..8d9f9851a4 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/destructure-direct-reassignment.js @@ -0,0 +1,7 @@ +function foo(props) { + let x, y; + ({ x, y } = { x: props.a, y: props.b }); + console.log(x); // prevent DCE from eliminating `x` altogether + x = props.c; + return x + y; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/destructuring-array-default.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/destructuring-array-default.js new file mode 100644 index 0000000000..a15539f441 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/destructuring-array-default.js @@ -0,0 +1,4 @@ +function Component(props) { + const [[x] = ["default"]] = props.y; + return x; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/destructuring-array-param-default.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/destructuring-array-param-default.js new file mode 100644 index 0000000000..f28a0fb7b2 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/destructuring-array-param-default.js @@ -0,0 +1,3 @@ +function Component([a = 2]) { + return a; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/destructuring-assignment-array-default.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/destructuring-assignment-array-default.js new file mode 100644 index 0000000000..331ece2dc2 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/destructuring-assignment-array-default.js @@ -0,0 +1,9 @@ +function Component(props) { + let x; + if (props.cond) { + [[x] = ["default"]] = props.y; + } else { + x = props.fallback; + } + return x; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/destructuring-assignment.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/destructuring-assignment.js new file mode 100644 index 0000000000..ebc2289107 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/destructuring-assignment.js @@ -0,0 +1,18 @@ +function foo(a, b, c) { + let d, g, n, o; + [ + d, + [ + { + e: { f: g }, + }, + ], + ] = a; + ({ + l: { + m: [[n]], + }, + o, + } = b); + return { d, g, n, o }; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/destructuring-mixed-scope-and-local-variables-with-default.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/destructuring-mixed-scope-and-local-variables-with-default.js new file mode 100644 index 0000000000..38e5546954 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/destructuring-mixed-scope-and-local-variables-with-default.js @@ -0,0 +1,20 @@ +function Component(props) { + const post = useFragment(graphql`...`, props.post); + const allUrls = []; + // `media` and `urls` are exported from the scope that will wrap this code, + // but `comments` is not (it doesn't need to be memoized, bc the callback + // only checks `comments.length`) + // because of the scope, the let declaration for media and urls are lifted + // out of the scope, and the destructure statement ends up turning into + // a reassignment, instead of a const declaration. this means we try to + // reassign `comments` when there's no declaration for it. + const { media = null, comments = [], urls = [] } = post; + const onClick = (e) => { + if (!comments.length) { + return; + } + console.log(comments.length); + }; + allUrls.push(...urls); + return ; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/destructuring-mixed-scope-declarations-and-locals.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/destructuring-mixed-scope-declarations-and-locals.js new file mode 100644 index 0000000000..5204e36e76 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/destructuring-mixed-scope-declarations-and-locals.js @@ -0,0 +1,20 @@ +function Component(props) { + const post = useFragment(graphql`...`, props.post); + const allUrls = []; + // `media` and `urls` are exported from the scope that will wrap this code, + // but `comments` is not (it doesn't need to be memoized, bc the callback + // only checks `comments.length`) + // because of the scope, the let declaration for media and urls are lifted + // out of the scope, and the destructure statement ends up turning into + // a reassignment, instead of a const declaration. this means we try to + // reassign `comments` when there's no declaration for it. + const { media, comments, urls } = post; + const onClick = (e) => { + if (!comments.length) { + return; + } + console.log(comments.length); + }; + allUrls.push(...urls); + return ; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/destructuring-object-default.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/destructuring-object-default.js new file mode 100644 index 0000000000..f380862d34 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/destructuring-object-default.js @@ -0,0 +1,4 @@ +function Component(props) { + const { x: { y } = { y: "default" } } = props.y; + return y; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/destructuring-object-param-default.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/destructuring-object-param-default.js new file mode 100644 index 0000000000..66712fe5ff --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/destructuring-object-param-default.js @@ -0,0 +1,3 @@ +function Component({ a = 2 }) { + return a; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/destructuring-property-inference.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/destructuring-property-inference.js new file mode 100644 index 0000000000..47cba2aa68 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/destructuring-property-inference.js @@ -0,0 +1,7 @@ +function Component(props) { + const x = []; + x.push(props.value); + const { length: y } = x; + foo(y); + return [x, y]; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/destructuring.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/destructuring.js new file mode 100644 index 0000000000..1e226e3e72 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/destructuring.js @@ -0,0 +1,19 @@ +function foo(a, b, c) { + const [ + d, + [ + { + e: { f }, + ...g + }, + ], + ...h + ] = a; + const { + l: { + m: [[n], ...o], + }, + p, + } = b; + return [d, f, g, h, n, o, p]; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/disable-jsx-memoization.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/disable-jsx-memoization.js new file mode 100644 index 0000000000..42125e01a7 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/disable-jsx-memoization.js @@ -0,0 +1,12 @@ +// @memoizeJsxElements false +function Component(props) { + const [name, setName] = useState(null); + const onChange = function (e) { + setName(e.target.value); + }; + return ( +
+ +
+ ); +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/do-while-break.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/do-while-break.js new file mode 100644 index 0000000000..5a311fe9a3 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/do-while-break.js @@ -0,0 +1,6 @@ +function Component(props) { + do { + break; + } while (props.cond); + return props; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/do-while-compound-test.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/do-while-compound-test.js new file mode 100644 index 0000000000..3588f94706 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/do-while-compound-test.js @@ -0,0 +1,9 @@ +function Component(props) { + let x = [1, 2, 3]; + let ret = []; + do { + let item = x.pop(); + ret.push(item * 2); + } while (x.length && props.cond); + return ret; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/do-while-conditional-break.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/do-while-conditional-break.js new file mode 100644 index 0000000000..c64286efc3 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/do-while-conditional-break.js @@ -0,0 +1,10 @@ +function Component(props) { + let x = [0, 1, 2, 3]; + do { + if (x === 0) { + break; + } + mutate(x); + } while (props.cond); + return x; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/do-while-continue.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/do-while-continue.js new file mode 100644 index 0000000000..a4792f7891 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/do-while-continue.js @@ -0,0 +1,13 @@ +function Component() { + const x = [0, 1, 2, 3]; + const ret = []; + do { + const item = x.pop(); + if (item === 0) { + continue; + } + ret.push(item / 2); + } while (x.length); + + return ret; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/do-while-early-unconditional-break.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/do-while-early-unconditional-break.js new file mode 100644 index 0000000000..764f2d4be9 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/do-while-early-unconditional-break.js @@ -0,0 +1,8 @@ +function Component(props) { + let x = [1, 2, 3]; + do { + mutate(x); + break; + } while (props.cond); + return x; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/do-while-simple.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/do-while-simple.js new file mode 100644 index 0000000000..b1d79aaaf5 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/do-while-simple.js @@ -0,0 +1,9 @@ +function Component() { + let x = [1, 2, 3]; + let ret = []; + do { + let item = x.pop(); + ret.push(item * 2); + } while (x.length); + return ret; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/dominator.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/dominator.js new file mode 100644 index 0000000000..488f1bee85 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/dominator.js @@ -0,0 +1,33 @@ +function Component(props) { + let x = 0; + label: if (props.a) { + x = 1; + } else { + if (props.b) { + x = 2; + } else { + break label; + } + x = 3; + } + label2: switch (props.c) { + case "a": { + x = 4; + break; + } + case "b": { + break label2; + } + case "c": { + x = 5; + // intentional fallthrough + } + default: { + x = 6; + } + } + if (props.d) { + return null; + } + return x; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/early-return.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/early-return.js new file mode 100644 index 0000000000..deefb5d7f0 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/early-return.js @@ -0,0 +1,8 @@ +function MyApp(props) { + let res; + if (props.cond) { + return; + } else { + res = 1; + } +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error._todo.computed-lval-in-destructure.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error._todo.computed-lval-in-destructure.js new file mode 100644 index 0000000000..f663f55207 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error._todo.computed-lval-in-destructure.js @@ -0,0 +1,6 @@ +function Component(props) { + const computedKey = props.key; + const { [computedKey]: x } = props.val; + + return x; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error._todo.multi-arrow-expr-export-default-gating-test.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error._todo.multi-arrow-expr-export-default-gating-test.js new file mode 100644 index 0000000000..6d20710d2b --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error._todo.multi-arrow-expr-export-default-gating-test.js @@ -0,0 +1,9 @@ +// @gating +const ErrorView = (error, _retry) => ; + +export default Renderer = (props) => ( + + + + +); diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.babel-existing-react-namespace-import.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.babel-existing-react-namespace-import.js new file mode 100644 index 0000000000..231a979838 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.babel-existing-react-namespace-import.js @@ -0,0 +1,15 @@ +import * as React from "react"; + +function Component(props) { + const [x] = React.useState(0); + const expensiveNumber = React.useMemo(() => calculateExpensiveNumber(x), [x]); + + return
{expensiveNumber}
; +} + +function Component2(props) { + const [x] = React.useState(0); + const expensiveNumber = React.useMemo(() => calculateExpensiveNumber(x), [x]); + + return
{expensiveNumber}
; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.bug-validate-no-set-state-not-all-mutable-range-extensions-are-bad.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.bug-validate-no-set-state-not-all-mutable-range-extensions-are-bad.js new file mode 100644 index 0000000000..e8301cfd6e --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.bug-validate-no-set-state-not-all-mutable-range-extensions-are-bad.js @@ -0,0 +1,24 @@ +function Component(props) { + const logEvent = useLogging(props.appId); + const [currentStep, setCurrentStep] = useState(0); + + const onSubmit = (errorEvent) => { + // 2. onSubmit inherits the mutable range of logEvent + logEvent(errorEvent); + // 3. this call then triggers the ValidateNoSetStateInRender check incorrectly, even though + // onSubmit is not called during render (although it _could_ be, if OtherComponent does so. + // but we can't tell without x-file analysis) + setCurrentStep(1); + }; + + switch (currentStep) { + case 0: + return ; + case 1: + return ; + default: + // 1. logEvent's mutable range is extended to this instruction + logEvent("Invalid step"); + return ; + } +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.call-args-destructuring-asignment-complex.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.call-args-destructuring-asignment-complex.js new file mode 100644 index 0000000000..6f5dd4ea4a --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.call-args-destructuring-asignment-complex.js @@ -0,0 +1,5 @@ +function Component(props) { + let x = makeObject(); + x.foo(([[x]] = makeObject())); + return x; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.codegen-error-on-conflicting-imports.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.codegen-error-on-conflicting-imports.js new file mode 100644 index 0000000000..a275e6671f --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.codegen-error-on-conflicting-imports.js @@ -0,0 +1,6 @@ +// @enableEmitFreeze @instrumentForget + +let makeReadOnly = "conflicting identifier"; +function useFoo(props) { + return foo(props.x); +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.hoisted-function-declaration.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.hoisted-function-declaration.js new file mode 100644 index 0000000000..9e5fec3f36 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.hoisted-function-declaration.js @@ -0,0 +1,8 @@ +function component(a) { + let t = { a }; + x(t); // hoisted call + function x(p) { + p.foo(); + } + return t; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.hooks-with-React-namespace.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.hooks-with-React-namespace.js new file mode 100644 index 0000000000..41a3271cee --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.hooks-with-React-namespace.js @@ -0,0 +1,4 @@ +function Foo() { + const [x, setX] = React.useState(1); + return x; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-access-ref-during-render.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-access-ref-during-render.js new file mode 100644 index 0000000000..0be1f1047a --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-access-ref-during-render.js @@ -0,0 +1,6 @@ +// @debug +function Component(props) { + const ref = useRef(null); + const value = ref.current; + return value; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-array-push-frozen.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-array-push-frozen.js new file mode 100644 index 0000000000..3ede9c0463 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-array-push-frozen.js @@ -0,0 +1,6 @@ +function Component(props) { + const x = []; +
{x}
; + x.push(props.value); + return x; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-assign-hook-to-local.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-assign-hook-to-local.js new file mode 100644 index 0000000000..886860e4de --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-assign-hook-to-local.js @@ -0,0 +1,5 @@ +function Component(props) { + const x = useState; + const state = x(null); + return state[0]; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-capture-func-passed-to-jsx.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-capture-func-passed-to-jsx.js new file mode 100644 index 0000000000..35357391f9 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-capture-func-passed-to-jsx.js @@ -0,0 +1,11 @@ +function component(a, b) { + let y = { b }; + let z = { a }; + let x = function () { + z.a = 2; + y.b; + }; + let t = ; + mutate(x); // x should be frozen here + return t; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-computed-store-to-frozen-value.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-computed-store-to-frozen-value.js new file mode 100644 index 0000000000..a0741c5a58 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-computed-store-to-frozen-value.js @@ -0,0 +1,7 @@ +function Component(props) { + const x = makeObject(); + // freeze +
{x}
; + x[0] = true; + return x; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-delete-computed-property-of-frozen-value.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-delete-computed-property-of-frozen-value.js new file mode 100644 index 0000000000..d9b47447d3 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-delete-computed-property-of-frozen-value.js @@ -0,0 +1,7 @@ +function Component(props) { + const x = makeObject(); + // freeze +
{x}
; + delete x[y]; + return x; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-delete-property-of-frozen-value.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-delete-property-of-frozen-value.js new file mode 100644 index 0000000000..f4239d7f8a --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-delete-property-of-frozen-value.js @@ -0,0 +1,7 @@ +function Component(props) { + const x = makeObject(); + // freeze +
{x}
; + delete x.y; + return x; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-destructure-assignment-to-global.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-destructure-assignment-to-global.js new file mode 100644 index 0000000000..9bd077cdef --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-destructure-assignment-to-global.js @@ -0,0 +1,4 @@ +function useFoo(props) { + [x] = props; + return { x }; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-destructure-to-local-global-variables.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-destructure-to-local-global-variables.js new file mode 100644 index 0000000000..0bee2274ae --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-destructure-to-local-global-variables.js @@ -0,0 +1,6 @@ +function Component(props) { + let a; + [a, b] = props.value; + + return [a, b]; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-freeze-conditionally-mutable-lambda.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-freeze-conditionally-mutable-lambda.js new file mode 100644 index 0000000000..0ffb689787 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-freeze-conditionally-mutable-lambda.js @@ -0,0 +1,16 @@ +function Component(props) { + const x = {}; + let fn; + if (props.cond) { + // mutable + fn = () => { + x.value = props.value; + }; + } else { + // immutable + fn = () => { + x.value; + }; + } + return fn; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-freeze-mutable-lambda-mutate-local.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-freeze-mutable-lambda-mutate-local.js new file mode 100644 index 0000000000..846b9df81a --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-freeze-mutable-lambda-mutate-local.js @@ -0,0 +1,9 @@ +function Component(props) { + const x = {}; + const onChange = (e) => { + // INVALID! should use copy-on-write and pass the new value + x.value = e.target.value; + setX(x); + }; + return ; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-freeze-mutable-lambda-reassign-local.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-freeze-mutable-lambda-reassign-local.js new file mode 100644 index 0000000000..b13ea05c67 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-freeze-mutable-lambda-reassign-local.js @@ -0,0 +1,7 @@ +function Component(props) { + let x = ""; + const onChange = (e) => { + x = e.target.value; + }; + return ; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-function-expression-mutates-immutable-value.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-function-expression-mutates-immutable-value.js new file mode 100644 index 0000000000..c4d62da44c --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-function-expression-mutates-immutable-value.js @@ -0,0 +1,9 @@ +function Component(props) { + const [x, setX] = useState({ value: "" }); + const onChange = (e) => { + // INVALID! should use copy-on-write and pass the new value + x.value = e.target.value; + setX(x); + }; + return ; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-mutate-after-aliased-freeze.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-mutate-after-aliased-freeze.js new file mode 100644 index 0000000000..8b08aaa215 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-mutate-after-aliased-freeze.js @@ -0,0 +1,16 @@ +function Component(props) { + let x = []; + let y = x; + + if (props.p1) { + x = []; + } + + let _ = ; + + // y is MaybeFrozen at this point, since it may alias to x + // (which is the above line freezes) + y.push(props.p2); + + return ; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-mutate-after-freeze.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-mutate-after-freeze.js new file mode 100644 index 0000000000..a40fbcb31e --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-mutate-after-freeze.js @@ -0,0 +1,10 @@ +function Component(props) { + let x = []; + + let _ = ; + + // x is Frozen at this point + x.push(props.p2); + + return
{_}
; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-pass-hook-as-call-arg.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-pass-hook-as-call-arg.js new file mode 100644 index 0000000000..b53bcb8181 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-pass-hook-as-call-arg.js @@ -0,0 +1,3 @@ +function Component(props) { + return foo(useFoo); +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-pass-hook-as-prop.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-pass-hook-as-prop.js new file mode 100644 index 0000000000..4b3ea52d74 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-pass-hook-as-prop.js @@ -0,0 +1,3 @@ +function Component(props) { + return ; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-pass-ref-to-function.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-pass-ref-to-function.js new file mode 100644 index 0000000000..ce93fc174c --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-pass-ref-to-function.js @@ -0,0 +1,5 @@ +function Component(props) { + const ref = useRef(null); + const x = foo(ref); + return x.current; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-property-store-to-frozen-value.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-property-store-to-frozen-value.js new file mode 100644 index 0000000000..ff54bb789a --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-property-store-to-frozen-value.js @@ -0,0 +1,7 @@ +function Component(props) { + const x = makeObject(); + // freeze +
{x}
; + x.y = true; + return x; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-ref-in-callback-invoked-during-render.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-ref-in-callback-invoked-during-render.js new file mode 100644 index 0000000000..f400b30286 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-ref-in-callback-invoked-during-render.js @@ -0,0 +1,9 @@ +// @debug +function Component(props) { + const ref = useRef(null); + const renderItem = (item) => { + const current = ref.current; + return ; + }; + return {props.items.map((item) => renderItem(item))}; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-ref-value-as-props.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-ref-value-as-props.js new file mode 100644 index 0000000000..3cf0b2aaf8 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-ref-value-as-props.js @@ -0,0 +1,4 @@ +function Component(props) { + const ref = useRef(null); + return ; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-set-and-read-ref-during-render.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-set-and-read-ref-during-render.js new file mode 100644 index 0000000000..97ce6931db --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-set-and-read-ref-during-render.js @@ -0,0 +1,5 @@ +function Component(props) { + const ref = useRef(null); + ref.current = props.value; + return ref.current; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-sketchy-code-use-forget.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-sketchy-code-use-forget.js new file mode 100644 index 0000000000..08f080632c --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-sketchy-code-use-forget.js @@ -0,0 +1,7 @@ +/* eslint-disable react-hooks/rules-of-hooks */ +function lowercasecomponent() { + "use forget"; + const x = []; + return
{x}
; +} +/* eslint-enable react-hooks/rules-of-hooks */ diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-ternary-with-hook-values.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-ternary-with-hook-values.js new file mode 100644 index 0000000000..3a47b73e1c --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-ternary-with-hook-values.js @@ -0,0 +1,4 @@ +function Component(props) { + const x = props.cond ? useA : useB; + return x(); +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-unconditional-set-state-in-render.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-unconditional-set-state-in-render.js new file mode 100644 index 0000000000..afef24308b --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-unconditional-set-state-in-render.js @@ -0,0 +1,9 @@ +function Component(props) { + const [x, setX] = useState(0); + const aliased = setX; + + setX(1); + aliased(2); + + return x; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-use-ref-added-to-dep-without-type-info.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-use-ref-added-to-dep-without-type-info.js new file mode 100644 index 0000000000..bbf5facc4a --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-use-ref-added-to-dep-without-type-info.js @@ -0,0 +1,12 @@ +function Foo({ a }) { + const ref = useRef(); + // type information is lost here as we don't track types of fields + const val = { ref }; + // without type info, we don't know that val.ref.current is a ref value so we + // *would* end up depending on val.ref.current + // however, this is an instance of accessing a ref during render and is disallowed + // under React's rules, so we reject this input + const x = { a, val: val.ref.current }; + + return ; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-useMemo-async-callback.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-useMemo-async-callback.js new file mode 100644 index 0000000000..e9da86149c --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-useMemo-async-callback.js @@ -0,0 +1,6 @@ +function component(a, b) { + let x = useMemo(async () => { + await a; + }, []); + return x; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-useMemo-callback-args.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-useMemo-callback-args.js new file mode 100644 index 0000000000..ae3c3379e1 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.invalid-useMemo-callback-args.js @@ -0,0 +1,4 @@ +function component(a, b) { + let x = useMemo((c) => a, []); + return x; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.mutate-captured-arg-separately.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.mutate-captured-arg-separately.js new file mode 100644 index 0000000000..3545a21849 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.mutate-captured-arg-separately.js @@ -0,0 +1,10 @@ +// Let's not support identifiers defined after use for now. +function component(a) { + let y = function () { + m(x); + }; + + let x = { a }; + m(x); + return y; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.mutate-global-increment-op-invalid-react.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.mutate-global-increment-op-invalid-react.js new file mode 100644 index 0000000000..6d754345cf --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.mutate-global-increment-op-invalid-react.js @@ -0,0 +1,6 @@ +let renderCount = 0; + +function NoHooks() { + renderCount++; + return
; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.reassignment-to-global.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.reassignment-to-global.js new file mode 100644 index 0000000000..d0509a3d52 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.reassignment-to-global.js @@ -0,0 +1,5 @@ +function Component() { + // Cannot assign to globals + someUnknownGlobal = true; + moduleLocal = true; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.todo-kitchensink.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.todo-kitchensink.js new file mode 100644 index 0000000000..111f9b25b1 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.todo-kitchensink.js @@ -0,0 +1,70 @@ +function foo([a, b], { c, d, e = "e" }, f = "f", ...args) { + let i = 0; + var x = []; + + class Bar { + #secretSauce = 42; + constructor() { + console.log(this.#secretSauce); + } + } + + const g = { b() {}, c: () => {} }; + const { z, aa = "aa" } = useCustom(); + + ; + ; + + const j = function bar([quz, qux], ...args) {}; + + for (; i < 3; i += 1) { + x.push(i); + } + for (; i < 3; ) { + break; + } + for (;;) { + break; + } + + graphql` + ${g} + `; + + graphql`\\t\n`; + + for (c of [1, 2]) { + } + for ([v] of [[1], [2]]) { + } + for ({ v } of [{ v: 1 }, { v: 2 }]) { + } + + for (let x in { a: 1 }) { + } + + let updateIdentifier = 0; + --updateIdentifier; + ++updateIdentifier; + updateIdentifier.y++; + updateIdentifier.y--; + + switch (i) { + case 1 + 1: { + } + case foo(): { + } + case x.y: { + } + default: { + } + } + + function component(a) { + // Add support for function declarations once we support `var` hoisting. + function t() {} + t(); + } +} + +let moduleLocal = false; diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.todo-unconditional-set-state-lambda.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.todo-unconditional-set-state-lambda.js new file mode 100644 index 0000000000..8a89c2cbb1 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.todo-unconditional-set-state-lambda.js @@ -0,0 +1,12 @@ +function Component(props) { + let y = 0; + const [x, setX] = useState(0); + + const foo = () => { + setX(1); + y = 1; // TODO: force foo's mutable range to extend, but ideally we can just remove this line + }; + foo(); + + return [x, y]; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.todo.destructure-assignment-to-context-var.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.todo.destructure-assignment-to-context-var.js new file mode 100644 index 0000000000..6e2a09649d --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.todo.destructure-assignment-to-context-var.js @@ -0,0 +1,9 @@ +function useFoo(props) { + let x; + [x] = props; + const foo = () => { + x = getX(props); + }; + foo(); + return { x }; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.useMemo-callback-generator.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.useMemo-callback-generator.js new file mode 100644 index 0000000000..2a4739a0db --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.useMemo-callback-generator.js @@ -0,0 +1,9 @@ +function component(a, b) { + // we don't handle generators at all so this test isn't + // useful for now, but adding this test in case we do + // add support for generators in the future. + let x = useMemo(function* () { + yield a; + }, []); + return x; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.while-with-assignment-in-test.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.while-with-assignment-in-test.js new file mode 100644 index 0000000000..0ad8369a39 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/error.while-with-assignment-in-test.js @@ -0,0 +1,10 @@ +function f(reader) { + const queue = [1, 2, 3]; + let value = 0; + let sum = 0; + // BUG: we need to codegen the complex test expression + while ((value = queue.pop()) != null) { + sum += value; + } + return sum; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/escape-analysis-destructured-rest-element.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/escape-analysis-destructured-rest-element.js new file mode 100644 index 0000000000..cdfce1b258 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/escape-analysis-destructured-rest-element.js @@ -0,0 +1,7 @@ +function Component(props) { + // b is an object, must be memoized even though the input is not memoized + const { a, ...b } = props.a; + // d is an array, mut be memoized even though the input is not memoized + const [c, ...d] = props.c; + return
; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/escape-analysis-jsx-child.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/escape-analysis-jsx-child.js new file mode 100644 index 0000000000..7df580429c --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/escape-analysis-jsx-child.js @@ -0,0 +1,11 @@ +function foo(a, b, c) { + const x = []; + if (a) { + const y = []; + if (b) { + y.push(c); + } + x.push(
{y}
); + } + return x; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/escape-analysis-logical.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/escape-analysis-logical.js new file mode 100644 index 0000000000..4582a56fa9 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/escape-analysis-logical.js @@ -0,0 +1,8 @@ +function Component(props) { + const a = [props.a]; + const b = [props.b]; + const c = [props.c]; + // We don't do constant folding for non-primitive values (yet) so we consider + // that any of a, b, or c could return here + return (a && b) || c; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/escape-analysis-non-escaping-interleaved-allocating-dependency.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/escape-analysis-non-escaping-interleaved-allocating-dependency.js new file mode 100644 index 0000000000..a7646fcc95 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/escape-analysis-non-escaping-interleaved-allocating-dependency.js @@ -0,0 +1,15 @@ +function Component(props) { + // a can be independently memoized, is not mutated later + const a = [props.a]; + + // b and c are interleaved and grouped into a single scope, + // but they are independent values. c does not escape, but + // we need to ensure that a is memoized or else b will invalidate + // on every render since a is a dependency. + const b = []; + const c = {}; + c.a = a; + b.push(props.b); + + return b; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/escape-analysis-non-escaping-interleaved-allocating-nested-dependency.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/escape-analysis-non-escaping-interleaved-allocating-nested-dependency.js new file mode 100644 index 0000000000..21e3cd07f6 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/escape-analysis-non-escaping-interleaved-allocating-nested-dependency.js @@ -0,0 +1,24 @@ +function Component(props) { + // a can be independently memoized, is not mutated later + // but a is a dependnecy of b, which is a dependency of c. + // we have to memoize a to avoid breaking memoization of b, + // to avoid breaking memoization of c. + const a = [props.a]; + + // a can be independently memoized, is not mutated later, + // but is a dependency of d which is part of c's scope. + // we have to memoize b to avoid breaking memoization of c. + const b = [a]; + + // c and d are interleaved and grouped into a single scope, + // but they are independent values. d does not escape, but + // we need to ensure that b is memoized or else b will invalidate + // on every render since a is a dependency. we also need to + // ensure that a is memoized, since it's a dependency of b. + const c = []; + const d = {}; + d.b = b; + c.push(props.b); + + return c; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/escape-analysis-non-escaping-interleaved-primitive-dependency.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/escape-analysis-non-escaping-interleaved-primitive-dependency.js new file mode 100644 index 0000000000..b8d3bd280c --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/escape-analysis-non-escaping-interleaved-primitive-dependency.js @@ -0,0 +1,17 @@ +function Component(props) { + // a does not need to be memoized ever, even though it's a + // dependency of c, which exists in a scope that has a memoized + // output. it doesn't need to be memoized bc the value is a primitive type. + const a = props.a + props.b; + + // b and c are interleaved and grouped into a single scope, + // but they are independent values. c does not escape, but + // we need to ensure that a is memoized or else b will invalidate + // on every render since a is a dependency. + const b = []; + const c = {}; + c.a = a; + b.push(props.c); + + return b; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/escape-analysis-not-conditional-test.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/escape-analysis-not-conditional-test.js new file mode 100644 index 0000000000..d59b67810f --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/escape-analysis-not-conditional-test.js @@ -0,0 +1,5 @@ +function Component(props) { + const x = [props.a]; + const y = x ? props.b : props.c; + return y; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/escape-analysis-not-if-test.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/escape-analysis-not-if-test.js new file mode 100644 index 0000000000..e999f4e143 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/escape-analysis-not-if-test.js @@ -0,0 +1,10 @@ +function Component(props) { + const x = [props.a]; + let y; + if (x) { + y = props.b; + } else { + y = props.c; + } + return y; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/escape-analysis-not-switch-case.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/escape-analysis-not-switch-case.js new file mode 100644 index 0000000000..bf577624e4 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/escape-analysis-not-switch-case.js @@ -0,0 +1,10 @@ +function Component(props) { + const a = [props.a]; + let x = props.b; + switch (props.c) { + case a: { + x = props.d; + } + } + return x; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/escape-analysis-not-switch-test.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/escape-analysis-not-switch-test.js new file mode 100644 index 0000000000..58ceaff461 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/escape-analysis-not-switch-test.js @@ -0,0 +1,10 @@ +function Component(props) { + const a = [props.a]; + let x = props.b; + switch (a) { + case true: { + x = props.c; + } + } + return x; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/expression-with-assignment-dynamic.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/expression-with-assignment-dynamic.js new file mode 100644 index 0000000000..e3a58967b4 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/expression-with-assignment-dynamic.js @@ -0,0 +1,4 @@ +function f(y) { + let x = y; + return x + (x = 2) + x; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/expression-with-assignment.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/expression-with-assignment.js new file mode 100644 index 0000000000..5d4ec4c51b --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/expression-with-assignment.js @@ -0,0 +1,4 @@ +function f() { + let x = 1; + return x + (x = 2) + x; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/extend-scopes-if.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/extend-scopes-if.js new file mode 100644 index 0000000000..fd3b253585 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/extend-scopes-if.js @@ -0,0 +1,14 @@ +function foo(a, b, c) { + let x = []; + if (a) { + if (b) { + if (c) { + x.push(0); + } + } + } + if (x.length) { + return x; + } + return null; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/fbt-call-complex-param-value.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/fbt-call-complex-param-value.js new file mode 100644 index 0000000000..0683c1aa53 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/fbt-call-complex-param-value.js @@ -0,0 +1,9 @@ +import fbt from "fbt"; + +function Component(props) { + const text = fbt( + `Hello, ${fbt.param("(key) name", capitalize(props.name))}!`, + "(description) Greeting" + ); + return
{text}
; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/fbt-call.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/fbt-call.js new file mode 100644 index 0000000000..f0719d10f7 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/fbt-call.js @@ -0,0 +1,9 @@ +import fbt from "fbt"; + +function Component(props) { + const text = fbt( + `${fbt.param("(key) count", props.count)} items`, + "(description) Number of items" + ); + return
{text}
; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/fbt-params-complex-param-value.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/fbt-params-complex-param-value.js new file mode 100644 index 0000000000..31ef0115d1 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/fbt-params-complex-param-value.js @@ -0,0 +1,9 @@ +import fbt from "fbt"; + +function Component(props) { + return ( + + Hello {capitalize(props.name)} + + ); +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/fbt-params.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/fbt-params.js new file mode 100644 index 0000000000..c2a3207770 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/fbt-params.js @@ -0,0 +1,9 @@ +import fbt from "fbt"; + +function Component(props) { + return ( + + Hello {props.name} + + ); +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/fbt-template-string-same-scope.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/fbt-template-string-same-scope.js new file mode 100644 index 0000000000..09c531c33b --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/fbt-template-string-same-scope.js @@ -0,0 +1,17 @@ +import fbt from "fbt"; + +export function Component(props) { + let count = 0; + if (props.items) { + count = props.items.length; + } + return ( + + {fbt( + `for ${fbt.param("count", count)} experiences`, + `Label for the number of items`, + { project: "public" } + )} + + ); +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/for-empty-update-with-continue.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/for-empty-update-with-continue.js new file mode 100644 index 0000000000..8ad3eeeb16 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/for-empty-update-with-continue.js @@ -0,0 +1,9 @@ +function Component(props) { + let x = 0; + for (let i = 0; i < props.count; ) { + x += i; + i += 1; + continue; + } + return x; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/for-empty-update.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/for-empty-update.js new file mode 100644 index 0000000000..d1411e8498 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/for-empty-update.js @@ -0,0 +1,10 @@ +function Component(props) { + let x = 0; + for (let i = 0; i < props.count; ) { + x += i; + if (x > 10) { + break; + } + } + return x; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/for-logical.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/for-logical.js new file mode 100644 index 0000000000..b0e5a09fac --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/for-logical.js @@ -0,0 +1,12 @@ +function foo(props) { + let y = 0; + for ( + let x = 0; + x > props.min && x < props.max; + x += props.cond ? props.increment : 2 + ) { + x *= 2; + y += x; + } + return y; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/for-of-break.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/for-of-break.js new file mode 100644 index 0000000000..1248bc8306 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/for-of-break.js @@ -0,0 +1,7 @@ +function Component() { + const x = []; + for (const item of [1, 2]) { + break; + } + return x; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/for-of-conditional-break.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/for-of-conditional-break.js new file mode 100644 index 0000000000..23ebd337a8 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/for-of-conditional-break.js @@ -0,0 +1,10 @@ +function Component() { + const x = []; + for (const item of [1, 2]) { + if (item === 1) { + break; + } + x.push(item); + } + return x; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/for-of-continue.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/for-of-continue.js new file mode 100644 index 0000000000..4f5e878ba3 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/for-of-continue.js @@ -0,0 +1,11 @@ +function Component() { + const x = [0, 1, 2, 3]; + const ret = []; + for (const item of x) { + if (item === 0) { + continue; + } + ret.push(item / 2); + } + return ret; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/for-of-destructure.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/for-of-destructure.js new file mode 100644 index 0000000000..480bb662dd --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/for-of-destructure.js @@ -0,0 +1,8 @@ +function Component() { + let x = []; + let items = [{ v: 0 }, { v: 1 }, { v: 2 }]; + for (const { v } of items) { + x.push(v * 2); + } + return x; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/for-of-mutate.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/for-of-mutate.js new file mode 100644 index 0000000000..ea7d16c938 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/for-of-mutate.js @@ -0,0 +1,8 @@ +function Component(props) { + const collection = [makeObject()]; + const results = []; + for (const item of collection) { + results.push(
{mutate(item)}
); + } + return
{results}
; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/for-of-simple.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/for-of-simple.js new file mode 100644 index 0000000000..b708b1b3b9 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/for-of-simple.js @@ -0,0 +1,8 @@ +function Component() { + let x = []; + let items = [0, 1, 2]; + for (const ii of items) { + x.push(ii * 2); + } + return x; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/for-return.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/for-return.js new file mode 100644 index 0000000000..0e3651b75e --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/for-return.js @@ -0,0 +1,5 @@ +function Component(props) { + for (let i = 0; i < props.count; i++) { + return; + } +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/frozen-after-alias.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/frozen-after-alias.js new file mode 100644 index 0000000000..852504b81d --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/frozen-after-alias.js @@ -0,0 +1,10 @@ +function Component() { + const a = []; + const b = a; + useFreeze(a); + foo(b); // should be readonly, value is guaranteed frozen via alias + return b; +} + +function useFreeze() {} +function foo(x) {} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/function-declaration-reassign.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/function-declaration-reassign.js new file mode 100644 index 0000000000..92ee854664 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/function-declaration-reassign.js @@ -0,0 +1,7 @@ +function component() { + function x(a) { + a.foo(); + } + x = {}; + return x; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/function-declaration-redeclare.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/function-declaration-redeclare.js new file mode 100644 index 0000000000..03ba36473d --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/function-declaration-redeclare.js @@ -0,0 +1,7 @@ +function component() { + function x(a) { + a.foo(); + } + function x() {} + return x; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/function-declaration-simple.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/function-declaration-simple.js new file mode 100644 index 0000000000..f37d5e13ee --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/function-declaration-simple.js @@ -0,0 +1,8 @@ +function component(a) { + let t = { a }; + function x(p) { + p.foo(); + } + x(t); + return t; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/function-expression-captures-value-later-frozen-jsx.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/function-expression-captures-value-later-frozen-jsx.js new file mode 100644 index 0000000000..7e694fa1bd --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/function-expression-captures-value-later-frozen-jsx.js @@ -0,0 +1,12 @@ +function Component(props) { + let x = {}; + // onChange should be inferred as immutable, because the value + // it captures (`x`) is frozen by the time the function is referenced + const onChange = (e) => { + maybeMutate(x, e.target.value); + }; + if (props.cond) { +
{x}
; + } + return ; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/function-expression-maybe-mutates-hook-return-value.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/function-expression-maybe-mutates-hook-return-value.js new file mode 100644 index 0000000000..fcf38652b1 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/function-expression-maybe-mutates-hook-return-value.js @@ -0,0 +1,12 @@ +function Component(props) { + const id = useSelectedEntitytId(); + // this example should infer `id` as mutable, and then infer `onLoad` as mutable, + // and be rejected because onLoad cannot be passed as a frozen value in the JSX. + // however, we likely have to allow this example to work, because hook return + // values are generally immutable in practice and are also widely referenced in + // callbacks. + const onLoad = () => { + log(id); + }; + return ; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/function-expression-with-store-to-parameter.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/function-expression-with-store-to-parameter.js new file mode 100644 index 0000000000..d8412a7c83 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/function-expression-with-store-to-parameter.js @@ -0,0 +1,9 @@ +function Component(props) { + const mutate = (object, key, value) => { + object.updated = true; + object[key] = value; + }; + const x = makeObject(props); + mutate(x); + return x; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/function-param-assignment-pattern.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/function-param-assignment-pattern.js new file mode 100644 index 0000000000..2f2967583d --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/function-param-assignment-pattern.js @@ -0,0 +1,3 @@ +function Component(x = "default", y = [{}]) { + return [x, y]; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/gating-test-export-default-function.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/gating-test-export-default-function.js new file mode 100644 index 0000000000..0189289a52 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/gating-test-export-default-function.js @@ -0,0 +1,14 @@ +// @gating @forgetDirective +export default function Bar(props) { + "use forget"; + return
{props.bar}
; +} + +function NoForget(props) { + return {props.noForget}; +} + +function Foo(props) { + "use forget"; + return {props.bar}; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/gating-test-export-function-and-default.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/gating-test-export-function-and-default.js new file mode 100644 index 0000000000..ecb8eec81c --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/gating-test-export-function-and-default.js @@ -0,0 +1,14 @@ +// @gating @forgetDirective +export default function Bar(props) { + "use forget"; + return
{props.bar}
; +} + +function NoForget(props) { + return {props.noForget}; +} + +export function Foo(props) { + "use forget"; + return {props.bar}; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/gating-test-export-function.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/gating-test-export-function.js new file mode 100644 index 0000000000..01039a7f85 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/gating-test-export-function.js @@ -0,0 +1,14 @@ +// @gating @forgetDirective +export function Bar(props) { + "use forget"; + return
{props.bar}
; +} + +export function NoForget(props) { + return {props.noForget}; +} + +export function Foo(props) { + "use forget"; + return {props.bar}; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/gating-test.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/gating-test.js new file mode 100644 index 0000000000..0270dffc5f --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/gating-test.js @@ -0,0 +1,14 @@ +// @gating @forgetDirective +function Bar(props) { + "use forget"; + return
{props.bar}
; +} + +function NoForget(props) { + return {props.noForget}; +} + +function Foo(props) { + "use forget"; + return {props.bar}; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/global-jsx-tag-lowered-between-mutations.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/global-jsx-tag-lowered-between-mutations.js new file mode 100644 index 0000000000..8a0744fd50 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/global-jsx-tag-lowered-between-mutations.js @@ -0,0 +1,15 @@ +function Component(props) { + const maybeMutable = new MaybeMutable(); + // NOTE: this will produce invalid output. + // The HIR is roughly: + // ⌵ mutable range of `maybeMutable` + // StoreLocal maybeMutable = ... ⌝ + // t0 = LoadGlobal View ⎮ <-- View is lowered inside this mutable range + // and thus gets becomes an output of this scope, + // gets promoted to temporary + // t1 = LoadGlobal maybeMutate ⎮ + // t2 = LoadLocal maybeMutable ⎮ + // t3 = Call t1(t2) ⌟ + // t4 = Jsx tag=t0 props=[] children=[t3] <-- `t0` is an invalid tag + return {maybeMutate(maybeMutable)}; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/globals-Boolean.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/globals-Boolean.js new file mode 100644 index 0000000000..b19c8ff7a0 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/globals-Boolean.js @@ -0,0 +1,5 @@ +function Component(props) { + const x = {}; + const y = Boolean(x); + return [x, y]; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/globals-Number.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/globals-Number.js new file mode 100644 index 0000000000..8831bb4a33 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/globals-Number.js @@ -0,0 +1,5 @@ +function Component(props) { + const x = {}; + const y = Number(x); + return [x, y]; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/globals-String.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/globals-String.js new file mode 100644 index 0000000000..d5e769807e --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/globals-String.js @@ -0,0 +1,5 @@ +function Component(props) { + const x = {}; + const y = String(x); + return [x, y]; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/holey-array-expr.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/holey-array-expr.js new file mode 100644 index 0000000000..533b5553a1 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/holey-array-expr.js @@ -0,0 +1,4 @@ +function t(props) { + let x = [, foo, props]; + return x; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/holey-array-pattern-dce-2.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/holey-array-pattern-dce-2.js new file mode 100644 index 0000000000..3009a00812 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/holey-array-pattern-dce-2.js @@ -0,0 +1,4 @@ +function t(props) { + let [foo, bar, ,] = props; + return foo; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/holey-array-pattern-dce.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/holey-array-pattern-dce.js new file mode 100644 index 0000000000..2c070d4955 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/holey-array-pattern-dce.js @@ -0,0 +1,4 @@ +function t(props) { + let [, foo, bar] = props; + return foo; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/holey-array.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/holey-array.js new file mode 100644 index 0000000000..302672aa1c --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/holey-array.js @@ -0,0 +1,5 @@ +function t(props) { + let [, setstate] = useState(); + setstate(1); + return props.foo; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/hook-call.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/hook-call.js new file mode 100644 index 0000000000..f77767cfc8 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/hook-call.js @@ -0,0 +1,14 @@ +function useFreeze() {} +function foo() {} + +function Component(props) { + const x = []; + const y = useFreeze(x); + foo(y, x); + return ( + + {x} + {y} + + ); +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/hook-inside-logical-expression.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/hook-inside-logical-expression.js new file mode 100644 index 0000000000..483edd58bb --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/hook-inside-logical-expression.js @@ -0,0 +1,4 @@ +function Component(props) { + const user = useFragment(graphql`...`, props.user) ?? {}; + return user.name; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/hooks-freeze-arguments.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/hooks-freeze-arguments.js new file mode 100644 index 0000000000..cdb1fce7e1 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/hooks-freeze-arguments.js @@ -0,0 +1,10 @@ +function Component() { + const a = []; + useFreeze(a); // should freeze + useFreeze(a); // should be readonly + call(a); // should be readonly + return a; +} + +function useFreeze(x) {} +function call(x) {} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/hooks-freeze-possibly-mutable-arguments.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/hooks-freeze-possibly-mutable-arguments.js new file mode 100644 index 0000000000..bcf51ccc4e --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/hooks-freeze-possibly-mutable-arguments.js @@ -0,0 +1,17 @@ +function Component(props) { + const cond = props.cond; + const x = props.x; + let a; + if (cond) { + a = x; + } else { + a = []; + } + useFreeze(a); // should freeze, value *may* be mutable + useFreeze(a); // should be readonly + call(a); // should be readonly + return a; +} + +function useFreeze(x) {} +function call(x) {} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/immutable-hooks.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/immutable-hooks.js new file mode 100644 index 0000000000..b4103fa5da --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/immutable-hooks.js @@ -0,0 +1,9 @@ +// @enableAssumeHooksFollowRulesOfReact true +function Component(props) { + const x = {}; + // In enableAssumeHooksFollowRulesOfReact mode hooks freeze their inputs and return frozen values + const y = useFoo(x); + // Thus both x and y are frozen here, and x can be independently memoized + bar(x, y); + return [x, y]; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/inadvertent-mutability-readonly-class.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/inadvertent-mutability-readonly-class.js new file mode 100644 index 0000000000..11740ef0a4 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/inadvertent-mutability-readonly-class.js @@ -0,0 +1,15 @@ +function Component(props) { + const env = useRelayEnvironment(); + // Note: this is a class has no mutable methods, ie it always treats `this` as readonly + const mutator = new Mutator(env); + + useOtherHook(); + + // `x` should be independently memoizeable, since foo(x, mutator) cannot mutate + // the mutator. + const x = {}; + foo(x, mutator); + return x; +} + +class Mutator {} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/inadvertent-mutability-readonly-lambda.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/inadvertent-mutability-readonly-lambda.js new file mode 100644 index 0000000000..bd10465c74 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/inadvertent-mutability-readonly-lambda.js @@ -0,0 +1,13 @@ +function Component(props) { + const [value, setValue] = useState(null); + // NOTE: this lambda does not capture any mutable values (only the state setter) + // and thus should be treated as readonly + const onChange = (e) => setValue((value) => value + e.target.value); + + useOtherHook(); + + // x should be independently memoizeable, since foo(x, onChange) cannot modify onChange + const x = {}; + foo(x, onChange); + return x; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/independent-across-if.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/independent-across-if.js new file mode 100644 index 0000000000..d36900fff7 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/independent-across-if.js @@ -0,0 +1,28 @@ +function compute() {} +function mutate() {} +function foo() {} +function Foo() {} + +/** + * Should produce 3 scopes: + * + * a: inputs=props.a & props.c; outputs=a + * a = compute(props.a); + * if (props.c) + * mutate(a) + * b: inputs=props.b & props.c; outputs=b + * b = compute(props.b); + * if (props.c) + * mutate(b) + * return: inputs=a, b outputs=return + * return = + */ +function Component(props) { + const a = compute(props.a); + const b = compute(props.b); + if (props.c) { + mutate(a); + mutate(b); + } + return ; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/independent.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/independent.js new file mode 100644 index 0000000000..d7daa41b73 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/independent.js @@ -0,0 +1,19 @@ +/** + * Should produce 3 scopes: + * + * a: inputs=props.a, outputs=a + * a = compute(props.a); + * b: inputs=props.b, outputs=b + * b = compute(props.b); + * return: inputs=a, b outputs=return + * return = + */ +function Component(props) { + const a = compute(props.a); + const b = compute(props.b); + return ; +} + +function compute() {} +function foo() {} +function Foo() {} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/independently-memoize-object-property.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/independently-memoize-object-property.js new file mode 100644 index 0000000000..e76dce6c91 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/independently-memoize-object-property.js @@ -0,0 +1,7 @@ +function foo(a, b, c) { + const x = { a: a }; + // NOTE: this array should memoize independently from x, w only b,c as deps + x.y = [b, c]; + + return x; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/infer-computed-delete.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/infer-computed-delete.js new file mode 100644 index 0000000000..187e797f40 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/infer-computed-delete.js @@ -0,0 +1,6 @@ +// @debug +function Component(props) { + const x = makeObject(); + const y = delete x[props.value]; + return y; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/infer-global-object.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/infer-global-object.js new file mode 100644 index 0000000000..bcee757cc1 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/infer-global-object.js @@ -0,0 +1,13 @@ +// Check that we correctly resolve type and effect lookups on the javascript +// global object. +function Component(props) { + let neverAliasedOrMutated = foo(props.b); + let primitiveVal1 = Math.max(props.a, neverAliasedOrMutated); + let primitiveVal2 = Infinity; + let primitiveVal3 = globaThis.globalThis.NaN; + + // Even though we don't know the function signature of foo, + // we should be able to infer that it does not mutate its inputs. + foo(primitiveVal1, primitiveVal2, primitiveVal3); + return { primitiveVal1, primitiveVal2, primitiveVal3 }; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/infer-phi-primitive.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/infer-phi-primitive.js new file mode 100644 index 0000000000..faafa9ddd3 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/infer-phi-primitive.js @@ -0,0 +1,11 @@ +function foo(a, b) { + let x; + if (a) { + x = 1; + } else { + x = 2; + } + + let y = x; + return y; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/infer-property-delete.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/infer-property-delete.js new file mode 100644 index 0000000000..b854004444 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/infer-property-delete.js @@ -0,0 +1,5 @@ +function Component(props) { + const x = makeObject(); + const y = delete x.value; + return y; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/infer-types-through-type-cast.flow.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/infer-types-through-type-cast.flow.js new file mode 100644 index 0000000000..eaac49f9a2 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/infer-types-through-type-cast.flow.js @@ -0,0 +1,9 @@ +// @flow +function Component(props) { + // We can infer that `x` is a primitive bc it is aliased to `y`, + // which is used in a binary expression + const x = foo(); + const y = (x: any); + y + 1; + return x; +} \ No newline at end of file diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/inner-memo-value-not-promoted-to-outer-scope-dynamic.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/inner-memo-value-not-promoted-to-outer-scope-dynamic.js new file mode 100644 index 0000000000..dc36d75464 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/inner-memo-value-not-promoted-to-outer-scope-dynamic.js @@ -0,0 +1,14 @@ +function Component(props) { + const item = useFragment(FRAGMENT, props.item); + useFreeze(item); + + const count = new MaybeMutable(item); + return ( + + + {Text} + {{maybeMutate(count)}} + + + ); +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/inner-memo-value-not-promoted-to-outer-scope-static.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/inner-memo-value-not-promoted-to-outer-scope-static.js new file mode 100644 index 0000000000..5c92f8bcf5 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/inner-memo-value-not-promoted-to-outer-scope-static.js @@ -0,0 +1,11 @@ +function Component(props) { + const count = new MaybeMutable(); + return ( + + + {Text} + {{maybeMutate(count)}} + + + ); +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/interdependent-across-if.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/interdependent-across-if.js new file mode 100644 index 0000000000..8f05da6973 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/interdependent-across-if.js @@ -0,0 +1,22 @@ +function compute() {} +function foo() {} +function Foo() {} + +/** + * Should produce 1 scope: + * + * return: inputs=props.a & props.b & props.c; outputs=return + * const a = compute(props.a); + * const b = compute(props.b); + * if (props.c) + * foo(a, b); + * return = + */ +function Component(props) { + const a = compute(props.a); + const b = compute(props.b); + if (props.c) { + foo(a, b); + } + return ; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/interdependent.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/interdependent.js new file mode 100644 index 0000000000..aef5a385a3 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/interdependent.js @@ -0,0 +1,19 @@ +/** + * Should produce 1 scope: + * + * return: inputs=props.a & props.b; outputs=return + * const a = compute(props.a); + * const b = compute(props.b); + * foo(a, b); + * return = + */ +function Component(props) { + const a = compute(props.a); + const b = compute(props.b); + foo(a, b); + return ; +} + +function compute() {} +function foo() {} +function Foo() {} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/inverted-if-else.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/inverted-if-else.js new file mode 100644 index 0000000000..574de55c64 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/inverted-if-else.js @@ -0,0 +1,11 @@ +function foo(a, b, c) { + let x = null; + label: { + if (a) { + x = b; + break label; + } + x = c; + } + return x; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/inverted-if.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/inverted-if.js new file mode 100644 index 0000000000..97cd1fbff2 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/inverted-if.js @@ -0,0 +1,11 @@ +function foo(a, b, c, d) { + let y = []; + label: if (a) { + if (b) { + y.push(c); + break label; + } + y.push(d); + } + return y; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/issue852.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/issue852.js new file mode 100644 index 0000000000..907ff058d5 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/issue852.js @@ -0,0 +1,6 @@ +function Component(c) { + let x = { c }; + mutate(x); + let a = x; + let b = a; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/issue933-disjoint-set-infinite-loop.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/issue933-disjoint-set-infinite-loop.js new file mode 100644 index 0000000000..43d343bb1c --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/issue933-disjoint-set-infinite-loop.js @@ -0,0 +1,8 @@ +// This caused an infinite loop in the compiler +function MyApp(props) { + const y = makeObj(); + const tmp = y.a; + const tmp2 = tmp.b; + y.push(tmp2); + return y; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/jsx-empty-expression.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/jsx-empty-expression.js new file mode 100644 index 0000000000..357f27186e --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/jsx-empty-expression.js @@ -0,0 +1,8 @@ +export function Component(props) { + return ( +
+ {} + {props.a} +
+ ); +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/jsx-fragment.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/jsx-fragment.js new file mode 100644 index 0000000000..a8142a9539 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/jsx-fragment.js @@ -0,0 +1,10 @@ +function Foo(props) { + return ( + <> + Hello {props.greeting}{" "} +
+ <>Text +
+ + ); +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/jsx-member-expression-tag-grouping.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/jsx-member-expression-tag-grouping.js new file mode 100644 index 0000000000..4455f9a9ab --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/jsx-member-expression-tag-grouping.js @@ -0,0 +1,4 @@ +function Component(props) { + const maybeMutable = new MaybeMutable(); + return {maybeMutate(maybeMutable)}; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/jsx-member-expression.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/jsx-member-expression.js new file mode 100644 index 0000000000..40f36ac072 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/jsx-member-expression.js @@ -0,0 +1,7 @@ +function Component(props) { + return ( + + + + ); +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/jsx-namespaced-name.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/jsx-namespaced-name.js new file mode 100644 index 0000000000..e09a13331d --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/jsx-namespaced-name.js @@ -0,0 +1,3 @@ +function Component(props) { + return ; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/jsx-spread.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/jsx-spread.js new file mode 100644 index 0000000000..0dd5d5c96c --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/jsx-spread.js @@ -0,0 +1,5 @@ +function Component(props) { + return ( + + ); +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/jsx-tag-evaluation-order-non-global.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/jsx-tag-evaluation-order-non-global.js new file mode 100644 index 0000000000..b2440232c8 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/jsx-tag-evaluation-order-non-global.js @@ -0,0 +1,13 @@ +function Component(props) { + const maybeMutable = new MaybeMutable(); + let Tag = props.component; + // NOTE: the order of evaluation in the lowering is incorrect: + // the jsx element's tag observes `Tag` after reassignment, but should observe + // it before the reassignment. + return ( + + {((Tag = props.alternateComponent), maybeMutate(maybeMutable))} + + + ); +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/jsx-tag-evaluation-order.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/jsx-tag-evaluation-order.js new file mode 100644 index 0000000000..51f6b51ff7 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/jsx-tag-evaluation-order.js @@ -0,0 +1,9 @@ +function Component(props) { + let Tag = View; + return ( + + {((Tag = HScroll), props.value)} + + + ); +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/lambda-capture-returned-alias.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/lambda-capture-returned-alias.js new file mode 100644 index 0000000000..0bc0187f9a --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/lambda-capture-returned-alias.js @@ -0,0 +1,18 @@ +// Here, element should not be memoized independently of aliasedElement, since +// it is captured by fn. +// AnalyzeFunctions currently does not find captured objects. +// - mutated context refs are declared as `Capture` effect in `FunctionExpression.deps` +// - all other context refs are left as Unknown. InferReferenceEffects currently demotes +// them to reads +function CaptureNotMutate(props) { + const idx = foo(props.x); + const element = bar(props.el); + + const fn = function () { + const arr = { element }; + return arr[idx]; + }; + const aliasedElement = fn(); + mutate(aliasedElement); + return aliasedElement; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/lambda-mutate-shadowed-object.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/lambda-mutate-shadowed-object.js new file mode 100644 index 0000000000..4971f05bd7 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/lambda-mutate-shadowed-object.js @@ -0,0 +1,11 @@ +function Component() { + const x = {}; + { + const x = []; + const fn = function () { + mutate(x); + }; + fn(); + } + return x; // should return {} +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/lambda-mutated-non-reactive-to-reactive.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/lambda-mutated-non-reactive-to-reactive.js new file mode 100644 index 0000000000..85c905ea13 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/lambda-mutated-non-reactive-to-reactive.js @@ -0,0 +1,7 @@ +function f(a) { + let x; + (() => { + x = { a }; + })(); + return
; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/lambda-mutated-ref-non-reactive.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/lambda-mutated-ref-non-reactive.js new file mode 100644 index 0000000000..25f57c6374 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/lambda-mutated-ref-non-reactive.js @@ -0,0 +1,8 @@ +function f(a) { + let x; + (() => { + x = {}; + })(); + // this is not reactive on `x` as `x` is never reactive + return
; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/lambda-reassign-primitive.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/lambda-reassign-primitive.js new file mode 100644 index 0000000000..824b269bd5 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/lambda-reassign-primitive.js @@ -0,0 +1,14 @@ +// writing to primitives is not a 'mutate' or 'store' to context references, +// under current analysis in AnalyzeFunctions. +// $23:TFunction = Function @deps[ +// $21:TPrimitive, $22:TPrimitive]: + +function Component() { + let x = 40; + + const fn = function () { + x = x + 1; + }; + fn(); + return x; +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/lambda-reassign-shadowed-primitive.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/lambda-reassign-shadowed-primitive.js new file mode 100644 index 0000000000..66edf6b9f3 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/lambda-reassign-shadowed-primitive.js @@ -0,0 +1,11 @@ +function Component() { + const x = {}; + { + let x = 56; + const fn = function () { + x = 42; + }; + fn(); + } + return x; // should return {} +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/fixtures/lambda-with-fbt.js b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/lambda-with-fbt.js new file mode 100644 index 0000000000..539fc7e1f6 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/fixtures/lambda-with-fbt.js @@ -0,0 +1,30 @@ +import { fbt } from "fbt"; + +function Component() { + const buttonLabel = () => { + if (!someCondition) { + return {"Purchase as a gift"}; + } else if ( + !iconOnly && + showPrice && + item?.current_gift_offer?.price?.formatted != null + ) { + return ( + + {"Gift | "} + + {item?.current_gift_offer?.price?.formatted} + + + ); + } else if (!iconOnly && !showPrice) { + return {"Gift"}; + } + }; + + return ( + + ; + ; + + const j = function bar([quz, qux], ...args) {}; + + for (; i < 3; i += 1) { + x.push(i); + } + for (; i < 3; ) { + break; + } + for (;;) { + break; + } + + graphql` + ${g} + `; + + graphql`\\t\n`; + + for (c of [1, 2]) { + } + for ([v] of [[1], [2]]) { + } + for ({ v } of [{ v: 1 }, { v: 2 }]) { + } + + for (let x in { a: 1 }) { + } + + let updateIdentifier = 0; + --updateIdentifier; + ++updateIdentifier; + updateIdentifier.y++; + updateIdentifier.y--; + + switch (i) { + case 1 + 1: { + } + case foo(): { + } + case x.y: { + } + default: { + } + } + + function component(a) { + // Add support for function declarations once we support `var` hoisting. + function t() {} + t(); + } +} + +let moduleLocal = false; + + +Output: +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "foo", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [ + { + "type": "ArrayPattern", + "elements": [ + { + "type": "Identifier", + "name": "a", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "Identifier", + "name": "b", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ObjectPattern", + "properties": [ + { + "type": "Property", + "key": { + "type": "Identifier", + "name": "c", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "value": { + "type": "Identifier", + "name": "c", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "kind": "init", + "method": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "Property", + "key": { + "type": "Identifier", + "name": "d", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "value": { + "type": "Identifier", + "name": "d", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "kind": "init", + "method": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "Property", + "key": { + "type": "Identifier", + "name": "e", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "value": { + "type": "AssignmentPattern", + "left": { + "type": "Identifier", + "name": "e", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "right": { + "type": "StringLiteral", + "value": "e", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "kind": "init", + "method": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "AssignmentPattern", + "left": { + "type": "Identifier", + "name": "f", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "right": { + "type": "StringLiteral", + "value": "f", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "RestElement", + "argument": { + "type": "Identifier", + "name": "args", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "VariableDeclaration", + "kind": "let", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "i", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "NumericLiteral", + "value": 0, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "VariableDeclaration", + "kind": "var", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "ArrayExpression", + "elements": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ClassDeclaration", + "id": { + "type": "Identifier", + "name": "Bar", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "superClass": null, + "body": { + "type": "ClassBody", + "body": [ + { + "type": "ClassPrivateProperty", + "key": { + "type": "Identifier", + "name": "secretSauce", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "value": { + "type": "NumericLiteral", + "value": 4631107791820423168, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "static": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "constructor", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "value": { + "type": "FunctionExpression", + "id": null, + "params": [], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "console", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "log", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [ + { + "type": "MemberExpression", + "object": { + "type": "ThisExpression", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "PrivateName", + "id": { + "type": "Identifier", + "name": "secretSauce", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "kind": "constructor", + "computed": false, + "static": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "g", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "ObjectExpression", + "properties": [ + { + "type": "Property", + "key": { + "type": "Identifier", + "name": "b", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "value": { + "type": "FunctionExpression", + "id": null, + "params": [], + "body": { + "type": "BlockStatement", + "body": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "kind": "init", + "method": true, + "shorthand": false, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "Property", + "key": { + "type": "Identifier", + "name": "c", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "value": { + "type": "ArrowFunctionExpression", + "id": null, + "params": [], + "body": { + "type": "BlockStatement", + "body": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "expression": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "kind": "init", + "method": false, + "shorthand": false, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "ObjectPattern", + "properties": [ + { + "type": "Property", + "key": { + "type": "Identifier", + "name": "z", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "value": { + "type": "Identifier", + "name": "z", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "kind": "init", + "method": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "Property", + "key": { + "type": "Identifier", + "name": "aa", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "value": { + "type": "AssignmentPattern", + "left": { + "type": "Identifier", + "name": "aa", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "right": { + "type": "StringLiteral", + "value": "aa", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "kind": "init", + "method": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "useCustom", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "JSXElement", + "openingElement": { + "type": "JSXOpeningElement", + "name": { + "type": "JSXIdentifier", + "name": "Button", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "attributes": [ + { + "type": "JSXAttribute", + "name": { + "type": "JSXIdentifier", + "name": "haha", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "value": { + "type": "JSXExpressionContainer", + "expression": { + "type": "NumericLiteral", + "value": 4607182418800017408, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "selfClosing": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "children": [], + "closingElement": { + "type": "JSXClosingElement", + "name": { + "type": "JSXIdentifier", + "name": "Button", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "JSXElement", + "openingElement": { + "type": "JSXOpeningElement", + "name": { + "type": "JSXIdentifier", + "name": "Button", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "attributes": [], + "selfClosing": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "children": [ + { + "type": "JSXExpressionContainer", + "expression": { + "type": "JSXEmptyExpression", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "closingElement": { + "type": "JSXClosingElement", + "name": { + "type": "JSXIdentifier", + "name": "Button", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "j", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "FunctionExpression", + "id": { + "type": "Identifier", + "name": "bar", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [ + { + "type": "ArrayPattern", + "elements": [ + { + "type": "Identifier", + "name": "quz", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "Identifier", + "name": "qux", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "RestElement", + "argument": { + "type": "Identifier", + "name": "args", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ForStatement", + "init": null, + "test": { + "type": "BinaryExpression", + "left": { + "type": "Identifier", + "name": "i", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "operator": "<", + "right": { + "type": "NumericLiteral", + "value": 4613937818241073152, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "update": { + "type": "AssignmentExpression", + "operator": "+=", + "left": { + "type": "Identifier", + "name": "i", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "right": { + "type": "NumericLiteral", + "value": 4607182418800017408, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "push", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [ + { + "type": "Identifier", + "name": "i", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ForStatement", + "init": null, + "test": { + "type": "BinaryExpression", + "left": { + "type": "Identifier", + "name": "i", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "operator": "<", + "right": { + "type": "NumericLiteral", + "value": 4613937818241073152, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "update": null, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "BreakStatement", + "label": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ForStatement", + "init": null, + "test": null, + "update": null, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "BreakStatement", + "label": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "TaggedTemplateExpression", + "tag": { + "type": "Identifier", + "name": "graphql", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "quasi": { + "type": "TemplateLiteral", + "quasis": [ + { + "type": "TemplateElement", + "tail": false, + "value": { + "cooked": "\n ", + "raw": "\n " + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "TemplateElement", + "tail": true, + "value": { + "cooked": "\n ", + "raw": "\n " + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "expressions": [ + { + "type": "Identifier", + "name": "g", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "TaggedTemplateExpression", + "tag": { + "type": "Identifier", + "name": "graphql", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "quasi": { + "type": "TemplateLiteral", + "quasis": [ + { + "type": "TemplateElement", + "tail": true, + "value": { + "cooked": "\\t\n", + "raw": "\\\\t\\n" + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "expressions": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ForOfStatement", + "await": false, + "left": { + "type": "Identifier", + "name": "c", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "right": { + "type": "ArrayExpression", + "elements": [ + { + "type": "NumericLiteral", + "value": 4607182418800017408, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "NumericLiteral", + "value": 4611686018427387904, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "body": { + "type": "BlockStatement", + "body": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ForOfStatement", + "await": false, + "left": { + "type": "ArrayPattern", + "elements": [ + { + "type": "Identifier", + "name": "v", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "right": { + "type": "ArrayExpression", + "elements": [ + { + "type": "ArrayExpression", + "elements": [ + { + "type": "NumericLiteral", + "value": 4607182418800017408, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ArrayExpression", + "elements": [ + { + "type": "NumericLiteral", + "value": 4611686018427387904, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "body": { + "type": "BlockStatement", + "body": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ForOfStatement", + "await": false, + "left": { + "type": "ObjectPattern", + "properties": [ + { + "type": "Property", + "key": { + "type": "Identifier", + "name": "v", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "value": { + "type": "Identifier", + "name": "v", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "kind": "init", + "method": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "right": { + "type": "ArrayExpression", + "elements": [ + { + "type": "ObjectExpression", + "properties": [ + { + "type": "Property", + "key": { + "type": "Identifier", + "name": "v", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "value": { + "type": "NumericLiteral", + "value": 4607182418800017408, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "kind": "init", + "method": false, + "shorthand": false, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ObjectExpression", + "properties": [ + { + "type": "Property", + "key": { + "type": "Identifier", + "name": "v", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "value": { + "type": "NumericLiteral", + "value": 4611686018427387904, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "kind": "init", + "method": false, + "shorthand": false, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "body": { + "type": "BlockStatement", + "body": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ForInStatement", + "left": { + "type": "VariableDeclaration", + "kind": "let", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "right": { + "type": "ObjectExpression", + "properties": [ + { + "type": "Property", + "key": { + "type": "Identifier", + "name": "a", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "value": { + "type": "NumericLiteral", + "value": 4607182418800017408, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "kind": "init", + "method": false, + "shorthand": false, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "body": { + "type": "BlockStatement", + "body": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "VariableDeclaration", + "kind": "let", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "updateIdentifier", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "NumericLiteral", + "value": 0, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "UpdateExpression", + "operator": "--", + "argument": { + "type": "Identifier", + "name": "updateIdentifier", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "prefix": true, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "UpdateExpression", + "operator": "++", + "argument": { + "type": "Identifier", + "name": "updateIdentifier", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "prefix": true, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "UpdateExpression", + "operator": "++", + "argument": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "updateIdentifier", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "y", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "prefix": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "UpdateExpression", + "operator": "--", + "argument": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "updateIdentifier", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "y", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "prefix": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "SwitchStatement", + "discriminant": { + "type": "Identifier", + "name": "i", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "cases": [ + { + "type": "SwitchCase", + "test": { + "type": "BinaryExpression", + "left": { + "type": "NumericLiteral", + "value": 4607182418800017408, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "operator": "+", + "right": { + "type": "NumericLiteral", + "value": 4607182418800017408, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "consequent": [ + { + "type": "BlockStatement", + "body": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "SwitchCase", + "test": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "foo", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "consequent": [ + { + "type": "BlockStatement", + "body": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "SwitchCase", + "test": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "y", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "consequent": [ + { + "type": "BlockStatement", + "body": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "SwitchCase", + "test": null, + "consequent": [ + { + "type": "BlockStatement", + "body": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "component", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [ + { + "type": "Identifier", + "name": "a", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "t", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [], + "body": { + "type": "BlockStatement", + "body": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "t", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "VariableDeclaration", + "kind": "let", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "moduleLocal", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "BooleanLiteral", + "value": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "sourceType": "script", + "loc": null, + "range": { + "start": 0, + "end": 1 + } +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@error.todo-unconditional-set-state-lambda.js.snap b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@error.todo-unconditional-set-state-lambda.js.snap new file mode 100644 index 0000000000..6214d9de55 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@error.todo-unconditional-set-state-lambda.js.snap @@ -0,0 +1,393 @@ +--- +source: crates/forget_hermes_parser/tests/parser_test.rs +expression: "format!(\"Input:\\n{input}\\n\\nOutput:\\n{output}\")" +input_file: crates/forget_hermes_parser/tests/fixtures/error.todo-unconditional-set-state-lambda.js +--- +Input: +function Component(props) { + let y = 0; + const [x, setX] = useState(0); + + const foo = () => { + setX(1); + y = 1; // TODO: force foo's mutable range to extend, but ideally we can just remove this line + }; + foo(); + + return [x, y]; +} + + +Output: +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "Component", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [ + { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "VariableDeclaration", + "kind": "let", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "y", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "NumericLiteral", + "value": 0, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "ArrayPattern", + "elements": [ + { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "Identifier", + "name": "setX", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "useState", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [ + { + "type": "NumericLiteral", + "value": 0, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "foo", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "ArrowFunctionExpression", + "id": null, + "params": [], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "setX", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [ + { + "type": "NumericLiteral", + "value": 4607182418800017408, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "Identifier", + "name": "y", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "right": { + "type": "NumericLiteral", + "value": 4607182418800017408, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "expression": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "foo", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ReturnStatement", + "argument": { + "type": "ArrayExpression", + "elements": [ + { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "Identifier", + "name": "y", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "sourceType": "script", + "loc": null, + "range": { + "start": 0, + "end": 1 + } +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@error.todo.destructure-assignment-to-context-var.js.snap b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@error.todo.destructure-assignment-to-context-var.js.snap new file mode 100644 index 0000000000..340bda59d3 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@error.todo.destructure-assignment-to-context-var.js.snap @@ -0,0 +1,347 @@ +--- +source: crates/forget_hermes_parser/tests/parser_test.rs +expression: "format!(\"Input:\\n{input}\\n\\nOutput:\\n{output}\")" +input_file: crates/forget_hermes_parser/tests/fixtures/error.todo.destructure-assignment-to-context-var.js +--- +Input: +function useFoo(props) { + let x; + [x] = props; + const foo = () => { + x = getX(props); + }; + foo(); + return { x }; +} + + +Output: +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "useFoo", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [ + { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "VariableDeclaration", + "kind": "let", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "ArrayPattern", + "elements": [ + { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "right": { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "foo", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "ArrowFunctionExpression", + "id": null, + "params": [], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "right": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "getX", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [ + { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "expression": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "foo", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ReturnStatement", + "argument": { + "type": "ObjectExpression", + "properties": [ + { + "type": "Property", + "key": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "value": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "kind": "init", + "method": false, + "shorthand": true, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "sourceType": "script", + "loc": null, + "range": { + "start": 0, + "end": 1 + } +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@error.useMemo-callback-generator.js.snap b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@error.useMemo-callback-generator.js.snap new file mode 100644 index 0000000000..e4e9976084 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@error.useMemo-callback-generator.js.snap @@ -0,0 +1,217 @@ +--- +source: crates/forget_hermes_parser/tests/parser_test.rs +expression: "format!(\"Input:\\n{input}\\n\\nOutput:\\n{output}\")" +input_file: crates/forget_hermes_parser/tests/fixtures/error.useMemo-callback-generator.js +--- +Input: +function component(a, b) { + // we don't handle generators at all so this test isn't + // useful for now, but adding this test in case we do + // add support for generators in the future. + let x = useMemo(function* () { + yield a; + }, []); + return x; +} + + +Output: +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "component", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [ + { + "type": "Identifier", + "name": "a", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "Identifier", + "name": "b", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "VariableDeclaration", + "kind": "let", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "useMemo", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [ + { + "type": "FunctionExpression", + "id": null, + "params": [], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "YieldExpression", + "argument": { + "type": "Identifier", + "name": "a", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "delegate": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": true, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ArrayExpression", + "elements": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ReturnStatement", + "argument": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "sourceType": "script", + "loc": null, + "range": { + "start": 0, + "end": 1 + } +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@error.while-with-assignment-in-test.js.snap b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@error.while-with-assignment-in-test.js.snap new file mode 100644 index 0000000000..484cf852cb --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@error.while-with-assignment-in-test.js.snap @@ -0,0 +1,367 @@ +--- +source: crates/forget_hermes_parser/tests/parser_test.rs +expression: "format!(\"Input:\\n{input}\\n\\nOutput:\\n{output}\")" +input_file: crates/forget_hermes_parser/tests/fixtures/error.while-with-assignment-in-test.js +--- +Input: +function f(reader) { + const queue = [1, 2, 3]; + let value = 0; + let sum = 0; + // BUG: we need to codegen the complex test expression + while ((value = queue.pop()) != null) { + sum += value; + } + return sum; +} + + +Output: +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "f", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [ + { + "type": "Identifier", + "name": "reader", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "queue", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "ArrayExpression", + "elements": [ + { + "type": "NumericLiteral", + "value": 4607182418800017408, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "NumericLiteral", + "value": 4611686018427387904, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "NumericLiteral", + "value": 4613937818241073152, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "VariableDeclaration", + "kind": "let", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "value", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "NumericLiteral", + "value": 0, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "VariableDeclaration", + "kind": "let", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "sum", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "NumericLiteral", + "value": 0, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "WhileStatement", + "test": { + "type": "BinaryExpression", + "left": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "Identifier", + "name": "value", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "right": { + "type": "CallExpression", + "callee": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "queue", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "pop", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "operator": "!=", + "right": { + "type": "NullLiteral", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "+=", + "left": { + "type": "Identifier", + "name": "sum", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "right": { + "type": "Identifier", + "name": "value", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ReturnStatement", + "argument": { + "type": "Identifier", + "name": "sum", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "sourceType": "script", + "loc": null, + "range": { + "start": 0, + "end": 1 + } +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@escape-analysis-destructured-rest-element.js.snap b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@escape-analysis-destructured-rest-element.js.snap new file mode 100644 index 0000000000..4d615c7c8e --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@escape-analysis-destructured-rest-element.js.snap @@ -0,0 +1,390 @@ +--- +source: crates/forget_hermes_parser/tests/parser_test.rs +expression: "format!(\"Input:\\n{input}\\n\\nOutput:\\n{output}\")" +input_file: crates/forget_hermes_parser/tests/fixtures/escape-analysis-destructured-rest-element.js +--- +Input: +function Component(props) { + // b is an object, must be memoized even though the input is not memoized + const { a, ...b } = props.a; + // d is an array, mut be memoized even though the input is not memoized + const [c, ...d] = props.c; + return
; +} + + +Output: +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "Component", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [ + { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "ObjectPattern", + "properties": [ + { + "type": "Property", + "key": { + "type": "Identifier", + "name": "a", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "value": { + "type": "Identifier", + "name": "a", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "kind": "init", + "method": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "RestElement", + "argument": { + "type": "Identifier", + "name": "b", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "a", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "ArrayPattern", + "elements": [ + { + "type": "Identifier", + "name": "c", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "RestElement", + "argument": { + "type": "Identifier", + "name": "d", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "c", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ReturnStatement", + "argument": { + "type": "JSXElement", + "openingElement": { + "type": "JSXOpeningElement", + "name": { + "type": "JSXIdentifier", + "name": "div", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "attributes": [ + { + "type": "JSXAttribute", + "name": { + "type": "JSXIdentifier", + "name": "b", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "value": { + "type": "JSXExpressionContainer", + "expression": { + "type": "Identifier", + "name": "b", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "JSXAttribute", + "name": { + "type": "JSXIdentifier", + "name": "d", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "value": { + "type": "JSXExpressionContainer", + "expression": { + "type": "Identifier", + "name": "d", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "selfClosing": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "children": [], + "closingElement": { + "type": "JSXClosingElement", + "name": { + "type": "JSXIdentifier", + "name": "div", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "sourceType": "script", + "loc": null, + "range": { + "start": 0, + "end": 1 + } +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@escape-analysis-jsx-child.js.snap b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@escape-analysis-jsx-child.js.snap new file mode 100644 index 0000000000..5fdc40544e --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@escape-analysis-jsx-child.js.snap @@ -0,0 +1,420 @@ +--- +source: crates/forget_hermes_parser/tests/parser_test.rs +expression: "format!(\"Input:\\n{input}\\n\\nOutput:\\n{output}\")" +input_file: crates/forget_hermes_parser/tests/fixtures/escape-analysis-jsx-child.js +--- +Input: +function foo(a, b, c) { + const x = []; + if (a) { + const y = []; + if (b) { + y.push(c); + } + x.push(
{y}
); + } + return x; +} + + +Output: +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "foo", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [ + { + "type": "Identifier", + "name": "a", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "Identifier", + "name": "b", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "Identifier", + "name": "c", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "ArrayExpression", + "elements": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "IfStatement", + "test": { + "type": "Identifier", + "name": "a", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "consequent": { + "type": "BlockStatement", + "body": [ + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "y", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "ArrayExpression", + "elements": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "IfStatement", + "test": { + "type": "Identifier", + "name": "b", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "consequent": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "y", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "push", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [ + { + "type": "Identifier", + "name": "c", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "alternate": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "push", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [ + { + "type": "JSXElement", + "openingElement": { + "type": "JSXOpeningElement", + "name": { + "type": "JSXIdentifier", + "name": "div", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "attributes": [], + "selfClosing": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "children": [ + { + "type": "JSXExpressionContainer", + "expression": { + "type": "Identifier", + "name": "y", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "closingElement": { + "type": "JSXClosingElement", + "name": { + "type": "JSXIdentifier", + "name": "div", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "alternate": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ReturnStatement", + "argument": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "sourceType": "script", + "loc": null, + "range": { + "start": 0, + "end": 1 + } +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@escape-analysis-logical.js.snap b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@escape-analysis-logical.js.snap new file mode 100644 index 0000000000..f537404797 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@escape-analysis-logical.js.snap @@ -0,0 +1,335 @@ +--- +source: crates/forget_hermes_parser/tests/parser_test.rs +expression: "format!(\"Input:\\n{input}\\n\\nOutput:\\n{output}\")" +input_file: crates/forget_hermes_parser/tests/fixtures/escape-analysis-logical.js +--- +Input: +function Component(props) { + const a = [props.a]; + const b = [props.b]; + const c = [props.c]; + // We don't do constant folding for non-primitive values (yet) so we consider + // that any of a, b, or c could return here + return (a && b) || c; +} + + +Output: +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "Component", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [ + { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "a", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "ArrayExpression", + "elements": [ + { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "a", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "b", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "ArrayExpression", + "elements": [ + { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "b", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "c", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "ArrayExpression", + "elements": [ + { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "c", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ReturnStatement", + "argument": { + "type": "LogicalExpression", + "operator": "||", + "left": { + "type": "LogicalExpression", + "operator": "&&", + "left": { + "type": "Identifier", + "name": "a", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "right": { + "type": "Identifier", + "name": "b", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "right": { + "type": "Identifier", + "name": "c", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "sourceType": "script", + "loc": null, + "range": { + "start": 0, + "end": 1 + } +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@escape-analysis-non-escaping-interleaved-allocating-dependency.js.snap b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@escape-analysis-non-escaping-interleaved-allocating-dependency.js.snap new file mode 100644 index 0000000000..d599b2a2bc --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@escape-analysis-non-escaping-interleaved-allocating-dependency.js.snap @@ -0,0 +1,378 @@ +--- +source: crates/forget_hermes_parser/tests/parser_test.rs +expression: "format!(\"Input:\\n{input}\\n\\nOutput:\\n{output}\")" +input_file: crates/forget_hermes_parser/tests/fixtures/escape-analysis-non-escaping-interleaved-allocating-dependency.js +--- +Input: +function Component(props) { + // a can be independently memoized, is not mutated later + const a = [props.a]; + + // b and c are interleaved and grouped into a single scope, + // but they are independent values. c does not escape, but + // we need to ensure that a is memoized or else b will invalidate + // on every render since a is a dependency. + const b = []; + const c = {}; + c.a = a; + b.push(props.b); + + return b; +} + + +Output: +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "Component", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [ + { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "a", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "ArrayExpression", + "elements": [ + { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "a", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "b", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "ArrayExpression", + "elements": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "c", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "ObjectExpression", + "properties": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "c", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "a", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "right": { + "type": "Identifier", + "name": "a", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "b", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "push", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [ + { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "b", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ReturnStatement", + "argument": { + "type": "Identifier", + "name": "b", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "sourceType": "script", + "loc": null, + "range": { + "start": 0, + "end": 1 + } +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@escape-analysis-non-escaping-interleaved-allocating-nested-dependency.js.snap b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@escape-analysis-non-escaping-interleaved-allocating-nested-dependency.js.snap new file mode 100644 index 0000000000..5eef448099 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@escape-analysis-non-escaping-interleaved-allocating-nested-dependency.js.snap @@ -0,0 +1,436 @@ +--- +source: crates/forget_hermes_parser/tests/parser_test.rs +expression: "format!(\"Input:\\n{input}\\n\\nOutput:\\n{output}\")" +input_file: crates/forget_hermes_parser/tests/fixtures/escape-analysis-non-escaping-interleaved-allocating-nested-dependency.js +--- +Input: +function Component(props) { + // a can be independently memoized, is not mutated later + // but a is a dependnecy of b, which is a dependency of c. + // we have to memoize a to avoid breaking memoization of b, + // to avoid breaking memoization of c. + const a = [props.a]; + + // a can be independently memoized, is not mutated later, + // but is a dependency of d which is part of c's scope. + // we have to memoize b to avoid breaking memoization of c. + const b = [a]; + + // c and d are interleaved and grouped into a single scope, + // but they are independent values. d does not escape, but + // we need to ensure that b is memoized or else b will invalidate + // on every render since a is a dependency. we also need to + // ensure that a is memoized, since it's a dependency of b. + const c = []; + const d = {}; + d.b = b; + c.push(props.b); + + return c; +} + + +Output: +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "Component", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [ + { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "a", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "ArrayExpression", + "elements": [ + { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "a", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "b", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "ArrayExpression", + "elements": [ + { + "type": "Identifier", + "name": "a", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "c", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "ArrayExpression", + "elements": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "d", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "ObjectExpression", + "properties": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "d", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "b", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "right": { + "type": "Identifier", + "name": "b", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "c", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "push", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [ + { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "b", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ReturnStatement", + "argument": { + "type": "Identifier", + "name": "c", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "sourceType": "script", + "loc": null, + "range": { + "start": 0, + "end": 1 + } +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@escape-analysis-non-escaping-interleaved-primitive-dependency.js.snap b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@escape-analysis-non-escaping-interleaved-primitive-dependency.js.snap new file mode 100644 index 0000000000..ea7ba21b53 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@escape-analysis-non-escaping-interleaved-primitive-dependency.js.snap @@ -0,0 +1,408 @@ +--- +source: crates/forget_hermes_parser/tests/parser_test.rs +expression: "format!(\"Input:\\n{input}\\n\\nOutput:\\n{output}\")" +input_file: crates/forget_hermes_parser/tests/fixtures/escape-analysis-non-escaping-interleaved-primitive-dependency.js +--- +Input: +function Component(props) { + // a does not need to be memoized ever, even though it's a + // dependency of c, which exists in a scope that has a memoized + // output. it doesn't need to be memoized bc the value is a primitive type. + const a = props.a + props.b; + + // b and c are interleaved and grouped into a single scope, + // but they are independent values. c does not escape, but + // we need to ensure that a is memoized or else b will invalidate + // on every render since a is a dependency. + const b = []; + const c = {}; + c.a = a; + b.push(props.c); + + return b; +} + + +Output: +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "Component", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [ + { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "a", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "BinaryExpression", + "left": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "a", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "operator": "+", + "right": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "b", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "b", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "ArrayExpression", + "elements": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "c", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "ObjectExpression", + "properties": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "c", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "a", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "right": { + "type": "Identifier", + "name": "a", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "b", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "push", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [ + { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "c", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ReturnStatement", + "argument": { + "type": "Identifier", + "name": "b", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "sourceType": "script", + "loc": null, + "range": { + "start": 0, + "end": 1 + } +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@escape-analysis-not-conditional-test.js.snap b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@escape-analysis-not-conditional-test.js.snap new file mode 100644 index 0000000000..09a1ad7bc0 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@escape-analysis-not-conditional-test.js.snap @@ -0,0 +1,263 @@ +--- +source: crates/forget_hermes_parser/tests/parser_test.rs +expression: "format!(\"Input:\\n{input}\\n\\nOutput:\\n{output}\")" +input_file: crates/forget_hermes_parser/tests/fixtures/escape-analysis-not-conditional-test.js +--- +Input: +function Component(props) { + const x = [props.a]; + const y = x ? props.b : props.c; + return y; +} + + +Output: +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "Component", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [ + { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "ArrayExpression", + "elements": [ + { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "a", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "y", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "ConditionalExpression", + "test": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "alternate": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "c", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "consequent": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "b", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ReturnStatement", + "argument": { + "type": "Identifier", + "name": "y", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "sourceType": "script", + "loc": null, + "range": { + "start": 0, + "end": 1 + } +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@escape-analysis-not-if-test.js.snap b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@escape-analysis-not-if-test.js.snap new file mode 100644 index 0000000000..32a0233dba --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@escape-analysis-not-if-test.js.snap @@ -0,0 +1,345 @@ +--- +source: crates/forget_hermes_parser/tests/parser_test.rs +expression: "format!(\"Input:\\n{input}\\n\\nOutput:\\n{output}\")" +input_file: crates/forget_hermes_parser/tests/fixtures/escape-analysis-not-if-test.js +--- +Input: +function Component(props) { + const x = [props.a]; + let y; + if (x) { + y = props.b; + } else { + y = props.c; + } + return y; +} + + +Output: +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "Component", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [ + { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "ArrayExpression", + "elements": [ + { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "a", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "VariableDeclaration", + "kind": "let", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "y", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "IfStatement", + "test": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "consequent": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "Identifier", + "name": "y", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "right": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "b", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "alternate": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "Identifier", + "name": "y", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "right": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "c", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ReturnStatement", + "argument": { + "type": "Identifier", + "name": "y", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "sourceType": "script", + "loc": null, + "range": { + "start": 0, + "end": 1 + } +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@escape-analysis-not-switch-case.js.snap b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@escape-analysis-not-switch-case.js.snap new file mode 100644 index 0000000000..e7a316c9e5 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@escape-analysis-not-switch-case.js.snap @@ -0,0 +1,347 @@ +--- +source: crates/forget_hermes_parser/tests/parser_test.rs +expression: "format!(\"Input:\\n{input}\\n\\nOutput:\\n{output}\")" +input_file: crates/forget_hermes_parser/tests/fixtures/escape-analysis-not-switch-case.js +--- +Input: +function Component(props) { + const a = [props.a]; + let x = props.b; + switch (props.c) { + case a: { + x = props.d; + } + } + return x; +} + + +Output: +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "Component", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [ + { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "a", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "ArrayExpression", + "elements": [ + { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "a", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "VariableDeclaration", + "kind": "let", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "b", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "SwitchStatement", + "discriminant": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "c", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "cases": [ + { + "type": "SwitchCase", + "test": { + "type": "Identifier", + "name": "a", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "consequent": [ + { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "right": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "d", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ReturnStatement", + "argument": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "sourceType": "script", + "loc": null, + "range": { + "start": 0, + "end": 1 + } +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@escape-analysis-not-switch-test.js.snap b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@escape-analysis-not-switch-test.js.snap new file mode 100644 index 0000000000..d22f38f904 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@escape-analysis-not-switch-test.js.snap @@ -0,0 +1,327 @@ +--- +source: crates/forget_hermes_parser/tests/parser_test.rs +expression: "format!(\"Input:\\n{input}\\n\\nOutput:\\n{output}\")" +input_file: crates/forget_hermes_parser/tests/fixtures/escape-analysis-not-switch-test.js +--- +Input: +function Component(props) { + const a = [props.a]; + let x = props.b; + switch (a) { + case true: { + x = props.c; + } + } + return x; +} + + +Output: +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "Component", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [ + { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "a", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "ArrayExpression", + "elements": [ + { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "a", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "VariableDeclaration", + "kind": "let", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "b", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "SwitchStatement", + "discriminant": { + "type": "Identifier", + "name": "a", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "cases": [ + { + "type": "SwitchCase", + "test": { + "type": "BooleanLiteral", + "value": true, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "consequent": [ + { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "right": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "c", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ReturnStatement", + "argument": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "sourceType": "script", + "loc": null, + "range": { + "start": 0, + "end": 1 + } +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@expression-with-assignment-dynamic.js.snap b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@expression-with-assignment-dynamic.js.snap new file mode 100644 index 0000000000..7fb096e3dd --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@expression-with-assignment-dynamic.js.snap @@ -0,0 +1,184 @@ +--- +source: crates/forget_hermes_parser/tests/parser_test.rs +expression: "format!(\"Input:\\n{input}\\n\\nOutput:\\n{output}\")" +input_file: crates/forget_hermes_parser/tests/fixtures/expression-with-assignment-dynamic.js +--- +Input: +function f(y) { + let x = y; + return x + (x = 2) + x; +} + + +Output: +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "f", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [ + { + "type": "Identifier", + "name": "y", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "VariableDeclaration", + "kind": "let", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "Identifier", + "name": "y", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ReturnStatement", + "argument": { + "type": "BinaryExpression", + "left": { + "type": "BinaryExpression", + "left": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "operator": "+", + "right": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "right": { + "type": "NumericLiteral", + "value": 4611686018427387904, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "operator": "+", + "right": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "sourceType": "script", + "loc": null, + "range": { + "start": 0, + "end": 1 + } +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@expression-with-assignment.js.snap b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@expression-with-assignment.js.snap new file mode 100644 index 0000000000..cfebb3fc27 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@expression-with-assignment.js.snap @@ -0,0 +1,172 @@ +--- +source: crates/forget_hermes_parser/tests/parser_test.rs +expression: "format!(\"Input:\\n{input}\\n\\nOutput:\\n{output}\")" +input_file: crates/forget_hermes_parser/tests/fixtures/expression-with-assignment.js +--- +Input: +function f() { + let x = 1; + return x + (x = 2) + x; +} + + +Output: +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "f", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "VariableDeclaration", + "kind": "let", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "NumericLiteral", + "value": 4607182418800017408, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ReturnStatement", + "argument": { + "type": "BinaryExpression", + "left": { + "type": "BinaryExpression", + "left": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "operator": "+", + "right": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "right": { + "type": "NumericLiteral", + "value": 4611686018427387904, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "operator": "+", + "right": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "sourceType": "script", + "loc": null, + "range": { + "start": 0, + "end": 1 + } +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@extend-scopes-if.js.snap b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@extend-scopes-if.js.snap new file mode 100644 index 0000000000..58f357f054 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@extend-scopes-if.js.snap @@ -0,0 +1,365 @@ +--- +source: crates/forget_hermes_parser/tests/parser_test.rs +expression: "format!(\"Input:\\n{input}\\n\\nOutput:\\n{output}\")" +input_file: crates/forget_hermes_parser/tests/fixtures/extend-scopes-if.js +--- +Input: +function foo(a, b, c) { + let x = []; + if (a) { + if (b) { + if (c) { + x.push(0); + } + } + } + if (x.length) { + return x; + } + return null; +} + + +Output: +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "foo", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [ + { + "type": "Identifier", + "name": "a", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "Identifier", + "name": "b", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "Identifier", + "name": "c", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "VariableDeclaration", + "kind": "let", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "ArrayExpression", + "elements": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "IfStatement", + "test": { + "type": "Identifier", + "name": "a", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "consequent": { + "type": "BlockStatement", + "body": [ + { + "type": "IfStatement", + "test": { + "type": "Identifier", + "name": "b", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "consequent": { + "type": "BlockStatement", + "body": [ + { + "type": "IfStatement", + "test": { + "type": "Identifier", + "name": "c", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "consequent": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "push", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [ + { + "type": "NumericLiteral", + "value": 0, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "alternate": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "alternate": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "alternate": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "IfStatement", + "test": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "length", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "consequent": { + "type": "BlockStatement", + "body": [ + { + "type": "ReturnStatement", + "argument": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "alternate": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ReturnStatement", + "argument": { + "type": "NullLiteral", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "sourceType": "script", + "loc": null, + "range": { + "start": 0, + "end": 1 + } +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@fbt-call-complex-param-value.js.snap b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@fbt-call-complex-param-value.js.snap new file mode 100644 index 0000000000..e39e97af53 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@fbt-call-complex-param-value.js.snap @@ -0,0 +1,378 @@ +--- +source: crates/forget_hermes_parser/tests/parser_test.rs +expression: "format!(\"Input:\\n{input}\\n\\nOutput:\\n{output}\")" +input_file: crates/forget_hermes_parser/tests/fixtures/fbt-call-complex-param-value.js +--- +Input: +import fbt from "fbt"; + +function Component(props) { + const text = fbt( + `Hello, ${fbt.param("(key) name", capitalize(props.name))}!`, + "(description) Greeting" + ); + return
{text}
; +} + + +Output: +{ + "type": "Program", + "body": [ + { + "type": "ImportDeclaration", + "specifiers": [ + { + "type": "ImportDefaultSpecifier", + "local": { + "type": "Identifier", + "name": "fbt", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "source": { + "type": "StringLiteral", + "value": "fbt", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "Component", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [ + { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "text", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "fbt", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [ + { + "type": "TemplateLiteral", + "quasis": [ + { + "type": "TemplateElement", + "tail": false, + "value": { + "cooked": "Hello, ", + "raw": "Hello, " + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "TemplateElement", + "tail": true, + "value": { + "cooked": "!", + "raw": "!" + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "expressions": [ + { + "type": "CallExpression", + "callee": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "fbt", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "param", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [ + { + "type": "StringLiteral", + "value": "(key) name", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "capitalize", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [ + { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "name", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "StringLiteral", + "value": "(description) Greeting", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ReturnStatement", + "argument": { + "type": "JSXElement", + "openingElement": { + "type": "JSXOpeningElement", + "name": { + "type": "JSXIdentifier", + "name": "div", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "attributes": [], + "selfClosing": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "children": [ + { + "type": "JSXExpressionContainer", + "expression": { + "type": "Identifier", + "name": "text", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "closingElement": { + "type": "JSXClosingElement", + "name": { + "type": "JSXIdentifier", + "name": "div", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "sourceType": "script", + "loc": null, + "range": { + "start": 0, + "end": 1 + } +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@fbt-call.js.snap b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@fbt-call.js.snap new file mode 100644 index 0000000000..2f82ce09d1 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@fbt-call.js.snap @@ -0,0 +1,358 @@ +--- +source: crates/forget_hermes_parser/tests/parser_test.rs +expression: "format!(\"Input:\\n{input}\\n\\nOutput:\\n{output}\")" +input_file: crates/forget_hermes_parser/tests/fixtures/fbt-call.js +--- +Input: +import fbt from "fbt"; + +function Component(props) { + const text = fbt( + `${fbt.param("(key) count", props.count)} items`, + "(description) Number of items" + ); + return
{text}
; +} + + +Output: +{ + "type": "Program", + "body": [ + { + "type": "ImportDeclaration", + "specifiers": [ + { + "type": "ImportDefaultSpecifier", + "local": { + "type": "Identifier", + "name": "fbt", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "source": { + "type": "StringLiteral", + "value": "fbt", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "Component", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [ + { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "text", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "fbt", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [ + { + "type": "TemplateLiteral", + "quasis": [ + { + "type": "TemplateElement", + "tail": false, + "value": { + "cooked": "", + "raw": "" + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "TemplateElement", + "tail": true, + "value": { + "cooked": " items", + "raw": " items" + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "expressions": [ + { + "type": "CallExpression", + "callee": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "fbt", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "param", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [ + { + "type": "StringLiteral", + "value": "(key) count", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "count", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "StringLiteral", + "value": "(description) Number of items", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ReturnStatement", + "argument": { + "type": "JSXElement", + "openingElement": { + "type": "JSXOpeningElement", + "name": { + "type": "JSXIdentifier", + "name": "div", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "attributes": [], + "selfClosing": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "children": [ + { + "type": "JSXExpressionContainer", + "expression": { + "type": "Identifier", + "name": "text", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "closingElement": { + "type": "JSXClosingElement", + "name": { + "type": "JSXIdentifier", + "name": "div", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "sourceType": "script", + "loc": null, + "range": { + "start": 0, + "end": 1 + } +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@fbt-params-complex-param-value.js.snap b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@fbt-params-complex-param-value.js.snap new file mode 100644 index 0000000000..26a15950b1 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@fbt-params-complex-param-value.js.snap @@ -0,0 +1,387 @@ +--- +source: crates/forget_hermes_parser/tests/parser_test.rs +expression: "format!(\"Input:\\n{input}\\n\\nOutput:\\n{output}\")" +input_file: crates/forget_hermes_parser/tests/fixtures/fbt-params-complex-param-value.js +--- +Input: +import fbt from "fbt"; + +function Component(props) { + return ( + + Hello {capitalize(props.name)} + + ); +} + + +Output: +{ + "type": "Program", + "body": [ + { + "type": "ImportDeclaration", + "specifiers": [ + { + "type": "ImportDefaultSpecifier", + "local": { + "type": "Identifier", + "name": "fbt", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "source": { + "type": "StringLiteral", + "value": "fbt", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "Component", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [ + { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ReturnStatement", + "argument": { + "type": "JSXElement", + "openingElement": { + "type": "JSXOpeningElement", + "name": { + "type": "JSXIdentifier", + "name": "fbt", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "attributes": [ + { + "type": "JSXAttribute", + "name": { + "type": "JSXIdentifier", + "name": "desc", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "value": { + "type": "JSXExpressionContainer", + "expression": { + "type": "StringLiteral", + "value": "Dialog to show to user", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "selfClosing": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "children": [ + { + "type": "JSXText", + "value": "\n Hello ", + "raw": "\n Hello ", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "JSXElement", + "openingElement": { + "type": "JSXOpeningElement", + "name": { + "type": "JSXNamespacedName", + "namespace": { + "type": "JSXIdentifier", + "name": "fbt", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "name": { + "type": "JSXIdentifier", + "name": "param", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "attributes": [ + { + "type": "JSXAttribute", + "name": { + "type": "JSXIdentifier", + "name": "name", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "value": { + "type": "JSXStringLiteral", + "value": "user name", + "raw": "\"user name\"", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "selfClosing": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "children": [ + { + "type": "JSXExpressionContainer", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "capitalize", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [ + { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "name", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "closingElement": { + "type": "JSXClosingElement", + "name": { + "type": "JSXNamespacedName", + "namespace": { + "type": "JSXIdentifier", + "name": "fbt", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "name": { + "type": "JSXIdentifier", + "name": "param", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "JSXText", + "value": "\n ", + "raw": "\n ", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "closingElement": { + "type": "JSXClosingElement", + "name": { + "type": "JSXIdentifier", + "name": "fbt", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "sourceType": "script", + "loc": null, + "range": { + "start": 0, + "end": 1 + } +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@fbt-params.js.snap b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@fbt-params.js.snap new file mode 100644 index 0000000000..9f1224723e --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@fbt-params.js.snap @@ -0,0 +1,367 @@ +--- +source: crates/forget_hermes_parser/tests/parser_test.rs +expression: "format!(\"Input:\\n{input}\\n\\nOutput:\\n{output}\")" +input_file: crates/forget_hermes_parser/tests/fixtures/fbt-params.js +--- +Input: +import fbt from "fbt"; + +function Component(props) { + return ( + + Hello {props.name} + + ); +} + + +Output: +{ + "type": "Program", + "body": [ + { + "type": "ImportDeclaration", + "specifiers": [ + { + "type": "ImportDefaultSpecifier", + "local": { + "type": "Identifier", + "name": "fbt", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "source": { + "type": "StringLiteral", + "value": "fbt", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "Component", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [ + { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ReturnStatement", + "argument": { + "type": "JSXElement", + "openingElement": { + "type": "JSXOpeningElement", + "name": { + "type": "JSXIdentifier", + "name": "fbt", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "attributes": [ + { + "type": "JSXAttribute", + "name": { + "type": "JSXIdentifier", + "name": "desc", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "value": { + "type": "JSXExpressionContainer", + "expression": { + "type": "StringLiteral", + "value": "Dialog to show to user", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "selfClosing": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "children": [ + { + "type": "JSXText", + "value": "\n Hello ", + "raw": "\n Hello ", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "JSXElement", + "openingElement": { + "type": "JSXOpeningElement", + "name": { + "type": "JSXNamespacedName", + "namespace": { + "type": "JSXIdentifier", + "name": "fbt", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "name": { + "type": "JSXIdentifier", + "name": "param", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "attributes": [ + { + "type": "JSXAttribute", + "name": { + "type": "JSXIdentifier", + "name": "name", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "value": { + "type": "JSXStringLiteral", + "value": "user name", + "raw": "\"user name\"", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "selfClosing": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "children": [ + { + "type": "JSXExpressionContainer", + "expression": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "name", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "closingElement": { + "type": "JSXClosingElement", + "name": { + "type": "JSXNamespacedName", + "namespace": { + "type": "JSXIdentifier", + "name": "fbt", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "name": { + "type": "JSXIdentifier", + "name": "param", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "JSXText", + "value": "\n ", + "raw": "\n ", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "closingElement": { + "type": "JSXClosingElement", + "name": { + "type": "JSXIdentifier", + "name": "fbt", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "sourceType": "script", + "loc": null, + "range": { + "start": 0, + "end": 1 + } +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@fbt-template-string-same-scope.js.snap b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@fbt-template-string-same-scope.js.snap new file mode 100644 index 0000000000..8cdd71bd8f --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@fbt-template-string-same-scope.js.snap @@ -0,0 +1,556 @@ +--- +source: crates/forget_hermes_parser/tests/parser_test.rs +expression: "format!(\"Input:\\n{input}\\n\\nOutput:\\n{output}\")" +input_file: crates/forget_hermes_parser/tests/fixtures/fbt-template-string-same-scope.js +--- +Input: +import fbt from "fbt"; + +export function Component(props) { + let count = 0; + if (props.items) { + count = props.items.length; + } + return ( + + {fbt( + `for ${fbt.param("count", count)} experiences`, + `Label for the number of items`, + { project: "public" } + )} + + ); +} + + +Output: +{ + "type": "Program", + "body": [ + { + "type": "ImportDeclaration", + "specifiers": [ + { + "type": "ImportDefaultSpecifier", + "local": { + "type": "Identifier", + "name": "fbt", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "source": { + "type": "StringLiteral", + "value": "fbt", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ExportNamedDeclaration", + "declaration": { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "Component", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [ + { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "VariableDeclaration", + "kind": "let", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "count", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "NumericLiteral", + "value": 0, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "IfStatement", + "test": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "items", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "consequent": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "Identifier", + "name": "count", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "right": { + "type": "MemberExpression", + "object": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "items", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "length", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "alternate": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ReturnStatement", + "argument": { + "type": "JSXElement", + "openingElement": { + "type": "JSXOpeningElement", + "name": { + "type": "JSXIdentifier", + "name": "View", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "attributes": [], + "selfClosing": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "children": [ + { + "type": "JSXText", + "value": "\n ", + "raw": "\n ", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "JSXExpressionContainer", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "fbt", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [ + { + "type": "TemplateLiteral", + "quasis": [ + { + "type": "TemplateElement", + "tail": false, + "value": { + "cooked": "for ", + "raw": "for " + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "TemplateElement", + "tail": true, + "value": { + "cooked": " experiences", + "raw": " experiences" + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "expressions": [ + { + "type": "CallExpression", + "callee": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "fbt", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "param", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [ + { + "type": "StringLiteral", + "value": "count", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "Identifier", + "name": "count", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "TemplateLiteral", + "quasis": [ + { + "type": "TemplateElement", + "tail": true, + "value": { + "cooked": "Label for the number of items", + "raw": "Label for the number of items" + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "expressions": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ObjectExpression", + "properties": [ + { + "type": "Property", + "key": { + "type": "Identifier", + "name": "project", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "value": { + "type": "StringLiteral", + "value": "public", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "kind": "init", + "method": false, + "shorthand": false, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "JSXText", + "value": "\n ", + "raw": "\n ", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "closingElement": { + "type": "JSXClosingElement", + "name": { + "type": "JSXIdentifier", + "name": "View", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "specifiers": [], + "source": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "sourceType": "script", + "loc": null, + "range": { + "start": 0, + "end": 1 + } +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@for-empty-update-with-continue.js.snap b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@for-empty-update-with-continue.js.snap new file mode 100644 index 0000000000..80a60ed1d6 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@for-empty-update-with-continue.js.snap @@ -0,0 +1,321 @@ +--- +source: crates/forget_hermes_parser/tests/parser_test.rs +expression: "format!(\"Input:\\n{input}\\n\\nOutput:\\n{output}\")" +input_file: crates/forget_hermes_parser/tests/fixtures/for-empty-update-with-continue.js +--- +Input: +function Component(props) { + let x = 0; + for (let i = 0; i < props.count; ) { + x += i; + i += 1; + continue; + } + return x; +} + + +Output: +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "Component", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [ + { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "VariableDeclaration", + "kind": "let", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "NumericLiteral", + "value": 0, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ForStatement", + "init": { + "type": "VariableDeclaration", + "kind": "let", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "i", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "NumericLiteral", + "value": 0, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "test": { + "type": "BinaryExpression", + "left": { + "type": "Identifier", + "name": "i", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "operator": "<", + "right": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "count", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "update": null, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "+=", + "left": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "right": { + "type": "Identifier", + "name": "i", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "+=", + "left": { + "type": "Identifier", + "name": "i", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "right": { + "type": "NumericLiteral", + "value": 4607182418800017408, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ContinueStatement", + "label": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ReturnStatement", + "argument": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "sourceType": "script", + "loc": null, + "range": { + "start": 0, + "end": 1 + } +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@for-empty-update.js.snap b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@for-empty-update.js.snap new file mode 100644 index 0000000000..d91c39f2f1 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@for-empty-update.js.snap @@ -0,0 +1,332 @@ +--- +source: crates/forget_hermes_parser/tests/parser_test.rs +expression: "format!(\"Input:\\n{input}\\n\\nOutput:\\n{output}\")" +input_file: crates/forget_hermes_parser/tests/fixtures/for-empty-update.js +--- +Input: +function Component(props) { + let x = 0; + for (let i = 0; i < props.count; ) { + x += i; + if (x > 10) { + break; + } + } + return x; +} + + +Output: +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "Component", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [ + { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "VariableDeclaration", + "kind": "let", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "NumericLiteral", + "value": 0, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ForStatement", + "init": { + "type": "VariableDeclaration", + "kind": "let", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "i", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "NumericLiteral", + "value": 0, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "test": { + "type": "BinaryExpression", + "left": { + "type": "Identifier", + "name": "i", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "operator": "<", + "right": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "count", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "update": null, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "+=", + "left": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "right": { + "type": "Identifier", + "name": "i", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "IfStatement", + "test": { + "type": "BinaryExpression", + "left": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "operator": ">", + "right": { + "type": "NumericLiteral", + "value": 4621819117588971520, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "consequent": { + "type": "BlockStatement", + "body": [ + { + "type": "BreakStatement", + "label": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "alternate": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ReturnStatement", + "argument": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "sourceType": "script", + "loc": null, + "range": { + "start": 0, + "end": 1 + } +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@for-logical.js.snap b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@for-logical.js.snap new file mode 100644 index 0000000000..15b5f0d164 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@for-logical.js.snap @@ -0,0 +1,465 @@ +--- +source: crates/forget_hermes_parser/tests/parser_test.rs +expression: "format!(\"Input:\\n{input}\\n\\nOutput:\\n{output}\")" +input_file: crates/forget_hermes_parser/tests/fixtures/for-logical.js +--- +Input: +function foo(props) { + let y = 0; + for ( + let x = 0; + x > props.min && x < props.max; + x += props.cond ? props.increment : 2 + ) { + x *= 2; + y += x; + } + return y; +} + + +Output: +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "foo", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [ + { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "VariableDeclaration", + "kind": "let", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "y", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "NumericLiteral", + "value": 0, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ForStatement", + "init": { + "type": "VariableDeclaration", + "kind": "let", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "NumericLiteral", + "value": 0, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "test": { + "type": "LogicalExpression", + "operator": "&&", + "left": { + "type": "BinaryExpression", + "left": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "operator": ">", + "right": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "min", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "right": { + "type": "BinaryExpression", + "left": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "operator": "<", + "right": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "max", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "update": { + "type": "AssignmentExpression", + "operator": "+=", + "left": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "right": { + "type": "ConditionalExpression", + "test": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "cond", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "alternate": { + "type": "NumericLiteral", + "value": 4611686018427387904, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "consequent": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "increment", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "*=", + "left": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "right": { + "type": "NumericLiteral", + "value": 4611686018427387904, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "+=", + "left": { + "type": "Identifier", + "name": "y", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "right": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ReturnStatement", + "argument": { + "type": "Identifier", + "name": "y", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "sourceType": "script", + "loc": null, + "range": { + "start": 0, + "end": 1 + } +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@for-of-break.js.snap b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@for-of-break.js.snap new file mode 100644 index 0000000000..8667dc1180 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@for-of-break.js.snap @@ -0,0 +1,205 @@ +--- +source: crates/forget_hermes_parser/tests/parser_test.rs +expression: "format!(\"Input:\\n{input}\\n\\nOutput:\\n{output}\")" +input_file: crates/forget_hermes_parser/tests/fixtures/for-of-break.js +--- +Input: +function Component() { + const x = []; + for (const item of [1, 2]) { + break; + } + return x; +} + + +Output: +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "Component", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "ArrayExpression", + "elements": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ForOfStatement", + "await": false, + "left": { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "item", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "right": { + "type": "ArrayExpression", + "elements": [ + { + "type": "NumericLiteral", + "value": 4607182418800017408, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "NumericLiteral", + "value": 4611686018427387904, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "BreakStatement", + "label": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ReturnStatement", + "argument": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "sourceType": "script", + "loc": null, + "range": { + "start": 0, + "end": 1 + } +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@for-of-conditional-break.js.snap b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@for-of-conditional-break.js.snap new file mode 100644 index 0000000000..f71fc877d9 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@for-of-conditional-break.js.snap @@ -0,0 +1,313 @@ +--- +source: crates/forget_hermes_parser/tests/parser_test.rs +expression: "format!(\"Input:\\n{input}\\n\\nOutput:\\n{output}\")" +input_file: crates/forget_hermes_parser/tests/fixtures/for-of-conditional-break.js +--- +Input: +function Component() { + const x = []; + for (const item of [1, 2]) { + if (item === 1) { + break; + } + x.push(item); + } + return x; +} + + +Output: +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "Component", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "ArrayExpression", + "elements": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ForOfStatement", + "await": false, + "left": { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "item", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "right": { + "type": "ArrayExpression", + "elements": [ + { + "type": "NumericLiteral", + "value": 4607182418800017408, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "NumericLiteral", + "value": 4611686018427387904, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "IfStatement", + "test": { + "type": "BinaryExpression", + "left": { + "type": "Identifier", + "name": "item", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "operator": "===", + "right": { + "type": "NumericLiteral", + "value": 4607182418800017408, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "consequent": { + "type": "BlockStatement", + "body": [ + { + "type": "BreakStatement", + "label": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "alternate": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "push", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [ + { + "type": "Identifier", + "name": "item", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ReturnStatement", + "argument": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "sourceType": "script", + "loc": null, + "range": { + "start": 0, + "end": 1 + } +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@for-of-continue.js.snap b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@for-of-continue.js.snap new file mode 100644 index 0000000000..90d35eb0ed --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@for-of-continue.js.snap @@ -0,0 +1,389 @@ +--- +source: crates/forget_hermes_parser/tests/parser_test.rs +expression: "format!(\"Input:\\n{input}\\n\\nOutput:\\n{output}\")" +input_file: crates/forget_hermes_parser/tests/fixtures/for-of-continue.js +--- +Input: +function Component() { + const x = [0, 1, 2, 3]; + const ret = []; + for (const item of x) { + if (item === 0) { + continue; + } + ret.push(item / 2); + } + return ret; +} + + +Output: +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "Component", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "ArrayExpression", + "elements": [ + { + "type": "NumericLiteral", + "value": 0, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "NumericLiteral", + "value": 4607182418800017408, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "NumericLiteral", + "value": 4611686018427387904, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "NumericLiteral", + "value": 4613937818241073152, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "ret", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "ArrayExpression", + "elements": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ForOfStatement", + "await": false, + "left": { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "item", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "right": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "IfStatement", + "test": { + "type": "BinaryExpression", + "left": { + "type": "Identifier", + "name": "item", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "operator": "===", + "right": { + "type": "NumericLiteral", + "value": 0, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "consequent": { + "type": "BlockStatement", + "body": [ + { + "type": "ContinueStatement", + "label": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "alternate": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "ret", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "push", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [ + { + "type": "BinaryExpression", + "left": { + "type": "Identifier", + "name": "item", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "operator": "/", + "right": { + "type": "NumericLiteral", + "value": 4611686018427387904, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ReturnStatement", + "argument": { + "type": "Identifier", + "name": "ret", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "sourceType": "script", + "loc": null, + "range": { + "start": 0, + "end": 1 + } +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@for-of-destructure.js.snap b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@for-of-destructure.js.snap new file mode 100644 index 0000000000..a99dcd502c --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@for-of-destructure.js.snap @@ -0,0 +1,447 @@ +--- +source: crates/forget_hermes_parser/tests/parser_test.rs +expression: "format!(\"Input:\\n{input}\\n\\nOutput:\\n{output}\")" +input_file: crates/forget_hermes_parser/tests/fixtures/for-of-destructure.js +--- +Input: +function Component() { + let x = []; + let items = [{ v: 0 }, { v: 1 }, { v: 2 }]; + for (const { v } of items) { + x.push(v * 2); + } + return x; +} + + +Output: +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "Component", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "VariableDeclaration", + "kind": "let", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "ArrayExpression", + "elements": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "VariableDeclaration", + "kind": "let", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "items", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "ArrayExpression", + "elements": [ + { + "type": "ObjectExpression", + "properties": [ + { + "type": "Property", + "key": { + "type": "Identifier", + "name": "v", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "value": { + "type": "NumericLiteral", + "value": 0, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "kind": "init", + "method": false, + "shorthand": false, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ObjectExpression", + "properties": [ + { + "type": "Property", + "key": { + "type": "Identifier", + "name": "v", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "value": { + "type": "NumericLiteral", + "value": 4607182418800017408, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "kind": "init", + "method": false, + "shorthand": false, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ObjectExpression", + "properties": [ + { + "type": "Property", + "key": { + "type": "Identifier", + "name": "v", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "value": { + "type": "NumericLiteral", + "value": 4611686018427387904, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "kind": "init", + "method": false, + "shorthand": false, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ForOfStatement", + "await": false, + "left": { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "ObjectPattern", + "properties": [ + { + "type": "Property", + "key": { + "type": "Identifier", + "name": "v", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "value": { + "type": "Identifier", + "name": "v", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "kind": "init", + "method": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "right": { + "type": "Identifier", + "name": "items", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "push", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [ + { + "type": "BinaryExpression", + "left": { + "type": "Identifier", + "name": "v", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "operator": "*", + "right": { + "type": "NumericLiteral", + "value": 4611686018427387904, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ReturnStatement", + "argument": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "sourceType": "script", + "loc": null, + "range": { + "start": 0, + "end": 1 + } +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@for-of-mutate.js.snap b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@for-of-mutate.js.snap new file mode 100644 index 0000000000..b35bf8d9d2 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@for-of-mutate.js.snap @@ -0,0 +1,434 @@ +--- +source: crates/forget_hermes_parser/tests/parser_test.rs +expression: "format!(\"Input:\\n{input}\\n\\nOutput:\\n{output}\")" +input_file: crates/forget_hermes_parser/tests/fixtures/for-of-mutate.js +--- +Input: +function Component(props) { + const collection = [makeObject()]; + const results = []; + for (const item of collection) { + results.push(
{mutate(item)}
); + } + return
{results}
; +} + + +Output: +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "Component", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [ + { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "collection", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "ArrayExpression", + "elements": [ + { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "makeObject", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "results", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "ArrayExpression", + "elements": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ForOfStatement", + "await": false, + "left": { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "item", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "right": { + "type": "Identifier", + "name": "collection", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "results", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "push", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [ + { + "type": "JSXElement", + "openingElement": { + "type": "JSXOpeningElement", + "name": { + "type": "JSXIdentifier", + "name": "div", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "attributes": [], + "selfClosing": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "children": [ + { + "type": "JSXExpressionContainer", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "mutate", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [ + { + "type": "Identifier", + "name": "item", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "closingElement": { + "type": "JSXClosingElement", + "name": { + "type": "JSXIdentifier", + "name": "div", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ReturnStatement", + "argument": { + "type": "JSXElement", + "openingElement": { + "type": "JSXOpeningElement", + "name": { + "type": "JSXIdentifier", + "name": "div", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "attributes": [], + "selfClosing": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "children": [ + { + "type": "JSXExpressionContainer", + "expression": { + "type": "Identifier", + "name": "results", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "closingElement": { + "type": "JSXClosingElement", + "name": { + "type": "JSXIdentifier", + "name": "div", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "sourceType": "script", + "loc": null, + "range": { + "start": 0, + "end": 1 + } +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@for-of-simple.js.snap b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@for-of-simple.js.snap new file mode 100644 index 0000000000..a53aafec4c --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@for-of-simple.js.snap @@ -0,0 +1,321 @@ +--- +source: crates/forget_hermes_parser/tests/parser_test.rs +expression: "format!(\"Input:\\n{input}\\n\\nOutput:\\n{output}\")" +input_file: crates/forget_hermes_parser/tests/fixtures/for-of-simple.js +--- +Input: +function Component() { + let x = []; + let items = [0, 1, 2]; + for (const ii of items) { + x.push(ii * 2); + } + return x; +} + + +Output: +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "Component", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "VariableDeclaration", + "kind": "let", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "ArrayExpression", + "elements": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "VariableDeclaration", + "kind": "let", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "items", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "ArrayExpression", + "elements": [ + { + "type": "NumericLiteral", + "value": 0, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "NumericLiteral", + "value": 4607182418800017408, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "NumericLiteral", + "value": 4611686018427387904, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ForOfStatement", + "await": false, + "left": { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "ii", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "right": { + "type": "Identifier", + "name": "items", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "push", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [ + { + "type": "BinaryExpression", + "left": { + "type": "Identifier", + "name": "ii", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "operator": "*", + "right": { + "type": "NumericLiteral", + "value": 4611686018427387904, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ReturnStatement", + "argument": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "sourceType": "script", + "loc": null, + "range": { + "start": 0, + "end": 1 + } +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@for-return.js.snap b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@for-return.js.snap new file mode 100644 index 0000000000..e8a431d2fe --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@for-return.js.snap @@ -0,0 +1,205 @@ +--- +source: crates/forget_hermes_parser/tests/parser_test.rs +expression: "format!(\"Input:\\n{input}\\n\\nOutput:\\n{output}\")" +input_file: crates/forget_hermes_parser/tests/fixtures/for-return.js +--- +Input: +function Component(props) { + for (let i = 0; i < props.count; i++) { + return; + } +} + + +Output: +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "Component", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [ + { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ForStatement", + "init": { + "type": "VariableDeclaration", + "kind": "let", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "i", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "NumericLiteral", + "value": 0, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "test": { + "type": "BinaryExpression", + "left": { + "type": "Identifier", + "name": "i", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "operator": "<", + "right": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "count", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "update": { + "type": "UpdateExpression", + "operator": "++", + "argument": { + "type": "Identifier", + "name": "i", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "prefix": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ReturnStatement", + "argument": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "sourceType": "script", + "loc": null, + "range": { + "start": 0, + "end": 1 + } +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@frozen-after-alias.js.snap b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@frozen-after-alias.js.snap new file mode 100644 index 0000000000..e7bc92174a --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@frozen-after-alias.js.snap @@ -0,0 +1,320 @@ +--- +source: crates/forget_hermes_parser/tests/parser_test.rs +expression: "format!(\"Input:\\n{input}\\n\\nOutput:\\n{output}\")" +input_file: crates/forget_hermes_parser/tests/fixtures/frozen-after-alias.js +--- +Input: +function Component() { + const a = []; + const b = a; + useFreeze(a); + foo(b); // should be readonly, value is guaranteed frozen via alias + return b; +} + +function useFreeze() {} +function foo(x) {} + + +Output: +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "Component", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "a", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "ArrayExpression", + "elements": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "b", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "Identifier", + "name": "a", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "useFreeze", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [ + { + "type": "Identifier", + "name": "a", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "foo", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [ + { + "type": "Identifier", + "name": "b", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ReturnStatement", + "argument": { + "type": "Identifier", + "name": "b", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "useFreeze", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [], + "body": { + "type": "BlockStatement", + "body": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "foo", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [ + { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "sourceType": "script", + "loc": null, + "range": { + "start": 0, + "end": 1 + } +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@function-declaration-reassign.js.snap b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@function-declaration-reassign.js.snap new file mode 100644 index 0000000000..46a6fc9c6a --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@function-declaration-reassign.js.snap @@ -0,0 +1,212 @@ +--- +source: crates/forget_hermes_parser/tests/parser_test.rs +expression: "format!(\"Input:\\n{input}\\n\\nOutput:\\n{output}\")" +input_file: crates/forget_hermes_parser/tests/fixtures/function-declaration-reassign.js +--- +Input: +function component() { + function x(a) { + a.foo(); + } + x = {}; + return x; +} + + +Output: +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "component", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [ + { + "type": "Identifier", + "name": "a", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "a", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "foo", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "right": { + "type": "ObjectExpression", + "properties": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ReturnStatement", + "argument": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "sourceType": "script", + "loc": null, + "range": { + "start": 0, + "end": 1 + } +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@function-declaration-redeclare.js.snap b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@function-declaration-redeclare.js.snap new file mode 100644 index 0000000000..18a56089b3 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@function-declaration-redeclare.js.snap @@ -0,0 +1,210 @@ +--- +source: crates/forget_hermes_parser/tests/parser_test.rs +expression: "format!(\"Input:\\n{input}\\n\\nOutput:\\n{output}\")" +input_file: crates/forget_hermes_parser/tests/fixtures/function-declaration-redeclare.js +--- +Input: +function component() { + function x(a) { + a.foo(); + } + function x() {} + return x; +} + + +Output: +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "component", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [ + { + "type": "Identifier", + "name": "a", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "a", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "foo", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [], + "body": { + "type": "BlockStatement", + "body": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ReturnStatement", + "argument": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "sourceType": "script", + "loc": null, + "range": { + "start": 0, + "end": 1 + } +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@function-declaration-simple.js.snap b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@function-declaration-simple.js.snap new file mode 100644 index 0000000000..85c9d600eb --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@function-declaration-simple.js.snap @@ -0,0 +1,297 @@ +--- +source: crates/forget_hermes_parser/tests/parser_test.rs +expression: "format!(\"Input:\\n{input}\\n\\nOutput:\\n{output}\")" +input_file: crates/forget_hermes_parser/tests/fixtures/function-declaration-simple.js +--- +Input: +function component(a) { + let t = { a }; + function x(p) { + p.foo(); + } + x(t); + return t; +} + + +Output: +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "component", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [ + { + "type": "Identifier", + "name": "a", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "VariableDeclaration", + "kind": "let", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "t", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "ObjectExpression", + "properties": [ + { + "type": "Property", + "key": { + "type": "Identifier", + "name": "a", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "value": { + "type": "Identifier", + "name": "a", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "kind": "init", + "method": false, + "shorthand": true, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [ + { + "type": "Identifier", + "name": "p", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "p", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "foo", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [ + { + "type": "Identifier", + "name": "t", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ReturnStatement", + "argument": { + "type": "Identifier", + "name": "t", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "sourceType": "script", + "loc": null, + "range": { + "start": 0, + "end": 1 + } +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@function-expression-captures-value-later-frozen-jsx.js.snap b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@function-expression-captures-value-later-frozen-jsx.js.snap new file mode 100644 index 0000000000..b6694388ca --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@function-expression-captures-value-later-frozen-jsx.js.snap @@ -0,0 +1,501 @@ +--- +source: crates/forget_hermes_parser/tests/parser_test.rs +expression: "format!(\"Input:\\n{input}\\n\\nOutput:\\n{output}\")" +input_file: crates/forget_hermes_parser/tests/fixtures/function-expression-captures-value-later-frozen-jsx.js +--- +Input: +function Component(props) { + let x = {}; + // onChange should be inferred as immutable, because the value + // it captures (`x`) is frozen by the time the function is referenced + const onChange = (e) => { + maybeMutate(x, e.target.value); + }; + if (props.cond) { +
{x}
; + } + return ; +} + + +Output: +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "Component", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [ + { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "VariableDeclaration", + "kind": "let", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "ObjectExpression", + "properties": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "onChange", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "ArrowFunctionExpression", + "id": null, + "params": [ + { + "type": "Identifier", + "name": "e", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "maybeMutate", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [ + { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "MemberExpression", + "object": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "e", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "target", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "value", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "expression": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "IfStatement", + "test": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "cond", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "consequent": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "JSXElement", + "openingElement": { + "type": "JSXOpeningElement", + "name": { + "type": "JSXIdentifier", + "name": "div", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "attributes": [], + "selfClosing": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "children": [ + { + "type": "JSXExpressionContainer", + "expression": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "closingElement": { + "type": "JSXClosingElement", + "name": { + "type": "JSXIdentifier", + "name": "div", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "alternate": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ReturnStatement", + "argument": { + "type": "JSXElement", + "openingElement": { + "type": "JSXOpeningElement", + "name": { + "type": "JSXIdentifier", + "name": "Foo", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "attributes": [ + { + "type": "JSXAttribute", + "name": { + "type": "JSXIdentifier", + "name": "value", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "value": { + "type": "JSXExpressionContainer", + "expression": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "JSXAttribute", + "name": { + "type": "JSXIdentifier", + "name": "onChange", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "value": { + "type": "JSXExpressionContainer", + "expression": { + "type": "Identifier", + "name": "onChange", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "selfClosing": true, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "children": [], + "closingElement": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "sourceType": "script", + "loc": null, + "range": { + "start": 0, + "end": 1 + } +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@function-expression-maybe-mutates-hook-return-value.js.snap b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@function-expression-maybe-mutates-hook-return-value.js.snap new file mode 100644 index 0000000000..3a2e0a2588 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@function-expression-maybe-mutates-hook-return-value.js.snap @@ -0,0 +1,296 @@ +--- +source: crates/forget_hermes_parser/tests/parser_test.rs +expression: "format!(\"Input:\\n{input}\\n\\nOutput:\\n{output}\")" +input_file: crates/forget_hermes_parser/tests/fixtures/function-expression-maybe-mutates-hook-return-value.js +--- +Input: +function Component(props) { + const id = useSelectedEntitytId(); + // this example should infer `id` as mutable, and then infer `onLoad` as mutable, + // and be rejected because onLoad cannot be passed as a frozen value in the JSX. + // however, we likely have to allow this example to work, because hook return + // values are generally immutable in practice and are also widely referenced in + // callbacks. + const onLoad = () => { + log(id); + }; + return ; +} + + +Output: +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "Component", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [ + { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "id", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "useSelectedEntitytId", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "onLoad", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "ArrowFunctionExpression", + "id": null, + "params": [], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "log", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [ + { + "type": "Identifier", + "name": "id", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "expression": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ReturnStatement", + "argument": { + "type": "JSXElement", + "openingElement": { + "type": "JSXOpeningElement", + "name": { + "type": "JSXIdentifier", + "name": "Foo", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "attributes": [ + { + "type": "JSXAttribute", + "name": { + "type": "JSXIdentifier", + "name": "onLoad", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "value": { + "type": "JSXExpressionContainer", + "expression": { + "type": "Identifier", + "name": "onLoad", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "selfClosing": true, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "children": [], + "closingElement": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "sourceType": "script", + "loc": null, + "range": { + "start": 0, + "end": 1 + } +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@function-expression-with-store-to-parameter.js.snap b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@function-expression-with-store-to-parameter.js.snap new file mode 100644 index 0000000000..311c14c4b8 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@function-expression-with-store-to-parameter.js.snap @@ -0,0 +1,393 @@ +--- +source: crates/forget_hermes_parser/tests/parser_test.rs +expression: "format!(\"Input:\\n{input}\\n\\nOutput:\\n{output}\")" +input_file: crates/forget_hermes_parser/tests/fixtures/function-expression-with-store-to-parameter.js +--- +Input: +function Component(props) { + const mutate = (object, key, value) => { + object.updated = true; + object[key] = value; + }; + const x = makeObject(props); + mutate(x); + return x; +} + + +Output: +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "Component", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [ + { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "mutate", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "ArrowFunctionExpression", + "id": null, + "params": [ + { + "type": "Identifier", + "name": "object", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "Identifier", + "name": "key", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "Identifier", + "name": "value", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "object", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "updated", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "right": { + "type": "BooleanLiteral", + "value": true, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "object", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "key", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": true, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "right": { + "type": "Identifier", + "name": "value", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "expression": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "makeObject", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [ + { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "mutate", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [ + { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ReturnStatement", + "argument": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "sourceType": "script", + "loc": null, + "range": { + "start": 0, + "end": 1 + } +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@function-param-assignment-pattern.js.snap b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@function-param-assignment-pattern.js.snap new file mode 100644 index 0000000000..bcf2714e62 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@function-param-assignment-pattern.js.snap @@ -0,0 +1,162 @@ +--- +source: crates/forget_hermes_parser/tests/parser_test.rs +expression: "format!(\"Input:\\n{input}\\n\\nOutput:\\n{output}\")" +input_file: crates/forget_hermes_parser/tests/fixtures/function-param-assignment-pattern.js +--- +Input: +function Component(x = "default", y = [{}]) { + return [x, y]; +} + + +Output: +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "Component", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [ + { + "type": "AssignmentPattern", + "left": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "right": { + "type": "StringLiteral", + "value": "default", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "AssignmentPattern", + "left": { + "type": "Identifier", + "name": "y", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "right": { + "type": "ArrayExpression", + "elements": [ + { + "type": "ObjectExpression", + "properties": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ReturnStatement", + "argument": { + "type": "ArrayExpression", + "elements": [ + { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "Identifier", + "name": "y", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "sourceType": "script", + "loc": null, + "range": { + "start": 0, + "end": 1 + } +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@gating-test-export-default-function.js.snap b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@gating-test-export-default-function.js.snap new file mode 100644 index 0000000000..bc1551666b --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@gating-test-export-default-function.js.snap @@ -0,0 +1,492 @@ +--- +source: crates/forget_hermes_parser/tests/parser_test.rs +expression: "format!(\"Input:\\n{input}\\n\\nOutput:\\n{output}\")" +input_file: crates/forget_hermes_parser/tests/fixtures/gating-test-export-default-function.js +--- +Input: +// @gating @forgetDirective +export default function Bar(props) { + "use forget"; + return
{props.bar}
; +} + +function NoForget(props) { + return {props.noForget}; +} + +function Foo(props) { + "use forget"; + return {props.bar}; +} + + +Output: +{ + "type": "Program", + "body": [ + { + "type": "ExportDefaultDeclaration", + "declaration": { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "Bar", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [ + { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "StringLiteral", + "value": "use forget", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ReturnStatement", + "argument": { + "type": "JSXElement", + "openingElement": { + "type": "JSXOpeningElement", + "name": { + "type": "JSXIdentifier", + "name": "div", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "attributes": [], + "selfClosing": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "children": [ + { + "type": "JSXExpressionContainer", + "expression": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "bar", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "closingElement": { + "type": "JSXClosingElement", + "name": { + "type": "JSXIdentifier", + "name": "div", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "NoForget", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [ + { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ReturnStatement", + "argument": { + "type": "JSXElement", + "openingElement": { + "type": "JSXOpeningElement", + "name": { + "type": "JSXIdentifier", + "name": "Bar", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "attributes": [], + "selfClosing": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "children": [ + { + "type": "JSXExpressionContainer", + "expression": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "noForget", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "closingElement": { + "type": "JSXClosingElement", + "name": { + "type": "JSXIdentifier", + "name": "Bar", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "Foo", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [ + { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "StringLiteral", + "value": "use forget", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ReturnStatement", + "argument": { + "type": "JSXElement", + "openingElement": { + "type": "JSXOpeningElement", + "name": { + "type": "JSXIdentifier", + "name": "Foo", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "attributes": [], + "selfClosing": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "children": [ + { + "type": "JSXExpressionContainer", + "expression": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "bar", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "closingElement": { + "type": "JSXClosingElement", + "name": { + "type": "JSXIdentifier", + "name": "Foo", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "sourceType": "script", + "loc": null, + "range": { + "start": 0, + "end": 1 + } +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@gating-test-export-function-and-default.js.snap b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@gating-test-export-function-and-default.js.snap new file mode 100644 index 0000000000..d888d52828 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@gating-test-export-function-and-default.js.snap @@ -0,0 +1,502 @@ +--- +source: crates/forget_hermes_parser/tests/parser_test.rs +expression: "format!(\"Input:\\n{input}\\n\\nOutput:\\n{output}\")" +input_file: crates/forget_hermes_parser/tests/fixtures/gating-test-export-function-and-default.js +--- +Input: +// @gating @forgetDirective +export default function Bar(props) { + "use forget"; + return
{props.bar}
; +} + +function NoForget(props) { + return {props.noForget}; +} + +export function Foo(props) { + "use forget"; + return {props.bar}; +} + + +Output: +{ + "type": "Program", + "body": [ + { + "type": "ExportDefaultDeclaration", + "declaration": { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "Bar", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [ + { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "StringLiteral", + "value": "use forget", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ReturnStatement", + "argument": { + "type": "JSXElement", + "openingElement": { + "type": "JSXOpeningElement", + "name": { + "type": "JSXIdentifier", + "name": "div", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "attributes": [], + "selfClosing": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "children": [ + { + "type": "JSXExpressionContainer", + "expression": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "bar", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "closingElement": { + "type": "JSXClosingElement", + "name": { + "type": "JSXIdentifier", + "name": "div", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "NoForget", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [ + { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ReturnStatement", + "argument": { + "type": "JSXElement", + "openingElement": { + "type": "JSXOpeningElement", + "name": { + "type": "JSXIdentifier", + "name": "Bar", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "attributes": [], + "selfClosing": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "children": [ + { + "type": "JSXExpressionContainer", + "expression": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "noForget", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "closingElement": { + "type": "JSXClosingElement", + "name": { + "type": "JSXIdentifier", + "name": "Bar", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ExportNamedDeclaration", + "declaration": { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "Foo", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [ + { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "StringLiteral", + "value": "use forget", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ReturnStatement", + "argument": { + "type": "JSXElement", + "openingElement": { + "type": "JSXOpeningElement", + "name": { + "type": "JSXIdentifier", + "name": "Foo", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "attributes": [], + "selfClosing": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "children": [ + { + "type": "JSXExpressionContainer", + "expression": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "bar", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "closingElement": { + "type": "JSXClosingElement", + "name": { + "type": "JSXIdentifier", + "name": "Foo", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "specifiers": [], + "source": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "sourceType": "script", + "loc": null, + "range": { + "start": 0, + "end": 1 + } +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@gating-test-export-function.js.snap b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@gating-test-export-function.js.snap new file mode 100644 index 0000000000..36e91d8428 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@gating-test-export-function.js.snap @@ -0,0 +1,514 @@ +--- +source: crates/forget_hermes_parser/tests/parser_test.rs +expression: "format!(\"Input:\\n{input}\\n\\nOutput:\\n{output}\")" +input_file: crates/forget_hermes_parser/tests/fixtures/gating-test-export-function.js +--- +Input: +// @gating @forgetDirective +export function Bar(props) { + "use forget"; + return
{props.bar}
; +} + +export function NoForget(props) { + return {props.noForget}; +} + +export function Foo(props) { + "use forget"; + return {props.bar}; +} + + +Output: +{ + "type": "Program", + "body": [ + { + "type": "ExportNamedDeclaration", + "declaration": { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "Bar", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [ + { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "StringLiteral", + "value": "use forget", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ReturnStatement", + "argument": { + "type": "JSXElement", + "openingElement": { + "type": "JSXOpeningElement", + "name": { + "type": "JSXIdentifier", + "name": "div", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "attributes": [], + "selfClosing": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "children": [ + { + "type": "JSXExpressionContainer", + "expression": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "bar", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "closingElement": { + "type": "JSXClosingElement", + "name": { + "type": "JSXIdentifier", + "name": "div", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "specifiers": [], + "source": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ExportNamedDeclaration", + "declaration": { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "NoForget", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [ + { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ReturnStatement", + "argument": { + "type": "JSXElement", + "openingElement": { + "type": "JSXOpeningElement", + "name": { + "type": "JSXIdentifier", + "name": "Bar", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "attributes": [], + "selfClosing": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "children": [ + { + "type": "JSXExpressionContainer", + "expression": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "noForget", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "closingElement": { + "type": "JSXClosingElement", + "name": { + "type": "JSXIdentifier", + "name": "Bar", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "specifiers": [], + "source": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ExportNamedDeclaration", + "declaration": { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "Foo", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [ + { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "StringLiteral", + "value": "use forget", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ReturnStatement", + "argument": { + "type": "JSXElement", + "openingElement": { + "type": "JSXOpeningElement", + "name": { + "type": "JSXIdentifier", + "name": "Foo", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "attributes": [], + "selfClosing": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "children": [ + { + "type": "JSXExpressionContainer", + "expression": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "bar", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "closingElement": { + "type": "JSXClosingElement", + "name": { + "type": "JSXIdentifier", + "name": "Foo", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "specifiers": [], + "source": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "sourceType": "script", + "loc": null, + "range": { + "start": 0, + "end": 1 + } +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@gating-test.js.snap b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@gating-test.js.snap new file mode 100644 index 0000000000..a4e00c3286 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@gating-test.js.snap @@ -0,0 +1,484 @@ +--- +source: crates/forget_hermes_parser/tests/parser_test.rs +expression: "format!(\"Input:\\n{input}\\n\\nOutput:\\n{output}\")" +input_file: crates/forget_hermes_parser/tests/fixtures/gating-test.js +--- +Input: +// @gating @forgetDirective +function Bar(props) { + "use forget"; + return
{props.bar}
; +} + +function NoForget(props) { + return {props.noForget}; +} + +function Foo(props) { + "use forget"; + return {props.bar}; +} + + +Output: +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "Bar", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [ + { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "StringLiteral", + "value": "use forget", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ReturnStatement", + "argument": { + "type": "JSXElement", + "openingElement": { + "type": "JSXOpeningElement", + "name": { + "type": "JSXIdentifier", + "name": "div", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "attributes": [], + "selfClosing": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "children": [ + { + "type": "JSXExpressionContainer", + "expression": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "bar", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "closingElement": { + "type": "JSXClosingElement", + "name": { + "type": "JSXIdentifier", + "name": "div", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "NoForget", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [ + { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ReturnStatement", + "argument": { + "type": "JSXElement", + "openingElement": { + "type": "JSXOpeningElement", + "name": { + "type": "JSXIdentifier", + "name": "Bar", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "attributes": [], + "selfClosing": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "children": [ + { + "type": "JSXExpressionContainer", + "expression": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "noForget", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "closingElement": { + "type": "JSXClosingElement", + "name": { + "type": "JSXIdentifier", + "name": "Bar", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "Foo", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [ + { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "StringLiteral", + "value": "use forget", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ReturnStatement", + "argument": { + "type": "JSXElement", + "openingElement": { + "type": "JSXOpeningElement", + "name": { + "type": "JSXIdentifier", + "name": "Foo", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "attributes": [], + "selfClosing": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "children": [ + { + "type": "JSXExpressionContainer", + "expression": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "bar", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "closingElement": { + "type": "JSXClosingElement", + "name": { + "type": "JSXIdentifier", + "name": "Foo", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "sourceType": "script", + "loc": null, + "range": { + "start": 0, + "end": 1 + } +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@global-jsx-tag-lowered-between-mutations.js.snap b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@global-jsx-tag-lowered-between-mutations.js.snap new file mode 100644 index 0000000000..66c04c83ad --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@global-jsx-tag-lowered-between-mutations.js.snap @@ -0,0 +1,222 @@ +--- +source: crates/forget_hermes_parser/tests/parser_test.rs +expression: "format!(\"Input:\\n{input}\\n\\nOutput:\\n{output}\")" +input_file: crates/forget_hermes_parser/tests/fixtures/global-jsx-tag-lowered-between-mutations.js +--- +Input: +function Component(props) { + const maybeMutable = new MaybeMutable(); + // NOTE: this will produce invalid output. + // The HIR is roughly: + // ⌵ mutable range of `maybeMutable` + // StoreLocal maybeMutable = ... ⌝ + // t0 = LoadGlobal View ⎮ <-- View is lowered inside this mutable range + // and thus gets becomes an output of this scope, + // gets promoted to temporary + // t1 = LoadGlobal maybeMutate ⎮ + // t2 = LoadLocal maybeMutable ⎮ + // t3 = Call t1(t2) ⌟ + // t4 = Jsx tag=t0 props=[] children=[t3] <-- `t0` is an invalid tag + return {maybeMutate(maybeMutable)}; +} + + +Output: +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "Component", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [ + { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "maybeMutable", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "NewExpression", + "callee": { + "type": "Identifier", + "name": "MaybeMutable", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ReturnStatement", + "argument": { + "type": "JSXElement", + "openingElement": { + "type": "JSXOpeningElement", + "name": { + "type": "JSXIdentifier", + "name": "View", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "attributes": [], + "selfClosing": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "children": [ + { + "type": "JSXExpressionContainer", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "maybeMutate", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [ + { + "type": "Identifier", + "name": "maybeMutable", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "closingElement": { + "type": "JSXClosingElement", + "name": { + "type": "JSXIdentifier", + "name": "View", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "sourceType": "script", + "loc": null, + "range": { + "start": 0, + "end": 1 + } +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@globals-Boolean.js.snap b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@globals-Boolean.js.snap new file mode 100644 index 0000000000..75a74b563c --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@globals-Boolean.js.snap @@ -0,0 +1,207 @@ +--- +source: crates/forget_hermes_parser/tests/parser_test.rs +expression: "format!(\"Input:\\n{input}\\n\\nOutput:\\n{output}\")" +input_file: crates/forget_hermes_parser/tests/fixtures/globals-Boolean.js +--- +Input: +function Component(props) { + const x = {}; + const y = Boolean(x); + return [x, y]; +} + + +Output: +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "Component", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [ + { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "ObjectExpression", + "properties": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "y", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "Boolean", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [ + { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ReturnStatement", + "argument": { + "type": "ArrayExpression", + "elements": [ + { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "Identifier", + "name": "y", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "sourceType": "script", + "loc": null, + "range": { + "start": 0, + "end": 1 + } +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@globals-Number.js.snap b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@globals-Number.js.snap new file mode 100644 index 0000000000..7b7e732b84 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@globals-Number.js.snap @@ -0,0 +1,207 @@ +--- +source: crates/forget_hermes_parser/tests/parser_test.rs +expression: "format!(\"Input:\\n{input}\\n\\nOutput:\\n{output}\")" +input_file: crates/forget_hermes_parser/tests/fixtures/globals-Number.js +--- +Input: +function Component(props) { + const x = {}; + const y = Number(x); + return [x, y]; +} + + +Output: +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "Component", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [ + { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "ObjectExpression", + "properties": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "y", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "Number", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [ + { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ReturnStatement", + "argument": { + "type": "ArrayExpression", + "elements": [ + { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "Identifier", + "name": "y", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "sourceType": "script", + "loc": null, + "range": { + "start": 0, + "end": 1 + } +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@globals-String.js.snap b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@globals-String.js.snap new file mode 100644 index 0000000000..c6b64392d5 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@globals-String.js.snap @@ -0,0 +1,207 @@ +--- +source: crates/forget_hermes_parser/tests/parser_test.rs +expression: "format!(\"Input:\\n{input}\\n\\nOutput:\\n{output}\")" +input_file: crates/forget_hermes_parser/tests/fixtures/globals-String.js +--- +Input: +function Component(props) { + const x = {}; + const y = String(x); + return [x, y]; +} + + +Output: +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "Component", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [ + { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "ObjectExpression", + "properties": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "y", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "String", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [ + { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ReturnStatement", + "argument": { + "type": "ArrayExpression", + "elements": [ + { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "Identifier", + "name": "y", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "sourceType": "script", + "loc": null, + "range": { + "start": 0, + "end": 1 + } +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@holey-array-expr.js.snap b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@holey-array-expr.js.snap new file mode 100644 index 0000000000..81449a1b5f --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@holey-array-expr.js.snap @@ -0,0 +1,149 @@ +--- +source: crates/forget_hermes_parser/tests/parser_test.rs +expression: "format!(\"Input:\\n{input}\\n\\nOutput:\\n{output}\")" +input_file: crates/forget_hermes_parser/tests/fixtures/holey-array-expr.js +--- +Input: +function t(props) { + let x = [, foo, props]; + return x; +} + + +Output: +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "t", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [ + { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "VariableDeclaration", + "kind": "let", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "ArrayExpression", + "elements": [ + null, + { + "type": "Identifier", + "name": "foo", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ReturnStatement", + "argument": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "sourceType": "script", + "loc": null, + "range": { + "start": 0, + "end": 1 + } +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@holey-array-pattern-dce-2.js.snap b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@holey-array-pattern-dce-2.js.snap new file mode 100644 index 0000000000..cfcb119c9e --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@holey-array-pattern-dce-2.js.snap @@ -0,0 +1,149 @@ +--- +source: crates/forget_hermes_parser/tests/parser_test.rs +expression: "format!(\"Input:\\n{input}\\n\\nOutput:\\n{output}\")" +input_file: crates/forget_hermes_parser/tests/fixtures/holey-array-pattern-dce-2.js +--- +Input: +function t(props) { + let [foo, bar, ,] = props; + return foo; +} + + +Output: +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "t", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [ + { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "VariableDeclaration", + "kind": "let", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "ArrayPattern", + "elements": [ + { + "type": "Identifier", + "name": "foo", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "Identifier", + "name": "bar", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + null + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ReturnStatement", + "argument": { + "type": "Identifier", + "name": "foo", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "sourceType": "script", + "loc": null, + "range": { + "start": 0, + "end": 1 + } +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@holey-array-pattern-dce.js.snap b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@holey-array-pattern-dce.js.snap new file mode 100644 index 0000000000..051b0b353b --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@holey-array-pattern-dce.js.snap @@ -0,0 +1,149 @@ +--- +source: crates/forget_hermes_parser/tests/parser_test.rs +expression: "format!(\"Input:\\n{input}\\n\\nOutput:\\n{output}\")" +input_file: crates/forget_hermes_parser/tests/fixtures/holey-array-pattern-dce.js +--- +Input: +function t(props) { + let [, foo, bar] = props; + return foo; +} + + +Output: +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "t", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [ + { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "VariableDeclaration", + "kind": "let", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "ArrayPattern", + "elements": [ + null, + { + "type": "Identifier", + "name": "foo", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "Identifier", + "name": "bar", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ReturnStatement", + "argument": { + "type": "Identifier", + "name": "foo", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "sourceType": "script", + "loc": null, + "range": { + "start": 0, + "end": 1 + } +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@holey-array.js.snap b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@holey-array.js.snap new file mode 100644 index 0000000000..740e89a9f6 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@holey-array.js.snap @@ -0,0 +1,206 @@ +--- +source: crates/forget_hermes_parser/tests/parser_test.rs +expression: "format!(\"Input:\\n{input}\\n\\nOutput:\\n{output}\")" +input_file: crates/forget_hermes_parser/tests/fixtures/holey-array.js +--- +Input: +function t(props) { + let [, setstate] = useState(); + setstate(1); + return props.foo; +} + + +Output: +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "t", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [ + { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "VariableDeclaration", + "kind": "let", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "ArrayPattern", + "elements": [ + null, + { + "type": "Identifier", + "name": "setstate", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "useState", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "setstate", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [ + { + "type": "NumericLiteral", + "value": 4607182418800017408, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ReturnStatement", + "argument": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "foo", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "sourceType": "script", + "loc": null, + "range": { + "start": 0, + "end": 1 + } +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@hook-call.js.snap b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@hook-call.js.snap new file mode 100644 index 0000000000..29eea5c0fe --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@hook-call.js.snap @@ -0,0 +1,417 @@ +--- +source: crates/forget_hermes_parser/tests/parser_test.rs +expression: "format!(\"Input:\\n{input}\\n\\nOutput:\\n{output}\")" +input_file: crates/forget_hermes_parser/tests/fixtures/hook-call.js +--- +Input: +function useFreeze() {} +function foo() {} + +function Component(props) { + const x = []; + const y = useFreeze(x); + foo(y, x); + return ( + + {x} + {y} + + ); +} + + +Output: +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "useFreeze", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [], + "body": { + "type": "BlockStatement", + "body": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "foo", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [], + "body": { + "type": "BlockStatement", + "body": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "Component", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [ + { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "ArrayExpression", + "elements": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "y", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "useFreeze", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [ + { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "foo", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [ + { + "type": "Identifier", + "name": "y", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ReturnStatement", + "argument": { + "type": "JSXElement", + "openingElement": { + "type": "JSXOpeningElement", + "name": { + "type": "JSXIdentifier", + "name": "Component", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "attributes": [], + "selfClosing": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "children": [ + { + "type": "JSXText", + "value": "\n ", + "raw": "\n ", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "JSXExpressionContainer", + "expression": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "JSXText", + "value": "\n ", + "raw": "\n ", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "JSXExpressionContainer", + "expression": { + "type": "Identifier", + "name": "y", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "JSXText", + "value": "\n ", + "raw": "\n ", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "closingElement": { + "type": "JSXClosingElement", + "name": { + "type": "JSXIdentifier", + "name": "Component", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "sourceType": "script", + "loc": null, + "range": { + "start": 0, + "end": 1 + } +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@hook-inside-logical-expression.js.snap b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@hook-inside-logical-expression.js.snap new file mode 100644 index 0000000000..e384eb4717 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@hook-inside-logical-expression.js.snap @@ -0,0 +1,246 @@ +--- +source: crates/forget_hermes_parser/tests/parser_test.rs +expression: "format!(\"Input:\\n{input}\\n\\nOutput:\\n{output}\")" +input_file: crates/forget_hermes_parser/tests/fixtures/hook-inside-logical-expression.js +--- +Input: +function Component(props) { + const user = useFragment(graphql`...`, props.user) ?? {}; + return user.name; +} + + +Output: +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "Component", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [ + { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "user", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "LogicalExpression", + "operator": "??", + "left": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "useFragment", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [ + { + "type": "TaggedTemplateExpression", + "tag": { + "type": "Identifier", + "name": "graphql", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "quasi": { + "type": "TemplateLiteral", + "quasis": [ + { + "type": "TemplateElement", + "tail": true, + "value": { + "cooked": "...", + "raw": "..." + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "expressions": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "user", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "right": { + "type": "ObjectExpression", + "properties": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ReturnStatement", + "argument": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "user", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "name", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "sourceType": "script", + "loc": null, + "range": { + "start": 0, + "end": 1 + } +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@hooks-freeze-arguments.js.snap b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@hooks-freeze-arguments.js.snap new file mode 100644 index 0000000000..04f3ba4afa --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@hooks-freeze-arguments.js.snap @@ -0,0 +1,331 @@ +--- +source: crates/forget_hermes_parser/tests/parser_test.rs +expression: "format!(\"Input:\\n{input}\\n\\nOutput:\\n{output}\")" +input_file: crates/forget_hermes_parser/tests/fixtures/hooks-freeze-arguments.js +--- +Input: +function Component() { + const a = []; + useFreeze(a); // should freeze + useFreeze(a); // should be readonly + call(a); // should be readonly + return a; +} + +function useFreeze(x) {} +function call(x) {} + + +Output: +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "Component", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "a", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "ArrayExpression", + "elements": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "useFreeze", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [ + { + "type": "Identifier", + "name": "a", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "useFreeze", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [ + { + "type": "Identifier", + "name": "a", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "call", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [ + { + "type": "Identifier", + "name": "a", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ReturnStatement", + "argument": { + "type": "Identifier", + "name": "a", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "useFreeze", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [ + { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "call", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [ + { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "sourceType": "script", + "loc": null, + "range": { + "start": 0, + "end": 1 + } +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@hooks-freeze-possibly-mutable-arguments.js.snap b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@hooks-freeze-possibly-mutable-arguments.js.snap new file mode 100644 index 0000000000..16db23abab --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@hooks-freeze-possibly-mutable-arguments.js.snap @@ -0,0 +1,570 @@ +--- +source: crates/forget_hermes_parser/tests/parser_test.rs +expression: "format!(\"Input:\\n{input}\\n\\nOutput:\\n{output}\")" +input_file: crates/forget_hermes_parser/tests/fixtures/hooks-freeze-possibly-mutable-arguments.js +--- +Input: +function Component(props) { + const cond = props.cond; + const x = props.x; + let a; + if (cond) { + a = x; + } else { + a = []; + } + useFreeze(a); // should freeze, value *may* be mutable + useFreeze(a); // should be readonly + call(a); // should be readonly + return a; +} + +function useFreeze(x) {} +function call(x) {} + + +Output: +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "Component", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [ + { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "cond", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "cond", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "VariableDeclaration", + "kind": "let", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "a", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "IfStatement", + "test": { + "type": "Identifier", + "name": "cond", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "consequent": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "Identifier", + "name": "a", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "right": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "alternate": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "Identifier", + "name": "a", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "right": { + "type": "ArrayExpression", + "elements": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "useFreeze", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [ + { + "type": "Identifier", + "name": "a", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "useFreeze", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [ + { + "type": "Identifier", + "name": "a", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "call", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [ + { + "type": "Identifier", + "name": "a", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ReturnStatement", + "argument": { + "type": "Identifier", + "name": "a", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "useFreeze", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [ + { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "call", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [ + { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "sourceType": "script", + "loc": null, + "range": { + "start": 0, + "end": 1 + } +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@immutable-hooks.js.snap b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@immutable-hooks.js.snap new file mode 100644 index 0000000000..028df7383c --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@immutable-hooks.js.snap @@ -0,0 +1,260 @@ +--- +source: crates/forget_hermes_parser/tests/parser_test.rs +expression: "format!(\"Input:\\n{input}\\n\\nOutput:\\n{output}\")" +input_file: crates/forget_hermes_parser/tests/fixtures/immutable-hooks.js +--- +Input: +// @enableAssumeHooksFollowRulesOfReact true +function Component(props) { + const x = {}; + // In enableAssumeHooksFollowRulesOfReact mode hooks freeze their inputs and return frozen values + const y = useFoo(x); + // Thus both x and y are frozen here, and x can be independently memoized + bar(x, y); + return [x, y]; +} + + +Output: +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "Component", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [ + { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "ObjectExpression", + "properties": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "y", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "useFoo", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [ + { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "bar", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [ + { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "Identifier", + "name": "y", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ReturnStatement", + "argument": { + "type": "ArrayExpression", + "elements": [ + { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "Identifier", + "name": "y", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "sourceType": "script", + "loc": null, + "range": { + "start": 0, + "end": 1 + } +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@inadvertent-mutability-readonly-class.js.snap b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@inadvertent-mutability-readonly-class.js.snap new file mode 100644 index 0000000000..422e1408e4 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@inadvertent-mutability-readonly-class.js.snap @@ -0,0 +1,350 @@ +--- +source: crates/forget_hermes_parser/tests/parser_test.rs +expression: "format!(\"Input:\\n{input}\\n\\nOutput:\\n{output}\")" +input_file: crates/forget_hermes_parser/tests/fixtures/inadvertent-mutability-readonly-class.js +--- +Input: +function Component(props) { + const env = useRelayEnvironment(); + // Note: this is a class has no mutable methods, ie it always treats `this` as readonly + const mutator = new Mutator(env); + + useOtherHook(); + + // `x` should be independently memoizeable, since foo(x, mutator) cannot mutate + // the mutator. + const x = {}; + foo(x, mutator); + return x; +} + +class Mutator {} + + +Output: +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "Component", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [ + { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "env", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "useRelayEnvironment", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "mutator", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "NewExpression", + "callee": { + "type": "Identifier", + "name": "Mutator", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [ + { + "type": "Identifier", + "name": "env", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "useOtherHook", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "ObjectExpression", + "properties": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "foo", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [ + { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "Identifier", + "name": "mutator", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ReturnStatement", + "argument": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ClassDeclaration", + "id": { + "type": "Identifier", + "name": "Mutator", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "superClass": null, + "body": { + "type": "ClassBody", + "body": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "sourceType": "script", + "loc": null, + "range": { + "start": 0, + "end": 1 + } +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@inadvertent-mutability-readonly-lambda.js.snap b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@inadvertent-mutability-readonly-lambda.js.snap new file mode 100644 index 0000000000..95ec753711 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@inadvertent-mutability-readonly-lambda.js.snap @@ -0,0 +1,464 @@ +--- +source: crates/forget_hermes_parser/tests/parser_test.rs +expression: "format!(\"Input:\\n{input}\\n\\nOutput:\\n{output}\")" +input_file: crates/forget_hermes_parser/tests/fixtures/inadvertent-mutability-readonly-lambda.js +--- +Input: +function Component(props) { + const [value, setValue] = useState(null); + // NOTE: this lambda does not capture any mutable values (only the state setter) + // and thus should be treated as readonly + const onChange = (e) => setValue((value) => value + e.target.value); + + useOtherHook(); + + // x should be independently memoizeable, since foo(x, onChange) cannot modify onChange + const x = {}; + foo(x, onChange); + return x; +} + + +Output: +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "Component", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [ + { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "ArrayPattern", + "elements": [ + { + "type": "Identifier", + "name": "value", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "Identifier", + "name": "setValue", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "useState", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [ + { + "type": "NullLiteral", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "onChange", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "ArrowFunctionExpression", + "id": null, + "params": [ + { + "type": "Identifier", + "name": "e", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "setValue", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [ + { + "type": "ArrowFunctionExpression", + "id": null, + "params": [ + { + "type": "Identifier", + "name": "value", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BinaryExpression", + "left": { + "type": "Identifier", + "name": "value", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "operator": "+", + "right": { + "type": "MemberExpression", + "object": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "e", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "target", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "value", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": true, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "expression": true, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": true, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "expression": true, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "useOtherHook", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "ObjectExpression", + "properties": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "foo", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [ + { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "Identifier", + "name": "onChange", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ReturnStatement", + "argument": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "sourceType": "script", + "loc": null, + "range": { + "start": 0, + "end": 1 + } +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@independent-across-if.js.snap b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@independent-across-if.js.snap new file mode 100644 index 0000000000..7f31d8010b --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@independent-across-if.js.snap @@ -0,0 +1,625 @@ +--- +source: crates/forget_hermes_parser/tests/parser_test.rs +expression: "format!(\"Input:\\n{input}\\n\\nOutput:\\n{output}\")" +input_file: crates/forget_hermes_parser/tests/fixtures/independent-across-if.js +--- +Input: +function compute() {} +function mutate() {} +function foo() {} +function Foo() {} + +/** + * Should produce 3 scopes: + * + * a: inputs=props.a & props.c; outputs=a + * a = compute(props.a); + * if (props.c) + * mutate(a) + * b: inputs=props.b & props.c; outputs=b + * b = compute(props.b); + * if (props.c) + * mutate(b) + * return: inputs=a, b outputs=return + * return = + */ +function Component(props) { + const a = compute(props.a); + const b = compute(props.b); + if (props.c) { + mutate(a); + mutate(b); + } + return ; +} + + +Output: +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "compute", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [], + "body": { + "type": "BlockStatement", + "body": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "mutate", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [], + "body": { + "type": "BlockStatement", + "body": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "foo", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [], + "body": { + "type": "BlockStatement", + "body": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "Foo", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [], + "body": { + "type": "BlockStatement", + "body": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "Component", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [ + { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "a", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "compute", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [ + { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "a", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "b", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "compute", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [ + { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "b", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "IfStatement", + "test": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "c", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "consequent": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "mutate", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [ + { + "type": "Identifier", + "name": "a", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "mutate", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [ + { + "type": "Identifier", + "name": "b", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "alternate": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ReturnStatement", + "argument": { + "type": "JSXElement", + "openingElement": { + "type": "JSXOpeningElement", + "name": { + "type": "JSXIdentifier", + "name": "Foo", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "attributes": [ + { + "type": "JSXAttribute", + "name": { + "type": "JSXIdentifier", + "name": "a", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "value": { + "type": "JSXExpressionContainer", + "expression": { + "type": "Identifier", + "name": "a", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "JSXAttribute", + "name": { + "type": "JSXIdentifier", + "name": "b", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "value": { + "type": "JSXExpressionContainer", + "expression": { + "type": "Identifier", + "name": "b", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "selfClosing": true, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "children": [], + "closingElement": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "sourceType": "script", + "loc": null, + "range": { + "start": 0, + "end": 1 + } +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@independent.js.snap b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@independent.js.snap new file mode 100644 index 0000000000..229f0d72c6 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@independent.js.snap @@ -0,0 +1,455 @@ +--- +source: crates/forget_hermes_parser/tests/parser_test.rs +expression: "format!(\"Input:\\n{input}\\n\\nOutput:\\n{output}\")" +input_file: crates/forget_hermes_parser/tests/fixtures/independent.js +--- +Input: +/** + * Should produce 3 scopes: + * + * a: inputs=props.a, outputs=a + * a = compute(props.a); + * b: inputs=props.b, outputs=b + * b = compute(props.b); + * return: inputs=a, b outputs=return + * return = + */ +function Component(props) { + const a = compute(props.a); + const b = compute(props.b); + return ; +} + +function compute() {} +function foo() {} +function Foo() {} + + +Output: +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "Component", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [ + { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "a", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "compute", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [ + { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "a", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "b", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "compute", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [ + { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "b", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ReturnStatement", + "argument": { + "type": "JSXElement", + "openingElement": { + "type": "JSXOpeningElement", + "name": { + "type": "JSXIdentifier", + "name": "Foo", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "attributes": [ + { + "type": "JSXAttribute", + "name": { + "type": "JSXIdentifier", + "name": "a", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "value": { + "type": "JSXExpressionContainer", + "expression": { + "type": "Identifier", + "name": "a", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "JSXAttribute", + "name": { + "type": "JSXIdentifier", + "name": "b", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "value": { + "type": "JSXExpressionContainer", + "expression": { + "type": "Identifier", + "name": "b", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "selfClosing": true, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "children": [], + "closingElement": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "compute", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [], + "body": { + "type": "BlockStatement", + "body": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "foo", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [], + "body": { + "type": "BlockStatement", + "body": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "Foo", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [], + "body": { + "type": "BlockStatement", + "body": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "sourceType": "script", + "loc": null, + "range": { + "start": 0, + "end": 1 + } +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@independently-memoize-object-property.js.snap b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@independently-memoize-object-property.js.snap new file mode 100644 index 0000000000..87b71213e3 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@independently-memoize-object-property.js.snap @@ -0,0 +1,260 @@ +--- +source: crates/forget_hermes_parser/tests/parser_test.rs +expression: "format!(\"Input:\\n{input}\\n\\nOutput:\\n{output}\")" +input_file: crates/forget_hermes_parser/tests/fixtures/independently-memoize-object-property.js +--- +Input: +function foo(a, b, c) { + const x = { a: a }; + // NOTE: this array should memoize independently from x, w only b,c as deps + x.y = [b, c]; + + return x; +} + + +Output: +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "foo", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [ + { + "type": "Identifier", + "name": "a", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "Identifier", + "name": "b", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "Identifier", + "name": "c", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "ObjectExpression", + "properties": [ + { + "type": "Property", + "key": { + "type": "Identifier", + "name": "a", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "value": { + "type": "Identifier", + "name": "a", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "kind": "init", + "method": false, + "shorthand": false, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "y", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "right": { + "type": "ArrayExpression", + "elements": [ + { + "type": "Identifier", + "name": "b", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "Identifier", + "name": "c", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ReturnStatement", + "argument": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "sourceType": "script", + "loc": null, + "range": { + "start": 0, + "end": 1 + } +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@infer-computed-delete.js.snap b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@infer-computed-delete.js.snap new file mode 100644 index 0000000000..1abbca2c2f --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@infer-computed-delete.js.snap @@ -0,0 +1,226 @@ +--- +source: crates/forget_hermes_parser/tests/parser_test.rs +expression: "format!(\"Input:\\n{input}\\n\\nOutput:\\n{output}\")" +input_file: crates/forget_hermes_parser/tests/fixtures/infer-computed-delete.js +--- +Input: +// @debug +function Component(props) { + const x = makeObject(); + const y = delete x[props.value]; + return y; +} + + +Output: +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "Component", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [ + { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "makeObject", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "y", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "UnaryExpression", + "operator": "delete", + "prefix": true, + "argument": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "value", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": true, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ReturnStatement", + "argument": { + "type": "Identifier", + "name": "y", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "sourceType": "script", + "loc": null, + "range": { + "start": 0, + "end": 1 + } +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@infer-global-object.js.snap b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@infer-global-object.js.snap new file mode 100644 index 0000000000..ef2170ad4e --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@infer-global-object.js.snap @@ -0,0 +1,554 @@ +--- +source: crates/forget_hermes_parser/tests/parser_test.rs +expression: "format!(\"Input:\\n{input}\\n\\nOutput:\\n{output}\")" +input_file: crates/forget_hermes_parser/tests/fixtures/infer-global-object.js +--- +Input: +// Check that we correctly resolve type and effect lookups on the javascript +// global object. +function Component(props) { + let neverAliasedOrMutated = foo(props.b); + let primitiveVal1 = Math.max(props.a, neverAliasedOrMutated); + let primitiveVal2 = Infinity; + let primitiveVal3 = globaThis.globalThis.NaN; + + // Even though we don't know the function signature of foo, + // we should be able to infer that it does not mutate its inputs. + foo(primitiveVal1, primitiveVal2, primitiveVal3); + return { primitiveVal1, primitiveVal2, primitiveVal3 }; +} + + +Output: +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "Component", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [ + { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "VariableDeclaration", + "kind": "let", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "neverAliasedOrMutated", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "foo", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [ + { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "b", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "VariableDeclaration", + "kind": "let", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "primitiveVal1", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "CallExpression", + "callee": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "Math", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "max", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [ + { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "a", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "Identifier", + "name": "neverAliasedOrMutated", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "VariableDeclaration", + "kind": "let", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "primitiveVal2", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "Identifier", + "name": "Infinity", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "VariableDeclaration", + "kind": "let", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "primitiveVal3", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "MemberExpression", + "object": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "globaThis", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "globalThis", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "NaN", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "foo", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [ + { + "type": "Identifier", + "name": "primitiveVal1", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "Identifier", + "name": "primitiveVal2", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "Identifier", + "name": "primitiveVal3", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ReturnStatement", + "argument": { + "type": "ObjectExpression", + "properties": [ + { + "type": "Property", + "key": { + "type": "Identifier", + "name": "primitiveVal1", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "value": { + "type": "Identifier", + "name": "primitiveVal1", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "kind": "init", + "method": false, + "shorthand": true, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "Property", + "key": { + "type": "Identifier", + "name": "primitiveVal2", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "value": { + "type": "Identifier", + "name": "primitiveVal2", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "kind": "init", + "method": false, + "shorthand": true, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "Property", + "key": { + "type": "Identifier", + "name": "primitiveVal3", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "value": { + "type": "Identifier", + "name": "primitiveVal3", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "kind": "init", + "method": false, + "shorthand": true, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "sourceType": "script", + "loc": null, + "range": { + "start": 0, + "end": 1 + } +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@infer-phi-primitive.js.snap b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@infer-phi-primitive.js.snap new file mode 100644 index 0000000000..33180f871b --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@infer-phi-primitive.js.snap @@ -0,0 +1,287 @@ +--- +source: crates/forget_hermes_parser/tests/parser_test.rs +expression: "format!(\"Input:\\n{input}\\n\\nOutput:\\n{output}\")" +input_file: crates/forget_hermes_parser/tests/fixtures/infer-phi-primitive.js +--- +Input: +function foo(a, b) { + let x; + if (a) { + x = 1; + } else { + x = 2; + } + + let y = x; + return y; +} + + +Output: +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "foo", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [ + { + "type": "Identifier", + "name": "a", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "Identifier", + "name": "b", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "VariableDeclaration", + "kind": "let", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "IfStatement", + "test": { + "type": "Identifier", + "name": "a", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "consequent": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "right": { + "type": "NumericLiteral", + "value": 4607182418800017408, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "alternate": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "right": { + "type": "NumericLiteral", + "value": 4611686018427387904, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "VariableDeclaration", + "kind": "let", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "y", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ReturnStatement", + "argument": { + "type": "Identifier", + "name": "y", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "sourceType": "script", + "loc": null, + "range": { + "start": 0, + "end": 1 + } +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@infer-property-delete.js.snap b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@infer-property-delete.js.snap new file mode 100644 index 0000000000..eec31f302d --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@infer-property-delete.js.snap @@ -0,0 +1,206 @@ +--- +source: crates/forget_hermes_parser/tests/parser_test.rs +expression: "format!(\"Input:\\n{input}\\n\\nOutput:\\n{output}\")" +input_file: crates/forget_hermes_parser/tests/fixtures/infer-property-delete.js +--- +Input: +function Component(props) { + const x = makeObject(); + const y = delete x.value; + return y; +} + + +Output: +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "Component", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [ + { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "makeObject", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "y", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "UnaryExpression", + "operator": "delete", + "prefix": true, + "argument": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "value", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ReturnStatement", + "argument": { + "type": "Identifier", + "name": "y", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "sourceType": "script", + "loc": null, + "range": { + "start": 0, + "end": 1 + } +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@infer-types-through-type-cast.flow.js.snap b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@infer-types-through-type-cast.flow.js.snap new file mode 100644 index 0000000000..49e2a48e34 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@infer-types-through-type-cast.flow.js.snap @@ -0,0 +1,233 @@ +--- +source: crates/forget_hermes_parser/tests/parser_test.rs +expression: "format!(\"Input:\\n{input}\\n\\nOutput:\\n{output}\")" +input_file: crates/forget_hermes_parser/tests/fixtures/infer-types-through-type-cast.flow.js +--- +Input: +// @flow +function Component(props) { + // We can infer that `x` is a primitive bc it is aliased to `y`, + // which is used in a binary expression + const x = foo(); + const y = (x: any); + y + 1; + return x; +} + +Output: +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "Component", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [ + { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "foo", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "y", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "CoverTypedIdentifier", + "left": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "right": { + "type": "TSTypeAnnotation", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "BinaryExpression", + "left": { + "type": "Identifier", + "name": "y", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "operator": "+", + "right": { + "type": "NumericLiteral", + "value": 4607182418800017408, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ReturnStatement", + "argument": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "sourceType": "script", + "loc": null, + "range": { + "start": 0, + "end": 1 + } +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@inner-memo-value-not-promoted-to-outer-scope-dynamic.js.snap b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@inner-memo-value-not-promoted-to-outer-scope-dynamic.js.snap new file mode 100644 index 0000000000..f41cc8f440 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@inner-memo-value-not-promoted-to-outer-scope-dynamic.js.snap @@ -0,0 +1,573 @@ +--- +source: crates/forget_hermes_parser/tests/parser_test.rs +expression: "format!(\"Input:\\n{input}\\n\\nOutput:\\n{output}\")" +input_file: crates/forget_hermes_parser/tests/fixtures/inner-memo-value-not-promoted-to-outer-scope-dynamic.js +--- +Input: +function Component(props) { + const item = useFragment(FRAGMENT, props.item); + useFreeze(item); + + const count = new MaybeMutable(item); + return ( + + + {Text} + {{maybeMutate(count)}} + + + ); +} + + +Output: +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "Component", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [ + { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "item", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "useFragment", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [ + { + "type": "Identifier", + "name": "FRAGMENT", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "item", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "useFreeze", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [ + { + "type": "Identifier", + "name": "item", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "count", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "NewExpression", + "callee": { + "type": "Identifier", + "name": "MaybeMutable", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [ + { + "type": "Identifier", + "name": "item", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ReturnStatement", + "argument": { + "type": "JSXElement", + "openingElement": { + "type": "JSXOpeningElement", + "name": { + "type": "JSXIdentifier", + "name": "View", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "attributes": [], + "selfClosing": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "children": [ + { + "type": "JSXText", + "value": "\n ", + "raw": "\n ", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "JSXElement", + "openingElement": { + "type": "JSXOpeningElement", + "name": { + "type": "JSXIdentifier", + "name": "View", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "attributes": [], + "selfClosing": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "children": [ + { + "type": "JSXText", + "value": "\n ", + "raw": "\n ", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "JSXExpressionContainer", + "expression": { + "type": "JSXElement", + "openingElement": { + "type": "JSXOpeningElement", + "name": { + "type": "JSXIdentifier", + "name": "span", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "attributes": [], + "selfClosing": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "children": [ + { + "type": "JSXText", + "value": "Text", + "raw": "Text", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "closingElement": { + "type": "JSXClosingElement", + "name": { + "type": "JSXIdentifier", + "name": "span", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "JSXText", + "value": "\n ", + "raw": "\n ", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "JSXExpressionContainer", + "expression": { + "type": "JSXElement", + "openingElement": { + "type": "JSXOpeningElement", + "name": { + "type": "JSXIdentifier", + "name": "span", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "attributes": [], + "selfClosing": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "children": [ + { + "type": "JSXExpressionContainer", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "maybeMutate", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [ + { + "type": "Identifier", + "name": "count", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "closingElement": { + "type": "JSXClosingElement", + "name": { + "type": "JSXIdentifier", + "name": "span", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "JSXText", + "value": "\n ", + "raw": "\n ", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "closingElement": { + "type": "JSXClosingElement", + "name": { + "type": "JSXIdentifier", + "name": "View", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "JSXText", + "value": "\n ", + "raw": "\n ", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "closingElement": { + "type": "JSXClosingElement", + "name": { + "type": "JSXIdentifier", + "name": "View", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "sourceType": "script", + "loc": null, + "range": { + "start": 0, + "end": 1 + } +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@inner-memo-value-not-promoted-to-outer-scope-static.js.snap b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@inner-memo-value-not-promoted-to-outer-scope-static.js.snap new file mode 100644 index 0000000000..598f63a20d --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@inner-memo-value-not-promoted-to-outer-scope-static.js.snap @@ -0,0 +1,432 @@ +--- +source: crates/forget_hermes_parser/tests/parser_test.rs +expression: "format!(\"Input:\\n{input}\\n\\nOutput:\\n{output}\")" +input_file: crates/forget_hermes_parser/tests/fixtures/inner-memo-value-not-promoted-to-outer-scope-static.js +--- +Input: +function Component(props) { + const count = new MaybeMutable(); + return ( + + + {Text} + {{maybeMutate(count)}} + + + ); +} + + +Output: +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "Component", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [ + { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "count", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "NewExpression", + "callee": { + "type": "Identifier", + "name": "MaybeMutable", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ReturnStatement", + "argument": { + "type": "JSXElement", + "openingElement": { + "type": "JSXOpeningElement", + "name": { + "type": "JSXIdentifier", + "name": "View", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "attributes": [], + "selfClosing": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "children": [ + { + "type": "JSXText", + "value": "\n ", + "raw": "\n ", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "JSXElement", + "openingElement": { + "type": "JSXOpeningElement", + "name": { + "type": "JSXIdentifier", + "name": "View", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "attributes": [], + "selfClosing": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "children": [ + { + "type": "JSXText", + "value": "\n ", + "raw": "\n ", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "JSXExpressionContainer", + "expression": { + "type": "JSXElement", + "openingElement": { + "type": "JSXOpeningElement", + "name": { + "type": "JSXIdentifier", + "name": "span", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "attributes": [], + "selfClosing": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "children": [ + { + "type": "JSXText", + "value": "Text", + "raw": "Text", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "closingElement": { + "type": "JSXClosingElement", + "name": { + "type": "JSXIdentifier", + "name": "span", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "JSXText", + "value": "\n ", + "raw": "\n ", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "JSXExpressionContainer", + "expression": { + "type": "JSXElement", + "openingElement": { + "type": "JSXOpeningElement", + "name": { + "type": "JSXIdentifier", + "name": "span", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "attributes": [], + "selfClosing": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "children": [ + { + "type": "JSXExpressionContainer", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "maybeMutate", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [ + { + "type": "Identifier", + "name": "count", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "closingElement": { + "type": "JSXClosingElement", + "name": { + "type": "JSXIdentifier", + "name": "span", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "JSXText", + "value": "\n ", + "raw": "\n ", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "closingElement": { + "type": "JSXClosingElement", + "name": { + "type": "JSXIdentifier", + "name": "View", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "JSXText", + "value": "\n ", + "raw": "\n ", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "closingElement": { + "type": "JSXClosingElement", + "name": { + "type": "JSXIdentifier", + "name": "View", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "sourceType": "script", + "loc": null, + "range": { + "start": 0, + "end": 1 + } +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@interdependent-across-if.js.snap b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@interdependent-across-if.js.snap new file mode 100644 index 0000000000..d26e0c46d9 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@interdependent-across-if.js.snap @@ -0,0 +1,555 @@ +--- +source: crates/forget_hermes_parser/tests/parser_test.rs +expression: "format!(\"Input:\\n{input}\\n\\nOutput:\\n{output}\")" +input_file: crates/forget_hermes_parser/tests/fixtures/interdependent-across-if.js +--- +Input: +function compute() {} +function foo() {} +function Foo() {} + +/** + * Should produce 1 scope: + * + * return: inputs=props.a & props.b & props.c; outputs=return + * const a = compute(props.a); + * const b = compute(props.b); + * if (props.c) + * foo(a, b); + * return = + */ +function Component(props) { + const a = compute(props.a); + const b = compute(props.b); + if (props.c) { + foo(a, b); + } + return ; +} + + +Output: +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "compute", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [], + "body": { + "type": "BlockStatement", + "body": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "foo", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [], + "body": { + "type": "BlockStatement", + "body": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "Foo", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [], + "body": { + "type": "BlockStatement", + "body": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "Component", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [ + { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "a", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "compute", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [ + { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "a", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "b", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "compute", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [ + { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "b", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "IfStatement", + "test": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "c", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "consequent": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "foo", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [ + { + "type": "Identifier", + "name": "a", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "Identifier", + "name": "b", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "alternate": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ReturnStatement", + "argument": { + "type": "JSXElement", + "openingElement": { + "type": "JSXOpeningElement", + "name": { + "type": "JSXIdentifier", + "name": "Foo", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "attributes": [ + { + "type": "JSXAttribute", + "name": { + "type": "JSXIdentifier", + "name": "a", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "value": { + "type": "JSXExpressionContainer", + "expression": { + "type": "Identifier", + "name": "a", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "JSXAttribute", + "name": { + "type": "JSXIdentifier", + "name": "b", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "value": { + "type": "JSXExpressionContainer", + "expression": { + "type": "Identifier", + "name": "b", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "selfClosing": true, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "children": [], + "closingElement": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "sourceType": "script", + "loc": null, + "range": { + "start": 0, + "end": 1 + } +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@interdependent.js.snap b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@interdependent.js.snap new file mode 100644 index 0000000000..56f6448243 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@interdependent.js.snap @@ -0,0 +1,504 @@ +--- +source: crates/forget_hermes_parser/tests/parser_test.rs +expression: "format!(\"Input:\\n{input}\\n\\nOutput:\\n{output}\")" +input_file: crates/forget_hermes_parser/tests/fixtures/interdependent.js +--- +Input: +/** + * Should produce 1 scope: + * + * return: inputs=props.a & props.b; outputs=return + * const a = compute(props.a); + * const b = compute(props.b); + * foo(a, b); + * return = + */ +function Component(props) { + const a = compute(props.a); + const b = compute(props.b); + foo(a, b); + return ; +} + +function compute() {} +function foo() {} +function Foo() {} + + +Output: +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "Component", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [ + { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "a", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "compute", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [ + { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "a", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "b", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "compute", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [ + { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "b", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "foo", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [ + { + "type": "Identifier", + "name": "a", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "Identifier", + "name": "b", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ReturnStatement", + "argument": { + "type": "JSXElement", + "openingElement": { + "type": "JSXOpeningElement", + "name": { + "type": "JSXIdentifier", + "name": "Foo", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "attributes": [ + { + "type": "JSXAttribute", + "name": { + "type": "JSXIdentifier", + "name": "a", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "value": { + "type": "JSXExpressionContainer", + "expression": { + "type": "Identifier", + "name": "a", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "JSXAttribute", + "name": { + "type": "JSXIdentifier", + "name": "b", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "value": { + "type": "JSXExpressionContainer", + "expression": { + "type": "Identifier", + "name": "b", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "selfClosing": true, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "children": [], + "closingElement": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "compute", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [], + "body": { + "type": "BlockStatement", + "body": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "foo", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [], + "body": { + "type": "BlockStatement", + "body": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "Foo", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [], + "body": { + "type": "BlockStatement", + "body": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "sourceType": "script", + "loc": null, + "range": { + "start": 0, + "end": 1 + } +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@inverted-if-else.js.snap b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@inverted-if-else.js.snap new file mode 100644 index 0000000000..e02d001cf1 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@inverted-if-else.js.snap @@ -0,0 +1,304 @@ +--- +source: crates/forget_hermes_parser/tests/parser_test.rs +expression: "format!(\"Input:\\n{input}\\n\\nOutput:\\n{output}\")" +input_file: crates/forget_hermes_parser/tests/fixtures/inverted-if-else.js +--- +Input: +function foo(a, b, c) { + let x = null; + label: { + if (a) { + x = b; + break label; + } + x = c; + } + return x; +} + + +Output: +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "foo", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [ + { + "type": "Identifier", + "name": "a", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "Identifier", + "name": "b", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "Identifier", + "name": "c", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "VariableDeclaration", + "kind": "let", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "NullLiteral", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "LabeledStatement", + "label": { + "type": "Identifier", + "name": "label", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "IfStatement", + "test": { + "type": "Identifier", + "name": "a", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "consequent": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "right": { + "type": "Identifier", + "name": "b", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "BreakStatement", + "label": { + "type": "Identifier", + "name": "label", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "alternate": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "right": { + "type": "Identifier", + "name": "c", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ReturnStatement", + "argument": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "sourceType": "script", + "loc": null, + "range": { + "start": 0, + "end": 1 + } +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@inverted-if.js.snap b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@inverted-if.js.snap new file mode 100644 index 0000000000..e3d3925655 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@inverted-if.js.snap @@ -0,0 +1,374 @@ +--- +source: crates/forget_hermes_parser/tests/parser_test.rs +expression: "format!(\"Input:\\n{input}\\n\\nOutput:\\n{output}\")" +input_file: crates/forget_hermes_parser/tests/fixtures/inverted-if.js +--- +Input: +function foo(a, b, c, d) { + let y = []; + label: if (a) { + if (b) { + y.push(c); + break label; + } + y.push(d); + } + return y; +} + + +Output: +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "foo", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [ + { + "type": "Identifier", + "name": "a", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "Identifier", + "name": "b", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "Identifier", + "name": "c", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "Identifier", + "name": "d", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "VariableDeclaration", + "kind": "let", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "y", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "ArrayExpression", + "elements": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "LabeledStatement", + "label": { + "type": "Identifier", + "name": "label", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "body": { + "type": "IfStatement", + "test": { + "type": "Identifier", + "name": "a", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "consequent": { + "type": "BlockStatement", + "body": [ + { + "type": "IfStatement", + "test": { + "type": "Identifier", + "name": "b", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "consequent": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "y", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "push", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [ + { + "type": "Identifier", + "name": "c", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "BreakStatement", + "label": { + "type": "Identifier", + "name": "label", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "alternate": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "y", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "push", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [ + { + "type": "Identifier", + "name": "d", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "alternate": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ReturnStatement", + "argument": { + "type": "Identifier", + "name": "y", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "sourceType": "script", + "loc": null, + "range": { + "start": 0, + "end": 1 + } +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@issue852.js.snap b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@issue852.js.snap new file mode 100644 index 0000000000..48b9336fac --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@issue852.js.snap @@ -0,0 +1,261 @@ +--- +source: crates/forget_hermes_parser/tests/parser_test.rs +expression: "format!(\"Input:\\n{input}\\n\\nOutput:\\n{output}\")" +input_file: crates/forget_hermes_parser/tests/fixtures/issue852.js +--- +Input: +function Component(c) { + let x = { c }; + mutate(x); + let a = x; + let b = a; +} + + +Output: +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "Component", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [ + { + "type": "Identifier", + "name": "c", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "VariableDeclaration", + "kind": "let", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "ObjectExpression", + "properties": [ + { + "type": "Property", + "key": { + "type": "Identifier", + "name": "c", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "value": { + "type": "Identifier", + "name": "c", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "kind": "init", + "method": false, + "shorthand": true, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "mutate", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [ + { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "VariableDeclaration", + "kind": "let", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "a", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "VariableDeclaration", + "kind": "let", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "b", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "Identifier", + "name": "a", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "sourceType": "script", + "loc": null, + "range": { + "start": 0, + "end": 1 + } +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@issue933-disjoint-set-infinite-loop.js.snap b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@issue933-disjoint-set-infinite-loop.js.snap new file mode 100644 index 0000000000..64f6a22db3 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@issue933-disjoint-set-infinite-loop.js.snap @@ -0,0 +1,315 @@ +--- +source: crates/forget_hermes_parser/tests/parser_test.rs +expression: "format!(\"Input:\\n{input}\\n\\nOutput:\\n{output}\")" +input_file: crates/forget_hermes_parser/tests/fixtures/issue933-disjoint-set-infinite-loop.js +--- +Input: +// This caused an infinite loop in the compiler +function MyApp(props) { + const y = makeObj(); + const tmp = y.a; + const tmp2 = tmp.b; + y.push(tmp2); + return y; +} + + +Output: +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "MyApp", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [ + { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "y", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "makeObj", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "tmp", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "y", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "a", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "tmp2", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "tmp", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "b", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "y", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "push", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [ + { + "type": "Identifier", + "name": "tmp2", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ReturnStatement", + "argument": { + "type": "Identifier", + "name": "y", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "sourceType": "script", + "loc": null, + "range": { + "start": 0, + "end": 1 + } +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@jsx-empty-expression.js.snap b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@jsx-empty-expression.js.snap new file mode 100644 index 0000000000..5050ae05b1 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@jsx-empty-expression.js.snap @@ -0,0 +1,222 @@ +--- +source: crates/forget_hermes_parser/tests/parser_test.rs +expression: "format!(\"Input:\\n{input}\\n\\nOutput:\\n{output}\")" +input_file: crates/forget_hermes_parser/tests/fixtures/jsx-empty-expression.js +--- +Input: +export function Component(props) { + return ( +
+ {} + {props.a} +
+ ); +} + + +Output: +{ + "type": "Program", + "body": [ + { + "type": "ExportNamedDeclaration", + "declaration": { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "Component", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [ + { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ReturnStatement", + "argument": { + "type": "JSXElement", + "openingElement": { + "type": "JSXOpeningElement", + "name": { + "type": "JSXIdentifier", + "name": "div", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "attributes": [], + "selfClosing": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "children": [ + { + "type": "JSXText", + "value": "\n ", + "raw": "\n ", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "JSXExpressionContainer", + "expression": { + "type": "JSXEmptyExpression", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "JSXText", + "value": "\n ", + "raw": "\n ", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "JSXExpressionContainer", + "expression": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "a", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "JSXText", + "value": "\n ", + "raw": "\n ", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "closingElement": { + "type": "JSXClosingElement", + "name": { + "type": "JSXIdentifier", + "name": "div", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "specifiers": [], + "source": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "sourceType": "script", + "loc": null, + "range": { + "start": 0, + "end": 1 + } +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@jsx-fragment.js.snap b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@jsx-fragment.js.snap new file mode 100644 index 0000000000..122aef4ab5 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@jsx-fragment.js.snap @@ -0,0 +1,297 @@ +--- +source: crates/forget_hermes_parser/tests/parser_test.rs +expression: "format!(\"Input:\\n{input}\\n\\nOutput:\\n{output}\")" +input_file: crates/forget_hermes_parser/tests/fixtures/jsx-fragment.js +--- +Input: +function Foo(props) { + return ( + <> + Hello {props.greeting}{" "} +
+ <>Text +
+ + ); +} + + +Output: +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "Foo", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [ + { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ReturnStatement", + "argument": { + "type": "JSXFragment", + "openingFragment": { + "type": "JSXOpeningFragment", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "children": [ + { + "type": "JSXText", + "value": "\n Hello ", + "raw": "\n Hello ", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "JSXExpressionContainer", + "expression": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "greeting", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "JSXExpressionContainer", + "expression": { + "type": "StringLiteral", + "value": " ", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "JSXText", + "value": "\n ", + "raw": "\n ", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "JSXElement", + "openingElement": { + "type": "JSXOpeningElement", + "name": { + "type": "JSXIdentifier", + "name": "div", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "attributes": [], + "selfClosing": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "children": [ + { + "type": "JSXText", + "value": "\n ", + "raw": "\n ", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "JSXFragment", + "openingFragment": { + "type": "JSXOpeningFragment", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "children": [ + { + "type": "JSXText", + "value": "Text", + "raw": "Text", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "closingFragment": { + "type": "JSXClosingFragment", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "JSXText", + "value": "\n ", + "raw": "\n ", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "closingElement": { + "type": "JSXClosingElement", + "name": { + "type": "JSXIdentifier", + "name": "div", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "JSXText", + "value": "\n ", + "raw": "\n ", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "closingFragment": { + "type": "JSXClosingFragment", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "sourceType": "script", + "loc": null, + "range": { + "start": 0, + "end": 1 + } +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@jsx-member-expression-tag-grouping.js.snap b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@jsx-member-expression-tag-grouping.js.snap new file mode 100644 index 0000000000..60838b0fca --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@jsx-member-expression-tag-grouping.js.snap @@ -0,0 +1,245 @@ +--- +source: crates/forget_hermes_parser/tests/parser_test.rs +expression: "format!(\"Input:\\n{input}\\n\\nOutput:\\n{output}\")" +input_file: crates/forget_hermes_parser/tests/fixtures/jsx-member-expression-tag-grouping.js +--- +Input: +function Component(props) { + const maybeMutable = new MaybeMutable(); + return {maybeMutate(maybeMutable)}; +} + + +Output: +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "Component", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [ + { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "maybeMutable", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "NewExpression", + "callee": { + "type": "Identifier", + "name": "MaybeMutable", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ReturnStatement", + "argument": { + "type": "JSXElement", + "openingElement": { + "type": "JSXOpeningElement", + "name": { + "type": "JSXMemberExpression", + "object": { + "type": "JSXIdentifier", + "name": "Foo", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "JSXIdentifier", + "name": "Bar", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "attributes": [], + "selfClosing": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "children": [ + { + "type": "JSXExpressionContainer", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "maybeMutate", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [ + { + "type": "Identifier", + "name": "maybeMutable", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "closingElement": { + "type": "JSXClosingElement", + "name": { + "type": "JSXMemberExpression", + "object": { + "type": "JSXIdentifier", + "name": "Foo", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "JSXIdentifier", + "name": "Bar", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "sourceType": "script", + "loc": null, + "range": { + "start": 0, + "end": 1 + } +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@jsx-member-expression.js.snap b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@jsx-member-expression.js.snap new file mode 100644 index 0000000000..b3b00c40c1 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@jsx-member-expression.js.snap @@ -0,0 +1,279 @@ +--- +source: crates/forget_hermes_parser/tests/parser_test.rs +expression: "format!(\"Input:\\n{input}\\n\\nOutput:\\n{output}\")" +input_file: crates/forget_hermes_parser/tests/fixtures/jsx-member-expression.js +--- +Input: +function Component(props) { + return ( + + + + ); +} + + +Output: +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "Component", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [ + { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ReturnStatement", + "argument": { + "type": "JSXElement", + "openingElement": { + "type": "JSXOpeningElement", + "name": { + "type": "JSXMemberExpression", + "object": { + "type": "JSXMemberExpression", + "object": { + "type": "JSXIdentifier", + "name": "Sathya", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "JSXIdentifier", + "name": "Codes", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "JSXIdentifier", + "name": "Forget", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "attributes": [], + "selfClosing": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "children": [ + { + "type": "JSXText", + "value": "\n ", + "raw": "\n ", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "JSXElement", + "openingElement": { + "type": "JSXOpeningElement", + "name": { + "type": "JSXMemberExpression", + "object": { + "type": "JSXMemberExpression", + "object": { + "type": "JSXIdentifier", + "name": "Foo", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "JSXIdentifier", + "name": "Bar", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "JSXIdentifier", + "name": "Baz", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "attributes": [], + "selfClosing": true, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "children": [], + "closingElement": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "JSXText", + "value": "\n ", + "raw": "\n ", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "closingElement": { + "type": "JSXClosingElement", + "name": { + "type": "JSXMemberExpression", + "object": { + "type": "JSXMemberExpression", + "object": { + "type": "JSXIdentifier", + "name": "Sathya", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "JSXIdentifier", + "name": "Codes", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "JSXIdentifier", + "name": "Forget", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "sourceType": "script", + "loc": null, + "range": { + "start": 0, + "end": 1 + } +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@jsx-namespaced-name.js.snap b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@jsx-namespaced-name.js.snap new file mode 100644 index 0000000000..3bb8655e98 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@jsx-namespaced-name.js.snap @@ -0,0 +1,196 @@ +--- +source: crates/forget_hermes_parser/tests/parser_test.rs +expression: "format!(\"Input:\\n{input}\\n\\nOutput:\\n{output}\")" +input_file: crates/forget_hermes_parser/tests/fixtures/jsx-namespaced-name.js +--- +Input: +function Component(props) { + return ; +} + + +Output: +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "Component", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [ + { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ReturnStatement", + "argument": { + "type": "JSXElement", + "openingElement": { + "type": "JSXOpeningElement", + "name": { + "type": "JSXNamespacedName", + "namespace": { + "type": "JSXIdentifier", + "name": "xml", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "name": { + "type": "JSXIdentifier", + "name": "http", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "attributes": [ + { + "type": "JSXAttribute", + "name": { + "type": "JSXNamespacedName", + "namespace": { + "type": "JSXIdentifier", + "name": "protocol", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "name": { + "type": "JSXIdentifier", + "name": "version", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "value": { + "type": "JSXExpressionContainer", + "expression": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "version", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "selfClosing": true, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "children": [], + "closingElement": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "sourceType": "script", + "loc": null, + "range": { + "start": 0, + "end": 1 + } +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@jsx-spread.js.snap b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@jsx-spread.js.snap new file mode 100644 index 0000000000..9632a25f0e --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@jsx-spread.js.snap @@ -0,0 +1,263 @@ +--- +source: crates/forget_hermes_parser/tests/parser_test.rs +expression: "format!(\"Input:\\n{input}\\n\\nOutput:\\n{output}\")" +input_file: crates/forget_hermes_parser/tests/fixtures/jsx-spread.js +--- +Input: +function Component(props) { + return ( + + ); +} + + +Output: +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "Component", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [ + { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ReturnStatement", + "argument": { + "type": "JSXElement", + "openingElement": { + "type": "JSXOpeningElement", + "name": { + "type": "JSXIdentifier", + "name": "Component", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "attributes": [ + { + "type": "JSXSpreadAttribute", + "argument": { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "JSXSpreadAttribute", + "argument": { + "type": "ObjectExpression", + "properties": [ + { + "type": "Property", + "key": { + "type": "Identifier", + "name": "bar", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "value": { + "type": "ConditionalExpression", + "test": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "cond", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "alternate": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "bar", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "consequent": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "foo", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "kind": "init", + "method": false, + "shorthand": false, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "selfClosing": true, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "children": [], + "closingElement": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "sourceType": "script", + "loc": null, + "range": { + "start": 0, + "end": 1 + } +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@jsx-tag-evaluation-order-non-global.js.snap b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@jsx-tag-evaluation-order-non-global.js.snap new file mode 100644 index 0000000000..266e7f43b7 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@jsx-tag-evaluation-order-non-global.js.snap @@ -0,0 +1,395 @@ +--- +source: crates/forget_hermes_parser/tests/parser_test.rs +expression: "format!(\"Input:\\n{input}\\n\\nOutput:\\n{output}\")" +input_file: crates/forget_hermes_parser/tests/fixtures/jsx-tag-evaluation-order-non-global.js +--- +Input: +function Component(props) { + const maybeMutable = new MaybeMutable(); + let Tag = props.component; + // NOTE: the order of evaluation in the lowering is incorrect: + // the jsx element's tag observes `Tag` after reassignment, but should observe + // it before the reassignment. + return ( + + {((Tag = props.alternateComponent), maybeMutate(maybeMutable))} + + + ); +} + + +Output: +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "Component", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [ + { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "maybeMutable", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "NewExpression", + "callee": { + "type": "Identifier", + "name": "MaybeMutable", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "VariableDeclaration", + "kind": "let", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "Tag", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "component", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ReturnStatement", + "argument": { + "type": "JSXElement", + "openingElement": { + "type": "JSXOpeningElement", + "name": { + "type": "JSXIdentifier", + "name": "Tag", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "attributes": [], + "selfClosing": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "children": [ + { + "type": "JSXText", + "value": "\n ", + "raw": "\n ", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "JSXExpressionContainer", + "expression": { + "type": "SequenceExpression", + "expressions": [ + { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "Identifier", + "name": "Tag", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "right": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "alternateComponent", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "maybeMutate", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [ + { + "type": "Identifier", + "name": "maybeMutable", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "JSXText", + "value": "\n ", + "raw": "\n ", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "JSXElement", + "openingElement": { + "type": "JSXOpeningElement", + "name": { + "type": "JSXIdentifier", + "name": "Tag", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "attributes": [], + "selfClosing": true, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "children": [], + "closingElement": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "JSXText", + "value": "\n ", + "raw": "\n ", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "closingElement": { + "type": "JSXClosingElement", + "name": { + "type": "JSXIdentifier", + "name": "Tag", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "sourceType": "script", + "loc": null, + "range": { + "start": 0, + "end": 1 + } +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@jsx-tag-evaluation-order.js.snap b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@jsx-tag-evaluation-order.js.snap new file mode 100644 index 0000000000..769b60da3c --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@jsx-tag-evaluation-order.js.snap @@ -0,0 +1,304 @@ +--- +source: crates/forget_hermes_parser/tests/parser_test.rs +expression: "format!(\"Input:\\n{input}\\n\\nOutput:\\n{output}\")" +input_file: crates/forget_hermes_parser/tests/fixtures/jsx-tag-evaluation-order.js +--- +Input: +function Component(props) { + let Tag = View; + return ( + + {((Tag = HScroll), props.value)} + + + ); +} + + +Output: +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "Component", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [ + { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "VariableDeclaration", + "kind": "let", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "Tag", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "Identifier", + "name": "View", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ReturnStatement", + "argument": { + "type": "JSXElement", + "openingElement": { + "type": "JSXOpeningElement", + "name": { + "type": "JSXIdentifier", + "name": "Tag", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "attributes": [], + "selfClosing": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "children": [ + { + "type": "JSXText", + "value": "\n ", + "raw": "\n ", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "JSXExpressionContainer", + "expression": { + "type": "SequenceExpression", + "expressions": [ + { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "Identifier", + "name": "Tag", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "right": { + "type": "Identifier", + "name": "HScroll", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "value", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "JSXText", + "value": "\n ", + "raw": "\n ", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "JSXElement", + "openingElement": { + "type": "JSXOpeningElement", + "name": { + "type": "JSXIdentifier", + "name": "Tag", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "attributes": [], + "selfClosing": true, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "children": [], + "closingElement": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "JSXText", + "value": "\n ", + "raw": "\n ", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "closingElement": { + "type": "JSXClosingElement", + "name": { + "type": "JSXIdentifier", + "name": "Tag", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "sourceType": "script", + "loc": null, + "range": { + "start": 0, + "end": 1 + } +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@lambda-capture-returned-alias.js.snap b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@lambda-capture-returned-alias.js.snap new file mode 100644 index 0000000000..c3e177f63d --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@lambda-capture-returned-alias.js.snap @@ -0,0 +1,510 @@ +--- +source: crates/forget_hermes_parser/tests/parser_test.rs +expression: "format!(\"Input:\\n{input}\\n\\nOutput:\\n{output}\")" +input_file: crates/forget_hermes_parser/tests/fixtures/lambda-capture-returned-alias.js +--- +Input: +// Here, element should not be memoized independently of aliasedElement, since +// it is captured by fn. +// AnalyzeFunctions currently does not find captured objects. +// - mutated context refs are declared as `Capture` effect in `FunctionExpression.deps` +// - all other context refs are left as Unknown. InferReferenceEffects currently demotes +// them to reads +function CaptureNotMutate(props) { + const idx = foo(props.x); + const element = bar(props.el); + + const fn = function () { + const arr = { element }; + return arr[idx]; + }; + const aliasedElement = fn(); + mutate(aliasedElement); + return aliasedElement; +} + + +Output: +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "CaptureNotMutate", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [ + { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "idx", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "foo", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [ + { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "element", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "bar", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [ + { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "props", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "el", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "fn", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "FunctionExpression", + "id": null, + "params": [], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "arr", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "ObjectExpression", + "properties": [ + { + "type": "Property", + "key": { + "type": "Identifier", + "name": "element", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "value": { + "type": "Identifier", + "name": "element", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "kind": "init", + "method": false, + "shorthand": true, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ReturnStatement", + "argument": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "arr", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "property": { + "type": "Identifier", + "name": "idx", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "computed": true, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "aliasedElement", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "fn", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "mutate", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [ + { + "type": "Identifier", + "name": "aliasedElement", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ReturnStatement", + "argument": { + "type": "Identifier", + "name": "aliasedElement", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "sourceType": "script", + "loc": null, + "range": { + "start": 0, + "end": 1 + } +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@lambda-mutate-shadowed-object.js.snap b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@lambda-mutate-shadowed-object.js.snap new file mode 100644 index 0000000000..cced72dd8d --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@lambda-mutate-shadowed-object.js.snap @@ -0,0 +1,294 @@ +--- +source: crates/forget_hermes_parser/tests/parser_test.rs +expression: "format!(\"Input:\\n{input}\\n\\nOutput:\\n{output}\")" +input_file: crates/forget_hermes_parser/tests/fixtures/lambda-mutate-shadowed-object.js +--- +Input: +function Component() { + const x = {}; + { + const x = []; + const fn = function () { + mutate(x); + }; + fn(); + } + return x; // should return {} +} + + +Output: +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "Component", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "ObjectExpression", + "properties": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "BlockStatement", + "body": [ + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "ArrayExpression", + "elements": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "fn", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "FunctionExpression", + "id": null, + "params": [], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "mutate", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [ + { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "fn", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ReturnStatement", + "argument": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "sourceType": "script", + "loc": null, + "range": { + "start": 0, + "end": 1 + } +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@lambda-mutated-non-reactive-to-reactive.js.snap b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@lambda-mutated-non-reactive-to-reactive.js.snap new file mode 100644 index 0000000000..b2382ab8be --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@lambda-mutated-non-reactive-to-reactive.js.snap @@ -0,0 +1,293 @@ +--- +source: crates/forget_hermes_parser/tests/parser_test.rs +expression: "format!(\"Input:\\n{input}\\n\\nOutput:\\n{output}\")" +input_file: crates/forget_hermes_parser/tests/fixtures/lambda-mutated-non-reactive-to-reactive.js +--- +Input: +function f(a) { + let x; + (() => { + x = { a }; + })(); + return
; +} + + +Output: +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "f", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [ + { + "type": "Identifier", + "name": "a", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "VariableDeclaration", + "kind": "let", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "ArrowFunctionExpression", + "id": null, + "params": [], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "right": { + "type": "ObjectExpression", + "properties": [ + { + "type": "Property", + "key": { + "type": "Identifier", + "name": "a", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "value": { + "type": "Identifier", + "name": "a", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "kind": "init", + "method": false, + "shorthand": true, + "computed": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "expression": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ReturnStatement", + "argument": { + "type": "JSXElement", + "openingElement": { + "type": "JSXOpeningElement", + "name": { + "type": "JSXIdentifier", + "name": "div", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "attributes": [ + { + "type": "JSXAttribute", + "name": { + "type": "JSXIdentifier", + "name": "x", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "value": { + "type": "JSXExpressionContainer", + "expression": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "selfClosing": true, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "children": [], + "closingElement": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "sourceType": "script", + "loc": null, + "range": { + "start": 0, + "end": 1 + } +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@lambda-mutated-ref-non-reactive.js.snap b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@lambda-mutated-ref-non-reactive.js.snap new file mode 100644 index 0000000000..701806219a --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@lambda-mutated-ref-non-reactive.js.snap @@ -0,0 +1,261 @@ +--- +source: crates/forget_hermes_parser/tests/parser_test.rs +expression: "format!(\"Input:\\n{input}\\n\\nOutput:\\n{output}\")" +input_file: crates/forget_hermes_parser/tests/fixtures/lambda-mutated-ref-non-reactive.js +--- +Input: +function f(a) { + let x; + (() => { + x = {}; + })(); + // this is not reactive on `x` as `x` is never reactive + return
; +} + + +Output: +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "f", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [ + { + "type": "Identifier", + "name": "a", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "VariableDeclaration", + "kind": "let", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "ArrowFunctionExpression", + "id": null, + "params": [], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "right": { + "type": "ObjectExpression", + "properties": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "expression": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ReturnStatement", + "argument": { + "type": "JSXElement", + "openingElement": { + "type": "JSXOpeningElement", + "name": { + "type": "JSXIdentifier", + "name": "div", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "attributes": [ + { + "type": "JSXAttribute", + "name": { + "type": "JSXIdentifier", + "name": "x", + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "value": { + "type": "JSXExpressionContainer", + "expression": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "selfClosing": true, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "children": [], + "closingElement": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "sourceType": "script", + "loc": null, + "range": { + "start": 0, + "end": 1 + } +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@lambda-reassign-primitive.js.snap b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@lambda-reassign-primitive.js.snap new file mode 100644 index 0000000000..3eacae3d64 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@lambda-reassign-primitive.js.snap @@ -0,0 +1,266 @@ +--- +source: crates/forget_hermes_parser/tests/parser_test.rs +expression: "format!(\"Input:\\n{input}\\n\\nOutput:\\n{output}\")" +input_file: crates/forget_hermes_parser/tests/fixtures/lambda-reassign-primitive.js +--- +Input: +// writing to primitives is not a 'mutate' or 'store' to context references, +// under current analysis in AnalyzeFunctions. +// $23:TFunction = Function @deps[ +// $21:TPrimitive, $22:TPrimitive]: + +function Component() { + let x = 40; + + const fn = function () { + x = x + 1; + }; + fn(); + return x; +} + + +Output: +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "Component", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "VariableDeclaration", + "kind": "let", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "NumericLiteral", + "value": 4630826316843712512, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "fn", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "FunctionExpression", + "id": null, + "params": [], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "right": { + "type": "BinaryExpression", + "left": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "operator": "+", + "right": { + "type": "NumericLiteral", + "value": 4607182418800017408, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "fn", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ReturnStatement", + "argument": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "sourceType": "script", + "loc": null, + "range": { + "start": 0, + "end": 1 + } +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@lambda-reassign-shadowed-primitive.js.snap b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@lambda-reassign-shadowed-primitive.js.snap new file mode 100644 index 0000000000..f4eedcbdd3 --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@lambda-reassign-shadowed-primitive.js.snap @@ -0,0 +1,292 @@ +--- +source: crates/forget_hermes_parser/tests/parser_test.rs +expression: "format!(\"Input:\\n{input}\\n\\nOutput:\\n{output}\")" +input_file: crates/forget_hermes_parser/tests/fixtures/lambda-reassign-shadowed-primitive.js +--- +Input: +function Component() { + const x = {}; + { + let x = 56; + const fn = function () { + x = 42; + }; + fn(); + } + return x; // should return {} +} + + +Output: +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "Component", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "params": [], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "ObjectExpression", + "properties": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "BlockStatement", + "body": [ + { + "type": "VariableDeclaration", + "kind": "let", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "NumericLiteral", + "value": 4633078116657397760, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "VariableDeclaration", + "kind": "const", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "fn", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "init": { + "type": "FunctionExpression", + "id": null, + "params": [], + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "right": { + "type": "NumericLiteral", + "value": 4631107791820423168, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "fn", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "arguments": [], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "directive": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + { + "type": "ReturnStatement", + "argument": { + "type": "Identifier", + "name": "x", + "typeAnnotation": null, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "loc": null, + "range": { + "start": 0, + "end": 1 + } + }, + "generator": false, + "async": false, + "loc": null, + "range": { + "start": 0, + "end": 1 + }, + "loc": null, + "range": { + "start": 0, + "end": 1 + } + } + ], + "sourceType": "script", + "loc": null, + "range": { + "start": 0, + "end": 1 + } +} diff --git a/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@lambda-with-fbt.js.snap b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@lambda-with-fbt.js.snap new file mode 100644 index 0000000000..7fea28fb3b --- /dev/null +++ b/compiler/forget/crates/forget_hermes_parser/tests/snapshots/parser_test__fixtures@lambda-with-fbt.js.snap @@ -0,0 +1,1130 @@ +--- +source: crates/forget_hermes_parser/tests/parser_test.rs +expression: "format!(\"Input:\\n{input}\\n\\nOutput:\\n{output}\")" +input_file: crates/forget_hermes_parser/tests/fixtures/lambda-with-fbt.js +--- +Input: +import { fbt } from "fbt"; + +function Component() { + const buttonLabel = () => { + if (!someCondition) { + return {"Purchase as a gift"}; + } else if ( + !iconOnly && + showPrice && + item?.current_gift_offer?.price?.formatted != null + ) { + return ( + + {"Gift | "} + + {item?.current_gift_offer?.price?.formatted} + + + ); + } else if (!iconOnly && !showPrice) { + return {"Gift"}; + } + }; + + return ( + +