From dfaf698f57a310d2344d2b2fbd157d066eb05f52 Mon Sep 17 00:00:00 2001 From: Mike Vitousek Date: Mon, 5 Aug 2024 14:55:01 -0700 Subject: [PATCH] tonights forecast: a freeze is coming --- compiler/out | 58802 ++++++++++++++++ .../ReactiveScopes/CodegenReactiveFunction.ts | 45 +- 2 files changed, 58842 insertions(+), 5 deletions(-) create mode 100644 compiler/out diff --git a/compiler/out b/compiler/out new file mode 100644 index 0000000000..461b92d243 --- /dev/null +++ b/compiler/out @@ -0,0 +1,58802 @@ +yarn run v1.22.22 +$ yarn workspace babel-plugin-react-compiler run snap +$ node ../snap/dist/main.js + PASS  while-with-assignment-in-test + FAIL  while-property + FAIL  while-logical + FAIL  while-conditional-continue + FAIL  while-break + FAIL  value-block-mutates-outer-value + FAIL  validate-no-set-state-in-render-unconditional-lambda-which-conditionally-sets-state-ok + FAIL  validate-no-set-state-in-render-uncalled-function-with-mutable-range-is-valid + FAIL  userspace-use-memo-cache + FAIL  useState-unpruned-dependency + FAIL  useState-pruned-dependency-change-detect + FAIL  useState-and-other-hook-unpruned-dependency + FAIL  useReducer-returned-dispatcher-is-non-reactive + FAIL  useMemo-switch-return + FAIL  useMemo-switch-no-fallthrough + FAIL  useMemo-simple + FAIL  useMemo-simple-preserved + FAIL  useMemo-simple-preserved-nomemo + FAIL  useMemo-return-empty + FAIL  useMemo-nested-ifs + PASS  useMemo-named-function + FAIL  useMemo-multiple-if-else + FAIL  useMemo-maybe-modified-later-preserve-memoization-guarantees + FAIL  useMemo-maybe-modified-later-dont-preserve-memoization-guarantees + FAIL  useMemo-mabye-modified-free-variable-preserve-memoization-guarantees + FAIL  useMemo-mabye-modified-free-variable-dont-preserve-memoization-guarantees + FAIL  useMemo-logical + FAIL  useMemo-labeled-statement-unconditional-return + FAIL  useMemo-inverted-if + FAIL  useMemo-inlining-block-return + FAIL  useMemo-independently-memoizeable + FAIL  useMemo-if-else-multiple-return + FAIL  useEffect-snap-test + FAIL  useEffect-nested-lambdas + FAIL  useEffect-namespace-pruned + FAIL  useEffect-method-call + FAIL  useEffect-global-pruned + FAIL  useEffect-external-mutate + FAIL  useEffect-arg-memoized + FAIL  useContext-read-context-in-callback + FAIL  useContext-read-context-in-callback-if-condition + FAIL  useContext-maybe-mutate-context-in-callback + FAIL  useCallback-set-ref-value-preserve-memoization + FAIL  useCallback-set-ref-value-dont-preserve-memoization + FAIL  useCallback-set-ref-nested-property + FAIL  useCallback-set-ref-nested-property-preserve-memoization + FAIL  useCallback-set-ref-nested-property-dont-preserve-memoization + FAIL  useCallback-multiple-callbacks-modifying-same-ref-preserve-memoization + FAIL  useCallback-maybe-modify-free-variable-preserve-memoization-guarantee + FAIL  useCallback-maybe-modify-free-variable-dont-preserve-memoization-guarantee + FAIL  useCallback-call-second-function-which-captures-maybe-mutable-value-preserve-memoization + FAIL  useCallback-call-second-function-which-captures-maybe-mutable-value-dont-preserve-memoization + FAIL  useActionState-dispatch-considered-as-non-reactive + FAIL  use-operator-method-call + FAIL  use-operator-conditional + FAIL  use-operator-call-expression + PASS  use-no-memo-simple + PASS  use-no-memo-module-level + PASS  use-no-forget-with-eslint-suppression + PASS  use-no-forget-multiple-with-eslint-suppression + PASS  use-no-forget-module-level + FAIL  use-memo-simple + FAIL  use-callback-simple + FAIL  update-global-in-callback + FAIL  update-expression + FAIL  update-expression-on-function-parameter-4 + FAIL  update-expression-on-function-parameter-3 + FAIL  update-expression-on-function-parameter-2 + FAIL  update-expression-on-function-parameter-1 + FAIL  update-expression-in-sequence + PASS  update-expression-constant-propagation + FAIL  unused-ternary-assigned-to-variable + FAIL  unused-optional-method-assigned-to-variable + FAIL  unused-object-element + FAIL  unused-object-element-with-rest + FAIL  unused-logical + FAIL  unused-logical-assigned-to-variable + FAIL  unused-conditional + FAIL  unused-array-rest-element + FAIL  unused-array-middle-element + FAIL  unmemoized-nonreactive-dependency-is-pruned-as-dependency + FAIL  unlabeled-break-within-label-switch + FAIL  unlabeled-break-within-label-loop + FAIL  unknown-hooks-do-not-assert + FAIL  uninitialized-declaration-in-reactive-scope + FAIL  unconditional-break-label + FAIL  unary-expr + PASS  type-test-return-type-inference + PASS  type-test-primitive + PASS  type-test-polymorphic + PASS  type-test-field-store + PASS  type-test-field-load-binary-op + PASS  type-field-load + FAIL  type-cast-expression.flow + PASS  type-binary-operator + FAIL  type-args-test-binary-operator + FAIL  type-alias.flow + PASS  type-alias-used-as-variable-annotation_.flow + PASS  type-alias-used-as-variable-annotation + PASS  type-alias-used-as-annotation_.flow + PASS  type-alias-used-as-annotation + FAIL  type-alias-declaration + FAIL  try-catch + FAIL  try-catch-within-object-method + FAIL  try-catch-within-object-method-returns-caught-value + FAIL  try-catch-within-mutable-range + FAIL  try-catch-within-function-expression + FAIL  try-catch-within-function-expression-returns-caught-value + FAIL  try-catch-with-return + FAIL  try-catch-with-catch-param + FAIL  try-catch-try-value-modified-in-catch + FAIL  try-catch-try-value-modified-in-catch-escaping + FAIL  try-catch-try-immediately-throws-after-constant-propagation + FAIL  try-catch-try-immediately-returns + FAIL  try-catch-mutate-outer-value + FAIL  try-catch-in-nested-scope + FAIL  try-catch-empty-try + FAIL  try-catch-alias-try-values + FAIL  trivial + FAIL  transitive-freeze-function-expressions + FAIL  transitive-freeze-array + PASS  transitive-alias-fields + FAIL  todo.unnecessary-lambda-memoization + PASS  todo.error.object-pattern-computed-key + FAIL  todo-function-expression-captures-value-later-frozen + FAIL  timers + FAIL  ternary-expression + FAIL  ternary-assignment-expression + FAIL  temporary-property-load-accessed-outside-scope + FAIL  temporary-at-start-of-value-block + FAIL  temporary-accessed-outside-scope + FAIL  template-literal + PASS  tagged-template-literal + FAIL  tagged-template-in-hook + FAIL  switch + FAIL  switch-with-only-default + FAIL  switch-with-fallthrough + FAIL  switch-non-final-default + FAIL  switch-global-propertyload-case-test + PASS  store-via-new + PASS  store-via-call + PASS  ssa-while + PASS  ssa-while-no-reassign + PASS  ssa-throw + PASS  ssa-switch + PASS  ssa-single-if + PASS  ssa-simple + PASS  ssa-simple-phi + FAIL  ssa-sibling-phis + FAIL  ssa-shadowing + PASS  ssa-return + FAIL  ssa-renaming + FAIL  ssa-renaming-with-mutation + FAIL  ssa-renaming-via-destructuring + FAIL  ssa-renaming-via-destructuring-with-mutation + FAIL  ssa-renaming-unconditional-with-mutation + FAIL  ssa-renaming-unconditional-ternary + FAIL  ssa-renaming-unconditional-ternary-with-mutation + FAIL  ssa-renaming-ternary + FAIL  ssa-renaming-ternary-with-mutation + FAIL  ssa-renaming-ternary-destruction + FAIL  ssa-renaming-ternary-destruction-with-mutation + FAIL  ssa-reassign + PASS  ssa-reassign-in-rval + PASS  ssa-property + PASS  ssa-property-mutate + PASS  ssa-property-mutate-alias + PASS  ssa-property-mutate-2 + PASS  ssa-property-call + PASS  ssa-property-alias-mutate + FAIL  ssa-property-alias-mutate-inside-if + FAIL  ssa-property-alias-mutate-if + FAIL  ssa-property-alias-if + FAIL  ssa-property-alias-alias-mutate-if + FAIL  ssa-objectexpression + PASS  ssa-objectexpression-phi + FAIL  ssa-non-empty-initializer + FAIL  ssa-newexpression + FAIL  ssa-nested-partial-reassignment + FAIL  ssa-nested-partial-phi + FAIL  ssa-nested-loops-no-reassign + FAIL  ssa-multiple-phis + FAIL  ssa-leave-case + PASS  ssa-if-else + PASS  ssa-for + PASS  ssa-for-trivial-update + FAIL  ssa-for-of + PASS  ssa-complex-single-if + PASS  ssa-complex-multiple-if + FAIL  ssa-cascading-eliminated-phis + FAIL  ssa-call-jsx + FAIL  ssa-call-jsx-2 + FAIL  ssa-arrayexpression + PASS  skip-useMemoCache + FAIL  simple + FAIL  simple-scope + PASS  simple-function-1 + PASS  simple-alias + PASS  should-bailout-without-compilation-infer-mode + PASS  should-bailout-without-compilation-annotation-mode + PASS  sequentially-constant-progagatable-if-test-conditions + FAIL  sequential-destructuring-both-mixed-local-and-scope-declaration + FAIL  sequential-destructuring-assignment-to-scope-declarations + FAIL  sequence-expression + FAIL  same-variable-as-dep-and-redeclare + FAIL  same-variable-as-dep-and-redeclare-maybe-frozen + PASS  rewrite-phis-in-lambda-capture-context + FAIL  reverse-postorder + FAIL  return-undefined + FAIL  return-conditional + FAIL  rest-param-with-object-spread-pattern + FAIL  rest-param-with-identifier + FAIL  rest-param-with-array-pattern + FAIL  resolve-react-hooks-based-on-import-name + FAIL  repro + FAIL  repro-unreachable-code-early-return-in-useMemo + FAIL  repro-unmerged-fbt-call-merge-overlapping-reactive-scopes + FAIL  repro-undefined-expression-of-jsxexpressioncontainer + FAIL  repro-slow-validate-preserve-memo + FAIL  repro-separate-scopes-for-divs + FAIL  repro-scope-missing-mutable-range + PASS  repro-retain-source-when-bailout + FAIL  repro-renaming-conflicting-decls + FAIL  repro-ref-mutable-range + FAIL  repro-reassign-to-variable-without-mutable-range + PASS  repro-preds-undefined-try-catch-return-primitive + FAIL  repro-object-pattern + PASS  repro-non-identifier-object-keys + FAIL  repro-no-value-for-temporary + FAIL  repro-no-value-for-temporary-reactive-scope-with-early-return + PASS  repro-no-gating-import-without-compiled-functions + FAIL  repro-no-declarations-in-reactive-scope-with-early-return + FAIL  repro-mutable-range-extending-into-ternary + FAIL  repro-missing-dependency-if-within-while + FAIL  repro-memoize-array-with-immutable-map-after-hook + FAIL  repro-invalid-scope-merging-value-blocks + FAIL  repro-invalid-reactivity-value-block + FAIL  repro-invalid-pruned-scope-leaks-value + FAIL  repro-invalid-pruned-scope-leaks-value-via-alias + FAIL  repro-instruction-part-of-already-closed-scope + FAIL  repro-independently-memoized-property-load-for-method-call + FAIL  repro-hoisting + FAIL  repro-hoisting-variable-collision + FAIL  repro-duplicate-type-import + FAIL  repro-duplicate-instruction-from-merge-consecutive-scopes + FAIL  repro-duplicate-import-specifier + FAIL  repro-dont-memoize-array-with-mutable-map-after-hook + FAIL  repro-dont-memoize-array-with-capturing-map-after-hook + FAIL  repro-dce-circular-reference + FAIL  repro-allocating-ternary-test-instruction-scope + FAIL  reordering-across-blocks + FAIL  renaming-jsx-tag-lowercase + FAIL  rename-source-variables + FAIL  rename-source-variables-nested-object-method + FAIL  rename-source-variables-nested-function + FAIL  regexp-literal + FAIL  ref-parameter-mutate-in-effect + FAIL  ref-like-name-in-useCallback + FAIL  ref-like-name-in-useCallback-2 + FAIL  ref-like-name-in-effect + FAIL  ref-in-effect + FAIL  ref-current-write-not-added-to-dep + FAIL  ref-current-optional-field-no-added-to-dep + FAIL  ref-current-not-added-to-dep + FAIL  ref-current-not-added-to-dep-2 + FAIL  ref-current-field-write-not-added-to-dep + FAIL  ref-current-field-not-added-to-dep + FAIL  ref-current-aliased-not-added-to-dep-2 + FAIL  ref-current-aliased-no-added-to-dep + FAIL  reduce-reactive-cond-deps-return-in-scope + FAIL  reduce-reactive-cond-deps-cfg-nested-testifelse + FAIL  reduce-reactive-cond-deps-break-in-scope + FAIL  recursive-function + FAIL  reassignment + FAIL  reassignment-separate-scopes + FAIL  reassignment-conditional + FAIL  reassigned-phi-in-returned-function-expression + FAIL  reassign-primitive-in-context + FAIL  reassign-object-in-context + PASS  reassign-in-while-loop-condition + PASS  reassign-global-return + FAIL  reassign-global-hook-arg + FAIL  reanimated-no-memo-arg + FAIL  readonly-object-method-calls + FAIL  readonly-object-method-calls-mutable-lambda + FAIL  reactivity-via-readonly-alias-of-mutable-value + FAIL  reactivity-via-aliased-mutation-through-property-load + FAIL  reactivity-via-aliased-mutation-lambda + FAIL  reactivity-via-aliased-mutation-array + FAIL  reactivity-analysis-reactive-via-mutation-of-property-load + FAIL  reactivity-analysis-reactive-via-mutation-of-computed-load + FAIL  reactivity-analysis-interleaved-reactivity + FAIL  reactive-scopes + FAIL  reactive-scopes-if + PASS  reactive-scope-grouping + FAIL  reactive-dependency-object-captured-with-reactive-mutated + FAIL  reactive-dependency-nonreactive-captured-with-reactive + FAIL  reactive-dependency-fixpoint + FAIL  reactive-dependencies-non-optional-properties-inside-optional-chain + FAIL  reactive-control-dependency-while-test + FAIL  reactive-control-dependency-via-mutation-switch + FAIL  reactive-control-dependency-via-mutation-if + FAIL  reactive-control-dependency-switch-condition + FAIL  reactive-control-dependency-switch-case-test + FAIL  reactive-control-dependency-reactive-after-fixpoint + FAIL  reactive-control-dependency-phi-setState-type + FAIL  reactive-control-dependency-on-context-variable + FAIL  reactive-control-dependency-if + FAIL  reactive-control-dependency-from-interleaved-reactivity-while + FAIL  reactive-control-dependency-from-interleaved-reactivity-switch + FAIL  reactive-control-dependency-from-interleaved-reactivity-if + FAIL  reactive-control-dependency-from-interleaved-reactivity-for-update + FAIL  reactive-control-dependency-from-interleaved-reactivity-for-test + FAIL  reactive-control-dependency-from-interleaved-reactivity-for-of + FAIL  reactive-control-dependency-from-interleaved-reactivity-for-init + FAIL  reactive-control-dependency-from-interleaved-reactivity-for-in + FAIL  reactive-control-dependency-from-interleaved-reactivity-do-while + FAIL  reactive-control-dependency-forof-collection + FAIL  reactive-control-dependency-forin-collection + FAIL  reactive-control-dependency-for-update + FAIL  reactive-control-dependency-for-test + FAIL  reactive-control-dependency-for-init + FAIL  reactive-control-dependency-do-while-test + FAIL  reactive-control-dependency-do-while-indirect + FAIL  react-namespace + FAIL  quoted-strings-jsx-attribute-escaped-constant-propagation + FAIL  quoted-strings-in-jsx-attribute + FAIL  quoted-strings-in-jsx-attribute-escaped + FAIL  prune-scopes-whose-deps-may-invalidate-array + FAIL  prune-scopes-whose-deps-invalidate-object + FAIL  prune-scopes-whose-deps-invalidate-new + FAIL  prune-scopes-whose-deps-invalidate-jsx + FAIL  prune-scopes-whose-deps-invalidate-array + FAIL  property-call-spread + PASS  property-call-evaluation-order + FAIL  property-assignment + FAIL  prop-capturing-function-1 + FAIL  primitive-reassigned-loop-force-scopes-enabled + FAIL  primitive-as-dep + FAIL  primitive-as-dep-nested-scope + FAIL  primitive-alias-mutate + PASS  preserve-jsxtext-stringliteral-distinction + FAIL  phi-type-inference-property-store + FAIL  phi-type-inference-array-push + FAIL  phi-reference-effects + FAIL  partial-early-return-within-reactive-scope + FAIL  overlapping-scopes-within-block + FAIL  overlapping-scopes-while + FAIL  overlapping-scopes-shadowing-within-block + FAIL  overlapping-scopes-shadowed + FAIL  overlapping-scopes-interleaved + FAIL  overlapping-scopes-interleaved-by-terminal + FAIL  outlining-in-react-memo + FAIL  outlining-in-func-expr + FAIL  outlined-helper + FAIL  outlined-destructured-params + FAIL  optional-receiver-optional-method + FAIL  optional-receiver-method-call + FAIL  optional-method-call + FAIL  optional-member-expression + FAIL  optional-member-expression-with-optional-member-expr-as-property + FAIL  optional-member-expression-chain + FAIL  optional-member-expression-call-as-property + FAIL  optional-computed-member-expression + FAIL  optional-computed-load-static + FAIL  optional-call + FAIL  optional-call-with-optional-property-load + FAIL  optional-call-with-independently-memoizable-arg + FAIL  optional-call-simple + FAIL  optional-call-logical + FAIL  optional-call-chained + FAIL  option-enable-change-variable-codegen + FAIL  object-shorthand-method-nested + FAIL  object-shorthand-method-2 + FAIL  object-shorthand-method-1 + FAIL  object-properties + FAIL  object-pattern-params + FAIL  object-mutated-in-consequent-alternate-both-return + PASS  object-method-shorthand + FAIL  object-method-shorthand-mutated-after + FAIL  object-method-shorthand-hook-dep + FAIL  object-method-shorthand-derived-value + FAIL  object-method-shorthand-aliased-mutate-after + FAIL  object-method-shorthand-3 + FAIL  object-method-maybe-alias + FAIL  object-literal-spread-element + FAIL  object-literal-method-in-ternary-test + FAIL  object-literal-method-in-ternary-consequent + FAIL  object-literal-method-derived-in-ternary-consequent + FAIL  object-literal-method-call-in-ternary-test + FAIL  object-expression-string-literal-key + FAIL  object-expression-computed-key + FAIL  object-expression-computed-key-object-mutated-later + FAIL  object-expression-computed-key-non-reactive + FAIL  object-expression-computed-key-constant-string + FAIL  object-expression-computed-key-constant-number + FAIL  object-computed-access-assignment + FAIL  obj-mutated-after-nested-if-else-with-alias + FAIL  obj-mutated-after-if-else + FAIL  obj-mutated-after-if-else-with-alias + FAIL  obj-literal-mutated-after-if-else + FAIL  obj-literal-cached-in-if-else + FAIL  nonreactive-noescaping-dependency-can-inline-into-consuming-scope + FAIL  nonoptional-load-from-optional-memberexpr + FAIL  nonmutating-capture-in-unsplittable-memo-block + FAIL  non-null-assertion + FAIL  noAlias-filter-on-array-prop + FAIL  no-flow-bailout-unrelated + FAIL  new-spread + FAIL  new-does-not-mutate-class + FAIL  nested-scopes-hook-call + FAIL  nested-scopes-begin-same-instr-valueblock + FAIL  nested-optional-member-expr + PASS  nested-function-with-param-as-captured-dep + FAIL  nested-function-shadowed-identifiers + FAIL  mutation-within-jsx + FAIL  mutation-within-jsx-and-break + FAIL  mutation-within-capture-and-mutablerange + FAIL  mutation-during-jsx-construction + FAIL  mutate-outer-scope-within-value-block + FAIL  mutable-liverange-loop + FAIL  mutable-lifetime-with-aliasing + FAIL  mutable-lifetime-loops + FAIL  multiple-calls-to-hoisted-callback-from-other-callback + FAIL  multi-directive + FAIL  multi-arrow-expr-gating-test + FAIL  multi-arrow-expr-export-gating-test + FAIL  multi-arrow-expr-export-default-gating-test + FAIL  module-scoped-bindings + FAIL  method-call + FAIL  method-call-fn-call + FAIL  method-call-computed + PASS  meta-property + FAIL  merged-scopes-are-valid-effect-deps + FAIL  merge-scopes-callback + FAIL  merge-nested-scopes-with-same-inputs + FAIL  merge-consecutive-scopes + FAIL  merge-consecutive-scopes-reordering + FAIL  merge-consecutive-scopes-objects + FAIL  merge-consecutive-scopes-no-deps + FAIL  merge-consecutive-scopes-deps-subset-of-decls + FAIL  merge-consecutive-nested-scopes + FAIL  memoize-value-block-value-sequence + FAIL  memoize-value-block-value-logical + FAIL  memoize-value-block-value-logical-no-sequence + FAIL  memoize-value-block-value-conditional + FAIL  memoization-comments + FAIL  mege-consecutive-scopes-dont-merge-with-different-deps + FAIL  maybe-mutate-object-in-callback + PASS  loop-unused-let + FAIL  logical-expression + FAIL  logical-expression-object + FAIL  log-pruned-memoization + PASS  lambda-return-expression + PASS  lambda-reassign-shadowed-primitive + PASS  lambda-reassign-primitive + FAIL  lambda-mutated-ref-non-reactive + FAIL  lambda-mutated-non-reactive-to-reactive + PASS  lambda-mutate-shadowed-object + FAIL  lambda-capture-returned-alias + PASS  lambda-array-access-member-expr-param + PASS  lambda-array-access-member-expr-captured + FAIL  labeled-break-within-label-switch + FAIL  labeled-break-within-label-loop + FAIL  jsx-ternary-local-variable + FAIL  jsx-tag-evaluation-order + FAIL  jsx-tag-evaluation-order-non-global + FAIL  jsx-string-attribute-non-ascii + FAIL  jsx-string-attribute-expression-container + FAIL  jsx-spread + FAIL  jsx-reactive-local-variable-member-expr + PASS  jsx-preserve-whitespace + FAIL  jsx-namespaced-name + FAIL  jsx-memberexpr-tag-in-lambda + FAIL  jsx-member-expression + FAIL  jsx-member-expression-tag-grouping + FAIL  jsx-local-tag-in-lambda + FAIL  jsx-local-memberexpr-tag + FAIL  jsx-local-memberexpr-tag-conditional + PASS  jsx-html-entity + FAIL  jsx-freeze + FAIL  jsx-fragment + FAIL  jsx-empty-expression + FAIL  jsx-attribute-with-jsx-fragment-value.flow + FAIL  jsx-attribute-with-jsx-element-value + FAIL  jsx-attribute-default-to-true + FAIL  issue933-disjoint-set-infinite-loop + FAIL  issue852 + FAIL  inverted-if + FAIL  inverted-if-else + FAIL  interdependent + FAIL  interdependent-across-if + FAIL  inner-memo-value-not-promoted-to-outer-scope-static + FAIL  inner-memo-value-not-promoted-to-outer-scope-dynamic + FAIL  infer-types-through-type-cast.flow + PASS  infer-skip-components-without-hooks-or-jsx + FAIL  infer-property-delete + FAIL  infer-phi-primitive + PASS  infer-no-component-obj-return + PASS  infer-no-component-nested-jsx + PASS  infer-no-component-annot + FAIL  infer-global-object + FAIL  infer-functions-hook-with-jsx + FAIL  infer-functions-hook-with-hook-call + FAIL  infer-functions-component-with-ref-arg + FAIL  infer-functions-component-with-jsx + FAIL  infer-functions-component-with-hook-call + FAIL  infer-function-forwardRef + FAIL  infer-function-expression-component + FAIL  infer-function-expression-React-memo-gating + FAIL  infer-function-assignment + FAIL  infer-function-React-memo + PASS  infer-dont-compile-components-with-multiple-params + FAIL  infer-computed-delete + FAIL  infer-compile-hooks-with-multiple-params + FAIL  independently-memoize-object-property + FAIL  independent + FAIL  independent-across-if + FAIL  incompatible-destructuring-kinds + FAIL  inadvertent-mutability-readonly-lambda + FAIL  inadvertent-mutability-readonly-class + FAIL  immutable-hooks + FAIL  iife-return-modified-later + FAIL  iife-return-modified-later-phi + FAIL  ignore-use-no-forget + PASS  ignore-inner-interface-types + FAIL  idx-no-outlining + FAIL  hooks-with-prefix + FAIL  hooks-with-React-namespace + FAIL  hooks-freeze-possibly-mutable-arguments + FAIL  hooks-freeze-arguments + PASS  hook-property-load-local + FAIL  hook-noAlias + FAIL  hook-inside-logical-expression + FAIL  hook-declaration-basic.flow + FAIL  hook-call + FAIL  holey-array + FAIL  holey-array-pattern-dce + FAIL  holey-array-pattern-dce-2 + FAIL  holey-array-expr + FAIL  hoisting-within-lambda + PASS  hoisting-simple-function-expression + PASS  hoisting-simple-const-declaration + PASS  hoisting-repro-variable-used-in-assignment + FAIL  hoisting-recursive-call + FAIL  hoisting-recursive-call-within-lambda + PASS  hoisting-object-method + PASS  hoisting-nested-const-declaration + FAIL  hoisting-nested-const-declaration-2 + FAIL  hoisting-nested-block-statements + FAIL  hoisting-member-expression + FAIL  hoisting-computed-member-expression + FAIL  hoisted-declaration-with-scope + FAIL  globals-dont-resolve-local-useState + FAIL  globals-String + FAIL  globals-Number + FAIL  globals-Boolean + FAIL  global-jsx-tag-lowered-between-mutations + FAIL  gating-with-hoisted-type-reference.flow + FAIL  gating-test + FAIL  gating-test-export-function + FAIL  gating-test-export-function-and-default + FAIL  gating-test-export-default-function + PASS  gating-preserves-function-properties + PASS  gating-access-function-name-in-component + FAIL  functionexpr–conditional-access + FAIL  function-param-assignment-pattern + FAIL  function-expression-with-store-to-parameter + FAIL  function-expression-prototype-call + FAIL  function-expression-prototype-call-mutating + FAIL  function-expression-maybe-mutates-hook-return-value + FAIL  function-expression-captures-value-later-frozen-jsx + FAIL  function-expr-directive + FAIL  function-declaration-simple + PASS  function-declaration-redeclare + PASS  function-declaration-reassign + FAIL  frozen-after-alias + FAIL  for-with-assignment-as-update + FAIL  for-return + PASS  for-of-simple + FAIL  for-of-nonmutating-loop-local-collection + FAIL  for-of-mutate + FAIL  for-of-mutate-item-of-local-collection + FAIL  for-of-iterator-of-immutable-collection + FAIL  for-of-immutable-collection + PASS  for-of-destructure + PASS  for-of-continue + PASS  for-of-conditional-break + FAIL  for-of-capture-item-of-local-collection-mutate-later + FAIL  for-of-capture-item-of-local-collection-mutate-later-value-initially-null + PASS  for-of-break + FAIL  for-multiple-variable-declarations-in-initializer + FAIL  for-loop-with-value-block-initializer + PASS  for-loop-let-undefined-decl + FAIL  for-logical + FAIL  for-in-statement + FAIL  for-in-statement-type-inference + FAIL  for-in-statement-empty-body + FAIL  for-in-statement-continue + FAIL  for-in-statement-break + FAIL  for-in-statement-body-always-returns + FAIL  for-empty-update + FAIL  for-empty-update-with-continue + FAIL  flatten-scopes-with-methodcall-hook + FAIL  flag-enable-emit-hook-guards + FAIL  fast-refresh-reloading + FAIL  fast-refresh-refresh-on-const-changes-dev + FAIL  fast-refresh-dont-refresh-const-changes-prod + FAIL  extend-scopes-if + PASS  expression-with-assignment + FAIL  expression-with-assignment-dynamic + FAIL  existing-variables-with-c-name + FAIL  escape-analysis-not-switch-test + FAIL  escape-analysis-not-switch-case + FAIL  escape-analysis-not-if-test + FAIL  escape-analysis-not-conditional-test + FAIL  escape-analysis-non-escaping-interleaved-primitive-dependency + FAIL  escape-analysis-non-escaping-interleaved-allocating-nested-dependency + FAIL  escape-analysis-non-escaping-interleaved-allocating-dependency + FAIL  escape-analysis-logical + FAIL  escape-analysis-jsx-child + FAIL  escape-analysis-destructured-rest-element + PASS  error.validate-mutate-ref-arg-in-render + PASS  error.validate-memoized-effect-deps-invalidated-dep-value + PASS  error.useMemo-non-literal-depslist + PASS  error.useMemo-callback-generator + PASS  error.update-global-should-bailout + PASS  error.unconditional-set-state-nested-function-expressions + PASS  error.unconditional-set-state-lambda + PASS  error.unconditional-set-state-in-render-with-loop-throw + PASS  error.unconditional-set-state-in-render-after-loop + PASS  error.unconditional-set-state-in-render-after-loop-break + PASS  error.todo.try-catch-with-throw + PASS  error.todo-useMemo-with-optional + PASS  error.todo-useCallback-set-ref-nested-property-ref-modified-later-preserve-memoization + PASS  error.todo-useCallback-accesses-ref-mutated-later-via-function-preserve-memoization + PASS  error.todo-repro-unmemoized-callback-captured-in-context-variable + PASS  error.todo-repro-named-function-with-shadowed-local-same-name + PASS  error.todo-repro-declaration-for-all-identifiers + PASS  error.todo-recursive-function-expression + PASS  error.todo-reassign-const + PASS  error.todo-optional-call-chain-in-ternary + PASS  error.todo-optional-call-chain-in-optional + PASS  error.todo-optional-call-chain-in-logical-expr + PASS  error.todo-object-expression-set-syntax + PASS  error.todo-object-expression-get-syntax + PASS  error.todo-object-expression-computed-key-mutate-key-while-constructing-object + PASS  error.todo-object-expression-computed-key-modified-during-after-construction + PASS  error.todo-object-expression-computed-key-modified-during-after-construction-sequence-expr + PASS  error.todo-new-target-meta-property + PASS  error.todo-nested-method-calls-lower-property-load-into-temporary + PASS  error.todo-logical-expression-within-try-catch + PASS  error.todo-kitchensink + PASS  error.todo-hoisting-simple-var-declaration + PASS  error.todo-hoisted-function-in-unreachable-code + PASS  error.todo-hoist-function-decls + PASS  error.todo-handle-update-context-identifiers + PASS  error.todo-function-expression-references-variable-its-assigned-to + PASS  error.todo-function-expression-references-later-variable-declaration + PASS  error.todo-for-of-loop-with-context-variable-iterator + PASS  error.todo-for-loop-with-context-variable-iterator + PASS  error.todo-for-in-loop-with-context-variable-iterator + PASS  error.todo-for-await-loops + PASS  error.store-property-in-global + PASS  error.sketchy-code-rules-of-hooks + PASS  error.sketchy-code-exhaustive-deps + PASS  error.ref-like-name-not-a-ref + PASS  error.ref-like-name-not-Ref + PASS  error.reassignment-to-global + PASS  error.reassignment-to-global-indirect + PASS  error.reassign-global-fn-arg + PASS  error.propertyload-hook + PASS  error.object-capture-global-mutation + PASS  error.not-useEffect-external-mutate + PASS  error.nomemo-and-change-detect + PASS  error.mutate-props + PASS  error.mutate-property-from-global + PASS  error.mutate-hook-argument + PASS  error.mutate-global-increment-op-invalid-react + PASS  error.mutate-function-property + PASS  error.mutate-captured-arg-separately + PASS  error.mutable-range-shared-inner-outer-function + PASS  error.modify-useReducer-state + PASS  error.modify-state + PASS  error.modify-state-2 + PASS  error.invalid-write-ref-prop-in-render + PASS  error.invalid-write-but-dont-read-ref-in-render + PASS  error.invalid-useMemo-callback-args + PASS  error.invalid-useMemo-async-callback + PASS  error.invalid-useLayoutEffect-dep-not-memoized + PASS  error.invalid-useInsertionEffect-dep-not-memoized + PASS  error.invalid-useEffect-dep-not-memoized + PASS  error.invalid-useEffect-dep-not-memoized-bc-range-overlaps-hook + PASS  error.invalid-use-ref-added-to-dep-without-type-info + PASS  error.invalid-unconditional-set-state-in-render + PASS  error.invalid-unclosed-eslint-suppression + PASS  error.invalid-ternary-with-hook-values + PASS  error.invalid-sketchy-code-use-forget + PASS  error.invalid-setState-in-useMemo + PASS  error.invalid-setState-in-useMemo-indirect-useCallback + PASS  error.invalid-set-and-read-ref-nested-property-during-render + PASS  error.invalid-set-and-read-ref-during-render + PASS  error.invalid-ref-value-as-props + PASS  error.invalid-ref-in-callback-invoked-during-render + PASS  error.invalid-reassign-local-variable-in-jsx-callback + PASS  error.invalid-reassign-local-variable-in-hook-argument + PASS  error.invalid-reassign-local-variable-in-effect + PASS  error.invalid-reassign-local-variable-in-async-callback + PASS  error.invalid-reassign-local-in-hook-return-value + PASS  error.invalid-reassign-const + PASS  error.invalid-read-ref-prop-in-render-property-load + PASS  error.invalid-read-ref-prop-in-render-destructure + PASS  error.invalid-props-mutation-in-effect-indirect + PASS  error.invalid-property-store-to-frozen-value + PASS  error.invalid-prop-mutation-indirect + PASS  error.invalid-pass-ref-to-function + PASS  error.invalid-pass-hook-as-prop + PASS  error.invalid-pass-hook-as-call-arg + PASS  error.invalid-nested-function-reassign-local-variable-in-effect + PASS  error.invalid-mutation-of-possible-props-phi-indirect + PASS  error.invalid-mutation-in-closure + PASS  error.invalid-mutate-props-via-for-of-iterator + PASS  error.invalid-mutate-props-in-effect-fixpoint + PASS  error.invalid-mutate-context + PASS  error.invalid-mutate-context-in-callback + PASS  error.invalid-mutate-after-freeze + PASS  error.invalid-mutate-after-aliased-freeze + PASS  error.invalid-global-reassignment-indirect + PASS  error.invalid-function-expression-mutates-immutable-value + PASS  error.invalid-disallow-mutating-refs-in-render-transitive + PASS  error.invalid-disallow-mutating-ref-in-render + PASS  error.invalid-destructure-to-local-global-variables + PASS  error.invalid-destructure-assignment-to-global + PASS  error.invalid-delete-property-of-frozen-value + PASS  error.invalid-delete-computed-property-of-frozen-value + PASS  error.invalid-conditional-setState-in-useMemo + PASS  error.invalid-conditional-call-non-hook-imported-as-hook + PASS  error.invalid-conditional-call-aliased-react-hook + PASS  error.invalid-conditional-call-aliased-hook-import + PASS  error.invalid-computed-store-to-frozen-value + PASS  error.invalid-assign-hook-to-local + PASS  error.invalid-array-push-frozen + PASS  error.invalid-aliased-ref-in-callback-invoked-during-render- + PASS  error.invalid-access-ref-during-render + PASS  error.invalid-ReactUseMemo-async-callback + PASS  error.hook-property-load-local-hook + PASS  error.hoisting-simple-function-declaration + PASS  error.hoisted-function-declaration + PASS  error.handle-unexpected-exception-pipeline + PASS  error.gating-use-before-decl + PASS  error.gating-hoisting + PASS  error.dont-hoist-inline-reference + PASS  error.default-param-accesses-local + PASS  error.declare-reassign-variable-in-function-declaration + PASS  error.context-variable-only-chained-assign + PASS  error.conditional-hooks-as-method-call + PASS  error.conditional-hook-unknown-hook-react-namespace + PASS  error.component-syntax-ref-gating.flow + PASS  error.codegen-error-on-conflicting-imports + PASS  error.capitalized-method-call + PASS  error.capitalized-function-call + PASS  error.capitalized-function-call-aliased + PASS  error.call-args-destructuring-asignment-complex + PASS  error.bailout-on-suppression-of-custom-rule + PASS  error.bailout-on-flow-suppression + PASS  error.assign-global-in-jsx-spread-attribute + PASS  error.assign-global-in-jsx-children + PASS  error.assign-global-in-component-tag-function + PASS  error._todo.computed-lval-in-destructure + PASS  empty-catch-statement + FAIL  early-return + FAIL  early-return-within-reactive-scope + FAIL  early-return-no-declarations-reassignments-dependencies + FAIL  early-return-nested-early-return-within-reactive-scope + FAIL  drop-methodcall-usememo + FAIL  drop-methodcall-usecallback + FAIL  dont-merge-overlapping-scopes-with-intermediate-reassignment + FAIL  dont-merge-overlapping-scopes-store-const-used-later + FAIL  dont-merge-if-dep-is-inner-declaration-of-previous-scope + FAIL  dominator + PASS  do-while-simple + FAIL  do-while-early-unconditional-break + PASS  do-while-continue + FAIL  do-while-conditional-break + FAIL  do-while-compound-test + FAIL  do-while-break + FAIL  destructuring + FAIL  destructuring-with-typecast-as-default-value.flow + FAIL  destructuring-with-conditional-as-default-value + FAIL  destructuring-same-property-identifier-names + FAIL  destructuring-property-inference + FAIL  destructuring-object-pattern-within-rest + FAIL  destructuring-object-param-default + FAIL  destructuring-object-default + FAIL  destructuring-mixed-scope-declarations-and-locals + FAIL  destructuring-mixed-scope-and-local-variables-with-default + FAIL  destructuring-default-past-end-of-array + FAIL  destructuring-default-at-explicit-undefined + FAIL  destructuring-default-at-explicit-null + FAIL  destructuring-default-at-array-hole + FAIL  destructuring-assignment + FAIL  destructuring-assignment-array-default + FAIL  destructuring-array-param-default + FAIL  destructuring-array-default + PASS  destructure-string-literal-property-key + PASS  destructure-string-literal-invalid-identifier-property-key + FAIL  destructure-param-string-literal-key + FAIL  destructure-param-string-literal-key-invalid-identifier + FAIL  destructure-object-declaration-to-context-var + FAIL  destructure-object-assignment-to-context-var + PASS  destructure-mixed-property-key-types + FAIL  destructure-in-branch-ssa + FAIL  destructure-direct-reassignment + FAIL  destructure-default-array-with-unary + FAIL  destructure-capture-global + FAIL  destructure-array-declaration-to-context-var + FAIL  destructure-array-assignment-to-context-var + FAIL  dependencies + FAIL  dependencies-outputs + FAIL  delete-property + FAIL  delete-computed-property + FAIL  default-param-with-reorderable-callback + FAIL  default-param-with-empty-callback + FAIL  default-param-calls-global-function + FAIL  default-param-array-with-unary + PASS  deeply-nested-function-expressions-with-params + FAIL  declare-reassign-variable-in-closure + FAIL  debugger + FAIL  debugger-memoized + FAIL  dce-unused-prefix-update + FAIL  dce-unused-postfix-update + FAIL  dce-unused-const + FAIL  dce-loop + FAIL  createElement-freeze + FAIL  controlled-input + FAIL  context-variable-reassigned-two-lambdas + FAIL  context-variable-reassigned-reactive-capture + FAIL  context-variable-reassigned-outside-of-lambda + FAIL  context-variable-reassigned-objectmethod + FAIL  context-variable-reactive-implicit-control-flow + FAIL  context-variable-reactive-explicit-control-flow + FAIL  context-variable-as-jsx-element-tag + FAIL  constructor + PASS  constant-propagation + PASS  constant-propagation-while + FAIL  constant-propagation-unary + PASS  constant-propagation-string-concat + FAIL  constant-propagation-phi + FAIL  constant-propagation-into-function-expressions + PASS  constant-propagation-for + FAIL  constant-propagation-bit-ops + FAIL  constant-propagate-global-phis + FAIL  constant-propagate-global-phis-constant + PASS  constant-prop-to-object-method + PASS  constant-prop-colliding-identifier + PASS  constant-prop-across-objectmethod-def + FAIL  constant-computed + FAIL  const-propagation-phi-nodes + PASS  const-propagation-into-function-expression-primitive + FAIL  const-propagation-into-function-expression-global + FAIL  console-readonly + FAIL  consecutive-use-memo + FAIL  conflicting-dollar-sign-variable + FAIL  conditional-set-state-in-render + FAIL  conditional-on-mutable + FAIL  conditional-early-return + FAIL  conditional-break-labeled + FAIL  concise-arrow-expr + FAIL  computed-store-alias + FAIL  computed-load-primitive-as-dependency + FAIL  computed-call-spread + PASS  computed-call-evaluation-order + FAIL  component + FAIL  component-inner-function-with-many-args + FAIL  component-declaration-basic.flow + FAIL  complex-while + FAIL  codegen-instrument-forget-test + FAIL  codegen-instrument-forget-gating-test + FAIL  codegen-emit-make-read-only + FAIL  codegen-emit-imports-same-source + PASS  class-component-with-render-helper + FAIL  change-detect-reassign + PASS  chained-assignment-expressions + PASS  chained-assignment-context-variable + FAIL  capturing-variable-in-nested-function + FAIL  capturing-variable-in-nested-block + FAIL  capturing-reference-changes-type + FAIL  capturing-nested-member-expr + FAIL  capturing-nested-member-expr-in-nested-func + FAIL  capturing-nested-member-call + FAIL  capturing-member-expr + FAIL  capturing-function-within-block + FAIL  capturing-function-skip-computed-path + FAIL  capturing-function-shadow-captured + FAIL  capturing-function-runs-inference + FAIL  capturing-function-renamed-ref + FAIL  capturing-function-member-expr-call + FAIL  capturing-function-member-expr-arguments + FAIL  capturing-function-decl + FAIL  capturing-function-conditional-capture-mutate + FAIL  capturing-function-capture-ref-before-rename + FAIL  capturing-function-alias-computed-load + FAIL  capturing-function-alias-computed-load-iife + FAIL  capturing-function-alias-computed-load-4 + FAIL  capturing-function-alias-computed-load-4-iife + FAIL  capturing-function-alias-computed-load-3 + FAIL  capturing-function-alias-computed-load-3-iife + FAIL  capturing-function-alias-computed-load-2 + FAIL  capturing-function-alias-computed-load-2-iife + FAIL  capturing-function-1 + FAIL  capturing-func-simple-alias + FAIL  capturing-func-simple-alias-iife + FAIL  capturing-func-mutate + FAIL  capturing-func-mutate-nested + FAIL  capturing-func-mutate-3 + FAIL  capturing-func-mutate-2 + FAIL  capturing-func-alias-receiver-mutate + FAIL  capturing-func-alias-receiver-mutate-iife + FAIL  capturing-func-alias-receiver-computed-mutate + FAIL  capturing-func-alias-receiver-computed-mutate-iife + FAIL  capturing-func-alias-mutate + FAIL  capturing-func-alias-mutate-iife + FAIL  capturing-func-alias-computed-mutate + FAIL  capturing-func-alias-computed-mutate-iife + FAIL  capturing-func-alias-captured-mutate + FAIL  capturing-func-alias-captured-mutate-iife + FAIL  capturing-func-alias-captured-mutate-arr + FAIL  capturing-func-alias-captured-mutate-arr-iife + FAIL  capturing-fun-alias-captured-mutate-arr-2 + FAIL  capturing-fun-alias-captured-mutate-arr-2-iife + FAIL  capturing-fun-alias-captured-mutate-2 + FAIL  capturing-fun-alias-captured-mutate-2-iife + FAIL  capturing-arrow-function-1 + FAIL  capture_mutate-across-fns + FAIL  capture_mutate-across-fns-iife + FAIL  capture-ref-for-later-mutation + FAIL  capture-param-mutate + FAIL  capture-indirect-mutate-alias + FAIL  capture-indirect-mutate-alias-iife + FAIL  capitalized-function-allowlist + FAIL  call + FAIL  call-with-independently-memoizable-arg + FAIL  call-spread + FAIL  call-args-destructuring-assignment + FAIL  call-args-assignment + FAIL  builtin-jsx-tag-lowered-between-mutations + FAIL  bug-invalid-hoisting-functionexpr + PASS  bug-codegen-inline-iife + FAIL  block-scoping-switch-variable-scoping + FAIL  block-scoping-switch-dead-code + FAIL  babel-existing-react-namespace-import + FAIL  babel-existing-react-kitchensink-import + FAIL  babel-existing-react-import + FAIL  await + FAIL  await-side-effecting-promise + PASS  assignment-variations + PASS  assignment-variations-complex-lvalue + PASS  assignment-variations-complex-lvalue-array + FAIL  assignment-in-nested-if + FAIL  assignment-expression-nested-path + FAIL  assignment-expression-computed + PASS  arrow-function-one-line-directive + FAIL  arrow-function-expr-gating-test + FAIL  arrow-expr-directive + FAIL  array-push-effect + FAIL  array-property-call + FAIL  array-properties + FAIL  array-pattern-params + FAIL  array-map-noAlias-escaping-function + FAIL  array-map-mutable-array-non-mutating-lambda-mutated-result + FAIL  array-map-mutable-array-mutating-lambda + FAIL  array-map-mutable-array-mutating-lambda-noAlias + FAIL  array-map-frozen-array + FAIL  array-map-frozen-array-noAlias + FAIL  array-map-captures-receiver-noAlias + FAIL  array-join + FAIL  array-expression-spread + FAIL  array-concat-should-capture + FAIL  array-at-mutate-after-capture + FAIL  array-at-effect + FAIL  array-at-closure + FAIL  array-access-assignment + FAIL  allow-ref-access-in-unused-callback-nested + FAIL  allow-ref-access-in-effect + FAIL  allow-ref-access-in-effect-indirect + FAIL  allow-reassignment-to-global-function-jsx-prop + FAIL  allow-passing-refs-as-props + FAIL  allow-mutating-ref-property-in-callback-passed-to-jsx + FAIL  allow-mutating-ref-property-in-callback-passed-to-jsx-indirect + FAIL  allow-mutating-ref-in-callback-passed-to-jsx + FAIL  allow-mutating-ref-in-callback-passed-to-jsx-indirect + FAIL  allow-mutate-global-in-effect-fixpoint + FAIL  allow-modify-global-in-callback-jsx + FAIL  allow-global-reassignment-in-effect + FAIL  allow-global-reassignment-in-effect-indirect + PASS  allow-global-mutation-unused-usecallback + FAIL  allow-global-mutation-in-effect-indirect + FAIL  allow-global-mutation-in-effect-indirect-usecallback + FAIL  allocating-primitive-as-dep + FAIL  allocating-primitive-as-dep-nested-scope + FAIL  allocating-logical-expression-instruction-scope + FAIL  align-scopes-within-nested-valueblock-in-array + PASS  align-scopes-trycatch-nested-overlapping-range + FAIL  align-scopes-reactive-scope-overlaps-try + FAIL  align-scopes-reactive-scope-overlaps-label + FAIL  align-scopes-reactive-scope-overlaps-if + FAIL  align-scopes-nested-block-structure + FAIL  align-scopes-iife-return-modified-later-logical + FAIL  align-scope-starts-within-cond + FAIL  alias-while + PASS  alias-nested-member-path + PASS  alias-nested-member-path-mutate + FAIL  alias-computed-load + PASS  alias-capture-in-method-receiver + PASS  alias-capture-in-method-receiver-and-mutate + FAIL  type-annotations/type-annotation-var-array_.flow + FAIL  type-annotations/type-annotation-var-array + FAIL  type-annotations/type-annotation-as-number_.flow + FAIL  type-annotations/type-annotation-as-number + FAIL  type-annotations/type-annotation-as-array_.flow + FAIL  type-annotations/type-annotation-as-array + FAIL  type-annotations/todo_type-annotations-props + PASS  rules-of-hooks/todo.invalid.invalid-rules-of-hooks-e69ffce323c3 + FAIL  rules-of-hooks/todo.invalid.invalid-rules-of-hooks-e675f0a672d8 + PASS  rules-of-hooks/todo.invalid.invalid-rules-of-hooks-ddeca9708b63 + FAIL  rules-of-hooks/todo.invalid.invalid-rules-of-hooks-c59788ef5676 + PASS  rules-of-hooks/todo.invalid.invalid-rules-of-hooks-acb56658fe7e + FAIL  rules-of-hooks/todo.invalid.invalid-rules-of-hooks-a63fd4f9dcc0 + PASS  rules-of-hooks/todo.invalid.invalid-rules-of-hooks-9c79feec4b9b + PASS  rules-of-hooks/todo.invalid.invalid-rules-of-hooks-99b5c750d1d1 + PASS  rules-of-hooks/todo.invalid.invalid-rules-of-hooks-8303403b8e4c + FAIL  rules-of-hooks/todo.invalid.invalid-rules-of-hooks-5a7ac9a6e8fa + PASS  rules-of-hooks/todo.invalid.invalid-rules-of-hooks-2c51251df67a + PASS  rules-of-hooks/todo.invalid.invalid-rules-of-hooks-28a7111f56a7 + PASS  rules-of-hooks/todo.invalid.invalid-rules-of-hooks-206e2811c87c + PASS  rules-of-hooks/todo.invalid.invalid-rules-of-hooks-191029ac48c8 + PASS  rules-of-hooks/todo.error.rules-of-hooks-e29c874aa913 + PASS  rules-of-hooks/todo.error.rules-of-hooks-d0935abedc42 + PASS  rules-of-hooks/todo.error.rules-of-hooks-27c18dc8dad2 + PASS  rules-of-hooks/todo.error.invalid-rules-of-hooks-a0058f0b446d + PASS  rules-of-hooks/todo.error.invalid-rules-of-hooks-8566f9a360e2 + PASS  rules-of-hooks/todo.error.invalid-rules-of-hooks-368024110a58 + FAIL  rules-of-hooks/todo.bail.rules-of-hooks-fadd52c1e460 + FAIL  rules-of-hooks/todo.bail.rules-of-hooks-e9f9bac89f8f + FAIL  rules-of-hooks/todo.bail.rules-of-hooks-e0a5db3ae21e + FAIL  rules-of-hooks/todo.bail.rules-of-hooks-6949b255e7eb + FAIL  rules-of-hooks/todo.bail.rules-of-hooks-28a78701970c + FAIL  rules-of-hooks/todo.bail.rules-of-hooks-279ac76f53af + PASS  rules-of-hooks/rules-of-hooks-fe6042f7628b + FAIL  rules-of-hooks/rules-of-hooks-eacfcaa6ef89 + FAIL  rules-of-hooks/rules-of-hooks-e66a744cffbe + PASS  rules-of-hooks/rules-of-hooks-e5dd6caf4084 + PASS  rules-of-hooks/rules-of-hooks-dfde14171fcd + PASS  rules-of-hooks/rules-of-hooks-df4d750736f3 + FAIL  rules-of-hooks/rules-of-hooks-cfdfe5572fc7 + FAIL  rules-of-hooks/rules-of-hooks-c5d1f3143c4c + FAIL  rules-of-hooks/rules-of-hooks-c1e8c7f4c191 + FAIL  rules-of-hooks/rules-of-hooks-9d7879272ff6 + FAIL  rules-of-hooks/rules-of-hooks-9a47e97b5d13 + FAIL  rules-of-hooks/rules-of-hooks-93dc5d5e538a + PASS  rules-of-hooks/rules-of-hooks-8f1c2c3f71c9 + FAIL  rules-of-hooks/rules-of-hooks-844a496db20b + PASS  rules-of-hooks/rules-of-hooks-7e52f5eec669 + FAIL  rules-of-hooks/rules-of-hooks-69521d94fa03 + PASS  rules-of-hooks/rules-of-hooks-4f6c78a14bf7 + PASS  rules-of-hooks/rules-of-hooks-485bf041f55f + PASS  rules-of-hooks/rules-of-hooks-347b0dae66f1 + PASS  rules-of-hooks/rules-of-hooks-33a6e23edac1 + FAIL  rules-of-hooks/rules-of-hooks-2e405c78cb80 + PASS  rules-of-hooks/rules-of-hooks-2bec02ac982b + FAIL  rules-of-hooks/rules-of-hooks-23dc7fffde57 + FAIL  rules-of-hooks/rules-of-hooks-1ff6c3fbbc94 + FAIL  rules-of-hooks/rules-of-hooks-0e2214abc294 + PASS  rules-of-hooks/rules-of-hooks-0592bd574811 + PASS  rules-of-hooks/error.invalid.invalid-rules-of-hooks-d952b82c2597 + PASS  rules-of-hooks/error.invalid.invalid-rules-of-hooks-d842d36db450 + PASS  rules-of-hooks/error.invalid.invalid-rules-of-hooks-76a74b4666e9 + PASS  rules-of-hooks/error.invalid.invalid-rules-of-hooks-449a37146a83 + PASS  rules-of-hooks/error.invalid.invalid-rules-of-hooks-0de1224ce64b + PASS  rules-of-hooks/error.invalid.invalid-rules-of-hooks-0a1dbff27ba0 + PASS  rules-of-hooks/error.invalid-rules-of-hooks-f69800950ff0 + PASS  rules-of-hooks/error.invalid-rules-of-hooks-f3d6c5e9c83d + PASS  rules-of-hooks/error.invalid-rules-of-hooks-ea7c2fb545a9 + PASS  rules-of-hooks/error.invalid-rules-of-hooks-d85c144bdf40 + PASS  rules-of-hooks/error.invalid-rules-of-hooks-d740d54e9c21 + PASS  rules-of-hooks/error.invalid-rules-of-hooks-c906cace44e9 + PASS  rules-of-hooks/error.invalid-rules-of-hooks-b4dcda3d60ed + PASS  rules-of-hooks/error.invalid-rules-of-hooks-9bf17c174134 + PASS  rules-of-hooks/error.invalid-rules-of-hooks-9718e30b856c + PASS  rules-of-hooks/error.invalid-rules-of-hooks-79128a755612 + PASS  rules-of-hooks/error.invalid-rules-of-hooks-49d341e5d68f + PASS  rules-of-hooks/error.invalid-rules-of-hooks-2aabd222fc6a + PASS  rules-of-hooks/error.invalid-rules-of-hooks-1b9527f967f3 + PASS  rules-of-hooks/error.invalid-hook-reassigned-in-conditional + PASS  rules-of-hooks/error.invalid-hook-optionalcall + PASS  rules-of-hooks/error.invalid-hook-optional-property + PASS  rules-of-hooks/error.invalid-hook-optional-methodcall + PASS  rules-of-hooks/error.invalid-hook-in-nested-object-method + PASS  rules-of-hooks/error.invalid-hook-in-nested-function-expression-object-expression + PASS  rules-of-hooks/error.invalid-hook-if-consequent + PASS  rules-of-hooks/error.invalid-hook-if-alternate + PASS  rules-of-hooks/error.invalid-hook-from-property-of-other-hook + PASS  rules-of-hooks/error.invalid-hook-from-hook-return + PASS  rules-of-hooks/error.invalid-hook-for + PASS  rules-of-hooks/error.invalid-hook-as-prop + PASS  rules-of-hooks/error.invalid-hook-as-conditional-test + PASS  rules-of-hooks/error.invalid-hook-after-early-return + PASS  rules-of-hooks/error.invalid-dynamic-hook-via-hooklike-local + PASS  rules-of-hooks/error.invalid-condtionally-call-hooklike-property-of-local + PASS  rules-of-hooks/error.invalid-conditionally-methodcall-hooklike-property-of-local + PASS  rules-of-hooks/error.invalid-conditionally-call-prop-named-like-hook + PASS  rules-of-hooks/error.invalid-conditionally-call-local-named-like-hook + PASS  rules-of-hooks/error.invalid-call-phi-possibly-hook + PASS  rules-of-hooks/error.bail.rules-of-hooks-8503ca76d6f8 + PASS  rules-of-hooks/error.bail.rules-of-hooks-3d692676194b + FAIL  rules-of-hooks/allow-props-named-like-hooks + FAIL  rules-of-hooks/allow-locals-named-like-hooks + FAIL  reduce-reactive-deps/uncond-subpath-order3 + FAIL  reduce-reactive-deps/uncond-subpath-order2 + FAIL  reduce-reactive-deps/uncond-subpath-order1 + FAIL  reduce-reactive-deps/uncond-overlap-direct + FAIL  reduce-reactive-deps/uncond-overlap-descendant + FAIL  reduce-reactive-deps/uncond-nonoverlap-direct + FAIL  reduce-reactive-deps/uncond-nonoverlap-descendant + FAIL  reduce-reactive-deps/superpath-order2 + FAIL  reduce-reactive-deps/superpath-order1 + FAIL  reduce-reactive-deps/subpath-order2 + FAIL  reduce-reactive-deps/subpath-order1 + FAIL  reduce-reactive-deps/reduce-if-exhaustive-poisoned-deps + FAIL  reduce-reactive-deps/promote-uncond + FAIL  reduce-reactive-deps/no-uncond + FAIL  reduce-reactive-deps/memberexpr-join-optional-chain2 + FAIL  reduce-reactive-deps/memberexpr-join-optional-chain + FAIL  reduce-reactive-deps/join-uncond-scopes-cond-deps + FAIL  reduce-reactive-deps/conditional-member-expr + FAIL  reduce-reactive-deps/cond-scope + FAIL  reduce-reactive-deps/cfg-switch-missing-default + FAIL  reduce-reactive-deps/cfg-switch-missing-case + FAIL  reduce-reactive-deps/cfg-switch-exhaustive + FAIL  reduce-reactive-deps/cfg-nested-ifelse + FAIL  reduce-reactive-deps/cfg-nested-ifelse-missing + FAIL  reduce-reactive-deps/cfg-ifelse + FAIL  reduce-reactive-deps/cfg-condexpr + FAIL  reduce-reactive-deps/jump-unpoisoned/throw-before-scope-starts + FAIL  reduce-reactive-deps/jump-unpoisoned/return-before-scope-starts + FAIL  reduce-reactive-deps/jump-unpoisoned/reduce-if-exhaustive-nonpoisoned-deps1 + FAIL  reduce-reactive-deps/jump-unpoisoned/reduce-if-exhaustive-nonpoisoned-deps + FAIL  reduce-reactive-deps/jump-unpoisoned/jump-target-within-scope-loop-break + FAIL  reduce-reactive-deps/jump-unpoisoned/jump-target-within-scope-label + FAIL  reduce-reactive-deps/jump-unpoisoned/else-branch-scope-unpoisoned + FAIL  reduce-reactive-deps/jump-poisoned/return-poisons-outer-scope + FAIL  reduce-reactive-deps/jump-poisoned/return-in-scope + FAIL  reduce-reactive-deps/jump-poisoned/reduce-if-nonexhaustive-poisoned-deps1 + FAIL  reduce-reactive-deps/jump-poisoned/reduce-if-nonexhaustive-poisoned-deps + FAIL  reduce-reactive-deps/jump-poisoned/loop-break-in-scope + FAIL  reduce-reactive-deps/jump-poisoned/break-poisons-outer-scope + FAIL  reduce-reactive-deps/jump-poisoned/break-in-scope + FAIL  preserve-memo-validation/useMemo-with-refs.flow + FAIL  preserve-memo-validation/useMemo-with-no-depslist + FAIL  preserve-memo-validation/useMemo-reordering-depslist-controlflow + FAIL  preserve-memo-validation/useMemo-reordering-depslist-assignment + FAIL  preserve-memo-validation/useMemo-invoke-prop + FAIL  preserve-memo-validation/useMemo-inner-decl + PASS  preserve-memo-validation/useMemo-infer-scope-global + FAIL  preserve-memo-validation/useMemo-infer-nonallocating + FAIL  preserve-memo-validation/useMemo-infer-more-specific + FAIL  preserve-memo-validation/useMemo-infer-fewer-deps + FAIL  preserve-memo-validation/useMemo-in-other-reactive-block + FAIL  preserve-memo-validation/useMemo-dropped-infer-always-invalidating + FAIL  preserve-memo-validation/useMemo-constant-prop + FAIL  preserve-memo-validation/useMemo-conditional-access-own-scope + FAIL  preserve-memo-validation/useMemo-conditional-access-noAlloc + FAIL  preserve-memo-validation/useMemo-conditional-access-alloc + FAIL  preserve-memo-validation/useMemo-alias-property-load-dep + FAIL  preserve-memo-validation/useCallback-with-no-depslist + FAIL  preserve-memo-validation/useCallback-reordering-depslist-assignment + FAIL  preserve-memo-validation/useCallback-reordering-deplist-controlflow + FAIL  preserve-memo-validation/useCallback-nonescaping + FAIL  preserve-memo-validation/useCallback-nonescaping-invoked-callback-escaping-return + PASS  preserve-memo-validation/useCallback-infer-scope-global + PASS  preserve-memo-validation/useCallback-infer-read-dep + FAIL  preserve-memo-validation/useCallback-infer-more-specific + FAIL  preserve-memo-validation/useCallback-infer-fewer-deps + FAIL  preserve-memo-validation/useCallback-infer-conditional-value-block + FAIL  preserve-memo-validation/useCallback-in-other-reactive-block + FAIL  preserve-memo-validation/useCallback-conditional-access-own-scope + FAIL  preserve-memo-validation/useCallback-captures-reassigned-context + FAIL  preserve-memo-validation/useCallback-captures-reassigned-context-property + FAIL  preserve-memo-validation/useCallback-alias-property-load-dep + PASS  preserve-memo-validation/todo-ensure-constant-prop-decls-get-removed + FAIL  preserve-memo-validation/maybe-invalid-useMemo-no-memoblock-sideeffect + PASS  preserve-memo-validation/error.validate-useMemo-named-function + PASS  preserve-memo-validation/error.useMemo-unrelated-mutation-in-depslist + PASS  preserve-memo-validation/error.useMemo-property-call-dep + PASS  preserve-memo-validation/error.useMemo-property-call-chained-object + PASS  preserve-memo-validation/error.useMemo-infer-less-specific-conditional-value-block + PASS  preserve-memo-validation/error.useMemo-infer-less-specific-conditional-access + PASS  preserve-memo-validation/error.useMemo-dep-not-recognized + PASS  preserve-memo-validation/error.useMemo-aliased-var + PASS  preserve-memo-validation/error.useCallback-property-call-dep + PASS  preserve-memo-validation/error.useCallback-infer-less-specific-conditional-access + PASS  preserve-memo-validation/error.useCallback-conditional-access-noAlloc + PASS  preserve-memo-validation/error.useCallback-aliased-var + PASS  preserve-memo-validation/error.todo-useCallback-captures-invalidating-value + PASS  preserve-memo-validation/error.maybe-invalid-useMemo-read-maybeRef + PASS  preserve-memo-validation/error.maybe-invalid-useCallback-read-maybeRef + PASS  preserve-memo-validation/error.invalid-useCallback-captures-reassigned-context + PASS  preserve-memo-validation/error.false-positive-useMemo-infer-mutate-deps + FAIL  original-reactive-scopes-fork/repro-allocating-ternary-test-instruction-scope + FAIL  original-reactive-scopes-fork/mutation-within-jsx + FAIL  original-reactive-scopes-fork/mutation-within-jsx-and-break + FAIL  original-reactive-scopes-fork/mutation-within-capture-and-mutablerange + FAIL  original-reactive-scopes-fork/mutate-outer-scope-within-value-block + FAIL  original-reactive-scopes-fork/invalid-align-scopes-within-nested-valueblock-in-array + FAIL  original-reactive-scopes-fork/capture-ref-for-later-mutation + FAIL  original-reactive-scopes-fork/bug-nonmutating-capture-in-unsplittable-memo-block + FAIL  original-reactive-scopes-fork/bug-hoisted-declaration-with-scope + FAIL  original-reactive-scopes-fork/allocating-logical-expression-instruction-scope + FAIL  meta-isms/repro-cx-namespace-nesting + FAIL  meta-isms/repro-cx-namespace-assigned-to-temporary + FAIL  meta-isms/repro-cx-assigned-to-temporary + FAIL  fbt/repro-macro-property-not-handled + FAIL  fbt/lambda-with-fbt + FAIL  fbt/fbtparam-with-jsx-fragment-value + FAIL  fbt/fbtparam-with-jsx-element-content + FAIL  fbt/fbtparam-text-must-use-expression-container + FAIL  fbt/fbt-whitespace-within-text + FAIL  fbt/fbt-whitespace-around-param-value + FAIL  fbt/fbt-to-string + FAIL  fbt/fbt-template-string-same-scope + FAIL  fbt/fbt-single-space-btw-param-and-text + FAIL  fbt/fbt-preserve-whitespace + FAIL  fbt/fbt-preserve-whitespace-two-subtrees + FAIL  fbt/fbt-preserve-whitespace-subtree + FAIL  fbt/fbt-preserve-jsxtext + FAIL  fbt/fbt-params + FAIL  fbt/fbt-params-complex-param-value + FAIL  fbt/fbt-param-with-unicode + FAIL  fbt/fbt-param-with-trailing-whitespace + FAIL  fbt/fbt-param-with-quotes + FAIL  fbt/fbt-param-with-newline + FAIL  fbt/fbt-param-with-leading-whitespace + FAIL  fbt/fbt-no-whitespace-btw-text-and-param + FAIL  fbt/fbt-call + FAIL  fbt/fbt-call-complex-param-value + FAIL  fbt/fbs-params + PASS  fbt/error.todo-multiple-fbt-plural + PASS  fbt/error.todo-locally-require-fbt + PASS  fbt/error.todo-fbt-unknown-enum-value + PASS  fbt/error.todo-fbt-as-local + FAIL  fbt/bug-fbt-plural-multiple-mixed-call-tag + FAIL  fbt/bug-fbt-plural-multiple-function-calls + +Failures: + +FAIL: while-property +- Expected ++ Received + + + ## Input + + ```javascript + function foo(a, b) { + let x = 0; + while (a.b.c) { + x += b; + } + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + function foo(a, b) { ++ Object.freeze(a); ++ Object.freeze(b); + let x = 0; + while (a.b.c) { + x = x + b; + } + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: while-logical +- Expected ++ Received + + + ## Input + + ```javascript + function foo(props) { + let x = 0; + while (x > props.min && x < props.max) { + x *= 2; + } + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + function foo(props) { ++ Object.freeze(props); + let x = 0; + while (x > props.min && x < props.max) { + x = x * 2; + } + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: while-conditional-continue +- Expected ++ Received + + + ## Input + + ```javascript + function foo(a, b, c, d) { + while (a) { + if (b) { + continue; + } + c(); + continue; + } + d(); + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + function foo(a, b, c, d) { ++ Object.freeze(a); ++ Object.freeze(b); ++ Object.freeze(c); ++ Object.freeze(d); + while (a) { + if (b) { + continue; + } + + c(); + } + + d(); + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: while-break +- Expected ++ Received + + + ## Input + + ```javascript + function foo(a, b) { + while (a) { + break; + } + return b; + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + function foo(a, b) { ++ Object.freeze(a); ++ Object.freeze(b); + while (a) { + break; + } + return b; + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: value-block-mutates-outer-value +- Expected ++ Received + + + ## Input + + ```javascript + import {makeArray, useHook} from 'shared-runtime'; + + /** + * Here, the cond ? [...] : defaultList value block produces two + * new values (each with its own scope): + * $0 = ["text"] + * $1 = { text: $0 } + * The same value block also mutates customList, so it must be + * merged with the scope producing customList + */ + function Foo({defaultList, cond}) { + const comparator = (a, b) => a - b; + useHook(); + const customList = makeArray(1, 5, 2); + useHook(); + const result = cond + ? [...customList.sort(comparator), {text: ['text']}] + : defaultList; + + return result; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Foo, + params: [{defaultList: [2, 4], cond: true}], + }; + + ``` + + ## Code + + ```javascript + import { makeArray, useHook } from "shared-runtime"; + + /** + * Here, the cond ? [...] : defaultList value block produces two + * new values (each with its own scope): + * $0 = ["text"] + * $1 = { text: $0 } + * The same value block also mutates customList, so it must be + * merged with the scope producing customList + */ + function Foo(t0) { ++ Object.freeze(t0); + const { defaultList, cond } = t0; + const comparator = _temp; +- useHook(); ++ (function () { ++ const $res$ = useHook(); ++ Object.freeze($res$); ++ return $res$; ++ })(); + const customList = makeArray(1, 5, 2); +- useHook(); ++ (function () { ++ const $res$ = useHook(); ++ Object.freeze($res$); ++ return $res$; ++ })(); + const result = cond + ? [...customList.sort(comparator), { text: ["text"] }] + : defaultList; + return result; + } + function _temp(a, b) { + return a - b; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Foo, + params: [{ defaultList: [2, 4], cond: true }], + }; + + ``` +  + ### Eval output + (kind: ok) [1,2,5,{"text":["text"]}] + +FAIL: validate-no-set-state-in-render-unconditional-lambda-which-conditionally-sets-state-ok +- Expected ++ Received + + + ## Input + + ```javascript + // @validateNoSetStateInRender + import {useState} from 'react'; + + function Component(props) { + const [x, setX] = useState(0); + + const foo = () => { + setX(1); + }; + + const bar = () => { + if (props.cond) { + // This call is now conditional, so this should pass validation + foo(); + } + }; + + const baz = () => { + bar(); + }; + baz(); + + return [x]; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{cond: false}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; // @validateNoSetStateInRender + import { useState } from "react"; + + function Component(props) { + const $ = _c(2); +- const [x, setX] = useState(0); ++ Object.freeze(props); ++ const [x, setX] = (function () { ++ const $res$ = useState(Object.freeze(0)); ++ Object.freeze($res$); ++ return $res$; ++ })(); + + const foo = () => { + setX(1); + }; + + const bar = () => { + if (props.cond) { + foo(); + } + }; + + const baz = () => { + bar(); + }; + + baz(); + let t0; + if ($[0] !== x) { + t0 = [x]; + $[0] = x; + $[1] = t0; + } else { + t0 = $[1]; + } + return t0; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ cond: false }], + }; + + ``` +  + ### Eval output + (kind: ok) [0] + +FAIL: validate-no-set-state-in-render-uncalled-function-with-mutable-range-is-valid +- Expected ++ Received + + + ## Input + + ```javascript + // @validateNoSetStateInRender @enableAssumeHooksFollowRulesOfReact + function Component(props) { + const logEvent = useLogging(props.appId); + const [currentStep, setCurrentStep] = useState(0); + + // onSubmit gets the same mutable range as `logEvent`, since that is called + // later. however, our validation uses direct aliasing to track function + // expressions which are invoked, and understands that this function isn't + // called during render: + const onSubmit = errorEvent => { + logEvent(errorEvent); + 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 ; + } + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; // @validateNoSetStateInRender @enableAssumeHooksFollowRulesOfReact + function Component(props) { + const $ = _c(7); +- const logEvent = useLogging(props.appId); +- const [currentStep, setCurrentStep] = useState(0); ++ Object.freeze(props); ++ const logEvent = (function () { ++ const $res$ = useLogging(Object.freeze(props.appId)); ++ Object.freeze($res$); ++ return $res$; ++ })(); ++ const [currentStep, setCurrentStep] = (function () { ++ const $res$ = useState(Object.freeze(0)); ++ Object.freeze($res$); ++ return $res$; ++ })(); + let t0; + if ($[0] !== logEvent) { + t0 = (errorEvent) => { + logEvent(errorEvent); + setCurrentStep(1); + }; + $[0] = logEvent; + $[1] = t0; + } else { + t0 = $[1]; + } + const onSubmit = t0; + switch (currentStep) { + case 0: { + let t1; + if ($[2] === Symbol.for("react.memo_cache_sentinel")) { +- t1 = ; ++ t1 = ( ++  ++ ); + $[2] = t1; + } else { + t1 = $[2]; + } + return t1; + } + case 1: { + let t1; + if ($[3] === Symbol.for("react.memo_cache_sentinel")) { + t1 = { foo: "joe" }; + $[3] = t1; + } else { + t1 = $[3]; + } + let t2; + if ($[4] !== onSubmit) { +- t2 = ; ++ t2 = ( ++  ++ ); + $[4] = onSubmit; + $[5] = t2; + } else { + t2 = $[5]; + } + return t2; + } + default: { + logEvent("Invalid step"); + let t1; + if ($[6] === Symbol.for("react.memo_cache_sentinel")) { +- t1 = ; ++ t1 = ( ++  ++ ); + $[6] = t1; + } else { + t1 = $[6]; + } + return t1; + } + } + } + + ``` +  + +FAIL: userspace-use-memo-cache +- Expected ++ Received + + + ## Input + + ```javascript + // @runtimeModule="react-forget-runtime" + function Component(props) { + const [x, setX] = useState(1); + let y; + if (props.cond) { + y = x * 2; + } + return ( + { + setX(10 * y); + }}> + ); + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [true], + isComponent: true, + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react-forget-runtime"; // @runtimeModule="react-forget-runtime" + function Component(props) { + const $ = _c(5); +- const [x, setX] = useState(1); ++ Object.freeze(props); ++ const [x, setX] = (function () { ++ const $res$ = useState(Object.freeze(1)); ++ Object.freeze($res$); ++ return $res$; ++ })(); + let y; + if ($[0] !== props.cond || $[1] !== x) { + if (props.cond) { + y = x * 2; + } + $[0] = props.cond; + $[1] = x; + $[2] = y; + } else { + y = $[2]; + } + + const t0 = y; + let t1; + if ($[3] !== t0) { + t1 = ( + { +- setX(10 * y); ++ onClick={function () { ++ const $res$ = () => { ++ setX(10 * y); ++ }; ++ Object.freeze($res$); ++ return $res$; + }} + /> + ); + $[3] = t0; + $[4] = t1; + } else { + t1 = $[4]; + } + return t1; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [true], + isComponent: true, + }; + + ``` +  + +FAIL: useState-unpruned-dependency +- Expected ++ Received + + + ## Input + + ```javascript + import {useState} from 'react'; // @enableChangeDetectionForDebugging + + function Component(props) { + const w = f(props.x); + const [x, _] = useState(w); + return ( +
 + {x} + {w} +
 + ); + } + + function f(x) { + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{x: 42}], + isComponent: true, + }; + + ``` + + ## Code + + ```javascript + import { $structuralCheck } from "react-compiler-runtime"; + import { c as _c } from "react/compiler-runtime"; + import { useState } from "react"; // @enableChangeDetectionForDebugging + + function Component(props) { + const $ = _c(5); ++ Object.freeze(props); + let t0; + { + t0 = f(props.x); + let condition = $[0] !== props.x; + if (!condition) { + let old$t0 = $[1]; + $structuralCheck(old$t0, t0, "t0", "Component", "cached", "(4:4)"); + } + $[0] = props.x; + $[1] = t0; + if (condition) { + t0 = f(props.x); + $structuralCheck($[1], t0, "t0", "Component", "recomputed", "(4:4)"); + t0 = $[1]; + } + } + const w = t0; +- const [x] = useState(w); ++ const [x] = (function () { ++ const $res$ = useState(Object.freeze(w)); ++ Object.freeze($res$); ++ return $res$; ++ })(); + let t1; + { + t1 = ( +
 + {x} + {w} +
 + ); + let condition = $[2] !== x || $[3] !== w; + if (!condition) { + let old$t1 = $[4]; + $structuralCheck(old$t1, t1, "t1", "Component", "cached", "(7:10)"); + } + $[2] = x; + $[3] = w; + $[4] = t1; + if (condition) { + t1 = ( +
 + {x} + {w} +
 + ); + $structuralCheck($[4], t1, "t1", "Component", "recomputed", "(7:10)"); + t1 = $[4]; + } + } + return t1; + } + + function f(x) { ++ Object.freeze(x); + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ x: 42 }], + isComponent: true, + }; + + ``` +  + +FAIL: useState-pruned-dependency-change-detect +- Expected ++ Received + + + ## Input + + ```javascript + // @enableChangeDetectionForDebugging + import {useState} from 'react'; + + function Component(props) { + const [x, _] = useState(f(props.x)); + return
{x}
; + } + + ``` + + ## Code + + ```javascript + import { $structuralCheck } from "react-compiler-runtime"; + import { c as _c } from "react/compiler-runtime"; // @enableChangeDetectionForDebugging + import { useState } from "react"; + + function Component(props) { + const $ = _c(3); ++ Object.freeze(props); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = f(props.x); + $[0] = t0; + } else { + t0 = $[0]; + } +- const [x] = useState(t0); ++ const [x] = (function () { ++ const $res$ = useState(Object.freeze(t0)); ++ Object.freeze($res$); ++ return $res$; ++ })(); + let t1; + { + t1 =
{x}
; + let condition = $[1] !== x; + if (!condition) { + let old$t1 = $[2]; + $structuralCheck(old$t1, t1, "t1", "Component", "cached", "(6:6)"); + } + $[1] = x; + $[2] = t1; + if (condition) { + t1 =
{x}
; + $structuralCheck($[2], t1, "t1", "Component", "recomputed", "(6:6)"); + t1 = $[2]; + } + } + return t1; + } + + ``` +  + +FAIL: useState-and-other-hook-unpruned-dependency +- Expected ++ Received + + + ## Input + + ```javascript + import {useState} from 'react'; // @enableChangeDetectionForDebugging + + function useOther(x) { + return x; + } + + function Component(props) { + const w = f(props.x); + const z = useOther(w); + const [x, _] = useState(z); + return
{x}
; + } + + function f(x) { + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{x: 42}], + isComponent: true, + }; + + ``` + + ## Code + + ```javascript + import { $structuralCheck } from "react-compiler-runtime"; + import { c as _c } from "react/compiler-runtime"; + import { useState } from "react"; // @enableChangeDetectionForDebugging + + function useOther(x) { ++ Object.freeze(x); + return x; + } + + function Component(props) { + const $ = _c(4); ++ Object.freeze(props); + let t0; + { + t0 = f(props.x); + let condition = $[0] !== props.x; + if (!condition) { + let old$t0 = $[1]; + $structuralCheck(old$t0, t0, "t0", "Component", "cached", "(8:8)"); + } + $[0] = props.x; + $[1] = t0; + if (condition) { + t0 = f(props.x); + $structuralCheck($[1], t0, "t0", "Component", "recomputed", "(8:8)"); + t0 = $[1]; + } + } + const w = t0; +- const z = useOther(w); +- const [x] = useState(z); ++ const z = (function () { ++ const $res$ = useOther(Object.freeze(w)); ++ Object.freeze($res$); ++ return $res$; ++ })(); ++ const [x] = (function () { ++ const $res$ = useState(Object.freeze(z)); ++ Object.freeze($res$); ++ return $res$; ++ })(); + let t1; + { + t1 =
{x}
; + let condition = $[2] !== x; + if (!condition) { + let old$t1 = $[3]; + $structuralCheck(old$t1, t1, "t1", "Component", "cached", "(11:11)"); + } + $[2] = x; + $[3] = t1; + if (condition) { + t1 =
{x}
; + $structuralCheck($[3], t1, "t1", "Component", "recomputed", "(11:11)"); + t1 = $[3]; + } + } + return t1; + } + + function f(x) { ++ Object.freeze(x); + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ x: 42 }], + isComponent: true, + }; + + ``` +  + +FAIL: useReducer-returned-dispatcher-is-non-reactive +- Expected ++ Received + + + ## Input + + ```javascript + import {useReducer} from 'react'; + + function f() { + const [state, dispatch] = useReducer(); + + const onClick = () => { + dispatch(); + }; + + return
; + } + + export const FIXTURE_ENTRYPOINT = { + fn: f, + params: [], + isComponent: true, + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { useReducer } from "react"; + + function f() { + const $ = _c(1); +- const [state, dispatch] = useReducer(); ++ const [state, dispatch] = (function () { ++ const $res$ = useReducer(); ++ Object.freeze($res$); ++ return $res$; ++ })(); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + const onClick = () => { + dispatch(); + }; + +- t0 =
; ++ t0 = ( ++  ++ ); + $[0] = t0; + } else { + t0 = $[0]; + } + return t0; + } + + export const FIXTURE_ENTRYPOINT = { + fn: f, + params: [], + isComponent: true, + }; + + ``` +  + ### Eval output + (kind: ok)
 + +FAIL: useMemo-switch-return +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + const x = useMemo(() => { + let y; + switch (props.switch) { + case 'foo': { + return 'foo'; + } + case 'bar': { + y = 'bar'; + break; + } + default: { + y = props.y; + } + } + return y; + }); + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + function Component(props) { ++ Object.freeze(props); + let t0; + bb0: { + let y; + bb1: switch (props.switch) { + case "foo": { + t0 = "foo"; + break bb0; + } + case "bar": { + y = "bar"; + break bb1; + } + default: { + y = props.y; + } + } + + t0 = y; + } + const x = t0; + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: useMemo-switch-no-fallthrough +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + const x = useMemo(() => { + switch (props.key) { + case 'key': { + return props.value; + } + default: { + return props.defaultValue; + } + } + }); + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + function Component(props) { ++ Object.freeze(props); + let t0; + bb0: switch (props.key) { + case "key": { + t0 = props.value; + break bb0; + } + default: { + t0 = props.defaultValue; + } + } + const x = t0; + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: useMemo-simple +- Expected ++ Received + + + ## Input + + ```javascript + function component(a) { + let x = useMemo(() => [a], [a]); + return ; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function component(a) { + const $ = _c(4); ++ Object.freeze(a); + let t0; + let t1; + if ($[0] !== a) { + t1 = [a]; + $[0] = a; + $[1] = t1; + } else { + t1 = $[1]; + } + t0 = t1; + const x = t0; + let t2; + if ($[2] !== x) { +- t2 = ; ++ t2 = ( ++  ++ ); + $[2] = x; + $[3] = t2; + } else { + t2 = $[3]; + } + return t2; + } + + ``` +  + +FAIL: useMemo-simple-preserved +- Expected ++ Received + + + ## Input + + ```javascript + // @enablePreserveExistingManualUseMemo + import {useMemo} from 'react'; + + function Component({a}) { + let x = useMemo(() => [a], []); + return
{x}
; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{a: 42}], + isComponent: true, + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; // @enablePreserveExistingManualUseMemo + import { useMemo } from "react"; + + function Component(t0) { + const $ = _c(5); ++ Object.freeze(t0); + const { a } = t0; + let t1; + if ($[0] !== a) { + t1 = () => [a]; + $[0] = a; + $[1] = t1; + } else { + t1 = $[1]; + } + let t2; + if ($[2] === Symbol.for("react.memo_cache_sentinel")) { + t2 = []; + $[2] = t2; + } else { + t2 = $[2]; + } +- const x = useMemo(t1, t2); ++ const x = (function () { ++ const $res$ = useMemo(Object.freeze(t1), Object.freeze(t2)); ++ Object.freeze($res$); ++ return $res$; ++ })(); + let t3; + if ($[3] !== x) { + t3 =
{x}
; + $[3] = x; + $[4] = t3; + } else { + t3 = $[4]; + } + return t3; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ a: 42 }], + isComponent: true, + }; + + ``` +  + ### Eval output + (kind: ok)
42
 + +FAIL: useMemo-simple-preserved-nomemo +- Expected ++ Received + + + ## Input + + ```javascript + // @disableMemoizationForDebugging + import {useMemo} from 'react'; + + function Component({a}) { + let x = useMemo(() => [a], []); + return
{x}
; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{a: 42}], + isComponent: true, + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; // @disableMemoizationForDebugging + import { useMemo } from "react"; + + function Component(t0) { + const $ = _c(5); ++ Object.freeze(t0); + const { a } = t0; + let t1; + if ($[0] !== a || true) { + t1 = () => [a]; + $[0] = a; + $[1] = t1; + } else { + t1 = $[1]; + } + let t2; + if ($[2] === Symbol.for("react.memo_cache_sentinel") || true) { + t2 = []; + $[2] = t2; + } else { + t2 = $[2]; + } +- const x = useMemo(t1, t2); ++ const x = (function () { ++ const $res$ = useMemo(Object.freeze(t1), Object.freeze(t2)); ++ Object.freeze($res$); ++ return $res$; ++ })(); + let t3; + if ($[3] !== x || true) { + t3 =
{x}
; + $[3] = x; + $[4] = t3; + } else { + t3 = $[4]; + } + return t3; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ a: 42 }], + isComponent: true, + }; + + ``` +  + ### Eval output + (kind: ok)
42
 + +FAIL: useMemo-return-empty +- Expected ++ Received + + + ## Input + + ```javascript + function component(a) { + let x = useMemo(() => { + mutate(a); + }, []); + return x; + } + + ``` + + ## Code + + ```javascript + function component(a) { ++ Object.freeze(a); + let t0; + + mutate(a); + t0 = undefined; + } + + ``` +  + +FAIL: useMemo-nested-ifs +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + const x = useMemo(() => { + if (props.cond) { + if (props.cond) { + } + } + }, [props.cond]); + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + function Component(props) { ++ Object.freeze(props); + let t0; + if (props.cond) { + if (props.cond) { + } + } + t0 = undefined; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: useMemo-multiple-if-else +- Expected ++ Received + + + ## Input + + ```javascript + import {useMemo} from 'react'; + + function Component(props) { + const x = useMemo(() => { + let y = []; + if (props.cond) { + y.push(props.a); + } + if (props.cond2) { + return y; + } + y.push(props.b); + return y; + }); + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{a: 1, b: 2, cond2: false}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { useMemo } from "react"; + + function Component(props) { + const $ = _c(3); ++ Object.freeze(props); + let t0; + bb0: { + let y; + if ($[0] !== props) { + y = []; + if (props.cond) { + y.push(props.a); + } + if (props.cond2) { + t0 = y; + break bb0; + } + + y.push(props.b); + $[0] = props; + $[1] = y; + $[2] = t0; + } else { + y = $[1]; + t0 = $[2]; + } + t0 = y; + } + const x = t0; + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ a: 1, b: 2, cond2: false }], + }; + + ``` +  + ### Eval output + (kind: ok) [2] + +FAIL: useMemo-maybe-modified-later-preserve-memoization-guarantees +- Expected ++ Received + + + ## Input + + ```javascript + // @enablePreserveExistingMemoizationGuarantees + import {useMemo} from 'react'; + import {identity, makeObject_Primitives, mutate} from 'shared-runtime'; + + function Component(props) { + const object = useMemo(() => makeObject_Primitives(), []); + identity(object); + return object; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; // @enablePreserveExistingMemoizationGuarantees + import { useMemo } from "react"; + import { identity, makeObject_Primitives, mutate } from "shared-runtime"; + + function Component(props) { + const $ = _c(1); ++ Object.freeze(props); + let t0; + let t1; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t1 = makeObject_Primitives(); + $[0] = t1; + } else { + t1 = $[0]; + } + t0 = t1; + const object = t0; + identity(object); + return object; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + }; + + ``` +  + ### Eval output + (kind: ok) {"a":0,"b":"value1","c":true} + +FAIL: useMemo-maybe-modified-later-dont-preserve-memoization-guarantees +- Expected ++ Received + + + ## Input + + ```javascript + // @enablePreserveExistingMemoizationGuarantees:false + import {useMemo} from 'react'; + import {identity, makeObject_Primitives, mutate} from 'shared-runtime'; + + function Component(props) { + const object = useMemo(() => makeObject_Primitives(), []); + identity(object); + return object; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; // @enablePreserveExistingMemoizationGuarantees:false + import { useMemo } from "react"; + import { identity, makeObject_Primitives, mutate } from "shared-runtime"; + + function Component(props) { + const $ = _c(2); ++ Object.freeze(props); + let t0; + let object; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = makeObject_Primitives(); + object = t0; + identity(object); + $[0] = object; + $[1] = t0; + } else { + object = $[0]; + t0 = $[1]; + } + return object; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + }; + + ``` +  + ### Eval output + (kind: ok) {"a":0,"b":"value1","c":true} + +FAIL: useMemo-mabye-modified-free-variable-preserve-memoization-guarantees +- Expected ++ Received + + + ## Input + + ```javascript + // @enablePreserveExistingMemoizationGuarantees + import {useMemo} from 'react'; + import {identity, makeObject_Primitives, mutate, useHook} from 'shared-runtime'; + + function Component(props) { + // With the feature enabled these variables are inferred as frozen as of + // the useMemo call + const free = makeObject_Primitives(); + const free2 = makeObject_Primitives(); + const part = free2.part; + + // Thus their mutable range ends prior to this hook call, and both the above + // values and the useMemo block value can be memoized + useHook(); + + const object = useMemo(() => { + const x = makeObject_Primitives(); + x.value = props.value; + mutate(x, free, part); + return x; + }, [props.value, free, part]); + + // These calls should be inferred as non-mutating due to the above freeze inference + identity(free); + identity(part); + + return object; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{value: 42}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; // @enablePreserveExistingMemoizationGuarantees + import { useMemo } from "react"; + import { + identity, + makeObject_Primitives, + mutate, + useHook, + } from "shared-runtime"; + + function Component(props) { + const $ = _c(4); ++ Object.freeze(props); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = makeObject_Primitives(); + $[0] = t0; + } else { + t0 = $[0]; + } + const free = t0; + let t1; + if ($[1] === Symbol.for("react.memo_cache_sentinel")) { + t1 = makeObject_Primitives(); + $[1] = t1; + } else { + t1 = $[1]; + } + const free2 = t1; + const part = free2.part; +- +- useHook(); ++ (function () { ++ const $res$ = useHook(); ++ Object.freeze($res$); ++ return $res$; ++ })(); + let t2; + let x; + if ($[2] !== props.value) { + x = makeObject_Primitives(); + x.value = props.value; + mutate(x, free, part); + $[2] = props.value; + $[3] = x; + } else { + x = $[3]; + } + t2 = x; + const object = t2; + + identity(free); + identity(part); + return object; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ value: 42 }], + }; + + ``` +  + ### Eval output + (kind: ok) {"a":0,"b":"value1","c":true,"value":42,"wat0":"joe"} + +FAIL: useMemo-mabye-modified-free-variable-dont-preserve-memoization-guarantees +- Expected ++ Received + + + ## Input + + ```javascript + // @enablePreserveExistingMemoizationGuarantees:false + import {useMemo} from 'react'; + import {identity, makeObject_Primitives, mutate, useHook} from 'shared-runtime'; + + function Component(props) { + // With the feature disabled these variables are inferred as being mutated inside the useMemo block + const free = makeObject_Primitives(); + const free2 = makeObject_Primitives(); + const part = free2.part; + + // This causes their range to extend to include this hook call, and in turn for the memoization to be pruned + useHook(); + const object = useMemo(() => { + const x = makeObject_Primitives(); + x.value = props.value; + mutate(x, free, part); + return x; + }, [props.value]); + + identity(free); + identity(part); + return object; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{value: 42}], + }; + + ``` + + ## Code + + ```javascript + // @enablePreserveExistingMemoizationGuarantees:false + import { useMemo } from "react"; + import { + identity, + makeObject_Primitives, + mutate, + useHook, + } from "shared-runtime"; + + function Component(props) { ++ Object.freeze(props); ++ + const free = makeObject_Primitives(); + const free2 = makeObject_Primitives(); + const part = free2.part; +- +- useHook(); ++ (function () { ++ const $res$ = useHook(); ++ Object.freeze($res$); ++ return $res$; ++ })(); + let t0; + + const x = makeObject_Primitives(); + x.value = props.value; + mutate(x, free, part); + t0 = x; + const object = t0; + + identity(free); + identity(part); + return object; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ value: 42 }], + }; + + ``` +  + ### Eval output + (kind: ok) {"a":0,"b":"value1","c":true,"value":42,"wat0":"joe"} + +FAIL: useMemo-logical +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + const x = useMemo(() => props.a && props.b); + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + function Component(props) { ++ Object.freeze(props); + let t0; + t0 = props.a && props.b; + const x = t0; + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: useMemo-labeled-statement-unconditional-return +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + const x = useMemo(() => { + label: { + return props.value; + } + }); + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + function Component(props) { ++ Object.freeze(props); + let t0; + + t0 = props.value; + const x = t0; + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: useMemo-inverted-if +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + const x = useMemo(() => { + label: { + if (props.cond) { + break label; + } + return props.a; + } + return props.b; + }); + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + function Component(props) { ++ Object.freeze(props); + let t0; + bb0: { + bb1: { + if (props.cond) { + break bb1; + } + + t0 = props.a; + break bb0; + } + + t0 = props.b; + } + const x = t0; + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: useMemo-inlining-block-return +- Expected ++ Received + + + ## Input + + ```javascript + function component(a, b) { + let x = useMemo(() => { + if (a) { + return {b}; + } + }, [a, b]); + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: component, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function component(a, b) { + const $ = _c(2); ++ Object.freeze(a); ++ Object.freeze(b); + let t0; + bb0: { + if (a) { + let t1; + if ($[0] !== b) { + t1 = { b }; + $[0] = b; + $[1] = t1; + } else { + t1 = $[1]; + } + t0 = t1; + break bb0; + } + t0 = undefined; + } + const x = t0; + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: component, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: useMemo-independently-memoizeable +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + const [a, b] = useMemo(() => { + const items = []; + const a = makeObject(props.a); + const b = makeObject(props.b); + return [a, b]; + }); + return [a, b]; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(10); ++ Object.freeze(props); + let t0; + let t1; + if ($[0] !== props.a) { + t1 = makeObject(props.a); + $[0] = props.a; + $[1] = t1; + } else { + t1 = $[1]; + } + const a = t1; + let t2; + if ($[2] !== props.b) { + t2 = makeObject(props.b); + $[2] = props.b; + $[3] = t2; + } else { + t2 = $[3]; + } + const b = t2; + let t3; + if ($[4] !== a || $[5] !== b) { + t3 = [a, b]; + $[4] = a; + $[5] = b; + $[6] = t3; + } else { + t3 = $[6]; + } + t0 = t3; + const [a_0, b_0] = t0; + let t4; + if ($[7] !== a_0 || $[8] !== b_0) { + t4 = [a_0, b_0]; + $[7] = a_0; + $[8] = b_0; + $[9] = t4; + } else { + t4 = $[9]; + } + return t4; + } + + ``` +  + +FAIL: useMemo-if-else-multiple-return +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + const x = useMemo(() => { + if (props.cond) { + return makeObject(props.a); + } + return makeObject(props.b); + }); + return x; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(4); ++ Object.freeze(props); + let t0; + bb0: { + if (props.cond) { + let t1; + if ($[0] !== props.a) { + t1 = makeObject(props.a); + $[0] = props.a; + $[1] = t1; + } else { + t1 = $[1]; + } + t0 = t1; + break bb0; + } + let t1; + if ($[2] !== props.b) { + t1 = makeObject(props.b); + $[2] = props.b; + $[3] = t1; + } else { + t1 = $[3]; + } + t0 = t1; + } + const x = t0; + return x; + } + + ``` +  + +FAIL: useEffect-snap-test +- Expected ++ Received + + + ## Input + + ```javascript + import {useEffect, useState} from 'react'; + + function Component() { + const [state, setState] = useState('hello'); + useEffect(() => { + setState('goodbye'); + }, []); + + return
{state}
; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { useEffect, useState } from "react"; + + function Component() { + const $ = _c(4); +- const [state, setState] = useState("hello"); ++ const [state, setState] = (function () { ++ const $res$ = useState(Object.freeze("hello")); ++ Object.freeze($res$); ++ return $res$; ++ })(); + let t0; + let t1; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = () => { + setState("goodbye"); + }; + t1 = []; + $[0] = t0; + $[1] = t1; + } else { + t0 = $[0]; + t1 = $[1]; + } +- useEffect(t0, t1); ++ (function () { ++ const $res$ = useEffect(Object.freeze(t0), Object.freeze(t1)); ++ Object.freeze($res$); ++ return $res$; ++ })(); + let t2; + if ($[2] !== state) { + t2 =
{state}
; + $[2] = state; + $[3] = t2; + } else { + t2 = $[3]; + } + return t2; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + }; + + ``` +  + ### Eval output + (kind: ok)
goodbye
 + +FAIL: useEffect-nested-lambdas +- Expected ++ Received + + + ## Input + + ```javascript + // @enableTransitivelyFreezeFunctionExpressions:false + + function Component(props) { + const item = useMutable(props.itemId); + const dispatch = useDispatch(); + useFreeze(dispatch); + + const exit = useCallback(() => { + dispatch(createExitAction()); + }, [dispatch]); + + useEffect(() => { + const cleanup = GlobalEventEmitter.addListener('onInput', () => { + if (item.value) { + exit(); + } + }); + return () => cleanup.remove(); + }, [exit, item]); + + maybeMutate(item); + + return
; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; // @enableTransitivelyFreezeFunctionExpressions:false + + function Component(props) { + const $ = _c(9); +- const item = useMutable(props.itemId); +- const dispatch = useDispatch(); +- useFreeze(dispatch); ++ Object.freeze(props); ++ const item = (function () { ++ const $res$ = useMutable(Object.freeze(props.itemId)); ++ Object.freeze($res$); ++ return $res$; ++ })(); ++ const dispatch = (function () { ++ const $res$ = useDispatch(); ++ Object.freeze($res$); ++ return $res$; ++ })(); ++ (function () { ++ const $res$ = useFreeze(Object.freeze(dispatch)); ++ Object.freeze($res$); ++ return $res$; ++ })(); + let t0; + if ($[0] !== dispatch) { + t0 = () => { + dispatch(createExitAction()); + }; + $[0] = dispatch; + $[1] = t0; + } else { + t0 = $[1]; + } + const exit = t0; + let t1; + if ($[2] !== item.value || $[3] !== exit) { + t1 = () => { + const cleanup = GlobalEventEmitter.addListener("onInput", () => { + if (item.value) { + exit(); + } + }); + return () => cleanup.remove(); + }; + $[2] = item.value; + $[3] = exit; + $[4] = t1; + } else { + t1 = $[4]; + } + let t2; + if ($[5] !== exit || $[6] !== item) { + t2 = [exit, item]; + $[5] = exit; + $[6] = item; + $[7] = t2; + } else { + t2 = $[7]; + } +- useEffect(t1, t2); ++ (function () { ++ const $res$ = useEffect(Object.freeze(t1), Object.freeze(t2)); ++ Object.freeze($res$); ++ return $res$; ++ })(); + + maybeMutate(item); + let t3; + if ($[8] === Symbol.for("react.memo_cache_sentinel")) { + t3 =
; + $[8] = t3; + } else { + t3 = $[8]; + } + return t3; + } + + ``` +  + +FAIL: useEffect-namespace-pruned +- Expected ++ Received + + + ## Input + + ```javascript + import * as React from 'react'; + + function someGlobal() {} + function useFoo() { + const fn = React.useMemo( + () => + function () { + someGlobal(); + }, + [] + ); + React.useEffect(() => { + fn(); + }, [fn]); + + return null; + } + + export const FIXTURE_ENTRYPOINT = { + fn: useFoo, + params: [], + isComponent: false, + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import * as React from "react"; + + function someGlobal() {} + function useFoo() { + const $ = _c(2); + let t0; + t0 = _temp; + const fn = t0; + let t1; + let t2; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t1 = () => { + fn(); + }; + t2 = [fn]; + $[0] = t1; + $[1] = t2; + } else { + t1 = $[0]; + t2 = $[1]; + } +- React.useEffect(t1, t2); ++ (function () { ++ const $res$ = React.useEffect(Object.freeze(t1), Object.freeze(t2)); ++ Object.freeze($res$); ++ return $res$; ++ })(); + return null; + } + function _temp() { + someGlobal(); + } + + export const FIXTURE_ENTRYPOINT = { + fn: useFoo, + params: [], + isComponent: false, + }; + + ``` +  + ### Eval output + (kind: ok) null + +FAIL: useEffect-method-call +- Expected ++ Received + + + ## Input + + ```javascript + let x = {}; + function Component() { + React.useEffect(() => { + x.foo = 1; + }); + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [], + }; + + ``` + + ## Code + + ```javascript + let x = {}; + function Component() { +- React.useEffect(_temp); ++ (function () { ++ const $res$ = React.useEffect(Object.freeze(_temp)); ++ Object.freeze($res$); ++ return $res$; ++ })(); + } + function _temp() { + x.foo = 1; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [], + }; + + ``` +  + ### Eval output + (kind: ok)  + +FAIL: useEffect-global-pruned +- Expected ++ Received + + + ## Input + + ```javascript + import {useEffect} from 'react'; + + function someGlobal() {} + function useFoo() { + const fn = React.useMemo( + () => + function () { + someGlobal(); + }, + [] + ); + useEffect(() => { + fn(); + }, [fn]); + + return null; + } + + export const FIXTURE_ENTRYPOINT = { + fn: useFoo, + params: [], + isComponent: false, + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { useEffect } from "react"; + + function someGlobal() {} + function useFoo() { + const $ = _c(2); + let t0; + t0 = _temp; + const fn = t0; + let t1; + let t2; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t1 = () => { + fn(); + }; + t2 = [fn]; + $[0] = t1; + $[1] = t2; + } else { + t1 = $[0]; + t2 = $[1]; + } +- useEffect(t1, t2); ++ (function () { ++ const $res$ = useEffect(Object.freeze(t1), Object.freeze(t2)); ++ Object.freeze($res$); ++ return $res$; ++ })(); + return null; + } + function _temp() { + someGlobal(); + } + + export const FIXTURE_ENTRYPOINT = { + fn: useFoo, + params: [], + isComponent: false, + }; + + ``` +  + ### Eval output + (kind: ok) null + +FAIL: useEffect-external-mutate +- Expected ++ Received + + + ## Input + + ```javascript + import {useEffect} from 'react'; + + let x = {a: 42}; + + function Component(props) { + useEffect(() => { + x.a = 10; + }); + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [], + }; + + ``` + + ## Code + + ```javascript + import { useEffect } from "react"; + + let x = { a: 42 }; + + function Component(props) { +- useEffect(_temp); ++ Object.freeze(props); ++ (function () { ++ const $res$ = useEffect(Object.freeze(_temp)); ++ Object.freeze($res$); ++ return $res$; ++ })(); + } + function _temp() { + x.a = 10; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [], + }; + + ``` +  + ### Eval output + (kind: ok)  + +FAIL: useEffect-arg-memoized +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + const dispatch = useDispatch(); + useFreeze(dispatch); + + // onUpdate should be memoized even though it doesn't + // flow into the return value + const onUpdate = () => { + dispatch({kind: 'update'}); + }; + + useEffect(() => { + onUpdate(); + }, [onUpdate]); + + return
; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(6); +- const dispatch = useDispatch(); +- useFreeze(dispatch); ++ Object.freeze(props); ++ const dispatch = (function () { ++ const $res$ = useDispatch(); ++ Object.freeze($res$); ++ return $res$; ++ })(); ++ (function () { ++ const $res$ = useFreeze(Object.freeze(dispatch)); ++ Object.freeze($res$); ++ return $res$; ++ })(); + let t0; + if ($[0] !== dispatch) { + t0 = () => { + dispatch({ kind: "update" }); + }; + $[0] = dispatch; + $[1] = t0; + } else { + t0 = $[1]; + } + const onUpdate = t0; + let t1; + let t2; + if ($[2] !== onUpdate) { + t1 = () => { + onUpdate(); + }; + t2 = [onUpdate]; + $[2] = onUpdate; + $[3] = t1; + $[4] = t2; + } else { + t1 = $[3]; + t2 = $[4]; + } +- useEffect(t1, t2); ++ (function () { ++ const $res$ = useEffect(Object.freeze(t1), Object.freeze(t2)); ++ Object.freeze($res$); ++ return $res$; ++ })(); + let t3; + if ($[5] === Symbol.for("react.memo_cache_sentinel")) { + t3 =
; + $[5] = t3; + } else { + t3 = $[5]; + } + return t3; + } + + ``` +  + +FAIL: useContext-read-context-in-callback +- Expected ++ Received + + + ## Input + + ```javascript + import {createContext, useContext} from 'react'; + + const FooContext = createContext({current: null}); + + function Component(props) { + const foo = useContext(FooContext); + // This function should be memoized since it is only reading the context value + const onClick = () => { + console.log(foo.current); + }; + return
{props.children}
; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{children:
Hello
}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { createContext, useContext } from "react"; + + const FooContext = createContext({ current: null }); + + function Component(props) { + const $ = _c(5); +- const foo = useContext(FooContext); ++ Object.freeze(props); ++ const foo = (function () { ++ const $res$ = useContext(Object.freeze(FooContext)); ++ Object.freeze($res$); ++ return $res$; ++ })(); + let t0; + if ($[0] !== foo.current) { + t0 = () => { + console.log(foo.current); + }; + $[0] = foo.current; + $[1] = t0; + } else { + t0 = $[1]; + } + const onClick = t0; + let t1; + if ($[2] !== onClick || $[3] !== props.children) { +- t1 =
{props.children}
; ++ t1 = ( ++  ++ {props.children} ++
 ++ ); + $[2] = onClick; + $[3] = props.children; + $[4] = t1; + } else { + t1 = $[4]; + } + return t1; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ children:
Hello
}], + }; + + ``` +  + ### Eval output + (kind: ok)
Hello
 + +FAIL: useContext-read-context-in-callback-if-condition + >> Unexpected error during test: + + +Found differences in evaluator results +Non-forget (expected): +(kind: ok)
{"value":{}}
+Forget: +(kind: ok)
{"value":"[[ function params=0 ]]"}
+ +FAIL: useContext-maybe-mutate-context-in-callback +- Expected ++ Received + + + ## Input + + ```javascript + import * as React from 'react'; + import {useContext} from 'react'; + import {mutate} from 'shared-runtime'; + + const FooContext = React.createContext({current: null}); + + function Component(props) { + const Foo = useContext(FooContext); + // This callback can be memoized because we aren't 100% positive that + // `mutate()` actually mutates, so we optimistically assume it doesn't + // Its range doesn't get entagled w the useContext call so we're able + // to create a reactive scope and memoize it. + const onClick = () => { + mutate(Foo.current); + }; + return
{props.children}
; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{children:
Hello
}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import * as React from "react"; + import { useContext } from "react"; + import { mutate } from "shared-runtime"; + + const FooContext = React.createContext({ current: null }); + + function Component(props) { + const $ = _c(5); +- const Foo = useContext(FooContext); ++ Object.freeze(props); ++ const Foo = (function () { ++ const $res$ = useContext(Object.freeze(FooContext)); ++ Object.freeze($res$); ++ return $res$; ++ })(); + let t0; + if ($[0] !== Foo.current) { + t0 = () => { + mutate(Foo.current); + }; + $[0] = Foo.current; + $[1] = t0; + } else { + t0 = $[1]; + } + const onClick = t0; + let t1; + if ($[2] !== onClick || $[3] !== props.children) { +- t1 =
{props.children}
; ++ t1 = ( ++  ++ {props.children} ++
 ++ ); + $[2] = onClick; + $[3] = props.children; + $[4] = t1; + } else { + t1 = $[4]; + } + return t1; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ children:
Hello
}], + }; + + ``` +  + ### Eval output + (kind: ok)
Hello
 + +FAIL: useCallback-set-ref-value-preserve-memoization +- Expected ++ Received + + + ## Input + + ```javascript + // @enablePreserveExistingMemoizationGuarantees + import {useCallback, useRef} from 'react'; + + function Component(props) { + const ref = useRef(null); + + const onChange = useCallback(event => { + // The ref should still be mutable here even though function deps are frozen in + // @enablePreserveExistingMemoizationGuarantees mode + ref.current = event.target.value; + }); + + return ; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; // @enablePreserveExistingMemoizationGuarantees + import { useCallback, useRef } from "react"; + + function Component(props) { + const $ = _c(3); +- const ref = useRef(null); ++ Object.freeze(props); ++ const ref = (function () { ++ const $res$ = useRef(Object.freeze(null)); ++ Object.freeze($res$); ++ return $res$; ++ })(); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = (event) => { + ref.current = event.target.value; + }; + $[0] = t0; + } else { + t0 = $[0]; + } + const onChange = t0; + let t1; + if ($[1] !== onChange) { +- t1 = ; ++ t1 = ( ++  ++ ); + $[1] = onChange; + $[2] = t1; + } else { + t1 = $[2]; + } + return t1; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + }; + + ``` +  + ### Eval output + (kind: ok)  + +FAIL: useCallback-set-ref-value-dont-preserve-memoization +- Expected ++ Received + + + ## Input + + ```javascript + // @enablePreserveExistingMemoizationGuarantees + import {useCallback, useRef} from 'react'; + + function Component(props) { + const ref = useRef(null); + + const onChange = useCallback(event => { + // The ref should still be mutable here even though function deps are frozen in + // @enablePreserveExistingMemoizationGuarantees mode + ref.current = event.target.value; + }); + + return ; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; // @enablePreserveExistingMemoizationGuarantees + import { useCallback, useRef } from "react"; + + function Component(props) { + const $ = _c(3); +- const ref = useRef(null); ++ Object.freeze(props); ++ const ref = (function () { ++ const $res$ = useRef(Object.freeze(null)); ++ Object.freeze($res$); ++ return $res$; ++ })(); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = (event) => { + ref.current = event.target.value; + }; + $[0] = t0; + } else { + t0 = $[0]; + } + const onChange = t0; + let t1; + if ($[1] !== onChange) { +- t1 = ; ++ t1 = ( ++  ++ ); + $[1] = onChange; + $[2] = t1; + } else { + t1 = $[2]; + } + return t1; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + }; + + ``` +  + ### Eval output + (kind: ok)  + +FAIL: useCallback-set-ref-nested-property +- Expected ++ Received + + + ## Input + + ```javascript + import {useCallback, useRef} from 'react'; + + // Identical to useCallback-set-ref-nested-property-preserve-memoization, + // but with a different set of compiler flags + function Component({}) { + const ref = useRef({inner: null}); + + const onChange = useCallback(event => { + // The ref should still be mutable here even though function deps are frozen in + // @enablePreserveExistingMemoizationGuarantees mode + ref.current.inner = event.target.value; + }); + + return ; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { useCallback, useRef } from "react"; + + // Identical to useCallback-set-ref-nested-property-preserve-memoization, + // but with a different set of compiler flags + function Component(t0) { + const $ = _c(4); ++ Object.freeze(t0); + let t1; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t1 = { inner: null }; + $[0] = t1; + } else { + t1 = $[0]; + } +- const ref = useRef(t1); ++ const ref = (function () { ++ const $res$ = useRef(Object.freeze(t1)); ++ Object.freeze($res$); ++ return $res$; ++ })(); + let t2; + if ($[1] === Symbol.for("react.memo_cache_sentinel")) { + t2 = (event) => { + ref.current.inner = event.target.value; + }; + $[1] = t2; + } else { + t2 = $[1]; + } + const onChange = t2; + let t3; + if ($[2] !== onChange) { +- t3 = ; ++ t3 = ( ++  ++ ); + $[2] = onChange; + $[3] = t3; + } else { + t3 = $[3]; + } + return t3; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + }; + + ``` +  + ### Eval output + (kind: ok)  + +FAIL: useCallback-set-ref-nested-property-preserve-memoization +- Expected ++ Received + + + ## Input + + ```javascript + // @enablePreserveExistingMemoizationGuarantees + import {useCallback, useRef} from 'react'; + + function Component(props) { + const ref = useRef({inner: null}); + + const onChange = useCallback(event => { + // The ref should still be mutable here even though function deps are frozen in + // @enablePreserveExistingMemoizationGuarantees mode + ref.current.inner = event.target.value; + }); + + return ; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; // @enablePreserveExistingMemoizationGuarantees + import { useCallback, useRef } from "react"; + + function Component(props) { + const $ = _c(4); ++ Object.freeze(props); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = { inner: null }; + $[0] = t0; + } else { + t0 = $[0]; + } +- const ref = useRef(t0); ++ const ref = (function () { ++ const $res$ = useRef(Object.freeze(t0)); ++ Object.freeze($res$); ++ return $res$; ++ })(); + let t1; + if ($[1] === Symbol.for("react.memo_cache_sentinel")) { + t1 = (event) => { + ref.current.inner = event.target.value; + }; + $[1] = t1; + } else { + t1 = $[1]; + } + const onChange = t1; + let t2; + if ($[2] !== onChange) { +- t2 = ; ++ t2 = ( ++  ++ ); + $[2] = onChange; + $[3] = t2; + } else { + t2 = $[3]; + } + return t2; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + }; + + ``` +  + ### Eval output + (kind: ok)  + +FAIL: useCallback-set-ref-nested-property-dont-preserve-memoization + >> Unexpected error during test: + + +Found differences in evaluator results +Non-forget (expected): +(kind: ok) +Forget: +(kind: exception) Cannot assign to read only property 'inner' of object '#' + +FAIL: useCallback-multiple-callbacks-modifying-same-ref-preserve-memoization +- Expected ++ Received + + + ## Input + + ```javascript + // @enablePreserveExistingMemoizationGuarantees + import {useCallback, useRef} from 'react'; + + function Component(props) { + const ref = useRef({inner: null}); + + const onChange = useCallback(event => { + // The ref should still be mutable here even though function deps are frozen in + // @enablePreserveExistingMemoizationGuarantees mode + ref.current.inner = event.target.value; + }); + + const onReset = useCallback(() => { + ref.current.inner = null; + }); + + return ; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; // @enablePreserveExistingMemoizationGuarantees + import { useCallback, useRef } from "react"; + + function Component(props) { + const $ = _c(6); ++ Object.freeze(props); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = { inner: null }; + $[0] = t0; + } else { + t0 = $[0]; + } +- const ref = useRef(t0); ++ const ref = (function () { ++ const $res$ = useRef(Object.freeze(t0)); ++ Object.freeze($res$); ++ return $res$; ++ })(); + let t1; + if ($[1] === Symbol.for("react.memo_cache_sentinel")) { + t1 = (event) => { + ref.current.inner = event.target.value; + }; + $[1] = t1; + } else { + t1 = $[1]; + } + const onChange = t1; + let t2; + if ($[2] === Symbol.for("react.memo_cache_sentinel")) { + t2 = () => { + ref.current.inner = null; + }; + $[2] = t2; + } else { + t2 = $[2]; + } + const onReset = t2; + let t3; + if ($[3] !== onChange || $[4] !== onReset) { +- t3 = ; ++ t3 = ( ++  ++ ); + $[3] = onChange; + $[4] = onReset; + $[5] = t3; + } else { + t3 = $[5]; + } + return t3; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + }; + + ``` +  + ### Eval output + (kind: ok)  + +FAIL: useCallback-maybe-modify-free-variable-preserve-memoization-guarantee +- Expected ++ Received + + + ## Input + + ```javascript + // @enablePreserveExistingMemoizationGuarantees + import {useCallback} from 'react'; + import {identity, makeObject_Primitives, mutate, useHook} from 'shared-runtime'; + + function Component(props) { + const free = makeObject_Primitives(); + const free2 = makeObject_Primitives(); + const part = free2.part; + useHook(); + const callback = useCallback(() => { + const x = makeObject_Primitives(); + x.value = props.value; + mutate(x, free, part); + }, [props.value]); + mutate(free, part); + return callback; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{value: 42}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; // @enablePreserveExistingMemoizationGuarantees + import { useCallback } from "react"; + import { + identity, + makeObject_Primitives, + mutate, + useHook, + } from "shared-runtime"; + + function Component(props) { + const $ = _c(4); ++ Object.freeze(props); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = makeObject_Primitives(); + $[0] = t0; + } else { + t0 = $[0]; + } + const free = t0; + let t1; + if ($[1] === Symbol.for("react.memo_cache_sentinel")) { + t1 = makeObject_Primitives(); + $[1] = t1; + } else { + t1 = $[1]; + } + const free2 = t1; + const part = free2.part; +- useHook(); ++ (function () { ++ const $res$ = useHook(); ++ Object.freeze($res$); ++ return $res$; ++ })(); + let t2; + if ($[2] !== props.value) { + t2 = () => { + const x = makeObject_Primitives(); + x.value = props.value; + mutate(x, free, part); + }; + $[2] = props.value; + $[3] = t2; + } else { + t2 = $[3]; + } + const callback = t2; + + mutate(free, part); + return callback; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ value: 42 }], + }; + + ``` +  + ### Eval output + (kind: ok) "[[ function params=0 ]]" + +FAIL: useCallback-maybe-modify-free-variable-dont-preserve-memoization-guarantee +- Expected ++ Received + + + ## Input + + ```javascript + // @enablePreserveExistingMemoizationGuarantees:false + import {useCallback} from 'react'; + import {identity, makeObject_Primitives, mutate, useHook} from 'shared-runtime'; + + function Component(props) { + const free = makeObject_Primitives(); + const free2 = makeObject_Primitives(); + const part = free2.part; + useHook(); + const callback = useCallback(() => { + const x = makeObject_Primitives(); + x.value = props.value; + mutate(x, free, part); + }, [props.value]); + + mutate(free, part); + return callback; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{value: 42}], + }; + + ``` + + ## Code + + ```javascript + // @enablePreserveExistingMemoizationGuarantees:false + import { useCallback } from "react"; + import { + identity, + makeObject_Primitives, + mutate, + useHook, + } from "shared-runtime"; + + function Component(props) { ++ Object.freeze(props); + const free = makeObject_Primitives(); + const free2 = makeObject_Primitives(); + const part = free2.part; +- useHook(); ++ (function () { ++ const $res$ = useHook(); ++ Object.freeze($res$); ++ return $res$; ++ })(); + const callback = () => { + const x = makeObject_Primitives(); + x.value = props.value; + mutate(x, free, part); + }; + + mutate(free, part); + return callback; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ value: 42 }], + }; + + ``` +  + ### Eval output + (kind: ok) "[[ function params=0 ]]" + +FAIL: useCallback-call-second-function-which-captures-maybe-mutable-value-preserve-memoization +- Expected ++ Received + + + ## Input + + ```javascript + // @enablePreserveExistingMemoizationGuarantees + import {useCallback} from 'react'; + import { + identity, + logValue, + makeObject_Primitives, + useHook, + } from 'shared-runtime'; + + function Component(props) { + const object = makeObject_Primitives(); + + useHook(); + + const log = () => { + logValue(object); + }; + + const onClick = useCallback(() => { + log(); + }, [log]); + + identity(object); + + return
; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; // @enablePreserveExistingMemoizationGuarantees + import { useCallback } from "react"; + import { + identity, + logValue, + makeObject_Primitives, + useHook, + } from "shared-runtime"; + + function Component(props) { + const $ = _c(4); ++ Object.freeze(props); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = makeObject_Primitives(); + $[0] = t0; + } else { + t0 = $[0]; + } + const object = t0; +- +- useHook(); ++ (function () { ++ const $res$ = useHook(); ++ Object.freeze($res$); ++ return $res$; ++ })(); + let t1; + if ($[1] === Symbol.for("react.memo_cache_sentinel")) { + t1 = () => { + logValue(object); + }; + $[1] = t1; + } else { + t1 = $[1]; + } + const log = t1; + let t2; + if ($[2] === Symbol.for("react.memo_cache_sentinel")) { + t2 = () => { + log(); + }; + $[2] = t2; + } else { + t2 = $[2]; + } + const onClick = t2; + + identity(object); + let t3; + if ($[3] === Symbol.for("react.memo_cache_sentinel")) { +- t3 =
; ++ t3 = ( ++  ++ ); + $[3] = t3; + } else { + t3 = $[3]; + } + return t3; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + }; + + ``` +  + ### Eval output + (kind: ok)
 + +FAIL: useCallback-call-second-function-which-captures-maybe-mutable-value-dont-preserve-memoization +- Expected ++ Received + + + ## Input + + ```javascript + // @enablePreserveExistingMemoizationGuarantees:false @enableTransitivelyFreezeFunctionExpressions:false + import {useCallback} from 'react'; + import { + identity, + logValue, + makeObject_Primitives, + useHook, + } from 'shared-runtime'; + + function Component(props) { + const object = makeObject_Primitives(); + + useHook(); + + const log = () => { + logValue(object); + }; + + const onClick = useCallback(() => { + log(); + }, [log]); + + identity(object); + + return
; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; // @enablePreserveExistingMemoizationGuarantees:false @enableTransitivelyFreezeFunctionExpressions:false + import { useCallback } from "react"; + import { + identity, + logValue, + makeObject_Primitives, + useHook, + } from "shared-runtime"; + + function Component(props) { + const $ = _c(2); ++ Object.freeze(props); + const object = makeObject_Primitives(); +- +- useHook(); ++ (function () { ++ const $res$ = useHook(); ++ Object.freeze($res$); ++ return $res$; ++ })(); + + const log = () => { + logValue(object); + }; + + const onClick = () => { + log(); + }; + + identity(object); + let t0; + if ($[0] !== onClick) { +- t0 =
; ++ t0 = ( ++  ++ ); + $[0] = onClick; + $[1] = t0; + } else { + t0 = $[1]; + } + return t0; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + }; + + ``` +  + ### Eval output + (kind: ok)
 + +FAIL: useActionState-dispatch-considered-as-non-reactive +- Expected ++ Received + + + ## Input + + ```javascript + import {useActionState} from 'react'; + + function Component() { + const [actionState, dispatchAction] = useActionState(); + const onSubmitAction = () => { + dispatchAction(); + }; + return ; + } + + function Foo() {} + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { useActionState } from "react"; + + function Component() { + const $ = _c(1); +- const [actionState, dispatchAction] = useActionState(); ++ const [actionState, dispatchAction] = (function () { ++ const $res$ = useActionState(); ++ Object.freeze($res$); ++ return $res$; ++ })(); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + const onSubmitAction = () => { + dispatchAction(); + }; + +- t0 = ; ++ t0 = ( ++  ++ ); + $[0] = t0; + } else { + t0 = $[0]; + } + return t0; + } + + function Foo() {} + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [], + }; + + ``` +  + ### Eval output + (kind: ok)  + +FAIL: use-operator-method-call + >> Unexpected error during test: + + +Found differences in evaluator results +Non-forget (expected): +(kind: ok)
{"inputs":[null],"output":["[[ cyclic ref *2 ]]"]}
+
{"inputs":[42],"output":[42]}
+
{"inputs":[42],"output":[42]}
+
{"inputs":[null],"output":["[[ cyclic ref *2 ]]"]}
+
{"inputs":[null],"output":["[[ cyclic ref *2 ]]"]}
+
{"inputs":[42],"output":[42]}
+
{"inputs":[null],"output":["[[ cyclic ref *2 ]]"]}
+
{"inputs":[42],"output":[42]}
+
{"inputs":[null],"output":["[[ cyclic ref *2 ]]"]}
+Forget: +(kind: ok) [[ (exception in render) Error: Too many re-renders. React limits the number of renders to prevent an infinite loop. ]] +[[ (exception in render) Error: Too many re-renders. React limits the number of renders to prevent an infinite loop. ]] +[[ (exception in render) Error: Too many re-renders. React limits the number of renders to prevent an infinite loop. ]] +[[ (exception in render) Error: Too many re-renders. React limits the number of renders to prevent an infinite loop. ]] +[[ (exception in render) Error: Too many re-renders. React limits the number of renders to prevent an infinite loop. ]] +[[ (exception in render) Error: Too many re-renders. React limits the number of renders to prevent an infinite loop. ]] +[[ (exception in render) Error: Too many re-renders. React limits the number of renders to prevent an infinite loop. ]] +[[ (exception in render) Error: Too many re-renders. React limits the number of renders to prevent an infinite loop. ]] +[[ (exception in render) Error: Too many re-renders. React limits the number of renders to prevent an infinite loop. ]] + +FAIL: use-operator-conditional + >> Unexpected error during test: + + +Found differences in evaluator results +Non-forget (expected): +(kind: ok)
{"inputs":[42],"output":[42]}
+
{"inputs":[null],"output":["[[ cyclic ref *2 ]]"]}
+
{"inputs":[null],"output":["[[ cyclic ref *2 ]]"]}
+
{"inputs":[null],"output":["[[ cyclic ref *2 ]]"]}
+
{"inputs":[42],"output":[42]}
+
{"inputs":[null],"output":["[[ cyclic ref *2 ]]"]}
+
{"inputs":[null],"output":["[[ cyclic ref *2 ]]"]}
+
{"inputs":[42],"output":[42]}
+Forget: +(kind: ok) [[ (exception in render) Error: Too many re-renders. React limits the number of renders to prevent an infinite loop. ]] +[[ (exception in render) Error: Too many re-renders. React limits the number of renders to prevent an infinite loop. ]] +[[ (exception in render) Error: Too many re-renders. React limits the number of renders to prevent an infinite loop. ]] +[[ (exception in render) Error: Too many re-renders. React limits the number of renders to prevent an infinite loop. ]] +[[ (exception in render) Error: Too many re-renders. React limits the number of renders to prevent an infinite loop. ]] +[[ (exception in render) Error: Too many re-renders. React limits the number of renders to prevent an infinite loop. ]] +[[ (exception in render) Error: Too many re-renders. React limits the number of renders to prevent an infinite loop. ]] +[[ (exception in render) Error: Too many re-renders. React limits the number of renders to prevent an infinite loop. ]] + +FAIL: use-operator-call-expression + >> Unexpected error during test: + + +Found differences in evaluator results +Non-forget (expected): +(kind: ok)
{"inputs":[null],"output":["[[ cyclic ref *2 ]]"]}
+
{"inputs":[42],"output":[42]}
+
{"inputs":[42],"output":[42]}
+
{"inputs":[null],"output":["[[ cyclic ref *2 ]]"]}
+
{"inputs":[null],"output":["[[ cyclic ref *2 ]]"]}
+
{"inputs":[42],"output":[42]}
+
{"inputs":[null],"output":["[[ cyclic ref *2 ]]"]}
+
{"inputs":[42],"output":[42]}
+
{"inputs":[null],"output":["[[ cyclic ref *2 ]]"]}
+Forget: +(kind: ok) [[ (exception in render) Error: Too many re-renders. React limits the number of renders to prevent an infinite loop. ]] +[[ (exception in render) Error: Too many re-renders. React limits the number of renders to prevent an infinite loop. ]] +[[ (exception in render) Error: Too many re-renders. React limits the number of renders to prevent an infinite loop. ]] +[[ (exception in render) Error: Too many re-renders. React limits the number of renders to prevent an infinite loop. ]] +[[ (exception in render) Error: Too many re-renders. React limits the number of renders to prevent an infinite loop. ]] +[[ (exception in render) Error: Too many re-renders. React limits the number of renders to prevent an infinite loop. ]] +[[ (exception in render) Error: Too many re-renders. React limits the number of renders to prevent an infinite loop. ]] +[[ (exception in render) Error: Too many re-renders. React limits the number of renders to prevent an infinite loop. ]] +[[ (exception in render) Error: Too many re-renders. React limits the number of renders to prevent an infinite loop. ]] + +FAIL: use-memo-simple + >> Unexpected error during test: + + +Found differences in evaluator results +Non-forget (expected): +(kind: ok)
"foo"
+Forget: +(kind: ok)
"foo"
+logs: ['Warning: Invalid value for prop %s on <%s> tag. Either remove it from the element, or pass a string or number value to keep it in the DOM. For details, see https://react.dev/link/attribute-behavior %s','`x`','div','\n' + + ' at div\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)'] + +FAIL: use-callback-simple +- Expected ++ Received + + + ## Input + + ```javascript + function component() { + const [count, setCount] = useState(0); + const increment = useCallback(() => setCount(count + 1)); + + return ; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function component() { + const $ = _c(4); +- const [count, setCount] = useState(0); ++ const [count, setCount] = (function () { ++ const $res$ = useState(Object.freeze(0)); ++ Object.freeze($res$); ++ return $res$; ++ })(); + let t0; + if ($[0] !== count) { + t0 = () => setCount(count + 1); + $[0] = count; + $[1] = t0; + } else { + t0 = $[1]; + } + const increment = t0; + let t1; + if ($[2] !== increment) { +- t1 = ; ++ t1 = ( ++  ++ ); + $[2] = increment; + $[3] = t1; + } else { + t1 = $[3]; + } + return t1; + } + + ``` +  + +FAIL: update-global-in-callback + >> Unexpected error during test: + + +Found differences in evaluator results +Non-forget (expected): +(kind: ok)
{"cb":{"kind":"Function","result":1},"shouldInvokeFns":true}
+Forget: +(kind: ok)
{"cb":{"kind":"Function","result":{"kind":"Function","result":1}},"shouldInvokeFns":{"kind":"Function","result":true}}
+ +FAIL: update-expression +- Expected ++ Received + + + ## Input + + ```javascript + function foo(props: {x: number}) { + let x = props.x; + let y = x++; + let z = x--; + return {x, y, z}; + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: [{x: 1}], + isComponent: false, + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function foo(props) { + const $ = _c(4); ++ Object.freeze(props); + let x = props.x; + const y = x++; + const z = x--; + let t0; + if ($[0] !== x || $[1] !== y || $[2] !== z) { + t0 = { x, y, z }; + $[0] = x; + $[1] = y; + $[2] = z; + $[3] = t0; + } else { + t0 = $[3]; + } + return t0; + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: [{ x: 1 }], + isComponent: false, + }; + + ``` +  + ### Eval output + (kind: ok) {"x":1,"y":1,"z":2} + +FAIL: update-expression-on-function-parameter-4 +- Expected ++ Received + + + ## Input + + ```javascript + function Component([b]) { + let f = b--; + let g = --b; + return [b, f, g]; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [[3]], + isComponent: false, + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(t0) { + const $ = _c(4); ++ Object.freeze(t0); + let [b] = t0; + const f = b--; + const g = --b; + let t1; + if ($[0] !== b || $[1] !== f || $[2] !== g) { + t1 = [b, f, g]; + $[0] = b; + $[1] = f; + $[2] = g; + $[3] = t1; + } else { + t1 = $[3]; + } + return t1; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [[3]], + isComponent: false, + }; + + ``` +  + ### Eval output + (kind: ok) [1,3,1] + +FAIL: update-expression-on-function-parameter-3 +- Expected ++ Received + + + ## Input + + ```javascript + function Component({c}) { + let h = c++; + let i = --c; + return [c, h, i]; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{c: 4}], + isComponent: false, + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(t0) { + const $ = _c(4); ++ Object.freeze(t0); + let { c } = t0; + const h = c++; + const i = --c; + let t1; + if ($[0] !== c || $[1] !== h || $[2] !== i) { + t1 = [c, h, i]; + $[0] = c; + $[1] = h; + $[2] = i; + $[3] = t1; + } else { + t1 = $[3]; + } + return t1; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ c: 4 }], + isComponent: false, + }; + + ``` +  + ### Eval output + (kind: ok) [4,4,4] + +FAIL: update-expression-on-function-parameter-2 +- Expected ++ Received + + + ## Input + + ```javascript + function Component(a) { + let d = a++; + let e = ++a; + return [a, d, e]; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [2], + isComponent: false, + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(a) { + const $ = _c(4); ++ Object.freeze(a); + const d = a++; + const e = ++a; + let t0; + if ($[0] !== a || $[1] !== d || $[2] !== e) { + t0 = [a, d, e]; + $[0] = a; + $[1] = d; + $[2] = e; + $[3] = t0; + } else { + t0 = $[3]; + } + return t0; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [2], + isComponent: false, + }; + + ``` +  + ### Eval output + (kind: ok) [4,2,4] + +FAIL: update-expression-on-function-parameter-1 +- Expected ++ Received + + + ## Input + + ```javascript + function Component({a: a, b: [b], c: {c}}) { + let d = a++; + let e = ++a; + let f = b--; + let g = --b; + let h = c++; + let i = --c; + return [a, b, c, d, e, f, g, h, i]; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{a: 2, b: [3], c: {c: 4}}], + isComponent: false, + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(t0) { + const $ = _c(10); ++ Object.freeze(t0); + let { a, b: t1, c: t2 } = t0; + let [b] = t1; + let { c } = t2; + const d = a++; + const e = ++a; + const f = b--; + const g = --b; + const h = c++; + const i = --c; + let t3; + if ( + $[0] !== a || + $[1] !== b || + $[2] !== c || + $[3] !== d || + $[4] !== e || + $[5] !== f || + $[6] !== g || + $[7] !== h || + $[8] !== i + ) { + t3 = [a, b, c, d, e, f, g, h, i]; + $[0] = a; + $[1] = b; + $[2] = c; + $[3] = d; + $[4] = e; + $[5] = f; + $[6] = g; + $[7] = h; + $[8] = i; + $[9] = t3; + } else { + t3 = $[9]; + } + return t3; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ a: 2, b: [3], c: { c: 4 } }], + isComponent: false, + }; + + ``` +  + ### Eval output + (kind: ok) [4,1,4,2,4,3,1,4,4] + +FAIL: update-expression-in-sequence +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + let a = props.x; + let b; + let c; + let d; + if (props.cond) { + d = ((b = a), a++, (c = a), ++a); + } + return [a, b, c, d]; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{x: 2, cond: true}], + isComponent: false, + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(5); ++ Object.freeze(props); + let a = props.x; + let b; + let c; + let d; + if (props.cond) { + d = ((b = a), a++, (c = a), ++a); + } + let t0; + if ($[0] !== a || $[1] !== b || $[2] !== c || $[3] !== d) { + t0 = [a, b, c, d]; + $[0] = a; + $[1] = b; + $[2] = c; + $[3] = d; + $[4] = t0; + } else { + t0 = $[4]; + } + return t0; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ x: 2, cond: true }], + isComponent: false, + }; + + ``` +  + ### Eval output + (kind: ok) [4,2,3,4] + +FAIL: unused-ternary-assigned-to-variable +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + // unused! + const obj = makeObject(); + const _ = obj.a ? props.b : props.c; + return null; + } + + ``` + + ## Code + + ```javascript + function Component(props) { ++ Object.freeze(props); ++ + const obj = makeObject(); + obj.a ? props.b : props.c; + return null; + } + + ``` +  + +FAIL: unused-optional-method-assigned-to-variable +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + // unused! + const obj = makeObject(); + const _ = obj.a?.b?.(props.c); + return null; + } + + ``` + + ## Code + + ```javascript + function Component(props) { ++ Object.freeze(props); ++ + const obj = makeObject(); + obj.a?.b?.(props.c); + return null; + } + + ``` +  + +FAIL: unused-object-element +- Expected ++ Received + + + ## Input + + ```javascript + function Foo(props) { + const {x, y, ...z} = props.a; + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Foo, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + function Foo(props) { ++ Object.freeze(props); + const { x } = props.a; + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Foo, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: unused-object-element-with-rest +- Expected ++ Received + + + ## Input + + ```javascript + function Foo(props) { + // can't remove `unused` since it affects which properties are copied into `rest` + const {unused, ...rest} = props.a; + return rest; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Foo, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Foo(props) { + const $ = _c(2); ++ Object.freeze(props); + let rest; + if ($[0] !== props.a) { + const { unused, ...t0 } = props.a; + rest = t0; + $[0] = props.a; + $[1] = rest; + } else { + rest = $[1]; + } + return rest; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Foo, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: unused-logical +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + let x = 0; + props.cond ? (x = 1) : (x = 2); + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + function Component(props) { ++ Object.freeze(props); + let x; + props.cond ? (x = 1) : (x = 2); + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: unused-logical-assigned-to-variable +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + // unused! + const obj = makeObject(); + const obj2 = makeObject(); + const _ = (obj.a ?? obj2.b) || props.c; + return null; + } + + ``` + + ## Code + + ```javascript + function Component(props) { ++ Object.freeze(props); ++ + const obj = makeObject(); + const obj2 = makeObject(); + (obj.a ?? obj2.b) || props.c; + return null; + } + + ``` +  + +FAIL: unused-conditional +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + let x = 0; + (x = 1) && (x = 2); + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + function Component(props) { ++ Object.freeze(props); + let x; + ((x = 1), 1) && (x = 2); + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: unused-array-rest-element +- Expected ++ Received + + + ## Input + + ```javascript + function foo(props) { + const [x, y, ...z] = props.a; + return x + y; + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + function foo(props) { ++ Object.freeze(props); + const [x, y] = props.a; + return x + y; + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: unused-array-middle-element +- Expected ++ Received + + + ## Input + + ```javascript + function foo(props) { + const [x, unused, y] = props.a; + return x + y; + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + function foo(props) { ++ Object.freeze(props); + const [x, unused, y] = props.a; + return x + y; + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: unmemoized-nonreactive-dependency-is-pruned-as-dependency +- Expected ++ Received + + + ## Input + + ```javascript + import {mutate, useNoAlias} from 'shared-runtime'; + + function Component(props) { + // Here `x` cannot be memoized bc its mutable range spans a hook call: + const x = []; + useNoAlias(); + mutate(x); + + // However, `x` is non-reactive. It cannot semantically change, so we + // exclude it as a dependency of the JSX element: + return
{x}
; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{value: 42}], + }; + + ``` + + ## Code + + ```javascript + import { mutate, useNoAlias } from "shared-runtime"; + + function Component(props) { ++ Object.freeze(props); ++ + const x = []; +- useNoAlias(); ++ (function () { ++ const $res$ = useNoAlias(); ++ Object.freeze($res$); ++ return $res$; ++ })(); + mutate(x); + return
{x}
; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ value: 42 }], + }; + + ``` +  + ### Eval output + (kind: ok)
 + +FAIL: unlabeled-break-within-label-switch +- Expected ++ Received + + + ## Input + + ```javascript + import {CONST_STRING0} from 'shared-runtime'; + + function useHook(cond) { + const log = []; + switch (CONST_STRING0) { + case CONST_STRING0: + log.push(`@A`); + bb0: { + if (cond) { + break; + } + log.push(`@B`); + } + log.push(`@C`); + } + return log; + } + + export const FIXTURE_ENTRYPOINT = { + fn: useHook, + params: [true], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { CONST_STRING0 } from "shared-runtime"; + + function useHook(cond) { + const $ = _c(2); ++ Object.freeze(cond); + let log; + if ($[0] !== cond) { + log = []; + bb0: switch (CONST_STRING0) { + case CONST_STRING0: { + log.push(`@A`); + if (cond) { + break bb0; + } + + log.push(`@B`); + + log.push(`@C`); + } + } + $[0] = cond; + $[1] = log; + } else { + log = $[1]; + } + return log; + } + + export const FIXTURE_ENTRYPOINT = { + fn: useHook, + params: [true], + }; + + ``` +  + ### Eval output + (kind: ok) ["@A"] + +FAIL: unlabeled-break-within-label-loop +- Expected ++ Received + + + ## Input + + ```javascript + function useHook(end) { + const log = []; + for (let i = 0; i < end + 1; i++) { + log.push(`${i} @A`); + bb0: { + if (i === end) { + break; + } + log.push(`${i} @B`); + } + log.push(`${i} @C`); + } + return log; + } + + export const FIXTURE_ENTRYPOINT = { + fn: useHook, + params: [1], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function useHook(end) { + const $ = _c(2); ++ Object.freeze(end); + let log; + if ($[0] !== end) { + log = []; + for (let i = 0; i < end + 1; i++) { + log.push(`${i} @A`); + if (i === end) { + break; + } + + log.push(`${i} @B`); + + log.push(`${i} @C`); + } + $[0] = end; + $[1] = log; + } else { + log = $[1]; + } + return log; + } + + export const FIXTURE_ENTRYPOINT = { + fn: useHook, + params: [1], + }; + + ``` +  + ### Eval output + (kind: ok) ["0 @A","0 @B","0 @C","1 @A"] + +FAIL: unknown-hooks-do-not-assert +- Expected ++ Received + + + ## Input + + ```javascript + // Forget currently bails out when it detects a potential mutation (Effect.Mutate) + // to an immutable value. This should not apply to unknown / untyped hooks. + function Component(props) { + const x = useUnknownHook1(props); + const y = useUnknownHook2(x); + return y; + } + + ``` + + ## Code + + ```javascript + // Forget currently bails out when it detects a potential mutation (Effect.Mutate) + // to an immutable value. This should not apply to unknown / untyped hooks. + function Component(props) { +- const x = useUnknownHook1(props); +- const y = useUnknownHook2(x); ++ Object.freeze(props); ++ const x = (function () { ++ const $res$ = useUnknownHook1(Object.freeze(props)); ++ Object.freeze($res$); ++ return $res$; ++ })(); ++ const y = (function () { ++ const $res$ = useUnknownHook2(Object.freeze(x)); ++ Object.freeze($res$); ++ return $res$; ++ })(); + return y; + } + + ``` +  + +FAIL: uninitialized-declaration-in-reactive-scope +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + let x = mutate(); + let y; + foo(x); + return [y, x]; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(1); ++ Object.freeze(props); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + const x = mutate(); + let y; + foo(x); + t0 = [y, x]; + $[0] = t0; + } else { + t0 = $[0]; + } + return t0; + } + + ``` +  + +FAIL: unconditional-break-label +- Expected ++ Received + + + ## Input + + ```javascript + function foo(a) { + let x = 0; + bar: { + x = 1; + break bar; + } + return a + x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + function foo(a) { ++ Object.freeze(a); + return a + 1; + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: unary-expr +- Expected ++ Received + + + ## Input + + ```javascript + function component(a) { + let t = {t: a}; + let z = +t.t; + let q = -t.t; + let p = void t.t; + let n = delete t.t; + let m = !t.t; + let e = ~t.t; + let f = typeof t.t; + return {z, p, q, n, m, e, f}; + } + + export const FIXTURE_ENTRYPOINT = { + fn: component, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function component(a) { + const $ = _c(8); ++ Object.freeze(a); + const t = { t: a }; + const z = +t.t; + const q = -t.t; + const p = void t.t; + const n = delete t.t; + const m = !t.t; + const e = ~t.t; + const f = typeof t.t; + let t0; + if ( + $[0] !== z || + $[1] !== p || + $[2] !== q || + $[3] !== n || + $[4] !== m || + $[5] !== e || + $[6] !== f + ) { + t0 = { z, p, q, n, m, e, f }; + $[0] = z; + $[1] = p; + $[2] = q; + $[3] = n; + $[4] = m; + $[5] = e; + $[6] = f; + $[7] = t0; + } else { + t0 = $[7]; + } + return t0; + } + + export const FIXTURE_ENTRYPOINT = { + fn: component, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: type-cast-expression.flow +- Expected ++ Received + + + ## Input + + ```javascript + // @flow + type Foo = {bar: string}; + function Component(props) { + const x = {bar: props.bar}; + const y = (x: Foo); + y.bar = 'hello'; + const z = (y: Foo); + return z; + } + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + type Foo = { bar: string }; + function Component(props) { + const $ = _c(2); ++ Object.freeze(props); + let y; + if ($[0] !== props.bar) { + const x = { bar: props.bar }; + y = (x: Foo); + y.bar = "hello"; + $[0] = props.bar; + $[1] = y; + } else { + y = $[1]; + } + const z = (y: Foo); + return z; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: type-args-test-binary-operator +- Expected ++ Received + + + ## Input + + ```javascript + function component(a, b) { + if (a > b) { + let m = {}; + } + } + + export const FIXTURE_ENTRYPOINT = { + fn: component, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + function component(a, b) { ++ Object.freeze(a); ++ Object.freeze(b); + if (a > b) { + } + } + + export const FIXTURE_ENTRYPOINT = { + fn: component, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: type-alias.flow +- Expected ++ Received + + + ## Input + + ```javascript + // @flow + function Component(props) { + type User = {name: string}; + const user: User = {name: props.name}; + return user; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{name: 'Mofei'}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(2); ++ Object.freeze(props); + let t0; + if ($[0] !== props.name) { + t0 = { name: props.name }; + $[0] = props.name; + $[1] = t0; + } else { + t0 = $[1]; + } + const user = t0; + return user; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ name: "Mofei" }], + }; + + ``` +  + ### Eval output + (kind: ok) {"name":"Mofei"} + +FAIL: type-alias-declaration +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + type User = {name: string}; + const user: User = {name: props.name}; + return user; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{name: 'Mofei'}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(2); ++ Object.freeze(props); + let t0; + if ($[0] !== props.name) { + t0 = { name: props.name }; + $[0] = props.name; + $[1] = t0; + } else { + t0 = $[1]; + } + const user = t0; + return user; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ name: "Mofei" }], + }; + + ``` +  + ### Eval output + (kind: ok) {"name":"Mofei"} + +FAIL: try-catch +- Expected ++ Received + + + ## Input + + ```javascript + const {throwErrorWithMessage} = require('shared-runtime'); + + function Component(props) { + let x; + try { + x = throwErrorWithMessage('oops'); + } catch { + x = null; + } + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + const { throwErrorWithMessage } = require("shared-runtime"); + + function Component(props) { + const $ = _c(1); ++ Object.freeze(props); + let x; + try { + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = throwErrorWithMessage("oops"); + $[0] = t0; + } else { + t0 = $[0]; + } + x = t0; + } catch { + x = null; + } + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + }; + + ``` +  + ### Eval output + (kind: ok) null + +FAIL: try-catch-within-object-method +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + const object = { + foo() { + try { + return []; + } catch (e) { + return; + } + }, + }; + return object.foo(); + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(1); ++ Object.freeze(props); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + const object = { + foo() { + try { + return []; + } catch (t1) { + return; + } + }, + }; + + t0 = object.foo(); + $[0] = t0; + } else { + t0 = $[0]; + } + return t0; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + }; + + ``` +  + ### Eval output + (kind: ok) [] + +FAIL: try-catch-within-object-method-returns-caught-value +- Expected ++ Received + + + ## Input + + ```javascript + import {throwInput} from 'shared-runtime'; + + function Component(props) { + const object = { + foo() { + try { + throwInput([props.value]); + } catch (e) { + return e; + } + }, + }; + return object.foo(); + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{value: 42}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { throwInput } from "shared-runtime"; + + function Component(props) { + const $ = _c(2); ++ Object.freeze(props); + let t0; + if ($[0] !== props.value) { + const object = { + foo() { + try { + throwInput([props.value]); + } catch (t1) { + const e = t1; + return e; + } + }, + }; + + t0 = object.foo(); + $[0] = props.value; + $[1] = t0; + } else { + t0 = $[1]; + } + return t0; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ value: 42 }], + }; + + ``` +  + ### Eval output + (kind: ok) [42] + +FAIL: try-catch-within-mutable-range +- Expected ++ Received + + + ## Input + + ```javascript + const {throwErrorWithMessage, shallowCopy} = require('shared-runtime'); + + function Component(props) { + const x = []; + try { + x.push(throwErrorWithMessage('oops')); + } catch { + x.push(shallowCopy({})); + } + x.push(props.value); // extend the mutable range to include the try/catch + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + const { throwErrorWithMessage, shallowCopy } = require("shared-runtime"); + + function Component(props) { + const $ = _c(4); ++ Object.freeze(props); + let x; + if ($[0] !== props.value) { + x = []; + try { + let t0; + if ($[2] === Symbol.for("react.memo_cache_sentinel")) { + t0 = throwErrorWithMessage("oops"); + $[2] = t0; + } else { + t0 = $[2]; + } + x.push(t0); + } catch { + let t0; + if ($[3] === Symbol.for("react.memo_cache_sentinel")) { + t0 = shallowCopy({}); + $[3] = t0; + } else { + t0 = $[3]; + } + x.push(t0); + } + + x.push(props.value); + $[0] = props.value; + $[1] = x; + } else { + x = $[1]; + } + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + }; + + ``` +  + ### Eval output + (kind: ok) [{},null] + +FAIL: try-catch-within-function-expression +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + const callback = () => { + try { + return []; + } catch (e) { + return; + } + }; + return callback(); + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(1); ++ Object.freeze(props); + const callback = _temp; + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = callback(); + $[0] = t0; + } else { + t0 = $[0]; + } + return t0; + } + function _temp() { + try { + return []; + } catch (t0) { + return; + } + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + }; + + ``` +  + ### Eval output + (kind: ok) [] + +FAIL: try-catch-within-function-expression-returns-caught-value +- Expected ++ Received + + + ## Input + + ```javascript + import {throwInput} from 'shared-runtime'; + + function Component(props) { + const callback = () => { + try { + throwInput([props.value]); + } catch (e) { + return e; + } + }; + return callback(); + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{value: 42}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { throwInput } from "shared-runtime"; + + function Component(props) { + const $ = _c(4); ++ Object.freeze(props); + let t0; + if ($[0] !== props.value) { + t0 = () => { + try { + throwInput([props.value]); + } catch (t1) { + const e = t1; + return e; + } + }; + $[0] = props.value; + $[1] = t0; + } else { + t0 = $[1]; + } + const callback = t0; + let t1; + if ($[2] !== callback) { + t1 = callback(); + $[2] = callback; + $[3] = t1; + } else { + t1 = $[3]; + } + return t1; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ value: 42 }], + }; + + ``` +  + ### Eval output + (kind: ok) [42] + +FAIL: try-catch-with-return +- Expected ++ Received + + + ## Input + + ```javascript + const {shallowCopy, throwInput} = require('shared-runtime'); + + function Component(props) { + let x = []; + try { + const y = shallowCopy({}); + if (y == null) { + return; + } + x.push(throwInput(y)); + } catch { + return null; + } + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + const { shallowCopy, throwInput } = require("shared-runtime"); + + function Component(props) { + const $ = _c(2); ++ Object.freeze(props); + let x; + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = Symbol.for("react.early_return_sentinel"); + bb0: { + x = []; + try { + const y = shallowCopy({}); + if (y == null) { + t0 = undefined; + break bb0; + } + + x.push(throwInput(y)); + } catch { + t0 = null; + break bb0; + } + } + $[0] = x; + $[1] = t0; + } else { + x = $[0]; + t0 = $[1]; + } + if (t0 !== Symbol.for("react.early_return_sentinel")) { + return t0; + } + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + }; + + ``` +  + ### Eval output + (kind: ok) null + +FAIL: try-catch-with-catch-param +- Expected ++ Received + + + ## Input + + ```javascript + const {throwInput} = require('shared-runtime'); + + function Component(props) { + let x = []; + try { + // foo could throw its argument... + throwInput(x); + } catch (e) { + // ... in which case this could be mutating `x`! + e.push(null); + return e; + } + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + const { throwInput } = require("shared-runtime"); + + function Component(props) { + const $ = _c(2); ++ Object.freeze(props); + let x; + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = Symbol.for("react.early_return_sentinel"); + bb0: { + x = []; + try { + throwInput(x); + } catch (t1) { + const e = t1; + e.push(null); + t0 = e; + break bb0; + } + } + $[0] = x; + $[1] = t0; + } else { + x = $[0]; + t0 = $[1]; + } + if (t0 !== Symbol.for("react.early_return_sentinel")) { + return t0; + } + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + }; + + ``` +  + ### Eval output + (kind: ok) [null] + +FAIL: try-catch-try-value-modified-in-catch +- Expected ++ Received + + + ## Input + + ```javascript + const {throwInput} = require('shared-runtime'); + + function Component(props) { + try { + const y = []; + y.push(props.y); + throwInput(y); + } catch (e) { + e.push(props.e); + return e; + } + return null; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{y: 'foo', e: 'bar'}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + const { throwInput } = require("shared-runtime"); + + function Component(props) { + const $ = _c(3); ++ Object.freeze(props); + let t0; + if ($[0] !== props.y || $[1] !== props.e) { + t0 = Symbol.for("react.early_return_sentinel"); + bb0: { + try { + const y = []; + y.push(props.y); + throwInput(y); + } catch (t1) { + const e = t1; + e.push(props.e); + t0 = e; + break bb0; + } + } + $[0] = props.y; + $[1] = props.e; + $[2] = t0; + } else { + t0 = $[2]; + } + if (t0 !== Symbol.for("react.early_return_sentinel")) { + return t0; + } + return null; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ y: "foo", e: "bar" }], + }; + + ``` +  + ### Eval output + (kind: ok) ["foo","bar"] + +FAIL: try-catch-try-value-modified-in-catch-escaping +- Expected ++ Received + + + ## Input + + ```javascript + const {throwInput} = require('shared-runtime'); + + function Component(props) { + let x; + try { + const y = []; + y.push(props.y); + throwInput(y); + } catch (e) { + e.push(props.e); + x = e; + } + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{y: 'foo', e: 'bar'}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + const { throwInput } = require("shared-runtime"); + + function Component(props) { + const $ = _c(3); ++ Object.freeze(props); + let x; + if ($[0] !== props.y || $[1] !== props.e) { + try { + const y = []; + y.push(props.y); + throwInput(y); + } catch (t0) { + const e = t0; + e.push(props.e); + x = e; + } + $[0] = props.y; + $[1] = props.e; + $[2] = x; + } else { + x = $[2]; + } + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ y: "foo", e: "bar" }], + }; + + ``` +  + ### Eval output + (kind: ok) ["foo","bar"] + +FAIL: try-catch-try-immediately-throws-after-constant-propagation +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + let x = props.default; + const y = 42; + try { + // note: this constant propagates so that we know + // the handler is unreachable + return y; + } catch (e) { + x = e; + } + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{default: 42}], + }; + + ``` + + ## Code + + ```javascript + function Component(props) { ++ Object.freeze(props); + let x; + return 42; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ default: 42 }], + }; + + ``` +  + ### Eval output + (kind: ok) 42 + +FAIL: try-catch-try-immediately-returns +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + let x = props.default; + try { + // note: has to be a primitive, we want an instruction that cannot throw + // to ensure there is no maybe-throw terminal + const y = 42; + return y; + } catch (e) { + x = e; + } + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{default: 42}], + }; + + ``` + + ## Code + + ```javascript + function Component(props) { ++ Object.freeze(props); + let x; + return 42; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ default: 42 }], + }; + + ``` +  + ### Eval output + (kind: ok) 42 + +FAIL: try-catch-mutate-outer-value +- Expected ++ Received + + + ## Input + + ```javascript + const {shallowCopy, throwErrorWithMessage} = require('shared-runtime'); + + function Component(props) { + const x = []; + try { + x.push(throwErrorWithMessage('oops')); + } catch { + x.push(shallowCopy({a: props.a})); + } + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{a: 1}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + const { shallowCopy, throwErrorWithMessage } = require("shared-runtime"); + + function Component(props) { + const $ = _c(3); ++ Object.freeze(props); + let x; + if ($[0] !== props.a) { + x = []; + try { + let t0; + if ($[2] === Symbol.for("react.memo_cache_sentinel")) { + t0 = throwErrorWithMessage("oops"); + $[2] = t0; + } else { + t0 = $[2]; + } + x.push(t0); + } catch { + x.push(shallowCopy({ a: props.a })); + } + $[0] = props.a; + $[1] = x; + } else { + x = $[1]; + } + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ a: 1 }], + }; + + ``` +  + ### Eval output + (kind: ok) [{"a":1}] + +FAIL: try-catch-in-nested-scope +- Expected ++ Received + + + ## Input + + ```javascript + import {mutate, setProperty, throwErrorWithMessageIf} from 'shared-runtime'; + + function useFoo({value, cond}) { + let y = [value]; + let x = {cond}; + + try { + mutate(x); + throwErrorWithMessageIf(x.cond, 'error'); + } catch { + setProperty(x, 'henderson'); + return x; + } + setProperty(x, 'nevada'); + y.push(x); + + return y; + } + + export const FIXTURE_ENTRYPOINT = { + fn: useFoo, + params: [{value: 4, cond: true}], + sequentialRenders: [ + {value: 4, cond: true}, + {value: 5, cond: true}, + {value: 5, cond: false}, + ], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { mutate, setProperty, throwErrorWithMessageIf } from "shared-runtime"; + + function useFoo(t0) { + const $ = _c(6); ++ Object.freeze(t0); + const { value, cond } = t0; + let y; + let t1; + if ($[0] !== value || $[1] !== cond) { + t1 = Symbol.for("react.early_return_sentinel"); + bb0: { + y = [value]; + let x; + if ($[4] !== cond) { + x = { cond }; + try { + mutate(x); + throwErrorWithMessageIf(x.cond, "error"); + } catch { + setProperty(x, "henderson"); + t1 = x; + break bb0; + } + + setProperty(x, "nevada"); + $[4] = cond; + $[5] = x; + } else { + x = $[5]; + } + y.push(x); + } + $[0] = value; + $[1] = cond; + $[2] = y; + $[3] = t1; + } else { + y = $[2]; + t1 = $[3]; + } + if (t1 !== Symbol.for("react.early_return_sentinel")) { + return t1; + } + return y; + } + + export const FIXTURE_ENTRYPOINT = { + fn: useFoo, + params: [{ value: 4, cond: true }], + sequentialRenders: [ + { value: 4, cond: true }, + { value: 5, cond: true }, + { value: 5, cond: false }, + ], + }; + + ``` +  + ### Eval output + (kind: ok) {"cond":true,"wat0":"joe","wat1":"henderson"} + {"cond":true,"wat0":"joe","wat1":"henderson"} + [5,{"cond":false,"wat0":"joe","wat1":"nevada"}] + +FAIL: try-catch-empty-try +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + let x = props.default; + try { + } catch (e) { + x = e; + } + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{default: 42}], + }; + + ``` + + ## Code + + ```javascript + function Component(props) { ++ Object.freeze(props); + const x = props.default; + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ default: 42 }], + }; + + ``` +  + ### Eval output + (kind: ok) 42 + +FAIL: try-catch-alias-try-values +- Expected ++ Received + + + ## Input + + ```javascript + const {throwInput} = require('shared-runtime'); + + function Component(props) { + let y; + let x = []; + try { + // throws x + throwInput(x); + } catch (e) { + // e = x + y = e; // y = x + } + y.push(null); + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + const { throwInput } = require("shared-runtime"); + + function Component(props) { + const $ = _c(1); ++ Object.freeze(props); + let x; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + let y; + x = []; + try { + throwInput(x); + } catch (t0) { + const e = t0; + + y = e; + } + + y.push(null); + $[0] = x; + } else { + x = $[0]; + } + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + }; + + ``` +  + ### Eval output + (kind: ok) [null] + +FAIL: trivial +- Expected ++ Received + + + ## Input + + ```javascript + function foo(x) { + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + function foo(x) { ++ Object.freeze(x); + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: transitive-freeze-function-expressions +- Expected ++ Received + + + ## Input + + ```javascript + // @enableTransitivelyFreezeFunctionExpressions + function Component(props) { + const {data, loadNext, isLoadingNext} = + usePaginationFragment(props.key).items ?? []; + + const loadMoreWithTiming = () => { + if (data.length === 0) { + return; + } + loadNext(); + }; + + useEffect(() => { + if (isLoadingNext) { + return; + } + loadMoreWithTiming(); + }, [isLoadingNext, loadMoreWithTiming]); + + const items = data.map(x => x); + + return items; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; // @enableTransitivelyFreezeFunctionExpressions + function Component(props) { + const $ = _c(9); ++ Object.freeze(props); + const { data, loadNext, isLoadingNext } = +- usePaginationFragment(props.key).items ?? []; ++ (function () { ++ const $res$ = usePaginationFragment(Object.freeze(props.key)); ++ Object.freeze($res$); ++ return $res$; ++ })().items ?? []; + let t0; + if ($[0] !== data.length || $[1] !== loadNext) { + t0 = () => { + if (data.length === 0) { + return; + } + + loadNext(); + }; + $[0] = data.length; + $[1] = loadNext; + $[2] = t0; + } else { + t0 = $[2]; + } + const loadMoreWithTiming = t0; + let t1; + let t2; + if ($[3] !== isLoadingNext || $[4] !== loadMoreWithTiming) { + t1 = () => { + if (isLoadingNext) { + return; + } + + loadMoreWithTiming(); + }; + t2 = [isLoadingNext, loadMoreWithTiming]; + $[3] = isLoadingNext; + $[4] = loadMoreWithTiming; + $[5] = t1; + $[6] = t2; + } else { + t1 = $[5]; + t2 = $[6]; + } +- useEffect(t1, t2); ++ (function () { ++ const $res$ = useEffect(Object.freeze(t1), Object.freeze(t2)); ++ Object.freeze($res$); ++ return $res$; ++ })(); + let t3; + if ($[7] !== data) { + t3 = data.map(_temp); + $[7] = data; + $[8] = t3; + } else { + t3 = $[8]; + } + const items = t3; + return items; + } + function _temp(x) { + return x; + } + + ``` +  + +FAIL: transitive-freeze-array +- Expected ++ Received + + + ## Input + + ```javascript + // @enablePreserveExistingMemoizationGuarantees + const {mutate} = require('shared-runtime'); + + function Component(props) { + const x = {}; + const y = {}; + const items = [x, y]; + items.pop(); +
{items}
; // note: enablePreserveExistingMemoizationGuarantees only visits function expressions, not arrays, so this doesn't freeze x/y + mutate(y); // ok! not part of `items` anymore bc of items.pop() + return [x, y, items]; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; // @enablePreserveExistingMemoizationGuarantees + const { mutate } = require("shared-runtime"); + + function Component(props) { + const $ = _c(1); ++ Object.freeze(props); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + const x = {}; + const y = {}; + const items = [x, y]; + items.pop(); + + mutate(y); + t0 = [x, y, items]; + $[0] = t0; + } else { + t0 = $[0]; + } + return t0; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + }; + + ``` +  + ### Eval output + (kind: ok) [{},{"wat0":"joe"},["[[ cyclic ref *1 ]]"]] + +FAIL: todo.unnecessary-lambda-memoization +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + const data = useFreeze(); // assume this returns {items: Array<{...}>} + // In this call `data` and `data.items` have a read effect *and* the lambda itself + // is readonly (it doesn't capture ony mutable references). Further, we ca + // theoretically determine that the lambda doesn't need to be memoized, since + // data.items is an Array and Array.prototype.map does not capture its input (callback) + // in the return value. + // An observation is that even without knowing the exact type of `data`, if we know + // that it is a plain, readonly javascript object, then we can infer that any `.map()` + // calls *must* be Array.prototype.map (or else they are a runtime error), since no + // other builtin has a .map() function. + const items = data.items.map(item => ); + return
{items}
; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(4); +- const data = useFreeze(); ++ Object.freeze(props); ++ const data = (function () { ++ const $res$ = useFreeze(); ++ Object.freeze($res$); ++ return $res$; ++ })(); + let t0; + if ($[0] !== data.items) { + t0 = data.items.map(_temp); + $[0] = data.items; + $[1] = t0; + } else { + t0 = $[1]; + } + const items = t0; + let t1; + if ($[2] !== items) { + t1 =
{items}
; + $[2] = items; + $[3] = t1; + } else { + t1 = $[3]; + } + return t1; + } + function _temp(item) { +- return ; ++ return ( ++  ++ ); + } + + ``` +  + +FAIL: todo-function-expression-captures-value-later-frozen +- Expected ++ Received + + + ## Input + + ```javascript + 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}
; + } + // ideally this call would be outside the memoization block for `x` + onChange(); + return ; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(2); ++ Object.freeze(props); + let t0; + if ($[0] !== props.cond) { + const x = {}; + + const onChange = (e) => { + maybeMutate(x, e.target.value); + }; + if (props.cond) { + } + + onChange(); +- t0 = ; ++ t0 = ( ++  ++ ); + $[0] = props.cond; + $[1] = t0; + } else { + t0 = $[1]; + } + return t0; + } + + ``` +  + +FAIL: timers +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + const start = performance.now(); + const now = Date.now(); + const time = performance.now() - start; + return ( +
 + rendering took {time} at {now} +
 + ); + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(2); ++ Object.freeze(props); + const start = performance.now(); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = Date.now(); + $[0] = t0; + } else { + t0 = $[0]; + } + const now = t0; + const time = performance.now() - start; + let t1; + if ($[1] === Symbol.for("react.memo_cache_sentinel")) { + t1 = ( +
 + rendering took + {time} at {now} +
 + ); + $[1] = t1; + } else { + t1 = $[1]; + } + return t1; + } + + ``` +  + +FAIL: ternary-expression +- Expected ++ Received + + + ## Input + + ```javascript + function ternary(props) { + const a = props.a && props.b ? props.c || props.d : props.e ?? props.f; + const b = props.a ? (props.b && props.c ? props.d : props.e) : props.f; + return a ? b : null; + } + + export const FIXTURE_ENTRYPOINT = { + fn: ternary, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + function ternary(props) { ++ Object.freeze(props); + const a = props.a && props.b ? props.c || props.d : (props.e ?? props.f); + const b = props.a ? (props.b && props.c ? props.d : props.e) : props.f; + return a ? b : null; + } + + export const FIXTURE_ENTRYPOINT = { + fn: ternary, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: ternary-assignment-expression +- Expected ++ Received + + + ## Input + + ```javascript + function ternary(props) { + let x = 0; + const y = props.a ? (x = 1) : (x = 2); + return x + y; + } + + export const FIXTURE_ENTRYPOINT = { + fn: ternary, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + function ternary(props) { ++ Object.freeze(props); + let x; + const y = props.a ? (x = 1) : (x = 2); + return x + y; + } + + export const FIXTURE_ENTRYPOINT = { + fn: ternary, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: temporary-property-load-accessed-outside-scope +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + const maybeMutable = new MaybeMutable(); + let x = props.value; + return [x, maybeMutate(maybeMutable)]; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(6); ++ Object.freeze(props); + let t0; + let t1; + if ($[0] !== props.value) { + const maybeMutable = new MaybeMutable(); + const x = props.value; + t0 = x; + t1 = maybeMutate(maybeMutable); + $[0] = props.value; + $[1] = t0; + $[2] = t1; + } else { + t0 = $[1]; + t1 = $[2]; + } + let t2; + if ($[3] !== t0 || $[4] !== t1) { + t2 = [t0, t1]; + $[3] = t0; + $[4] = t1; + $[5] = t2; + } else { + t2 = $[5]; + } + return t2; + } + + ``` +  + +FAIL: temporary-at-start-of-value-block +- Expected ++ Received + + + ## Input + + ```javascript + function component(props) { + // NOTE: the temporary for the leading space was previously dropped + const x = isMenuShown ? {props.a ? props.b : props.c} : null; + return x; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function component(props) { + const $ = _c(2); ++ Object.freeze(props); + let t0; + if ($[0] !== props) { + t0 = isMenuShown ? {props.a ? props.b : props.c} : null; + $[0] = props; + $[1] = t0; + } else { + t0 = $[1]; + } + const x = t0; + return x; + } + + ``` +  + +FAIL: temporary-accessed-outside-scope +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + const maybeMutable = new MaybeMutable(); + let x = props; + return [x, maybeMutate(maybeMutable)]; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(6); ++ Object.freeze(props); + let t0; + let t1; + if ($[0] !== props) { + const maybeMutable = new MaybeMutable(); + const x = props; + t0 = x; + t1 = maybeMutate(maybeMutable); + $[0] = props; + $[1] = t0; + $[2] = t1; + } else { + t0 = $[1]; + t1 = $[2]; + } + let t2; + if ($[3] !== t0 || $[4] !== t1) { + t2 = [t0, t1]; + $[3] = t0; + $[4] = t1; + $[5] = t2; + } else { + t2 = $[5]; + } + return t2; + } + + ``` +  + +FAIL: template-literal +- Expected ++ Received + + + ## Input + + ```javascript + function componentA(props) { + let t = `hello ${props.a}, ${props.b}!`; + t += ``; + return t; + } + + function componentB(props) { + let x = useFoo(`hello ${props.a}`); + return x; + } + + ``` + + ## Code + + ```javascript + function componentA(props) { ++ Object.freeze(props); + let t = `hello ${props.a}, ${props.b}!`; + t = t + ``; + return t; + } + + function componentB(props) { +- const x = useFoo(`hello ${props.a}`); ++ Object.freeze(props); ++ const x = (function () { ++ const $res$ = useFoo(Object.freeze(`hello ${props.a}`)); ++ Object.freeze($res$); ++ return $res$; ++ })(); + return x; + } + + ``` +  + +FAIL: tagged-template-in-hook +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + const user = useFragment( + graphql` + fragment F on User { + name + } + `, + props.user + ); + return user.name; + } + + ``` + + ## Code + + ```javascript + function Component(props) { +- const user = useFragment( +- graphql` +- fragment F on User { +- name +- } +- `, +- props.user, +- ); ++ Object.freeze(props); ++ const user = (function () { ++ const $res$ = useFragment( ++ Object.freeze(graphql` ++ fragment F on User { ++ name ++ } ++ `), ++ Object.freeze(props.user), ++ ); ++ Object.freeze($res$); ++ return $res$; ++ })(); + return user.name; + } + + ``` +  + +FAIL: switch +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + let x = []; + let y; + switch (props.p0) { + case true: { + x.push(props.p2); + x.push(props.p3); + y = []; + } + case false: { + y = x; + break; + } + } + const child = ; + y.push(props.p4); + return {child}; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(6); ++ Object.freeze(props); + let y; + let t0; + if ($[0] !== props) { + const x = []; + switch (props.p0) { + case true: { + x.push(props.p2); + x.push(props.p3); + } + case false: { + y = x; + } + } + +- t0 = ; ++ t0 = ( ++  ++ ); + $[0] = props; + $[1] = y; + $[2] = t0; + } else { + y = $[1]; + t0 = $[2]; + } + const child = t0; + y.push(props.p4); + let t1; + if ($[3] !== y || $[4] !== child) { +- t1 = {child}; ++ t1 = ( ++  ++ {child} ++  ++ ); + $[3] = y; + $[4] = child; + $[5] = t1; + } else { + t1 = $[5]; + } + return t1; + } + + ``` +  + +FAIL: switch-with-only-default +- Expected ++ Received + + + ## Input + + ```javascript + import {Stringify} from 'shared-runtime'; + + function Component({kind, ...props}) { + switch (kind) { + default: + return ; + } + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{kind: 'foo', a: 1, b: true, c: 'sathya'}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { Stringify } from "shared-runtime"; + + function Component(t0) { + const $ = _c(5); ++ Object.freeze(t0); + let kind; + let props; + if ($[0] !== t0) { + ({ kind, ...props } = t0); + $[0] = t0; + $[1] = kind; + $[2] = props; + } else { + kind = $[1]; + props = $[2]; + } + switch (kind) { + default: { + let t1; + if ($[3] !== props) { + t1 = ; + $[3] = props; + $[4] = t1; + } else { + t1 = $[4]; + } + return t1; + } + } + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ kind: "foo", a: 1, b: true, c: "sathya" }], + }; + + ``` +  + ### Eval output + (kind: ok)
{"a":1,"b":true,"c":"sathya"}
 + +FAIL: switch-with-fallthrough +- Expected ++ Received + + + ## Input + + ```javascript + function foo(x) { + let y; + switch (x) { + case 0: { + y = 0; + } + case 1: { + y = 1; + } + case 2: { + break; + } + case 3: { + y = 3; + break; + } + case 4: { + y = 4; + } + case 5: { + y = 5; + } + default: { + y = 0; + } + } + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + function foo(x) { ++ Object.freeze(x); + bb0: switch (x) { + case 0: { + } + case 1: { + } + case 2: { + break bb0; + } + case 3: { + break bb0; + } + case 4: { + } + case 5: { + } + default: { + } + } + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: switch-non-final-default +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + let x = []; + let y; + switch (props.p0) { + case 1: { + break; + } + case true: { + x.push(props.p2); + y = []; + } + default: { + break; + } + case false: { + y = x; + break; + } + } + const child = ; + y.push(props.p4); + return {child}; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(7); ++ Object.freeze(props); + let y; + let t0; + if ($[0] !== props) { + const x = []; + bb0: switch (props.p0) { + case 1: { + break bb0; + } + case true: { + x.push(props.p2); + let t1; + if ($[3] === Symbol.for("react.memo_cache_sentinel")) { + t1 = []; + $[3] = t1; + } else { + t1 = $[3]; + } + y = t1; + } + default: { + break bb0; + } + case false: { + y = x; + } + } + +- t0 = ; ++ t0 = ( ++  ++ ); + $[0] = props; + $[1] = y; + $[2] = t0; + } else { + y = $[1]; + t0 = $[2]; + } + const child = t0; + y.push(props.p4); + let t1; + if ($[4] !== y || $[5] !== child) { +- t1 = {child}; ++ t1 = ( ++  ++ {child} ++  ++ ); + $[4] = y; + $[5] = child; + $[6] = t1; + } else { + t1 = $[6]; + } + return t1; + } + + ``` +  + +FAIL: switch-global-propertyload-case-test +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + switch (props.value) { + case Global.Property: { + return true; + } + default: { + return false; + } + } + } + + ``` + + ## Code + + ```javascript + function Component(props) { ++ Object.freeze(props); + switch (props.value) { + case Global.Property: { + return true; + } + default: { + return false; + } + } + } + + ``` +  + +FAIL: ssa-sibling-phis +- Expected ++ Received + + + ## Input + + ```javascript + function foo(a, b, c, d) { + let x = 0; + if (true) { + if (true) { + x = a; + } else { + x = b; + } + x; + } else { + if (true) { + x = c; + } else { + x = d; + } + x; + } + // note: intentionally no phi here so that there are two distinct phis above + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript +- function foo(a, b, c, d) {} ++ function foo(a, b, c, d) { ++ Object.freeze(a); ++ Object.freeze(b); ++ Object.freeze(c); ++ Object.freeze(d); ++ } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: ssa-shadowing +- Expected ++ Received + + + ## Input + + ```javascript + function log() {} + + function Foo(cond) { + let str = ''; + if (cond) { + let str = 'other test'; + log(str); + } else { + str = 'fallthrough test'; + } + log(str); + } + + ``` + + ## Code + + ```javascript + function log() {} + + function Foo(cond) { ++ Object.freeze(cond); + let str = ""; + if (cond) { + log("other test"); + } else { + str = "fallthrough test"; + } + + log(str); + } + + ``` +  + +FAIL: ssa-renaming +- Expected ++ Received + + + ## Input + + ```javascript + function foo(props) { + let x = []; + x.push(props.bar); + if (props.cond) { + x = {}; + x = []; + x.push(props.foo); + } + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function foo(props) { + const $ = _c(4); ++ Object.freeze(props); + let x; + if ($[0] !== props.bar) { + x = []; + x.push(props.bar); + $[0] = props.bar; + $[1] = x; + } else { + x = $[1]; + } + if (props.cond) { + if ($[2] !== props.foo) { + x = []; + x.push(props.foo); + $[2] = props.foo; + $[3] = x; + } else { + x = $[3]; + } + } + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: ssa-renaming-with-mutation +- Expected ++ Received + + + ## Input + + ```javascript + function foo(props) { + let x = []; + x.push(props.bar); + if (props.cond) { + x = {}; + x = []; + x.push(props.foo); + } + mut(x); + return x; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function foo(props) { + const $ = _c(2); ++ Object.freeze(props); + let x; + if ($[0] !== props) { + x = []; + x.push(props.bar); + if (props.cond) { + x = []; + x.push(props.foo); + } + + mut(x); + $[0] = props; + $[1] = x; + } else { + x = $[1]; + } + return x; + } + + ``` +  + +FAIL: ssa-renaming-via-destructuring +- Expected ++ Received + + + ## Input + + ```javascript + function foo(props) { + let {x} = {x: []}; + x.push(props.bar); + if (props.cond) { + ({x} = {x: {}}); + ({x} = {x: []}); + x.push(props.foo); + } + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function foo(props) { + const $ = _c(4); ++ Object.freeze(props); + let x; + if ($[0] !== props.bar) { + ({ x } = { x: [] }); + x.push(props.bar); + $[0] = props.bar; + $[1] = x; + } else { + x = $[1]; + } + if (props.cond) { + if ($[2] !== props.foo) { + ({ x } = { x: [] }); + x.push(props.foo); + $[2] = props.foo; + $[3] = x; + } else { + x = $[3]; + } + } + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: ssa-renaming-via-destructuring-with-mutation +- Expected ++ Received + + + ## Input + + ```javascript + function foo(props) { + let {x} = {x: []}; + x.push(props.bar); + if (props.cond) { + ({x} = {x: {}}); + ({x} = {x: []}); + x.push(props.foo); + } + mut(x); + return x; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function foo(props) { + const $ = _c(2); ++ Object.freeze(props); + let x; + if ($[0] !== props) { + ({ x } = { x: [] }); + x.push(props.bar); + if (props.cond) { + ({ x } = { x: [] }); + x.push(props.foo); + } + + mut(x); + $[0] = props; + $[1] = x; + } else { + x = $[1]; + } + return x; + } + + ``` +  + +FAIL: ssa-renaming-unconditional-with-mutation +- Expected ++ Received + + + ## Input + + ```javascript + function foo(props) { + let x = []; + x.push(props.bar); + if (props.cond) { + x = {}; + x = []; + x.push(props.foo); + } else { + x = []; + x = []; + x.push(props.bar); + } + mut(x); + return x; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function foo(props) { + const $ = _c(2); ++ Object.freeze(props); + let x; + if ($[0] !== props) { + x = []; + x.push(props.bar); + if (props.cond) { + x = []; + x.push(props.foo); + } else { + x = []; + x.push(props.bar); + } + + mut(x); + $[0] = props; + $[1] = x; + } else { + x = $[1]; + } + return x; + } + + ``` +  + +FAIL: ssa-renaming-unconditional-ternary +- Expected ++ Received + + + ## Input + + ```javascript + function foo(props) { + let x = []; + x.push(props.bar); + props.cond + ? ((x = {}), (x = []), x.push(props.foo)) + : ((x = []), (x = []), x.push(props.bar)); + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function foo(props) { + const $ = _c(4); ++ Object.freeze(props); + let x; + if ($[0] !== props.bar) { + x = []; + x.push(props.bar); + $[0] = props.bar; + $[1] = x; + } else { + x = $[1]; + } + if ($[2] !== props) { + props.cond ? ((x = []), x.push(props.foo)) : ((x = []), x.push(props.bar)); + $[2] = props; + $[3] = x; + } else { + x = $[3]; + } + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: ssa-renaming-unconditional-ternary-with-mutation +- Expected ++ Received + + + ## Input + + ```javascript + import {arrayPush} from 'shared-runtime'; + function foo(props) { + let x = []; + x.push(props.bar); + props.cond + ? ((x = {}), (x = []), x.push(props.foo)) + : ((x = []), (x = []), x.push(props.bar)); + arrayPush(x, 4); + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: [{cond: false, foo: 2, bar: 55}], + sequentialRenders: [ + {cond: false, foo: 2, bar: 55}, + {cond: false, foo: 3, bar: 55}, + {cond: true, foo: 3, bar: 55}, + ], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { arrayPush } from "shared-runtime"; + function foo(props) { + const $ = _c(2); ++ Object.freeze(props); + let x; + if ($[0] !== props) { + x = []; + x.push(props.bar); + props.cond ? ((x = []), x.push(props.foo)) : ((x = []), x.push(props.bar)); + arrayPush(x, 4); + $[0] = props; + $[1] = x; + } else { + x = $[1]; + } + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: [{ cond: false, foo: 2, bar: 55 }], + sequentialRenders: [ + { cond: false, foo: 2, bar: 55 }, + { cond: false, foo: 3, bar: 55 }, + { cond: true, foo: 3, bar: 55 }, + ], + }; + + ``` +  + ### Eval output + (kind: ok) [55,4] + [55,4] + [3,4] + +FAIL: ssa-renaming-ternary +- Expected ++ Received + + + ## Input + + ```javascript + function foo(props) { + let x = []; + x.push(props.bar); + props.cond ? ((x = {}), (x = []), x.push(props.foo)) : null; + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function foo(props) { + const $ = _c(4); ++ Object.freeze(props); + let x; + if ($[0] !== props.bar) { + x = []; + x.push(props.bar); + $[0] = props.bar; + $[1] = x; + } else { + x = $[1]; + } + if ($[2] !== props) { + props.cond ? ((x = []), x.push(props.foo)) : null; + $[2] = props; + $[3] = x; + } else { + x = $[3]; + } + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: ssa-renaming-ternary-with-mutation +- Expected ++ Received + + + ## Input + + ```javascript + function foo(props) { + let x = []; + x.push(props.bar); + props.cond ? ((x = {}), (x = []), x.push(props.foo)) : null; + mut(x); + return x; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function foo(props) { + const $ = _c(2); ++ Object.freeze(props); + let x; + if ($[0] !== props) { + x = []; + x.push(props.bar); + props.cond ? ((x = []), x.push(props.foo)) : null; + mut(x); + $[0] = props; + $[1] = x; + } else { + x = $[1]; + } + return x; + } + + ``` +  + +FAIL: ssa-renaming-ternary-destruction +- Expected ++ Received + + + ## Input + + ```javascript + function foo(props) { + let x = []; + x.push(props.bar); + props.cond ? (({x} = {x: {}}), ([x] = [[]]), x.push(props.foo)) : null; + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function foo(props) { + const $ = _c(4); ++ Object.freeze(props); + let x; + if ($[0] !== props.bar) { + x = []; + x.push(props.bar); + $[0] = props.bar; + $[1] = x; + } else { + x = $[1]; + } + if ($[2] !== props) { + props.cond ? (([x] = [[]]), x.push(props.foo)) : null; + $[2] = props; + $[3] = x; + } else { + x = $[3]; + } + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: ssa-renaming-ternary-destruction-with-mutation +- Expected ++ Received + + + ## Input + + ```javascript + function foo(props) { + let x = []; + x.push(props.bar); + props.cond ? (({x} = {x: {}}), ([x] = [[]]), x.push(props.foo)) : null; + mut(x); + return x; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function foo(props) { + const $ = _c(2); ++ Object.freeze(props); + let x; + if ($[0] !== props) { + x = []; + x.push(props.bar); + props.cond ? (([x] = [[]]), x.push(props.foo)) : null; + mut(x); + $[0] = props; + $[1] = x; + } else { + x = $[1]; + } + return x; + } + + ``` +  + +FAIL: ssa-reassign +- Expected ++ Received + + + ## Input + + ```javascript + function foo(a, b, c) { + let x = 0; + x = a; + x = b; + x = c; + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + function foo(a, b, c) { ++ Object.freeze(a); ++ Object.freeze(b); ++ Object.freeze(c); + let x; + + x = c; + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: ssa-property-alias-mutate-inside-if +- Expected ++ Received + + + ## Input + + ```javascript + function foo(a) { + const x = {}; + if (a) { + let y = {}; + x.y = y; + mutate(y); // aliases x & y, but not z + } else { + let z = {}; + x.z = z; + } + return x; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function foo(a) { + const $ = _c(3); ++ Object.freeze(a); + let x; + if ($[0] !== a) { + x = {}; + if (a) { + const y = {}; + x.y = y; + mutate(y); + } else { + let t0; + if ($[2] === Symbol.for("react.memo_cache_sentinel")) { + t0 = {}; + $[2] = t0; + } else { + t0 = $[2]; + } + const z = t0; + x.z = z; + } + $[0] = a; + $[1] = x; + } else { + x = $[1]; + } + return x; + } + + ``` +  + +FAIL: ssa-property-alias-mutate-if +- Expected ++ Received + + + ## Input + + ```javascript + function foo(a) { + const x = {}; + if (a) { + let y = {}; + x.y = y; + } else { + let z = {}; + x.z = z; + } + mutate(x); + return x; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function foo(a) { + const $ = _c(2); ++ Object.freeze(a); + let x; + if ($[0] !== a) { + x = {}; + if (a) { + const y = {}; + x.y = y; + } else { + const z = {}; + x.z = z; + } + + mutate(x); + $[0] = a; + $[1] = x; + } else { + x = $[1]; + } + return x; + } + + ``` +  + +FAIL: ssa-property-alias-if +- Expected ++ Received + + + ## Input + + ```javascript + function foo(a) { + const x = {}; + if (a) { + let y = {}; + x.y = y; + } else { + let z = {}; + x.z = z; + } + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function foo(a) { + const $ = _c(4); ++ Object.freeze(a); + let x; + if ($[0] !== a) { + x = {}; + if (a) { + let t0; + if ($[2] === Symbol.for("react.memo_cache_sentinel")) { + t0 = {}; + $[2] = t0; + } else { + t0 = $[2]; + } + const y = t0; + x.y = y; + } else { + let t0; + if ($[3] === Symbol.for("react.memo_cache_sentinel")) { + t0 = {}; + $[3] = t0; + } else { + t0 = $[3]; + } + const z = t0; + x.z = z; + } + $[0] = a; + $[1] = x; + } else { + x = $[1]; + } + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: ssa-property-alias-alias-mutate-if +- Expected ++ Received + + + ## Input + + ```javascript + function foo(a) { + const b = {}; + const x = b; + if (a) { + let y = {}; + x.y = y; + } else { + let z = {}; + x.z = z; + } + mutate(b); // aliases x, y & z + return x; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function foo(a) { + const $ = _c(2); ++ Object.freeze(a); + let x; + if ($[0] !== a) { + const b = {}; + x = b; + if (a) { + const y = {}; + x.y = y; + } else { + const z = {}; + x.z = z; + } + + mutate(b); + $[0] = a; + $[1] = x; + } else { + x = $[1]; + } + return x; + } + + ``` +  + +FAIL: ssa-objectexpression +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + const a = 1; + const b = 2; + const x = {a: a, b: b}; + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(1); ++ Object.freeze(props); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = { a: 1, b: 2 }; + $[0] = t0; + } else { + t0 = $[0]; + } + const x = t0; + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: ssa-non-empty-initializer +- Expected ++ Received + + + ## Input + + ```javascript + function foo(a, b) { + let x = []; + if (a) { + x = 1; + } + + let y = x; + return y; + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function foo(a, b) { + const $ = _c(1); ++ Object.freeze(a); ++ Object.freeze(b); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = []; + $[0] = t0; + } else { + t0 = $[0]; + } + let x = t0; + if (a) { + x = 1; + } + + const y = x; + return y; + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: ssa-newexpression +- Expected ++ Received + + + ## Input + + ```javascript + function Foo() {} + + function Component(props) { + const a = []; + const b = {}; + let c = new Foo(a, b); + return c; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Foo() {} + + function Component(props) { + const $ = _c(1); ++ Object.freeze(props); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + const a = []; + const b = {}; + t0 = new Foo(a, b); + $[0] = t0; + } else { + t0 = $[0]; + } + const c = t0; + return c; + } + + ``` +  + +FAIL: ssa-nested-partial-reassignment +- Expected ++ Received + + + ## Input + + ```javascript + function foo(a, b, c, d, e) { + let x = null; + if (a) { + x = b; + } else { + if (c) { + x = d; + } + } + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + function foo(a, b, c, d, e) { ++ Object.freeze(a); ++ Object.freeze(b); ++ Object.freeze(c); ++ Object.freeze(d); ++ Object.freeze(e); + let x = null; + if (a) { + x = b; + } else { + if (c) { + x = d; + } + } + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: ssa-nested-partial-phi +- Expected ++ Received + + + ## Input + + ```javascript + function foo(a, b, c) { + let x = a; + if (b) { + if (c) { + x = c; + } + // TODO: move the return to the end of the function + return x; + } + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + function foo(a, b, c) { ++ Object.freeze(a); ++ Object.freeze(b); ++ Object.freeze(c); + let x = a; + if (b) { + if (c) { + x = c; + } + return x; + } + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: ssa-nested-loops-no-reassign +- Expected ++ Received + + + ## Input + + ```javascript + // @xonly + function foo(a, b, c) { + let x = 0; + while (a) { + while (b) { + while (c) { + x + 1; + } + } + } + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + // @xonly + function foo(a, b, c) { ++ Object.freeze(a); ++ Object.freeze(b); ++ Object.freeze(c); + while (a) { + while (b) { + while (c) {} + } + } + return 0; + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: ssa-multiple-phis +- Expected ++ Received + + + ## Input + + ```javascript + function foo(a, b, c, d) { + let x = 0; + if (true) { + if (true) { + x = a; + } else { + x = b; + } + x; + } else { + if (true) { + x = c; + } else { + x = d; + } + x; + } + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + function foo(a, b, c, d) { ++ Object.freeze(a); ++ Object.freeze(b); ++ Object.freeze(c); ++ Object.freeze(d); + let x; + + x = a; + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: ssa-leave-case +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + let x = []; + let y; + if (props.p0) { + x.push(props.p1); + y = x; + } + return ( +  + {x} + {y} +  + ); + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(2); ++ Object.freeze(props); + let t0; + if ($[0] !== props) { + const x = []; + let y; + if (props.p0) { + x.push(props.p1); + y = x; + } + + t0 = ( +  + {x} + {y} +  + ); + $[0] = props; + $[1] = t0; + } else { + t0 = $[1]; + } + return t0; + } + + ``` +  + +FAIL: ssa-for-of +- Expected ++ Received + + + ## Input + + ```javascript + function foo(cond) { + let items = []; + for (const item of items) { + let y = 0; + if (cond) { + y = 1; + } + } + return items; + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function foo(cond) { + const $ = _c(1); ++ Object.freeze(cond); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = []; + $[0] = t0; + } else { + t0 = $[0]; + } + const items = t0; + for (const item of items) { + if (cond) { + } + } + return items; + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: ssa-cascading-eliminated-phis +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + let x = 0; + const values = []; + const y = props.a || props.b; + values.push(y); + if (props.c) { + x = 1; + } + values.push(x); + if (props.d) { + x = 2; + } + values.push(x); + return values; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(4); ++ Object.freeze(props); + let x = 0; + let values; + if ($[0] !== props || $[1] !== x) { + values = []; + const y = props.a || props.b; + values.push(y); + if (props.c) { + x = 1; + } + + values.push(x); + if (props.d) { + x = 2; + } + + values.push(x); + $[0] = props; + $[1] = x; + $[2] = values; + $[3] = x; + } else { + values = $[2]; + x = $[3]; + } + return values; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: ssa-call-jsx +- Expected ++ Received + + + ## Input + + ```javascript + function foo() {} + + function Component(props) { + const a = []; + const b = {}; + foo(a, b); + let _ =
; + foo(a, b); + return
; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function foo() {} + + function Component(props) { + const $ = _c(1); ++ Object.freeze(props); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + const a = []; + const b = {}; + foo(a, b); + + foo(a, b); +- t0 =
; ++ t0 = ( ++  ++ ); + $[0] = t0; + } else { + t0 = $[0]; + } + return t0; + } + + ``` +  + +FAIL: ssa-call-jsx-2 +- Expected ++ Received + + + ## Input + + ```javascript + // @Pass runMutableRangeAnalysis + function foo() {} + + function Component(props) { + const a = []; + const b = {}; + foo(a, b); + if (foo()) { + let _ =
; + } + foo(a, b); + return
; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; // @Pass runMutableRangeAnalysis + function foo() {} + + function Component(props) { + const $ = _c(1); ++ Object.freeze(props); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + const a = []; + const b = {}; + foo(a, b); + if (foo()) { + } + + foo(a, b); +- t0 =
; ++ t0 = ( ++  ++ ); + $[0] = t0; + } else { + t0 = $[0]; + } + return t0; + } + + ``` +  + +FAIL: ssa-arrayexpression +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + const a = 1; + const b = 2; + const x = [a, b]; + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(1); ++ Object.freeze(props); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = [1, 2]; + $[0] = t0; + } else { + t0 = $[0]; + } + const x = t0; + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: simple +- Expected ++ Received + + + ## Input + + ```javascript + export default function foo(x, y) { + if (x) { + return foo(false, y); + } + return [y * 10]; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + export default function foo(x, y) { + const $ = _c(4); ++ Object.freeze(x); ++ Object.freeze(y); + if (x) { + let t0; + if ($[0] !== y) { + t0 = foo(false, y); + $[0] = y; + $[1] = t0; + } else { + t0 = $[1]; + } + return t0; + } + + const t0 = y * 10; + let t1; + if ($[2] !== t0) { + t1 = [t0]; + $[2] = t0; + $[3] = t1; + } else { + t1 = $[3]; + } + return t1; + } + + ``` +  + +FAIL: simple-scope +- Expected ++ Received + + + ## Input + + ```javascript + function foo(a) { + const x = [a.b]; + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function foo(a) { + const $ = _c(2); ++ Object.freeze(a); + let t0; + if ($[0] !== a.b) { + t0 = [a.b]; + $[0] = a.b; + $[1] = t0; + } else { + t0 = $[1]; + } + const x = t0; + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: sequential-destructuring-both-mixed-local-and-scope-declaration + >> Unexpected error during test: + + +Found differences in evaluator results +Non-forget (expected): +(kind: ok)
Sathya!
+Forget: +(kind: ok)
Sathya!
+logs: ['Warning: Invalid value for prop %s on <%s> tag. Either remove it from the element, or pass a string or number value to keep it in the DOM. For details, see https://react.dev/link/attribute-behavior %s','`className`','span','\n' + + ' at span\n' + + ' at div\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)'] + +FAIL: sequential-destructuring-assignment-to-scope-declarations + >> Unexpected error during test: + + +Found differences in evaluator results +Non-forget (expected): +(kind: ok)
Mofei!
+Forget: +(kind: ok)
Mofei!
+logs: ['Warning: Invalid value for prop %s on <%s> tag. Either remove it from the element, or pass a string or number value to keep it in the DOM. For details, see https://react.dev/link/attribute-behavior %s','`className`','span','\n' + + ' at span\n' + + ' at div\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)'] + +FAIL: sequence-expression +- Expected ++ Received + + + ## Input + + ```javascript + function sequence(props) { + let x = (null, Math.max(1, 2), foo()); + while ((foo(), true)) { + x = (foo(), 2); + } + return x; + } + + function foo() {} + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function sequence(props) { + const $ = _c(2); ++ Object.freeze(props); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = (Math.max(1, 2), foo()); + $[0] = t0; + } else { + t0 = $[0]; + } + let x = t0; + if ($[1] === Symbol.for("react.memo_cache_sentinel")) { + while ((foo(), true)) { + x = (foo(), 2); + } + $[1] = x; + } else { + x = $[1]; + } + return x; + } + + function foo() {} + + ``` +  + +FAIL: same-variable-as-dep-and-redeclare +- Expected ++ Received + + + ## Input + + ```javascript + // note: comments are for the ideal scopes, not what is currently + // emitted + function foo(props) { + // scope 0: deps=[props.a] decl=[x] reassign=none + let x = []; + x.push(props.a); + + // scope 1: deps=[x] decl=[header] reassign=none + const header =
{x}
; + + // scope 2: + // deps=[x, props.b, props.c] + // decl=none + // reassign=[x] + const y = [x]; // y depends on the earlier x + x = []; // x reassigned + y.push(props.b); // interleaved mutation of x/y + x.push(props.c); // interleaved mutation + + // scope 3 ... + const content = ( +
 + {x} + {y} +
 + ); + + // scope 4 ... + return ( + <> + {header} + {content} +  + ); + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; // note: comments are for the ideal scopes, not what is currently + // emitted + function foo(props) { + const $ = _c(14); ++ Object.freeze(props); + let x; + let t0; + if ($[0] !== props.a) { + x = []; + x.push(props.a); + + t0 =
{x}
; + $[0] = props.a; + $[1] = x; + $[2] = t0; + } else { + x = $[1]; + t0 = $[2]; + } + const header = t0; + let y; + if ($[3] !== x || $[4] !== props.b || $[5] !== props.c) { + y = [x]; + x = []; + y.push(props.b); + x.push(props.c); + $[3] = x; + $[4] = props.b; + $[5] = props.c; + $[6] = y; + $[7] = x; + } else { + y = $[6]; + x = $[7]; + } + let t1; + if ($[8] !== x || $[9] !== y) { + t1 = ( +
 + {x} + {y} +
 + ); + $[8] = x; + $[9] = y; + $[10] = t1; + } else { + t1 = $[10]; + } + const content = t1; + let t2; + if ($[11] !== header || $[12] !== content) { + t2 = ( + <> + {header} + {content} +  + ); + $[11] = header; + $[12] = content; + $[13] = t2; + } else { + t2 = $[13]; + } + return t2; + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: same-variable-as-dep-and-redeclare-maybe-frozen +- Expected ++ Received + + + ## Input + + ```javascript + // note: comments are for the ideal scopes, not what is currently + // emitted + function foo(props) { + // scope 0: deps=[props.a] decl=[x] reassign=none + let x = []; + x.push(props.a); + + // scope 1: deps=[x] decl=[header] reassign=none + const header = props.showHeader ?
{x}
: null; + + // scope 2: + // deps=[x, props.b, props.c] + // decl=none + // reassign=[x] + const y = [x]; // y depends on the earlier x + x = []; // x reassigned + y.push(props.b); // interleaved mutation of x/y + x.push(props.c); // interleaved mutation + + // scope 3 ... + const content = ( +
 + {x} + {y} +
 + ); + + // scope 4 ... + return ( + <> + {header} + {content} +  + ); + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; // note: comments are for the ideal scopes, not what is currently + // emitted + function foo(props) { + const $ = _c(16); ++ Object.freeze(props); + let x; + if ($[0] !== props.a) { + x = []; + x.push(props.a); + $[0] = props.a; + $[1] = x; + } else { + x = $[1]; + } + let t0; + if ($[2] !== props.showHeader || $[3] !== x) { + t0 = props.showHeader ?
{x}
: null; + $[2] = props.showHeader; + $[3] = x; + $[4] = t0; + } else { + t0 = $[4]; + } + const header = t0; + let y; + if ($[5] !== x || $[6] !== props.b || $[7] !== props.c) { + y = [x]; + x = []; + y.push(props.b); + x.push(props.c); + $[5] = x; + $[6] = props.b; + $[7] = props.c; + $[8] = y; + $[9] = x; + } else { + y = $[8]; + x = $[9]; + } + let t1; + if ($[10] !== x || $[11] !== y) { + t1 = ( +
 + {x} + {y} +
 + ); + $[10] = x; + $[11] = y; + $[12] = t1; + } else { + t1 = $[12]; + } + const content = t1; + let t2; + if ($[13] !== header || $[14] !== content) { + t2 = ( + <> + {header} + {content} +  + ); + $[13] = header; + $[14] = content; + $[15] = t2; + } else { + t2 = $[15]; + } + return t2; + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: reverse-postorder +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + let x; + if (props.cond) { + switch (props.test) { + case 0: { + x = props.v0; + break; + } + case 1: { + x = props.v1; + break; + } + case 2: { + } + default: { + x = props.v2; + } + } + } else { + if (props.cond2) { + x = props.b; + } else { + x = props.c; + } + } + x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + function Component(props) { ++ Object.freeze(props); + if (props.cond) { + bb0: switch (props.test) { + case 0: { + break bb0; + } + case 1: { + break bb0; + } + case 2: { + } + default: { + } + } + } else { + if (props.cond2) { + } + } + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: return-undefined +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + if (props.cond) { + return undefined; + } + return props.value; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + function Component(props) { ++ Object.freeze(props); + if (props.cond) { + return; + } + return props.value; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: return-conditional +- Expected ++ Received + + + ## Input + + ```javascript + function foo(a, b) { + if (a == null) { + return null; + } else { + return b; + } + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + function foo(a, b) { ++ Object.freeze(a); ++ Object.freeze(b); + if (a == null) { + return null; + } else { + return b; + } + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: rest-param-with-object-spread-pattern +- Expected ++ Received + + + ## Input + + ```javascript + function Component(foo, ...{bar}) { + return [foo, bar]; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ['foo', {bar: 'bar'}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(foo, ...t0) { + const $ = _c(3); ++ Object.freeze(foo); ++ Object.freeze(t0); + const { bar } = t0; + let t1; + if ($[0] !== foo || $[1] !== bar) { + t1 = [foo, bar]; + $[0] = foo; + $[1] = bar; + $[2] = t1; + } else { + t1 = $[2]; + } + return t1; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ["foo", { bar: "bar" }], + }; + + ``` +  + ### Eval output + (kind: ok) ["foo",null] + +FAIL: rest-param-with-identifier +- Expected ++ Received + + + ## Input + + ```javascript + function Component(foo, ...bar) { + return [foo, bar]; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ['foo', 'bar', 'baz'], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(foo, ...t0) { + const $ = _c(3); ++ Object.freeze(foo); ++ Object.freeze(t0); + const bar = t0; + let t1; + if ($[0] !== foo || $[1] !== bar) { + t1 = [foo, bar]; + $[0] = foo; + $[1] = bar; + $[2] = t1; + } else { + t1 = $[2]; + } + return t1; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ["foo", "bar", "baz"], + }; + + ``` +  + ### Eval output + (kind: ok) ["foo",["bar","baz"]] + +FAIL: rest-param-with-array-pattern +- Expected ++ Received + + + ## Input + + ```javascript + function Component(foo, ...[bar]) { + return [foo, bar]; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ['foo', ['bar', 'baz']], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(foo, ...t0) { + const $ = _c(3); ++ Object.freeze(foo); ++ Object.freeze(t0); + const [bar] = t0; + let t1; + if ($[0] !== foo || $[1] !== bar) { + t1 = [foo, bar]; + $[0] = foo; + $[1] = bar; + $[2] = t1; + } else { + t1 = $[2]; + } + return t1; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ["foo", ["bar", "baz"]], + }; + + ``` +  + ### Eval output + (kind: ok) ["foo",["bar","baz"]] + +FAIL: resolve-react-hooks-based-on-import-name +- Expected ++ Received + + + ## Input + + ```javascript + import {useState as useReactState} from 'react'; + + function Component() { + const [state, setState] = useReactState(0); + + const onClick = () => { + setState(s => s + 1); + }; + + return ( + <> + Count {state} +  +  + ); + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { useState as useReactState } from "react"; + + function Component() { + const $ = _c(4); +- const [state, setState] = useReactState(0); ++ const [state, setState] = (function () { ++ const $res$ = useReactState(Object.freeze(0)); ++ Object.freeze($res$); ++ return $res$; ++ })(); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = () => { + setState((s) => s + 1); + }; + $[0] = t0; + } else { + t0 = $[0]; + } + const onClick = t0; + let t1; + if ($[1] === Symbol.for("react.memo_cache_sentinel")) { +- t1 = ; ++ t1 = ( ++  ++ Increment ++  ++ ); + $[1] = t1; + } else { + t1 = $[1]; + } + let t2; + if ($[2] !== state) { + t2 = ( + <> + Count {state} + {t1} +  + ); + $[2] = state; + $[3] = t2; + } else { + t2 = $[3]; + } + return t2; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + }; + + ``` +  + ### Eval output + (kind: ok) Count 0 + +FAIL: repro +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + const item = props.item; + const thumbnails = []; + const baseVideos = getBaseVideos(item); + useMemo(() => { + baseVideos.forEach(video => { + const baseVideo = video.hasBaseVideo; + if (Boolean(baseVideo)) { + thumbnails.push({extraVideo: true}); + } + }); + }); + return ; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(7); ++ Object.freeze(props); + const item = props.item; + let t0; + let baseVideos; + let thumbnails; + if ($[0] !== item) { + thumbnails = []; + baseVideos = getBaseVideos(item); + + baseVideos.forEach((video) => { + const baseVideo = video.hasBaseVideo; + if (Boolean(baseVideo)) { + thumbnails.push({ extraVideo: true }); + } + }); + $[0] = item; + $[1] = t0; + $[2] = baseVideos; + $[3] = thumbnails; + } else { + t0 = $[1]; + baseVideos = $[2]; + thumbnails = $[3]; + } + t0 = undefined; + let t1; + if ($[4] !== baseVideos || $[5] !== thumbnails) { +- t1 = ; ++ t1 = ( ++  ++ ); + $[4] = baseVideos; + $[5] = thumbnails; + $[6] = t1; + } else { + t1 = $[6]; + } + return t1; + } + + ``` +  + +FAIL: repro-unreachable-code-early-return-in-useMemo + >> Unexpected error during test: + + +Found differences in evaluator results +Non-forget (expected): +(kind: ok)
{"inputs":[null],"output":"[[ cyclic ref *2 ]]"}
+
{"inputs":[null],"output":"[[ cyclic ref *2 ]]"}
+
{"inputs":[42],"output":{"value":42}}
+
{"inputs":[42],"output":{"value":42}}
+
{"inputs":[null],"output":"[[ cyclic ref *2 ]]"}
+
{"inputs":[42],"output":{"value":42}}
+
{"inputs":[null],"output":"[[ cyclic ref *2 ]]"}
+
{"inputs":[42],"output":{"value":42}}
+Forget: +(kind: ok) [[ (exception in render) Error: Too many re-renders. React limits the number of renders to prevent an infinite loop. ]] +[[ (exception in render) Error: Too many re-renders. React limits the number of renders to prevent an infinite loop. ]] +[[ (exception in render) Error: Too many re-renders. React limits the number of renders to prevent an infinite loop. ]] +[[ (exception in render) Error: Too many re-renders. React limits the number of renders to prevent an infinite loop. ]] +[[ (exception in render) Error: Too many re-renders. React limits the number of renders to prevent an infinite loop. ]] +[[ (exception in render) Error: Too many re-renders. React limits the number of renders to prevent an infinite loop. ]] +[[ (exception in render) Error: Too many re-renders. React limits the number of renders to prevent an infinite loop. ]] +[[ (exception in render) Error: Too many re-renders. React limits the number of renders to prevent an infinite loop. ]] + +FAIL: repro-unmerged-fbt-call-merge-overlapping-reactive-scopes + >> Unexpected error during test: + + +Found differences in evaluator results +Non-forget (expected): +(kind: ok)
{"description":"Text here","label":"3 bars"}
+Forget: +(kind: ok)
{"description":"[[ function params=0 ]]","label":"[[ function params=0 ]]"}
+ +FAIL: repro-undefined-expression-of-jsxexpressioncontainer + >> Unexpected error during test: + + +Found differences in evaluator results +Non-forget (expected): +(kind: ok)
StaticText1
{"type":"submit","children":["Submit!"],"style":{"left":true}}
{"type":"button","children":["Reset"],"style":{"right":true}}
+Forget: +(kind: ok)
StaticText1
{"type":"submit","children":["Submit!"],"style":"[[ function params=0 ]]"}
{"type":"button","children":["Reset"],"style":"[[ function params=0 ]]"}
+logs: ['Warning: Encountered two children with the same key, `%s`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.%s','function () {\n' + + ' const $res$ = `button-${i}`;\n' + + ' Object.freeze($res$);\n' + + ' return $res$;\n' + + ' }','\n' + + ' at div\n' + + ' at StaticText1 (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/shared-runtime.js:187:76)\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)'] + +FAIL: repro-slow-validate-preserve-memo +- Expected ++ Received + + + ## Input + + ```javascript + // @validatePreserveExistingMemoizationGuarantees + + import {Builder} from 'shared-runtime'; + function useTest({isNull, data}: {isNull: boolean; data: string}) { + const result = Builder.makeBuilder(isNull, 'hello world') + ?.push('1', 2) + ?.push(3, { + a: 4, + b: 5, + c: data, + }) + ?.push(6, data) + ?.push(7, '8') + ?.push('8', Builder.makeBuilder(!isNull)?.push(9).vals)?.vals; + return result; + } + + export const FIXTURE_ENTRYPOINT = { + fn: useTest, + params: [{isNull: false, data: 'param'}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; // @validatePreserveExistingMemoizationGuarantees + + import { Builder } from "shared-runtime"; + function useTest(t0) { + const $ = _c(3); ++ Object.freeze(t0); + const { isNull, data } = t0; + let t1; + if ($[0] !== isNull || $[1] !== data) { + t1 = Builder.makeBuilder(isNull, "hello world") + ?.push("1", 2) + ?.push(3, { a: 4, b: 5, c: data }) + ?.push( + 6, + + data, + ) + ?.push(7, "8") + ?.push("8", Builder.makeBuilder(!isNull)?.push(9).vals)?.vals; + $[0] = isNull; + $[1] = data; + $[2] = t1; + } else { + t1 = $[2]; + } + const result = t1; + return result; + } + + export const FIXTURE_ENTRYPOINT = { + fn: useTest, + params: [{ isNull: false, data: "param" }], + }; + + ``` +  + ### Eval output + (kind: ok) ["hello world","1",2,3,{"a":4,"b":5,"c":"param"},6,"param",7,"8","8",null] + +FAIL: repro-separate-scopes-for-divs + >> Unexpected error during test: + + +Found differences in evaluator results +Non-forget (expected): +(kind: ok)
+
+
+Forget: +(kind: ok)
+
+
+logs: ['Warning: Invalid value for prop %s on <%s> tag. Either remove it from the element, or pass a string or number value to keep it in the DOM. For details, see https://react.dev/link/attribute-behavior %s','`className`','div','\n' + + ' at div\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)\n' + + ' at WrapperTestComponentWithErrorBoundary (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:63:9)'] + +FAIL: repro-scope-missing-mutable-range +- Expected ++ Received + + + ## Input + + ```javascript + function HomeDiscoStoreItemTileRating(props) { + const item = useFragment(); + let count = 0; + const aggregates = item?.aggregates || []; + aggregates.forEach(aggregate => { + count += aggregate.count || 0; + }); + + return {count}; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function HomeDiscoStoreItemTileRating(props) { + const $ = _c(4); +- const item = useFragment(); ++ Object.freeze(props); ++ const item = (function () { ++ const $res$ = useFragment(); ++ Object.freeze($res$); ++ return $res$; ++ })(); + let count; + if ($[0] !== item) { + count = 0; + const aggregates = item?.aggregates || []; + aggregates.forEach((aggregate) => { + count = count + (aggregate.count || 0); + count; + }); + $[0] = item; + $[1] = count; + } else { + count = $[1]; + } + + const t0 = count; + let t1; + if ($[2] !== t0) { + t1 = {t0}; + $[2] = t0; + $[3] = t1; + } else { + t1 = $[3]; + } + return t1; + } + + ``` +  + +FAIL: repro-renaming-conflicting-decls + >> Unexpected error during test: + + +Found differences in evaluator results +Non-forget (expected): +(kind: ok)
{"link":{"url":"{\"val\":2}"},"val1":[1],"val2":[2],"val3":[3],"val4":[4],"val5":[5],"children":[{},2]}
+Forget: +(kind: ok)
{"link":"[[ function params=0 ]]","val1":"[[ function params=0 ]]","val2":"[[ function params=0 ]]","val3":"[[ function params=0 ]]","val4":"[[ function params=0 ]]","val5":"[[ function params=0 ]]","children":[{},2]}
+ +FAIL: repro-ref-mutable-range + >> Unexpected error during test: + + +Found differences in evaluator results +Non-forget (expected): +(kind: ok)
{"ref":{"current":"fake-ref-object"}}
+Forget: +(kind: ok)
{"ref":"[[ function params=0 ]]"}
+ +FAIL: repro-reassign-to-variable-without-mutable-range +- Expected ++ Received + + + ## Input + + ```javascript + // @debug + function Component(a, b) { + let x = []; + let y = []; + let z = foo(a); + if (FLAG) { + x = bar(z); + y = baz(b); + } + return [x, y]; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; // @debug + function Component(a, b) { + const $ = _c(11); ++ Object.freeze(a); ++ Object.freeze(b); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = []; + $[0] = t0; + } else { + t0 = $[0]; + } + let x = t0; + let t1; + if ($[1] === Symbol.for("react.memo_cache_sentinel")) { + t1 = []; + $[1] = t1; + } else { + t1 = $[1]; + } + let y = t1; + if ($[2] !== a || $[3] !== b) { + const z = foo(a); + if (FLAG) { + x = bar(z); + let t2; + if ($[6] !== b) { + t2 = baz(b); + $[6] = b; + $[7] = t2; + } else { + t2 = $[7]; + } + y = t2; + } + $[2] = a; + $[3] = b; + $[4] = x; + $[5] = y; + } else { + x = $[4]; + y = $[5]; + } + let t2; + if ($[8] !== x || $[9] !== y) { + t2 = [x, y]; + $[8] = x; + $[9] = y; + $[10] = t2; + } else { + t2 = $[10]; + } + return t2; + } + + ``` +  + +FAIL: repro-object-pattern +- Expected ++ Received + + + ## Input + + ```javascript + function component(t) { + let {a} = t; + let y = {a}; + return y; + } + + export const FIXTURE_ENTRYPOINT = { + fn: component, + params: [{a: 42}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function component(t) { + const $ = _c(2); ++ Object.freeze(t); + const { a } = t; + let t0; + if ($[0] !== a) { + t0 = { a }; + $[0] = a; + $[1] = t0; + } else { + t0 = $[1]; + } + const y = t0; + return y; + } + + export const FIXTURE_ENTRYPOINT = { + fn: component, + params: [{ a: 42 }], + }; + + ``` +  + ### Eval output + (kind: ok) {"a":42} + +FAIL: repro-no-value-for-temporary +- Expected ++ Received + + + ## Input + + ```javascript + // @flow @enableAssumeHooksFollowRulesOfReact @enableTransitivelyFreezeFunctionExpressions + function Component(listItem, thread) { + const isFoo = isFooThread(thread.threadType); + const body = useBar(listItem, [getBadgeText(listItem, isFoo)]); + + return body; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(listItem, thread) { + const $ = _c(7); ++ Object.freeze(listItem); ++ Object.freeze(thread); + let t0; + let t1; + let t2; + if ($[0] !== thread.threadType || $[1] !== listItem) { + const isFoo = isFooThread(thread.threadType); + t1 = useBar; + t2 = listItem; + t0 = getBadgeText(listItem, isFoo); + $[0] = thread.threadType; + $[1] = listItem; + $[2] = t0; + $[3] = t1; + $[4] = t2; + } else { + t0 = $[2]; + t1 = $[3]; + t2 = $[4]; + } + let t3; + if ($[5] !== t0) { + t3 = [t0]; + $[5] = t0; + $[6] = t3; + } else { + t3 = $[6]; + } +- const body = t1(t2, t3); ++ const body = (function () { ++ const $res$ = t1(Object.freeze(t2), Object.freeze(t3)); ++ Object.freeze($res$); ++ return $res$; ++ })(); + return body; + } + + ``` +  + ### Eval output + (kind: exception) Fixture not implemented + +FAIL: repro-no-value-for-temporary-reactive-scope-with-early-return +- Expected ++ Received + + + ## Input + + ```javascript + // @flow @enableAssumeHooksFollowRulesOfReact @enableTransitivelyFreezeFunctionExpressions + import {identity, makeObject_Primitives} from 'shared-runtime'; + import fbt from 'fbt'; + + function Component(props) { + const object = makeObject_Primitives(); + const cond = makeObject_Primitives(); + if (!cond) { + return null; + } + + return ( +
 + {fbt( + 'Lorum ipsum' + fbt.param('thing', object.b) + ' blah blah blah', + 'More text' + )} +
 + ); + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { identity, makeObject_Primitives } from "shared-runtime"; + import fbt from "fbt"; + + function Component(props) { + const $ = _c(2); ++ Object.freeze(props); + let t0; + let t1; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t1 = Symbol.for("react.early_return_sentinel"); + bb0: { + const object = makeObject_Primitives(); + const cond = makeObject_Primitives(); + if (!cond) { + t1 = null; + break bb0; + } + + t0 = ( +
 + {fbt._( + "Lorum ipsum{thing} blah blah blah", + [fbt._param("thing", object.b)], + { hk: "lwmuH" }, + )} +
 + ); + } + $[0] = t0; + $[1] = t1; + } else { + t0 = $[0]; + t1 = $[1]; + } + if (t1 !== Symbol.for("react.early_return_sentinel")) { + return t1; + } + return t0; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + }; + + ``` +  + ### Eval output + (kind: ok)
Lorum ipsumvalue1 blah blah blah
 + +FAIL: repro-no-declarations-in-reactive-scope-with-early-return +- Expected ++ Received + + + ## Input + + ```javascript + // @enableAssumeHooksFollowRulesOfReact @enableTransitivelyFreezeFunctionExpressions + function Component() { + const items = useItems(); + const filteredItems = useMemo( + () => + items.filter(([item]) => { + return item.name != null; + }), + [item] + ); + + if (filteredItems.length === 0) { + // note: this must return nested JSX to create the right scope + // shape that causes no declarations to be emitted + return ( +
 +  +
 + ); + } + + return ( + <> + {filteredItems.map(([item]) => ( +  + ))} +  + ); + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; // @enableAssumeHooksFollowRulesOfReact @enableTransitivelyFreezeFunctionExpressions + function Component() { + const $ = _c(8); +- const items = useItems(); ++ const items = (function () { ++ const $res$ = useItems(); ++ Object.freeze($res$); ++ return $res$; ++ })(); + let t0; + let t1; + let t2; + if ($[0] !== items) { + t2 = Symbol.for("react.early_return_sentinel"); + bb0: { + let t3; + if ($[4] === Symbol.for("react.memo_cache_sentinel")) { + t3 = (t4) => { + const [item] = t4; + return item.name != null; + }; + $[4] = t3; + } else { + t3 = $[4]; + } + t0 = items.filter(t3); + const filteredItems = t0; + if (filteredItems.length === 0) { + let t4; + if ($[5] === Symbol.for("react.memo_cache_sentinel")) { + t4 = ( +
 +  +
 + ); + $[5] = t4; + } else { + t4 = $[5]; + } + t2 = t4; + break bb0; + } + + t1 = filteredItems.map(_temp); + } + $[0] = items; + $[1] = t1; + $[2] = t2; + $[3] = t0; + } else { + t1 = $[1]; + t2 = $[2]; + t0 = $[3]; + } + if (t2 !== Symbol.for("react.early_return_sentinel")) { + return t2; + } + let t3; + if ($[6] !== t1) { + t3 = <>{t1}; + $[6] = t1; + $[7] = t3; + } else { + t3 = $[7]; + } + return t3; + } + function _temp(t0) { + const [item_0] = t0; +- return ; ++ return ( ++  ++ ); + } + + ``` +  + ### Eval output + (kind: exception) Fixture not implemented + +FAIL: repro-mutable-range-extending-into-ternary + >> Unexpected error during test: + + +Found differences in evaluator results +Non-forget (expected): +(kind: ok)
Alice
+
Alice
Bob
+
+
Bob
Claire
+Forget: +(kind: ok)
Alice
+
Alice
Bob
+
+
Bob
Claire
+logs: ['Warning: Encountered two children with the same key, `%s`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.%s','function () {\n' + + ' const $res$ = item.id;\n' + + ' Object.freeze($res$);\n' + + ' return $res$;\n' + + ' }','\n' + + ' at div\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)\n' + + ' at WrapperTestComponentWithErrorBoundary (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:63:9)','Warning: Encountered two children with the same key, `%s`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.%s','function () {\n' + + ' const $res$ = item.id;\n' + + ' Object.freeze($res$);\n' + + ' return $res$;\n' + + ' }','\n' + + ' at div\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)\n' + + ' at WrapperTestComponentWithErrorBoundary (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:63:9)'] + +FAIL: repro-missing-dependency-if-within-while + >> Unexpected error during test: + + +Found differences in evaluator results +Non-forget (expected): +(kind: ok)
0
0
0
0
0
0
0
0
0
0
+
0
0
0
0
0
0
0
0
0
0
+
42
42
42
42
42
42
42
42
42
42
+
42
42
42
42
42
42
42
42
42
42
+
0
0
0
0
0
0
0
0
0
0
+
42
42
42
42
42
42
42
42
42
42
+
0
0
0
0
0
0
0
0
0
0
+
42
42
42
42
42
42
42
42
42
42
+Forget: +(kind: ok)
0
0
0
0
0
0
0
0
0
0
+
0
0
0
0
0
0
0
0
0
0
+
42
42
42
42
42
42
42
42
42
42
+
42
42
42
42
42
42
42
42
42
42
+
0
0
0
0
0
0
0
0
0
0
+
42
42
42
42
42
42
42
42
42
42
+
0
0
0
0
0
0
0
0
0
0
+
42
42
42
42
42
42
42
42
42
42
+logs: ['Warning: Encountered two children with the same key, `%s`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.%s','function () {\n' + + ' const $res$ = i;\n' + + ' Object.freeze($res$);\n' + + ' return $res$;\n' + + ' }','\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)\n' + + ' at WrapperTestComponentWithErrorBoundary (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:63:9)','Warning: Encountered two children with the same key, `%s`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.%s','function () {\n' + + ' const $res$ = i;\n' + + ' Object.freeze($res$);\n' + + ' return $res$;\n' + + ' }','\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)\n' + + ' at WrapperTestComponentWithErrorBoundary (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:63:9)','Warning: Encountered two children with the same key, `%s`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.%s','function () {\n' + + ' const $res$ = i;\n' + + ' Object.freeze($res$);\n' + + ' return $res$;\n' + + ' }','\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)\n' + + ' at WrapperTestComponentWithErrorBoundary (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:63:9)','Warning: Encountered two children with the same key, `%s`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.%s','function () {\n' + + ' const $res$ = i;\n' + + ' Object.freeze($res$);\n' + + ' return $res$;\n' + + ' }','\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)\n' + + ' at WrapperTestComponentWithErrorBoundary (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:63:9)','Warning: Encountered two children with the same key, `%s`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.%s','function () {\n' + + ' const $res$ = i;\n' + + ' Object.freeze($res$);\n' + + ' return $res$;\n' + + ' }','\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)\n' + + ' at WrapperTestComponentWithErrorBoundary (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:63:9)','Warning: Encountered two children with the same key, `%s`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.%s','function () {\n' + + ' const $res$ = i;\n' + + ' Object.freeze($res$);\n' + + ' return $res$;\n' + + ' }','\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)\n' + + ' at WrapperTestComponentWithErrorBoundary (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:63:9)','Warning: Encountered two children with the same key, `%s`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.%s','function () {\n' + + ' const $res$ = i;\n' + + ' Object.freeze($res$);\n' + + ' return $res$;\n' + + ' }','\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)\n' + + ' at WrapperTestComponentWithErrorBoundary (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:63:9)','Warning: Encountered two children with the same key, `%s`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.%s','function () {\n' + + ' const $res$ = i;\n' + + ' Object.freeze($res$);\n' + + ' return $res$;\n' + + ' }','\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)\n' + + ' at WrapperTestComponentWithErrorBoundary (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:63:9)','Warning: Encountered two children with the same key, `%s`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.%s','function () {\n' + + ' const $res$ = i;\n' + + ' Object.freeze($res$);\n' + + ' return $res$;\n' + + ' }','\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)\n' + + ' at WrapperTestComponentWithErrorBoundary (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:63:9)','Warning: Encountered two children with the same key, `%s`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.%s','function () {\n' + + ' const $res$ = i;\n' + + ' Object.freeze($res$);\n' + + ' return $res$;\n' + + ' }','\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)\n' + + ' at WrapperTestComponentWithErrorBoundary (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:63:9)','Warning: Encountered two children with the same key, `%s`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.%s','function () {\n' + + ' const $res$ = i;\n' + + ' Object.freeze($res$);\n' + + ' return $res$;\n' + + ' }','\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)\n' + + ' at WrapperTestComponentWithErrorBoundary (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:63:9)','Warning: Encountered two children with the same key, `%s`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.%s','function () {\n' + + ' const $res$ = i;\n' + + ' Object.freeze($res$);\n' + + ' return $res$;\n' + + ' }','\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)\n' + + ' at WrapperTestComponentWithErrorBoundary (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:63:9)','Warning: Encountered two children with the same key, `%s`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.%s','function () {\n' + + ' const $res$ = i;\n' + + ' Object.freeze($res$);\n' + + ' return $res$;\n' + + ' }','\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)\n' + + ' at WrapperTestComponentWithErrorBoundary (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:63:9)','Warning: Encountered two children with the same key, `%s`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.%s','function () {\n' + + ' const $res$ = i;\n' + + ' Object.freeze($res$);\n' + + ' return $res$;\n' + + ' }','\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)\n' + + ' at WrapperTestComponentWithErrorBoundary (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:63:9)','Warning: Encountered two children with the same key, `%s`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.%s','function () {\n' + + ' const $res$ = i;\n' + + ' Object.freeze($res$);\n' + + ' return $res$;\n' + + ' }','\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)\n' + + ' at WrapperTestComponentWithErrorBoundary (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:63:9)','Warning: Encountered two children with the same key, `%s`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.%s','function () {\n' + + ' const $res$ = i;\n' + + ' Object.freeze($res$);\n' + + ' return $res$;\n' + + ' }','\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)\n' + + ' at WrapperTestComponentWithErrorBoundary (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:63:9)','Warning: Encountered two children with the same key, `%s`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.%s','function () {\n' + + ' const $res$ = i;\n' + + ' Object.freeze($res$);\n' + + ' return $res$;\n' + + ' }','\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)\n' + + ' at WrapperTestComponentWithErrorBoundary (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:63:9)','Warning: Encountered two children with the same key, `%s`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.%s','function () {\n' + + ' const $res$ = i;\n' + + ' Object.freeze($res$);\n' + + ' return $res$;\n' + + ' }','\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)\n' + + ' at WrapperTestComponentWithErrorBoundary (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:63:9)','Warning: Encountered two children with the same key, `%s`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.%s','function () {\n' + + ' const $res$ = i;\n' + + ' Object.freeze($res$);\n' + + ' return $res$;\n' + + ' }','\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)\n' + + ' at WrapperTestComponentWithErrorBoundary (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:63:9)','Warning: Encountered two children with the same key, `%s`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.%s','function () {\n' + + ' const $res$ = i;\n' + + ' Object.freeze($res$);\n' + + ' return $res$;\n' + + ' }','\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)\n' + + ' at WrapperTestComponentWithErrorBoundary (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:63:9)','Warning: Encountered two children with the same key, `%s`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.%s','function () {\n' + + ' const $res$ = i;\n' + + ' Object.freeze($res$);\n' + + ' return $res$;\n' + + ' }','\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)\n' + + ' at WrapperTestComponentWithErrorBoundary (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:63:9)','Warning: Encountered two children with the same key, `%s`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.%s','function () {\n' + + ' const $res$ = i;\n' + + ' Object.freeze($res$);\n' + + ' return $res$;\n' + + ' }','\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)\n' + + ' at WrapperTestComponentWithErrorBoundary (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:63:9)','Warning: Encountered two children with the same key, `%s`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.%s','function () {\n' + + ' const $res$ = i;\n' + + ' Object.freeze($res$);\n' + + ' return $res$;\n' + + ' }','\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)\n' + + ' at WrapperTestComponentWithErrorBoundary (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:63:9)','Warning: Encountered two children with the same key, `%s`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.%s','function () {\n' + + ' const $res$ = i;\n' + + ' Object.freeze($res$);\n' + + ' return $res$;\n' + + ' }','\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)\n' + + ' at WrapperTestComponentWithErrorBoundary (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:63:9)','Warning: Encountered two children with the same key, `%s`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.%s','function () {\n' + + ' const $res$ = i;\n' + + ' Object.freeze($res$);\n' + + ' return $res$;\n' + + ' }','\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)\n' + + ' at WrapperTestComponentWithErrorBoundary (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:63:9)','Warning: Encountered two children with the same key, `%s`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.%s','function () {\n' + + ' const $res$ = i;\n' + + ' Object.freeze($res$);\n' + + ' return $res$;\n' + + ' }','\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)\n' + + ' at WrapperTestComponentWithErrorBoundary (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:63:9)','Warning: Encountered two children with the same key, `%s`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.%s','function () {\n' + + ' const $res$ = i;\n' + + ' Object.freeze($res$);\n' + + ' return $res$;\n' + + ' }','\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)\n' + + ' at WrapperTestComponentWithErrorBoundary (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:63:9)','Warning: Encountered two children with the same key, `%s`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.%s','function () {\n' + + ' const $res$ = i;\n' + + ' Object.freeze($res$);\n' + + ' return $res$;\n' + + ' }','\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)\n' + + ' at WrapperTestComponentWithErrorBoundary (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:63:9)','Warning: Encountered two children with the same key, `%s`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.%s','function () {\n' + + ' const $res$ = i;\n' + + ' Object.freeze($res$);\n' + + ' return $res$;\n' + + ' }','\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)\n' + + ' at WrapperTestComponentWithErrorBoundary (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:63:9)','Warning: Encountered two children with the same key, `%s`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.%s','function () {\n' + + ' const $res$ = i;\n' + + ' Object.freeze($res$);\n' + + ' return $res$;\n' + + ' }','\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)\n' + + ' at WrapperTestComponentWithErrorBoundary (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:63:9)','Warning: Encountered two children with the same key, `%s`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.%s','function () {\n' + + ' const $res$ = i;\n' + + ' Object.freeze($res$);\n' + + ' return $res$;\n' + + ' }','\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)\n' + + ' at WrapperTestComponentWithErrorBoundary (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:63:9)','Warning: Encountered two children with the same key, `%s`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.%s','function () {\n' + + ' const $res$ = i;\n' + + ' Object.freeze($res$);\n' + + ' return $res$;\n' + + ' }','\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)\n' + + ' at WrapperTestComponentWithErrorBoundary (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:63:9)','Warning: Encountered two children with the same key, `%s`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.%s','function () {\n' + + ' const $res$ = i;\n' + + ' Object.freeze($res$);\n' + + ' return $res$;\n' + + ' }','\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)\n' + + ' at WrapperTestComponentWithErrorBoundary (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:63:9)','Warning: Encountered two children with the same key, `%s`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.%s','function () {\n' + + ' const $res$ = i;\n' + + ' Object.freeze($res$);\n' + + ' return $res$;\n' + + ' }','\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)\n' + + ' at WrapperTestComponentWithErrorBoundary (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:63:9)','Warning: Encountered two children with the same key, `%s`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.%s','function () {\n' + + ' const $res$ = i;\n' + + ' Object.freeze($res$);\n' + + ' return $res$;\n' + + ' }','\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)\n' + + ' at WrapperTestComponentWithErrorBoundary (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:63:9)','Warning: Encountered two children with the same key, `%s`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.%s','function () {\n' + + ' const $res$ = i;\n' + + ' Object.freeze($res$);\n' + + ' return $res$;\n' + + ' }','\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)\n' + + ' at WrapperTestComponentWithErrorBoundary (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:63:9)','Warning: Encountered two children with the same key, `%s`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.%s','function () {\n' + + ' const $res$ = i;\n' + + ' Object.freeze($res$);\n' + + ' return $res$;\n' + + ' }','\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)\n' + + ' at WrapperTestComponentWithErrorBoundary (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:63:9)','Warning: Encountered two children with the same key, `%s`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.%s','function () {\n' + + ' const $res$ = i;\n' + + ' Object.freeze($res$);\n' + + ' return $res$;\n' + + ' }','\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)\n' + + ' at WrapperTestComponentWithErrorBoundary (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:63:9)','Warning: Encountered two children with the same key, `%s`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.%s','function () {\n' + + ' const $res$ = i;\n' + + ' Object.freeze($res$);\n' + + ' return $res$;\n' + + ' }','\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)\n' + + ' at WrapperTestComponentWithErrorBoundary (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:63:9)','Warning: Encountered two children with the same key, `%s`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.%s','function () {\n' + + ' const $res$ = i;\n' + + ' Object.freeze($res$);\n' + + ' return $res$;\n' + + ' }','\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)\n' + + ' at WrapperTestComponentWithErrorBoundary (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:63:9)','Warning: Encountered two children with the same key, `%s`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.%s','function () {\n' + + ' const $res$ = i;\n' + + ' Object.freeze($res$);\n' + + ' return $res$;\n' + + ' }','\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)\n' + + ' at WrapperTestComponentWithErrorBoundary (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:63:9)','Warning: Encountered two children with the same key, `%s`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.%s','function () {\n' + + ' const $res$ = i;\n' + + ' Object.freeze($res$);\n' + + ' return $res$;\n' + + ' }','\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)\n' + + ' at WrapperTestComponentWithErrorBoundary (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:63:9)','Warning: Encountered two children with the same key, `%s`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.%s','function () {\n' + + ' const $res$ = i;\n' + + ' Object.freeze($res$);\n' + + ' return $res$;\n' + + ' }','\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)\n' + + ' at WrapperTestComponentWithErrorBoundary (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:63:9)','Warning: Encountered two children with the same key, `%s`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.%s','function () {\n' + + ' const $res$ = i;\n' + + ' Object.freeze($res$);\n' + + ' return $res$;\n' + + ' }','\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)\n' + + ' at WrapperTestComponentWithErrorBoundary (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:63:9)','Warning: Encountered two children with the same key, `%s`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.%s','function () {\n' + + ' const $res$ = i;\n' + + ' Object.freeze($res$);\n' + + ' return $res$;\n' + + ' }','\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)\n' + + ' at WrapperTestComponentWithErrorBoundary (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:63:9)','Warning: Encountered two children with the same key, `%s`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.%s','function () {\n' + + ' const $res$ = i;\n' + + ' Object.freeze($res$);\n' + + ' return $res$;\n' + + ' }','\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)\n' + + ' at WrapperTestComponentWithErrorBoundary (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:63:9)','Warning: Encountered two children with the same key, `%s`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.%s','function () {\n' + + ' const $res$ = i;\n' + + ' Object.freeze($res$);\n' + + ' return $res$;\n' + + ' }','\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)\n' + + ' at WrapperTestComponentWithErrorBoundary (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:63:9)','Warning: Encountered two children with the same key, `%s`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.%s','function () {\n' + + ' const $res$ = i;\n' + + ' Object.freeze($res$);\n' + + ' return $res$;\n' + + ' }','\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)\n' + + ' at WrapperTestComponentWithErrorBoundary (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:63:9)','Warning: Encountered two children with the same key, `%s`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.%s','function () {\n' + + ' const $res$ = i;\n' + + ' Object.freeze($res$);\n' + + ' return $res$;\n' + + ' }','\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)\n' + + ' at WrapperTestComponentWithErrorBoundary (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:63:9)','Warning: Encountered two children with the same key, `%s`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.%s','function () {\n' + + ' const $res$ = i;\n' + + ' Object.freeze($res$);\n' + + ' return $res$;\n' + + ' }','\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)\n' + + ' at WrapperTestComponentWithErrorBoundary (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:63:9)','Warning: Encountered two children with the same key, `%s`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.%s','function () {\n' + + ' const $res$ = i;\n' + + ' Object.freeze($res$);\n' + + ' return $res$;\n' + + ' }','\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)\n' + + ' at WrapperTestComponentWithErrorBoundary (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:63:9)','Warning: Encountered two children with the same key, `%s`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.%s','function () {\n' + + ' const $res$ = i;\n' + + ' Object.freeze($res$);\n' + + ' return $res$;\n' + + ' }','\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)\n' + + ' at WrapperTestComponentWithErrorBoundary (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:63:9)','Warning: Encountered two children with the same key, `%s`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.%s','function () {\n' + + ' const $res$ = i;\n' + + ' Object.freeze($res$);\n' + + ' return $res$;\n' + + ' }','\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)\n' + + ' at WrapperTestComponentWithErrorBoundary (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:63:9)','Warning: Encountered two children with the same key, `%s`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.%s','function () {\n' + + ' const $res$ = i;\n' + + ' Object.freeze($res$);\n' + + ' return $res$;\n' + + ' }','\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)\n' + + ' at WrapperTestComponentWithErrorBoundary (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:63:9)','Warning: Encountered two children with the same key, `%s`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.%s','function () {\n' + + ' const $res$ = i;\n' + + ' Object.freeze($res$);\n' + + ' return $res$;\n' + + ' }','\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)\n' + + ' at WrapperTestComponentWithErrorBoundary (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:63:9)','Warning: Encountered two children with the same key, `%s`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.%s','function () {\n' + + ' const $res$ = i;\n' + + ' Object.freeze($res$);\n' + + ' return $res$;\n' + + ' }','\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)\n' + + ' at WrapperTestComponentWithErrorBoundary (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:63:9)','Warning: Encountered two children with the same key, `%s`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.%s','function () {\n' + + ' const $res$ = i;\n' + + ' Object.freeze($res$);\n' + + ' return $res$;\n' + + ' }','\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)\n' + + ' at WrapperTestComponentWithErrorBoundary (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:63:9)','Warning: Encountered two children with the same key, `%s`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.%s','function () {\n' + + ' const $res$ = i;\n' + + ' Object.freeze($res$);\n' + + ' return $res$;\n' + + ' }','\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)\n' + + ' at WrapperTestComponentWithErrorBoundary (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:63:9)','Warning: Encountered two children with the same key, `%s`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.%s','function () {\n' + + ' const $res$ = i;\n' + + ' Object.freeze($res$);\n' + + ' return $res$;\n' + + ' }','\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)\n' + + ' at WrapperTestComponentWithErrorBoundary (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:63:9)','Warning: Encountered two children with the same key, `%s`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.%s','function () {\n' + + ' const $res$ = i;\n' + + ' Object.freeze($res$);\n' + + ' return $res$;\n' + + ' }','\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)\n' + + ' at WrapperTestComponentWithErrorBoundary (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:63:9)','Warning: Encountered two children with the same key, `%s`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.%s','function () {\n' + + ' const $res$ = i;\n' + + ' Object.freeze($res$);\n' + + ' return $res$;\n' + + ' }','\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)\n' + + ' at WrapperTestComponentWithErrorBoundary (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:63:9)','Warning: Encountered two children with the same key, `%s`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.%s','function () {\n' + + ' const $res$ = i;\n' + + ' Object.freeze($res$);\n' + + ' return $res$;\n' + + ' }','\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)\n' + + ' at WrapperTestComponentWithErrorBoundary (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:63:9)','Warning: Encountered two children with the same key, `%s`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.%s','function () {\n' + + ' const $res$ = i;\n' + + ' Object.freeze($res$);\n' + + ' return $res$;\n' + + ' }','\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)\n' + + ' at WrapperTestComponentWithErrorBoundary (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:63:9)','Warning: Encountered two children with the same key, `%s`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.%s','function () {\n' + + ' const $res$ = i;\n' + + ' Object.freeze($res$);\n' + + ' return $res$;\n' + + ' }','\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)\n' + + ' at WrapperTestComponentWithErrorBoundary (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:63:9)','Warning: Encountered two children with the same key, `%s`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.%s','function () {\n' + + ' const $res$ = i;\n' + + ' Object.freeze($res$);\n' + + ' return $res$;\n' + + ' }','\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)\n' + + ' at WrapperTestComponentWithErrorBoundary (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:63:9)','Warning: Encountered two children with the same key, `%s`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.%s','function () {\n' + + ' const $res$ = i;\n' + + ' Object.freeze($res$);\n' + + ' return $res$;\n' + + ' }','\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)\n' + + ' at WrapperTestComponentWithErrorBoundary (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:63:9)','Warning: Encountered two children with the same key, `%s`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.%s','function () {\n' + + ' const $res$ = i;\n' + + ' Object.freeze($res$);\n' + + ' return $res$;\n' + + ' }','\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)\n' + + ' at WrapperTestComponentWithErrorBoundary (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:63:9)','Warning: Encountered two children with the same key, `%s`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.%s','function () {\n' + + ' const $res$ = i;\n' + + ' Object.freeze($res$);\n' + + ' return $res$;\n' + + ' }','\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)\n' + + ' at WrapperTestComponentWithErrorBoundary (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:63:9)','Warning: Encountered two children with the same key, `%s`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.%s','function () {\n' + + ' const $res$ = i;\n' + + ' Object.freeze($res$);\n' + + ' return $res$;\n' + + ' }','\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)\n' + + ' at WrapperTestComponentWithErrorBoundary (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:63:9)','Warning: Encountered two children with the same key, `%s`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.%s','function () {\n' + + ' const $res$ = i;\n' + + ' Object.freeze($res$);\n' + + ' return $res$;\n' + + ' }','\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)\n' + + ' at WrapperTestComponentWithErrorBoundary (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:63:9)','Warning: Encountered two children with the same key, `%s`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.%s','function () {\n' + + ' const $res$ = i;\n' + + ' Object.freeze($res$);\n' + + ' return $res$;\n' + + ' }','\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)\n' + + ' at WrapperTestComponentWithErrorBoundary (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:63:9)','Warning: Encountered two children with the same key, `%s`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.%s','function () {\n' + + ' const $res$ = i;\n' + + ' Object.freeze($res$);\n' + + ' return $res$;\n' + + ' }','\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)\n' + + ' at WrapperTestComponentWithErrorBoundary (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:63:9)'] + +FAIL: repro-memoize-array-with-immutable-map-after-hook +- Expected ++ Received + + + ## Input + + ```javascript + import {useEffect, useState} from 'react'; + + function Component(props) { + const x = [props.value]; + useEffect(() => {}, []); + const onClick = () => { + console.log(x.length); + }; + return ( +
 + {x.map(item => { + return {item}; + })} +
 + ); + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{value: 42}], + isComponent: true, + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { useEffect, useState } from "react"; + + function Component(props) { + const $ = _c(10); ++ Object.freeze(props); + let t0; + if ($[0] !== props.value) { + t0 = [props.value]; + $[0] = props.value; + $[1] = t0; + } else { + t0 = $[1]; + } + const x = t0; + let t1; + if ($[2] === Symbol.for("react.memo_cache_sentinel")) { + t1 = []; + $[2] = t1; + } else { + t1 = $[2]; + } +- useEffect(_temp, t1); ++ (function () { ++ const $res$ = useEffect(Object.freeze(_temp), Object.freeze(t1)); ++ Object.freeze($res$); ++ return $res$; ++ })(); + let t2; + if ($[3] !== x.length) { + t2 = () => { + console.log(x.length); + }; + $[3] = x.length; + $[4] = t2; + } else { + t2 = $[4]; + } + const onClick = t2; + let t3; + if ($[5] !== x) { + t3 = x.map(_temp2); + $[5] = x; + $[6] = t3; + } else { + t3 = $[6]; + } + let t4; + if ($[7] !== onClick || $[8] !== t3) { +- t4 =
{t3}
; ++ t4 = ( ++  ++ {t3} ++
 ++ ); + $[7] = onClick; + $[8] = t3; + $[9] = t4; + } else { + t4 = $[9]; + } + return t4; + } + function _temp2(item) { +- return {item}; ++ return ( ++  ++ {item} ++  ++ ); + } + function _temp() {} + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ value: 42 }], + isComponent: true, + }; + + ``` +  + ### Eval output + (kind: ok)
42
 + +FAIL: repro-invalid-scope-merging-value-blocks +- Expected ++ Received + + + ## Input + + ```javascript + import { + CONST_TRUE, + identity, + makeObject_Primitives, + mutateAndReturn, + useHook, + } from 'shared-runtime'; + + /** + * value and `mutateAndReturn(value)` should end up in the same reactive scope. + * (1) `value = makeObject` and `(temporary) = mutateAndReturn(value)` should be assigned + * the same scope id (on their identifiers) + * (2) alignScopesToBlockScopes should expand the scopes of both `(temporary) = identity(1)` + * and `(temporary) = mutateAndReturn(value)` to the outermost value block boundaries + * (3) mergeOverlappingScopes should merge the scopes of the above two instructions + */ + function Component({}) { + const value = makeObject_Primitives(); + useHook(); + const mutatedValue = + identity(1) && CONST_TRUE ? mutateAndReturn(value) : null; + const result = []; + useHook(); + result.push(value, mutatedValue); + return result; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + sequentialRenders: [{}, {}, {}], + }; + + ``` + + ## Code + + ```javascript + import { + CONST_TRUE, + identity, + makeObject_Primitives, + mutateAndReturn, + useHook, + } from "shared-runtime"; + + /** + * value and `mutateAndReturn(value)` should end up in the same reactive scope. + * (1) `value = makeObject` and `(temporary) = mutateAndReturn(value)` should be assigned + * the same scope id (on their identifiers) + * (2) alignScopesToBlockScopes should expand the scopes of both `(temporary) = identity(1)` + * and `(temporary) = mutateAndReturn(value)` to the outermost value block boundaries + * (3) mergeOverlappingScopes should merge the scopes of the above two instructions + */ + function Component(t0) { ++ Object.freeze(t0); + const value = makeObject_Primitives(); +- useHook(); ++ (function () { ++ const $res$ = useHook(); ++ Object.freeze($res$); ++ return $res$; ++ })(); + const mutatedValue = + identity(1) && CONST_TRUE ? mutateAndReturn(value) : null; + const result = []; +- useHook(); ++ (function () { ++ const $res$ = useHook(); ++ Object.freeze($res$); ++ return $res$; ++ })(); + result.push(value, mutatedValue); + return result; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + sequentialRenders: [{}, {}, {}], + }; + + ``` +  + ### Eval output + (kind: ok) [{"a":0,"b":"value1","c":true,"wat0":"joe"},"[[ cyclic ref *1 ]]"] + [{"a":0,"b":"value1","c":true,"wat0":"joe"},"[[ cyclic ref *1 ]]"] + [{"a":0,"b":"value1","c":true,"wat0":"joe"},"[[ cyclic ref *1 ]]"] + +FAIL: repro-invalid-reactivity-value-block +- Expected ++ Received + + + ## Input + + ```javascript + import { + CONST_TRUE, + identity, + makeObject_Primitives, + useNoAlias, + } from 'shared-runtime'; + + /** + * Here the scope for `obj` is pruned because it spans the `useNoAlias()` hook call. + * Because `obj` is non-reactive, it would by default be excluded as dependency for + * `result = [...identity(obj)..., obj]`, but this could then cause the values in + * `result` to be out of sync with `obj`. + * + * The fix is to consider pruned memo block outputs as reactive, since they will + * recreate on every render. This means `thing` depends on both y and z. + */ + function Foo() { + const obj = makeObject_Primitives(); + // hook calls keeps the next two lines as its own reactive scope + useNoAlias(); + + const shouldCaptureObj = obj != null && CONST_TRUE; + const result = [shouldCaptureObj ? identity(obj) : null, obj]; + + useNoAlias(result, obj); + + if (shouldCaptureObj && result[0] !== obj) { + throw new Error('Unexpected'); + } + return result; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Foo, + params: [{}], + sequentialRenders: [{}, {}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { + CONST_TRUE, + identity, + makeObject_Primitives, + useNoAlias, + } from "shared-runtime"; + + /** + * Here the scope for `obj` is pruned because it spans the `useNoAlias()` hook call. + * Because `obj` is non-reactive, it would by default be excluded as dependency for + * `result = [...identity(obj)..., obj]`, but this could then cause the values in + * `result` to be out of sync with `obj`. + * + * The fix is to consider pruned memo block outputs as reactive, since they will + * recreate on every render. This means `thing` depends on both y and z. + */ + function Foo() { + const $ = _c(3); + const obj = makeObject_Primitives(); +- +- useNoAlias(); ++ (function () { ++ const $res$ = useNoAlias(); ++ Object.freeze($res$); ++ return $res$; ++ })(); + + const shouldCaptureObj = obj != null && CONST_TRUE; + const t0 = shouldCaptureObj ? identity(obj) : null; + let t1; + if ($[0] !== t0 || $[1] !== obj) { + t1 = [t0, obj]; + $[0] = t0; + $[1] = obj; + $[2] = t1; + } else { + t1 = $[2]; + } + const result = t1; +- +- useNoAlias(result, obj); ++ (function () { ++ const $res$ = useNoAlias(Object.freeze(result), Object.freeze(obj)); ++ Object.freeze($res$); ++ return $res$; ++ })(); + if (shouldCaptureObj && result[0] !== obj) { + throw new Error("Unexpected"); + } + return result; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Foo, + params: [{}], + sequentialRenders: [{}, {}], + }; + + ``` +  + ### Eval output + (kind: ok) [{"a":0,"b":"value1","c":true},"[[ cyclic ref *1 ]]"] + [{"a":0,"b":"value1","c":true},"[[ cyclic ref *1 ]]"] + +FAIL: repro-invalid-pruned-scope-leaks-value +- Expected ++ Received + + + ## Input + + ```javascript + import invariant from 'invariant'; + import {makeObject_Primitives, mutate, sum, useIdentity} from 'shared-runtime'; + + /** + * Here, `z`'s original memo block is removed due to the inner hook call. + * However, we also infer that `z` is non-reactive, so by default we would create + * the memo block for `thing = [y, z]` as only depending on `y`. + * + * This could then mean that `thing[1]` and `z` may not refer to the same value, + * since z recreates every time but `thing` doesn't correspondingly invalidate. + * + * The fix is to consider pruned memo block outputs as reactive, since they will + * recreate on every render. This means `thing` depends on both y and z. + */ + function MyApp({count}) { + const z = makeObject_Primitives(); + const x = useIdentity(2); + const y = sum(x, count); + mutate(z); + const thing = [y, z]; + if (thing[1] !== z) { + invariant(false, 'oh no!'); + } + return thing; + } + + export const FIXTURE_ENTRYPOINT = { + fn: MyApp, + params: [{count: 2}], + sequentialRenders: [{count: 2}, {count: 2}, {count: 3}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import invariant from "invariant"; + import { + makeObject_Primitives, + mutate, + sum, + useIdentity, + } from "shared-runtime"; + + /** + * Here, `z`'s original memo block is removed due to the inner hook call. + * However, we also infer that `z` is non-reactive, so by default we would create + * the memo block for `thing = [y, z]` as only depending on `y`. + * + * This could then mean that `thing[1]` and `z` may not refer to the same value, + * since z recreates every time but `thing` doesn't correspondingly invalidate. + * + * The fix is to consider pruned memo block outputs as reactive, since they will + * recreate on every render. This means `thing` depends on both y and z. + */ + function MyApp(t0) { + const $ = _c(6); ++ Object.freeze(t0); + const { count } = t0; + const z = makeObject_Primitives(); +- const x = useIdentity(2); ++ const x = (function () { ++ const $res$ = useIdentity(Object.freeze(2)); ++ Object.freeze($res$); ++ return $res$; ++ })(); + let t1; + if ($[0] !== x || $[1] !== count) { + t1 = sum(x, count); + $[0] = x; + $[1] = count; + $[2] = t1; + } else { + t1 = $[2]; + } + const y = t1; + mutate(z); + let t2; + if ($[3] !== y || $[4] !== z) { + t2 = [y, z]; + $[3] = y; + $[4] = z; + $[5] = t2; + } else { + t2 = $[5]; + } + const thing = t2; + if (thing[1] !== z) { + invariant(false, "oh no!"); + } + return thing; + } + + export const FIXTURE_ENTRYPOINT = { + fn: MyApp, + params: [{ count: 2 }], + sequentialRenders: [{ count: 2 }, { count: 2 }, { count: 3 }], + }; + + ``` +  + ### Eval output + (kind: ok) [4,{"a":0,"b":"value1","c":true,"wat0":"joe"}] + [4,{"a":0,"b":"value1","c":true,"wat0":"joe"}] + [5,{"a":0,"b":"value1","c":true,"wat0":"joe"}] + +FAIL: repro-invalid-pruned-scope-leaks-value-via-alias +- Expected ++ Received + + + ## Input + + ```javascript + import invariant from 'invariant'; + import {makeObject_Primitives, mutate, sum, useIdentity} from 'shared-runtime'; + + /** + * Here, `z`'s original memo block is removed due to the inner hook call. + * However, we also infer that `z` is non-reactive, so by default we would create + * the memo block for `thing = [y, z]` as only depending on `y`. + * + * This could then mean that `thing[1]` and `z` may not refer to the same value, + * since z recreates every time but `thing` doesn't correspondingly invalidate. + * + * The fix is to consider pruned memo block outputs as reactive, since they will + * recreate on every render. This means `thing` depends on both y and z. + */ + function MyApp({count}) { + const z = makeObject_Primitives(); + const x = useIdentity(2); + const y = sum(x, count); + mutate(z); + const z2 = z; + const thing = [y, z2]; + if (thing[1] !== z) { + invariant(false, 'oh no!'); + } + return thing; + } + + export const FIXTURE_ENTRYPOINT = { + fn: MyApp, + params: [{count: 2}], + sequentialRenders: [{count: 2}, {count: 2}, {count: 3}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import invariant from "invariant"; + import { + makeObject_Primitives, + mutate, + sum, + useIdentity, + } from "shared-runtime"; + + /** + * Here, `z`'s original memo block is removed due to the inner hook call. + * However, we also infer that `z` is non-reactive, so by default we would create + * the memo block for `thing = [y, z]` as only depending on `y`. + * + * This could then mean that `thing[1]` and `z` may not refer to the same value, + * since z recreates every time but `thing` doesn't correspondingly invalidate. + * + * The fix is to consider pruned memo block outputs as reactive, since they will + * recreate on every render. This means `thing` depends on both y and z. + */ + function MyApp(t0) { + const $ = _c(6); ++ Object.freeze(t0); + const { count } = t0; + const z = makeObject_Primitives(); +- const x = useIdentity(2); ++ const x = (function () { ++ const $res$ = useIdentity(Object.freeze(2)); ++ Object.freeze($res$); ++ return $res$; ++ })(); + let t1; + if ($[0] !== x || $[1] !== count) { + t1 = sum(x, count); + $[0] = x; + $[1] = count; + $[2] = t1; + } else { + t1 = $[2]; + } + const y = t1; + mutate(z); + const z2 = z; + let t2; + if ($[3] !== y || $[4] !== z2) { + t2 = [y, z2]; + $[3] = y; + $[4] = z2; + $[5] = t2; + } else { + t2 = $[5]; + } + const thing = t2; + if (thing[1] !== z) { + invariant(false, "oh no!"); + } + return thing; + } + + export const FIXTURE_ENTRYPOINT = { + fn: MyApp, + params: [{ count: 2 }], + sequentialRenders: [{ count: 2 }, { count: 2 }, { count: 3 }], + }; + + ``` +  + ### Eval output + (kind: ok) [4,{"a":0,"b":"value1","c":true,"wat0":"joe"}] + [4,{"a":0,"b":"value1","c":true,"wat0":"joe"}] + [5,{"a":0,"b":"value1","c":true,"wat0":"joe"}] + +FAIL: repro-instruction-part-of-already-closed-scope + >> Unexpected error during test: + + +Found differences in evaluator results +Non-forget (expected): +(kind: ok)
{"value":{"a":0,"b":"value1","c":true}}
{"value":{"a":0,"b":"value1","c":true}}
{"value":{"a":0,"b":"value1","c":true}}
+Forget: +(kind: ok)
{"value":"[[ function params=0 ]]"}
{"value":"[[ function params=0 ]]"}
{"value":"[[ function params=0 ]]"}
+ +FAIL: repro-independently-memoized-property-load-for-method-call +- Expected ++ Received + + + ## Input + + ```javascript + // @flow @enableAssumeHooksFollowRulesOfReact + function Component({label, highlightedItem}) { + const serverTime = useServerTime(); + const highlight = new Highlight(highlightedItem); + + const time = serverTime.get(); + // subtle bit here: the binary expression infers the result of the call + // as a primitive and not needing memoization. the logical is necessary + // because without it there are no intermediate scopes which observe + // the result of the binary expression, so its memoization can be pruned + const timestampLabel = time / 1000 || label; + + return ( + <> + {highlight.render()} + {timestampLabel} +  + ); + } + + function useServerTime() { + 'use no forget'; + + return { + get() { + return 42000; // would be a constant value from the server + }, + }; + } + + class Highlight { + constructor(value) { + this.value = value; + } + + render() { + return this.value; + } + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{label: '', highlightedItem: 'Seconds passed: '}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(t0) { + const $ = _c(8); ++ Object.freeze(t0); + const { label, highlightedItem } = t0; +- const serverTime = useServerTime(); ++ const serverTime = (function () { ++ const $res$ = useServerTime(); ++ Object.freeze($res$); ++ return $res$; ++ })(); + let t1; + let timestampLabel; + if ($[0] !== highlightedItem || $[1] !== serverTime || $[2] !== label) { + const highlight = new Highlight(highlightedItem); + + const time = serverTime.get(); + + timestampLabel = time / 1000 || label; + + t1 = highlight.render(); + $[0] = highlightedItem; + $[1] = serverTime; + $[2] = label; + $[3] = t1; + $[4] = timestampLabel; + } else { + t1 = $[3]; + timestampLabel = $[4]; + } + let t2; + if ($[5] !== t1 || $[6] !== timestampLabel) { + t2 = ( + <> + {t1} + {timestampLabel} +  + ); + $[5] = t1; + $[6] = timestampLabel; + $[7] = t2; + } else { + t2 = $[7]; + } + return t2; + } + + function useServerTime() { + "use no forget"; + + return { + get() { + return 42000; + }, + }; + } + + class Highlight { + constructor(value) { + this.value = value; + } + + render() { + return this.value; + } + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ label: "", highlightedItem: "Seconds passed: " }], + }; + + ``` +  + ### Eval output + (kind: ok) Seconds passed: 42 + +FAIL: repro-hoisting +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + const wat = () => { + const pathname = 'wat'; + pathname; + }; + + const pathname = props.wat; + const deeplinkItemId = pathname ? props.itemID : null; + + return ; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{wat: '/dev/null', itemID: 42}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(3); ++ Object.freeze(props); + const wat = _temp; + + const pathname_0 = props.wat; + const deeplinkItemId = pathname_0 ? props.itemID : null; + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = () => wat(); + $[0] = t0; + } else { + t0 = $[0]; + } + let t1; + if ($[1] !== deeplinkItemId) { +- t1 = ; ++ t1 = ( ++  ++ {deeplinkItemId} ++  ++ ); + $[1] = deeplinkItemId; + $[2] = t1; + } else { + t1 = $[2]; + } + return t1; + } + function _temp() {} + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ wat: "/dev/null", itemID: 42 }], + }; + + ``` +  + ### Eval output + (kind: ok)  + +FAIL: repro-hoisting-variable-collision +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + const items = props.items.map(x => x); + const x = 42; + return [x, items]; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{items: [0, 42, null, undefined, {object: true}]}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(4); ++ Object.freeze(props); + let t0; + if ($[0] !== props.items) { + t0 = props.items.map(_temp); + $[0] = props.items; + $[1] = t0; + } else { + t0 = $[1]; + } + const items = t0; + let t1; + if ($[2] !== items) { + t1 = [42, items]; + $[2] = items; + $[3] = t1; + } else { + t1 = $[3]; + } + return t1; + } + function _temp(x) { + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ items: [0, 42, null, undefined, { object: true }] }], + }; + + ``` +  + ### Eval output + (kind: ok) [42,[0,42,null,null,{"object":true}]] + +FAIL: repro-duplicate-type-import +- Expected ++ Received + + + ## Input + + ```javascript + import type {ReactElement} from 'react'; + + function Component(_props: {}): ReactElement { + return
hello world
; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import type { ReactElement } from "react"; + + function Component(_props) { + const $ = _c(1); ++ Object.freeze(_props); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 =
hello world
; + $[0] = t0; + } else { + t0 = $[0]; + } + return t0; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + }; + + ``` +  + ### Eval output + (kind: ok)
hello world
 + +FAIL: repro-duplicate-instruction-from-merge-consecutive-scopes + >> Unexpected error during test: + + +Found differences in evaluator results +Non-forget (expected): +(kind: ok)
{}
{"title":false}
+Forget: +(kind: ok)
{"title":"[[ function params=0 ]]"}
{"title":"[[ function params=0 ]]"}
+ +FAIL: repro-duplicate-import-specifier +- Expected ++ Received + + + ## Input + + ```javascript + import type {SetStateAction, Dispatch} from 'react'; + import {useState} from 'react'; + + function Component(_props: {}) { + const [x, _setX]: [number, Dispatch>] = useState(0); + return {x}; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import type { SetStateAction, Dispatch } from "react"; + import { useState } from "react"; + + function Component(_props) { + const $ = _c(2); +- const [x] = useState(0); ++ Object.freeze(_props); ++ const [x] = (function () { ++ const $res$ = useState(Object.freeze(0)); ++ Object.freeze($res$); ++ return $res$; ++ })(); + let t0; + if ($[0] !== x) { + t0 = { x }; + $[0] = x; + $[1] = t0; + } else { + t0 = $[1]; + } + return t0; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + }; + + ``` +  + ### Eval output + (kind: ok) {"x":0} + +FAIL: repro-dont-memoize-array-with-mutable-map-after-hook +- Expected ++ Received + + + ## Input + + ```javascript + import {useEffect, useState} from 'react'; + import {mutate} from 'shared-runtime'; + + function Component(props) { + const x = [{...props.value}]; + useEffect(() => {}, []); + const onClick = () => { + console.log(x.length); + }; + let y; + return ( +
 + {x.map(item => { + item.flag = true; + return {item.text}; + })} + {mutate(y)} +
 + ); + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{value: {id: 0, text: 'Hello', flag: false}}], + isComponent: true, + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { useEffect, useState } from "react"; + import { mutate } from "shared-runtime"; + + function Component(props) { + const $ = _c(7); ++ Object.freeze(props); + const x = [{ ...props.value }]; + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = []; + $[0] = t0; + } else { + t0 = $[0]; + } +- useEffect(_temp, t0); ++ (function () { ++ const $res$ = useEffect(Object.freeze(_temp), Object.freeze(t0)); ++ Object.freeze($res$); ++ return $res$; ++ })(); + const onClick = () => { + console.log(x.length); + }; + + let y; + + const t1 = x.map(_temp2); + let t2; + if ($[1] !== y) { + t2 = mutate(y); + $[1] = y; + $[2] = t2; + } else { + t2 = $[2]; + } + let t3; + if ($[3] !== onClick || $[4] !== t1 || $[5] !== t2) { + t3 = ( +-
 ++  + {t1} + {t2} +
 + ); + $[3] = onClick; + $[4] = t1; + $[5] = t2; + $[6] = t3; + } else { + t3 = $[6]; + } + return t3; + } + function _temp2(item) { + item.flag = true; +- return {item.text}; ++ return ( ++  ++ {item.text} ++  ++ ); + } + function _temp() {} + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ value: { id: 0, text: "Hello", flag: false } }], + isComponent: true, + }; + + ``` +  + ### Eval output + (kind: ok)
Hello
 + +FAIL: repro-dont-memoize-array-with-capturing-map-after-hook +- Expected ++ Received + + + ## Input + + ```javascript + import {useEffect, useState} from 'react'; + import {mutate} from 'shared-runtime'; + + function Component(props) { + const x = [{...props.value}]; + useEffect(() => {}, []); + const onClick = () => { + console.log(x.length); + }; + let y; + return ( +
 + {x.map(item => { + y = item; + return {item.text}; + })} + {mutate(y)} +
 + ); + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{value: {id: 0, text: 'Hello!'}}], + isComponent: true, + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { useEffect, useState } from "react"; + import { mutate } from "shared-runtime"; + + function Component(props) { + const $ = _c(5); ++ Object.freeze(props); + const x = [{ ...props.value }]; + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = []; + $[0] = t0; + } else { + t0 = $[0]; + } +- useEffect(_temp, t0); ++ (function () { ++ const $res$ = useEffect(Object.freeze(_temp), Object.freeze(t0)); ++ Object.freeze($res$); ++ return $res$; ++ })(); + const onClick = () => { + console.log(x.length); + }; + + let y; + + const t1 = x.map((item) => { + y = item; +- return {item.text}; ++ return ( ++  ++ {item.text} ++  ++ ); + }); + const t2 = mutate(y); + let t3; + if ($[1] !== onClick || $[2] !== t1 || $[3] !== t2) { + t3 = ( +-
 ++  + {t1} + {t2} +
 + ); + $[1] = onClick; + $[2] = t1; + $[3] = t2; + $[4] = t3; + } else { + t3 = $[4]; + } + return t3; + } + function _temp() {} + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ value: { id: 0, text: "Hello!" } }], + isComponent: true, + }; + + ``` +  + ### Eval output + (kind: ok)
Hello!
 + +FAIL: repro-dce-circular-reference +- Expected ++ Received + + + ## Input + + ```javascript + import {identity} from 'shared-runtime'; + + function Component({data}) { + let x = 0; + for (const item of data) { + const {current, other} = item; + x += current; + identity(other); + } + return [x]; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [ + { + data: [ + {current: 2, other: 3}, + {current: 4, other: 5}, + ], + }, + ], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { identity } from "shared-runtime"; + + function Component(t0) { + const $ = _c(2); ++ Object.freeze(t0); + const { data } = t0; + let x = 0; + for (const item of data) { + const { current, other } = item; + x = x + current; + identity(other); + } + let t1; + if ($[0] !== x) { + t1 = [x]; + $[0] = x; + $[1] = t1; + } else { + t1 = $[1]; + } + return t1; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [ + { + data: [ + { current: 2, other: 3 }, + { current: 4, other: 5 }, + ], + }, + ], + }; + + ``` +  + ### Eval output + (kind: ok) [6] + +FAIL: repro-allocating-ternary-test-instruction-scope +- Expected ++ Received + + + ## Input + + ```javascript + import {identity, makeObject_Primitives} from 'shared-runtime'; + + function useTest({cond}) { + const val = makeObject_Primitives(); + + useHook(); + /** + * We don't technically need a reactive scope for this ternary as + * it cannot produce newly allocated values. + * While identity(...) may allocate, we can teach the compiler that + * its result is only used as as a test condition + */ + const result = identity(cond) ? val : null; + return result; + } + + export const FIXTURE_ENTRYPOINT = { + fn: useTest, + params: [{cond: true}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { identity, makeObject_Primitives } from "shared-runtime"; + + function useTest(t0) { + const $ = _c(3); ++ Object.freeze(t0); + const { cond } = t0; + let t1; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t1 = makeObject_Primitives(); + $[0] = t1; + } else { + t1 = $[0]; + } + const val = t1; +- +- useHook(); ++ (function () { ++ const $res$ = useHook(); ++ Object.freeze($res$); ++ return $res$; ++ })(); + let t2; + if ($[1] !== cond) { + t2 = identity(cond) ? val : null; + $[1] = cond; + $[2] = t2; + } else { + t2 = $[2]; + } + const result = t2; + return result; + } + + export const FIXTURE_ENTRYPOINT = { + fn: useTest, + params: [{ cond: true }], + }; + + ``` +  + ### Eval output + (kind: exception) useHook is not defined + +FAIL: reordering-across-blocks +- Expected ++ Received + + + ## Input + + ```javascript + import {Stringify} from 'shared-runtime'; + + function Component({config}) { + /** + * The original memoization is optimal in the sense that it has + * one output (the object) and one dependency (`config`). Both + * the `a` and `b` functions will have to be recreated whenever + * `config` changes, cascading to update the object. + * + * However, we currently only consider consecutive scopes for + * merging, so we first see the `a` scope, then the `b` scope, + * and see that the output of the `a` scope is used later - + * so we don't merge these scopes, and so on. + * + * The more optimal thing would be to build a dependency graph + * of scopes so that we can see the data flow is along the lines + * of: + * + * config + * / \ + * [a] [b] + * \ / + * [object] + * + * All the scopes (shown in []) are transitively dependent on + * `config`, so they can be merged. + */ + const object = useMemo(() => { + const a = event => { + config?.onA?.(event); + }; + + const b = event => { + config?.onB?.(event); + }; + + return { + b, + a, + }; + }, [config]); + + return ; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { Stringify } from "shared-runtime"; + + function Component(t0) { + const $ = _c(9); ++ Object.freeze(t0); + const { config } = t0; + let t1; + let t2; + if ($[0] !== config) { + t2 = (event) => { + config?.onA?.(event); + }; + $[0] = config; + $[1] = t2; + } else { + t2 = $[1]; + } + const a = t2; + let t3; + if ($[2] !== config) { + t3 = (event_0) => { + config?.onB?.(event_0); + }; + $[2] = config; + $[3] = t3; + } else { + t3 = $[3]; + } + const b = t3; + let t4; + if ($[4] !== b || $[5] !== a) { + t4 = { b, a }; + $[4] = b; + $[5] = a; + $[6] = t4; + } else { + t4 = $[6]; + } + t1 = t4; + const object = t1; + let t5; + if ($[7] !== object) { +- t5 = ; ++ t5 = ( ++  ++ ); + $[7] = object; + $[8] = t5; + } else { + t5 = $[8]; + } + return t5; + } + + ``` +  + ### Eval output + (kind: exception) Fixture not implemented + +FAIL: renaming-jsx-tag-lowercase + >> Unexpected error during test: + + +Found differences in evaluator results +Non-forget (expected): +(kind: ok)
{"value":{}}
{"value":{}}
+Forget: +(kind: ok)
{"value":"[[ function params=0 ]]"}
{"value":"[[ function params=0 ]]"}
+ +FAIL: rename-source-variables +- Expected ++ Received + + + ## Input + + ```javascript + // @enableChangeVariableCodegen + import {identity} from 'shared-runtime'; + + const $ = 'module_$'; + const t0 = 'module_t0'; + const c_0 = 'module_c_0'; + function useFoo(props: {value: number}): number { + const results = identity(props.value); + console.log($); + console.log(t0); + console.log(c_0); + return results; + } + + export const FIXTURE_ENTRYPOINT = { + fn: useFoo, + params: [{value: 0}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; // @enableChangeVariableCodegen + import { identity } from "shared-runtime"; + + const $ = "module_$"; + const t0 = "module_t0"; + const c_0 = "module_c_0"; + function useFoo(props) { + const $0 = _c(2); ++ Object.freeze(props); + const c_00 = $0[0] !== props.value; + let t1; + if (c_00) { + t1 = identity(props.value); + $0[0] = props.value; + $0[1] = t1; + } else { + t1 = $0[1]; + } + const results = t1; + console.log($); + console.log(t0); + console.log(c_0); + return results; + } + + export const FIXTURE_ENTRYPOINT = { + fn: useFoo, + params: [{ value: 0 }], + }; + + ``` +  + ### Eval output + (kind: ok) 0 + logs: ['module_$','module_t0','module_c_0'] + +FAIL: rename-source-variables-nested-object-method +- Expected ++ Received + + + ## Input + + ```javascript + // @enableChangeVariableCodegen + import {identity} from 'shared-runtime'; + + const $ = 'module_$'; + const t0 = 'module_t0'; + const c_0 = 'module_c_0'; + function useFoo(props: {value: number}): number { + const a = { + foo() { + const b = { + bar() { + console.log($); + console.log(t0); + console.log(c_0); + return identity(props.value); + }, + }; + return b; + }, + }; + return a.foo().bar(); + } + + export const FIXTURE_ENTRYPOINT = { + fn: useFoo, + params: [{value: 42}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; // @enableChangeVariableCodegen + import { identity } from "shared-runtime"; + + const $ = "module_$"; + const t0 = "module_t0"; + const c_0 = "module_c_0"; + function useFoo(props) { + const $0 = _c(2); ++ Object.freeze(props); + const c_00 = $0[0] !== props.value; + let t1; + if (c_00) { + const a = { + foo() { + const b = { + bar() { + console.log($); + console.log(t0); + console.log(c_0); + return identity(props.value); + }, + }; + return b; + }, + }; + + t1 = a.foo().bar(); + $0[0] = props.value; + $0[1] = t1; + } else { + t1 = $0[1]; + } + return t1; + } + + export const FIXTURE_ENTRYPOINT = { + fn: useFoo, + params: [{ value: 42 }], + }; + + ``` +  + ### Eval output + (kind: ok) 42 + logs: ['module_$','module_t0','module_c_0'] + +FAIL: rename-source-variables-nested-function +- Expected ++ Received + + + ## Input + + ```javascript + // @enableChangeVariableCodegen + import {identity} from 'shared-runtime'; + + const $ = 'module_$'; + const t0 = 'module_t0'; + const c_0 = 'module_c_0'; + function useFoo(props: {value: number}): number { + const a = () => { + const b = () => { + const c = () => { + console.log($); + console.log(t0); + console.log(c_0); + return identity(props.value); + }; + return c; + }; + return b; + }; + return a()()(); + } + + export const FIXTURE_ENTRYPOINT = { + fn: useFoo, + params: [{value: 42}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; // @enableChangeVariableCodegen + import { identity } from "shared-runtime"; + + const $ = "module_$"; + const t0 = "module_t0"; + const c_0 = "module_c_0"; + function useFoo(props) { + const $0 = _c(4); ++ Object.freeze(props); + const c_00 = $0[0] !== props.value; + let t1; + if (c_00) { + t1 = () => { + const b = () => { + const c = () => { + console.log($); + console.log(t0); + console.log(c_0); + return identity(props.value); + }; + return c; + }; + return b; + }; + $0[0] = props.value; + $0[1] = t1; + } else { + t1 = $0[1]; + } + const a = t1; + const c_2 = $0[2] !== a; + let t2; + if (c_2) { + t2 = a()()(); + $0[2] = a; + $0[3] = t2; + } else { + t2 = $0[3]; + } + return t2; + } + + export const FIXTURE_ENTRYPOINT = { + fn: useFoo, + params: [{ value: 42 }], + }; + + ``` +  + ### Eval output + (kind: ok) 42 + logs: ['module_$','module_t0','module_c_0'] + +FAIL: regexp-literal +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + const pattern = /foo/g; + const value = makeValue(); + // We treat RegExp instances as mutable objects (bc they are) + // so by default we assume this could be mutating `value`: + if (pattern.test(value)) { + return
{value}
; + } + return
Default
; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(4); ++ Object.freeze(props); + let t0; + let value; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + const pattern = /foo/g; + value = makeValue(); + + t0 = pattern.test(value); + $[0] = t0; + $[1] = value; + } else { + t0 = $[0]; + value = $[1]; + } + if (t0) { + let t1; + if ($[2] === Symbol.for("react.memo_cache_sentinel")) { + t1 =
{value}
; + $[2] = t1; + } else { + t1 = $[2]; + } + return t1; + } + let t1; + if ($[3] === Symbol.for("react.memo_cache_sentinel")) { + t1 =
Default
; + $[3] = t1; + } else { + t1 = $[3]; + } + return t1; + } + + ``` +  + +FAIL: ref-parameter-mutate-in-effect + >> Unexpected error during test: + + +Found differences in evaluator results +Non-forget (expected): +(kind: ok)
foo
+Forget: +(kind: exception) Cannot add property current, object is not extensible + +FAIL: ref-like-name-in-useCallback +- Expected ++ Received + + + ## Input + + ```javascript + // @enableTreatRefLikeIdentifiersAsRefs @validatePreserveExistingMemoizationGuarantees + import {useRef, useCallback} from 'react'; + + function useCustomRef() { + return useRef({click: () => {}}); + } + + function Foo() { + const customRef = useCustomRef(); + + const onClick = useCallback(() => { + customRef.current?.click(); + }, []); + + return  + +FAIL: ref-like-name-in-useCallback-2 +- Expected ++ Received + + + ## Input + + ```javascript + // @enableTreatRefLikeIdentifiersAsRefs @validatePreserveExistingMemoizationGuarantees + import {useRef, useCallback} from 'react'; + + function useCustomRef() { + return useRef({click: () => {}}); + } + + function Foo() { + const ref = useCustomRef(); + + const onClick = useCallback(() => { + ref.current?.click(); + }, []); + + return  + +FAIL: ref-like-name-in-effect +- Expected ++ Received + + + ## Input + + ```javascript + // @enableTreatRefLikeIdentifiersAsRefs @validatePreserveExistingMemoizationGuarantees + import {useRef, useEffect} from 'react'; + + function useCustomRef() { + return useRef({click: () => {}}); + } + + function Foo() { + const ref = useCustomRef(); + + useEffect(() => { + ref.current?.click(); + }, []); + + return
foo
; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Foo, + params: [], + isComponent: true, + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; // @enableTreatRefLikeIdentifiersAsRefs @validatePreserveExistingMemoizationGuarantees + import { useRef, useEffect } from "react"; + + function useCustomRef() { + const $ = _c(1); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = { click: _temp }; + $[0] = t0; + } else { + t0 = $[0]; + } +- return useRef(t0); ++ return (function () { ++ const $res$ = useRef(Object.freeze(t0)); ++ Object.freeze($res$); ++ return $res$; ++ })(); + } + function _temp() {} + + function Foo() { + const $ = _c(3); +- const ref = useCustomRef(); ++ const ref = (function () { ++ const $res$ = useCustomRef(); ++ Object.freeze($res$); ++ return $res$; ++ })(); + let t0; + let t1; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = () => { + ref.current?.click(); + }; + t1 = []; + $[0] = t0; + $[1] = t1; + } else { + t0 = $[0]; + t1 = $[1]; + } +- useEffect(t0, t1); ++ (function () { ++ const $res$ = useEffect(Object.freeze(t0), Object.freeze(t1)); ++ Object.freeze($res$); ++ return $res$; ++ })(); + let t2; + if ($[2] === Symbol.for("react.memo_cache_sentinel")) { + t2 =
foo
; + $[2] = t2; + } else { + t2 = $[2]; + } + return t2; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Foo, + params: [], + isComponent: true, + }; + + ``` +  + ### Eval output + (kind: ok)
foo
 + +FAIL: ref-in-effect +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + const ref = useRef(null); + const onChange = e => { + const newValue = e.target.value ?? ref.current; + ref.current = newValue; + }; + useEffect(() => { + console.log(ref.current); + }); + return ; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(4); +- const ref = useRef(null); ++ Object.freeze(props); ++ const ref = (function () { ++ const $res$ = useRef(Object.freeze(null)); ++ Object.freeze($res$); ++ return $res$; ++ })(); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = (e) => { + const newValue = e.target.value ?? ref.current; + ref.current = newValue; + }; + $[0] = t0; + } else { + t0 = $[0]; + } + const onChange = t0; + let t1; + if ($[1] === Symbol.for("react.memo_cache_sentinel")) { + t1 = () => { + console.log(ref.current); + }; + $[1] = t1; + } else { + t1 = $[1]; + } +- useEffect(t1); ++ (function () { ++ const $res$ = useEffect(Object.freeze(t1)); ++ Object.freeze($res$); ++ return $res$; ++ })(); + let t2; + if ($[2] !== onChange) { +- t2 = ; ++ t2 = ( ++  ++ ); + $[2] = onChange; + $[3] = t2; + } else { + t2 = $[3]; + } + return t2; + } + + ``` +  + +FAIL: ref-current-write-not-added-to-dep +- Expected ++ Received + + + ## Input + + ```javascript + function VideoTab() { + const ref = useRef(); + let x = () => { + ref.current = 1; + }; + + return ; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function VideoTab() { + const $ = _c(3); +- const ref = useRef(); ++ const ref = (function () { ++ const $res$ = useRef(); ++ Object.freeze($res$); ++ return $res$; ++ })(); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = () => { + ref.current = 1; + }; + $[0] = t0; + } else { + t0 = $[0]; + } + const x = t0; + let t1; + if ($[1] !== x) { +- t1 = ; ++ t1 = ( ++  ++ ); + $[1] = x; + $[2] = t1; + } else { + t1 = $[2]; + } + return t1; + } + + ``` +  + +FAIL: ref-current-optional-field-no-added-to-dep +- Expected ++ Received + + + ## Input + + ```javascript + function VideoTab() { + const ref = useRef(); + let x = () => { + ref.current?.x; + }; + + return ; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function VideoTab() { + const $ = _c(3); +- const ref = useRef(); ++ const ref = (function () { ++ const $res$ = useRef(); ++ Object.freeze($res$); ++ return $res$; ++ })(); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = () => { + ref.current?.x; + }; + $[0] = t0; + } else { + t0 = $[0]; + } + const x = t0; + let t1; + if ($[1] !== x) { +- t1 = ; ++ t1 = ( ++  ++ ); + $[1] = x; + $[2] = t1; + } else { + t1 = $[2]; + } + return t1; + } + + ``` +  + +FAIL: ref-current-not-added-to-dep +- Expected ++ Received + + + ## Input + + ```javascript + function VideoTab() { + const ref = useRef(); + let x = () => { + console.log(ref.current); + }; + + return ; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function VideoTab() { + const $ = _c(3); +- const ref = useRef(); ++ const ref = (function () { ++ const $res$ = useRef(); ++ Object.freeze($res$); ++ return $res$; ++ })(); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = () => { + console.log(ref.current); + }; + $[0] = t0; + } else { + t0 = $[0]; + } + const x = t0; + let t1; + if ($[1] !== x) { +- t1 = ; ++ t1 = ( ++  ++ ); + $[1] = x; + $[2] = t1; + } else { + t1 = $[2]; + } + return t1; + } + + ``` +  + +FAIL: ref-current-not-added-to-dep-2 +- Expected ++ Received + + + ## Input + + ```javascript + // @validateRefAccessDuringRender:false + function Foo({a}) { + const ref = useRef(); + const x = {a, val: ref.current}; + + return ; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; // @validateRefAccessDuringRender:false + function Foo(t0) { + const $ = _c(4); ++ Object.freeze(t0); + const { a } = t0; +- const ref = useRef(); ++ const ref = (function () { ++ const $res$ = useRef(); ++ Object.freeze($res$); ++ return $res$; ++ })(); + let t1; + if ($[0] !== a) { + t1 = { a, val: ref.current }; + $[0] = a; + $[1] = t1; + } else { + t1 = $[1]; + } + const x = t1; + let t2; + if ($[2] !== x) { +- t2 = ; ++ t2 = ( ++  ++ ); + $[2] = x; + $[3] = t2; + } else { + t2 = $[3]; + } + return t2; + } + + ``` +  + +FAIL: ref-current-field-write-not-added-to-dep +- Expected ++ Received + + + ## Input + + ```javascript + import {useRef} from 'react'; + + function Component() { + const ref = useRef({text: {value: null}}); + const inputChanged = e => { + ref.current.text.value = e.target.value; + }; + + return ; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { useRef } from "react"; + + function Component() { + const $ = _c(4); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = { text: { value: null } }; + $[0] = t0; + } else { + t0 = $[0]; + } +- const ref = useRef(t0); ++ const ref = (function () { ++ const $res$ = useRef(Object.freeze(t0)); ++ Object.freeze($res$); ++ return $res$; ++ })(); + let t1; + if ($[1] === Symbol.for("react.memo_cache_sentinel")) { + t1 = (e) => { + ref.current.text.value = e.target.value; + }; + $[1] = t1; + } else { + t1 = $[1]; + } + const inputChanged = t1; + let t2; + if ($[2] !== inputChanged) { +- t2 = ; ++ t2 = ( ++  ++ ); + $[2] = inputChanged; + $[3] = t2; + } else { + t2 = $[3]; + } + return t2; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + }; + + ``` +  + ### Eval output + (kind: ok)  + +FAIL: ref-current-field-not-added-to-dep +- Expected ++ Received + + + ## Input + + ```javascript + // @validateRefAccessDuringRender false + function VideoTab() { + const ref = useRef(); + let x = () => { + console.log(ref.current.x); + }; + + return ; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; // @validateRefAccessDuringRender false + function VideoTab() { + const $ = _c(3); +- const ref = useRef(); ++ const ref = (function () { ++ const $res$ = useRef(); ++ Object.freeze($res$); ++ return $res$; ++ })(); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = () => { + console.log(ref.current.x); + }; + $[0] = t0; + } else { + t0 = $[0]; + } + const x = t0; + let t1; + if ($[1] !== x) { +- t1 = ; ++ t1 = ( ++  ++ ); + $[1] = x; + $[2] = t1; + } else { + t1 = $[2]; + } + return t1; + } + + ``` +  + +FAIL: ref-current-aliased-not-added-to-dep-2 +- Expected ++ Received + + + ## Input + + ```javascript + // @validateRefAccessDuringRender:false + function Foo({a}) { + const ref = useRef(); + const val = ref.current; + const x = {a, val}; + + return ; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; // @validateRefAccessDuringRender:false + function Foo(t0) { + const $ = _c(4); ++ Object.freeze(t0); + const { a } = t0; +- const ref = useRef(); ++ const ref = (function () { ++ const $res$ = useRef(); ++ Object.freeze($res$); ++ return $res$; ++ })(); + const val = ref.current; + let t1; + if ($[0] !== a) { + t1 = { a, val }; + $[0] = a; + $[1] = t1; + } else { + t1 = $[1]; + } + const x = t1; + let t2; + if ($[2] !== x) { +- t2 = ; ++ t2 = ( ++  ++ ); + $[2] = x; + $[3] = t2; + } else { + t2 = $[3]; + } + return t2; + } + + ``` +  + +FAIL: ref-current-aliased-no-added-to-dep +- Expected ++ Received + + + ## Input + + ```javascript + // @validateRefAccessDuringRender false + function VideoTab() { + const ref = useRef(); + const t = ref.current; + let x = () => { + console.log(t); + }; + + return ; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; // @validateRefAccessDuringRender false + function VideoTab() { + const $ = _c(3); +- const ref = useRef(); ++ const ref = (function () { ++ const $res$ = useRef(); ++ Object.freeze($res$); ++ return $res$; ++ })(); + const t = ref.current; + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = () => { + console.log(t); + }; + $[0] = t0; + } else { + t0 = $[0]; + } + const x = t0; + let t1; + if ($[1] !== x) { +- t1 = ; ++ t1 = ( ++  ++ ); + $[1] = x; + $[2] = t1; + } else { + t1 = $[2]; + } + return t1; + } + + ``` +  + +FAIL: reduce-reactive-cond-deps-return-in-scope +- Expected ++ Received + + + ## Input + + ```javascript + function useFoo({obj, objIsNull}) { + const x = []; + if (objIsNull) { + return; + } else { + x.push(obj.a); + } + x.push(obj.b); + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: useFoo, + params: [{obj: null, objIsNull: true}], + sequentialRenders: [ + {obj: null, objIsNull: true}, + {obj: {a: 2}, objIsNull: false}, + ], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function useFoo(t0) { + const $ = _c(4); ++ Object.freeze(t0); + const { obj, objIsNull } = t0; + let x; + let t1; + if ($[0] !== objIsNull || $[1] !== obj) { + t1 = Symbol.for("react.early_return_sentinel"); + bb0: { + x = []; + if (objIsNull) { + t1 = undefined; + break bb0; + } else { + x.push(obj.a); + } + + x.push(obj.b); + } + $[0] = objIsNull; + $[1] = obj; + $[2] = x; + $[3] = t1; + } else { + x = $[2]; + t1 = $[3]; + } + if (t1 !== Symbol.for("react.early_return_sentinel")) { + return t1; + } + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: useFoo, + params: [{ obj: null, objIsNull: true }], + sequentialRenders: [ + { obj: null, objIsNull: true }, + { obj: { a: 2 }, objIsNull: false }, + ], + }; + + ``` +  + ### Eval output + (kind: ok)  + [2,null] + +FAIL: reduce-reactive-cond-deps-cfg-nested-testifelse +- Expected ++ Received + + + ## Input + + ```javascript + import {setProperty} from 'shared-runtime'; + + function useFoo({o, branchCheck}: {o: {value: number}; branchCheck: boolean}) { + let x = {}; + if (branchCheck) { + setProperty(x, o.value); + } else { + if (o.value) { + setProperty(x, o.value); + } else { + setProperty(x, o.value); + } + } + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: useFoo, + params: [{o: {value: 2}, branchCheck: false}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { setProperty } from "shared-runtime"; + + function useFoo(t0) { + const $ = _c(3); ++ Object.freeze(t0); + const { o, branchCheck } = t0; + let x; + if ($[0] !== branchCheck || $[1] !== o.value) { + x = {}; + if (branchCheck) { + setProperty(x, o.value); + } else { + if (o.value) { + setProperty(x, o.value); + } else { + setProperty(x, o.value); + } + } + $[0] = branchCheck; + $[1] = o.value; + $[2] = x; + } else { + x = $[2]; + } + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: useFoo, + params: [{ o: { value: 2 }, branchCheck: false }], + }; + + ``` +  + ### Eval output + (kind: ok) {"wat0":2} + +FAIL: reduce-reactive-cond-deps-break-in-scope +- Expected ++ Received + + + ## Input + + ```javascript + function useFoo({obj, objIsNull}) { + const x = []; + b0: { + if (objIsNull) { + break b0; + } else { + x.push(obj.a); + } + x.push(obj.b); + } + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: useFoo, + params: [{obj: null, objIsNull: true}], + sequentialRenders: [ + {obj: null, objIsNull: true}, + {obj: {a: 2}, objIsNull: false}, + ], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function useFoo(t0) { + const $ = _c(3); ++ Object.freeze(t0); + const { obj, objIsNull } = t0; + let x; + if ($[0] !== objIsNull || $[1] !== obj) { + x = []; + bb0: { + if (objIsNull) { + break bb0; + } else { + x.push(obj.a); + } + + x.push(obj.b); + } + $[0] = objIsNull; + $[1] = obj; + $[2] = x; + } else { + x = $[2]; + } + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: useFoo, + params: [{ obj: null, objIsNull: true }], + sequentialRenders: [ + { obj: null, objIsNull: true }, + { obj: { a: 2 }, objIsNull: false }, + ], + }; + + ``` +  + ### Eval output + (kind: ok) [] + [2,null] + +FAIL: recursive-function +- Expected ++ Received + + + ## Input + + ```javascript + function foo(x) { + if (x <= 0) { + return 0; + } + return x + foo(x - 1) + (() => foo(x - 2))(); + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: [10], + }; + + ``` + + ## Code + + ```javascript + function foo(x) { ++ Object.freeze(x); + if (x <= 0) { + return 0; + } + let t0; + t0 = foo(x - 2); + return x + foo(x - 1) + t0; + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: [10], + }; + + ``` +  + ### Eval output + (kind: ok) 364 + +FAIL: reassignment +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + let x = []; + x.push(props.p0); + let y = x; + + x = []; + let _ = ; + + y.push(props.p1); + + return ; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(4); ++ Object.freeze(props); + let t0; + if ($[0] !== props.p0 || $[1] !== props.p1) { + let x = []; + x.push(props.p0); + const y = x; + let t1; + if ($[3] === Symbol.for("react.memo_cache_sentinel")) { + t1 = []; + $[3] = t1; + } else { + t1 = $[3]; + } + x = t1; + + y.push(props.p1); + +- t0 = ; ++ t0 = ( ++  ++ ); + $[0] = props.p0; + $[1] = props.p1; + $[2] = t0; + } else { + t0 = $[2]; + } + return t0; + } + + ``` +  + +FAIL: reassignment-separate-scopes +- Expected ++ Received + + + ## Input + + ```javascript + function foo(a, b, c) { + let x = []; + if (a) { + x.push(a); + } + let y =
{x}
; + + switch (b) { + case 0: { + x = []; + x.push(b); + break; + } + default: { + x = []; + x.push(c); + } + } + return ( +
 + {y} + {x} +
 + ); + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function foo(a, b, c) { + const $ = _c(10); ++ Object.freeze(a); ++ Object.freeze(b); ++ Object.freeze(c); + let x; + let t0; + if ($[0] !== a) { + x = []; + if (a) { + x.push(a); + } + + t0 =
{x}
; + $[0] = a; + $[1] = x; + $[2] = t0; + } else { + x = $[1]; + t0 = $[2]; + } + const y = t0; + bb0: switch (b) { + case 0: { + if ($[3] !== b) { + x = []; + x.push(b); + $[3] = b; + $[4] = x; + } else { + x = $[4]; + } + break bb0; + } + default: { + if ($[5] !== c) { + x = []; + x.push(c); + $[5] = c; + $[6] = x; + } else { + x = $[6]; + } + } + } + let t1; + if ($[7] !== y || $[8] !== x) { + t1 = ( +
 + {y} + {x} +
 + ); + $[7] = y; + $[8] = x; + $[9] = t1; + } else { + t1 = $[9]; + } + return t1; + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: reassignment-conditional +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + let x = []; + x.push(props.p0); + let y = x; + + if (props.p1) { + x = []; + } + + y.push(props.p2); + + return ; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(5); ++ Object.freeze(props); + let t0; + if ($[0] !== props.p0 || $[1] !== props.p1 || $[2] !== props.p2) { + let x = []; + x.push(props.p0); + const y = x; + if (props.p1) { + let t1; + if ($[4] === Symbol.for("react.memo_cache_sentinel")) { + t1 = []; + $[4] = t1; + } else { + t1 = $[4]; + } + x = t1; + } + + y.push(props.p2); + +- t0 = ; ++ t0 = ( ++  ++ ); + $[0] = props.p0; + $[1] = props.p1; + $[2] = props.p2; + $[3] = t0; + } else { + t0 = $[3]; + } + return t0; + } + + ``` +  + +FAIL: reassigned-phi-in-returned-function-expression +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + return () => { + let str; + if (arguments.length) { + str = arguments[0]; + } else { + str = props.str; + } + global.log(str); + }; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(2); ++ Object.freeze(props); + let t0; + if ($[0] !== props.str) { + t0 = () => { + let str; + if (arguments.length) { + str = arguments[0]; + } else { + str = props.str; + } + + global.log(str); + }; + $[0] = props.str; + $[1] = t0; + } else { + t0 = $[1]; + } + return t0; + } + + ``` +  + +FAIL: reassign-primitive-in-context +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + let x = 5; + let foo = () => { + x = {}; + }; + foo(); + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(1); ++ Object.freeze(props); + let x; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + x = 5; + const foo = () => { + x = {}; + }; + + foo(); + $[0] = x; + } else { + x = $[0]; + } + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + }; + + ``` +  + ### Eval output + (kind: ok) {} + +FAIL: reassign-object-in-context +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + let x = []; + let foo = () => { + x = {}; + }; + foo(); + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(1); ++ Object.freeze(props); + let x; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + x = []; + const foo = () => { + x = {}; + }; + + foo(); + $[0] = x; + } else { + x = $[0]; + } + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + }; + + ``` +  + +FAIL: reassign-global-hook-arg +- Expected ++ Received + + + ## Input + + ```javascript + let b = 1; + + export default function MyApp() { + const fn = () => { + b = 2; + }; + return useFoo(fn); + } + + function useFoo(fn) {} + + export const FIXTURE_ENTRYPOINT = { + fn: MyApp, + params: [], + }; + + ``` + + ## Code + + ```javascript + let b = 1; + + export default function MyApp() { + const fn = _temp; +- return useFoo(fn); ++ return (function () { ++ const $res$ = useFoo(Object.freeze(fn)); ++ Object.freeze($res$); ++ return $res$; ++ })(); + } + function _temp() { + b = 2; + } + +- function useFoo(fn) {} ++ function useFoo(fn) { ++ Object.freeze(fn); ++ } + + export const FIXTURE_ENTRYPOINT = { + fn: MyApp, + params: [], + }; + + ``` +  + ### Eval output + (kind: ok)  + +FAIL: reanimated-no-memo-arg +- Expected ++ Received + + + ## Input + + ```javascript + // @enableCustomTypeDefinitionForReanimated + function Component() { + const radius = useSharedValue(50); + + const animatedProps = useAnimatedProps(() => { + // draw a circle + const path = ` + M 100, 100 + m -${radius.value}, 0 + a ${radius.value},${radius.value} 0 1,0 ${radius.value * 2},0 + a ${radius.value},${radius.value} 0 1,0 ${-radius.value * 2},0 + `; + return { + d: path, + }; + }); + + // attach animated props to an SVG path using animatedProps + return ( +  +  +  + ); + } + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [], + isComponent: false, + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; // @enableCustomTypeDefinitionForReanimated + function Component() { + const $ = _c(2); +- const radius = useSharedValue(50); ++ const radius = (function () { ++ const $res$ = useSharedValue(Object.freeze(50)); ++ Object.freeze($res$); ++ return $res$; ++ })(); + +- const animatedProps = useAnimatedProps(() => { +- const path = ` ++ const animatedProps = (function () { ++ const $res$ = useAnimatedProps( ++ Object.freeze(() => { ++ const path = ` + M 100, 100 + m -${radius.value}, 0 + a ${radius.value},${radius.value} 0 1,0 ${radius.value * 2},0 + a ${radius.value},${radius.value} 0 1,0 ${-radius.value * 2},0 + `; +- return { d: path }; +- }); ++ return { d: path }; ++ }), ++ ); ++ Object.freeze($res$); ++ return $res$; ++ })(); + let t0; + if ($[0] !== animatedProps) { + t0 = ( +  +-  ++  +  + ); + $[0] = animatedProps; + $[1] = t0; + } else { + t0 = $[1]; + } + return t0; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [], + isComponent: false, + }; + + ``` +  + +FAIL: readonly-object-method-calls +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + const user = useFragment( + graphql` + fragment Component_user on User { + name + } + `, + props.user + ); + const posts = user.timeline.posts.edges.nodes.map(node => ( +  + )); + posts.push({}); + const count = posts.length; + foo(count); + return <>{posts}; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(5); +- const user = useFragment( +- graphql` +- fragment Component_user on User { +- name +- } +- `, +- props.user, +- ); ++ Object.freeze(props); ++ const user = (function () { ++ const $res$ = useFragment( ++ Object.freeze(graphql` ++ fragment Component_user on User { ++ name ++ } ++ `), ++ Object.freeze(props.user), ++ ); ++ Object.freeze($res$); ++ return $res$; ++ })(); + let posts; + if ($[0] !== user.timeline.posts.edges.nodes) { + posts = user.timeline.posts.edges.nodes.map(_temp); + let t0; + if ($[2] === Symbol.for("react.memo_cache_sentinel")) { + t0 = {}; + $[2] = t0; + } else { + t0 = $[2]; + } + posts.push(t0); + $[0] = user.timeline.posts.edges.nodes; + $[1] = posts; + } else { + posts = $[1]; + } + const count = posts.length; + foo(count); + let t0; + if ($[3] !== posts) { + t0 = <>{posts}; + $[3] = posts; + $[4] = t0; + } else { + t0 = $[4]; + } + return t0; + } + function _temp(node) { +- return ; ++ return ( ++  ++ ); + } + + ``` +  + +FAIL: readonly-object-method-calls-mutable-lambda +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + const x = makeObject(); + const user = useFragment( + graphql` + fragment Component_user on User { + name + } + `, + props.user + ); + const posts = user.timeline.posts.edges.nodes.map(node => { + x.y = true; + return ; + }); + posts.push({}); + const count = posts.length; + foo(count); + return <>{posts}; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(3); ++ Object.freeze(props); + const x = makeObject(); +- const user = useFragment( +- graphql` +- fragment Component_user on User { +- name +- } +- `, +- props.user, +- ); ++ const user = (function () { ++ const $res$ = useFragment( ++ Object.freeze(graphql` ++ fragment Component_user on User { ++ name ++ } ++ `), ++ Object.freeze(props.user), ++ ); ++ Object.freeze($res$); ++ return $res$; ++ })(); + const posts = user.timeline.posts.edges.nodes.map((node) => { + x.y = true; +- return ; ++ return ( ++  ++ ); + }); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = {}; + $[0] = t0; + } else { + t0 = $[0]; + } + posts.push(t0); + const count = posts.length; + foo(count); + let t1; + if ($[1] !== posts) { + t1 = <>{posts}; + $[1] = posts; + $[2] = t1; + } else { + t1 = $[2]; + } + return t1; + } + + ``` +  + +FAIL: reactivity-via-readonly-alias-of-mutable-value +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + const x = []; + const y = x; + + // y isn't reactive yet when we first visit this, so z is initially non-reactive + const z = [y]; + + // then we realize y is reactive. we need a fixpoint to propagate this back to z + y.push(props.input); + + // PruneNonReactiveDependencies partially propagates reactivity (for now) which + // we bypass with an indirection of storing into another variable + const a = [z]; + + // b's value is conditional on `a`, which is reactive per above + let b = 0; + if (a[0][0][0] === 42) { + b = 1; + } + + return [b]; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [], + sequentialRenders: [ + {input: 42}, + {input: 42}, + {input: 'sathya'}, + {input: 'sathya'}, + {input: 42}, + {input: 'sathya'}, + {input: 42}, + {input: 'sathya'}, + ], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(2); ++ Object.freeze(props); + const x = []; + const y = x; + + const z = [y]; + + y.push(props.input); + + const a = [z]; + + let b = 0; + if (a[0][0][0] === 42) { + b = 1; + } + let t0; + if ($[0] !== b) { + t0 = [b]; + $[0] = b; + $[1] = t0; + } else { + t0 = $[1]; + } + return t0; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [], + sequentialRenders: [ + { input: 42 }, + { input: 42 }, + { input: "sathya" }, + { input: "sathya" }, + { input: 42 }, + { input: "sathya" }, + { input: 42 }, + { input: "sathya" }, + ], + }; + + ``` +  + ### Eval output + (kind: ok) [1] + [1] + [0] + [0] + [1] + [0] + [1] + [0] + +FAIL: reactivity-via-aliased-mutation-through-property-load +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + const x = {}; + const y = []; + x.y = y; + x.y.push(props.input); + + let z = 0; + if (x.y[0]) { + z = 1; + } + + return [z]; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [], + sequentialRenders: [ + {input: true}, + {input: true}, + {input: false}, + {input: false}, + {input: true}, + {input: false}, + {input: true}, + {input: false}, + ], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(2); ++ Object.freeze(props); + const x = {}; + const y = []; + x.y = y; + x.y.push(props.input); + + let z = 0; + if (x.y[0]) { + z = 1; + } + let t0; + if ($[0] !== z) { + t0 = [z]; + $[0] = z; + $[1] = t0; + } else { + t0 = $[1]; + } + return t0; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [], + sequentialRenders: [ + { input: true }, + { input: true }, + { input: false }, + { input: false }, + { input: true }, + { input: false }, + { input: true }, + { input: false }, + ], + }; + + ``` +  + ### Eval output + (kind: ok) [1] + [1] + [0] + [0] + [1] + [0] + [1] + [0] + +FAIL: reactivity-via-aliased-mutation-lambda +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + const x = []; + const f = arg => { + const y = x; + y.push(arg); + }; + f(props.input); + + return [x[0]]; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [], + sequentialRenders: [ + {input: 42}, + {input: 42}, + {input: 'sathya'}, + {input: 'sathya'}, + {input: 42}, + {input: 'sathya'}, + {input: 42}, + {input: 'sathya'}, + ], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(4); ++ Object.freeze(props); + let x; + if ($[0] !== props.input) { + x = []; + const f = (arg) => { + const y = x; + y.push(arg); + }; + + f(props.input); + $[0] = props.input; + $[1] = x; + } else { + x = $[1]; + } + + const t0 = x[0]; + let t1; + if ($[2] !== t0) { + t1 = [t0]; + $[2] = t0; + $[3] = t1; + } else { + t1 = $[3]; + } + return t1; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [], + sequentialRenders: [ + { input: 42 }, + { input: 42 }, + { input: "sathya" }, + { input: "sathya" }, + { input: 42 }, + { input: "sathya" }, + { input: 42 }, + { input: "sathya" }, + ], + }; + + ``` +  + ### Eval output + (kind: ok) [42] + [42] + ["sathya"] + ["sathya"] + [42] + ["sathya"] + [42] + ["sathya"] + +FAIL: reactivity-via-aliased-mutation-array +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + const x = []; + const y = x; + y.push(props.input); + + return [x[0]]; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [], + sequentialRenders: [ + {input: 42}, + {input: 42}, + {input: 'sathya'}, + {input: 'sathya'}, + {input: 42}, + {input: 'sathya'}, + {input: 42}, + {input: 'sathya'}, + ], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(4); ++ Object.freeze(props); + let x; + if ($[0] !== props.input) { + x = []; + const y = x; + y.push(props.input); + $[0] = props.input; + $[1] = x; + } else { + x = $[1]; + } + + const t0 = x[0]; + let t1; + if ($[2] !== t0) { + t1 = [t0]; + $[2] = t0; + $[3] = t1; + } else { + t1 = $[3]; + } + return t1; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [], + sequentialRenders: [ + { input: 42 }, + { input: 42 }, + { input: "sathya" }, + { input: "sathya" }, + { input: 42 }, + { input: "sathya" }, + { input: 42 }, + { input: "sathya" }, + ], + }; + + ``` +  + ### Eval output + (kind: ok) [42] + [42] + ["sathya"] + ["sathya"] + [42] + ["sathya"] + [42] + ["sathya"] + +FAIL: reactivity-analysis-reactive-via-mutation-of-property-load +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + const items = bar(); + mutate(items.a, props.a); + + const count = foo(items.length + 1); + + return {items, count}; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(7); ++ Object.freeze(props); + let items; + if ($[0] !== props.a) { + items = bar(); + mutate(items.a, props.a); + $[0] = props.a; + $[1] = items; + } else { + items = $[1]; + } + + const t0 = items.length + 1; + let t1; + if ($[2] !== t0) { + t1 = foo(t0); + $[2] = t0; + $[3] = t1; + } else { + t1 = $[3]; + } + const count = t1; + let t2; + if ($[4] !== items || $[5] !== count) { + t2 = { items, count }; + $[4] = items; + $[5] = count; + $[6] = t2; + } else { + t2 = $[6]; + } + return t2; + } + + ``` +  + +FAIL: reactivity-analysis-reactive-via-mutation-of-computed-load +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + const items = bar(); + mutate(items[props.key], props.a); + + const count = foo(items.length + 1); + + return {items, count}; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(8); ++ Object.freeze(props); + let items; + if ($[0] !== props.key || $[1] !== props.a) { + items = bar(); + mutate(items[props.key], props.a); + $[0] = props.key; + $[1] = props.a; + $[2] = items; + } else { + items = $[2]; + } + + const t0 = items.length + 1; + let t1; + if ($[3] !== t0) { + t1 = foo(t0); + $[3] = t0; + $[4] = t1; + } else { + t1 = $[4]; + } + const count = t1; + let t2; + if ($[5] !== items || $[6] !== count) { + t2 = { items, count }; + $[5] = items; + $[6] = count; + $[7] = t2; + } else { + t2 = $[7]; + } + return t2; + } + + ``` +  + +FAIL: reactivity-analysis-interleaved-reactivity +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + // a and b are technically independent, but their mutation is interleaved + // so they are grouped in a single reactive scope. a does not have any + // reactive inputs, but b does. therefore, we have to treat a as reactive, + // since it will be recreated based on a reactive input. + const a = {}; + const b = []; + b.push(props.b); + a.a = null; + + // because a may recreate when b does, it becomes reactive. we have to recreate + // c if a changes. + const c = [a]; + + // Example usage that could fail if we didn't treat a as reactive: + // const [c, a] = Component({b: ...}); + // assert(c[0] === a); + return [c, a]; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(6); ++ Object.freeze(props); + let a; + let t0; + if ($[0] !== props.b) { + a = {}; + const b = []; + b.push(props.b); + a.a = null; + + t0 = [a]; + $[0] = props.b; + $[1] = a; + $[2] = t0; + } else { + a = $[1]; + t0 = $[2]; + } + const c = t0; + let t1; + if ($[3] !== c || $[4] !== a) { + t1 = [c, a]; + $[3] = c; + $[4] = a; + $[5] = t1; + } else { + t1 = $[5]; + } + return t1; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: reactive-scopes +- Expected ++ Received + + + ## Input + + ```javascript + function f(a, b) { + let x = []; // <- x starts being mutable here. + if (a.length === 1) { + if (b) { + x.push(b); // <- x stops being mutable here. + } + } + + return
{x}
; + } + + export const FIXTURE_ENTRYPOINT = { + fn: f, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function f(a, b) { + const $ = _c(3); ++ Object.freeze(a); ++ Object.freeze(b); + let t0; + if ($[0] !== a.length || $[1] !== b) { + const x = []; + if (a.length === 1) { + if (b) { + x.push(b); + } + } + + t0 =
{x}
; + $[0] = a.length; + $[1] = b; + $[2] = t0; + } else { + t0 = $[2]; + } + return t0; + } + + export const FIXTURE_ENTRYPOINT = { + fn: f, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: reactive-scopes-if +- Expected ++ Received + + + ## Input + + ```javascript + function foo(a, b, c) { + const x = []; + if (a) { + const y = []; + y.push(b); + x.push(
{y}
); + } else { + x.push(c); + } + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function foo(a, b, c) { + const $ = _c(8); ++ Object.freeze(a); ++ Object.freeze(b); ++ Object.freeze(c); + let x; + if ($[0] !== a || $[1] !== b || $[2] !== c) { + x = []; + if (a) { + let y; + if ($[4] !== b) { + y = []; + y.push(b); + $[4] = b; + $[5] = y; + } else { + y = $[5]; + } + let t0; + if ($[6] !== y) { + t0 =
{y}
; + $[6] = y; + $[7] = t0; + } else { + t0 = $[7]; + } + x.push(t0); + } else { + x.push(c); + } + $[0] = a; + $[1] = b; + $[2] = c; + $[3] = x; + } else { + x = $[3]; + } + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: reactive-dependency-object-captured-with-reactive-mutated +- Expected ++ Received + + + ## Input + + ```javascript + const {mutate} = require('shared-runtime'); + + function Component(props) { + const x = {}; + const y = props.y; + const z = [x, y]; + mutate(z); + // x's object identity can change bc it co-mutates with z, which is reactive via props.y + return [x]; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{y: 42}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + const { mutate } = require("shared-runtime"); + + function Component(props) { + const $ = _c(2); ++ Object.freeze(props); + let t0; + if ($[0] !== props.y) { + const x = {}; + const y = props.y; + const z = [x, y]; + mutate(z); + + t0 = [x]; + $[0] = props.y; + $[1] = t0; + } else { + t0 = $[1]; + } + return t0; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ y: 42 }], + }; + + ``` +  + ### Eval output + (kind: ok) [{}] + +FAIL: reactive-dependency-nonreactive-captured-with-reactive +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + const x = {}; + const y = props.y; + return [x, y]; // x is captured here along with a reactive value. this shouldn't make `x` reactive! + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{y: 42}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(3); ++ Object.freeze(props); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = {}; + $[0] = t0; + } else { + t0 = $[0]; + } + const x = t0; + const y = props.y; + let t1; + if ($[1] !== y) { + t1 = [x, y]; + $[1] = y; + $[2] = t1; + } else { + t1 = $[2]; + } + return t1; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ y: 42 }], + }; + + ``` +  + ### Eval output + (kind: ok) [{},42] + +FAIL: reactive-dependency-fixpoint +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + let x = 0; + let y = 0; + + while (x === 0) { + x = y; + y = props.value; + } + + // x and y initially start out with non-reactive values, + // but after an iteration of the loop y becomes reactive, + // and this reactive value then flows into x on the next + // loop iteration, making x reactive. + return [x]; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{value: 42}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(2); ++ Object.freeze(props); + let x = 0; + let y = 0; + while (x === 0) { + x = y; + y = props.value; + } + let t0; + if ($[0] !== x) { + t0 = [x]; + $[0] = x; + $[1] = t0; + } else { + t0 = $[1]; + } + return t0; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ value: 42 }], + }; + + ``` +  + ### Eval output + (kind: ok) [42] + +FAIL: reactive-dependencies-non-optional-properties-inside-optional-chain +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + return props.post.feedback.comments?.edges?.map(render); + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(2); ++ Object.freeze(props); + let t0; + if ($[0] !== props.post.feedback.comments) { + t0 = props.post.feedback.comments?.edges?.map(render); + $[0] = props.post.feedback.comments; + $[1] = t0; + } else { + t0 = $[1]; + } + return t0; + } + + ``` +  + +FAIL: reactive-control-dependency-while-test +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + let x; + let i = 0; + while (i < props.test) { + if (i > 10) { + x = 10; + } else { + x = 1; + } + i++; + } + // The values assigned to `x` are non-reactive, but the value of `x` + // depends on the "control" variable `i`, whose value is affected by + // `props.test` which is reactive. + // Therefore x should be treated as reactive too. + return [x]; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [], + sequentialRenders: [ + {test: 12}, + {test: 12}, + {test: 1}, + {test: 1}, + {test: 12}, + {test: 1}, + {test: 12}, + {test: 1}, + ], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(2); ++ Object.freeze(props); + let x; + let i = 0; + while (i < props.test) { + if (i > 10) { + x = 10; + } else { + x = 1; + } + + i++; + } + let t0; + if ($[0] !== x) { + t0 = [x]; + $[0] = x; + $[1] = t0; + } else { + t0 = $[1]; + } + return t0; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [], + sequentialRenders: [ + { test: 12 }, + { test: 12 }, + { test: 1 }, + { test: 1 }, + { test: 12 }, + { test: 1 }, + { test: 12 }, + { test: 1 }, + ], + }; + + ``` +  + ### Eval output + (kind: ok) [10] + [10] + [1] + [1] + [10] + [1] + [10] + [1] + +FAIL: reactive-control-dependency-via-mutation-switch +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + // x is mutated conditionally based on a reactive value, + // so it needs to be considered reactive + let x = []; + if (props.cond) { + x.push(1); + } + // Since x is reactive, y is now reactively controlled too: + let y = false; + switch (x[0]) { + case 1: { + y = true; + break; + } + } + // Thus this value should be reactive on `y`: + return [y]; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [], + sequentialRenders: [ + {cond: true}, + {cond: true}, + {cond: false}, + {cond: false}, + {cond: true}, + {cond: false}, + {cond: true}, + {cond: false}, + ], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(2); ++ Object.freeze(props); + + const x = []; + if (props.cond) { + x.push(1); + } + + let y = false; + switch (x[0]) { + case 1: { + y = true; + } + } + let t0; + if ($[0] !== y) { + t0 = [y]; + $[0] = y; + $[1] = t0; + } else { + t0 = $[1]; + } + return t0; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [], + sequentialRenders: [ + { cond: true }, + { cond: true }, + { cond: false }, + { cond: false }, + { cond: true }, + { cond: false }, + { cond: true }, + { cond: false }, + ], + }; + + ``` +  + ### Eval output + (kind: ok) [true] + [true] + [false] + [false] + [true] + [false] + [true] + [false] + +FAIL: reactive-control-dependency-via-mutation-if +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + // x is mutated conditionally based on a reactive value, + // so it needs to be considered reactive + let x = []; + if (props.cond) { + x.push(1); + } + // Since x is reactive, y is now reactively controlled too: + let y = false; + if (x[0]) { + y = true; + } + // Thus this value should be reactive on `y`: + return [y]; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [], + sequentialRenders: [ + {cond: true}, + {cond: true}, + {cond: false}, + {cond: false}, + {cond: true}, + {cond: false}, + {cond: true}, + {cond: false}, + ], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(2); ++ Object.freeze(props); + + const x = []; + if (props.cond) { + x.push(1); + } + + let y = false; + if (x[0]) { + y = true; + } + let t0; + if ($[0] !== y) { + t0 = [y]; + $[0] = y; + $[1] = t0; + } else { + t0 = $[1]; + } + return t0; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [], + sequentialRenders: [ + { cond: true }, + { cond: true }, + { cond: false }, + { cond: false }, + { cond: true }, + { cond: false }, + { cond: true }, + { cond: false }, + ], + }; + + ``` +  + ### Eval output + (kind: ok) [true] + [true] + [false] + [false] + [true] + [false] + [true] + [false] + +FAIL: reactive-control-dependency-switch-condition +- Expected ++ Received + + + ## Input + + ```javascript + const GLOBAL = 42; + + function Component({value}) { + let x; + switch (GLOBAL) { + case value: { + x = 1; + break; + } + default: { + x = 2; + } + } + // The values assigned to `x` are non-reactive, but the value of `x` + // depends on the "control" value `props.value` which is reactive. + // Therefore x should be treated as reactive too. + return [x]; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [], + sequentialRenders: [ + {value: GLOBAL}, + {value: GLOBAL}, + {value: null}, + {value: null}, + {value: GLOBAL}, + {value: null}, + {value: GLOBAL}, + {value: null}, + ], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + const GLOBAL = 42; + + function Component(t0) { + const $ = _c(2); ++ Object.freeze(t0); + const { value } = t0; + let x; + bb0: switch (GLOBAL) { + case value: { + x = 1; + break bb0; + } + default: { + x = 2; + } + } + let t1; + if ($[0] !== x) { + t1 = [x]; + $[0] = x; + $[1] = t1; + } else { + t1 = $[1]; + } + return t1; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [], + sequentialRenders: [ + { value: GLOBAL }, + { value: GLOBAL }, + { value: null }, + { value: null }, + { value: GLOBAL }, + { value: null }, + { value: GLOBAL }, + { value: null }, + ], + }; + + ``` +  + ### Eval output + (kind: ok) [1] + [1] + [2] + [2] + [1] + [2] + [1] + [2] + +FAIL: reactive-control-dependency-switch-case-test +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + let x; + switch (props.cond) { + case true: { + x = 1; + break; + } + case false: { + x = 2; + break; + } + default: { + x = 3; + } + } + // The values assigned to `x` are non-reactive, but the value of `x` + // depends on the "control" value `props.cond` which is reactive. + // Therefore x should be treated as reactive too. + return [x]; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [], + sequentialRenders: [ + {cond: true}, + {cond: true}, + {cond: false}, + {cond: false}, + {cond: true}, + {cond: false}, + {cond: true}, + {cond: false}, + ], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(2); ++ Object.freeze(props); + let x; + bb0: switch (props.cond) { + case true: { + x = 1; + break bb0; + } + case false: { + x = 2; + break bb0; + } + default: { + x = 3; + } + } + let t0; + if ($[0] !== x) { + t0 = [x]; + $[0] = x; + $[1] = t0; + } else { + t0 = $[1]; + } + return t0; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [], + sequentialRenders: [ + { cond: true }, + { cond: true }, + { cond: false }, + { cond: false }, + { cond: true }, + { cond: false }, + { cond: true }, + { cond: false }, + ], + }; + + ``` +  + ### Eval output + (kind: ok) [1] + [1] + [2] + [2] + [1] + [2] + [1] + [2] + +FAIL: reactive-control-dependency-reactive-after-fixpoint +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + let x = 0; + + let value = null; + loop: for (let i = 0; i < 10; i++) { + switch (value) { + case true: { + x = 1; + break loop; + } + case false: { + x = 2; + break loop; + } + } + + value = props.cond; + } + + // The values assigned to `x` are non-reactive, but the value of `x` + // depends on the "control" variable `value` used as the switch test + // condition. That variable is initially null on the first iteration + // of the loop, but is later set to `props.value` which is reactive. + // Therefore x should be treated as reactive. + return [x]; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [], + sequentialRenders: [ + {cond: true}, + {cond: true}, + {cond: false}, + {cond: false}, + {cond: true}, + {cond: false}, + {cond: true}, + {cond: false}, + ], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(2); ++ Object.freeze(props); + let x = 0; + + let value = null; + for (let i = 0; i < 10; i++) { + switch (value) { + case true: { + x = 1; + break; + } + case false: { + x = 2; + break; + } + } + + value = props.cond; + } + let t0; + if ($[0] !== x) { + t0 = [x]; + $[0] = x; + $[1] = t0; + } else { + t0 = $[1]; + } + return t0; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [], + sequentialRenders: [ + { cond: true }, + { cond: true }, + { cond: false }, + { cond: false }, + { cond: true }, + { cond: false }, + { cond: true }, + { cond: false }, + ], + }; + + ``` +  + ### Eval output + (kind: ok) [1] + [1] + [2] + [2] + [1] + [2] + [1] + [2] + +FAIL: reactive-control-dependency-phi-setState-type + >> Unexpected error during test: + + +Found differences in evaluator results +Non-forget (expected): +(kind: ok) ok +ok +ok +ok +ok +ok +ok +ok +Forget: +(kind: ok) [[ (exception in render) Invariant Violation: Expected the correct setState function ]] +[[ (exception in render) Invariant Violation: Expected the correct setState function ]] +[[ (exception in render) Invariant Violation: Expected the correct setState function ]] +[[ (exception in render) Invariant Violation: Expected the correct setState function ]] +[[ (exception in render) Invariant Violation: Expected the correct setState function ]] +[[ (exception in render) Invariant Violation: Expected the correct setState function ]] +[[ (exception in render) Invariant Violation: Expected the correct setState function ]] +[[ (exception in render) Invariant Violation: Expected the correct setState function ]] + +FAIL: reactive-control-dependency-on-context-variable +- Expected ++ Received + + + ## Input + + ```javascript + import {identity} from 'shared-runtime'; + + function Component(props) { + let x; + // Reassign `x` based on a reactive value, but inside a function expression + // to make it a context variable + const f = () => { + if (props.cond) { + x = 1; + } else { + x = 2; + } + }; + // Pass `f` through a function to prevent IIFE inlining optimizations + const f2 = identity(f); + f2(); + + // The values assigned to `x` are non-reactive, but the value of `x` + // depends on the "control" value `props.cond` which is reactive. + // Therefore x should be treated as reactive too. + return [x]; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [], + sequentialRenders: [ + {cond: true}, + {cond: true}, + {cond: false}, + {cond: false}, + {cond: true}, + {cond: false}, + {cond: true}, + {cond: false}, + ], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { identity } from "shared-runtime"; + + function Component(props) { + const $ = _c(4); ++ Object.freeze(props); + let x; + if ($[0] !== props.cond) { + const f = () => { + if (props.cond) { + x = 1; + } else { + x = 2; + } + }; + + const f2 = identity(f); + f2(); + $[0] = props.cond; + $[1] = x; + } else { + x = $[1]; + } + + const t0 = x; + let t1; + if ($[2] !== t0) { + t1 = [t0]; + $[2] = t0; + $[3] = t1; + } else { + t1 = $[3]; + } + return t1; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [], + sequentialRenders: [ + { cond: true }, + { cond: true }, + { cond: false }, + { cond: false }, + { cond: true }, + { cond: false }, + { cond: true }, + { cond: false }, + ], + }; + + ``` +  + ### Eval output + (kind: ok) [1] + [1] + [2] + [2] + [1] + [2] + [1] + [2] + +FAIL: reactive-control-dependency-if +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + let x; + if (props.cond) { + x = 1; + } else { + x = 2; + } + // The values assigned to `x` are non-reactive, but the value of `x` + // depends on the "control" value `props.cond` which is reactive. + // Therefore x should be treated as reactive too. + return [x]; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [], + sequentialRenders: [ + {cond: true}, + {cond: true}, + {cond: false}, + {cond: false}, + {cond: true}, + {cond: false}, + {cond: true}, + {cond: false}, + ], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(2); ++ Object.freeze(props); + let x; + if (props.cond) { + x = 1; + } else { + x = 2; + } + let t0; + if ($[0] !== x) { + t0 = [x]; + $[0] = x; + $[1] = t0; + } else { + t0 = $[1]; + } + return t0; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [], + sequentialRenders: [ + { cond: true }, + { cond: true }, + { cond: false }, + { cond: false }, + { cond: true }, + { cond: false }, + { cond: true }, + { cond: false }, + ], + }; + + ``` +  + ### Eval output + (kind: ok) [1] + [1] + [2] + [2] + [1] + [2] + [1] + [2] + +FAIL: reactive-control-dependency-from-interleaved-reactivity-while +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + // a and b are independent but their mutations are interleaved, so + // they get grouped in a reactive scope. this means that a becomes + // reactive since it will effectively re-evaluate based on a reactive + // input + const a = []; + const b = []; + b.push(props.cond); + a.push(null); + + // Downstream consumer of a, which initially seems non-reactive except + // that a becomes reactive, per above + const c = [a]; + + let x; + while (c[0][0]) { + x = 1; + } + // The values assigned to `x` are non-reactive, but the value of `x` + // depends on the "control" value `c[0]` which becomes reactive via + // being interleaved with `b`. + // Therefore x should be treated as reactive too. + return [x]; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{cond: true}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(1); ++ Object.freeze(props); + + const a = []; + const b = []; + b.push(props.cond); + a.push(null); + + const c = [a]; + + let x; + while (c[0][0]) { + x = 1; + } + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = [x]; + $[0] = t0; + } else { + t0 = $[0]; + } + return t0; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ cond: true }], + }; + + ``` +  + ### Eval output + (kind: ok) [null] + +FAIL: reactive-control-dependency-from-interleaved-reactivity-switch +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + // a and b are independent but their mutations are interleaved, so + // they get grouped in a reactive scope. this means that a becomes + // reactive since it will effectively re-evaluate based on a reactive + // input + const a = []; + const b = []; + b.push(props.cond); + a.push(null); + + // Downstream consumer of a, which initially seems non-reactive except + // that a becomes reactive, per above + const c = [a]; + + let x; + switch (c[0][0]) { + case true: { + x = 1; + break; + } + default: { + x = 2; + } + } + // The values assigned to `x` are non-reactive, but the value of `x` + // depends on the "control" value `c[0]` which becomes reactive via + // being interleaved with `b`. + // Therefore x should be treated as reactive too. + return [x]; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{cond: true}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(1); ++ Object.freeze(props); + + const a = []; + const b = []; + b.push(props.cond); + a.push(null); + + const c = [a]; + + let x; + bb0: switch (c[0][0]) { + case true: { + x = 1; + break bb0; + } + default: { + x = 2; + } + } + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = [x]; + $[0] = t0; + } else { + t0 = $[0]; + } + return t0; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ cond: true }], + }; + + ``` +  + ### Eval output + (kind: ok) [2] + +FAIL: reactive-control-dependency-from-interleaved-reactivity-if +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + // a and b are independent but their mutations are interleaved, so + // they get grouped in a reactive scope. this means that a becomes + // reactive since it will effectively re-evaluate based on a reactive + // input + const a = []; + const b = []; + b.push(props.cond); + a.push(null); + + // Downstream consumer of a, which initially seems non-reactive except + // that a becomes reactive, per above + const c = [a]; + + let x; + if (c[0][0]) { + x = 1; + } else { + x = 2; + } + // The values assigned to `x` are non-reactive, but the value of `x` + // depends on the "control" value `c[0]` which becomes reactive via + // being interleaved with `b`. + // Therefore x should be treated as reactive too. + return [x]; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{cond: true}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(1); ++ Object.freeze(props); + + const a = []; + const b = []; + b.push(props.cond); + a.push(null); + + const c = [a]; + + let x; + if (c[0][0]) { + x = 1; + } else { + x = 2; + } + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = [x]; + $[0] = t0; + } else { + t0 = $[0]; + } + return t0; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ cond: true }], + }; + + ``` +  + ### Eval output + (kind: ok) [2] + +FAIL: reactive-control-dependency-from-interleaved-reactivity-for-update +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + // a and b are independent but their mutations are interleaved, so + // they get grouped in a reactive scope. this means that a becomes + // reactive since it will effectively re-evaluate based on a reactive + // input + const a = []; + const b = []; + b.push(props.cond); + a.push(10); + + // Downstream consumer of a, which initially seems non-reactive except + // that a becomes reactive, per above + const c = [a]; + + let x; + for (let i = 0; i < 10; i += c[0][0]) { + x = 1; + } + // The values assigned to `x` are non-reactive, but the value of `x` + // depends on the "control" value `c[0]` which becomes reactive via + // being interleaved with `b`. + // Therefore x should be treated as reactive too. + return [x]; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{cond: true}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(1); ++ Object.freeze(props); + + const a = []; + const b = []; + b.push(props.cond); + a.push(10); + + const c = [a]; + + let x; + for (let i = 0; i < 10; i = i + c[0][0], i) { + x = 1; + } + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = [x]; + $[0] = t0; + } else { + t0 = $[0]; + } + return t0; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ cond: true }], + }; + + ``` +  + ### Eval output + (kind: ok) [1] + +FAIL: reactive-control-dependency-from-interleaved-reactivity-for-test +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + // a and b are independent but their mutations are interleaved, so + // they get grouped in a reactive scope. this means that a becomes + // reactive since it will effectively re-evaluate based on a reactive + // input + const a = []; + const b = []; + b.push(props.cond); + a.push(10); + + // Downstream consumer of a, which initially seems non-reactive except + // that a becomes reactive, per above + const c = [a]; + + let x; + for (let i = 0; i < c[0][0]; i++) { + x = 1; + } + // The values assigned to `x` are non-reactive, but the value of `x` + // depends on the "control" value `c[0]` which becomes reactive via + // being interleaved with `b`. + // Therefore x should be treated as reactive too. + return [x]; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{cond: true}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(1); ++ Object.freeze(props); + + const a = []; + const b = []; + b.push(props.cond); + a.push(10); + + const c = [a]; + + let x; + for (let i = 0; i < c[0][0]; i++) { + x = 1; + } + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = [x]; + $[0] = t0; + } else { + t0 = $[0]; + } + return t0; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ cond: true }], + }; + + ``` +  + ### Eval output + (kind: ok) [1] + +FAIL: reactive-control-dependency-from-interleaved-reactivity-for-of +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + // a and b are independent but their mutations are interleaved, so + // they get grouped in a reactive scope. this means that a becomes + // reactive since it will effectively re-evaluate based on a reactive + // input + const a = []; + const b = []; + b.push(props.cond); + a.push(null); + + // Downstream consumer of a, which initially seems non-reactive except + // that a becomes reactive, per above + const c = [a]; + + let x; + for (const i of c[0]) { + x = 1; + } + // The values assigned to `x` are non-reactive, but the value of `x` + // depends on the "control" value `c[0]` which becomes reactive via + // being interleaved with `b`. + // Therefore x should be treated as reactive too. + return [x]; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{cond: true}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(1); ++ Object.freeze(props); + + const a = []; + const b = []; + b.push(props.cond); + a.push(null); + + const c = [a]; + + let x; + for (const i of c[0]) { + x = 1; + } + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = [x]; + $[0] = t0; + } else { + t0 = $[0]; + } + return t0; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ cond: true }], + }; + + ``` +  + ### Eval output + (kind: ok) [1] + +FAIL: reactive-control-dependency-from-interleaved-reactivity-for-init +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + // a and b are independent but their mutations are interleaved, so + // they get grouped in a reactive scope. this means that a becomes + // reactive since it will effectively re-evaluate based on a reactive + // input + const a = []; + const b = []; + b.push(props.cond); + a.push(0); + + // Downstream consumer of a, which initially seems non-reactive except + // that a becomes reactive, per above + const c = [a]; + + let x; + for (let i = c[0][0]; i < 10; i++) { + x = 1; + } + // The values assigned to `x` are non-reactive, but the value of `x` + // depends on the "control" value `c[0]` which becomes reactive via + // being interleaved with `b`. + // Therefore x should be treated as reactive too. + return [x]; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{cond: true}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(1); ++ Object.freeze(props); + + const a = []; + const b = []; + b.push(props.cond); + a.push(0); + + const c = [a]; + + let x; + for (let i = c[0][0]; i < 10; i++) { + x = 1; + } + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = [x]; + $[0] = t0; + } else { + t0 = $[0]; + } + return t0; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ cond: true }], + }; + + ``` +  + ### Eval output + (kind: ok) [1] + +FAIL: reactive-control-dependency-from-interleaved-reactivity-for-in +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + // a and b are independent but their mutations are interleaved, so + // they get grouped in a reactive scope. this means that a becomes + // reactive since it will effectively re-evaluate based on a reactive + // input + const a = []; + const b = []; + b.push(props.cond); + a.push({a: false}); + + // Downstream consumer of a, which initially seems non-reactive except + // that a becomes reactive, per above + const c = [a]; + + let x; + for (const i in c[0][0]) { + x = 1; + } + // The values assigned to `x` are non-reactive, but the value of `x` + // depends on the "control" value `c[0]` which becomes reactive via + // being interleaved with `b`. + // Therefore x should be treated as reactive too. + return [x]; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{cond: true}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(1); ++ Object.freeze(props); + + const a = []; + const b = []; + b.push(props.cond); + a.push({ a: false }); + + const c = [a]; + + let x; + for (const i in c[0][0]) { + x = 1; + } + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = [x]; + $[0] = t0; + } else { + t0 = $[0]; + } + return t0; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ cond: true }], + }; + + ``` +  + ### Eval output + (kind: ok) [1] + +FAIL: reactive-control-dependency-from-interleaved-reactivity-do-while +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + // a and b are independent but their mutations are interleaved, so + // they get grouped in a reactive scope. this means that a becomes + // reactive since it will effectively re-evaluate based on a reactive + // input + const a = []; + const b = []; + b.push(props.cond); + a.push(false); + + // Downstream consumer of a, which initially seems non-reactive except + // that a becomes reactive, per above + const c = [a]; + + let x = 0; + do { + x += 1; + } while (c[0][0]); + // The values assigned to `x` are non-reactive, but the value of `x` + // depends on the "control" value `c[0]` which becomes reactive via + // being interleaved with `b`. + // Therefore x should be treated as reactive too. + return [x]; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{cond: true}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(1); ++ Object.freeze(props); + + const a = []; + const b = []; + b.push(props.cond); + a.push(false); + + const c = [a]; + + let x = 0; + do { + x = x + 1; + } while (c[0][0]); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = [x]; + $[0] = t0; + } else { + t0 = $[0]; + } + return t0; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ cond: true }], + }; + + ``` +  + ### Eval output + (kind: ok) [1] + +FAIL: reactive-control-dependency-forof-collection +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + let x; + for (const i of props.values) { + if (i > 10) { + x = 10; + } else { + x = 1; + } + } + // The values assigned to `x` are non-reactive, but the value of `x` + // depends on the "control" variable `i`, whose value is derived from + // `props.values` which is reactive. + // Therefore x should be treated as reactive too. + return [x]; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [], + sequentialRenders: [ + {values: [12]}, + {values: [12]}, + {values: [1]}, + {values: [1]}, + {values: [12]}, + {values: [1]}, + {values: [12]}, + {values: [1]}, + ], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(2); ++ Object.freeze(props); + let x; + for (const i of props.values) { + if (i > 10) { + x = 10; + } else { + x = 1; + } + } + let t0; + if ($[0] !== x) { + t0 = [x]; + $[0] = x; + $[1] = t0; + } else { + t0 = $[1]; + } + return t0; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [], + sequentialRenders: [ + { values: [12] }, + { values: [12] }, + { values: [1] }, + { values: [1] }, + { values: [12] }, + { values: [1] }, + { values: [12] }, + { values: [1] }, + ], + }; + + ``` +  + ### Eval output + (kind: ok) [10] + [10] + [1] + [1] + [10] + [1] + [10] + [1] + +FAIL: reactive-control-dependency-forin-collection +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + let x; + for (const key in props.values) { + const i = parseInt(key, 10); + if (i > 10) { + x = 10; + } else { + x = 1; + } + } + // The values assigned to `x` are non-reactive, but the value of `x` + // depends on the "control" variable `i`, whose value is derived from + // `props.values` which is reactive. + // Therefore x should be treated as reactive too. + return [x]; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [], + sequentialRenders: [ + {values: {'12': true}}, + {values: {'12': true}}, + {values: {'1': true}}, + {values: {'1': true}}, + {values: {'12': true}}, + {values: {'1': true}}, + {values: {'12': true}}, + {values: {'1': true}}, + ], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(2); ++ Object.freeze(props); + let x; + for (const key in props.values) { + const i = parseInt(key, 10); + if (i > 10) { + x = 10; + } else { + x = 1; + } + } + let t0; + if ($[0] !== x) { + t0 = [x]; + $[0] = x; + $[1] = t0; + } else { + t0 = $[1]; + } + return t0; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [], + sequentialRenders: [ + { values: { "12": true } }, + { values: { "12": true } }, + { values: { "1": true } }, + { values: { "1": true } }, + { values: { "12": true } }, + { values: { "1": true } }, + { values: { "12": true } }, + { values: { "1": true } }, + ], + }; + + ``` +  + ### Eval output + (kind: ok) [10] + [10] + [1] + [1] + [10] + [1] + [10] + [1] + +FAIL: reactive-control-dependency-for-update +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + let x; + for (let i = 0; i < 10; i += props.update) { + if (i > 0 && i % 2 === 0) { + x = 2; + } else { + x = 1; + } + } + // The values assigned to `x` are non-reactive, but the value of `x` + // depends on the "control" variable `i`, whose possible values are + // affected by `props.update` which is reactive. + // Therefore x should be treated as reactive too. + return [x]; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [], + sequentialRenders: [ + {update: 2}, + {update: 2}, + {update: 1}, + {update: 1}, + {update: 2}, + {update: 1}, + {update: 2}, + {update: 1}, + ], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(2); ++ Object.freeze(props); + let x; + for (let i = 0; i < 10; i = i + props.update, i) { + if (i > 0 && i % 2 === 0) { + x = 2; + } else { + x = 1; + } + } + let t0; + if ($[0] !== x) { + t0 = [x]; + $[0] = x; + $[1] = t0; + } else { + t0 = $[1]; + } + return t0; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [], + sequentialRenders: [ + { update: 2 }, + { update: 2 }, + { update: 1 }, + { update: 1 }, + { update: 2 }, + { update: 1 }, + { update: 2 }, + { update: 1 }, + ], + }; + + ``` +  + ### Eval output + (kind: ok) [2] + [2] + [1] + [1] + [2] + [1] + [2] + [1] + +FAIL: reactive-control-dependency-for-test +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + let x; + for (let i = 0; i < props.test; i++) { + if (i > 10) { + x = 10; + } else { + x = 1; + } + } + // The values assigned to `x` are non-reactive, but the value of `x` + // depends on the "control" variable `i`, whose value is capped by + // `props.test` which is reactive. + // Therefore x should be treated as reactive too. + return [x]; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [], + sequentialRenders: [ + {test: 12}, + {test: 12}, + {test: 1}, + {test: 1}, + {test: 12}, + {test: 1}, + {test: 12}, + {test: 1}, + ], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(2); ++ Object.freeze(props); + let x; + for (let i = 0; i < props.test; i++) { + if (i > 10) { + x = 10; + } else { + x = 1; + } + } + let t0; + if ($[0] !== x) { + t0 = [x]; + $[0] = x; + $[1] = t0; + } else { + t0 = $[1]; + } + return t0; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [], + sequentialRenders: [ + { test: 12 }, + { test: 12 }, + { test: 1 }, + { test: 1 }, + { test: 12 }, + { test: 1 }, + { test: 12 }, + { test: 1 }, + ], + }; + + ``` +  + ### Eval output + (kind: ok) [10] + [10] + [1] + [1] + [10] + [1] + [10] + [1] + +FAIL: reactive-control-dependency-for-init +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + let x; + for (let i = props.init; i < 10; i++) { + if (i === 0) { + x = 0; + break; + } else { + x = 1; + break; + } + } + // The values assigned to `x` are non-reactive, but the value of `x` + // depends on the "control" variable `i`, whose initial value `props.init` is reactive. + // Therefore x should be treated as reactive too. + return [x]; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [], + sequentialRenders: [ + {init: 0}, + {init: 0}, + {init: 10}, + {init: 10}, + {init: 0}, + {init: 10}, + {init: 0}, + {init: 10}, + ], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(2); ++ Object.freeze(props); + let x; + for (const i = props.init; i < 10; ) { + if (i === 0) { + x = 0; + break; + } else { + x = 1; + break; + } + } + let t0; + if ($[0] !== x) { + t0 = [x]; + $[0] = x; + $[1] = t0; + } else { + t0 = $[1]; + } + return t0; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [], + sequentialRenders: [ + { init: 0 }, + { init: 0 }, + { init: 10 }, + { init: 10 }, + { init: 0 }, + { init: 10 }, + { init: 0 }, + { init: 10 }, + ], + }; + + ``` +  + ### Eval output + (kind: ok) [0] + [0] + [null] + [null] + [0] + [null] + [0] + [null] + +FAIL: reactive-control-dependency-do-while-test +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + let x; + let i = 0; + do { + if (i > 10) { + x = 10; + } else { + x = 1; + } + i++; + } while (i < props.test); + // The values assigned to `x` are non-reactive, but the value of `x` + // depends on the "control" variable `i`, whose value is affected by + // `props.test` which is reactive. + // Therefore x should be treated as reactive too. + return [x]; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [], + sequentialRenders: [ + {test: 12}, + {test: 12}, + {test: 1}, + {test: 1}, + {test: 12}, + {test: 1}, + {test: 12}, + {test: 1}, + ], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(2); ++ Object.freeze(props); + let x; + let i = 0; + do { + if (i > 10) { + x = 10; + } else { + x = 1; + } + + i++; + } while (i < props.test); + let t0; + if ($[0] !== x) { + t0 = [x]; + $[0] = x; + $[1] = t0; + } else { + t0 = $[1]; + } + return t0; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [], + sequentialRenders: [ + { test: 12 }, + { test: 12 }, + { test: 1 }, + { test: 1 }, + { test: 12 }, + { test: 1 }, + { test: 12 }, + { test: 1 }, + ], + }; + + ``` +  + ### Eval output + (kind: ok) [10] + [10] + [1] + [1] + [10] + [1] + [10] + [1] + +FAIL: reactive-control-dependency-do-while-indirect +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + let x = 0; + let y = 0; + let z = 0; + do { + x += 1; + y += 1; + z = y; + } while (x < props.limit); + return [z]; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [], + sequentialRenders: [ + {limit: 10}, + {limit: 10}, + {limit: 1}, + {limit: 1}, + {limit: 10}, + {limit: 1}, + {limit: 10}, + {limit: 1}, + ], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(2); ++ Object.freeze(props); + let x = 0; + let y = 0; + let z; + do { + x = x + 1; + y = y + 1; + z = y; + } while (x < props.limit); + let t0; + if ($[0] !== z) { + t0 = [z]; + $[0] = z; + $[1] = t0; + } else { + t0 = $[1]; + } + return t0; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [], + sequentialRenders: [ + { limit: 10 }, + { limit: 10 }, + { limit: 1 }, + { limit: 1 }, + { limit: 10 }, + { limit: 1 }, + { limit: 10 }, + { limit: 1 }, + ], + }; + + ``` +  + ### Eval output + (kind: ok) [10] + [10] + [1] + [1] + [10] + [1] + [10] + [1] + +FAIL: react-namespace +- Expected ++ Received + + + ## Input + + ```javascript + const FooContext = React.createContext({current: null}); + + function Component(props) { + const foo = React.useContext(FooContext); + const ref = React.useRef(); + const [x, setX] = React.useState(false); + const onClick = () => { + setX(true); + ref.current = true; + }; + return
{React.cloneElement(props.children)}
; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{children:
Hello
}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + const FooContext = React.createContext({ current: null }); + + function Component(props) { + const $ = _c(6); +- React.useContext(FooContext); +- const ref = React.useRef(); +- const [x, setX] = React.useState(false); ++ Object.freeze(props); ++ (function () { ++ const $res$ = React.useContext(Object.freeze(FooContext)); ++ Object.freeze($res$); ++ return $res$; ++ })(); ++ const ref = (function () { ++ const $res$ = React.useRef(); ++ Object.freeze($res$); ++ return $res$; ++ })(); ++ const [x, setX] = (function () { ++ const $res$ = React.useState(Object.freeze(false)); ++ Object.freeze($res$); ++ return $res$; ++ })(); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = () => { + setX(true); + ref.current = true; + }; + $[0] = t0; + } else { + t0 = $[0]; + } + const onClick = t0; + let t1; + if ($[1] !== props.children) { + t1 = React.cloneElement(props.children); + $[1] = props.children; + $[2] = t1; + } else { + t1 = $[2]; + } + let t2; + if ($[3] !== onClick || $[4] !== t1) { +- t2 =
{t1}
; ++ t2 = ( ++  ++ {t1} ++
 ++ ); + $[3] = onClick; + $[4] = t1; + $[5] = t2; + } else { + t2 = $[5]; + } + return t2; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ children:
Hello
}], + }; + + ``` +  + ### Eval output + (kind: ok)
Hello
 + +FAIL: quoted-strings-jsx-attribute-escaped-constant-propagation + >> Unexpected error during test: + + +Found differences in evaluator results +Non-forget (expected): +(kind: ok) Some "text" +Forget: +(kind: ok) +logs: ['Warning: Functions are not valid as a React child. This may happen if you return %s instead of <%s /> from render. Or maybe you meant to call this function rather than return it.\n' + + ' <%s>{%s}%s','text','text','Child','text','Child','\n' + + ' at Child (eval at doEval (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:200:28), :40:16)\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)'] + +FAIL: quoted-strings-in-jsx-attribute + >> Unexpected error during test: + + +Found differences in evaluator results +Non-forget (expected): +(kind: ok) Some "text" +Forget: +(kind: ok) +logs: ['Warning: Functions are not valid as a React child. This may happen if you return %s instead of <%s /> from render. Or maybe you meant to call this function rather than return it.\n' + + ' <%s>{%s}%s','text','text','Child','text','Child','\n' + + ' at Child (eval at doEval (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:200:28), :40:16)\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)'] + +FAIL: quoted-strings-in-jsx-attribute-escaped + >> Unexpected error during test: + + +Found differences in evaluator results +Non-forget (expected): +(kind: ok) Some \"text\" +Forget: +(kind: ok) +logs: ['Warning: Functions are not valid as a React child. This may happen if you return %s instead of <%s /> from render. Or maybe you meant to call this function rather than return it.\n' + + ' <%s>{%s}%s','text','text','Child','text','Child','\n' + + ' at Child (eval at doEval (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:200:28), :40:16)\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)'] + +FAIL: prune-scopes-whose-deps-may-invalidate-array +- Expected ++ Received + + + ## Input + + ```javascript + import {useHook, identity} from 'shared-runtime'; + + function Component(props) { + let x = 42; + if (props.cond) { + x = []; + } + useHook(); // intersperse a hook call to prevent memoization of x + identity(x); + + const y = [x]; + + return [y]; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{value: 'sathya'}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { useHook, identity } from "shared-runtime"; + + function Component(props) { + const $ = _c(4); ++ Object.freeze(props); + let x = 42; + if (props.cond) { + x = []; + } +- +- useHook(); ++ (function () { ++ const $res$ = useHook(); ++ Object.freeze($res$); ++ return $res$; ++ })(); + identity(x); + let t0; + if ($[0] !== x) { + t0 = [x]; + $[0] = x; + $[1] = t0; + } else { + t0 = $[1]; + } + const y = t0; + let t1; + if ($[2] !== y) { + t1 = [y]; + $[2] = y; + $[3] = t1; + } else { + t1 = $[3]; + } + return t1; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ value: "sathya" }], + }; + + ``` +  + ### Eval output + (kind: ok) [[42]] + +FAIL: prune-scopes-whose-deps-invalidate-object +- Expected ++ Received + + + ## Input + + ```javascript + import {useHook} from 'shared-runtime'; + + function Component(props) { + const x = {}; + useHook(); // intersperse a hook call to prevent memoization of x + x.value = props.value; + + const y = {x}; + + return {y}; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{value: 'sathya'}], + }; + + ``` + + ## Code + + ```javascript + import { useHook } from "shared-runtime"; + + function Component(props) { ++ Object.freeze(props); + const x = {}; +- useHook(); ++ (function () { ++ const $res$ = useHook(); ++ Object.freeze($res$); ++ return $res$; ++ })(); + x.value = props.value; + + const y = { x }; + return { y }; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ value: "sathya" }], + }; + + ``` +  + ### Eval output + (kind: ok) {"y":{"x":{"value":"sathya"}}} + +FAIL: prune-scopes-whose-deps-invalidate-new +- Expected ++ Received + + + ## Input + + ```javascript + import {useHook} from 'shared-runtime'; + + function Component(props) { + const x = new Foo(); + useHook(); // intersperse a hook call to prevent memoization of x + x.value = props.value; + + const y = {x}; + + return {y}; + } + + class Foo {} + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{value: 'sathya'}], + }; + + ``` + + ## Code + + ```javascript + import { useHook } from "shared-runtime"; + + function Component(props) { ++ Object.freeze(props); + const x = new Foo(); +- useHook(); ++ (function () { ++ const $res$ = useHook(); ++ Object.freeze($res$); ++ return $res$; ++ })(); + x.value = props.value; + + const y = { x }; + return { y }; + } + + class Foo {} + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ value: "sathya" }], + }; + + ``` +  + ### Eval output + (kind: ok) {"y":{"x":{"value":"sathya"}}} + +FAIL: prune-scopes-whose-deps-invalidate-jsx +- Expected ++ Received + + + ## Input + + ```javascript + import {useHook} from 'shared-runtime'; + + function Component(props) { + const o = {}; + const x =
{props.value}
; // create within the range of x to group with x + useHook(); // intersperse a hook call to prevent memoization of x + o.value = props.value; + + const y =
{x}
; + + return
{y}
; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{value: 'sathya'}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { useHook } from "shared-runtime"; + + function Component(props) { + const $ = _c(6); ++ Object.freeze(props); + const o = {}; + let t0; + if ($[0] !== props.value) { + t0 =
{props.value}
; + $[0] = props.value; + $[1] = t0; + } else { + t0 = $[1]; + } + const x = t0; +- useHook(); ++ (function () { ++ const $res$ = useHook(); ++ Object.freeze($res$); ++ return $res$; ++ })(); + o.value = props.value; + let t1; + if ($[2] !== x) { + t1 =
{x}
; + $[2] = x; + $[3] = t1; + } else { + t1 = $[3]; + } + const y = t1; + let t2; + if ($[4] !== y) { + t2 =
{y}
; + $[4] = y; + $[5] = t2; + } else { + t2 = $[5]; + } + return t2; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ value: "sathya" }], + }; + + ``` +  + ### Eval output + (kind: ok)
sathya
 + +FAIL: prune-scopes-whose-deps-invalidate-array +- Expected ++ Received + + + ## Input + + ```javascript + import {useHook} from 'shared-runtime'; + + function Component(props) { + const x = []; + useHook(); // intersperse a hook call to prevent memoization of x + x.push(props.value); + + const y = [x]; + + return [y]; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{value: 'sathya'}], + }; + + ``` + + ## Code + + ```javascript + import { useHook } from "shared-runtime"; + + function Component(props) { ++ Object.freeze(props); + const x = []; +- useHook(); ++ (function () { ++ const $res$ = useHook(); ++ Object.freeze($res$); ++ return $res$; ++ })(); + x.push(props.value); + + const y = [x]; + return [y]; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ value: "sathya" }], + }; + + ``` +  + ### Eval output + (kind: ok) [[["sathya"]]] + +FAIL: property-call-spread +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + const x = foo.bar(...props.a, null, ...props.b); + return x; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(3); ++ Object.freeze(props); + let t0; + if ($[0] !== props.a || $[1] !== props.b) { + t0 = foo.bar(...props.a, null, ...props.b); + $[0] = props.a; + $[1] = props.b; + $[2] = t0; + } else { + t0 = $[2]; + } + const x = t0; + return x; + } + + ``` +  + +FAIL: property-assignment +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + const x = {}; + const y = []; + x.y = y; + const child = ; + x.y.push(props.p0); + return {child}; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(2); ++ Object.freeze(props); + let t0; + if ($[0] !== props.p0) { + const x = {}; + const y = []; + x.y = y; +- const child = ; ++ const child = ( ++  ++ ); + x.y.push(props.p0); +- t0 = {child}; ++ t0 = ( ++  ++ {child} ++  ++ ); + $[0] = props.p0; + $[1] = t0; + } else { + t0 = $[1]; + } + return t0; + } + + ``` +  + +FAIL: prop-capturing-function-1 +- Expected ++ Received + + + ## Input + + ```javascript + function component(a, b) { + let z = {a, b}; + let x = function () { + console.log(z); + }; + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: component, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function component(a, b) { + const $ = _c(5); ++ Object.freeze(a); ++ Object.freeze(b); + let t0; + if ($[0] !== a || $[1] !== b) { + t0 = { a, b }; + $[0] = a; + $[1] = b; + $[2] = t0; + } else { + t0 = $[2]; + } + const z = t0; + let t1; + if ($[3] !== z) { + t1 = function () { + console.log(z); + }; + $[3] = z; + $[4] = t1; + } else { + t1 = $[4]; + } + const x = t1; + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: component, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: primitive-reassigned-loop-force-scopes-enabled +- Expected ++ Received + + + ## Input + + ```javascript + // @enableForest + function Component({base, start, increment, test}) { + let value = base; + for (let i = start; i < test; i += increment) { + value += i; + } + return
{value}
; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{base: 0, start: 0, test: 10, increment: 1}], + sequentialRenders: [ + {base: 0, start: 1, test: 10, increment: 1}, + {base: 0, start: 0, test: 10, increment: 2}, + {base: 2, start: 0, test: 10, increment: 2}, + {base: 0, start: 0, test: 11, increment: 2}, + ], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; // @enableForest + function Component(t0) { + const $ = _c(5); ++ Object.freeze(t0); + const { base, start, increment, test } = t0; + let value; + if ($[0] !== base || $[1] !== start || $[2] !== test || $[3] !== increment) { + value = base; + for (let i = start; i < test; i = i + increment, i) { + value = value + i; + } + $[0] = base; + $[1] = start; + $[2] = test; + $[3] = increment; + $[4] = value; + } else { + value = $[4]; + } + return
{value}
; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ base: 0, start: 0, test: 10, increment: 1 }], + sequentialRenders: [ + { base: 0, start: 1, test: 10, increment: 1 }, + { base: 0, start: 0, test: 10, increment: 2 }, + { base: 2, start: 0, test: 10, increment: 2 }, + { base: 0, start: 0, test: 11, increment: 2 }, + ], + }; + + ``` +  + ### Eval output + (kind: ok)
45
 +
20
 +
22
 +
30
 + +FAIL: primitive-as-dep +- Expected ++ Received + + + ## Input + + ```javascript + // props.b + 1 is an non-allocating expression, which means Forget can + // emit it trivially and repeatedly (e.g. no need to memoize props.b + 1 + // separately from props.b) + // Correctness: + // y depends on either props.b or props.b + 1 + function PrimitiveAsDep(props) { + let y = foo(props.b + 1); + return y; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; // props.b + 1 is an non-allocating expression, which means Forget can + // emit it trivially and repeatedly (e.g. no need to memoize props.b + 1 + // separately from props.b) + // Correctness: + // y depends on either props.b or props.b + 1 + function PrimitiveAsDep(props) { + const $ = _c(2); ++ Object.freeze(props); + const t0 = props.b + 1; + let t1; + if ($[0] !== t0) { + t1 = foo(t0); + $[0] = t0; + $[1] = t1; + } else { + t1 = $[1]; + } + const y = t1; + return y; + } + + ``` +  + +FAIL: primitive-as-dep-nested-scope +- Expected ++ Received + + + ## Input + + ```javascript + // props.b + 1 is an non-allocating expression, which means Forget can + // emit it trivially and repeatedly (e.g. no need to memoize props.b + 1 + // separately from props.b) + // Correctness: + + import {identity, mutate, setProperty} from 'shared-runtime'; + + // y depends on either props.b or props.b + 1 + function PrimitiveAsDepNested(props) { + let x = {}; + mutate(x); + let y = identity(props.b + 1); + setProperty(x, props.a); + return [x, y]; + } + + export const FIXTURE_ENTRYPOINT = { + fn: PrimitiveAsDepNested, + params: [{a: 1, b: 2}], + sequentialRenders: [ + // change b + {a: 1, b: 3}, + // change b + {a: 1, b: 4}, + // change a + {a: 2, b: 4}, + // change a + {a: 3, b: 4}, + ], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; // props.b + 1 is an non-allocating expression, which means Forget can + // emit it trivially and repeatedly (e.g. no need to memoize props.b + 1 + // separately from props.b) + // Correctness: + + import { identity, mutate, setProperty } from "shared-runtime"; + + // y depends on either props.b or props.b + 1 + function PrimitiveAsDepNested(props) { + const $ = _c(5); ++ Object.freeze(props); + let t0; + if ($[0] !== props.b || $[1] !== props.a) { + const x = {}; + mutate(x); + const t1 = props.b + 1; + let t2; + if ($[3] !== t1) { + t2 = identity(t1); + $[3] = t1; + $[4] = t2; + } else { + t2 = $[4]; + } + const y = t2; + setProperty(x, props.a); + t0 = [x, y]; + $[0] = props.b; + $[1] = props.a; + $[2] = t0; + } else { + t0 = $[2]; + } + return t0; + } + + export const FIXTURE_ENTRYPOINT = { + fn: PrimitiveAsDepNested, + params: [{ a: 1, b: 2 }], + sequentialRenders: [ + // change b + { a: 1, b: 3 }, + // change b + { a: 1, b: 4 }, + // change a + { a: 2, b: 4 }, + // change a + { a: 3, b: 4 }, + ], + }; + + ``` +  + ### Eval output + (kind: ok) [{"wat0":"joe","wat1":1},4] + [{"wat0":"joe","wat1":1},5] + [{"wat0":"joe","wat1":2},5] + [{"wat0":"joe","wat1":3},5] + +FAIL: primitive-alias-mutate +- Expected ++ Received + + + ## Input + + ```javascript + function component(a) { + let x = 'foo'; + if (a) { + x = 'bar'; + } else { + x = 'baz'; + } + let y = x; + mutate(y); + return y; + } + + ``` + + ## Code + + ```javascript + function component(a) { ++ Object.freeze(a); + let x; + if (a) { + x = "bar"; + } else { + x = "baz"; + } + + const y = x; + mutate(y); + return y; + } + + ``` +  + +FAIL: phi-type-inference-property-store +- Expected ++ Received + + + ## Input + + ```javascript + // @debug + function Component(props) { + const x = {}; + let y; + if (props.cond) { + y = {}; + } else { + y = {a: props.a}; + } + // This should be inferred as ` y` s.t. `x` can still + // be independently memoized. *But* this also must properly + // extend the mutable range of the object literals in the + // if/else branches + y.x = x; + + return [x, y]; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{cond: false, a: 'a!'}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; // @debug + function Component(props) { + const $ = _c(5); ++ Object.freeze(props); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = {}; + $[0] = t0; + } else { + t0 = $[0]; + } + const x = t0; + let y; + if ($[1] !== props) { + if (props.cond) { + y = {}; + } else { + y = { a: props.a }; + } + + y.x = x; + $[1] = props; + $[2] = y; + } else { + y = $[2]; + } + let t1; + if ($[3] !== y) { + t1 = [x, y]; + $[3] = y; + $[4] = t1; + } else { + t1 = $[4]; + } + return t1; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ cond: false, a: "a!" }], + }; + + ``` +  + ### Eval output + (kind: ok) [{},{"a":"a!","x":"[[ cyclic ref *1 ]]"}] + +FAIL: phi-type-inference-array-push +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + const x = {}; + let y; + if (props.cond) { + y = [props.value]; + } else { + y = []; + } + // This should be inferred as ` y` s.t. `x` can still + // be independently memoized. *But* this also must properly + // extend the mutable range of the array literals in the + // if/else branches + y.push(x); + + return [x, y]; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{cond: true, value: 42}], + sequentialRenders: [ + {cond: true, value: 3.14}, + {cond: false, value: 3.14}, + {cond: true, value: 42}, + ], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(2); ++ Object.freeze(props); + let t0; + if ($[0] !== props) { + const x = {}; + let y; + if (props.cond) { + y = [props.value]; + } else { + y = []; + } + + y.push(x); + + t0 = [x, y]; + $[0] = props; + $[1] = t0; + } else { + t0 = $[1]; + } + return t0; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ cond: true, value: 42 }], + sequentialRenders: [ + { cond: true, value: 3.14 }, + { cond: false, value: 3.14 }, + { cond: true, value: 42 }, + ], + }; + + ``` +  + ### Eval output + (kind: ok) [{},[3.14,"[[ cyclic ref *1 ]]"]] + [{},["[[ cyclic ref *1 ]]"]] + [{},[42,"[[ cyclic ref *1 ]]"]] + +FAIL: phi-reference-effects +- Expected ++ Received + + + ## Input + + ```javascript + import {arrayPush} from 'shared-runtime'; + + function Foo(cond) { + let x = null; + if (cond) { + x = []; + } else { + } + // Here, x = phi(x$null, x$[]) should receive a ValueKind of Mutable + arrayPush(x, 2); + + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Foo, + params: [{cond: true}], + sequentialRenders: [{cond: true}, {cond: true}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { arrayPush } from "shared-runtime"; + + function Foo(cond) { + const $ = _c(2); ++ Object.freeze(cond); + let x; + if ($[0] !== cond) { + x = null; + if (cond) { + x = []; + } + + arrayPush(x, 2); + $[0] = cond; + $[1] = x; + } else { + x = $[1]; + } + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Foo, + params: [{ cond: true }], + sequentialRenders: [{ cond: true }, { cond: true }], + }; + + ``` +  + ### Eval output + (kind: ok) [2] + [2] + +FAIL: partial-early-return-within-reactive-scope +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + let x = []; + let y = null; + if (props.cond) { + x.push(props.a); + // oops no memo! + return x; + } else { + y = foo(); + if (props.b) { + return; + } + } + return y; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{cond: true, a: 42}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(4); ++ Object.freeze(props); + let y; + let t0; + if ($[0] !== props) { + t0 = Symbol.for("react.early_return_sentinel"); + bb0: { + const x = []; + if (props.cond) { + x.push(props.a); + t0 = x; + break bb0; + } else { + let t1; + if ($[3] === Symbol.for("react.memo_cache_sentinel")) { + t1 = foo(); + $[3] = t1; + } else { + t1 = $[3]; + } + y = t1; + if (props.b) { + t0 = undefined; + break bb0; + } + } + } + $[0] = props; + $[1] = y; + $[2] = t0; + } else { + y = $[1]; + t0 = $[2]; + } + if (t0 !== Symbol.for("react.early_return_sentinel")) { + return t0; + } + return y; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ cond: true, a: 42 }], + }; + + ``` +  + ### Eval output + (kind: ok) [42] + +FAIL: overlapping-scopes-within-block +- Expected ++ Received + + + ## Input + + ```javascript + function foo(a, b, c) { + let x = []; + if (a) { + let y = []; + if (b) { + y.push(c); + } + + x.push(y); + } + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function foo(a, b, c) { + const $ = _c(7); ++ Object.freeze(a); ++ Object.freeze(b); ++ Object.freeze(c); + let x; + if ($[0] !== a || $[1] !== b || $[2] !== c) { + x = []; + if (a) { + let y; + if ($[4] !== b || $[5] !== c) { + y = []; + if (b) { + y.push(c); + } + $[4] = b; + $[5] = c; + $[6] = y; + } else { + y = $[6]; + } + + x.push(y); + } + $[0] = a; + $[1] = b; + $[2] = c; + $[3] = x; + } else { + x = $[3]; + } + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: overlapping-scopes-while +- Expected ++ Received + + + ## Input + + ```javascript + function foo(a, b, c) { + let x = []; + let y = []; + while (c) { + y.push(b); + x.push(a); + } + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + function foo(a, b, c) { ++ Object.freeze(a); ++ Object.freeze(b); ++ Object.freeze(c); + const x = []; + const y = []; + while (c) { + y.push(b); + x.push(a); + } + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: overlapping-scopes-shadowing-within-block +- Expected ++ Received + + + ## Input + + ```javascript + function foo(a, b, c) { + let x = []; + if (a) { + let y = []; + if (b) { + y.push(c); + } + + x.push(
{y}
); + } + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function foo(a, b, c) { + const $ = _c(9); ++ Object.freeze(a); ++ Object.freeze(b); ++ Object.freeze(c); + let x; + if ($[0] !== a || $[1] !== b || $[2] !== c) { + x = []; + if (a) { + let y; + if ($[4] !== b || $[5] !== c) { + y = []; + if (b) { + y.push(c); + } + $[4] = b; + $[5] = c; + $[6] = y; + } else { + y = $[6]; + } + let t0; + if ($[7] !== y) { + t0 =
{y}
; + $[7] = y; + $[8] = t0; + } else { + t0 = $[8]; + } + x.push(t0); + } + $[0] = a; + $[1] = b; + $[2] = c; + $[3] = x; + } else { + x = $[3]; + } + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: overlapping-scopes-shadowed +- Expected ++ Received + + + ## Input + + ```javascript + function foo(a, b) { + let x = []; + let y = []; + y.push(b); + x.push(a); + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + function foo(a, b) { ++ Object.freeze(a); ++ Object.freeze(b); + const x = []; + const y = []; + y.push(b); + x.push(a); + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: overlapping-scopes-interleaved +- Expected ++ Received + + + ## Input + + ```javascript + function foo(a, b) { + let x = []; + let y = []; + x.push(a); + y.push(b); + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + function foo(a, b) { ++ Object.freeze(a); ++ Object.freeze(b); + const x = []; + const y = []; + x.push(a); + y.push(b); + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: overlapping-scopes-interleaved-by-terminal +- Expected ++ Received + + + ## Input + + ```javascript + function foo(a, b, c) { + const x = []; + const y = []; + + if (x) { + } + + y.push(a); + x.push(b); + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + function foo(a, b, c) { ++ Object.freeze(a); ++ Object.freeze(b); ++ Object.freeze(c); + const x = []; + const y = []; + if (x) { + } + + y.push(a); + x.push(b); + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: outlining-in-react-memo + >> Unexpected error during test: + + +Found differences in evaluator results +Non-forget (expected): +(kind: ok)
  • foo
  • bar
+Forget: +(kind: ok)
  • foo
  • bar
+logs: ['Warning: Encountered two children with the same key, `%s`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.%s','function () {\n' + + ' const $res$ = item.id;\n' + + ' Object.freeze($res$);\n' + + ' return $res$;\n' + + ' }','\n' + + ' at ul\n' + + ' at eval (eval at doEval (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:200:28), :34:36)\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)'] + +FAIL: outlining-in-func-expr + >> Unexpected error during test: + + +Found differences in evaluator results +Non-forget (expected): +(kind: ok)
  • foo
  • bar
+Forget: +(kind: ok)
  • foo
  • bar
+logs: ['Warning: Encountered two children with the same key, `%s`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.%s','function () {\n' + + ' const $res$ = item.id;\n' + + ' Object.freeze($res$);\n' + + ' return $res$;\n' + + ' }','\n' + + ' at ul\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)'] + +FAIL: outlined-helper + >> Unexpected error during test: + + +Found differences in evaluator results +Non-forget (expected): +(kind: ok)
{"item":"one"}
+Forget: +(kind: ok)
{"item":"[[ function params=0 ]]"}
+ +FAIL: outlined-destructured-params + >> Unexpected error during test: + + +Found differences in evaluator results +Non-forget (expected): +(kind: ok)
{"name":"one"}
+Forget: +(kind: ok)
{"name":"[[ function params=0 ]]"}
+ +FAIL: optional-receiver-optional-method +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + const x = makeOptionalObject(props); + const y = makeObject(props); + const z = x?.optionalMethod?.(y.a, props.a, foo(y.b), bar(props.b)); + return z; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(2); ++ Object.freeze(props); + let t0; + if ($[0] !== props) { + const x = makeOptionalObject(props); + const y = makeObject(props); + t0 = x?.optionalMethod?.(y.a, props.a, foo(y.b), bar(props.b)); + $[0] = props; + $[1] = t0; + } else { + t0 = $[1]; + } + const z = t0; + return z; + } + + ``` +  + +FAIL: optional-receiver-method-call +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + const x = makeOptionalObject(props); + const y = makeObject(props); + const z = x?.method(y.a, props.a, foo(y.b), bar(props.b)); + return z; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(2); ++ Object.freeze(props); + let t0; + if ($[0] !== props) { + const x = makeOptionalObject(props); + const y = makeObject(props); + t0 = x?.method(y.a, props.a, foo(y.b), bar(props.b)); + $[0] = props; + $[1] = t0; + } else { + t0 = $[1]; + } + const z = t0; + return z; + } + + ``` +  + +FAIL: optional-method-call +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + const x = makeObject(props); + const y = makeObject(props); + const z = x.optionalMethod?.(y.a, props.a, foo(y.b), bar(props.b)); + return z; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(2); ++ Object.freeze(props); + let t0; + if ($[0] !== props) { + const x = makeObject(props); + const y = makeObject(props); + t0 = x.optionalMethod?.(y.a, props.a, foo(y.b), bar(props.b)); + $[0] = props; + $[1] = t0; + } else { + t0 = $[1]; + } + const z = t0; + return z; + } + + ``` +  + +FAIL: optional-member-expression +- Expected ++ Received + + + ## Input + + ```javascript + function Foo(props) { + let x = bar(props.a); + let y = x?.b; + + let z = useBar(y); + return z; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Foo(props) { + const $ = _c(2); ++ Object.freeze(props); + let t0; + if ($[0] !== props.a) { + t0 = bar(props.a); + $[0] = props.a; + $[1] = t0; + } else { + t0 = $[1]; + } + const x = t0; + const y = x?.b; + +- const z = useBar(y); ++ const z = (function () { ++ const $res$ = useBar(Object.freeze(y)); ++ Object.freeze($res$); ++ return $res$; ++ })(); + return z; + } + + ``` +  + +FAIL: optional-member-expression-with-optional-member-expr-as-property +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + const x = makeObject(); + return x.y?.[props.a?.[props.b?.[props.c]]]; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(1); ++ Object.freeze(props); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = makeObject(); + $[0] = t0; + } else { + t0 = $[0]; + } + const x = t0; + return x.y?.[props.a?.[props.b?.[props.c]]]; + } + + ``` +  + +FAIL: optional-member-expression-chain +- Expected ++ Received + + + ## Input + + ```javascript + // Note that `a?.b.c` is semantically different from `(a?.b).c` + // We should codegen the correct member expressions + function Component(props) { + let x = props?.b.c; + let y = props?.b.c.d?.e.f.g?.h; + return {x, y}; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; // Note that `a?.b.c` is semantically different from `(a?.b).c` + // We should codegen the correct member expressions + function Component(props) { + const $ = _c(3); ++ Object.freeze(props); + const x = props?.b.c; + const y = props?.b.c.d?.e.f.g?.h; + let t0; + if ($[0] !== x || $[1] !== y) { + t0 = { x, y }; + $[0] = x; + $[1] = y; + $[2] = t0; + } else { + t0 = $[2]; + } + return t0; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: optional-member-expression-call-as-property +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + const x = makeObject(); + return x?.[foo(props.value)]; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(3); ++ Object.freeze(props); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = makeObject(); + $[0] = t0; + } else { + t0 = $[0]; + } + const x = t0; + let t1; + if ($[1] !== props) { + t1 = x?.[foo(props.value)]; + $[1] = props; + $[2] = t1; + } else { + t1 = $[2]; + } + return t1; + } + + ``` +  + +FAIL: optional-computed-member-expression +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + const object = makeObject(props); + return object?.[props.key]; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(2); ++ Object.freeze(props); + let t0; + if ($[0] !== props) { + t0 = makeObject(props); + $[0] = props; + $[1] = t0; + } else { + t0 = $[1]; + } + const object = t0; + return object?.[props.key]; + } + + ``` +  + +FAIL: optional-computed-load-static +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + let x = a?.b.c[0]; + return x; + } + + ``` + + ## Code + + ```javascript + function Component(props) { ++ Object.freeze(props); + const x = a?.b.c[0]; + return x; + } + + ``` +  + +FAIL: optional-call +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + const x = makeOptionalFunction(props); + const y = makeObject(props); + const z = x?.(y.a, props.a, foo(y.b), bar(props.b)); + return z; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(2); ++ Object.freeze(props); + let t0; + if ($[0] !== props) { + const x = makeOptionalFunction(props); + const y = makeObject(props); + t0 = x?.(y.a, props.a, foo(y.b), bar(props.b)); + $[0] = props; + $[1] = t0; + } else { + t0 = $[1]; + } + const z = t0; + return z; + } + + ``` +  + +FAIL: optional-call-with-optional-property-load +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + return props?.items?.map?.(render)?.filter(Boolean) ?? []; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(2); ++ Object.freeze(props); + let t0; + if ($[0] !== props) { + t0 = props?.items?.map?.(render)?.filter(Boolean) ?? []; + $[0] = props; + $[1] = t0; + } else { + t0 = $[1]; + } + return t0; + } + + ``` +  + +FAIL: optional-call-with-independently-memoizable-arg +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + const x = makeOptionalFunction(props); + // for a regular call, the JSX element could be independently memoized + // since it is an immutable value. however, because the call is optional, + // we can't extract out independent memoization for the element w/o + // forcing that argument to evaluate unconditionally + const y = x?.( +
 + {props.text} +
 + ); + return y; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(2); ++ Object.freeze(props); + let t0; + if ($[0] !== props) { + const x = makeOptionalFunction(props); + + t0 = x?.( +
 + {props.text} +
, + ); + $[0] = props; + $[1] = t0; + } else { + t0 = $[1]; + } + const y = t0; + return y; + } + + ``` +  + +FAIL: optional-call-simple +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + return foo?.(props); + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(2); ++ Object.freeze(props); + let t0; + if ($[0] !== props) { + t0 = foo?.(props); + $[0] = props; + $[1] = t0; + } else { + t0 = $[1]; + } + return t0; + } + + ``` +  + +FAIL: optional-call-logical +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + const item = useFragment( + graphql` + fragment F on T { + id + } + `, + props.item + ); + return item.items?.map(item => renderItem(item)) ?? []; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(2); +- const item = useFragment( +- graphql` +- fragment F on T { +- id +- } +- `, +- props.item, +- ); ++ Object.freeze(props); ++ const item = (function () { ++ const $res$ = useFragment( ++ Object.freeze(graphql` ++ fragment F on T { ++ id ++ } ++ `), ++ Object.freeze(props.item), ++ ); ++ Object.freeze($res$); ++ return $res$; ++ })(); + let t0; + if ($[0] !== item.items) { + t0 = item.items?.map(_temp) ?? []; + $[0] = item.items; + $[1] = t0; + } else { + t0 = $[1]; + } + return t0; + } + function _temp(item_0) { + return renderItem(item_0); + } + + ``` +  + +FAIL: optional-call-chained +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + return call?.(props.a)?.(props.b)?.(props.c); + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(2); ++ Object.freeze(props); + let t0; + if ($[0] !== props) { + t0 = call?.(props.a)?.(props.b)?.(props.c); + $[0] = props; + $[1] = t0; + } else { + t0 = $[1]; + } + return t0; + } + + ``` +  + +FAIL: option-enable-change-variable-codegen +- Expected ++ Received + + + ## Input + + ```javascript + // @enableChangeVariableCodegen + function Component(props) { + const c_0 = [props.a, props.b.c]; + return c_0; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{a: 3.14, b: {c: true}}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; // @enableChangeVariableCodegen + function Component(props) { + const $ = _c(3); ++ Object.freeze(props); + const c_00 = $[0] !== props.a; + const c_1 = $[1] !== props.b.c; + let t0; + if (c_00 || c_1) { + t0 = [props.a, props.b.c]; + $[0] = props.a; + $[1] = props.b.c; + $[2] = t0; + } else { + t0 = $[2]; + } + const c_0 = t0; + return c_0; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ a: 3.14, b: { c: true } }], + }; + + ``` +  + ### Eval output + (kind: ok) [3.14,true] + +FAIL: object-shorthand-method-nested +- Expected ++ Received + + + ## Input + + ```javascript + import {useState} from 'react'; + import {createHookWrapper} from 'shared-runtime'; + + function useHook({value}) { + const [state] = useState(false); + + return { + getX() { + return { + a: [], + getY() { + return value; + }, + state, + }; + }, + }; + } + + export const FIXTURE_ENTRYPOINT = { + fn: createHookWrapper(useHook), + params: [{value: 0}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { useState } from "react"; + import { createHookWrapper } from "shared-runtime"; + + function useHook(t0) { + const $ = _c(3); ++ Object.freeze(t0); + const { value } = t0; +- const [state] = useState(false); ++ const [state] = (function () { ++ const $res$ = useState(Object.freeze(false)); ++ Object.freeze($res$); ++ return $res$; ++ })(); + let t1; + if ($[0] !== value || $[1] !== state) { + t1 = { + getX() { + return { + a: [], + getY() { + return value; + }, + state, + }; + }, + }; + $[0] = value; + $[1] = state; + $[2] = t1; + } else { + t1 = $[2]; + } + return t1; + } + + export const FIXTURE_ENTRYPOINT = { + fn: createHookWrapper(useHook), + params: [{ value: 0 }], + }; + + ``` +  + ### Eval output + (kind: ok)
{"result":{"getX":{"kind":"Function","result":{"a":[],"getY":{"kind":"Function","result":0},"state":false}}},"shouldInvokeFns":true}
 + +FAIL: object-shorthand-method-2 +- Expected ++ Received + + + ## Input + + ```javascript + import {createHookWrapper} from 'shared-runtime'; + + function useHook({a, b, c}) { + return { + x: [a], + y() { + return [b]; + }, + z: {c}, + }; + } + + export const FIXTURE_ENTRYPOINT = { + fn: createHookWrapper(useHook), + params: [{a: 1, b: 2, c: 2}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { createHookWrapper } from "shared-runtime"; + + function useHook(t0) { + const $ = _c(8); ++ Object.freeze(t0); + const { a, b, c } = t0; + let t1; + if ($[0] !== a) { + t1 = [a]; + $[0] = a; + $[1] = t1; + } else { + t1 = $[1]; + } + let t2; + if ($[2] !== b || $[3] !== c || $[4] !== t1) { + let t3; + if ($[6] !== c) { + t3 = { c }; + $[6] = c; + $[7] = t3; + } else { + t3 = $[7]; + } + t2 = { + x: t1, + y() { + return [b]; + }, + z: t3, + }; + $[2] = b; + $[3] = c; + $[4] = t1; + $[5] = t2; + } else { + t2 = $[5]; + } + return t2; + } + + export const FIXTURE_ENTRYPOINT = { + fn: createHookWrapper(useHook), + params: [{ a: 1, b: 2, c: 2 }], + }; + + ``` +  + ### Eval output + (kind: ok)
{"result":{"x":[1],"y":{"kind":"Function","result":[2]},"z":{"c":2}},"shouldInvokeFns":true}
 + +FAIL: object-shorthand-method-1 +- Expected ++ Received + + + ## Input + + ```javascript + import {createHookWrapper} from 'shared-runtime'; + function useHook({a, b}) { + return { + x: function () { + return [a]; + }, + y() { + return [b]; + }, + }; + } + + export const FIXTURE_ENTRYPOINT = { + fn: createHookWrapper(useHook), + params: [{a: 1, b: 2}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { createHookWrapper } from "shared-runtime"; + function useHook(t0) { + const $ = _c(5); ++ Object.freeze(t0); + const { a, b } = t0; + let t1; + if ($[0] !== a) { + t1 = function () { + return [a]; + }; + $[0] = a; + $[1] = t1; + } else { + t1 = $[1]; + } + let t2; + if ($[2] !== b || $[3] !== t1) { + t2 = { + x: t1, + y() { + return [b]; + }, + }; + $[2] = b; + $[3] = t1; + $[4] = t2; + } else { + t2 = $[4]; + } + return t2; + } + + export const FIXTURE_ENTRYPOINT = { + fn: createHookWrapper(useHook), + params: [{ a: 1, b: 2 }], + }; + + ``` +  + ### Eval output + (kind: ok)
{"result":{"x":{"kind":"Function","result":[1]},"y":{"kind":"Function","result":[2]}},"shouldInvokeFns":true}
 + +FAIL: object-properties +- Expected ++ Received + + + ## Input + + ```javascript + function foo(a, b, c) { + const x = a.x; + const y = {...b.c.d}; + y.z = c.d.e; + foo(a.b.c); + [a.b.c]; + } + + ``` + + ## Code + + ```javascript + function foo(a, b, c) { ++ Object.freeze(a); ++ Object.freeze(b); ++ Object.freeze(c); ++ + const y = { ...b.c.d }; + y.z = c.d.e; + foo(a.b.c); + } + + ``` +  + +FAIL: object-pattern-params +- Expected ++ Received + + + ## Input + + ```javascript + function component({a, b}) { + let y = {a}; + let z = {b}; + return {y, z}; + } + + export const FIXTURE_ENTRYPOINT = { + fn: component, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function component(t0) { + const $ = _c(7); ++ Object.freeze(t0); + const { a, b } = t0; + let t1; + if ($[0] !== a) { + t1 = { a }; + $[0] = a; + $[1] = t1; + } else { + t1 = $[1]; + } + const y = t1; + let t2; + if ($[2] !== b) { + t2 = { b }; + $[2] = b; + $[3] = t2; + } else { + t2 = $[3]; + } + const z = t2; + let t3; + if ($[4] !== y || $[5] !== z) { + t3 = { y, z }; + $[4] = y; + $[5] = z; + $[6] = t3; + } else { + t3 = $[6]; + } + return t3; + } + + export const FIXTURE_ENTRYPOINT = { + fn: component, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: object-mutated-in-consequent-alternate-both-return +- Expected ++ Received + + + ## Input + + ```javascript + import {makeObject_Primitives} from 'shared-runtime'; + + function Component(props) { + const object = makeObject_Primitives(); + if (props.cond) { + object.value = 1; + return object; + } else { + object.value = props.value; + return object; + } + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{cond: false, value: [0, 1, 2]}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { makeObject_Primitives } from "shared-runtime"; + + function Component(props) { + const $ = _c(2); ++ Object.freeze(props); + let t0; + if ($[0] !== props) { + t0 = Symbol.for("react.early_return_sentinel"); + bb0: { + const object = makeObject_Primitives(); + if (props.cond) { + object.value = 1; + t0 = object; + break bb0; + } else { + object.value = props.value; + t0 = object; + break bb0; + } + } + $[0] = props; + $[1] = t0; + } else { + t0 = $[1]; + } + if (t0 !== Symbol.for("react.early_return_sentinel")) { + return t0; + } + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ cond: false, value: [0, 1, 2] }], + }; + + ``` +  + ### Eval output + (kind: ok) {"a":0,"b":"value1","c":true,"value":[0,1,2]} + +FAIL: object-method-shorthand-mutated-after +- Expected ++ Received + + + ## Input + + ```javascript + import {createHookWrapper, mutate, mutateAndReturn} from 'shared-runtime'; + function useHook({value}) { + const x = mutateAndReturn({value}); + const obj = { + getValue() { + return x; + }, + }; + mutate(obj); + return obj; + } + + export const FIXTURE_ENTRYPOINT = { + fn: createHookWrapper(useHook), + params: [{value: 0}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { createHookWrapper, mutate, mutateAndReturn } from "shared-runtime"; + function useHook(t0) { + const $ = _c(2); ++ Object.freeze(t0); + const { value } = t0; + let obj; + if ($[0] !== value) { + const x = mutateAndReturn({ value }); + obj = { + getValue() { + return x; + }, + }; + + mutate(obj); + $[0] = value; + $[1] = obj; + } else { + obj = $[1]; + } + return obj; + } + + export const FIXTURE_ENTRYPOINT = { + fn: createHookWrapper(useHook), + params: [{ value: 0 }], + }; + + ``` +  + ### Eval output + (kind: ok)
{"result":{"getValue":{"kind":"Function","result":{"value":0,"wat0":"joe"}},"wat0":"joe"},"shouldInvokeFns":true}
 + +FAIL: object-method-shorthand-hook-dep +- Expected ++ Received + + + ## Input + + ```javascript + import {createHookWrapper} from 'shared-runtime'; + import {useState} from 'react'; + function useFoo() { + const [state, _setState] = useState(false); + return { + func() { + return state; + }, + }; + } + + export const FIXTURE_ENTRYPOINT = { + fn: createHookWrapper(useFoo), + params: [{}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { createHookWrapper } from "shared-runtime"; + import { useState } from "react"; + function useFoo() { + const $ = _c(2); +- const [state] = useState(false); ++ const [state] = (function () { ++ const $res$ = useState(Object.freeze(false)); ++ Object.freeze($res$); ++ return $res$; ++ })(); + let t0; + if ($[0] !== state) { + t0 = { + func() { + return state; + }, + }; + $[0] = state; + $[1] = t0; + } else { + t0 = $[1]; + } + return t0; + } + + export const FIXTURE_ENTRYPOINT = { + fn: createHookWrapper(useFoo), + params: [{}], + }; + + ``` +  + ### Eval output + (kind: ok)
{"result":{"func":{"kind":"Function","result":false}},"shouldInvokeFns":true}
 + +FAIL: object-method-shorthand-derived-value +- Expected ++ Received + + + ## Input + + ```javascript + import {createHookWrapper, mutateAndReturn} from 'shared-runtime'; + function useHook({value}) { + const x = mutateAndReturn({value}); + const obj = { + getValue() { + return x; + }, + }; + return obj; + } + + export const FIXTURE_ENTRYPOINT = { + fn: createHookWrapper(useHook), + params: [{value: 0}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { createHookWrapper, mutateAndReturn } from "shared-runtime"; + function useHook(t0) { + const $ = _c(4); ++ Object.freeze(t0); + const { value } = t0; + let t1; + if ($[0] !== value) { + t1 = mutateAndReturn({ value }); + $[0] = value; + $[1] = t1; + } else { + t1 = $[1]; + } + const x = t1; + let t2; + if ($[2] !== x) { + t2 = { + getValue() { + return x; + }, + }; + $[2] = x; + $[3] = t2; + } else { + t2 = $[3]; + } + const obj = t2; + return obj; + } + + export const FIXTURE_ENTRYPOINT = { + fn: createHookWrapper(useHook), + params: [{ value: 0 }], + }; + + ``` +  + ### Eval output + (kind: ok)
{"result":{"getValue":{"kind":"Function","result":{"value":0,"wat0":"joe"}}},"shouldInvokeFns":true}
 + +FAIL: object-method-shorthand-aliased-mutate-after +- Expected ++ Received + + + ## Input + + ```javascript + import {createHookWrapper, mutate, mutateAndReturn} from 'shared-runtime'; + function useHook({value}) { + const x = mutateAndReturn({value}); + const obj = { + getValue() { + return value; + }, + }; + mutate(x); + return obj; + } + + export const FIXTURE_ENTRYPOINT = { + fn: createHookWrapper(useHook), + params: [{value: 0}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { createHookWrapper, mutate, mutateAndReturn } from "shared-runtime"; + function useHook(t0) { + const $ = _c(2); ++ Object.freeze(t0); + const { value } = t0; + let obj; + if ($[0] !== value) { + const x = mutateAndReturn({ value }); + obj = { + getValue() { + return value; + }, + }; + + mutate(x); + $[0] = value; + $[1] = obj; + } else { + obj = $[1]; + } + return obj; + } + + export const FIXTURE_ENTRYPOINT = { + fn: createHookWrapper(useHook), + params: [{ value: 0 }], + }; + + ``` +  + ### Eval output + (kind: ok)
{"result":{"getValue":{"kind":"Function","result":0}},"shouldInvokeFns":true}
 + +FAIL: object-method-shorthand-3 +- Expected ++ Received + + + ## Input + + ```javascript + import {createHookWrapper, mutate} from 'shared-runtime'; + + function useHook(a) { + const x = {a}; + let obj = { + method() { + mutate(x); + return x; + }, + }; + return obj.method(); + } + + export const FIXTURE_ENTRYPOINT = { + fn: createHookWrapper(useHook), + params: [{x: 1}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { createHookWrapper, mutate } from "shared-runtime"; + + function useHook(a) { + const $ = _c(2); ++ Object.freeze(a); + let t0; + if ($[0] !== a) { + const x = { a }; + const obj = { + method() { + mutate(x); + return x; + }, + }; + + t0 = obj.method(); + $[0] = a; + $[1] = t0; + } else { + t0 = $[1]; + } + return t0; + } + + export const FIXTURE_ENTRYPOINT = { + fn: createHookWrapper(useHook), + params: [{ x: 1 }], + }; + + ``` +  + ### Eval output + (kind: ok)
{"result":{"a":{"x":1},"wat0":"joe"},"shouldInvokeFns":true}
 + +FAIL: object-method-maybe-alias +- Expected ++ Received + + + ## Input + + ```javascript + import {createHookWrapper, setProperty} from 'shared-runtime'; + function useHook(props) { + const x = { + getX() { + return props; + }, + }; + const y = { + getY() { + return 'y'; + }, + }; + return setProperty(x, y); + } + + export const FIXTURE_ENTRYPOINT = { + fn: createHookWrapper(useHook), + params: [{value: 0}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { createHookWrapper, setProperty } from "shared-runtime"; + function useHook(props) { + const $ = _c(2); ++ Object.freeze(props); + let t0; + if ($[0] !== props) { + const x = { + getX() { + return props; + }, + }; + + const y = { + getY() { + return "y"; + }, + }; + + t0 = setProperty(x, y); + $[0] = props; + $[1] = t0; + } else { + t0 = $[1]; + } + return t0; + } + + export const FIXTURE_ENTRYPOINT = { + fn: createHookWrapper(useHook), + params: [{ value: 0 }], + }; + + ``` +  + ### Eval output + (kind: ok)
{"result":{"getX":{"kind":"Function","result":{"value":0}},"wat0":{"getY":{"kind":"Function","result":"y"}}},"shouldInvokeFns":true}
 + +FAIL: object-literal-spread-element +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + const x = {...props.foo}; + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(2); ++ Object.freeze(props); + let t0; + if ($[0] !== props.foo) { + t0 = { ...props.foo }; + $[0] = props.foo; + $[1] = t0; + } else { + t0 = $[1]; + } + const x = t0; + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: object-literal-method-in-ternary-test +- Expected ++ Received + + + ## Input + + ```javascript + import {createHookWrapper, CONST_STRING0, CONST_STRING1} from 'shared-runtime'; + + function useHook({value}) { + return { + getValue() { + return identity(value); + }, + } + ? CONST_STRING0 + : CONST_STRING1; + } + + export const FIXTURE_ENTRYPOINT = { + fn: createHookWrapper(useHook), + params: [{value: 0}], + }; + + ``` + + ## Code + + ```javascript + import { + createHookWrapper, + CONST_STRING0, + CONST_STRING1, + } from "shared-runtime"; + + function useHook(t0) { ++ Object.freeze(t0); + const { value } = t0; + return { + getValue() { + return identity(value); + }, + } + ? CONST_STRING0 + : CONST_STRING1; + } + + export const FIXTURE_ENTRYPOINT = { + fn: createHookWrapper(useHook), + params: [{ value: 0 }], + }; + + ``` +  + ### Eval output + (kind: ok)
{"result":"global string 0","shouldInvokeFns":true}
 + +FAIL: object-literal-method-in-ternary-consequent +- Expected ++ Received + + + ## Input + + ```javascript + import {createHookWrapper} from 'shared-runtime'; + + function useHook({isCond, value}) { + return isCond + ? { + getValue() { + return value; + }, + } + : 42; + } + + export const FIXTURE_ENTRYPOINT = { + fn: createHookWrapper(useHook), + params: [{isCond: true, value: 0}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { createHookWrapper } from "shared-runtime"; + + function useHook(t0) { + const $ = _c(3); ++ Object.freeze(t0); + const { isCond, value } = t0; + let t1; + if ($[0] !== isCond || $[1] !== value) { + t1 = isCond + ? { + getValue() { + return value; + }, + } + : 42; + $[0] = isCond; + $[1] = value; + $[2] = t1; + } else { + t1 = $[2]; + } + return t1; + } + + export const FIXTURE_ENTRYPOINT = { + fn: createHookWrapper(useHook), + params: [{ isCond: true, value: 0 }], + }; + + ``` +  + ### Eval output + (kind: ok)
{"result":{"getValue":{"kind":"Function","result":0}},"shouldInvokeFns":true}
 + +FAIL: object-literal-method-derived-in-ternary-consequent +- Expected ++ Received + + + ## Input + + ```javascript + import {identity, createHookWrapper} from 'shared-runtime'; + + function useHook({isCond, value}) { + return isCond + ? identity({ + getValue() { + return value; + }, + }) + : 42; + } + + export const FIXTURE_ENTRYPOINT = { + fn: createHookWrapper(useHook), + params: [{isCond: true, value: 0}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { identity, createHookWrapper } from "shared-runtime"; + + function useHook(t0) { + const $ = _c(3); ++ Object.freeze(t0); + const { isCond, value } = t0; + let t1; + if ($[0] !== isCond || $[1] !== value) { + t1 = isCond + ? identity({ + getValue() { + return value; + }, + }) + : 42; + $[0] = isCond; + $[1] = value; + $[2] = t1; + } else { + t1 = $[2]; + } + return t1; + } + + export const FIXTURE_ENTRYPOINT = { + fn: createHookWrapper(useHook), + params: [{ isCond: true, value: 0 }], + }; + + ``` +  + ### Eval output + (kind: ok)
{"result":{"getValue":{"kind":"Function","result":0}},"shouldInvokeFns":true}
 + +FAIL: object-literal-method-call-in-ternary-test +- Expected ++ Received + + + ## Input + + ```javascript + import { + createHookWrapper, + identity, + CONST_STRING0, + CONST_STRING1, + } from 'shared-runtime'; + + function useHook({value}) { + return { + getValue() { + return identity(value); + }, + }.getValue() + ? CONST_STRING0 + : CONST_STRING1; + } + + export const FIXTURE_ENTRYPOINT = { + fn: createHookWrapper(useHook), + params: [{value: 0}], + }; + + ``` + + ## Code + + ```javascript + import { + createHookWrapper, + identity, + CONST_STRING0, + CONST_STRING1, + } from "shared-runtime"; + + function useHook(t0) { ++ Object.freeze(t0); + const { value } = t0; + return { + getValue() { + return identity(value); + }, + }.getValue() + ? CONST_STRING0 + : CONST_STRING1; + } + + export const FIXTURE_ENTRYPOINT = { + fn: createHookWrapper(useHook), + params: [{ value: 0 }], + }; + + ``` +  + ### Eval output + (kind: ok)
{"result":"global string 1","shouldInvokeFns":true}
 + +FAIL: object-expression-string-literal-key +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + const x = {['foo']: props.foo}; + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(2); ++ Object.freeze(props); + let t0; + if ($[0] !== props.foo) { + t0 = { foo: props.foo }; + $[0] = props.foo; + $[1] = t0; + } else { + t0 = $[1]; + } + const x = t0; + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: object-expression-computed-key +- Expected ++ Received + + + ## Input + + ```javascript + import {identity} from 'shared-runtime'; + + const SCALE = 2; + + function Component(props) { + const {key} = props; + const context = { + [key]: identity([props.value, SCALE]), + }; + return context; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{key: 'Sathya', value: 'Compiler'}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { identity } from "shared-runtime"; + + const SCALE = 2; + + function Component(props) { + const $ = _c(5); ++ Object.freeze(props); + const { key } = props; + let t0; + if ($[0] !== props.value) { + t0 = identity([props.value, SCALE]); + $[0] = props.value; + $[1] = t0; + } else { + t0 = $[1]; + } + let t1; + if ($[2] !== key || $[3] !== t0) { + t1 = { [key]: t0 }; + $[2] = key; + $[3] = t0; + $[4] = t1; + } else { + t1 = $[4]; + } + const context = t1; + return context; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ key: "Sathya", value: "Compiler" }], + }; + + ``` +  + ### Eval output + (kind: ok) {"Sathya":["Compiler",2]} + +FAIL: object-expression-computed-key-object-mutated-later +- Expected ++ Received + + + ## Input + + ```javascript + import {identity, mutate} from 'shared-runtime'; + + function Component(props) { + const key = {}; + const context = { + [key]: identity([props.value]), + }; + mutate(key); + return context; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{value: 42}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { identity, mutate } from "shared-runtime"; + + function Component(props) { + const $ = _c(5); ++ Object.freeze(props); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = {}; + $[0] = t0; + } else { + t0 = $[0]; + } + const key = t0; + let t1; + if ($[1] !== props.value) { + t1 = identity([props.value]); + $[1] = props.value; + $[2] = t1; + } else { + t1 = $[2]; + } + let t2; + if ($[3] !== t1) { + t2 = { [key]: t1 }; + $[3] = t1; + $[4] = t2; + } else { + t2 = $[4]; + } + const context = t2; + + mutate(key); + return context; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ value: 42 }], + }; + + ``` +  + ### Eval output + (kind: ok) {"[object Object]":[42]} + +FAIL: object-expression-computed-key-non-reactive +- Expected ++ Received + + + ## Input + + ```javascript + import {identity} from 'shared-runtime'; + + const SCALE = 2; + + function Component(props) { + const key = SCALE; + const context = { + [key]: identity([props.value]), + }; + return context; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{key: 'Sathya', value: 'Compiler'}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { identity } from "shared-runtime"; + + const SCALE = 2; + + function Component(props) { + const $ = _c(4); ++ Object.freeze(props); + let t0; + if ($[0] !== props.value) { + t0 = identity([props.value]); + $[0] = props.value; + $[1] = t0; + } else { + t0 = $[1]; + } + let t1; + if ($[2] !== t0) { + t1 = { [SCALE]: t0 }; + $[2] = t0; + $[3] = t1; + } else { + t1 = $[3]; + } + const context = t1; + return context; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ key: "Sathya", value: "Compiler" }], + }; + + ``` +  + ### Eval output + (kind: ok) {"2":["Compiler"]} + +FAIL: object-expression-computed-key-constant-string +- Expected ++ Received + + + ## Input + + ```javascript + import {identity} from 'shared-runtime'; + + function Component(props) { + const key = 'KeyName'; + const context = { + [key]: identity([props.value]), + }; + return context; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{value: 42}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { identity } from "shared-runtime"; + + function Component(props) { + const $ = _c(4); ++ Object.freeze(props); + let t0; + if ($[0] !== props.value) { + t0 = identity([props.value]); + $[0] = props.value; + $[1] = t0; + } else { + t0 = $[1]; + } + let t1; + if ($[2] !== t0) { + t1 = { ["KeyName"]: t0 }; + $[2] = t0; + $[3] = t1; + } else { + t1 = $[3]; + } + const context = t1; + return context; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ value: 42 }], + }; + + ``` +  + ### Eval output + (kind: ok) {"KeyName":[42]} + +FAIL: object-expression-computed-key-constant-number +- Expected ++ Received + + + ## Input + + ```javascript + import {identity} from 'shared-runtime'; + + function Component(props) { + const key = 42; + const context = { + [key]: identity([props.value]), + }; + return context; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{value: 'hello!'}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { identity } from "shared-runtime"; + + function Component(props) { + const $ = _c(4); ++ Object.freeze(props); + let t0; + if ($[0] !== props.value) { + t0 = identity([props.value]); + $[0] = props.value; + $[1] = t0; + } else { + t0 = $[1]; + } + let t1; + if ($[2] !== t0) { + t1 = { [42]: t0 }; + $[2] = t0; + $[3] = t1; + } else { + t1 = $[3]; + } + const context = t1; + return context; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ value: "hello!" }], + }; + + ``` +  + ### Eval output + (kind: ok) {"42":["hello!"]} + +FAIL: object-computed-access-assignment +- Expected ++ Received + + + ## Input + + ```javascript + function foo(a, b, c) { + const x = {...a}; + x[b] = c[b]; + x[1 + 2] = c[b * 4]; + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + function foo(a, b, c) { ++ Object.freeze(a); ++ Object.freeze(b); ++ Object.freeze(c); + const x = { ...a }; + x[b] = c[b]; + x[3] = c[b * 4]; + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: obj-mutated-after-nested-if-else-with-alias +- Expected ++ Received + + + ## Input + + ```javascript + function foo(a, b, c, d) { + let x = someObj(); + if (a) { + let z; + if (b) { + const w = someObj(); + z = w; + } else { + z = someObj(); + } + const y = z; + x = z; + } else { + x = someObj(); + } + + x.f = 1; + return x; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function foo(a, b, c, d) { + const $ = _c(3); ++ Object.freeze(a); ++ Object.freeze(b); ++ Object.freeze(c); ++ Object.freeze(d); + someObj(); + let x; + if ($[0] !== a || $[1] !== b) { + if (a) { + let z; + if (b) { + const w = someObj(); + z = w; + } else { + z = someObj(); + } + + x = z; + } else { + x = someObj(); + } + + x.f = 1; + $[0] = a; + $[1] = b; + $[2] = x; + } else { + x = $[2]; + } + return x; + } + + ``` +  + +FAIL: obj-mutated-after-if-else +- Expected ++ Received + + + ## Input + + ```javascript + function foo(a, b, c, d) { + let x = someObj(); + if (a) { + x = someObj(); + } else { + x = someObj(); + } + + x.f = 1; + return x; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function foo(a, b, c, d) { + const $ = _c(2); ++ Object.freeze(a); ++ Object.freeze(b); ++ Object.freeze(c); ++ Object.freeze(d); + someObj(); + let x; + if ($[0] !== a) { + if (a) { + x = someObj(); + } else { + x = someObj(); + } + + x.f = 1; + $[0] = a; + $[1] = x; + } else { + x = $[1]; + } + return x; + } + + ``` +  + +FAIL: obj-mutated-after-if-else-with-alias +- Expected ++ Received + + + ## Input + + ```javascript + function foo(a, b, c, d) { + let x = someObj(); + if (a) { + const y = someObj(); + const z = y; + x = z; + } else { + x = someObj(); + } + + x.f = 1; + return x; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function foo(a, b, c, d) { + const $ = _c(2); ++ Object.freeze(a); ++ Object.freeze(b); ++ Object.freeze(c); ++ Object.freeze(d); + someObj(); + let x; + if ($[0] !== a) { + if (a) { + const y = someObj(); + const z = y; + x = z; + } else { + x = someObj(); + } + + x.f = 1; + $[0] = a; + $[1] = x; + } else { + x = $[1]; + } + return x; + } + + ``` +  + +FAIL: obj-literal-mutated-after-if-else +- Expected ++ Received + + + ## Input + + ```javascript + function foo(a, b, c, d) { + let x = {}; + if (someVal) { + x = {b}; + } else { + x = {c}; + } + + x.f = 1; + return x; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function foo(a, b, c, d) { + const $ = _c(3); ++ Object.freeze(a); ++ Object.freeze(b); ++ Object.freeze(c); ++ Object.freeze(d); + let x; + if ($[0] !== b || $[1] !== c) { + if (someVal) { + x = { b }; + } else { + x = { c }; + } + + x.f = 1; + $[0] = b; + $[1] = c; + $[2] = x; + } else { + x = $[2]; + } + return x; + } + + ``` +  + +FAIL: obj-literal-cached-in-if-else +- Expected ++ Received + + + ## Input + + ```javascript + function foo(a, b, c, d) { + let x = {}; + if (someVal) { + x = {b}; + } else { + x = {c}; + } + + return x; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function foo(a, b, c, d) { + const $ = _c(4); ++ Object.freeze(a); ++ Object.freeze(b); ++ Object.freeze(c); ++ Object.freeze(d); + let x; + if (someVal) { + let t0; + if ($[0] !== b) { + t0 = { b }; + $[0] = b; + $[1] = t0; + } else { + t0 = $[1]; + } + x = t0; + } else { + let t0; + if ($[2] !== c) { + t0 = { c }; + $[2] = c; + $[3] = t0; + } else { + t0 = $[3]; + } + x = t0; + } + return x; + } + + ``` +  + +FAIL: nonreactive-noescaping-dependency-can-inline-into-consuming-scope +- Expected ++ Received + + + ## Input + + ```javascript + // @flow + function Component() { + return ( +
 + ); + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component() { + const $ = _c(1); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = ( +  + ); + $[0] = t0; + } else { + t0 = $[0]; + } + return t0; + } + + ``` +  + ### Eval output + (kind: exception) Fixture not implemented + +FAIL: nonoptional-load-from-optional-memberexpr +- Expected ++ Received + + + ## Input + + ```javascript + // Note that `a?.b.c` is semantically different from `(a?.b).c` + // Here, 'props?.a` is an optional chain, and `.b` is an unconditional load + // (nullthrows if a is nullish) + + function Component(props) { + let x = (props?.a).b; + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + // Note that `a?.b.c` is semantically different from `(a?.b).c` + // Here, 'props?.a` is an optional chain, and `.b` is an unconditional load + // (nullthrows if a is nullish) + + function Component(props) { ++ Object.freeze(props); + const x = (props?.a).b; + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: nonmutating-capture-in-unsplittable-memo-block +- Expected ++ Received + + + ## Input + + ```javascript + import {identity, mutate} from 'shared-runtime'; + + /** + * Currently, InferReactiveScopeVariables do not ensure that maybe-aliased + * values get assigned the same reactive scope. This is safe only when an + * already-constructed value is captured, e.g. + * ```js + * const x = makeObj(); ⌝ mutable range of x + * mutate(x); ⌟ + * <-- after this point, we can produce a canonical version + * of x for all following aliases + * const y = []; + * y.push(x); <-- y captures x + * ``` + * + * However, if a value is captured/aliased during its mutable range and the + * capturing container is separately memoized, it becomes difficult to guarantee + * that all aliases refer to the same value. + * + */ + function useFoo({a, b}) { + const x = {a}; + const y = {}; + mutate(x); + const z = [identity(y), b]; + mutate(y); + + if (z[0] !== y) { + throw new Error('oh no!'); + } + return z; + } + + export const FIXTURE_ENTRYPOINT = { + fn: useFoo, + params: [{a: 2, b: 3}], + sequentialRenders: [ + {a: 2, b: 3}, + {a: 4, b: 3}, + ], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { identity, mutate } from "shared-runtime"; + + /** + * Currently, InferReactiveScopeVariables do not ensure that maybe-aliased + * values get assigned the same reactive scope. This is safe only when an + * already-constructed value is captured, e.g. + * ```js + * const x = makeObj(); ⌝ mutable range of x + * mutate(x); ⌟ + * <-- after this point, we can produce a canonical version + * of x for all following aliases + * const y = []; + * y.push(x); <-- y captures x + * ``` + * + * However, if a value is captured/aliased during its mutable range and the + * capturing container is separately memoized, it becomes difficult to guarantee + * that all aliases refer to the same value. + * + */ + function useFoo(t0) { + const $ = _c(4); ++ Object.freeze(t0); + const { a, b } = t0; + let z; + let y; + if ($[0] !== a || $[1] !== b) { + const x = { a }; + y = {}; + mutate(x); + z = [identity(y), b]; + mutate(y); + $[0] = a; + $[1] = b; + $[2] = z; + $[3] = y; + } else { + z = $[2]; + y = $[3]; + } + if (z[0] !== y) { + throw new Error("oh no!"); + } + return z; + } + + export const FIXTURE_ENTRYPOINT = { + fn: useFoo, + params: [{ a: 2, b: 3 }], + sequentialRenders: [ + { a: 2, b: 3 }, + { a: 4, b: 3 }, + ], + }; + + ``` +  + ### Eval output + (kind: ok) [{"wat0":"joe"},3] + [{"wat0":"joe"},3] + +FAIL: non-null-assertion +- Expected ++ Received + + + ## Input + + ```javascript + interface ComponentProps { + name?: string; + } + + function Component(props: ComponentProps) { + return props.name!.toUpperCase(); + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{name: 'Alice'}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + interface ComponentProps { + name?: string; + } + + function Component(props) { + const $ = _c(2); ++ Object.freeze(props); + let t0; + if ($[0] !== props.name) { + t0 = props.name.toUpperCase(); + $[0] = props.name; + $[1] = t0; + } else { + t0 = $[1]; + } + return t0; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ name: "Alice" }], + }; + + ``` +  + ### Eval output + (kind: ok) "ALICE" + +FAIL: noAlias-filter-on-array-prop +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + const filtered = props.items.filter(item => item != null); + return filtered; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [ + { + items: [{a: true}, null, true, false, null, 'string', 3.14, null, [null]], + }, + ], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(2); ++ Object.freeze(props); + let t0; + if ($[0] !== props.items) { + t0 = props.items.filter(_temp); + $[0] = props.items; + $[1] = t0; + } else { + t0 = $[1]; + } + const filtered = t0; + return filtered; + } + function _temp(item) { + return item != null; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [ + { + items: [ + { a: true }, + null, + true, + false, + null, + "string", + 3.14, + null, + [null], + ], + }, + ], + }; + + ``` +  + ### Eval output + (kind: ok) [{"a":true},true,false,"string",3.14,[null]] + +FAIL: no-flow-bailout-unrelated +- Expected ++ Received + + + ## Input + + ```javascript + // @enableFlowSuppressions + + function useX() {} + + function Foo(props) { + // $FlowFixMe[incompatible-type] + useX(); + return null; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Foo, + params: [{}], + }; + + ``` + + ## Code + + ```javascript + // @enableFlowSuppressions + + function useX() {} + + function Foo(props) { +- useX(); ++ Object.freeze(props); ++ (function () { ++ const $res$ = useX(); ++ Object.freeze($res$); ++ return $res$; ++ })(); + return null; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Foo, + params: [{}], + }; + + ``` +  + ### Eval output + (kind: ok) null + +FAIL: new-spread +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + const x = new Foo(...props.foo, null, ...[props.bar]); + return x; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(3); ++ Object.freeze(props); + let t0; + if ($[0] !== props.bar || $[1] !== props.foo) { + t0 = new Foo(...props.foo, null, ...[props.bar]); + $[0] = props.bar; + $[1] = props.foo; + $[2] = t0; + } else { + t0 = $[2]; + } + const x = t0; + return x; + } + + ``` +  + +FAIL: new-does-not-mutate-class +- Expected ++ Received + + + ## Input + + ```javascript + import {identity} from 'shared-runtime'; + + class Foo {} + function Component({val}) { + const MyClass = identity(Foo); + const x = [val]; + const y = new MyClass(); + + return [x, y]; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{val: 0}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { identity } from "shared-runtime"; + + class Foo {} + function Component(t0) { + const $ = _c(6); ++ Object.freeze(t0); + const { val } = t0; + let t1; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t1 = identity(Foo); + $[0] = t1; + } else { + t1 = $[0]; + } + const MyClass = t1; + let t2; + if ($[1] !== val) { + t2 = [val]; + $[1] = val; + $[2] = t2; + } else { + t2 = $[2]; + } + const x = t2; + let t3; + if ($[3] === Symbol.for("react.memo_cache_sentinel")) { + t3 = new MyClass(); + $[3] = t3; + } else { + t3 = $[3]; + } + const y = t3; + let t4; + if ($[4] !== x) { + t4 = [x, y]; + $[4] = x; + $[5] = t4; + } else { + t4 = $[5]; + } + return t4; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ val: 0 }], + }; + + ``` +  + ### Eval output + (kind: ok) [[0],{}] + +FAIL: nested-scopes-hook-call +- Expected ++ Received + + + ## Input + + ```javascript + function component(props) { + let x = []; + let y = []; + y.push(useHook(props.foo)); + x.push(y); + return x; + } + + ``` + + ## Code + + ```javascript + function component(props) { ++ Object.freeze(props); + const x = []; + const y = []; +- y.push(useHook(props.foo)); ++ y.push( ++ (function () { ++ const $res$ = useHook(Object.freeze(props.foo)); ++ Object.freeze($res$); ++ return $res$; ++ })(), ++ ); + x.push(y); + return x; + } + + ``` +  + +FAIL: nested-scopes-begin-same-instr-valueblock +- Expected ++ Received + + + ## Input + + ```javascript + import {identity, mutate} from 'shared-runtime'; + + function Foo({cond}) { + const x = identity(identity(cond)) ? {a: 2} : {b: 2}; + + mutate(x); + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Foo, + params: [{cond: false}], + sequentialRenders: [{cond: false}, {cond: false}, {cond: true}, {cond: true}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { identity, mutate } from "shared-runtime"; + + function Foo(t0) { + const $ = _c(2); ++ Object.freeze(t0); + const { cond } = t0; + let x; + if ($[0] !== cond) { + x = identity(identity(cond)) ? { a: 2 } : { b: 2 }; + + mutate(x); + $[0] = cond; + $[1] = x; + } else { + x = $[1]; + } + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Foo, + params: [{ cond: false }], + sequentialRenders: [ + { cond: false }, + { cond: false }, + { cond: true }, + { cond: true }, + ], + }; + + ``` +  + ### Eval output + (kind: ok) {"b":2,"wat0":"joe"} + {"b":2,"wat0":"joe"} + {"a":2,"wat0":"joe"} + {"a":2,"wat0":"joe"} + +FAIL: nested-optional-member-expr +- Expected ++ Received + + + ## Input + + ```javascript + // We should codegen nested optional properties correctly + // (i.e. placing `?` in the correct PropertyLoad) + function Component(props) { + let x = foo(props.a?.b.c.d); + return x; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; // We should codegen nested optional properties correctly + // (i.e. placing `?` in the correct PropertyLoad) + function Component(props) { + const $ = _c(2); ++ Object.freeze(props); + const t0 = props.a?.b.c.d; + let t1; + if ($[0] !== t0) { + t1 = foo(t0); + $[0] = t0; + $[1] = t1; + } else { + t1 = $[1]; + } + const x = t1; + return x; + } + + ``` +  + +FAIL: nested-function-shadowed-identifiers +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + const [x, setX] = useState(null); + + const onChange = e => { + let x = null; // intentionally shadow the original x + setX(currentX => currentX + x); // intentionally refer to shadowed x + }; + + return ; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(3); +- const [x, setX] = useState(null); ++ Object.freeze(props); ++ const [x, setX] = (function () { ++ const $res$ = useState(Object.freeze(null)); ++ Object.freeze($res$); ++ return $res$; ++ })(); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = (e) => { + setX((currentX) => currentX + null); + }; + $[0] = t0; + } else { + t0 = $[0]; + } + const onChange = t0; + let t1; + if ($[1] !== x) { +- t1 = ; ++ t1 = ( ++  ++ ); + $[1] = x; + $[2] = t1; + } else { + t1 = $[2]; + } + return t1; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: mutation-within-jsx + >> Unexpected error during test: + + +Found differences in evaluator results +Non-forget (expected): +(kind: ok)
{"value":{"a":0,"b":"value1","c":true,"wat0":"joe"}}
+
{"value":{"a":0,"b":"value1","c":true,"wat0":"joe"}}
+Forget: +(kind: ok)
{"value":"[[ function params=0 ]]"}
+
{"value":"[[ function params=0 ]]"}
+ +FAIL: mutation-within-jsx-and-break + >> Unexpected error during test: + + +Found differences in evaluator results +Non-forget (expected): +(kind: ok)
{"value":{"a":0,"b":"value1","c":true,"wat0":"joe"}}
+
{"value":{"a":0,"b":"value1","c":true,"wat0":"joe"}}
+Forget: +(kind: ok)
{"value":"[[ function params=0 ]]"}
+
{"value":"[[ function params=0 ]]"}
+ +FAIL: mutation-within-capture-and-mutablerange +- Expected ++ Received + + + ## Input + + ```javascript + import {mutate} from 'shared-runtime'; + + /** + * This test fixture is similar to mutation-within-jsx. The only difference + * is that there is no `freeze` effect here, which means that `z` may be + * mutated after its memo block through mutating `y`. + * + * While this is technically correct (as `z` is a nested memo block), it + * is an edge case as we believe that values are not mutated after their + * memo blocks (which may lead to 'tearing', i.e. mutating one render's + * values in a subsequent render. + */ + function useFoo({a, b}) { + // x and y's scopes start here + const x = {a}; + const y = [b]; + mutate(x); + // z captures the result of `mutate(y)`, which may be aliased to `y`. + const z = [mutate(y)]; + // the following line may also mutate z + mutate(y); + // and end here + return z; + } + + export const FIXTURE_ENTRYPOINT = { + fn: useFoo, + params: [{a: 2, b: 3}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { mutate } from "shared-runtime"; + + /** + * This test fixture is similar to mutation-within-jsx. The only difference + * is that there is no `freeze` effect here, which means that `z` may be + * mutated after its memo block through mutating `y`. + * + * While this is technically correct (as `z` is a nested memo block), it + * is an edge case as we believe that values are not mutated after their + * memo blocks (which may lead to 'tearing', i.e. mutating one render's + * values in a subsequent render. + */ + function useFoo(t0) { + const $ = _c(3); ++ Object.freeze(t0); + const { a, b } = t0; + let z; + if ($[0] !== a || $[1] !== b) { + const x = { a }; + const y = [b]; + mutate(x); + + z = [mutate(y)]; + + mutate(y); + $[0] = a; + $[1] = b; + $[2] = z; + } else { + z = $[2]; + } + return z; + } + + export const FIXTURE_ENTRYPOINT = { + fn: useFoo, + params: [{ a: 2, b: 3 }], + }; + + ``` +  + ### Eval output + (kind: ok) [null] + +FAIL: mutation-during-jsx-construction +- Expected ++ Received + + + ## Input + + ```javascript + import {identity, mutate, mutateAndReturnNewValue} from 'shared-runtime'; + + function Component(props) { + const key = {}; + // Key is modified by the function, but key itself is not frozen + const element =
{props.value}
; + // Key is later mutated here: this mutation must be grouped with the + // jsx construction above + mutate(key); + return element; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{value: 42}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { identity, mutate, mutateAndReturnNewValue } from "shared-runtime"; + + function Component(props) { + const $ = _c(2); ++ Object.freeze(props); + let element; + if ($[0] !== props.value) { + const key = {}; + +- element =
{props.value}
; ++ element = ( ++  ++ {props.value} ++
 ++ ); + + mutate(key); + $[0] = props.value; + $[1] = element; + } else { + element = $[1]; + } + return element; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ value: 42 }], + }; + + ``` +  + ### Eval output + (kind: ok)
42
 + +FAIL: mutate-outer-scope-within-value-block +- Expected ++ Received + + + ## Input + + ```javascript + import {CONST_TRUE, identity, shallowCopy} from 'shared-runtime'; + + /** + * There are three values with their own scopes in this fixture. + * - arr, whose mutable range extends to the `mutate(...)` call + * - cond, which has a mutable range of exactly 1 (e.g. created but not + * mutated) + * - { val: CONST_TRUE }, which is also not mutated after creation. However, + * its scope range becomes extended to the value block. + * + * After AlignScopesToBlockScopes, our scopes look roughly like this + * ```js + * [1] arr = shallowCopy() ⌝@0 + * [2] cond = identity() <- @1 | + * [3] $0 = Ternary test=cond ⌝@2 | + * [4] {val : CONST_TRUE} | | + * [5] mutate(arr) | | + * [6] return $0 ⌟ ⌟ + * ``` + * + * Observe that instruction 5 mutates scope 0, which means that scopes 0 and 2 + * should be merged. + */ + function useFoo({input}) { + const arr = shallowCopy(input); + + const cond = identity(false); + return cond ? {val: CONST_TRUE} : mutate(arr); + } + + export const FIXTURE_ENTRYPOINT = { + fn: useFoo, + params: [{input: 3}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { CONST_TRUE, identity, shallowCopy } from "shared-runtime"; + + /** + * There are three values with their own scopes in this fixture. + * - arr, whose mutable range extends to the `mutate(...)` call + * - cond, which has a mutable range of exactly 1 (e.g. created but not + * mutated) + * - { val: CONST_TRUE }, which is also not mutated after creation. However, + * its scope range becomes extended to the value block. + * + * After AlignScopesToBlockScopes, our scopes look roughly like this + * ```js + * [1] arr = shallowCopy() ⌝@0 + * [2] cond = identity() <- @1 | + * [3] $0 = Ternary test=cond ⌝@2 | + * [4] {val : CONST_TRUE} | | + * [5] mutate(arr) | | + * [6] return $0 ⌟ ⌟ + * ``` + * + * Observe that instruction 5 mutates scope 0, which means that scopes 0 and 2 + * should be merged. + */ + function useFoo(t0) { + const $ = _c(2); ++ Object.freeze(t0); + const { input } = t0; + let t1; + if ($[0] !== input) { + const arr = shallowCopy(input); + + const cond = identity(false); + t1 = cond ? { val: CONST_TRUE } : mutate(arr); + $[0] = input; + $[1] = t1; + } else { + t1 = $[1]; + } + return t1; + } + + export const FIXTURE_ENTRYPOINT = { + fn: useFoo, + params: [{ input: 3 }], + }; + + ``` +  + ### Eval output + (kind: exception) mutate is not defined + +FAIL: mutable-liverange-loop +- Expected ++ Received + + + ## Input + + ```javascript + function mutate() {} + function cond() {} + + function Component(props) { + let a = {}; + let b = {}; + let c = {}; + let d = {}; + while (true) { + mutate(a, b); + if (cond(a)) { + break; + } + } + + // all of these tests are seemingly readonly, since the values are never directly + // mutated again. but they are all aliased by `d`, which is later modified, and + // these are therefore mutable references: + if (a) { + } + if (b) { + } + if (c) { + } + if (d) { + } + + mutate(d, null); + } + + ``` + + ## Code + + ```javascript + function mutate() {} + function cond() {} + + function Component(props) { ++ Object.freeze(props); + const a = {}; + const b = {}; + const c = {}; + const d = {}; + while (true) { + mutate(a, b); + if (cond(a)) { + break; + } + } + if (a) { + } + if (b) { + } + if (c) { + } + if (d) { + } + + mutate(d, null); + } + + ``` +  + +FAIL: mutable-lifetime-with-aliasing +- Expected ++ Received + + + ## Input + + ```javascript + function mutate(x, y) { + 'use no forget'; + if (!Array.isArray(x.value)) { + x.value = []; + } + x.value.push(y); + if (y != null) { + y.value = x; + } + } + + function Component(props) { + const a = {}; + const b = [a]; // array elements alias + const c = {}; + const d = {c}; // object values alias + + // capture all the values into this object + const x = {}; + x.b = b; + const y = mutate(x, d); // mutation aliases the arg and return value + + // all of these tests are seemingly readonly, since the values are never directly + // mutated again. but they are all aliased by `x`, which is later modified, and + // these are therefore mutable references: + if (a) { + } + if (b) { + } + if (c) { + } + if (d) { + } + if (y) { + } + + // could in theory mutate any of a/b/c/x/z, so the above should be inferred as mutable + mutate(x, null); + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + isComponent: false, + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function mutate(x, y) { + "use no forget"; + if (!Array.isArray(x.value)) { + x.value = []; + } + x.value.push(y); + if (y != null) { + y.value = x; + } + } + + function Component(props) { + const $ = _c(1); ++ Object.freeze(props); + let x; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + const a = {}; + const b = [a]; + const c = {}; + const d = { c }; + + x = {}; + x.b = b; + const y = mutate(x, d); + if (a) { + } + if (b) { + } + if (c) { + } + if (d) { + } + if (y) { + } + + mutate(x, null); + $[0] = x; + } else { + x = $[0]; + } + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + isComponent: false, + }; + + ``` +  + ### Eval output + (kind: ok) {"b":[{}],"value":[{"c":{},"value":"[[ cyclic ref *0 ]]"},null]} + +FAIL: mutable-lifetime-loops +- Expected ++ Received + + + ## Input + + ```javascript + function mutate(x, y) { + 'use no forget'; + if (x != null) { + x.value = (x.value ?? 0) + 1; + } + if (y != null) { + y.value = (y.value ?? 0) + 1; + } + } + function cond(x) { + 'use no forget'; + return x.value > 5; + } + + function testFunction(props) { + let a = {}; + let b = {}; + let c = {}; + let d = {}; + while (true) { + let z = a; + a = b; + b = c; + c = d; + d = z; + mutate(a, b); + if (cond(a)) { + break; + } + } + + // all of these tests are seemingly readonly, since the values are never directly + // mutated again. but they are all aliased by `d`, which is later modified, and + // these are therefore mutable references: + if (a) { + } + if (b) { + } + if (c) { + } + if (d) { + } + + mutate(d, null); + return {a, b, c, d}; + } + + export const FIXTURE_ENTRYPOINT = { + fn: testFunction, + params: [{}], + isComponent: false, + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function mutate(x, y) { + "use no forget"; + if (x != null) { + x.value = (x.value ?? 0) + 1; + } + if (y != null) { + y.value = (y.value ?? 0) + 1; + } + } + function cond(x) { + "use no forget"; + return x.value > 5; + } + + function testFunction(props) { + const $ = _c(1); ++ Object.freeze(props); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + let a = {}; + let b = {}; + let c = {}; + let d = {}; + while (true) { + const z = a; + a = b; + b = c; + c = d; + d = z; + mutate(a, b); + if (cond(a)) { + break; + } + } + if (a) { + } + if (b) { + } + if (c) { + } + if (d) { + } + + mutate(d, null); + t0 = { a, b, c, d }; + $[0] = t0; + } else { + t0 = $[0]; + } + return t0; + } + + export const FIXTURE_ENTRYPOINT = { + fn: testFunction, + params: [{}], + isComponent: false, + }; + + ``` +  + ### Eval output + (kind: ok) {"a":{"value":6},"b":{"value":5},"c":{"value":4},"d":{"value":6}} + +FAIL: multiple-calls-to-hoisted-callback-from-other-callback +- Expected ++ Received + + + ## Input + + ```javascript + import {useState} from 'react'; + + function Component(props) { + const [_state, setState] = useState(); + const a = () => { + return b(); + }; + const b = () => { + return ( + <> +
onClick(true)}>a
 +
onClick(false)}>b
 +  + ); + }; + const onClick = value => { + setState(value); + }; + + return
{a()}
; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { useState } from "react"; + + function Component(props) { + const $ = _c(1); +- const [_state, setState] = useState(); ++ Object.freeze(props); ++ const [_state, setState] = (function () { ++ const $res$ = useState(); ++ Object.freeze($res$); ++ return $res$; ++ })(); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + const a = () => b(); + + const b = () => ( + <> +-
onClick(true)}>a
 +-
onClick(false)}>b
 ++ onClick(true); ++ Object.freeze($res$); ++ return $res$; ++ }} ++ > ++ a ++
 ++ onClick(false); ++ Object.freeze($res$); ++ return $res$; ++ }} ++ > ++ b ++
 +  + ); + + const onClick = (value) => { + setState(value); + }; + + t0 =
{a()}
; + $[0] = t0; + } else { + t0 = $[0]; + } + return t0; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + }; + + ``` +  + ### Eval output + (kind: ok)
a
b
 + +FAIL: multi-directive +- Expected ++ Received + + + ## Input + + ```javascript + function Component() { + 'use foo'; + 'use bar'; + return
"foo"
; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [], + isComponent: true, + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component() { +- "use foo"; +- "use bar"; + const $ = _c(1); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 =
"foo"
; + $[0] = t0; + } else { + t0 = $[0]; + } + return t0; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [], + isComponent: true, + }; + + ``` +  + ### Eval output + (kind: ok)
"foo"
 + +FAIL: multi-arrow-expr-gating-test +- Expected ++ Received + + + ## Input + + ```javascript + // @gating + const ErrorView = (error, _retry) => ; + + const Renderer = props => ( +  +  +  +  + ); + + export default Renderer; + + ``` + + ## Code + + ```javascript + import { isForgetEnabled_Fixtures } from "ReactForgetFeatureFlag"; + import { c as _c } from "react/compiler-runtime"; // @gating + const ErrorView = isForgetEnabled_Fixtures() + ? (error, _retry) => { + const $ = _c(2); ++ Object.freeze(error); ++ Object.freeze(_retry); + let t0; + if ($[0] !== error) { +- t0 = ; ++ t0 = ( ++  ++ ); + $[0] = error; + $[1] = t0; + } else { + t0 = $[1]; + } + return t0; + } + : (error, _retry) => ; + + const Renderer = isForgetEnabled_Fixtures() + ? (props) => { + const $ = _c(1); ++ Object.freeze(props); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = ( +  +  +  +  + ); + $[0] = t0; + } else { + t0 = $[0]; + } + return t0; + } + : (props) => ( +  +  +  +  + ); + export default Renderer; + + ``` +  + +FAIL: multi-arrow-expr-export-gating-test +- Expected ++ Received + + + ## Input + + ```javascript + // @gating + const ErrorView = (error, _retry) => ; + + export const Renderer = props => ( +  +  +  +  + ); + + ``` + + ## Code + + ```javascript + import { isForgetEnabled_Fixtures } from "ReactForgetFeatureFlag"; + import { c as _c } from "react/compiler-runtime"; // @gating + const ErrorView = isForgetEnabled_Fixtures() + ? (error, _retry) => { + const $ = _c(2); ++ Object.freeze(error); ++ Object.freeze(_retry); + let t0; + if ($[0] !== error) { +- t0 = ; ++ t0 = ( ++  ++ ); + $[0] = error; + $[1] = t0; + } else { + t0 = $[1]; + } + return t0; + } + : (error, _retry) => ; + + export const Renderer = isForgetEnabled_Fixtures() + ? (props) => { + const $ = _c(1); ++ Object.freeze(props); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = ( +  +  +  +  + ); + $[0] = t0; + } else { + t0 = $[0]; + } + return t0; + } + : (props) => ( +  +  +  +  + ); + + ``` +  + +FAIL: multi-arrow-expr-export-default-gating-test +- Expected ++ Received + + + ## Input + + ```javascript + // @gating + const ErrorView = (error, _retry) => ; + + export default Renderer = props => ( +  +  +  +  + ); + + ``` + + ## Code + + ```javascript + import { isForgetEnabled_Fixtures } from "ReactForgetFeatureFlag"; + import { c as _c } from "react/compiler-runtime"; // @gating + const ErrorView = isForgetEnabled_Fixtures() + ? (error, _retry) => { + const $ = _c(2); ++ Object.freeze(error); ++ Object.freeze(_retry); + let t0; + if ($[0] !== error) { +- t0 = ; ++ t0 = ( ++  ++ ); + $[0] = error; + $[1] = t0; + } else { + t0 = $[1]; + } + return t0; + } + : (error, _retry) => ; + + export default Renderer = isForgetEnabled_Fixtures() + ? (props) => { + const $ = _c(1); ++ Object.freeze(props); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = ( +  +  +  +  + ); + $[0] = t0; + } else { + t0 = $[0]; + } + return t0; + } + : (props) => ( +  +  +  +  + ); + + ``` +  + +FAIL: module-scoped-bindings +- Expected ++ Received + + + ## Input + + ```javascript + import React from 'react'; + import {useState} from 'react'; + + const CONST = true; + + let NON_REASSIGNED_LET = true; + + let REASSIGNED_LET = false; + REASSIGNED_LET = true; + + function reassignedFunction() {} + reassignedFunction = true; + + function nonReassignedFunction() {} + + class ReassignedClass {} + ReassignedClass = true; + + class NonReassignedClass {} + + function Component() { + const [state] = useState(null); + return [ + React, + state, + CONST, + NON_REASSIGNED_LET, + REASSIGNED_LET, + reassignedFunction, + nonReassignedFunction, + ReassignedClass, + NonReassignedClass, + ]; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import React from "react"; + import { useState } from "react"; + + const CONST = true; + + let NON_REASSIGNED_LET = true; + + let REASSIGNED_LET = false; + REASSIGNED_LET = true; + + function reassignedFunction() {} + reassignedFunction = true; + + function nonReassignedFunction() {} + + class ReassignedClass {} + ReassignedClass = true; + + class NonReassignedClass {} + + function Component() { + const $ = _c(2); +- const [state] = useState(null); ++ const [state] = (function () { ++ const $res$ = useState(Object.freeze(null)); ++ Object.freeze($res$); ++ return $res$; ++ })(); + let t0; + if ($[0] !== state) { + t0 = [ + React, + + state, + CONST, + NON_REASSIGNED_LET, + REASSIGNED_LET, + reassignedFunction, + nonReassignedFunction, + ReassignedClass, + NonReassignedClass, + ]; + $[0] = state; + $[1] = t0; + } else { + t0 = $[1]; + } + return t0; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + }; + + ``` +  + ### Eval output + (kind: ok) [{"Children":{"map":"[[ function params=3 ]]","forEach":"[[ function params=3 ]]","count":"[[ function params=1 ]]","toArray":"[[ function params=1 ]]","only":"[[ function params=1 ]]"},"Component":"[[ function params=3 ]]","PureComponent":"[[ function params=3 ]]","__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE":{"H":{"readContext":"[[ function params=1 ]]","use":"[[ function params=1 ]]","useCallback":"[[ function params=2 ]]","useContext":"[[ function params=1 ]]","useEffect":"[[ function params=2 ]]","useImperativeHandle":"[[ function params=3 ]]","useInsertionEffect":"[[ function params=2 ]]","useLayoutEffect":"[[ function params=2 ]]","useMemo":"[[ function params=2 ]]","useReducer":"[[ function params=3 ]]","useRef":"[[ function params=1 ]]","useState":"[[ function params=1 ]]","useDebugValue":"[[ function params=2 ]]","useDeferredValue":"[[ function params=2 ]]","useTransition":"[[ function params=0 ]]","useSyncExternalStore":"[[ function params=3 ]]","useId":"[[ function params=0 ]]","useCacheRefresh":"[[ function params=0 ]]","useMemoCache":"[[ function params=1 ]]","useHostTransitionStatus":"[[ function params=0 ]]","useFormState":"[[ function params=3 ]]","useActionState":"[[ function params=3 ]]","useOptimistic":"[[ function params=2 ]]"},"A":{"getCacheForType":"[[ function params=1 ]]","getOwner":"[[ function params=0 ]]"},"T":null,"actQueue":["[[ function params=0 ]]","[[ function params=1 ]]"],"isBatchingLegacy":false,"didScheduleLegacyUpdate":false,"didUsePromise":false,"thrownErrors":[],"setExtraStackFrame":"[[ function params=1 ]]","getCurrentStack":"[[ function params=0 ]]","getStackAddendum":"[[ function params=0 ]]"},"act":"[[ function params=1 ]]","cache":"[[ function params=1 ]]","cloneElement":"[[ function params=3 ]]","createContext":"[[ function params=1 ]]","createElement":"[[ function params=3 ]]","createRef":"[[ function params=0 ]]","forwardRef":"[[ function params=1 ]]","isValidElement":"[[ function params=1 ]]","lazy":"[[ function params=1 ]]","memo":"[[ function params=2 ]]","startTransition":"[[ function params=2 ]]","unstable_useCacheRefresh":"[[ function params=0 ]]","use":"[[ function params=1 ]]","useActionState":"[[ function params=3 ]]","useCallback":"[[ function params=2 ]]","useContext":"[[ function params=1 ]]","useDebugValue":"[[ function params=2 ]]","useDeferredValue":"[[ function params=2 ]]","useEffect":"[[ function params=2 ]]","useId":"[[ function params=0 ]]","useImperativeHandle":"[[ function params=3 ]]","useInsertionEffect":"[[ function params=2 ]]","useLayoutEffect":"[[ function params=2 ]]","useMemo":"[[ function params=2 ]]","useOptimistic":"[[ function params=2 ]]","useReducer":"[[ function params=3 ]]","useRef":"[[ function params=1 ]]","useState":"[[ function params=1 ]]","useSyncExternalStore":"[[ function params=3 ]]","useTransition":"[[ function params=0 ]]","version":"19.0.0-beta-b498834eab-20240506","c":"[[ function params=1 ]]"},"[[ cyclic ref *6 ]]",true,true,true,true,"[[ function params=0 ]]",true,"[[ function params=0 ]]"] + +FAIL: method-call +- Expected ++ Received + + + ## Input + + ```javascript + import {addOne, shallowCopy} from 'shared-runtime'; + + function foo(a, b, c) { + // Construct and freeze x + const x = shallowCopy(a); +
{x}
; + + // y should depend on `x` and `b` + const y = x.foo(b); + return y; + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: [{foo: addOne}, 3], + isComponent: false, + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { addOne, shallowCopy } from "shared-runtime"; + + function foo(a, b, c) { + const $ = _c(5); ++ Object.freeze(a); ++ Object.freeze(b); ++ Object.freeze(c); + let t0; + if ($[0] !== a) { + t0 = shallowCopy(a); + $[0] = a; + $[1] = t0; + } else { + t0 = $[1]; + } + const x = t0; + let t1; + if ($[2] !== x || $[3] !== b) { + t1 = x.foo(b); + $[2] = x; + $[3] = b; + $[4] = t1; + } else { + t1 = $[4]; + } + const y = t1; + return y; + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: [{ foo: addOne }, 3], + isComponent: false, + }; + + ``` +  + ### Eval output + (kind: ok) 4 + +FAIL: method-call-fn-call +- Expected ++ Received + + + ## Input + + ```javascript + function foo(a, b, c) { + // Construct and freeze x + const x = makeObject(a); +
{x}
; + + // y should depend on `x` and `b` + const method = x.method; + const y = method.call(x, b); + return y; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function foo(a, b, c) { + const $ = _c(6); ++ Object.freeze(a); ++ Object.freeze(b); ++ Object.freeze(c); + let t0; + if ($[0] !== a) { + t0 = makeObject(a); + $[0] = a; + $[1] = t0; + } else { + t0 = $[1]; + } + const x = t0; + + const method = x.method; + let t1; + if ($[2] !== method || $[3] !== x || $[4] !== b) { + t1 = method.call(x, b); + $[2] = method; + $[3] = x; + $[4] = b; + $[5] = t1; + } else { + t1 = $[5]; + } + const y = t1; + return y; + } + + ``` +  + +FAIL: method-call-computed +- Expected ++ Received + + + ## Input + + ```javascript + function foo(a, b, c) { + // Construct and freeze x, y + const x = makeObject(a); + const y = makeObject(a); +
 + {x} + {y} +
; + + // z should depend on `x`, `y.method`, and `b` + const z = x[y.method](b); + return z; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function foo(a, b, c) { + const $ = _c(8); ++ Object.freeze(a); ++ Object.freeze(b); ++ Object.freeze(c); + let t0; + if ($[0] !== a) { + t0 = makeObject(a); + $[0] = a; + $[1] = t0; + } else { + t0 = $[1]; + } + const x = t0; + let t1; + if ($[2] !== a) { + t1 = makeObject(a); + $[2] = a; + $[3] = t1; + } else { + t1 = $[3]; + } + const y = t1; + let t2; + if ($[4] !== x || $[5] !== y.method || $[6] !== b) { + t2 = x[y.method](b); + $[4] = x; + $[5] = y.method; + $[6] = b; + $[7] = t2; + } else { + t2 = $[7]; + } + const z = t2; + return z; + } + + ``` +  + +FAIL: merged-scopes-are-valid-effect-deps +- Expected ++ Received + + + ## Input + + ```javascript + // @validateMemoizedEffectDependencies + + import {useEffect} from 'react'; + + function Component(props) { + const y = [[props.value]]; // merged w scope for inner array + + useEffect(() => { + console.log(y); + }, [y]); // should still be a valid dependency here + + return y; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{value: 42}], + isComponent: false, + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; // @validateMemoizedEffectDependencies + + import { useEffect } from "react"; + + function Component(props) { + const $ = _c(5); ++ Object.freeze(props); + let t0; + if ($[0] !== props.value) { + t0 = [[props.value]]; + $[0] = props.value; + $[1] = t0; + } else { + t0 = $[1]; + } + const y = t0; + let t1; + let t2; + if ($[2] !== y) { + t1 = () => { + console.log(y); + }; + t2 = [y]; + $[2] = y; + $[3] = t1; + $[4] = t2; + } else { + t1 = $[3]; + t2 = $[4]; + } +- useEffect(t1, t2); ++ (function () { ++ const $res$ = useEffect(Object.freeze(t1), Object.freeze(t2)); ++ Object.freeze($res$); ++ return $res$; ++ })(); + return y; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ value: 42 }], + isComponent: false, + }; + + ``` +  + ### Eval output + (kind: ok) [[42]] + logs: [[ [ 42 ] ]] + +FAIL: merge-scopes-callback +- Expected ++ Received + + + ## Input + + ```javascript + // @enableInstructionReordering + import {useState} from 'react'; + + function Component() { + const [state, setState] = useState(0); + const onClick = () => { + setState(s => s + 1); + }; + return ( + <> + Count: {state} +  +  + ); + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; // @enableInstructionReordering + import { useState } from "react"; + + function Component() { + const $ = _c(4); +- const [state, setState] = useState(0); ++ const [state, setState] = (function () { ++ const $res$ = useState(Object.freeze(0)); ++ Object.freeze($res$); ++ return $res$; ++ })(); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = () => { + setState((s) => s + 1); + }; + $[0] = t0; + } else { + t0 = $[0]; + } + const onClick = t0; + let t1; + if ($[1] === Symbol.for("react.memo_cache_sentinel")) { +- t1 = ; ++ t1 = ( ++  ++ Increment ++  ++ ); + $[1] = t1; + } else { + t1 = $[1]; + } + let t2; + if ($[2] !== state) { + t2 = ( + <> + Count: {state} + {t1} +  + ); + $[2] = state; + $[3] = t2; + } else { + t2 = $[3]; + } + return t2; + } + + ``` +  + ### Eval output + (kind: exception) Fixture not implemented + +FAIL: merge-nested-scopes-with-same-inputs +- Expected ++ Received + + + ## Input + + ```javascript + import {setProperty} from 'shared-runtime'; + + function Component(props) { + // start of scope for y, depend on props.a + let y = {}; + + // nested scope for x, dependent on props.a + const x = {}; + setProperty(x, props.a); + // end of scope for x + + y.a = props.a; + y.x = x; + // end of scope for y + + return y; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{a: 42}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { setProperty } from "shared-runtime"; + + function Component(props) { + const $ = _c(2); ++ Object.freeze(props); + let y; + if ($[0] !== props.a) { + y = {}; + + const x = {}; + setProperty(x, props.a); + + y.a = props.a; + y.x = x; + $[0] = props.a; + $[1] = y; + } else { + y = $[1]; + } + return y; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ a: 42 }], + }; + + ``` +  + ### Eval output + (kind: ok) {"a":42,"x":{"wat0":42}} + +FAIL: merge-consecutive-scopes +- Expected ++ Received + + + ## Input + + ```javascript + import {useState} from 'react'; + import {Stringify} from 'shared-runtime'; + + function Component() { + let [state, setState] = useState(0); + return ( +
 +  + {state} +  +
 + ); + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{value: 42}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { useState } from "react"; + import { Stringify } from "shared-runtime"; + + function Component() { + const $ = _c(8); +- const [state, setState] = useState(0); ++ const [state, setState] = (function () { ++ const $res$ = useState(Object.freeze(0)); ++ Object.freeze($res$); ++ return $res$; ++ })(); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = ; + $[0] = t0; + } else { + t0 = $[0]; + } + let t1; + if ($[1] !== state) { + t1 = {state}; + $[1] = state; + $[2] = t1; + } else { + t1 = $[2]; + } + let t2; + if ($[3] !== state) { + t2 = ( +-  + ); + $[3] = state; + $[4] = t2; + } else { + t2 = $[4]; + } + let t3; + if ($[5] !== t1 || $[6] !== t2) { + t3 = ( +
 + {t0} + {t1} + {t2} +
 + ); + $[5] = t1; + $[6] = t2; + $[7] = t3; + } else { + t3 = $[7]; + } + return t3; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ value: 42 }], + }; + + ``` +  + ### Eval output + (kind: ok)
{"text":"Counter"}
0
 + +FAIL: merge-consecutive-scopes-reordering +- Expected ++ Received + + + ## Input + + ```javascript + // @enableInstructionReordering + import {useState} from 'react'; + import {Stringify} from 'shared-runtime'; + + function Component() { + let [state, setState] = useState(0); + return ( +
 +  + {state} +  +
 + ); + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{value: 42}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; // @enableInstructionReordering + import { useState } from "react"; + import { Stringify } from "shared-runtime"; + + function Component() { + const $ = _c(7); +- const [state, setState] = useState(0); ++ const [state, setState] = (function () { ++ const $res$ = useState(Object.freeze(0)); ++ Object.freeze($res$); ++ return $res$; ++ })(); + let t0; + let t1; + if ($[0] !== state) { + t0 = ( +-  + ); + t1 = {state}; + $[0] = state; + $[1] = t0; + $[2] = t1; + } else { + t0 = $[1]; + t1 = $[2]; + } + let t2; + if ($[3] === Symbol.for("react.memo_cache_sentinel")) { + t2 = ; + $[3] = t2; + } else { + t2 = $[3]; + } + let t3; + if ($[4] !== t1 || $[5] !== t0) { + t3 = ( +
 + {t2} + {t1} + {t0} +
 + ); + $[4] = t1; + $[5] = t0; + $[6] = t3; + } else { + t3 = $[6]; + } + return t3; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ value: 42 }], + }; + + ``` +  + ### Eval output + (kind: ok)
{"text":"Counter"}
0
 + +FAIL: merge-consecutive-scopes-objects +- Expected ++ Received + + + ## Input + + ```javascript + import {useState} from 'react'; + import {Stringify} from 'shared-runtime'; + + // This is a translation of the original merge-consecutive-scopes which uses plain objects + // to describe the UI instead of JSX. The JSXText elements in that fixture happen to + // prevent scome scopes from merging, which concealed a bug with the merging logic. + // By avoiding JSX we eliminate extraneous instructions and more accurately test the merging. + function Component(props) { + let [state, setState] = useState(0); + return [ + {component: Stringify, props: {text: 'Counter'}}, + {component: 'span', props: {children: [state]}}, + { + component: 'button', + props: { + 'data-testid': 'button', + onClick: () => setState(state + 1), + children: ['increment'], + }, + }, + ]; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { useState } from "react"; + import { Stringify } from "shared-runtime"; + + // This is a translation of the original merge-consecutive-scopes which uses plain objects + // to describe the UI instead of JSX. The JSXText elements in that fixture happen to + // prevent scome scopes from merging, which concealed a bug with the merging logic. + // By avoiding JSX we eliminate extraneous instructions and more accurately test the merging. + function Component(props) { + const $ = _c(11); +- const [state, setState] = useState(0); ++ Object.freeze(props); ++ const [state, setState] = (function () { ++ const $res$ = useState(Object.freeze(0)); ++ Object.freeze($res$); ++ return $res$; ++ })(); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = { component: Stringify, props: { text: "Counter" } }; + $[0] = t0; + } else { + t0 = $[0]; + } + let t1; + if ($[1] !== state) { + t1 = { component: "span", props: { children: [state] } }; + $[1] = state; + $[2] = t1; + } else { + t1 = $[2]; + } + let t2; + if ($[3] !== state) { + t2 = () => setState(state + 1); + $[3] = state; + $[4] = t2; + } else { + t2 = $[4]; + } + let t3; + if ($[5] === Symbol.for("react.memo_cache_sentinel")) { + t3 = ["increment"]; + $[5] = t3; + } else { + t3 = $[5]; + } + let t4; + if ($[6] !== t2) { + t4 = { + component: "button", + props: { "data-testid": "button", onClick: t2, children: t3 }, + }; + $[6] = t2; + $[7] = t4; + } else { + t4 = $[7]; + } + let t5; + if ($[8] !== t1 || $[9] !== t4) { + t5 = [t0, t1, t4]; + $[8] = t1; + $[9] = t4; + $[10] = t5; + } else { + t5 = $[10]; + } + return t5; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + }; + + ``` +  + ### Eval output + (kind: ok) [{"component":"[[ function params=1 ]]","props":{"text":"Counter"}},{"component":"span","props":{"children":[0]}},{"component":"button","props":{"data-testid":"button","onClick":"[[ function params=0 ]]","children":["increment"]}}] + +FAIL: merge-consecutive-scopes-no-deps +- Expected ++ Received + + + ## Input + + ```javascript + const {getNumber} = require('shared-runtime'); + + function Component(props) { + // Two scopes: one for `getNumber()`, one for the object literal. + // Neither has dependencies so they should merge + return {session_id: getNumber()}; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + const { getNumber } = require("shared-runtime"); + + function Component(props) { + const $ = _c(1); ++ Object.freeze(props); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = { session_id: getNumber() }; + $[0] = t0; + } else { + t0 = $[0]; + } + return t0; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + }; + + ``` +  + ### Eval output + (kind: ok) {"session_id":4} + +FAIL: merge-consecutive-scopes-deps-subset-of-decls +- Expected ++ Received + + + ## Input + + ```javascript + import {useState} from 'react'; + + function Component() { + const [count, setCount] = useState(0); + return ( +
 +  + {/** + * The scope for the  +
 + ); + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { useState } from "react"; + + function Component() { + const $ = _c(2); +- const [count, setCount] = useState(0); ++ const [count, setCount] = (function () { ++ const $res$ = useState(Object.freeze(0)); ++ Object.freeze($res$); ++ return $res$; ++ })(); + let t0; + if ($[0] !== count) { + t0 = ( +
 +-  ++ setCount(count - 1); ++ Object.freeze($res$); ++ return $res$; ++ }} ++ > ++ Decrement ++  + +-  ++ setCount(count + 1); ++ Object.freeze($res$); ++ return $res$; ++ }} ++ > ++ Increment ++  +
 + ); + $[0] = count; + $[1] = t0; + } else { + t0 = $[1]; + } + return t0; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + }; + + ``` +  + ### Eval output + (kind: ok)
 + +FAIL: merge-consecutive-nested-scopes +- Expected ++ Received + + + ## Input + + ```javascript + const {getNumber} = require('shared-runtime'); + + function Component(props) { + let x; + // Two scopes: one for `getNumber()`, one for the object literal. + // Neither has dependencies so they should merge + if (props.cond) { + x = {session_id: getNumber()}; + } + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{cond: true}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + const { getNumber } = require("shared-runtime"); + + function Component(props) { + const $ = _c(1); ++ Object.freeze(props); + let x; + if (props.cond) { + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = { session_id: getNumber() }; + $[0] = t0; + } else { + t0 = $[0]; + } + x = t0; + } + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ cond: true }], + }; + + ``` +  + ### Eval output + (kind: ok) {"session_id":4} + +FAIL: memoize-value-block-value-sequence +- Expected ++ Received + + + ## Input + + ```javascript + function Foo(props) { + let x; + (x = []), null; + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Foo, + params: [{}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Foo(props) { + const $ = _c(1); ++ Object.freeze(props); + let x; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + (x = []), null; + $[0] = x; + } else { + x = $[0]; + } + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Foo, + params: [{}], + }; + + ``` +  + ### Eval output + (kind: ok) [] + +FAIL: memoize-value-block-value-logical +- Expected ++ Received + + + ## Input + + ```javascript + function Foo(props) { + let x; + true && ((x = []), null); + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Foo, + params: [{}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Foo(props) { + const $ = _c(1); ++ Object.freeze(props); + let x; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + true && ((x = []), null); + $[0] = x; + } else { + x = $[0]; + } + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Foo, + params: [{}], + }; + + ``` +  + ### Eval output + (kind: ok) [] + +FAIL: memoize-value-block-value-logical-no-sequence +- Expected ++ Received + + + ## Input + + ```javascript + function Foo(props) { + let x; + true && (x = []); + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Foo, + params: [{}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Foo(props) { + const $ = _c(1); ++ Object.freeze(props); + let x; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + true && (x = []); + $[0] = x; + } else { + x = $[0]; + } + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Foo, + params: [{}], + }; + + ``` +  + ### Eval output + (kind: ok) [] + +FAIL: memoize-value-block-value-conditional +- Expected ++ Received + + + ## Input + + ```javascript + function Foo(props) { + let x; + true ? (x = []) : (x = {}); + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Foo, + params: [{}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Foo(props) { + const $ = _c(1); ++ Object.freeze(props); + let x; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + true ? (x = []) : (x = {}); + $[0] = x; + } else { + x = $[0]; + } + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Foo, + params: [{}], + }; + + ``` +  + ### Eval output + (kind: ok) [] + +FAIL: memoization-comments +- Expected ++ Received + + + ## Input + + ```javascript + // @enableMemoizationComments + import {addOne, getNumber, identity} from 'shared-runtime'; + + function Component(props) { + const x = identity(props.a); + const y = addOne(x); + const z = identity(props.b); + return [x, y, z]; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{a: 1, b: 10}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; // @enableMemoizationComments + import { addOne, getNumber, identity } from "shared-runtime"; + + function Component(props) { + const $ = _c(9); ++ Object.freeze(props); + let t0; + let x; // "useMemo" for t0 and x: + // check if props.a changed + if ($[0] !== props.a) { + // Inputs changed, recompute + x = identity(props.a); + t0 = addOne(x); + $[0] = props.a; + $[1] = t0; + $[2] = x; + } else { + // Inputs did not change, use cached value + t0 = $[1]; + x = $[2]; + } + const y = t0; + let t1; // "useMemo" for t1: + // check if props.b changed + if ($[3] !== props.b) { + // Inputs changed, recompute + t1 = identity(props.b); + $[3] = props.b; + $[4] = t1; + } else { + // Inputs did not change, use cached value + t1 = $[4]; + } + const z = t1; + let t2; // "useMemo" for t2: + // check if x, y, or z changed + if ($[5] !== x || $[6] !== y || $[7] !== z) { + // Inputs changed, recompute + t2 = [x, y, z]; + $[5] = x; + $[6] = y; + $[7] = z; + $[8] = t2; + } else { + // Inputs did not change, use cached value + t2 = $[8]; + } + return t2; + } + export const FIXTURE_ENTRYPOINT = { fn: Component, params: [{ a: 1, b: 10 }] }; + + ``` +  + ### Eval output + (kind: ok) [1,2,10] + +FAIL: mege-consecutive-scopes-dont-merge-with-different-deps +- Expected ++ Received + + + ## Input + + ```javascript + const {getNumber, identity} = require('shared-runtime'); + + function Component(props) { + // Two scopes: one for `getNumber()`, one for the object literal. + // Neither has dependencies so they should merge + return {a: getNumber(), b: identity(props.id), c: ['static']}; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{id: 42}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + const { getNumber, identity } = require("shared-runtime"); + + function Component(props) { + const $ = _c(6); ++ Object.freeze(props); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = getNumber(); + $[0] = t0; + } else { + t0 = $[0]; + } + let t1; + if ($[1] !== props.id) { + t1 = identity(props.id); + $[1] = props.id; + $[2] = t1; + } else { + t1 = $[2]; + } + let t2; + if ($[3] === Symbol.for("react.memo_cache_sentinel")) { + t2 = ["static"]; + $[3] = t2; + } else { + t2 = $[3]; + } + let t3; + if ($[4] !== t1) { + t3 = { a: t0, b: t1, c: t2 }; + $[4] = t1; + $[5] = t3; + } else { + t3 = $[5]; + } + return t3; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ id: 42 }], + }; + + ``` +  + ### Eval output + (kind: ok) {"a":4,"b":42,"c":["static"]} + +FAIL: maybe-mutate-object-in-callback +- Expected ++ Received + + + ## Input + + ```javascript + const {mutate} = require('shared-runtime'); + + function Component(props) { + const object = {}; + // We optimistically assume function calls within callbacks don't mutate (unless the function + // is known to be called during render), so this should get memoized + const onClick = () => { + mutate(object); + }; + return {props.children}; + } + + function Foo({children}) { + return children; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{children:
Hello
}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + const { mutate } = require("shared-runtime"); + + function Component(props) { + const $ = _c(3); ++ Object.freeze(props); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + const object = {}; + + t0 = () => { + mutate(object); + }; + $[0] = t0; + } else { + t0 = $[0]; + } + const onClick = t0; + let t1; + if ($[1] !== props.children) { +- t1 = {props.children}; ++ t1 = ( ++  ++ {props.children} ++
 ++ ); + $[1] = props.children; + $[2] = t1; + } else { + t1 = $[2]; + } + return t1; + } + + function Foo(t0) { ++ Object.freeze(t0); + const { children } = t0; + return children; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ children:
Hello
}], + }; + + ``` +  + ### Eval output + (kind: ok)
Hello
 + +FAIL: logical-expression +- Expected ++ Received + + + ## Input + + ```javascript + function component(props) { + let a = props.a || (props.b && props.c && props.d); + let b = (props.a && props.b && props.c) || props.d; + return a ? b : props.c; + } + + export const FIXTURE_ENTRYPOINT = { + fn: component, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + function component(props) { ++ Object.freeze(props); + const a = props.a || (props.b && props.c && props.d); + const b = (props.a && props.b && props.c) || props.d; + return a ? b : props.c; + } + + export const FIXTURE_ENTRYPOINT = { + fn: component, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: logical-expression-object +- Expected ++ Received + + + ## Input + + ```javascript + function component(props) { + // The mutable range for a extens the entire body. + // commenting out the last line of InferMutableRanges fixes it. + // my guess of what's going on is that a is aliased into the return value object literal, + // and that alias makes it look like the range of a needs to be extended to that point. + // but what's weird is that the end of a's range doesn't quite extend to the object. + let a = props.a || (props.b && props.c && props.d); + let b = (props.a && props.b && props.c) || props.d; + return {a, b}; + } + + export const FIXTURE_ENTRYPOINT = { + fn: component, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function component(props) { + const $ = _c(3); ++ Object.freeze(props); + + const a = props.a || (props.b && props.c && props.d); + const b = (props.a && props.b && props.c) || props.d; + let t0; + if ($[0] !== a || $[1] !== b) { + t0 = { a, b }; + $[0] = a; + $[1] = b; + $[2] = t0; + } else { + t0 = $[2]; + } + return t0; + } + + export const FIXTURE_ENTRYPOINT = { + fn: component, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: log-pruned-memoization + >> Unexpected error during test: + + +Found differences in evaluator results +Non-forget (expected): +(kind: ok)
{"items":[42,{"a":0,"b":"value1","c":true},{"a":0,"b":"value1","c":true},{"a":0,"b":"value1","c":true},[{"a":0,"b":"value1","c":true},{"a":0,"b":"value1","c":true},{"a":0,"b":"value1","c":true},{"a":0,"b":"value1","c":true},{"a":0,"b":"value1","c":true},{"a":0,"b":"value1","c":true},{"a":0,"b":"value1","c":true},{"a":0,"b":"value1","c":true},{"a":0,"b":"value1","c":true},{"a":0,"b":"value1","c":true}]]}
+Forget: +(kind: ok)
{"items":"[[ function params=0 ]]"}
+ +FAIL: lambda-mutated-ref-non-reactive +- Expected ++ Received + + + ## Input + + ```javascript + function f(a) { + let x; + (() => { + x = {}; + })(); + // this is not reactive on `x` as `x` is never reactive + return
; + } + + export const FIXTURE_ENTRYPOINT = { + fn: f, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function f(a) { + const $ = _c(2); ++ Object.freeze(a); + let x; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + x; + x = {}; + $[0] = x; + } else { + x = $[0]; + } + let t0; + if ($[1] === Symbol.for("react.memo_cache_sentinel")) { +- t0 =
; ++ t0 = ( ++  ++ ); + $[1] = t0; + } else { + t0 = $[1]; + } + return t0; + } + + export const FIXTURE_ENTRYPOINT = { + fn: f, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: lambda-mutated-non-reactive-to-reactive +- Expected ++ Received + + + ## Input + + ```javascript + function f(a) { + let x; + (() => { + x = {a}; + })(); + return
; + } + + export const FIXTURE_ENTRYPOINT = { + fn: f, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function f(a) { + const $ = _c(4); ++ Object.freeze(a); + let x; + if ($[0] !== a) { + x; + x = { a }; + $[0] = a; + $[1] = x; + } else { + x = $[1]; + } + + const t0 = x; + let t1; + if ($[2] !== t0) { +- t1 =
; ++ t1 = ( ++  ++ ); + $[2] = t0; + $[3] = t1; + } else { + t1 = $[3]; + } + return t1; + } + + export const FIXTURE_ENTRYPOINT = { + fn: f, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: lambda-capture-returned-alias +- Expected ++ Received + + + ## Input + + ```javascript + // 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; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; // 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 $ = _c(5); ++ Object.freeze(props); + let t0; + if ($[0] !== props.x) { + t0 = foo(props.x); + $[0] = props.x; + $[1] = t0; + } else { + t0 = $[1]; + } + const idx = t0; + let aliasedElement; + if ($[2] !== props.el || $[3] !== idx) { + const element = bar(props.el); + + const fn = function () { + const arr = { element }; + return arr[idx]; + }; + + aliasedElement = fn(); + mutate(aliasedElement); + $[2] = props.el; + $[3] = idx; + $[4] = aliasedElement; + } else { + aliasedElement = $[4]; + } + return aliasedElement; + } + + ``` +  + +FAIL: labeled-break-within-label-switch +- Expected ++ Received + + + ## Input + + ```javascript + import {CONST_STRING0} from 'shared-runtime'; + + function useHook(cond) { + const log = []; + switch (CONST_STRING0) { + case CONST_STRING0: + log.push(`@A`); + bb0: { + if (cond) { + break bb0; + } + log.push(`@B`); + } + log.push(`@C`); + } + return log; + } + + export const FIXTURE_ENTRYPOINT = { + fn: useHook, + params: [true], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { CONST_STRING0 } from "shared-runtime"; + + function useHook(cond) { + const $ = _c(2); ++ Object.freeze(cond); + let log; + if ($[0] !== cond) { + log = []; + switch (CONST_STRING0) { + case CONST_STRING0: { + log.push(`@A`); + bb0: { + if (cond) { + break bb0; + } + + log.push(`@B`); + } + + log.push(`@C`); + } + } + $[0] = cond; + $[1] = log; + } else { + log = $[1]; + } + return log; + } + + export const FIXTURE_ENTRYPOINT = { + fn: useHook, + params: [true], + }; + + ``` +  + ### Eval output + (kind: ok) ["@A","@C"] + +FAIL: labeled-break-within-label-loop +- Expected ++ Received + + + ## Input + + ```javascript + function useHook(end) { + const log = []; + for (let i = 0; i < end + 1; i++) { + log.push(`${i} @A`); + bb0: { + if (i === end) { + break bb0; + } + log.push(`${i} @B`); + } + log.push(`${i} @C`); + } + return log; + } + + export const FIXTURE_ENTRYPOINT = { + fn: useHook, + params: [1], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function useHook(end) { + const $ = _c(2); ++ Object.freeze(end); + let log; + if ($[0] !== end) { + log = []; + for (let i = 0; i < end + 1; i++) { + log.push(`${i} @A`); + bb0: { + if (i === end) { + break bb0; + } + + log.push(`${i} @B`); + } + + log.push(`${i} @C`); + } + $[0] = end; + $[1] = log; + } else { + log = $[1]; + } + return log; + } + + export const FIXTURE_ENTRYPOINT = { + fn: useHook, + params: [1], + }; + + ``` +  + ### Eval output + (kind: ok) ["0 @A","0 @B","0 @C","1 @A","1 @C"] + +FAIL: jsx-ternary-local-variable + >> Unexpected error during test: + + +Found differences in evaluator results +Non-forget (expected): +(kind: ok)
HigherOrderComponent
StaticText2
+Forget: +(kind: exception) props.items.map is not a function + +FAIL: jsx-tag-evaluation-order +- Expected ++ Received + + + ## Input + + ```javascript + import {StaticText1, StaticText2} from 'shared-runtime'; + + function Component(props: {value: string}) { + let Tag = StaticText1; + + // Currently, Forget preserves jsx whitespace in the source text. + // prettier-ignore + return ( + {((Tag = StaticText2), props.value)} + ); + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{value: 'string value 1'}], + isComponent: true, + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { StaticText1, StaticText2 } from "shared-runtime"; + + function Component(props) { + const $ = _c(3); ++ Object.freeze(props); + + const t0 = props.value; + let t1; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t1 = ; + $[0] = t1; + } else { + t1 = $[0]; + } + let t2; + if ($[1] !== t0) { + t2 = ( +  + {t0} + {t1} +  + ); + $[1] = t0; + $[2] = t2; + } else { + t2 = $[2]; + } + return t2; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ value: "string value 1" }], + isComponent: true, + }; + + ``` +  + ### Eval output + (kind: ok)
StaticText1string value 1
StaticText2
 + +FAIL: jsx-tag-evaluation-order-non-global +- Expected ++ Received + + + ## Input + + ```javascript + import {StaticText1, StaticText2} from 'shared-runtime'; + + function MaybeMutable() { + return {}; + } + function maybeMutate(x) {} + + 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. + + // Currently, Forget preserves jsx whitespace in the source text. + // prettier-ignore + return ( + {((Tag = props.alternateComponent), maybeMutate(maybeMutable))} + ); + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{component: StaticText1, alternateComponent: StaticText2}], + isComponent: true, + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { StaticText1, StaticText2 } from "shared-runtime"; + + function MaybeMutable() { + const $ = _c(1); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = {}; + $[0] = t0; + } else { + t0 = $[0]; + } + return t0; + } + +- function maybeMutate(x) {} ++ function maybeMutate(x) { ++ Object.freeze(x); ++ } + + function Component(props) { + const $ = _c(11); ++ Object.freeze(props); + let Tag; + let T0; + let t0; + if ($[0] !== props.component || $[1] !== props.alternateComponent) { + const maybeMutable = new MaybeMutable(); + Tag = props.component; + + T0 = Tag; + t0 = ((Tag = props.alternateComponent), maybeMutate(maybeMutable)); + $[0] = props.component; + $[1] = props.alternateComponent; + $[2] = Tag; + $[3] = T0; + $[4] = t0; + } else { + Tag = $[2]; + T0 = $[3]; + t0 = $[4]; + } + let t1; + if ($[5] !== Tag) { + t1 = ; + $[5] = Tag; + $[6] = t1; + } else { + t1 = $[6]; + } + let t2; + if ($[7] !== T0 || $[8] !== t0 || $[9] !== t1) { + t2 = ( +  + {t0} + {t1} +  + ); + $[7] = T0; + $[8] = t0; + $[9] = t1; + $[10] = t2; + } else { + t2 = $[10]; + } + return t2; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ component: StaticText1, alternateComponent: StaticText2 }], + isComponent: true, + }; + + ``` +  + ### Eval output + (kind: ok)
StaticText1
StaticText2
 + +FAIL: jsx-string-attribute-non-ascii + >> Unexpected error during test: + + +Found differences in evaluator results +Non-forget (expected): +(kind: ok)

potetotes

in addition to understanding JavaScript semantics and the rules of React, the compiler team also understands தமிழ், 中文, 日本語, 한국어 and i think that’s pretty cool
+Forget: +(kind: ok)

potetotes

+logs: ['Warning: Functions are not valid as a React child. This may happen if you return %s instead of <%s /> from render. Or maybe you meant to call this function rather than return it.\n' + + ' <%s>{%s}%s','text','text','span','text','span','\n' + + ' at span\n' + + ' at div\n' + + ' at Post (eval at doEval (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:200:28), :39:36)\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)'] + +FAIL: jsx-string-attribute-expression-container + >> Unexpected error during test: + + +Found differences in evaluator results +Non-forget (expected): +(kind: ok)
+A E나은Laurenசத்யாSathya
+Forget: +(kind: ok)
LaurenSathya
+logs: ['Warning: Functions are not valid as a React child. This may happen if you return %s instead of <%s /> from render. Or maybe you meant to call this function rather than return it.\n' + + ' <%s>{%s}%s','value','value','span','value','span','\n' + + ' at span\n' + + ' at Text (eval at doEval (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:200:28), :60:36)\n' + + ' at div\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)'] + +FAIL: jsx-spread +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + return ( +  + ); + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(5); ++ Object.freeze(props); + + const t0 = props.cond ? props.foo : props.bar; + let t1; + if ($[0] !== t0) { + t1 = { bar: t0 }; + $[0] = t0; + $[1] = t1; + } else { + t1 = $[1]; + } + let t2; + if ($[2] !== props || $[3] !== t1) { + t2 = ; + $[2] = props; + $[3] = t1; + $[4] = t2; + } else { + t2 = $[4]; + } + return t2; + } + + ``` +  + +FAIL: jsx-reactive-local-variable-member-expr +- Expected ++ Received + + + ## Input + + ```javascript + import * as sharedRuntime from 'shared-runtime'; + + function Component({something}: {something: {StaticText1: React.ElementType}}) { + const Foo = something.StaticText1; + return () => ; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{something: sharedRuntime}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import * as sharedRuntime from "shared-runtime"; + + function Component(t0) { + const $ = _c(2); ++ Object.freeze(t0); + const { something } = t0; + const Foo = something.StaticText1; + let t1; + if ($[0] !== Foo) { + t1 = () => ; + $[0] = Foo; + $[1] = t1; + } else { + t1 = $[1]; + } + return t1; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ something: sharedRuntime }], + }; + + ``` +  + ### Eval output + (kind: ok) "[[ function params=0 ]]" + +FAIL: jsx-namespaced-name +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + return ; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(2); ++ Object.freeze(props); + let t0; + if ($[0] !== props.version) { +- t0 = ; ++ t0 = ( ++  ++ ); + $[0] = props.version; + $[1] = t0; + } else { + t0 = $[1]; + } + return t0; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: jsx-memberexpr-tag-in-lambda + >> Unexpected error during test: + + +Found differences in evaluator results +Non-forget (expected): +(kind: ok)
4
+Forget: +(kind: ok)
+logs: ['Warning: Functions are not valid as a React child. This may happen if you return %s instead of <%s /> from render. Or maybe you meant to call this function rather than return it.\n' + + ' <%s>{%s}%s','value','value','div','value','div','\n' + + ' at div\n' + + ' at Text (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/shared-runtime.js:183:61)\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)'] + +FAIL: jsx-member-expression +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + return ( +  +  +  + ); + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(1); ++ Object.freeze(props); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = ( +  +  +  + ); + $[0] = t0; + } else { + t0 = $[0]; + } + return t0; + } + + ``` +  + +FAIL: jsx-member-expression-tag-grouping +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + const maybeMutable = new MaybeMutable(); + return {maybeMutate(maybeMutable)}; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(1); ++ Object.freeze(props); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + const maybeMutable = new MaybeMutable(); + t0 = {maybeMutate(maybeMutable)}; + $[0] = t0; + } else { + t0 = $[0]; + } + return t0; + } + + ``` +  + +FAIL: jsx-local-tag-in-lambda + >> Unexpected error during test: + + +Found differences in evaluator results +Non-forget (expected): +(kind: ok)
{"value":4}
+Forget: +(kind: ok)
{"value":"[[ function params=0 ]]"}
+ +FAIL: jsx-local-memberexpr-tag + >> Unexpected error during test: + + +Found differences in evaluator results +Non-forget (expected): +(kind: ok)
4
+Forget: +(kind: ok)
+logs: ['Warning: Functions are not valid as a React child. This may happen if you return %s instead of <%s /> from render. Or maybe you meant to call this function rather than return it.\n' + + ' <%s>{%s}%s','value','value','div','value','div','\n' + + ' at div\n' + + ' at Text (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/shared-runtime.js:183:61)\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)'] + +FAIL: jsx-local-memberexpr-tag-conditional + >> Unexpected error during test: + + +Found differences in evaluator results +Non-forget (expected): +(kind: ok)
4
+Forget: +(kind: ok)
+logs: ['Warning: Functions are not valid as a React child. This may happen if you return %s instead of <%s /> from render. Or maybe you meant to call this function rather than return it.\n' + + ' <%s>{%s}%s','value','value','div','value','div','\n' + + ' at div\n' + + ' at Text (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/shared-runtime.js:183:61)\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)'] + +FAIL: jsx-freeze +- Expected ++ Received + + + ## Input + + ```javascript + import {jsx as _jsx} from 'react/jsx-runtime'; + import {shallowCopy} from 'shared-runtime'; + + function Component(props) { + const childprops = {style: {width: props.width}}; + const element = _jsx('div', { + childprops: childprops, + children: '"hello world"', + }); + shallowCopy(childprops); // function that in theory could mutate, we assume not bc createElement freezes + return element; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { jsx as _jsx } from "react/jsx-runtime"; + import { shallowCopy } from "shared-runtime"; + + function Component(props) { + const $ = _c(2); ++ Object.freeze(props); + let element; + if ($[0] !== props.width) { + const childprops = { style: { width: props.width } }; + element = _jsx("div", { childprops, children: '"hello world"' }); + shallowCopy(childprops); + $[0] = props.width; + $[1] = element; + } else { + element = $[1]; + } + return element; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + }; + + ``` +  + ### Eval output + (kind: ok)
"hello world"
 + +FAIL: jsx-fragment +- Expected ++ Received + + + ## Input + + ```javascript + function Foo(props) { + return ( + <> + Hello {props.greeting}{' '} +
 + <>Text +
 +  + ); + } + + export const FIXTURE_ENTRYPOINT = { + fn: Foo, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Foo(props) { + const $ = _c(3); ++ Object.freeze(props); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = ( +
 + <>Text +
 + ); + $[0] = t0; + } else { + t0 = $[0]; + } + let t1; + if ($[1] !== props.greeting) { + t1 = ( + <> + Hello {props.greeting} {t0} +  + ); + $[1] = props.greeting; + $[2] = t1; + } else { + t1 = $[2]; + } + return t1; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Foo, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: jsx-empty-expression +- Expected ++ Received + + + ## Input + + ```javascript + export function Component(props) { + return ( +
 + {} + {props.a} +
 + ); + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{a: 'hello'}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + export function Component(props) { + const $ = _c(2); ++ Object.freeze(props); + let t0; + if ($[0] !== props.a) { + t0 =
{props.a}
; + $[0] = props.a; + $[1] = t0; + } else { + t0 = $[1]; + } + return t0; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ a: "hello" }], + }; + + ``` +  + +FAIL: jsx-attribute-with-jsx-fragment-value.flow + >> Unexpected error during test: + + +Found differences in evaluator results +Non-forget (expected): +(kind: ok)
{"item":{"id":1,"name":"One!"}}
+Forget: +(kind: ok)
+logs: ['Warning: Functions are not valid as a React child. This may happen if you return %s instead of <%s /> from render. Or maybe you meant to call this function rather than return it.\n' + + ' <%s>{%s}%s','value','value','div','value','div','\n' + + ' at div\n' + + ' at Foo (eval at doEval (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:200:28), :58:36)\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)'] + +FAIL: jsx-attribute-with-jsx-element-value + >> Unexpected error during test: + + +Found differences in evaluator results +Non-forget (expected): +(kind: ok)
One!
+Forget: +(kind: ok) +logs: ['Warning: Functions are not valid as a React child. This may happen if you return %s instead of <%s /> from render. Or maybe you meant to call this function rather than return it.\n' + + ' <%s>{%s}%s','value','value','Foo','value','Foo','\n' + + ' at Foo (eval at doEval (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:200:28), :59:5)\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)'] + +FAIL: jsx-attribute-default-to-true + >> Unexpected error during test: + + +Found differences in evaluator results +Non-forget (expected): +(kind: ok)
{"truthyAttribute":true}
+Forget: +(kind: ok)
{"truthyAttribute":"[[ function params=0 ]]"}
+ +FAIL: issue933-disjoint-set-infinite-loop +- Expected ++ Received + + + ## Input + + ```javascript + function makeObj() { + 'use no forget'; + const result = []; + result.a = {b: 2}; + + return result; + } + + // 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; + } + + export const FIXTURE_ENTRYPOINT = { + fn: MyApp, + params: [], + isComponent: false, + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function makeObj() { + "use no forget"; + const result = []; + result.a = { b: 2 }; + + return result; + } + + // This caused an infinite loop in the compiler + function MyApp(props) { + const $ = _c(1); ++ Object.freeze(props); + let y; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + y = makeObj(); + const tmp = y.a; + const tmp2 = tmp.b; + y.push(tmp2); + $[0] = y; + } else { + y = $[0]; + } + return y; + } + + export const FIXTURE_ENTRYPOINT = { + fn: MyApp, + params: [], + isComponent: false, + }; + + ``` +  + ### Eval output + (kind: ok) [2] + +FAIL: issue852 +- Expected ++ Received + + + ## Input + + ```javascript + function Component(c) { + let x = {c}; + mutate(x); + let a = x; + let b = a; + } + + ``` + + ## Code + + ```javascript + function Component(c) { ++ Object.freeze(c); + const x = { c }; + mutate(x); + } + + ``` +  + +FAIL: inverted-if +- Expected ++ Received + + + ## Input + + ```javascript + function foo(a, b, c, d) { + let y = []; + label: if (a) { + if (b) { + y.push(c); + break label; + } + y.push(d); + } + return y; + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function foo(a, b, c, d) { + const $ = _c(5); ++ Object.freeze(a); ++ Object.freeze(b); ++ Object.freeze(c); ++ Object.freeze(d); + let y; + if ($[0] !== a || $[1] !== b || $[2] !== c || $[3] !== d) { + y = []; + bb0: if (a) { + if (b) { + y.push(c); + break bb0; + } + + y.push(d); + } + $[0] = a; + $[1] = b; + $[2] = c; + $[3] = d; + $[4] = y; + } else { + y = $[4]; + } + return y; + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: inverted-if-else +- Expected ++ Received + + + ## Input + + ```javascript + function foo(a, b, c) { + let x = null; + label: { + if (a) { + x = b; + break label; + } + x = c; + } + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + function foo(a, b, c) { ++ Object.freeze(a); ++ Object.freeze(b); ++ Object.freeze(c); + let x; + bb0: { + if (a) { + x = b; + break bb0; + } + + x = c; + } + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: interdependent +- Expected ++ Received + + + ## Input + + ```javascript + /** + * 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() {} + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; /** + * 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 $ = _c(7); ++ Object.freeze(props); + let a; + let b; + if ($[0] !== props.a || $[1] !== props.b) { + a = compute(props.a); + b = compute(props.b); + foo(a, b); + $[0] = props.a; + $[1] = props.b; + $[2] = a; + $[3] = b; + } else { + a = $[2]; + b = $[3]; + } + let t0; + if ($[4] !== a || $[5] !== b) { +- t0 = ; ++ t0 = ( ++  ++ ); + $[4] = a; + $[5] = b; + $[6] = t0; + } else { + t0 = $[6]; + } + return t0; + } + + function compute() {} + function foo() {} + function Foo() {} + + ``` +  + +FAIL: interdependent-across-if +- Expected ++ Received + + + ## Input + + ```javascript + 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 ; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + 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 $ = _c(8); ++ Object.freeze(props); + let a; + let b; + if ($[0] !== props.a || $[1] !== props.b || $[2] !== props.c) { + a = compute(props.a); + b = compute(props.b); + if (props.c) { + foo(a, b); + } + $[0] = props.a; + $[1] = props.b; + $[2] = props.c; + $[3] = a; + $[4] = b; + } else { + a = $[3]; + b = $[4]; + } + let t0; + if ($[5] !== a || $[6] !== b) { +- t0 = ; ++ t0 = ( ++  ++ ); + $[5] = a; + $[6] = b; + $[7] = t0; + } else { + t0 = $[7]; + } + return t0; + } + + ``` +  + +FAIL: inner-memo-value-not-promoted-to-outer-scope-static +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + const count = new MaybeMutable(); + return ( +  +  + {Text} + {{maybeMutate(count)}} +  +  + ); + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(1); ++ Object.freeze(props); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + const count = new MaybeMutable(); + + t0 = ( +  +  + Text + {maybeMutate(count)} +  +  + ); + $[0] = t0; + } else { + t0 = $[0]; + } + return t0; + } + + ``` +  + +FAIL: inner-memo-value-not-promoted-to-outer-scope-dynamic +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + const item = useFragment(FRAGMENT, props.item); + useFreeze(item); + + const count = new MaybeMutable(item); + return ( +  +  + {Text} + {{maybeMutate(count)}} +  +  + ); + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(15); +- const item = useFragment(FRAGMENT, props.item); +- useFreeze(item); ++ Object.freeze(props); ++ const item = (function () { ++ const $res$ = useFragment( ++ Object.freeze(FRAGMENT), ++ Object.freeze(props.item), ++ ); ++ Object.freeze($res$); ++ return $res$; ++ })(); ++ (function () { ++ const $res$ = useFreeze(Object.freeze(item)); ++ Object.freeze($res$); ++ return $res$; ++ })(); + let t0; + let T0; + let t1; + let T1; + if ($[0] !== item) { + const count = new MaybeMutable(item); + + T1 = View; + T0 = View; + if ($[5] === Symbol.for("react.memo_cache_sentinel")) { + t1 = Text; + $[5] = t1; + } else { + t1 = $[5]; + } + t0 = maybeMutate(count); + $[0] = item; + $[1] = t0; + $[2] = T0; + $[3] = t1; + $[4] = T1; + } else { + t0 = $[1]; + T0 = $[2]; + t1 = $[3]; + T1 = $[4]; + } + let t2; + if ($[6] !== t0) { + t2 = {t0}; + $[6] = t0; + $[7] = t2; + } else { + t2 = $[7]; + } + let t3; + if ($[8] !== T0 || $[9] !== t1 || $[10] !== t2) { + t3 = ( +  + {t1} + {t2} +  + ); + $[8] = T0; + $[9] = t1; + $[10] = t2; + $[11] = t3; + } else { + t3 = $[11]; + } + let t4; + if ($[12] !== T1 || $[13] !== t3) { + t4 = {t3}; + $[12] = T1; + $[13] = t3; + $[14] = t4; + } else { + t4 = $[14]; + } + return t4; + } + + ``` +  + +FAIL: infer-types-through-type-cast.flow +- Expected ++ Received + + + ## Input + + ```javascript + // @flow + import {getNumber} from 'shared-runtime'; + + 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 = getNumber(); + const y = (x: any); + y + 1; + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + isComponent: false, + }; + + ``` + + ## Code + + ```javascript + import { getNumber } from "shared-runtime"; + + function Component(props) { ++ Object.freeze(props); ++ + const x = getNumber(); + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + isComponent: false, + }; + + ``` +  + ### Eval output + (kind: ok) 4 + +FAIL: infer-property-delete +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + const x = makeObject(); + const y = delete x.value; + return y; + } + + ``` + + ## Code + + ```javascript + function Component(props) { ++ Object.freeze(props); + const x = makeObject(); + const y = delete x.value; + return y; + } + + ``` +  + +FAIL: infer-phi-primitive +- Expected ++ Received + + + ## Input + + ```javascript + function foo(a, b) { + let x; + if (a) { + x = 1; + } else { + x = 2; + } + + let y = x; + return y; + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: [true, false], + isComponent: false, + }; + + ``` + + ## Code + + ```javascript + function foo(a, b) { ++ Object.freeze(a); ++ Object.freeze(b); + let x; + if (a) { + x = 1; + } else { + x = 2; + } + + const y = x; + return y; + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: [true, false], + isComponent: false, + }; + + ``` +  + ### Eval output + (kind: ok) 1 + +FAIL: infer-global-object +- Expected ++ Received + + + ## Input + + ```javascript + import {identity, sum} from 'shared-runtime'; + + // Check that we correctly resolve type and effect lookups on the javascript + // global object. + function Component(props) { + let neverAliasedOrMutated = identity(props.b); + let primitiveVal1 = Math.max(props.a, neverAliasedOrMutated); + let primitiveVal2 = Infinity; + let primitiveVal3 = globalThis.globalThis.NaN; + + // Even though we don't know the function signature of sum, + // we should be able to infer that it does not mutate its inputs. + sum(primitiveVal1, primitiveVal2, primitiveVal3); + return {primitiveVal1, primitiveVal2, primitiveVal3}; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{a: 1, b: 2}], + isComponent: false, + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { identity, sum } from "shared-runtime"; + + // Check that we correctly resolve type and effect lookups on the javascript + // global object. + function Component(props) { + const $ = _c(4); ++ Object.freeze(props); + let t0; + if ($[0] !== props.b) { + t0 = identity(props.b); + $[0] = props.b; + $[1] = t0; + } else { + t0 = $[1]; + } + const neverAliasedOrMutated = t0; + const primitiveVal1 = Math.max(props.a, neverAliasedOrMutated); + + const primitiveVal3 = globalThis.globalThis.NaN; + + sum(primitiveVal1, Infinity, primitiveVal3); + let t1; + if ($[2] !== primitiveVal1) { + t1 = { primitiveVal1, primitiveVal2: Infinity, primitiveVal3 }; + $[2] = primitiveVal1; + $[3] = t1; + } else { + t1 = $[3]; + } + return t1; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ a: 1, b: 2 }], + isComponent: false, + }; + + ``` +  + ### Eval output + (kind: ok) {"primitiveVal1":2,"primitiveVal2":null,"primitiveVal3":null} + +FAIL: infer-functions-hook-with-jsx +- Expected ++ Received + + + ## Input + + ```javascript + // @compilationMode(infer) + function useDiv(props) { + return
; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; // @compilationMode(infer) + function useDiv(props) { + const $ = _c(1); ++ Object.freeze(props); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 =
; + $[0] = t0; + } else { + t0 = $[0]; + } + return t0; + } + + ``` +  + +FAIL: infer-functions-hook-with-hook-call +- Expected ++ Received + + + ## Input + + ```javascript + // @compilationMode(infer) + function useStateValue(props) { + const [state, _] = useState(null); + return [state]; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; // @compilationMode(infer) + function useStateValue(props) { + const $ = _c(2); +- const [state] = useState(null); ++ Object.freeze(props); ++ const [state] = (function () { ++ const $res$ = useState(Object.freeze(null)); ++ Object.freeze($res$); ++ return $res$; ++ })(); + let t0; + if ($[0] !== state) { + t0 = [state]; + $[0] = state; + $[1] = t0; + } else { + t0 = $[1]; + } + return t0; + } + + ``` +  + +FAIL: infer-functions-component-with-ref-arg +- Expected ++ Received + + + ## Input + + ```javascript + // @compilationMode(infer) + + function Foo({}, ref) { + return
; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Foo, + params: [{}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; // @compilationMode(infer) + + function Foo(t0, ref) { + const $ = _c(2); ++ Object.freeze(t0); ++ Object.freeze(ref); + let t1; + if ($[0] !== ref) { +- t1 =
; ++ t1 = ( ++  ++ ); + $[0] = ref; + $[1] = t1; + } else { + t1 = $[1]; + } + return t1; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Foo, + params: [{}], + }; + + ``` +  + ### Eval output + (kind: ok)
 + +FAIL: infer-functions-component-with-jsx +- Expected ++ Received + + + ## Input + + ```javascript + // @compilationMode(infer) + function Component(props) { + return
; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; // @compilationMode(infer) + function Component(props) { + const $ = _c(1); ++ Object.freeze(props); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 =
; + $[0] = t0; + } else { + t0 = $[0]; + } + return t0; + } + + ``` +  + +FAIL: infer-functions-component-with-hook-call +- Expected ++ Received + + + ## Input + + ```javascript + // @compilationMode(infer) + function Component(props) { + const [state, _] = useState(null); + return [state]; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; // @compilationMode(infer) + function Component(props) { + const $ = _c(2); +- const [state] = useState(null); ++ Object.freeze(props); ++ const [state] = (function () { ++ const $res$ = useState(Object.freeze(null)); ++ Object.freeze($res$); ++ return $res$; ++ })(); + let t0; + if ($[0] !== state) { + t0 = [state]; + $[0] = state; + $[1] = t0; + } else { + t0 = $[1]; + } + return t0; + } + + ``` +  + +FAIL: infer-function-forwardRef +- Expected ++ Received + + + ## Input + + ```javascript + // @compilationMode(infer) + React.forwardRef(props => { + return
; + }); + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; // @compilationMode(infer) + React.forwardRef((props) => { + const $ = _c(1); ++ Object.freeze(props); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 =
; + $[0] = t0; + } else { + t0 = $[0]; + } + return t0; + }); + + ``` +  + +FAIL: infer-function-expression-component +- Expected ++ Received + + + ## Input + + ```javascript + // @compilationMode(infer) + + const Component = function ComponentName(props) { + return ; + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; // @compilationMode(infer) + + const Component = function ComponentName(props) { + const $ = _c(1); ++ Object.freeze(props); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = ; + $[0] = t0; + } else { + t0 = $[0]; + } + return t0; + }; + + ``` +  + +FAIL: infer-function-expression-React-memo-gating +- Expected ++ Received + + + ## Input + + ```javascript + // @gating @compilationMode(infer) + import React from 'react'; + export default React.forwardRef(function notNamedLikeAComponent(props) { + return
; + }); + + ``` + + ## Code + + ```javascript + import { isForgetEnabled_Fixtures } from "ReactForgetFeatureFlag"; + import { c as _c } from "react/compiler-runtime"; // @gating @compilationMode(infer) + import React from "react"; + export default React.forwardRef( + isForgetEnabled_Fixtures() + ? function notNamedLikeAComponent(props) { + const $ = _c(1); ++ Object.freeze(props); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 =
; + $[0] = t0; + } else { + t0 = $[0]; + } + return t0; + } + : function notNamedLikeAComponent(props) { + return
; + }, + ); + + ``` +  + +FAIL: infer-function-assignment +- Expected ++ Received + + + ## Input + + ```javascript + // @compilationMode(infer) + const Component = props => { + return
; + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; // @compilationMode(infer) + const Component = (props) => { + const $ = _c(1); ++ Object.freeze(props); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 =
; + $[0] = t0; + } else { + t0 = $[0]; + } + return t0; + }; + + ``` +  + +FAIL: infer-function-React-memo +- Expected ++ Received + + + ## Input + + ```javascript + // @compilationMode(infer) + React.memo(props => { + return
; + }); + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; // @compilationMode(infer) + React.memo((props) => { + const $ = _c(1); ++ Object.freeze(props); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 =
; + $[0] = t0; + } else { + t0 = $[0]; + } + return t0; + }); + + ``` +  + +FAIL: infer-computed-delete +- Expected ++ Received + + + ## Input + + ```javascript + // @debug + function Component(props) { + const x = makeObject(); + const y = delete x[props.value]; + return y; + } + + ``` + + ## Code + + ```javascript + // @debug + function Component(props) { ++ Object.freeze(props); + const x = makeObject(); + const y = delete x[props.value]; + return y; + } + + ``` +  + +FAIL: infer-compile-hooks-with-multiple-params +- Expected ++ Received + + + ## Input + + ```javascript + // @compilationMode(infer) + import {useNoAlias} from 'shared-runtime'; + + // This should be compiled by Forget + function useFoo(value1, value2) { + return { + value: useNoAlias(value1 + value2), + }; + } + + export const FIXTURE_ENTRYPOINT = { + fn: useFoo, + params: [1, 2], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; // @compilationMode(infer) + import { useNoAlias } from "shared-runtime"; + + // This should be compiled by Forget + function useFoo(value1, value2) { + const $ = _c(2); ++ Object.freeze(value1); ++ Object.freeze(value2); + +- const t0 = useNoAlias(value1 + value2); ++ const t0 = (function () { ++ const $res$ = useNoAlias(Object.freeze(value1 + value2)); ++ Object.freeze($res$); ++ return $res$; ++ })(); + let t1; + if ($[0] !== t0) { + t1 = { value: t0 }; + $[0] = t0; + $[1] = t1; + } else { + t1 = $[1]; + } + return t1; + } + + export const FIXTURE_ENTRYPOINT = { + fn: useFoo, + params: [1, 2], + }; + + ``` +  + ### Eval output + (kind: ok) {"value":{}} + +FAIL: independently-memoize-object-property +- Expected ++ Received + + + ## Input + + ```javascript + 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; + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function foo(a, b, c) { + const $ = _c(7); ++ Object.freeze(a); ++ Object.freeze(b); ++ Object.freeze(c); + let x; + if ($[0] !== a || $[1] !== b || $[2] !== c) { + x = { a }; + let t0; + if ($[4] !== b || $[5] !== c) { + t0 = [b, c]; + $[4] = b; + $[5] = c; + $[6] = t0; + } else { + t0 = $[6]; + } + x.y = t0; + $[0] = a; + $[1] = b; + $[2] = c; + $[3] = x; + } else { + x = $[3]; + } + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: independent +- Expected ++ Received + + + ## Input + + ```javascript + /** + * 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() {} + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; /** + * 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 $ = _c(7); ++ Object.freeze(props); + let t0; + if ($[0] !== props.a) { + t0 = compute(props.a); + $[0] = props.a; + $[1] = t0; + } else { + t0 = $[1]; + } + const a = t0; + let t1; + if ($[2] !== props.b) { + t1 = compute(props.b); + $[2] = props.b; + $[3] = t1; + } else { + t1 = $[3]; + } + const b = t1; + let t2; + if ($[4] !== a || $[5] !== b) { +- t2 = ; ++ t2 = ( ++  ++ ); + $[4] = a; + $[5] = b; + $[6] = t2; + } else { + t2 = $[6]; + } + return t2; + } + + function compute() {} + function foo() {} + function Foo() {} + + ``` +  + +FAIL: independent-across-if +- Expected ++ Received + + + ## Input + + ```javascript + 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 ; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + 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 $ = _c(8); ++ Object.freeze(props); + let a; + let b; + if ($[0] !== props.a || $[1] !== props.b || $[2] !== props.c) { + a = compute(props.a); + b = compute(props.b); + if (props.c) { + mutate(a); + mutate(b); + } + $[0] = props.a; + $[1] = props.b; + $[2] = props.c; + $[3] = a; + $[4] = b; + } else { + a = $[3]; + b = $[4]; + } + let t0; + if ($[5] !== a || $[6] !== b) { +- t0 = ; ++ t0 = ( ++  ++ ); + $[5] = a; + $[6] = b; + $[7] = t0; + } else { + t0 = $[7]; + } + return t0; + } + + ``` +  + +FAIL: incompatible-destructuring-kinds + >> Unexpected error during test: + + +Found differences in evaluator results +Non-forget (expected): +(kind: ok)
{"a":null,"b":"[[ cyclic ref *1 ]]","onClick":"[[ function params=0 ]]"}
+Forget: +(kind: ok)
{"a":"[[ function params=0 ]]","b":"[[ function params=0 ]]","onClick":"[[ function params=0 ]]"}
+ +FAIL: inadvertent-mutability-readonly-lambda +- Expected ++ Received + + + ## Input + + ```javascript + 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; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(2); +- const [value, setValue] = useState(null); ++ Object.freeze(props); ++ const [value, setValue] = (function () { ++ const $res$ = useState(Object.freeze(null)); ++ Object.freeze($res$); ++ return $res$; ++ })(); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = (e) => setValue((value_0) => value_0 + e.target.value); + $[0] = t0; + } else { + t0 = $[0]; + } + const onChange = t0; +- +- useOtherHook(); ++ (function () { ++ const $res$ = useOtherHook(); ++ Object.freeze($res$); ++ return $res$; ++ })(); + let x; + if ($[1] === Symbol.for("react.memo_cache_sentinel")) { + x = {}; + foo(x, onChange); + $[1] = x; + } else { + x = $[1]; + } + return x; + } + + ``` +  + +FAIL: inadvertent-mutability-readonly-class +- Expected ++ Received + + + ## Input + + ```javascript + 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 {} + + ``` + + ## Code + + ```javascript + function Component(props) { +- const env = useRelayEnvironment(); ++ Object.freeze(props); ++ const env = (function () { ++ const $res$ = useRelayEnvironment(); ++ Object.freeze($res$); ++ return $res$; ++ })(); + + const mutator = new Mutator(env); +- +- useOtherHook(); ++ (function () { ++ const $res$ = useOtherHook(); ++ Object.freeze($res$); ++ return $res$; ++ })(); + + const x = {}; + foo(x, mutator); + return x; + } + + class Mutator {} + + ``` +  + +FAIL: immutable-hooks +- Expected ++ Received + + + ## Input + + ```javascript + // @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]; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; // @enableAssumeHooksFollowRulesOfReact true + function Component(props) { + const $ = _c(3); ++ Object.freeze(props); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = {}; + $[0] = t0; + } else { + t0 = $[0]; + } + const x = t0; + +- const y = useFoo(x); ++ const y = (function () { ++ const $res$ = useFoo(Object.freeze(x)); ++ Object.freeze($res$); ++ return $res$; ++ })(); + + bar(x, y); + let t1; + if ($[1] !== y) { + t1 = [x, y]; + $[1] = y; + $[2] = t1; + } else { + t1 = $[2]; + } + return t1; + } + + ``` +  + +FAIL: iife-return-modified-later +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + const items = (() => { + return []; + })(); + items.push(props.a); + return items; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{a: {}}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(3); ++ Object.freeze(props); + let t0; + let items; + if ($[0] !== props.a) { + t0 = []; + items = t0; + + items.push(props.a); + $[0] = props.a; + $[1] = items; + $[2] = t0; + } else { + items = $[1]; + t0 = $[2]; + } + return items; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ a: {} }], + }; + + ``` +  + ### Eval output + (kind: ok) [{}] + +FAIL: iife-return-modified-later-phi +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + const items = (() => { + if (props.cond) { + return []; + } else { + return null; + } + })(); + items?.push(props.a); + return items; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{a: {}}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(2); ++ Object.freeze(props); + let items; + if ($[0] !== props) { + let t0; + if (props.cond) { + t0 = []; + } else { + t0 = null; + } + items = t0; + + items?.push(props.a); + $[0] = props; + $[1] = items; + } else { + items = $[1]; + } + return items; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ a: {} }], + }; + + ``` +  + ### Eval output + (kind: ok) null + +FAIL: ignore-use-no-forget +- Expected ++ Received + + + ## Input + + ```javascript + // @ignoreUseNoForget + function Component(prop) { + 'use no forget'; + const result = prop.x.toFixed(); + return
{result}
; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{x: 1}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; // @ignoreUseNoForget + function Component(prop) { +- "use no forget"; + const $ = _c(4); ++ Object.freeze(prop); + let t0; + if ($[0] !== prop.x) { + t0 = prop.x.toFixed(); + $[0] = prop.x; + $[1] = t0; + } else { + t0 = $[1]; + } + const result = t0; + let t1; + if ($[2] !== result) { + t1 =
{result}
; + $[2] = result; + $[3] = t1; + } else { + t1 = $[3]; + } + return t1; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ x: 1 }], + }; + + ``` +  + ### Eval output + (kind: ok)
1
 + +FAIL: idx-no-outlining +- Expected ++ Received + + + ## Input + + ```javascript + // @customMacros(idx) + import idx from 'idx'; + + function Component(props) { + // the lambda should not be outlined + const groupName = idx(props, _ => _.group.label); + return
{groupName}
; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; // @customMacros(idx) + + function Component(props) { + var _ref2; + const $ = _c(4); ++ Object.freeze(props); + let t0; + if ($[0] !== props) { + var _ref; + + t0 = + (_ref = props) != null + ? (_ref = _ref.group) != null + ? _ref.label + : _ref + : _ref; + $[0] = props; + $[1] = t0; + } else { + t0 = $[1]; + } + const groupName = t0; + let t1; + if ($[2] !== groupName) { + t1 =
{groupName}
; + $[2] = groupName; + $[3] = t1; + } else { + t1 = $[3]; + } + return t1; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + }; + + ``` +  + ### Eval output + (kind: ok)
 + +FAIL: hooks-with-prefix +- Expected ++ Received + + + ## Input + + ```javascript + // @hookPattern:".*\b(use[^$]+)$" + + import * as React from 'react'; + import {makeArray, useHook} from 'shared-runtime'; + + const React$useState = React.useState; + const React$useMemo = React.useMemo; + const Internal$Reassigned$useHook = useHook; + + function Component() { + const [state, setState] = React$useState(0); + const object = Internal$Reassigned$useHook(); + const json = JSON.stringify(object); + const doubledArray = React$useMemo(() => { + return makeArray(state); + }, [state]); + return ( +
 + {doubledArray.join('')} + {json} +
 + ); + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; // @hookPattern:".*\b(use[^$]+)$" + + import * as React from "react"; + import { makeArray, useHook } from "shared-runtime"; + + const React$useState = React.useState; + const React$useMemo = React.useMemo; + const Internal$Reassigned$useHook = useHook; + + function Component() { + const $ = _c(8); +- const [state] = React$useState(0); +- const object = Internal$Reassigned$useHook(); ++ const [state] = (function () { ++ const $res$ = React$useState(Object.freeze(0)); ++ Object.freeze($res$); ++ return $res$; ++ })(); ++ const object = (function () { ++ const $res$ = Internal$Reassigned$useHook(); ++ Object.freeze($res$); ++ return $res$; ++ })(); + let t0; + if ($[0] !== object) { + t0 = JSON.stringify(object); + $[0] = object; + $[1] = t0; + } else { + t0 = $[1]; + } + const json = t0; + let t1; + let t2; + if ($[2] !== state) { + t1 = makeArray(state); + const doubledArray = t1; + + t2 = doubledArray.join(""); + $[2] = state; + $[3] = t2; + $[4] = t1; + } else { + t2 = $[3]; + t1 = $[4]; + } + let t3; + if ($[5] !== t2 || $[6] !== json) { + t3 = ( +
 + {t2} + {json} +
 + ); + $[5] = t2; + $[6] = json; + $[7] = t3; + } else { + t3 = $[7]; + } + return t3; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + }; + + ``` +  + ### Eval output + (kind: ok)
0{"a":0,"b":"value1","c":true}
 + +FAIL: hooks-with-React-namespace +- Expected ++ Received + + + ## Input + + ```javascript + function Component() { + const [x, setX] = React.useState(1); + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [], + }; + + ``` + + ## Code + + ```javascript + function Component() { +- const [x] = React.useState(1); ++ const [x] = (function () { ++ const $res$ = React.useState(Object.freeze(1)); ++ Object.freeze($res$); ++ return $res$; ++ })(); + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [], + }; + + ``` +  + ### Eval output + (kind: ok) 1 + +FAIL: hooks-freeze-possibly-mutable-arguments +- Expected ++ Received + + + ## Input + + ```javascript + 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) {} + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(1); ++ Object.freeze(props); + const cond = props.cond; + const x = props.x; + let a; + if (cond) { + a = x; + } else { + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = []; + $[0] = t0; + } else { + t0 = $[0]; + } + a = t0; + } +- +- useFreeze(a); +- useFreeze(a); ++ (function () { ++ const $res$ = useFreeze(Object.freeze(a)); ++ Object.freeze($res$); ++ return $res$; ++ })(); ++ (function () { ++ const $res$ = useFreeze(Object.freeze(a)); ++ Object.freeze($res$); ++ return $res$; ++ })(); + call(a); + return a; + } + +- function useFreeze(x) {} +- function call(x) {} ++ function useFreeze(x) { ++ Object.freeze(x); ++ } ++ function call(x) { ++ Object.freeze(x); ++ } + + ``` +  + +FAIL: hooks-freeze-arguments +- Expected ++ Received + + + ## Input + + ```javascript + 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) {} + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component() { + const $ = _c(1); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = []; + $[0] = t0; + } else { + t0 = $[0]; + } + const a = t0; +- useFreeze(a); +- useFreeze(a); ++ (function () { ++ const $res$ = useFreeze(Object.freeze(a)); ++ Object.freeze($res$); ++ return $res$; ++ })(); ++ (function () { ++ const $res$ = useFreeze(Object.freeze(a)); ++ Object.freeze($res$); ++ return $res$; ++ })(); + call(a); + return a; + } + +- function useFreeze(x) {} +- function call(x) {} ++ function useFreeze(x) { ++ Object.freeze(x); ++ } ++ function call(x) { ++ Object.freeze(x); ++ } + + ``` +  + +FAIL: hook-noAlias +- Expected ++ Received + + + ## Input + + ```javascript + import {useNoAlias} from 'shared-runtime'; + + function Component(props) { + const item = {a: props.a}; + const x = useNoAlias(item, () => { + console.log(props); + }, [props.a]); + return [x, item]; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{a: {id: 42}}], + isComponent: true, + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { useNoAlias } from "shared-runtime"; + + function Component(props) { + const $ = _c(5); ++ Object.freeze(props); + let t0; + if ($[0] !== props.a) { + t0 = { a: props.a }; + $[0] = props.a; + $[1] = t0; + } else { + t0 = $[1]; + } + const item = t0; +- const x = useNoAlias(item, () => { +- console.log(props); +- }, [props.a]); ++ const x = (function () { ++ const $res$ = useNoAlias( ++ Object.freeze(item), ++ Object.freeze(() => { ++ console.log(props); ++ }), ++ Object.freeze([props.a]), ++ ); ++ Object.freeze($res$); ++ return $res$; ++ })(); + let t1; + if ($[2] !== x || $[3] !== item) { + t1 = [x, item]; + $[2] = x; + $[3] = item; + $[4] = t1; + } else { + t1 = $[4]; + } + return t1; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ a: { id: 42 } }], + isComponent: true, + }; + + ``` +  + ### Eval output + (kind: ok) [{},{"a":{"id":42}}] + +FAIL: hook-inside-logical-expression +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + const user = + useFragment( + graphql` + fragment F on T { + id + } + `, + props.user + ) ?? {}; + return user.name; + } + + ``` + + ## Code + + ```javascript + function Component(props) { ++ Object.freeze(props); + const user = +- useFragment( +- graphql` +- fragment F on T { +- id +- } +- `, +- props.user, +- ) ?? {}; ++ (function () { ++ const $res$ = useFragment( ++ Object.freeze(graphql` ++ fragment F on T { ++ id ++ } ++ `), ++ Object.freeze(props.user), ++ ); ++ Object.freeze($res$); ++ return $res$; ++ })() ?? {}; + return user.name; + } + + ``` +  + +FAIL: hook-declaration-basic.flow +- Expected ++ Received + + + ## Input + + ```javascript + // @flow @compilationMode(infer) + export default hook useFoo(bar: number) { + return [bar]; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + export default function useFoo(bar) { + const $ = _c(2); ++ Object.freeze(bar); + let t0; + if ($[0] !== bar) { + t0 = [bar]; + $[0] = bar; + $[1] = t0; + } else { + t0 = $[1]; + } + return t0; + } + + ``` +  + +FAIL: hook-call +- Expected ++ Received + + + ## Input + + ```javascript + function useFreeze() {} + function foo() {} + + function Component(props) { + const x = []; + const y = useFreeze(x); + foo(y, x); + return ( +  + {x} + {y} +  + ); + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function useFreeze() {} + function foo() {} + + function Component(props) { + const $ = _c(3); ++ Object.freeze(props); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = []; + $[0] = t0; + } else { + t0 = $[0]; + } + const x = t0; +- const y = useFreeze(x); ++ const y = (function () { ++ const $res$ = useFreeze(Object.freeze(x)); ++ Object.freeze($res$); ++ return $res$; ++ })(); + foo(y, x); + let t1; + if ($[1] !== y) { + t1 = ( +  + {x} + {y} +  + ); + $[1] = y; + $[2] = t1; + } else { + t1 = $[2]; + } + return t1; + } + + ``` +  + +FAIL: holey-array +- Expected ++ Received + + + ## Input + + ```javascript + function t(props) { + let [, setstate] = useState(); + setstate(1); + return props.foo; + } + + export const FIXTURE_ENTRYPOINT = { + fn: t, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + function t(props) { +- const [, setstate] = useState(); ++ Object.freeze(props); ++ const [, setstate] = (function () { ++ const $res$ = useState(); ++ Object.freeze($res$); ++ return $res$; ++ })(); + setstate(1); + return props.foo; + } + + export const FIXTURE_ENTRYPOINT = { + fn: t, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: holey-array-pattern-dce +- Expected ++ Received + + + ## Input + + ```javascript + function t(props) { + let [, foo, bar] = props; + return foo; + } + + export const FIXTURE_ENTRYPOINT = { + fn: t, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + function t(props) { ++ Object.freeze(props); + const [, foo] = props; + return foo; + } + + export const FIXTURE_ENTRYPOINT = { + fn: t, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: holey-array-pattern-dce-2 +- Expected ++ Received + + + ## Input + + ```javascript + function t(props) { + let [foo, bar, ,] = props; + return foo; + } + + export const FIXTURE_ENTRYPOINT = { + fn: t, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + function t(props) { ++ Object.freeze(props); + const [foo] = props; + return foo; + } + + export const FIXTURE_ENTRYPOINT = { + fn: t, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: holey-array-expr +- Expected ++ Received + + + ## Input + + ```javascript + import {CONST_STRING0} from 'shared-runtime'; + + function t(props) { + let x = [, CONST_STRING0, props]; + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: t, + params: [{a: 1, b: 2}], + isComponent: false, + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { CONST_STRING0 } from "shared-runtime"; + + function t(props) { + const $ = _c(2); ++ Object.freeze(props); + let t0; + if ($[0] !== props) { + t0 = [, CONST_STRING0, props]; + $[0] = props; + $[1] = t0; + } else { + t0 = $[1]; + } + const x = t0; + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: t, + params: [{ a: 1, b: 2 }], + isComponent: false, + }; + + ``` +  + ### Eval output + (kind: ok) [null,"global string 0",{"a":1,"b":2}] + +FAIL: hoisting-within-lambda +- Expected ++ Received + + + ## Input + + ```javascript + function Component({}) { + const outer = () => { + const inner = () => { + return x; + }; + const x = 3; + return inner(); + }; + return
{outer()}
; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(t0) { + const $ = _c(1); ++ Object.freeze(t0); + const outer = _temp; + let t1; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t1 =
{outer()}
; + $[0] = t1; + } else { + t1 = $[0]; + } + return t1; + } + function _temp() { + const inner = () => x; + const x = 3; + return inner(); + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + }; + + ``` +  + ### Eval output + (kind: ok)
3
 + +FAIL: hoisting-recursive-call +- Expected ++ Received + + + ## Input + + ```javascript + function Foo({value}: {value: number}) { + const factorial = (x: number) => { + if (x <= 1) { + return 1; + } else { + return x * factorial(x - 1); + } + }; + + return factorial(value); + } + + export const FIXTURE_ENTRYPOINT = { + fn: Foo, + params: [{value: 3}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Foo(t0) { + const $ = _c(2); ++ Object.freeze(t0); + const { value } = t0; + let t1; + if ($[0] !== value) { + const factorial = (x) => { + if (x <= 1) { + return 1; + } else { + return x * factorial(x - 1); + } + }; + + t1 = factorial(value); + $[0] = value; + $[1] = t1; + } else { + t1 = $[1]; + } + return t1; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Foo, + params: [{ value: 3 }], + }; + + ``` +  + ### Eval output + (kind: ok) 6 + +FAIL: hoisting-recursive-call-within-lambda +- Expected ++ Received + + + ## Input + + ```javascript + function Foo({}) { + const outer = val => { + const fact = x => { + if (x <= 0) { + return 1; + } + return x * fact(x - 1); + }; + return fact(val); + }; + return outer(3); + } + + export const FIXTURE_ENTRYPOINT = { + fn: Foo, + params: [{}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Foo(t0) { + const $ = _c(1); ++ Object.freeze(t0); + const outer = _temp; + let t1; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t1 = outer(3); + $[0] = t1; + } else { + t1 = $[0]; + } + return t1; + } + function _temp(val) { + const fact = (x) => { + if (x <= 0) { + return 1; + } + return x * fact(x - 1); + }; + return fact(val); + } + + export const FIXTURE_ENTRYPOINT = { + fn: Foo, + params: [{}], + }; + + ``` +  + ### Eval output + (kind: ok) 6 + +FAIL: hoisting-nested-const-declaration-2 +- Expected ++ Received + + + ## Input + + ```javascript + function hoisting(cond) { + let items = []; + if (cond) { + const foo = () => { + items.push(bar()); + }; + const bar = () => true; + foo(); + } + return items; + } + + export const FIXTURE_ENTRYPOINT = { + fn: hoisting, + params: [true], + isComponent: false, + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function hoisting(cond) { + const $ = _c(2); ++ Object.freeze(cond); + let items; + if ($[0] !== cond) { + items = []; + if (cond) { + const foo = () => { + items.push(bar()); + }; + + const bar = _temp; + foo(); + } + $[0] = cond; + $[1] = items; + } else { + items = $[1]; + } + return items; + } + function _temp() { + return true; + } + + export const FIXTURE_ENTRYPOINT = { + fn: hoisting, + params: [true], + isComponent: false, + }; + + ``` +  + ### Eval output + (kind: ok) [true] + +FAIL: hoisting-nested-block-statements +- Expected ++ Received + + + ## Input + + ```javascript + import {print} from 'shared-runtime'; + + function hoisting(cond) { + if (cond) { + const x = 1; + print(x); + } + + const x = 2; + print(x); + } + + export const FIXTURE_ENTRYPOINT = { + fn: hoisting, + params: [false], + }; + + ``` + + ## Code + + ```javascript + import { print } from "shared-runtime"; + + function hoisting(cond) { ++ Object.freeze(cond); + if (cond) { + print(1); + } + + print(2); + } + + export const FIXTURE_ENTRYPOINT = { + fn: hoisting, + params: [false], + }; + + ``` +  + ### Eval output + (kind: ok)  + logs: [2] + +FAIL: hoisting-member-expression + >> Unexpected error during test: + + +Found differences in evaluator results +Non-forget (expected): +(kind: ok)
{"onClick":"[[ function params=1 ]]"}
+Forget: +(kind: ok)
{"onClick":"[[ function params=0 ]]"}
+ +FAIL: hoisting-computed-member-expression + >> Unexpected error during test: + + +Found differences in evaluator results +Non-forget (expected): +(kind: ok)
{"onClick":{"kind":"Function","result":1},"onClick2":{"kind":"Function","result":1},"shouldInvokeFns":true}
+Forget: +(kind: ok)
{"onClick":{"kind":"Function","result":{"kind":"Function","result":1}},"onClick2":{"kind":"Function","result":{"kind":"Function","result":1}},"shouldInvokeFns":{"kind":"Function","result":true}}
+ +FAIL: hoisted-declaration-with-scope +- Expected ++ Received + + + ## Input + + ```javascript + import {StaticText1, Stringify, identity, useHook} from 'shared-runtime'; + + /** + * `button` and `dispatcher` must end up in the same memo block. It would be + * invalid for `button` to take a dependency on `dispatcher` as dispatcher + * is created later. + */ + function useFoo({onClose}) { + const button = StaticText1 ?? ( + { + dispatcher.go('route2'); + }, + }} + /> + ); + + const dispatcher = useHook(); + + return button; + } + + export const FIXTURE_ENTRYPOINT = { + fn: useFoo, + params: [{onClose: identity()}], + }; + + ``` + + ## Code + + ```javascript + import { StaticText1, Stringify, identity, useHook } from "shared-runtime"; + + /** + * `button` and `dispatcher` must end up in the same memo block. It would be + * invalid for `button` to take a dependency on `dispatcher` as dispatcher + * is created later. + */ + function useFoo(t0) { ++ Object.freeze(t0); + const { onClose } = t0; + const button = StaticText1 ?? ( + { +- dispatcher.go("route2"); +- }, ++ primary={function () { ++ const $res$ = { label: identity("label"), onPress: onClose }; ++ Object.freeze($res$); ++ return $res$; ++ }} ++ secondary={function () { ++ const $res$ = { ++ onPress: () => { ++ dispatcher.go("route2"); ++ }, ++ }; ++ Object.freeze($res$); ++ return $res$; + }} + /> + ); + +- const dispatcher = useHook(); ++ const dispatcher = (function () { ++ const $res$ = useHook(); ++ Object.freeze($res$); ++ return $res$; ++ })(); + return button; + } + + export const FIXTURE_ENTRYPOINT = { + fn: useFoo, + params: [{ onClose: identity() }], + }; + + ``` +  + ### Eval output + (kind: ok) "[[ function params=1 ]]" + +FAIL: globals-dont-resolve-local-useState +- Expected ++ Received + + + ## Input + + ```javascript + import {useState as _useState, useCallback, useEffect} from 'react'; + import {ValidateMemoization} from 'shared-runtime'; + + function useState(value) { + const [state, setState] = _useState(value); + return [state, setState]; + } + + function Component() { + const [state, setState] = useState('hello'); + + return
setState('goodbye')}>{state}
; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { useState as _useState, useCallback, useEffect } from "react"; + import { ValidateMemoization } from "shared-runtime"; + + function useState(value) { + const $ = _c(2); +- const [state, setState] = _useState(value); ++ Object.freeze(value); ++ const [state, setState] = (function () { ++ const $res$ = _useState(Object.freeze(value)); ++ Object.freeze($res$); ++ return $res$; ++ })(); + let t0; + if ($[0] !== state) { + t0 = [state, setState]; + $[0] = state; + $[1] = t0; + } else { + t0 = $[1]; + } + return t0; + } + + function Component() { + const $ = _c(5); +- const [state, setState] = useState("hello"); ++ const [state, setState] = (function () { ++ const $res$ = useState(Object.freeze("hello")); ++ Object.freeze($res$); ++ return $res$; ++ })(); + let t0; + if ($[0] !== setState) { + t0 = () => setState("goodbye"); + $[0] = setState; + $[1] = t0; + } else { + t0 = $[1]; + } + let t1; + if ($[2] !== t0 || $[3] !== state) { +- t1 =
{state}
; ++ t1 = ( ++  ++ {state} ++
 ++ ); + $[2] = t0; + $[3] = state; + $[4] = t1; + } else { + t1 = $[4]; + } + return t1; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + }; + + ``` +  + ### Eval output + (kind: ok)
hello
 + +FAIL: globals-String +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + const x = {}; + const y = String(x); + return [x, y]; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(2); ++ Object.freeze(props); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = {}; + $[0] = t0; + } else { + t0 = $[0]; + } + const x = t0; + const y = String(x); + let t1; + if ($[1] === Symbol.for("react.memo_cache_sentinel")) { + t1 = [x, y]; + $[1] = t1; + } else { + t1 = $[1]; + } + return t1; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: globals-Number +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + const x = {}; + const y = Number(x); + return [x, y]; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(2); ++ Object.freeze(props); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = {}; + $[0] = t0; + } else { + t0 = $[0]; + } + const x = t0; + const y = Number(x); + let t1; + if ($[1] === Symbol.for("react.memo_cache_sentinel")) { + t1 = [x, y]; + $[1] = t1; + } else { + t1 = $[1]; + } + return t1; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: globals-Boolean +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + const x = {}; + const y = Boolean(x); + return [x, y]; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(2); ++ Object.freeze(props); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = {}; + $[0] = t0; + } else { + t0 = $[0]; + } + const x = t0; + const y = Boolean(x); + let t1; + if ($[1] === Symbol.for("react.memo_cache_sentinel")) { + t1 = [x, y]; + $[1] = t1; + } else { + t1 = $[1]; + } + return t1; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: global-jsx-tag-lowered-between-mutations +- Expected ++ Received + + + ## Input + + ```javascript + 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)}; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(1); ++ Object.freeze(props); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + const maybeMutable = new MaybeMutable(); + + t0 = {maybeMutate(maybeMutable)}; + $[0] = t0; + } else { + t0 = $[0]; + } + return t0; + } + + ``` +  + +FAIL: gating-with-hoisted-type-reference.flow +- Expected ++ Received + + + ## Input + + ```javascript + // @flow @gating + import {memo} from 'react'; + + type Props = React.ElementConfig; + + component Component(value: string) { + return
{value}
; + } + + export default memo(Component); + + ``` + + ## Code + + ```javascript + import { isForgetEnabled_Fixtures } from "ReactForgetFeatureFlag"; + import { c as _c } from "react/compiler-runtime"; + import { memo } from "react"; + + type Props = React.ElementConfig; + const Component = isForgetEnabled_Fixtures() + ? function Component(t0) { + const $ = _c(2); ++ Object.freeze(t0); + const { value } = t0; + let t1; + if ($[0] !== value) { + t1 =
{value}
; + $[0] = value; + $[1] = t1; + } else { + t1 = $[1]; + } + return t1; + } + : function Component({ value }: $ReadOnly<{ value: string }>) { + return
{value}
; + }; + + export default memo(Component); + + ``` +  + +FAIL: gating-test +- Expected ++ Received + + + ## Input + + ```javascript + // @gating @compilationMode(annotation) + function Bar(props) { + 'use forget'; + return
{props.bar}
; + } + + function NoForget(props) { + return {props.noForget}; + } + + function Foo(props) { + 'use forget'; + return {props.bar}; + } + + ``` + + ## Code + + ```javascript + import { isForgetEnabled_Fixtures } from "ReactForgetFeatureFlag"; + import { c as _c } from "react/compiler-runtime"; // @gating @compilationMode(annotation) + const Bar = isForgetEnabled_Fixtures() + ? function Bar(props) { +- "use forget"; + const $ = _c(2); ++ Object.freeze(props); + let t0; + if ($[0] !== props.bar) { + t0 =
{props.bar}
; + $[0] = props.bar; + $[1] = t0; + } else { + t0 = $[1]; + } + return t0; + } + : function Bar(props) { + "use forget"; + return
{props.bar}
; + }; + + function NoForget(props) { + return {props.noForget}; + } + const Foo = isForgetEnabled_Fixtures() + ? function Foo(props) { +- "use forget"; + const $ = _c(2); ++ Object.freeze(props); + let t0; + if ($[0] !== props.bar) { + t0 = {props.bar}; + $[0] = props.bar; + $[1] = t0; + } else { + t0 = $[1]; + } + return t0; + } + : function Foo(props) { + "use forget"; + return {props.bar}; + }; + + ``` +  + +FAIL: gating-test-export-function +- Expected ++ Received + + + ## Input + + ```javascript + // @gating @compilationMode(annotation) + 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}; + } + + ``` + + ## Code + + ```javascript + import { isForgetEnabled_Fixtures } from "ReactForgetFeatureFlag"; + import { c as _c } from "react/compiler-runtime"; // @gating @compilationMode(annotation) + export const Bar = isForgetEnabled_Fixtures() + ? function Bar(props) { +- "use forget"; + const $ = _c(2); ++ Object.freeze(props); + let t0; + if ($[0] !== props.bar) { + t0 =
{props.bar}
; + $[0] = props.bar; + $[1] = t0; + } else { + t0 = $[1]; + } + return t0; + } + : function Bar(props) { + "use forget"; + return
{props.bar}
; + }; + + export function NoForget(props) { + return {props.noForget}; + } + + export const Foo = isForgetEnabled_Fixtures() + ? function Foo(props) { +- "use forget"; + const $ = _c(2); ++ Object.freeze(props); + let t0; + if ($[0] !== props.bar) { + t0 = {props.bar}; + $[0] = props.bar; + $[1] = t0; + } else { + t0 = $[1]; + } + return t0; + } + : function Foo(props) { + "use forget"; + return {props.bar}; + }; + + ``` +  + +FAIL: gating-test-export-function-and-default +- Expected ++ Received + + + ## Input + + ```javascript + // @gating @compilationMode(annotation) + 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}; + } + + ``` + + ## Code + + ```javascript + import { isForgetEnabled_Fixtures } from "ReactForgetFeatureFlag"; + import { c as _c } from "react/compiler-runtime"; // @gating @compilationMode(annotation) + const Bar = isForgetEnabled_Fixtures() + ? function Bar(props) { +- "use forget"; + const $ = _c(2); ++ Object.freeze(props); + let t0; + if ($[0] !== props.bar) { + t0 =
{props.bar}
; + $[0] = props.bar; + $[1] = t0; + } else { + t0 = $[1]; + } + return t0; + } + : function Bar(props) { + "use forget"; + return
{props.bar}
; + }; + export default Bar; + + function NoForget(props) { + return {props.noForget}; + } + + export const Foo = isForgetEnabled_Fixtures() + ? function Foo(props) { +- "use forget"; + const $ = _c(2); ++ Object.freeze(props); + let t0; + if ($[0] !== props.bar) { + t0 = {props.bar}; + $[0] = props.bar; + $[1] = t0; + } else { + t0 = $[1]; + } + return t0; + } + : function Foo(props) { + "use forget"; + return {props.bar}; + }; + + ``` +  + +FAIL: gating-test-export-default-function +- Expected ++ Received + + + ## Input + + ```javascript + // @gating @compilationMode(annotation) + export default function Bar(props) { + 'use forget'; + return
{props.bar}
; + } + + function NoForget(props) { + return {props.noForget}; + } + + function Foo(props) { + 'use forget'; + return {props.bar}; + } + + ``` + + ## Code + + ```javascript + import { isForgetEnabled_Fixtures } from "ReactForgetFeatureFlag"; + import { c as _c } from "react/compiler-runtime"; // @gating @compilationMode(annotation) + const Bar = isForgetEnabled_Fixtures() + ? function Bar(props) { +- "use forget"; + const $ = _c(2); ++ Object.freeze(props); + let t0; + if ($[0] !== props.bar) { + t0 =
{props.bar}
; + $[0] = props.bar; + $[1] = t0; + } else { + t0 = $[1]; + } + return t0; + } + : function Bar(props) { + "use forget"; + return
{props.bar}
; + }; + export default Bar; + + function NoForget(props) { + return {props.noForget}; + } + const Foo = isForgetEnabled_Fixtures() + ? function Foo(props) { +- "use forget"; + const $ = _c(2); ++ Object.freeze(props); + let t0; + if ($[0] !== props.bar) { + t0 = {props.bar}; + $[0] = props.bar; + $[1] = t0; + } else { + t0 = $[1]; + } + return t0; + } + : function Foo(props) { + "use forget"; + return {props.bar}; + }; + + ``` +  + +FAIL: functionexpr–conditional-access +- Expected ++ Received + + + ## Input + + ```javascript + // @enableTreatFunctionDepsAsConditional + function Component(props) { + function getLength() { + return props.bar.length; + } + + return props.bar && getLength(); + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{bar: null}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; // @enableTreatFunctionDepsAsConditional + function Component(props) { + const $ = _c(5); ++ Object.freeze(props); + let t0; + if ($[0] !== props) { + t0 = function getLength() { + return props.bar.length; + }; + $[0] = props; + $[1] = t0; + } else { + t0 = $[1]; + } + const getLength = t0; + let t1; + if ($[2] !== props.bar || $[3] !== getLength) { + t1 = props.bar && getLength(); + $[2] = props.bar; + $[3] = getLength; + $[4] = t1; + } else { + t1 = $[4]; + } + return t1; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ bar: null }], + }; + + ``` +  + ### Eval output + (kind: ok) null + +FAIL: function-param-assignment-pattern +- Expected ++ Received + + + ## Input + + ```javascript + function Component(x = 'default', y = [{}]) { + return [x, y]; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(t0, t1) { + const $ = _c(5); ++ Object.freeze(t0); ++ Object.freeze(t1); + const x = t0 === undefined ? "default" : t0; + let t2; + if ($[0] !== t1) { + t2 = t1 === undefined ? [{}] : t1; + $[0] = t1; + $[1] = t2; + } else { + t2 = $[1]; + } + const y = t2; + let t3; + if ($[2] !== x || $[3] !== y) { + t3 = [x, y]; + $[2] = x; + $[3] = y; + $[4] = t3; + } else { + t3 = $[4]; + } + return t3; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: function-expression-with-store-to-parameter +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + const mutate = (object, key, value) => { + object.updated = true; + object[key] = value; + }; + const x = makeObject(props); + mutate(x); + return x; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(2); ++ Object.freeze(props); + const mutate = _temp; + let x; + if ($[0] !== props) { + x = makeObject(props); + mutate(x); + $[0] = props; + $[1] = x; + } else { + x = $[1]; + } + return x; + } + function _temp(object, key, value) { + object.updated = true; + object[key] = value; + } + + ``` +  + +FAIL: function-expression-prototype-call +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + const f = function () { + return
{props.name}
; + }; + return f.call(); + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{name: 'Jason'}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(4); ++ Object.freeze(props); + let t0; + if ($[0] !== props.name) { + t0 = function () { + return
{props.name}
; + }; + $[0] = props.name; + $[1] = t0; + } else { + t0 = $[1]; + } + const f = t0; + let t1; + if ($[2] !== f) { + t1 = f.call(); + $[2] = f; + $[3] = t1; + } else { + t1 = $[3]; + } + return t1; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ name: "Jason" }], + }; + + ``` +  + ### Eval output + (kind: ok)
Jason
 + +FAIL: function-expression-prototype-call-mutating + >> Unexpected error during test: + + +Found differences in evaluator results +Non-forget (expected): +(kind: ok)
{"inputs":["Lauren"],"output":["Lauren"]}
+
{"inputs":["Lauren"],"output":["Lauren"]}
+
{"inputs":["Jason"],"output":["Jason"]}
+Forget: +(kind: ok) [[ (exception in render) Error: Too many re-renders. React limits the number of renders to prevent an infinite loop. ]] +[[ (exception in render) Error: Too many re-renders. React limits the number of renders to prevent an infinite loop. ]] +[[ (exception in render) Error: Too many re-renders. React limits the number of renders to prevent an infinite loop. ]] + +FAIL: function-expression-maybe-mutates-hook-return-value +- Expected ++ Received + + + ## Input + + ```javascript + 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 ; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(4); +- const id = useSelectedEntitytId(); ++ Object.freeze(props); ++ const id = (function () { ++ const $res$ = useSelectedEntitytId(); ++ Object.freeze($res$); ++ return $res$; ++ })(); + let t0; + if ($[0] !== id) { + t0 = () => { + log(id); + }; + $[0] = id; + $[1] = t0; + } else { + t0 = $[1]; + } + const onLoad = t0; + let t1; + if ($[2] !== onLoad) { +- t1 = ; ++ t1 = ( ++  ++ ); + $[2] = onLoad; + $[3] = t1; + } else { + t1 = $[3]; + } + return t1; + } + + ``` +  + +FAIL: function-expression-captures-value-later-frozen-jsx +- Expected ++ Received + + + ## Input + + ```javascript + 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 ; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(3); ++ Object.freeze(props); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = {}; + $[0] = t0; + } else { + t0 = $[0]; + } + const x = t0; + let t1; + if ($[1] === Symbol.for("react.memo_cache_sentinel")) { + t1 = (e) => { + maybeMutate(x, e.target.value); + }; + $[1] = t1; + } else { + t1 = $[1]; + } + const onChange = t1; + if (props.cond) { + } + let t2; + if ($[2] === Symbol.for("react.memo_cache_sentinel")) { +- t2 = ; ++ t2 = ( ++  ++ ); + $[2] = t2; + } else { + t2 = $[2]; + } + return t2; + } + + ``` +  + +FAIL: function-expr-directive +- Expected ++ Received + + + ## Input + + ```javascript + function Component() { + 'use strict'; + let [count, setCount] = React.useState(0); + function update() { + 'worklet'; + setCount(count => count + 1); + } + return ; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [], + isComponent: true, + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component() { +- "use strict"; + const $ = _c(3); + +- const [count, setCount] = React.useState(0); ++ const [count, setCount] = (function () { ++ const $res$ = React.useState(Object.freeze(0)); ++ Object.freeze($res$); ++ return $res$; ++ })(); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = function update() { + "worklet"; + + setCount((count_0) => count_0 + 1); + }; + $[0] = t0; + } else { + t0 = $[0]; + } + const update = t0; + let t1; + if ($[1] !== count) { +- t1 = ; ++ t1 = ( ++  ++ {count} ++  ++ ); + $[1] = count; + $[2] = t1; + } else { + t1 = $[2]; + } + return t1; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [], + isComponent: true, + }; + + ``` +  + ### Eval output + (kind: ok)  + +FAIL: function-declaration-simple +- Expected ++ Received + + + ## Input + + ```javascript + function component(a) { + let t = {a}; + function x(p) { + p.foo(); + } + x(t); + return t; + } + + export const FIXTURE_ENTRYPOINT = { + fn: component, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function component(a) { + const $ = _c(3); ++ Object.freeze(a); + let t; + if ($[0] !== a) { + t = { a }; + let t0; + if ($[2] === Symbol.for("react.memo_cache_sentinel")) { + t0 = function x(p) { + p.foo(); + }; + $[2] = t0; + } else { + t0 = $[2]; + } + const x = t0; + + x(t); + $[0] = a; + $[1] = t; + } else { + t = $[1]; + } + return t; + } + + export const FIXTURE_ENTRYPOINT = { + fn: component, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: frozen-after-alias +- Expected ++ Received + + + ## Input + + ```javascript + 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) {} + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component() { + const $ = _c(1); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = []; + $[0] = t0; + } else { + t0 = $[0]; + } + const a = t0; + const b = a; +- useFreeze(a); ++ (function () { ++ const $res$ = useFreeze(Object.freeze(a)); ++ Object.freeze($res$); ++ return $res$; ++ })(); + foo(b); + return b; + } + + function useFreeze() {} +- function foo(x) {} ++ function foo(x) { ++ Object.freeze(x); ++ } + + ``` +  + +FAIL: for-with-assignment-as-update +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + let x = props.init; + for (let i = 0; i < 100; i = i + 1) { + x += i; + } + return [x]; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{init: 0}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(2); ++ Object.freeze(props); + let x = props.init; + for (let i = 0; i < 100; i = i + 1) { + x = x + i; + } + let t0; + if ($[0] !== x) { + t0 = [x]; + $[0] = x; + $[1] = t0; + } else { + t0 = $[1]; + } + return t0; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ init: 0 }], + }; + + ``` +  + ### Eval output + (kind: ok) [4950] + +FAIL: for-return +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + for (let i = 0; i < props.count; i++) { + return; + } + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + function Component(props) { ++ Object.freeze(props); + for (const i = 0; 0 < props.count; ) { + return; + } + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: for-of-nonmutating-loop-local-collection + >> Unexpected error during test: + + +Found differences in evaluator results +Non-forget (expected): +(kind: ok)
{"inputs":[1],"output":[1]}
{"inputs":[[1],0],"output":[0,1]}
+
{"inputs":[1],"output":[1]}
{"inputs":[[1],1],"output":[1,1]}
+
{"inputs":[0],"output":[0]}
{"inputs":[[0],1],"output":[1,0]}
+Forget: +(kind: ok) [[ (exception in render) Error: Too many re-renders. React limits the number of renders to prevent an infinite loop. ]] +[[ (exception in render) Error: Too many re-renders. React limits the number of renders to prevent an infinite loop. ]] +[[ (exception in render) Error: Too many re-renders. React limits the number of renders to prevent an infinite loop. ]] + +FAIL: for-of-mutate +- Expected ++ Received + + + ## Input + + ```javascript + import {makeObject_Primitives, mutateAndReturn, toJSON} from 'shared-runtime'; + + function Component(_props) { + const collection = [makeObject_Primitives()]; + const results = []; + for (const item of collection) { + results.push(
{toJSON(mutateAndReturn(item))}
); + } + return
{results}
; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [], + isComponent: true, + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { makeObject_Primitives, mutateAndReturn, toJSON } from "shared-runtime"; + + function Component(_props) { + const $ = _c(1); ++ Object.freeze(_props); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + const collection = [makeObject_Primitives()]; + const results = []; + for (const item of collection) { + results.push( +-
{toJSON(mutateAndReturn(item))}
, ++  ++ {toJSON(mutateAndReturn(item))} ++
, + ); + } + + t0 =
{results}
; + $[0] = t0; + } else { + t0 = $[0]; + } + return t0; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [], + isComponent: true, + }; + + ``` +  + ### Eval output + (kind: ok)
{"a":0,"b":"value1","c":true,"wat0":"joe"}
 + +FAIL: for-of-mutate-item-of-local-collection +- Expected ++ Received + + + ## Input + + ```javascript + import {makeObject_Primitives} from 'shared-runtime'; + + function Component(props) { + const items = [makeObject_Primitives(), makeObject_Primitives()]; + for (const x of items) { + x.a += 1; + } + return items; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + sequentialRenders: [{}, {}, {}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { makeObject_Primitives } from "shared-runtime"; + + function Component(props) { + const $ = _c(1); ++ Object.freeze(props); + let items; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + items = [makeObject_Primitives(), makeObject_Primitives()]; + for (const x of items) { + x.a = x.a + 1; + } + $[0] = items; + } else { + items = $[0]; + } + return items; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + sequentialRenders: [{}, {}, {}], + }; + + ``` +  + ### Eval output + (kind: ok) [{"a":1,"b":"value1","c":true},{"a":1,"b":"value1","c":true}] + [{"a":1,"b":"value1","c":true},{"a":1,"b":"value1","c":true}] + [{"a":1,"b":"value1","c":true},{"a":1,"b":"value1","c":true}] + +FAIL: for-of-iterator-of-immutable-collection +- Expected ++ Received + + + ## Input + + ```javascript + function Router({title, mapping}) { + const array = []; + for (let entry of mapping.values()) { + array.push([title, entry]); + } + return array; + } + + const routes = new Map([ + ['about', '/about'], + ['contact', '/contact'], + ]); + + export const FIXTURE_ENTRYPOINT = { + fn: Router, + params: [], + sequentialRenders: [ + { + title: 'Foo', + mapping: routes, + }, + { + title: 'Bar', + mapping: routes, + }, + ], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Router(t0) { + const $ = _c(3); ++ Object.freeze(t0); + const { title, mapping } = t0; + let array; + if ($[0] !== mapping || $[1] !== title) { + array = []; + for (const entry of mapping.values()) { + array.push([title, entry]); + } + $[0] = mapping; + $[1] = title; + $[2] = array; + } else { + array = $[2]; + } + return array; + } + + const routes = new Map([ + ["about", "/about"], + ["contact", "/contact"], + ]); + + export const FIXTURE_ENTRYPOINT = { + fn: Router, + params: [], + sequentialRenders: [ + { + title: "Foo", + mapping: routes, + }, + { + title: "Bar", + mapping: routes, + }, + ], + }; + + ``` +  + ### Eval output + (kind: ok) [["Foo","/about"],["Foo","/contact"]] + [["Bar","/about"],["Bar","/contact"]] + +FAIL: for-of-immutable-collection +- Expected ++ Received + + + ## Input + + ```javascript + function Router({title, mapping}) { + const array = []; + for (let [, entry] of mapping) { + array.push([title, entry]); + } + return array; + } + + const routes = new Map([ + ['about', '/about'], + ['contact', '/contact'], + ]); + + export const FIXTURE_ENTRYPOINT = { + fn: Router, + params: [], + sequentialRenders: [ + { + title: 'Foo', + mapping: routes, + }, + { + title: 'Bar', + mapping: routes, + }, + ], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Router(t0) { + const $ = _c(3); ++ Object.freeze(t0); + const { title, mapping } = t0; + let array; + if ($[0] !== mapping || $[1] !== title) { + array = []; + for (const [, entry] of mapping) { + array.push([title, entry]); + } + $[0] = mapping; + $[1] = title; + $[2] = array; + } else { + array = $[2]; + } + return array; + } + + const routes = new Map([ + ["about", "/about"], + ["contact", "/contact"], + ]); + + export const FIXTURE_ENTRYPOINT = { + fn: Router, + params: [], + sequentialRenders: [ + { + title: "Foo", + mapping: routes, + }, + { + title: "Bar", + mapping: routes, + }, + ], + }; + + ``` +  + ### Eval output + (kind: ok) [["Foo","/about"],["Foo","/contact"]] + [["Bar","/about"],["Bar","/contact"]] + +FAIL: for-of-capture-item-of-local-collection-mutate-later +- Expected ++ Received + + + ## Input + + ```javascript + import {makeObject_Primitives} from 'shared-runtime'; + + function Component(props) { + let lastItem = {}; + const items = [makeObject_Primitives(), makeObject_Primitives()]; + for (const x of items) { + lastItem = x; + } + if (lastItem != null) { + lastItem.a += 1; + } + return items; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + sequentialRenders: [{}, {}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { makeObject_Primitives } from "shared-runtime"; + + function Component(props) { + const $ = _c(1); ++ Object.freeze(props); + let items; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + let lastItem = {}; + items = [makeObject_Primitives(), makeObject_Primitives()]; + for (const x of items) { + lastItem = x; + } + if (lastItem != null) { + lastItem.a = lastItem.a + 1; + } + $[0] = items; + } else { + items = $[0]; + } + return items; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + sequentialRenders: [{}, {}], + }; + + ``` +  + ### Eval output + (kind: ok) [{"a":0,"b":"value1","c":true},{"a":1,"b":"value1","c":true}] + [{"a":0,"b":"value1","c":true},{"a":1,"b":"value1","c":true}] + +FAIL: for-of-capture-item-of-local-collection-mutate-later-value-initially-null +- Expected ++ Received + + + ## Input + + ```javascript + import {makeObject_Primitives} from 'shared-runtime'; + + function Component(props) { + let lastItem = null; + const items = [makeObject_Primitives(), makeObject_Primitives()]; + for (const x of items) { + lastItem = x; + } + if (lastItem != null) { + lastItem.a += 1; + } + return items; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + sequentialRenders: [{}, {}, {}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { makeObject_Primitives } from "shared-runtime"; + + function Component(props) { + const $ = _c(1); ++ Object.freeze(props); + let items; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + let lastItem = null; + items = [makeObject_Primitives(), makeObject_Primitives()]; + for (const x of items) { + lastItem = x; + } + if (lastItem != null) { + lastItem.a = lastItem.a + 1; + } + $[0] = items; + } else { + items = $[0]; + } + return items; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + sequentialRenders: [{}, {}, {}], + }; + + ``` +  + ### Eval output + (kind: ok) [{"a":0,"b":"value1","c":true},{"a":1,"b":"value1","c":true}] + [{"a":0,"b":"value1","c":true},{"a":1,"b":"value1","c":true}] + [{"a":0,"b":"value1","c":true},{"a":1,"b":"value1","c":true}] + +FAIL: for-multiple-variable-declarations-in-initializer +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + const items = []; + + for (let i = 0, length = props.items.length; i < length; i++) { + items.push(props.items[i]); + } + + return items; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{items: ['a', 'b', 42]}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(2); ++ Object.freeze(props); + let items; + if ($[0] !== props.items) { + items = []; + for (let i = 0, length = props.items.length; i < length; i++) { + items.push(props.items[i]); + } + $[0] = props.items; + $[1] = items; + } else { + items = $[1]; + } + return items; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ items: ["a", "b", 42] }], + }; + + ``` +  + ### Eval output + (kind: ok) ["a","b",42] + +FAIL: for-loop-with-value-block-initializer + >> Unexpected error during test: + + +Found differences in evaluator results +Non-forget (expected): +(kind: ok)
one
+
+
zero
one
two
+
one
two
+Forget: +(kind: ok)
one
+
+
zero
one
two
+
one
two
+logs: ['Warning: Encountered two children with the same key, `%s`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.%s','function () {\n' + + ' const $res$ = item.id;\n' + + ' Object.freeze($res$);\n' + + ' return $res$;\n' + + ' }','\n' + + ' at div\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)\n' + + ' at WrapperTestComponentWithErrorBoundary (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:63:9)','Warning: Encountered two children with the same key, `%s`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.%s','function () {\n' + + ' const $res$ = item.id;\n' + + ' Object.freeze($res$);\n' + + ' return $res$;\n' + + ' }','\n' + + ' at div\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)\n' + + ' at WrapperTestComponentWithErrorBoundary (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:63:9)','Warning: Encountered two children with the same key, `%s`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.%s','function () {\n' + + ' const $res$ = item.id;\n' + + ' Object.freeze($res$);\n' + + ' return $res$;\n' + + ' }','\n' + + ' at div\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)\n' + + ' at WrapperTestComponentWithErrorBoundary (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:63:9)'] + +FAIL: for-logical +- Expected ++ Received + + + ## Input + + ```javascript + 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; + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + function foo(props) { ++ Object.freeze(props); + let y = 0; + for ( + let x = 0; + x > props.min && x < props.max; + x = x + (props.cond ? props.increment : 2), x + ) { + x = x * 2; + y = y + x; + } + return y; + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: for-in-statement + >> Unexpected error during test: + + +Found differences in evaluator results +Non-forget (expected): +(kind: ok)
a
b
c
+
lauren
mofei
sathya
jason
+Forget: +(kind: ok)
a
b
c
+
lauren
mofei
sathya
jason
+logs: ['Warning: Encountered two children with the same key, `%s`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.%s','function () {\n' + + ' const $res$ = key;\n' + + ' Object.freeze($res$);\n' + + ' return $res$;\n' + + ' }','\n' + + ' at div\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)\n' + + ' at WrapperTestComponentWithErrorBoundary (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:63:9)','Warning: Encountered two children with the same key, `%s`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.%s','function () {\n' + + ' const $res$ = key;\n' + + ' Object.freeze($res$);\n' + + ' return $res$;\n' + + ' }','\n' + + ' at div\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)\n' + + ' at WrapperTestComponentWithErrorBoundary (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:63:9)','Warning: Encountered two children with the same key, `%s`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.%s','function () {\n' + + ' const $res$ = key;\n' + + ' Object.freeze($res$);\n' + + ' return $res$;\n' + + ' }','\n' + + ' at div\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)\n' + + ' at WrapperTestComponentWithErrorBoundary (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:63:9)','Warning: Encountered two children with the same key, `%s`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.%s','function () {\n' + + ' const $res$ = key;\n' + + ' Object.freeze($res$);\n' + + ' return $res$;\n' + + ' }','\n' + + ' at div\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)\n' + + ' at WrapperTestComponentWithErrorBoundary (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:63:9)','Warning: Encountered two children with the same key, `%s`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.%s','function () {\n' + + ' const $res$ = key;\n' + + ' Object.freeze($res$);\n' + + ' return $res$;\n' + + ' }','\n' + + ' at div\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)\n' + + ' at WrapperTestComponentWithErrorBoundary (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:63:9)'] + +FAIL: for-in-statement-type-inference +- Expected ++ Received + + + ## Input + + ```javascript + const {identity, mutate} = require('shared-runtime'); + + function Component(props) { + let x; + const object = {...props.value}; + for (const y in object) { + x = y; + } + mutate(x); // can't modify, x is known primitive! + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{value: {a: 'a', b: 'B', c: 'C!'}}], + }; + + ``` + + ## Code + + ```javascript + const { identity, mutate } = require("shared-runtime"); + + function Component(props) { ++ Object.freeze(props); + let x; + const object = { ...props.value }; + for (const y in object) { + x = y; + } + + mutate(x); + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ value: { a: "a", b: "B", c: "C!" } }], + }; + + ``` +  + ### Eval output + (kind: ok) "c" + +FAIL: for-in-statement-empty-body +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + let x; + for (const y in props.value) { + } + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{value: {a: 'a', b: 'B', c: 'C!'}}], + }; + + ``` + + ## Code + + ```javascript + function Component(props) { ++ Object.freeze(props); + let x; + for (const y in props.value) { + } + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ value: { a: "a", b: "B", c: "C!" } }], + }; + + ``` +  + ### Eval output + (kind: ok)  + +FAIL: for-in-statement-continue +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + let x; + const object = {...props.value}; + for (const y in object) { + if (y === 'continue') { + continue; + } + x = object[y]; + } + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{value: {a: 'a', continue: 'skip', b: 'hello!'}}], + sequentialRenders: [ + {value: {a: 'a', continue: 'skip', b: 'hello!'}}, + {value: {a: 'a', continue: 'skip', b: 'hello!'}}, + {value: {a: 'skip!', continue: true}}, + {value: {a: 'a', continue: 'skip', b: 'hello!'}}, + {value: {a: 'skip!', continue: true}}, + {value: {a: 'a', continue: 'skip', b: 'hello!'}}, + {value: {a: 'skip!', continue: true}}, + {value: {a: 'skip!', continue: true}}, + ], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(2); ++ Object.freeze(props); + let x; + let t0; + if ($[0] !== props.value) { + t0 = { ...props.value }; + $[0] = props.value; + $[1] = t0; + } else { + t0 = $[1]; + } + const object = t0; + for (const y in object) { + if (y === "continue") { + continue; + } + + x = object[y]; + } + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ value: { a: "a", continue: "skip", b: "hello!" } }], + sequentialRenders: [ + { value: { a: "a", continue: "skip", b: "hello!" } }, + { value: { a: "a", continue: "skip", b: "hello!" } }, + { value: { a: "skip!", continue: true } }, + { value: { a: "a", continue: "skip", b: "hello!" } }, + { value: { a: "skip!", continue: true } }, + { value: { a: "a", continue: "skip", b: "hello!" } }, + { value: { a: "skip!", continue: true } }, + { value: { a: "skip!", continue: true } }, + ], + }; + + ``` +  + ### Eval output + (kind: ok) "hello!" + "hello!" + "skip!" + "hello!" + "skip!" + "hello!" + "skip!" + "skip!" + +FAIL: for-in-statement-break +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + let x; + const object = {...props.value}; + for (const y in object) { + if (y === 'break') { + break; + } + x = object[y]; + } + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + // should return 'a' + params: [{a: 'a', break: null, c: 'C!'}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(2); ++ Object.freeze(props); + let x; + let t0; + if ($[0] !== props.value) { + t0 = { ...props.value }; + $[0] = props.value; + $[1] = t0; + } else { + t0 = $[1]; + } + const object = t0; + for (const y in object) { + if (y === "break") { + break; + } + + x = object[y]; + } + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + // should return 'a' + params: [{ a: "a", break: null, c: "C!" }], + }; + + ``` +  + ### Eval output + (kind: ok)  + +FAIL: for-in-statement-body-always-returns +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + for (const x in props.value) { + return x; + } + return null; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{value: {a: 'A!'}}], + }; + + ``` + + ## Code + + ```javascript + function Component(props) { ++ Object.freeze(props); + for (const x in props.value) { + return x; + } + return null; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ value: { a: "A!" } }], + }; + + ``` +  + ### Eval output + (kind: ok) "a" + +FAIL: for-empty-update +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + let x = 0; + for (let i = 0; i < props.count; ) { + x += i; + if (x > 10) { + break; + } + } + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + function Component(props) { ++ Object.freeze(props); + let x = 0; + for (const i = 0; 0 < props.count; ) { + x = x + 0; + if (x > 10) { + break; + } + } + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: for-empty-update-with-continue +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + let x = 0; + for (let i = 0; i < props.count; ) { + x += i; + i += 1; + continue; + } + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + function Component(props) { ++ Object.freeze(props); + let x = 0; + for (let i = 0; i < props.count; ) { + x = x + i; + i = i + 1; + } + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: flatten-scopes-with-methodcall-hook +- Expected ++ Received + + + ## Input + + ```javascript + const {ObjectWithHooks} = require('shared-runtime'); + + function Component(props) { + const x = []; + const [y] = ObjectWithHooks.useMakeArray(); + x.push(y); + return y; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + }; + + ``` + + ## Code + + ```javascript + const { ObjectWithHooks } = require("shared-runtime"); + + function Component(props) { ++ Object.freeze(props); + const x = []; +- const [y] = ObjectWithHooks.useMakeArray(); ++ const [y] = (function () { ++ const $res$ = ObjectWithHooks.useMakeArray(); ++ Object.freeze($res$); ++ return $res$; ++ })(); + x.push(y); + return y; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + }; + + ``` +  + ### Eval output + (kind: ok) 1 + +FAIL: flag-enable-emit-hook-guards +- Expected ++ Received + + + ## Input + + ```javascript + // @enableEmitHookGuards + import {createContext, useContext, useEffect, useState} from 'react'; + import { + CONST_STRING0, + ObjectWithHooks, + getNumber, + identity, + print, + } from 'shared-runtime'; + + const MyContext = createContext('my context value'); + function Component({value}) { + print(identity(CONST_STRING0)); + const [state, setState] = useState(getNumber()); + print(value, state); + useEffect(() => { + if (state === 4) { + setState(5); + } + }, [state]); + print(identity(value + state)); + return ObjectWithHooks.useIdentity(useContext(MyContext)); + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + args: [{value: 0}], + }; + + ``` + + ## Code + + ```javascript + import { $dispatcherGuard } from "react-compiler-runtime"; + import { c as _c } from "react/compiler-runtime"; // @enableEmitHookGuards + import { createContext, useContext, useEffect, useState } from "react"; + import { + CONST_STRING0, + ObjectWithHooks, + getNumber, + identity, + print, + } from "shared-runtime"; + + const MyContext = createContext("my context value"); + function Component(t0) { + const $ = _c(4); ++ Object.freeze(t0); + try { + $dispatcherGuard(0); + const { value } = t0; + print(identity(CONST_STRING0)); + let t1; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t1 = getNumber(); + $[0] = t1; + } else { + t1 = $[0]; + } + const [state, setState] = (function () { + try { + $dispatcherGuard(2); +- return useState(t1); ++ return (function () { ++ const $res$ = useState(Object.freeze(t1)); ++ Object.freeze($res$); ++ return $res$; ++ })(); + } finally { + $dispatcherGuard(3); + } + })(); + print(value, state); + let t2; + let t3; + if ($[1] !== state) { + t2 = () => { + if (state === 4) { + setState(5); + } + }; + + t3 = [state]; + $[1] = state; + $[2] = t2; + $[3] = t3; + } else { + t2 = $[2]; + t3 = $[3]; + } + (function () { + try { + $dispatcherGuard(2); +- return useEffect(t2, t3); ++ return (function () { ++ const $res$ = useEffect(Object.freeze(t2), Object.freeze(t3)); ++ Object.freeze($res$); ++ return $res$; ++ })(); + } finally { + $dispatcherGuard(3); + } + })(); + print(identity(value + state)); + return (function () { + try { + $dispatcherGuard(2); +- return ObjectWithHooks.useIdentity( +- (function () { +- try { +- $dispatcherGuard(2); +- return useContext(MyContext); +- } finally { +- $dispatcherGuard(3); +- } +- })(), +- ); ++ return (function () { ++ const $res$ = ObjectWithHooks.useIdentity( ++ Object.freeze( ++ (function () { ++ try { ++ $dispatcherGuard(2); ++ return (function () { ++ const $res$ = useContext(Object.freeze(MyContext)); ++ Object.freeze($res$); ++ return $res$; ++ })(); ++ } finally { ++ $dispatcherGuard(3); ++ } ++ })(), ++ ), ++ ); ++ Object.freeze($res$); ++ return $res$; ++ })(); + } finally { + $dispatcherGuard(3); + } + })(); + } finally { + $dispatcherGuard(1); + } + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + args: [{ value: 0 }], + }; + + ``` +  + +FAIL: fast-refresh-reloading + >> Unexpected error during test: + + +Found differences in evaluator results +Non-forget (expected): +(kind: ok)
{"inputs":[0],"output":[0]}
+
{"inputs":[0],"output":[0]}
+Forget: +(kind: ok) [[ (exception in render) Error: Too many re-renders. React limits the number of renders to prevent an infinite loop. ]] +[[ (exception in render) Error: Too many re-renders. React limits the number of renders to prevent an infinite loop. ]] + +FAIL: fast-refresh-refresh-on-const-changes-dev +- Expected ++ Received + + + ## Input + + ```javascript + // @compilationMode(infer) @enableResetCacheOnSourceFileChanges + import {useEffect, useMemo, useState} from 'react'; + import {ValidateMemoization} from 'shared-runtime'; + + let pretendConst = 0; + + function unsafeResetConst() { + pretendConst = 0; + } + + function unsafeUpdateConst() { + pretendConst += 1; + } + + function Component() { + useState(() => { + // unsafe: reset the constant when first rendering the instance + unsafeResetConst(); + }); + // UNSAFE! changing a module variable that is read by a component is normally + // unsafe, but in this case we're simulating a fast refresh between each render + unsafeUpdateConst(); + + // TODO: In fast refresh mode (@enableResetCacheOnSourceFileChanges) Forget should + // reset on changes to globals that impact the component/hook, effectively memoizing + // as if value was reactive. However, we don't want to actually treat globals as + // reactive (though that would be trivial) since it could change compilation too much + // btw dev and prod. Instead, we should reset the cache via a secondary mechanism. + const value = useMemo(() => [{pretendConst}], [pretendConst]); + + return ; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + sequentialRenders: [{}, {}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; // @compilationMode(infer) @enableResetCacheOnSourceFileChanges + import { useEffect, useMemo, useState } from "react"; + import { ValidateMemoization } from "shared-runtime"; + + let pretendConst = 0; + + function unsafeResetConst() { + pretendConst = 0; + } + + function unsafeUpdateConst() { + pretendConst += 1; + } + + function Component() { + const $ = _c(3); + if ( + $[0] !== "8d7015668f857996c3d895a7a90e3e16b8a791d5b9cd13f2c76e1c254aeedebb" + ) { + for (let $i = 0; $i < 3; $i += 1) { + $[$i] = Symbol.for("react.memo_cache_sentinel"); + } + $[0] = "8d7015668f857996c3d895a7a90e3e16b8a791d5b9cd13f2c76e1c254aeedebb"; + } +- useState(_temp); ++ (function () { ++ const $res$ = useState(Object.freeze(_temp)); ++ Object.freeze($res$); ++ return $res$; ++ })(); + + unsafeUpdateConst(); + let t0; + let t1; + if ($[1] === Symbol.for("react.memo_cache_sentinel")) { + t1 = [{ pretendConst }]; + $[1] = t1; + } else { + t1 = $[1]; + } + t0 = t1; + const value = t0; + let t2; + if ($[2] === Symbol.for("react.memo_cache_sentinel")) { +- t2 = ; ++ t2 = ( ++  ++ ); + $[2] = t2; + } else { + t2 = $[2]; + } + return t2; + } + function _temp() { + unsafeResetConst(); + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + sequentialRenders: [{}, {}], + }; + + ``` +  + +FAIL: fast-refresh-dont-refresh-const-changes-prod + >> Unexpected error during test: + + +Found differences in evaluator results +Non-forget (expected): +(kind: ok)
{"inputs":[],"output":[{"pretendConst":1}]}
+
{"inputs":[],"output":[{"pretendConst":1}]}
+Forget: +(kind: ok) [[ (exception in render) TypeError: inputs.some is not a function ]] +[[ (exception in render) TypeError: inputs.some is not a function ]] + +FAIL: extend-scopes-if +- Expected ++ Received + + + ## Input + + ```javascript + function foo(a, b, c) { + let x = []; + if (a) { + if (b) { + if (c) { + x.push(0); + } + } + } + if (x.length) { + return x; + } + return null; + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function foo(a, b, c) { + const $ = _c(4); ++ Object.freeze(a); ++ Object.freeze(b); ++ Object.freeze(c); + let x; + if ($[0] !== a || $[1] !== b || $[2] !== c) { + x = []; + if (a) { + if (b) { + if (c) { + x.push(0); + } + } + } + $[0] = a; + $[1] = b; + $[2] = c; + $[3] = x; + } else { + x = $[3]; + } + if (x.length) { + return x; + } + return null; + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: expression-with-assignment-dynamic +- Expected ++ Received + + + ## Input + + ```javascript + function f(y) { + let x = y; + return x + (x = 2) + x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: f, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + function f(y) { ++ Object.freeze(y); + let x = y; + return x + (x = 2) + 2; + } + + export const FIXTURE_ENTRYPOINT = { + fn: f, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: existing-variables-with-c-name + >> Unexpected error during test: + + +Found differences in evaluator results +Non-forget (expected): +(kind: ok)
{"inputs":[0],"output":[0]}
+
{"inputs":[0],"output":[0]}
+
{"inputs":[0],"output":[0]}
+Forget: +(kind: ok) [[ (exception in render) Error: Too many re-renders. React limits the number of renders to prevent an infinite loop. ]] +[[ (exception in render) Error: Too many re-renders. React limits the number of renders to prevent an infinite loop. ]] +[[ (exception in render) Error: Too many re-renders. React limits the number of renders to prevent an infinite loop. ]] + +FAIL: escape-analysis-not-switch-test +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + const a = [props.a]; + let x = props.b; + switch (a) { + case true: { + x = props.c; + } + } + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + function Component(props) { ++ Object.freeze(props); + const a = [props.a]; + let x = props.b; + switch (a) { + case true: { + x = props.c; + } + } + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: escape-analysis-not-switch-case +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + const a = [props.a]; + let x = props.b; + switch (props.c) { + case a: { + x = props.d; + } + } + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + function Component(props) { ++ Object.freeze(props); + const a = [props.a]; + let x = props.b; + switch (props.c) { + case a: { + x = props.d; + } + } + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: escape-analysis-not-if-test +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + const x = [props.a]; + let y; + if (x) { + y = props.b; + } else { + y = props.c; + } + return y; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + function Component(props) { ++ Object.freeze(props); + const x = [props.a]; + let y; + if (x) { + y = props.b; + } else { + y = props.c; + } + return y; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: escape-analysis-not-conditional-test +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + const x = [props.a]; + const y = x ? props.b : props.c; + return y; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + function Component(props) { ++ Object.freeze(props); + const x = [props.a]; + const y = x ? props.b : props.c; + return y; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: escape-analysis-non-escaping-interleaved-primitive-dependency +- Expected ++ Received + + + ## Input + + ```javascript + 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; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(3); ++ Object.freeze(props); + + const a = props.a + props.b; + let b; + if ($[0] !== a || $[1] !== props.c) { + b = []; + const c = {}; + c.a = a; + b.push(props.c); + $[0] = a; + $[1] = props.c; + $[2] = b; + } else { + b = $[2]; + } + return b; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: escape-analysis-non-escaping-interleaved-allocating-nested-dependency +- Expected ++ Received + + + ## Input + + ```javascript + 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; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(7); ++ Object.freeze(props); + let t0; + if ($[0] !== props.a) { + t0 = [props.a]; + $[0] = props.a; + $[1] = t0; + } else { + t0 = $[1]; + } + const a = t0; + let t1; + if ($[2] !== a) { + t1 = [a]; + $[2] = a; + $[3] = t1; + } else { + t1 = $[3]; + } + const b = t1; + let c; + if ($[4] !== b || $[5] !== props.b) { + c = []; + const d = {}; + d.b = b; + c.push(props.b); + $[4] = b; + $[5] = props.b; + $[6] = c; + } else { + c = $[6]; + } + return c; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: escape-analysis-non-escaping-interleaved-allocating-dependency +- Expected ++ Received + + + ## Input + + ```javascript + 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; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(5); ++ Object.freeze(props); + let t0; + if ($[0] !== props.a) { + t0 = [props.a]; + $[0] = props.a; + $[1] = t0; + } else { + t0 = $[1]; + } + const a = t0; + let b; + if ($[2] !== a || $[3] !== props.b) { + b = []; + const c = {}; + c.a = a; + b.push(props.b); + $[2] = a; + $[3] = props.b; + $[4] = b; + } else { + b = $[4]; + } + return b; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: escape-analysis-logical +- Expected ++ Received + + + ## Input + + ```javascript + 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; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(6); ++ Object.freeze(props); + let t0; + if ($[0] !== props.a) { + t0 = [props.a]; + $[0] = props.a; + $[1] = t0; + } else { + t0 = $[1]; + } + const a = t0; + let t1; + if ($[2] !== props.b) { + t1 = [props.b]; + $[2] = props.b; + $[3] = t1; + } else { + t1 = $[3]; + } + const b = t1; + let t2; + if ($[4] !== props.c) { + t2 = [props.c]; + $[4] = props.c; + $[5] = t2; + } else { + t2 = $[5]; + } + const c = t2; + return (a && b) || c; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: escape-analysis-jsx-child +- Expected ++ Received + + + ## Input + + ```javascript + function foo(a, b, c) { + const x = []; + if (a) { + const y = []; + if (b) { + y.push(c); + } + x.push(
{y}
); + } + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function foo(a, b, c) { + const $ = _c(9); ++ Object.freeze(a); ++ Object.freeze(b); ++ Object.freeze(c); + let x; + if ($[0] !== a || $[1] !== b || $[2] !== c) { + x = []; + if (a) { + let y; + if ($[4] !== b || $[5] !== c) { + y = []; + if (b) { + y.push(c); + } + $[4] = b; + $[5] = c; + $[6] = y; + } else { + y = $[6]; + } + let t0; + if ($[7] !== y) { + t0 =
{y}
; + $[7] = y; + $[8] = t0; + } else { + t0 = $[8]; + } + x.push(t0); + } + $[0] = a; + $[1] = b; + $[2] = c; + $[3] = x; + } else { + x = $[3]; + } + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: escape-analysis-destructured-rest-element +- Expected ++ Received + + + ## Input + + ```javascript + 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
; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(7); ++ Object.freeze(props); + let b; + if ($[0] !== props.a) { + const { a, ...t0 } = props.a; + b = t0; + $[0] = props.a; + $[1] = b; + } else { + b = $[1]; + } + let d; + if ($[2] !== props.c) { + const [c, ...t0] = props.c; + d = t0; + $[2] = props.c; + $[3] = d; + } else { + d = $[3]; + } + let t0; + if ($[4] !== b || $[5] !== d) { +- t0 =
; ++ t0 = ( ++  ++ ); + $[4] = b; + $[5] = d; + $[6] = t0; + } else { + t0 = $[6]; + } + return t0; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: early-return +- Expected ++ Received + + + ## Input + + ```javascript + function MyApp(props) { + let res; + if (props.cond) { + return; + } else { + res = 1; + } + } + + export const FIXTURE_ENTRYPOINT = { + fn: MyApp, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + function MyApp(props) { ++ Object.freeze(props); + if (props.cond) { + return; + } + } + + export const FIXTURE_ENTRYPOINT = { + fn: MyApp, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: early-return-within-reactive-scope +- Expected ++ Received + + + ## Input + + ```javascript + import {makeArray} from 'shared-runtime'; + + function Component(props) { + let x = []; + if (props.cond) { + x.push(props.a); + // oops no memo! + return x; + } else { + return makeArray(props.b); + } + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [], + sequentialRenders: [ + // pattern 1 + {cond: true, a: 42}, + {cond: true, a: 42}, + // pattern 2 + {cond: false, b: 3.14}, + {cond: false, b: 3.14}, + // pattern 1 + {cond: true, a: 42}, + // pattern 2 + {cond: false, b: 3.14}, + // pattern 1 + {cond: true, a: 42}, + // pattern 2 + {cond: false, b: 3.14}, + ], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { makeArray } from "shared-runtime"; + + function Component(props) { + const $ = _c(4); ++ Object.freeze(props); + let t0; + if ($[0] !== props) { + t0 = Symbol.for("react.early_return_sentinel"); + bb0: { + const x = []; + if (props.cond) { + x.push(props.a); + t0 = x; + break bb0; + } else { + let t1; + if ($[2] !== props.b) { + t1 = makeArray(props.b); + $[2] = props.b; + $[3] = t1; + } else { + t1 = $[3]; + } + t0 = t1; + break bb0; + } + } + $[0] = props; + $[1] = t0; + } else { + t0 = $[1]; + } + if (t0 !== Symbol.for("react.early_return_sentinel")) { + return t0; + } + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [], + sequentialRenders: [ + // pattern 1 + { cond: true, a: 42 }, + { cond: true, a: 42 }, + // pattern 2 + { cond: false, b: 3.14 }, + { cond: false, b: 3.14 }, + // pattern 1 + { cond: true, a: 42 }, + // pattern 2 + { cond: false, b: 3.14 }, + // pattern 1 + { cond: true, a: 42 }, + // pattern 2 + { cond: false, b: 3.14 }, + ], + }; + + ``` +  + ### Eval output + (kind: ok) [42] + [42] + [3.14] + [3.14] + [42] + [3.14] + [42] + [3.14] + +FAIL: early-return-no-declarations-reassignments-dependencies +- Expected ++ Received + + + ## Input + + ```javascript + import {makeArray} from 'shared-runtime'; + + /** + * This fixture tests what happens when a reactive has no declarations (other than an early return), + * no reassignments, and no dependencies. In this case the only thing we can use to decide if we + * should take the if or else branch is the early return declaration. But if that uses the same + * sentinel as the memo cache sentinel, then if the previous execution did not early return it will + * look like we didn't execute the memo block yet, and we'll needlessly re-execute instead of skipping + * to the else branch. + * + * We have to use a distinct sentinel for the early return value. + * + * Here the fixture will always take the "else" branch and never early return. Logging (not included) + * confirms that the scope for `x` only executes once, on the first render of the component. + */ + let ENABLE_FEATURE = false; + + function Component(props) { + let x = []; + if (ENABLE_FEATURE) { + x.push(42); + return x; + } else { + console.log('fallthrough'); + } + return makeArray(props.a); + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [], + sequentialRenders: [ + {a: 42}, + {a: 42}, + {a: 3.14}, + {a: 3.14}, + {a: 42}, + {a: 3.14}, + {a: 42}, + {a: 3.14}, + ], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { makeArray } from "shared-runtime"; + + /** + * This fixture tests what happens when a reactive has no declarations (other than an early return), + * no reassignments, and no dependencies. In this case the only thing we can use to decide if we + * should take the if or else branch is the early return declaration. But if that uses the same + * sentinel as the memo cache sentinel, then if the previous execution did not early return it will + * look like we didn't execute the memo block yet, and we'll needlessly re-execute instead of skipping + * to the else branch. + * + * We have to use a distinct sentinel for the early return value. + * + * Here the fixture will always take the "else" branch and never early return. Logging (not included) + * confirms that the scope for `x` only executes once, on the first render of the component. + */ + let ENABLE_FEATURE = false; + + function Component(props) { + const $ = _c(3); ++ Object.freeze(props); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = Symbol.for("react.early_return_sentinel"); + bb0: { + const x = []; + if (ENABLE_FEATURE) { + x.push(42); + t0 = x; + break bb0; + } else { + console.log("fallthrough"); + } + } + $[0] = t0; + } else { + t0 = $[0]; + } + if (t0 !== Symbol.for("react.early_return_sentinel")) { + return t0; + } + let t1; + if ($[1] !== props.a) { + t1 = makeArray(props.a); + $[1] = props.a; + $[2] = t1; + } else { + t1 = $[2]; + } + return t1; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [], + sequentialRenders: [ + { a: 42 }, + { a: 42 }, + { a: 3.14 }, + { a: 3.14 }, + { a: 42 }, + { a: 3.14 }, + { a: 42 }, + { a: 3.14 }, + ], + }; + + ``` +  + +FAIL: early-return-nested-early-return-within-reactive-scope +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + let x = []; + if (props.cond) { + x.push(props.a); + if (props.b) { + const y = [props.b]; + x.push(y); + // oops no memo! + return x; + } + // oops no memo! + return x; + } else { + return foo(); + } + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{cond: true, a: 42, b: 3.14}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(5); ++ Object.freeze(props); + let t0; + if ($[0] !== props) { + t0 = Symbol.for("react.early_return_sentinel"); + bb0: { + const x = []; + if (props.cond) { + x.push(props.a); + if (props.b) { + let t1; + if ($[2] !== props.b) { + t1 = [props.b]; + $[2] = props.b; + $[3] = t1; + } else { + t1 = $[3]; + } + const y = t1; + x.push(y); + t0 = x; + break bb0; + } + + t0 = x; + break bb0; + } else { + let t1; + if ($[4] === Symbol.for("react.memo_cache_sentinel")) { + t1 = foo(); + $[4] = t1; + } else { + t1 = $[4]; + } + t0 = t1; + break bb0; + } + } + $[0] = props; + $[1] = t0; + } else { + t0 = $[1]; + } + if (t0 !== Symbol.for("react.early_return_sentinel")) { + return t0; + } + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ cond: true, a: 42, b: 3.14 }], + }; + + ``` +  + ### Eval output + (kind: ok) [42,[3.14]] + +FAIL: drop-methodcall-usememo +- Expected ++ Received + + + ## Input + + ```javascript + import * as React from 'react'; + + function Component(props) { + const x = React.useMemo(() => { + const x = []; + x.push(props.value); + return x; + }, [props.value]); + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{value: 42}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import * as React from "react"; + + function Component(props) { + const $ = _c(2); ++ Object.freeze(props); + let t0; + let x; + if ($[0] !== props.value) { + x = []; + x.push(props.value); + $[0] = props.value; + $[1] = x; + } else { + x = $[1]; + } + t0 = x; + const x_0 = t0; + return x_0; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ value: 42 }], + }; + + ``` +  + ### Eval output + (kind: ok) [42] + +FAIL: drop-methodcall-usecallback +- Expected ++ Received + + + ## Input + + ```javascript + import * as React from 'react'; + + function Component(props) { + const onClick = React.useCallback(() => { + console.log(props.value); + }, [props.value]); + return
; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{value: 42}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import * as React from "react"; + + function Component(props) { + const $ = _c(4); ++ Object.freeze(props); + let t0; + if ($[0] !== props.value) { + t0 = () => { + console.log(props.value); + }; + $[0] = props.value; + $[1] = t0; + } else { + t0 = $[1]; + } + const onClick = t0; + let t1; + if ($[2] !== onClick) { +- t1 =
; ++ t1 = ( ++  ++ ); + $[2] = onClick; + $[3] = t1; + } else { + t1 = $[3]; + } + return t1; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ value: 42 }], + }; + + ``` +  + ### Eval output + (kind: ok)
 + +FAIL: dont-merge-overlapping-scopes-with-intermediate-reassignment +- Expected ++ Received + + + ## Input + + ```javascript + import {Stringify} from 'shared-runtime'; + + function Component(props) { + let x; + const array = [props.count]; + x = array; + const element =
{array}
; + return ( +
 + {element} + {x} +
 + ); + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{count: 42}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { Stringify } from "shared-runtime"; + + function Component(props) { + const $ = _c(7); ++ Object.freeze(props); + let x; + let t0; + if ($[0] !== props.count) { + t0 = [props.count]; + $[0] = props.count; + $[1] = t0; + } else { + t0 = $[1]; + } + const array = t0; + x = array; + let t1; + if ($[2] !== array) { + t1 =
{array}
; + $[2] = array; + $[3] = t1; + } else { + t1 = $[3]; + } + const element = t1; + let t2; + if ($[4] !== element || $[5] !== x) { + t2 = ( +
 + {element} + {x} +
 + ); + $[4] = element; + $[5] = x; + $[6] = t2; + } else { + t2 = $[6]; + } + return t2; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ count: 42 }], + }; + + ``` +  + ### Eval output + (kind: ok)
42
42
 + +FAIL: dont-merge-overlapping-scopes-store-const-used-later +- Expected ++ Received + + + ## Input + + ```javascript + import {Stringify, makeObject_Primitives} from 'shared-runtime'; + + function Component(props) { + const array = [props.count]; + const x = makeObject_Primitives(); + const element =
{array}
; + console.log(x); + return
{element}
; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{count: 42}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { Stringify, makeObject_Primitives } from "shared-runtime"; + + function Component(props) { + const $ = _c(6); ++ Object.freeze(props); + let t0; + if ($[0] !== props.count) { + t0 = [props.count]; + $[0] = props.count; + $[1] = t0; + } else { + t0 = $[1]; + } + const array = t0; + const x = makeObject_Primitives(); + let t1; + if ($[2] !== array) { + t1 =
{array}
; + $[2] = array; + $[3] = t1; + } else { + t1 = $[3]; + } + const element = t1; + console.log(x); + let t2; + if ($[4] !== element) { + t2 =
{element}
; + $[4] = element; + $[5] = t2; + } else { + t2 = $[5]; + } + return t2; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ count: 42 }], + }; + + ``` +  + ### Eval output + (kind: ok)
42
 + logs: [{ a: 0, b: 'value1', c: true }] + +FAIL: dont-merge-if-dep-is-inner-declaration-of-previous-scope +- Expected ++ Received + + + ## Input + + ```javascript + import {ValidateMemoization} from 'shared-runtime'; + + // Achieving Forget's level of memoization precision in this example isn't possible with useMemo + // without significantly altering the code, so disable the non-Forget evaluation of this fixture. + // @disableNonForgetInSprout + function Component({a, b, c}) { + const x = []; + let y; + if (a) { + y = [b]; + } + x.push(c); + + // this scope should not merge with the above scope because y does not invalidate + // on changes to `c` + const z = [y]; + + // return [x, z]; + return ( + <> +  +  +  + ); + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{a: false, b: null, c: 0}], + sequentialRenders: [ + {a: false, b: null, c: 0}, + {a: false, b: null, c: 1}, + {a: true, b: 0, c: 1}, + {a: true, b: 1, c: 1}, + ], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { ValidateMemoization } from "shared-runtime"; + + // Achieving Forget's level of memoization precision in this example isn't possible with useMemo + // without significantly altering the code, so disable the non-Forget evaluation of this fixture. + // @disableNonForgetInSprout + function Component(t0) { + const $ = _c(25); ++ Object.freeze(t0); + const { a, b, c } = t0; + let y; + let x; + if ($[0] !== a || $[1] !== b || $[2] !== c) { + x = []; + if (a) { + let t1; + if ($[5] !== b) { + t1 = [b]; + $[5] = b; + $[6] = t1; + } else { + t1 = $[6]; + } + y = t1; + } + + x.push(c); + $[0] = a; + $[1] = b; + $[2] = c; + $[3] = y; + $[4] = x; + } else { + y = $[3]; + x = $[4]; + } + let t1; + if ($[7] !== y) { + t1 = [y]; + $[7] = y; + $[8] = t1; + } else { + t1 = $[8]; + } + const z = t1; + let t2; + if ($[9] !== a || $[10] !== b || $[11] !== c) { + t2 = [a, b, c]; + $[9] = a; + $[10] = b; + $[11] = c; + $[12] = t2; + } else { + t2 = $[12]; + } + let t3; + if ($[13] !== t2 || $[14] !== x) { +- t3 = ; ++ t3 = ( ++  ++ ); + $[13] = t2; + $[14] = x; + $[15] = t3; + } else { + t3 = $[15]; + } + let t4; + if ($[16] !== a || $[17] !== b) { + t4 = [a, b]; + $[16] = a; + $[17] = b; + $[18] = t4; + } else { + t4 = $[18]; + } + let t5; + if ($[19] !== t4 || $[20] !== z) { +- t5 = ; ++ t5 = ( ++  ++ ); + $[19] = t4; + $[20] = z; + $[21] = t5; + } else { + t5 = $[21]; + } + let t6; + if ($[22] !== t3 || $[23] !== t5) { + t6 = ( + <> + {t3} + {t5} +  + ); + $[22] = t3; + $[23] = t5; + $[24] = t6; + } else { + t6 = $[24]; + } + return t6; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ a: false, b: null, c: 0 }], + sequentialRenders: [ + { a: false, b: null, c: 0 }, + { a: false, b: null, c: 1 }, + { a: true, b: 0, c: 1 }, + { a: true, b: 1, c: 1 }, + ], + }; + + ``` +  + ### Eval output +- (kind: ok)
{"inputs":[false,null,0],"output":[0]}
{"inputs":[false,null],"output":[null]}
 +-
{"inputs":[false,null,1],"output":[1]}
{"inputs":[false,null],"output":[null]}
 +-
{"inputs":[true,0,1],"output":[1]}
{"inputs":[true,0],"output":[[0]]}
 +-
{"inputs":[true,1,1],"output":[1]}
{"inputs":[true,1],"output":[[1]]}
 ++ (kind: ok) [[ (exception in render) Error: Too many re-renders. React limits the number of renders to prevent an infinite loop. ]] ++ [[ (exception in render) Error: Too many re-renders. React limits the number of renders to prevent an infinite loop. ]] ++ [[ (exception in render) Error: Too many re-renders. React limits the number of renders to prevent an infinite loop. ]] ++ [[ (exception in render) Error: Too many re-renders. React limits the number of renders to prevent an infinite loop. ]] + +FAIL: dominator +- Expected ++ Received + + + ## Input + + ```javascript + 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; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + function Component(props) { ++ Object.freeze(props); + let x = 0; + bb0: if (props.a) { + x = 1; + } else { + if (props.b) { + } else { + break bb0; + } + + x = 3; + } + bb1: bb2: switch (props.c) { + case "a": { + x = 4; + break bb2; + } + case "b": { + break bb1; + } + case "c": { + } + default: { + x = 6; + } + } + if (props.d) { + return null; + } + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: do-while-early-unconditional-break +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + let x = [1, 2, 3]; + do { + mutate(x); + break; + } while (props.cond); + return x; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(1); ++ Object.freeze(props); + let x; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + x = [1, 2, 3]; + + mutate(x); + $[0] = x; + } else { + x = $[0]; + } + return x; + } + + ``` +  + +FAIL: do-while-conditional-break +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + let x = [0, 1, 2, 3]; + do { + if (x === 0) { + break; + } + mutate(x); + } while (props.cond); + return x; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(2); ++ Object.freeze(props); + let x; + if ($[0] !== props) { + x = [0, 1, 2, 3]; + do { + if (x === 0) { + break; + } + + mutate(x); + } while (props.cond); + $[0] = props; + $[1] = x; + } else { + x = $[1]; + } + return x; + } + + ``` +  + +FAIL: do-while-compound-test +- Expected ++ Received + + + ## Input + + ```javascript + 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; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(2); ++ Object.freeze(props); + let ret; + if ($[0] !== props) { + const x = [1, 2, 3]; + ret = []; + do { + const item = x.pop(); + ret.push(item * 2); + } while (x.length && props.cond); + $[0] = props; + $[1] = ret; + } else { + ret = $[1]; + } + return ret; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: do-while-break +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + do { + break; + } while (props.cond); + return props; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + function Component(props) { ++ Object.freeze(props); + return props; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: destructuring +- Expected ++ Received + + + ## Input + + ```javascript + 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]; + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function foo(a, b, c) { + const $ = _c(18); ++ Object.freeze(a); ++ Object.freeze(b); ++ Object.freeze(c); + let t0; + let d; + let h; + if ($[0] !== a) { + [d, t0, ...h] = a; + $[0] = a; + $[1] = t0; + $[2] = d; + $[3] = h; + } else { + t0 = $[1]; + d = $[2]; + h = $[3]; + } + const [t1] = t0; + let t2; + let g; + if ($[4] !== t1) { + ({ e: t2, ...g } = t1); + $[4] = t1; + $[5] = t2; + $[6] = g; + } else { + t2 = $[5]; + g = $[6]; + } + const { f } = t2; + const { l: t3, p } = b; + const { m: t4 } = t3; + let t5; + let o; + if ($[7] !== t4) { + [t5, ...o] = t4; + $[7] = t4; + $[8] = t5; + $[9] = o; + } else { + t5 = $[8]; + o = $[9]; + } + const [n] = t5; + let t6; + if ( + $[10] !== d || + $[11] !== f || + $[12] !== g || + $[13] !== h || + $[14] !== n || + $[15] !== o || + $[16] !== p + ) { + t6 = [d, f, g, h, n, o, p]; + $[10] = d; + $[11] = f; + $[12] = g; + $[13] = h; + $[14] = n; + $[15] = o; + $[16] = p; + $[17] = t6; + } else { + t6 = $[17]; + } + return t6; + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: destructuring-with-typecast-as-default-value.flow +- Expected ++ Received + + + ## Input + + ```javascript + // @flow + function Component(props) { + const [x = ([]: Array)] = props.y; + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{y: []}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(2); ++ Object.freeze(props); + const [t0] = props.y; + let t1; + if ($[0] !== t0) { + t1 = t0 === undefined ? ([]: Array) : t0; + $[0] = t0; + $[1] = t1; + } else { + t1 = $[1]; + } + const x = t1; + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ y: [] }], + }; + + ``` +  + ### Eval output + (kind: ok) [] + +FAIL: destructuring-with-conditional-as-default-value +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + const [x = true ? 1 : 0] = props.y; + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{y: []}], + }; + + ``` + + ## Code + + ```javascript + function Component(props) { ++ Object.freeze(props); + const [t0] = props.y; + const x = t0 === undefined ? (true ? 1 : 0) : t0; + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ y: [] }], + }; + + ``` +  + ### Eval output + (kind: ok) 1 + +FAIL: destructuring-same-property-identifier-names +- Expected ++ Received + + + ## Input + + ```javascript + import {identity} from 'shared-runtime'; + + function Component(props) { + const { + x: {destructured}, + sameName: renamed, + } = props; + const sameName = identity(destructured); + + return [sameName, renamed]; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{x: {destructured: 0}, sameName: 2}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { identity } from "shared-runtime"; + + function Component(props) { + const $ = _c(5); ++ Object.freeze(props); + const { x: t0, sameName: renamed } = props; + const { destructured } = t0; + let t1; + if ($[0] !== destructured) { + t1 = identity(destructured); + $[0] = destructured; + $[1] = t1; + } else { + t1 = $[1]; + } + const sameName = t1; + let t2; + if ($[2] !== sameName || $[3] !== renamed) { + t2 = [sameName, renamed]; + $[2] = sameName; + $[3] = renamed; + $[4] = t2; + } else { + t2 = $[4]; + } + return t2; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ x: { destructured: 0 }, sameName: 2 }], + }; + + ``` +  + ### Eval output + (kind: ok) [0,2] + +FAIL: destructuring-property-inference +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + const x = []; + x.push(props.value); + const {length: y} = x; + foo(y); + return [x, y]; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(5); ++ Object.freeze(props); + let x; + if ($[0] !== props.value) { + x = []; + x.push(props.value); + $[0] = props.value; + $[1] = x; + } else { + x = $[1]; + } + const { length: y } = x; + foo(y); + let t0; + if ($[2] !== x || $[3] !== y) { + t0 = [x, y]; + $[2] = x; + $[3] = y; + $[4] = t0; + } else { + t0 = $[4]; + } + return t0; + } + + ``` +  + +FAIL: destructuring-object-pattern-within-rest +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + const [y, ...{z}] = props.value; + return [y, z]; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{value: ['y', {z: 'z!'}]}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(6); ++ Object.freeze(props); + let t0; + let y; + if ($[0] !== props.value) { + [y, ...t0] = props.value; + $[0] = props.value; + $[1] = t0; + $[2] = y; + } else { + t0 = $[1]; + y = $[2]; + } + const { z } = t0; + let t1; + if ($[3] !== y || $[4] !== z) { + t1 = [y, z]; + $[3] = y; + $[4] = z; + $[5] = t1; + } else { + t1 = $[5]; + } + return t1; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ value: ["y", { z: "z!" }] }], + }; + + ``` +  + ### Eval output + (kind: ok) ["y",null] + +FAIL: destructuring-object-param-default +- Expected ++ Received + + + ## Input + + ```javascript + function Component({a = 2}) { + return a; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + function Component(t0) { ++ Object.freeze(t0); + const { a: t1 } = t0; + const a = t1 === undefined ? 2 : t1; + return a; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: destructuring-object-default +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + const {x: {y} = {y: 'default'}} = props.y; + return y; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(2); ++ Object.freeze(props); + const { x: t0 } = props.y; + let t1; + if ($[0] !== t0) { + t1 = t0 === undefined ? { y: "default" } : t0; + $[0] = t0; + $[1] = t1; + } else { + t1 = $[1]; + } + const { y } = t1; + return y; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: destructuring-mixed-scope-declarations-and-locals +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + const post = useFragment( + graphql` + fragment F on T { + id + } + `, + 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 ; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(4); +- const post = useFragment( +- graphql` +- fragment F on T { +- id +- } +- `, +- props.post, +- ); ++ Object.freeze(props); ++ const post = (function () { ++ const $res$ = useFragment( ++ Object.freeze(graphql` ++ fragment F on T { ++ id ++ } ++ `), ++ Object.freeze(props.post), ++ ); ++ Object.freeze($res$); ++ return $res$; ++ })(); + let t0; + if ($[0] !== post) { + const allUrls = []; + + const { media, comments, urls } = post; + let t1; + if ($[2] !== comments.length) { + t1 = (e) => { + if (!comments.length) { + return; + } + + console.log(comments.length); + }; + $[2] = comments.length; + $[3] = t1; + } else { + t1 = $[3]; + } + const onClick = t1; + + allUrls.push(...urls); +- t0 = ; ++ t0 = ( ++  ++ ); + $[0] = post; + $[1] = t0; + } else { + t0 = $[1]; + } + return t0; + } + + ``` +  + +FAIL: destructuring-mixed-scope-and-local-variables-with-default + >> Unexpected error during test: + + +Found differences in evaluator results +Non-forget (expected): +(kind: ok)
{"media":null,"allUrls":["url1","url2","url3"],"onClick":"[[ function params=1 ]]"}
+Forget: +(kind: ok)
{"media":"[[ function params=0 ]]","allUrls":"[[ function params=0 ]]","onClick":"[[ function params=0 ]]"}
+ +FAIL: destructuring-default-past-end-of-array +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + // destructure past end of empty array, should evaluate to default + const [x = 42] = props.value; + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{value: []}], + }; + + ``` + + ## Code + + ```javascript + function Component(props) { ++ Object.freeze(props); ++ + const [t0] = props.value; + const x = t0 === undefined ? 42 : t0; + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ value: [] }], + }; + + ``` +  + ### Eval output + (kind: ok) 42 + +FAIL: destructuring-default-at-explicit-undefined +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + // destructure slot index has an explicit undefined in the input, should return default + const [x = 42] = props.value; + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{value: [undefined]}], + }; + + ``` + + ## Code + + ```javascript + function Component(props) { ++ Object.freeze(props); ++ + const [t0] = props.value; + const x = t0 === undefined ? 42 : t0; + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ value: [undefined] }], + }; + + ``` +  + ### Eval output + (kind: ok) 42 + +FAIL: destructuring-default-at-explicit-null +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + // destructure slot index has an explicit null in the input, should return null (not the default) + const [x = 42] = props.value; + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{value: [null]}], + }; + + ``` + + ## Code + + ```javascript + function Component(props) { ++ Object.freeze(props); ++ + const [t0] = props.value; + const x = t0 === undefined ? 42 : t0; + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ value: [null] }], + }; + + ``` +  + ### Eval output + (kind: ok) null + +FAIL: destructuring-default-at-array-hole +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + // destructure slot index has a hole in the input, should return default + const [x = 42] = props.value; + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{value: [, /* hole! */ 3.14]}], + }; + + ``` + + ## Code + + ```javascript + function Component(props) { ++ Object.freeze(props); ++ + const [t0] = props.value; + const x = t0 === undefined ? 42 : t0; + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ value: [, /* hole! */ 3.14] }], + }; + + ``` +  + ### Eval output + (kind: ok) 42 + +FAIL: destructuring-assignment +- Expected ++ Received + + + ## Input + + ```javascript + 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}; + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function foo(a, b, c) { + const $ = _c(5); ++ Object.freeze(a); ++ Object.freeze(b); ++ Object.freeze(c); + let d; + let g; + let n; + let o; + const [t0, t1] = a; + d = t0; + const [t2] = t1; + const { e: t3 } = t2; + ({ f: g } = t3); + const { l: t4, o: t5 } = b; + const { m: t6 } = t4; + const [t7] = t6; + [n] = t7; + o = t5; + let t8; + if ($[0] !== d || $[1] !== g || $[2] !== n || $[3] !== o) { + t8 = { d, g, n, o }; + $[0] = d; + $[1] = g; + $[2] = n; + $[3] = o; + $[4] = t8; + } else { + t8 = $[4]; + } + return t8; + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: destructuring-assignment-array-default +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + let x; + if (props.cond) { + [[x] = ['default']] = props.y; + } else { + x = props.fallback; + } + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(2); ++ Object.freeze(props); + let x; + if (props.cond) { + const [t0] = props.y; + let t1; + if ($[0] !== t0) { + t1 = t0 === undefined ? ["default"] : t0; + $[0] = t0; + $[1] = t1; + } else { + t1 = $[1]; + } + [x] = t1; + } else { + x = props.fallback; + } + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: destructuring-array-param-default +- Expected ++ Received + + + ## Input + + ```javascript + function Component([a = 2]) { + return a; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + function Component(t0) { ++ Object.freeze(t0); + const [t1] = t0; + const a = t1 === undefined ? 2 : t1; + return a; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: destructuring-array-default +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + const [[x] = ['default']] = props.y; + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(2); ++ Object.freeze(props); + const [t0] = props.y; + let t1; + if ($[0] !== t0) { + t1 = t0 === undefined ? ["default"] : t0; + $[0] = t0; + $[1] = t1; + } else { + t1 = $[1]; + } + const [x] = t1; + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: destructure-param-string-literal-key +- Expected ++ Received + + + ## Input + + ```javascript + function foo({data: dataTestID}) { + return dataTestID; + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: [{data: {}}], + isComponent: false, + }; + + ``` + + ## Code + + ```javascript + function foo(t0) { ++ Object.freeze(t0); + const { data: dataTestID } = t0; + return dataTestID; + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: [{ data: {} }], + isComponent: false, + }; + + ``` +  + ### Eval output + (kind: ok) {} + +FAIL: destructure-param-string-literal-key-invalid-identifier +- Expected ++ Received + + + ## Input + + ```javascript + function foo({'data-foo-bar': dataTestID}) { + return dataTestID; + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: [{'data-foo-bar': {}}], + isComponent: false, + }; + + ``` + + ## Code + + ```javascript + function foo(t0) { ++ Object.freeze(t0); + const { "data-foo-bar": dataTestID } = t0; + return dataTestID; + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: [{ "data-foo-bar": {} }], + isComponent: false, + }; + + ``` +  + ### Eval output + (kind: ok) {} + +FAIL: destructure-object-declaration-to-context-var +- Expected ++ Received + + + ## Input + + ```javascript + import {identity} from 'shared-runtime'; + + function Component(props) { + let {x} = props; + const foo = () => { + x = identity(props.x); + }; + foo(); + return {x}; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{x: 42}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { identity } from "shared-runtime"; + + function Component(props) { + const $ = _c(4); ++ Object.freeze(props); + let x; + if ($[0] !== props) { + const { x: t0 } = props; + x = t0; + const foo = () => { + x = identity(props.x); + }; + + foo(); + $[0] = props; + $[1] = x; + } else { + x = $[1]; + } + const t0 = x; + let t1; + if ($[2] !== t0) { + t1 = { x: t0 }; + $[2] = t0; + $[3] = t1; + } else { + t1 = $[3]; + } + return t1; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ x: 42 }], + }; + + ``` +  + ### Eval output + (kind: ok) {"x":42} + +FAIL: destructure-object-assignment-to-context-var +- Expected ++ Received + + + ## Input + + ```javascript + import {identity} from 'shared-runtime'; + + function Component(props) { + let x; + ({x} = props); + const foo = () => { + x = identity(props.x); + }; + foo(); + return {x}; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{x: 42}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { identity } from "shared-runtime"; + + function Component(props) { + const $ = _c(4); ++ Object.freeze(props); + let x; + if ($[0] !== props) { + const { x: t0 } = props; + x = t0; + const foo = () => { + x = identity(props.x); + }; + + foo(); + $[0] = props; + $[1] = x; + } else { + x = $[1]; + } + const t0 = x; + let t1; + if ($[2] !== t0) { + t1 = { x: t0 }; + $[2] = t0; + $[3] = t1; + } else { + t1 = $[3]; + } + return t1; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ x: 42 }], + }; + + ``` +  + ### Eval output + (kind: ok) {"x":42} + +FAIL: destructure-in-branch-ssa +- Expected ++ Received + + + ## Input + + ```javascript + function useFoo(props: { + x?: string; + y?: string; + z?: string; + doDestructure: boolean; + }) { + let x = null; + let y = null; + let z = null; + const myList = []; + if (props.doDestructure) { + ({x, y, z} = props); + + myList.push(z); + } + return { + x, + y, + myList, + }; + } + + export const FIXTURE_ENTRYPOINT = { + fn: useFoo, + params: [{x: 'hello', y: 'world', doDestructure: true}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function useFoo(props) { + const $ = _c(9); ++ Object.freeze(props); + + let x = null; + let y = null; + let z; + let myList; + if ($[0] !== props) { + myList = []; + if (props.doDestructure) { + ({ x, y, z } = props); + + myList.push(z); + } + $[0] = props; + $[1] = myList; + $[2] = x; + $[3] = y; + $[4] = z; + } else { + myList = $[1]; + x = $[2]; + y = $[3]; + z = $[4]; + } + let t0; + if ($[5] !== x || $[6] !== y || $[7] !== myList) { + t0 = { x, y, myList }; + $[5] = x; + $[6] = y; + $[7] = myList; + $[8] = t0; + } else { + t0 = $[8]; + } + return t0; + } + + export const FIXTURE_ENTRYPOINT = { + fn: useFoo, + params: [{ x: "hello", y: "world", doDestructure: true }], + }; + + ``` +  + ### Eval output + (kind: ok) {"x":"hello","y":"world","myList":[null]} + +FAIL: destructure-direct-reassignment +- Expected ++ Received + + + ## Input + + ```javascript + 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; + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + function foo(props) { ++ Object.freeze(props); + let x; + let y; + ({ x, y } = { x: props.a, y: props.b }); + console.log(x); + x = props.c; + return x + y; + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: destructure-default-array-with-unary +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + const [x = [-1, 1]] = props.value; + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{value: []}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(2); ++ Object.freeze(props); + const [t0] = props.value; + let t1; + if ($[0] !== t0) { + t1 = t0 === undefined ? [-1, 1] : t0; + $[0] = t0; + $[1] = t1; + } else { + t1 = $[1]; + } + const x = t1; + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ value: [] }], + }; + + ``` +  + ### Eval output + (kind: ok) [-1,1] + +FAIL: destructure-capture-global +- Expected ++ Received + + + ## Input + + ```javascript + let someGlobal = {}; + function component(a) { + let x = {a, someGlobal}; + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: component, + params: ['value 1'], + isComponent: false, + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + let someGlobal = {}; + function component(a) { + const $ = _c(2); ++ Object.freeze(a); + let t0; + if ($[0] !== a) { + t0 = { a, someGlobal }; + $[0] = a; + $[1] = t0; + } else { + t0 = $[1]; + } + const x = t0; + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: component, + params: ["value 1"], + isComponent: false, + }; + + ``` +  + ### Eval output + (kind: ok) {"a":"value 1","someGlobal":{}} + +FAIL: destructure-array-declaration-to-context-var +- Expected ++ Received + + + ## Input + + ```javascript + import {identity} from 'shared-runtime'; + + function Component(props) { + let [x] = props.value; + const foo = () => { + x = identity(props.value[0]); + }; + foo(); + return {x}; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{value: [42]}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { identity } from "shared-runtime"; + + function Component(props) { + const $ = _c(4); ++ Object.freeze(props); + let x; + if ($[0] !== props.value) { + const [t0] = props.value; + x = t0; + const foo = () => { + x = identity(props.value[0]); + }; + + foo(); + $[0] = props.value; + $[1] = x; + } else { + x = $[1]; + } + const t0 = x; + let t1; + if ($[2] !== t0) { + t1 = { x: t0 }; + $[2] = t0; + $[3] = t1; + } else { + t1 = $[3]; + } + return t1; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ value: [42] }], + }; + + ``` +  + ### Eval output + (kind: ok) {"x":42} + +FAIL: destructure-array-assignment-to-context-var +- Expected ++ Received + + + ## Input + + ```javascript + import {identity} from 'shared-runtime'; + + function Component(props) { + let x; + [x] = props.value; + const foo = () => { + x = identity(props.value[0]); + }; + foo(); + return {x}; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{value: [42]}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { identity } from "shared-runtime"; + + function Component(props) { + const $ = _c(4); ++ Object.freeze(props); + let x; + if ($[0] !== props.value) { + const [t0] = props.value; + x = t0; + const foo = () => { + x = identity(props.value[0]); + }; + + foo(); + $[0] = props.value; + $[1] = x; + } else { + x = $[1]; + } + const t0 = x; + let t1; + if ($[2] !== t0) { + t1 = { x: t0 }; + $[2] = t0; + $[3] = t1; + } else { + t1 = $[3]; + } + return t1; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ value: [42] }], + }; + + ``` +  + ### Eval output + (kind: ok) {"x":42} + +FAIL: dependencies +- Expected ++ Received + + + ## Input + + ```javascript + 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; + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function foo(x, y, z) { + const $ = _c(3); ++ Object.freeze(x); ++ Object.freeze(y); ++ Object.freeze(z); + const items = [z]; + items.push(x); + let items2; + if ($[0] !== x || $[1] !== y) { + items2 = []; + if (x) { + items2.push(y); + } + $[0] = x; + $[1] = y; + $[2] = items2; + } else { + items2 = $[2]; + } + if (y) { + items.push(x); + } + return items2; + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: dependencies-outputs +- Expected ++ Received + + + ## Input + + ```javascript + 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; + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function foo(a, b) { + const $ = _c(5); ++ Object.freeze(a); ++ Object.freeze(b); + let x; + if ($[0] !== a) { + x = []; + x.push(a); + $[0] = a; + $[1] = x; + } else { + x = $[1]; + } + let y; + if ($[2] !== x || $[3] !== b) { + y = []; + if (x.length) { + y.push(x); + } + if (b) { + y.push(b); + } + $[2] = x; + $[3] = b; + $[4] = y; + } else { + y = $[4]; + } + return y; + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: delete-property +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + const x = {a: props.a, b: props.b}; + delete x.b; + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(3); ++ Object.freeze(props); + let x; + if ($[0] !== props.a || $[1] !== props.b) { + x = { a: props.a, b: props.b }; + delete x.b; + $[0] = props.a; + $[1] = props.b; + $[2] = x; + } else { + x = $[2]; + } + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: delete-computed-property +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + const x = {a: props.a, b: props.b}; + const key = 'b'; + delete x[key]; + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(3); ++ Object.freeze(props); + let x; + if ($[0] !== props.a || $[1] !== props.b) { + x = { a: props.a, b: props.b }; + delete x["b"]; + $[0] = props.a; + $[1] = props.b; + $[2] = x; + } else { + x = $[2]; + } + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: default-param-with-reorderable-callback +- Expected ++ Received + + + ## Input + + ```javascript + function Component(x = () => [-1, true, 42.0, 'hello']) { + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [], + }; + + ``` + + ## Code + + ```javascript + function Component(t0) { ++ Object.freeze(t0); + const x = t0 === undefined ? _temp : t0; + return x; + } + function _temp() { + return [-1, true, 42, "hello"]; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [], + }; + + ``` +  + ### Eval output + (kind: ok) "[[ function params=0 ]]" + +FAIL: default-param-with-empty-callback +- Expected ++ Received + + + ## Input + + ```javascript + function Component(x = () => {}) { + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [], + }; + + ``` + + ## Code + + ```javascript + function Component(t0) { ++ Object.freeze(t0); + const x = t0 === undefined ? _temp : t0; + return x; + } + function _temp() {} + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [], + }; + + ``` +  + ### Eval output + (kind: ok) "[[ function params=0 ]]" + +FAIL: default-param-calls-global-function +- Expected ++ Received + + + ## Input + + ```javascript + import {identity} from 'shared-runtime'; + + function Component(x = identity([() => {}, true, 42, 'hello'])) { + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { identity } from "shared-runtime"; + + function Component(t0) { + const $ = _c(2); ++ Object.freeze(t0); + let t1; + if ($[0] !== t0) { + t1 = t0 === undefined ? identity([_temp, true, 42, "hello"]) : t0; + $[0] = t0; + $[1] = t1; + } else { + t1 = $[1]; + } + const x = t1; + return x; + } + function _temp() {} + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [], + }; + + ``` +  + ### Eval output + (kind: ok) ["[[ function params=0 ]]",true,42,"hello"] + +FAIL: default-param-array-with-unary +- Expected ++ Received + + + ## Input + + ```javascript + function Component(x = [-1, 1]) { + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(t0) { + const $ = _c(2); ++ Object.freeze(t0); + let t1; + if ($[0] !== t0) { + t1 = t0 === undefined ? [-1, 1] : t0; + $[0] = t0; + $[1] = t1; + } else { + t1 = $[1]; + } + const x = t1; + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [], + }; + + ``` +  + ### Eval output + (kind: ok) [-1,1] + +FAIL: declare-reassign-variable-in-closure +- Expected ++ Received + + + ## Input + + ```javascript + function Component(p) { + let x; + const foo = () => { + x = {}; + }; + foo(); + + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(p) { + const $ = _c(1); ++ Object.freeze(p); + let x; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + const foo = () => { + x = {}; + }; + + foo(); + $[0] = x; + } else { + x = $[0]; + } + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: debugger +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + debugger; + if (props.cond) { + debugger; + } else { + while (props.cond) { + debugger; + } + } + debugger; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + function Component(props) { ++ Object.freeze(props); + debugger; + if (props.cond) { + debugger; + } else { + while (props.cond) { + debugger; + } + } + debugger; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: debugger-memoized +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + const x = []; + debugger; + x.push(props.value); + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(2); ++ Object.freeze(props); + let x; + if ($[0] !== props.value) { + x = []; + debugger; + + x.push(props.value); + $[0] = props.value; + $[1] = x; + } else { + x = $[1]; + } + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: dce-unused-prefix-update +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + let i = 0; + --i; + i = props.i; + return i; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{i: 42}], + }; + + ``` + + ## Code + + ```javascript + function Component(props) { ++ Object.freeze(props); + let i; + + i = props.i; + return i; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ i: 42 }], + }; + + ``` +  + ### Eval output + (kind: ok) 42 + +FAIL: dce-unused-postfix-update +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + let i = 0; + i++; + i = props.i; + return i; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{i: 42}], + }; + + ``` + + ## Code + + ```javascript + function Component(props) { ++ Object.freeze(props); + let i; + + i = props.i; + return i; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ i: 42 }], + }; + + ``` +  + ### Eval output + (kind: ok) 42 + +FAIL: dce-unused-const +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + const _ = 42; + return props.value; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{value: 42}], + }; + + ``` + + ## Code + + ```javascript + function Component(props) { ++ Object.freeze(props); + return props.value; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ value: 42 }], + }; + + ``` +  + ### Eval output + (kind: ok) 42 + +FAIL: dce-loop +- Expected ++ Received + + + ## Input + + ```javascript + function foo(props) { + let x = 0; + let y = 0; + while (y < props.max) { + x++; + y++; + } + return y; + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: [{max: 10}], + isComponent: false, + }; + + ``` + + ## Code + + ```javascript + function foo(props) { ++ Object.freeze(props); ++ + let y = 0; + while (y < props.max) { + y++; + } + return y; + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: [{ max: 10 }], + isComponent: false, + }; + + ``` +  + ### Eval output + (kind: ok) 10 + +FAIL: createElement-freeze +- Expected ++ Received + + + ## Input + + ```javascript + import React from 'react'; + import {shallowCopy} from 'shared-runtime'; + + function Component(props) { + const childProps = {style: {width: props.width}}; + const element = React.createElement('div', childProps, ['hello world']); + shallowCopy(childProps); // function that in theory could mutate, we assume not bc createElement freezes + return element; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import React from "react"; + import { shallowCopy } from "shared-runtime"; + + function Component(props) { + const $ = _c(5); ++ Object.freeze(props); + let t0; + if ($[0] !== props.width) { + t0 = { style: { width: props.width } }; + $[0] = props.width; + $[1] = t0; + } else { + t0 = $[1]; + } + const childProps = t0; + let t1; + if ($[2] !== childProps) { + let t2; + if ($[4] === Symbol.for("react.memo_cache_sentinel")) { + t2 = ["hello world"]; + $[4] = t2; + } else { + t2 = $[4]; + } + t1 = React.createElement("div", childProps, t2); + $[2] = childProps; + $[3] = t1; + } else { + t1 = $[3]; + } + const element = t1; + shallowCopy(childProps); + return element; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + }; + + ``` +  + ### Eval output + (kind: ok)
hello world
 + +FAIL: controlled-input + >> Unexpected error during test: + + +Found differences in evaluator results +Non-forget (expected): +(kind: ok) +Forget: +(kind: ok) +logs: ['Warning: Invalid value for prop %s on <%s> tag. Either remove it from the element, or pass a string or number value to keep it in the DOM. For details, see https://react.dev/link/attribute-behavior %s','`value`','input','\n' + + ' at input\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)'] + +FAIL: context-variable-reassigned-two-lambdas +- Expected ++ Received + + + ## Input + + ```javascript + import {conditionalInvoke} from 'shared-runtime'; + + function Component({doReassign1, doReassign2}) { + let x = {}; + const reassign1 = () => { + x = 2; + }; + const reassign2 = () => { + x = 3; + }; + conditionalInvoke(doReassign1, reassign1); + conditionalInvoke(doReassign2, reassign2); + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{doReassign1: true, doReassign2: true}], + sequentialRenders: [ + {doReassign1: true, doReassign2: true}, + {doReassign1: true, doReassign2: false}, + {doReassign1: false, doReassign2: false}, + ], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { conditionalInvoke } from "shared-runtime"; + + function Component(t0) { + const $ = _c(3); ++ Object.freeze(t0); + const { doReassign1, doReassign2 } = t0; + let x; + if ($[0] !== doReassign1 || $[1] !== doReassign2) { + x = {}; + const reassign1 = () => { + x = 2; + }; + + const reassign2 = () => { + x = 3; + }; + + conditionalInvoke(doReassign1, reassign1); + conditionalInvoke(doReassign2, reassign2); + $[0] = doReassign1; + $[1] = doReassign2; + $[2] = x; + } else { + x = $[2]; + } + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ doReassign1: true, doReassign2: true }], + sequentialRenders: [ + { doReassign1: true, doReassign2: true }, + { doReassign1: true, doReassign2: false }, + { doReassign1: false, doReassign2: false }, + ], + }; + + ``` +  + ### Eval output + (kind: ok) 3 + 2 + {} + +FAIL: context-variable-reassigned-reactive-capture +- Expected ++ Received + + + ## Input + + ```javascript + import {invoke} from 'shared-runtime'; + + function Component({value}) { + let x = null; + const reassign = () => { + x = value; + }; + invoke(reassign); + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{value: 2}], + sequentialRenders: [{value: 2}, {value: 4}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { invoke } from "shared-runtime"; + + function Component(t0) { + const $ = _c(2); ++ Object.freeze(t0); + const { value } = t0; + let x; + if ($[0] !== value) { + x = null; + const reassign = () => { + x = value; + }; + + invoke(reassign); + $[0] = value; + $[1] = x; + } else { + x = $[1]; + } + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ value: 2 }], + sequentialRenders: [{ value: 2 }, { value: 4 }], + }; + + ``` +  + ### Eval output + (kind: ok) 2 + 4 + +FAIL: context-variable-reassigned-outside-of-lambda + >> Unexpected error during test: + + +Found differences in evaluator results +Non-forget (expected): +(kind: ok)
{"callback":{"kind":"Function"},"shouldInvokeFns":true}
+logs: [{}] +Forget: +(kind: ok)
{"callback":{"kind":"Function","result":{"kind":"Function"}},"shouldInvokeFns":{"kind":"Function","result":true}}
+logs: [{}] + +FAIL: context-variable-reassigned-objectmethod +- Expected ++ Received + + + ## Input + + ```javascript + import {invoke} from 'shared-runtime'; + + function Component({cond}) { + let x = 2; + const obj = { + method(cond) { + if (cond) { + x = 4; + } + }, + }; + invoke(obj.method, cond); + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{cond: true}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { invoke } from "shared-runtime"; + + function Component(t0) { + const $ = _c(2); ++ Object.freeze(t0); + const { cond } = t0; + let x; + if ($[0] !== cond) { + x = 2; + const obj = { + method(cond_0) { + if (cond_0) { + x = 4; + } + }, + }; + + invoke(obj.method, cond); + $[0] = cond; + $[1] = x; + } else { + x = $[1]; + } + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ cond: true }], + }; + + ``` +  + ### Eval output + (kind: ok) 4 + +FAIL: context-variable-reactive-implicit-control-flow +- Expected ++ Received + + + ## Input + + ```javascript + import {conditionalInvoke} from 'shared-runtime'; + + // same as context-variable-reactive-explicit-control-flow.js, but make + // the control flow implicit + + function Component({shouldReassign}) { + let x = null; + const reassign = () => { + x = 2; + }; + conditionalInvoke(shouldReassign, reassign); + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{shouldReassign: true}], + sequentialRenders: [{shouldReassign: false}, {shouldReassign: true}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { conditionalInvoke } from "shared-runtime"; + + // same as context-variable-reactive-explicit-control-flow.js, but make + // the control flow implicit + + function Component(t0) { + const $ = _c(2); ++ Object.freeze(t0); + const { shouldReassign } = t0; + let x; + if ($[0] !== shouldReassign) { + x = null; + const reassign = () => { + x = 2; + }; + + conditionalInvoke(shouldReassign, reassign); + $[0] = shouldReassign; + $[1] = x; + } else { + x = $[1]; + } + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ shouldReassign: true }], + sequentialRenders: [{ shouldReassign: false }, { shouldReassign: true }], + }; + + ``` +  + ### Eval output + (kind: ok) null + 2 + +FAIL: context-variable-reactive-explicit-control-flow +- Expected ++ Received + + + ## Input + + ```javascript + import {invoke} from 'shared-runtime'; + + function Component({shouldReassign}) { + let x = null; + const reassign = () => { + if (shouldReassign) { + x = 2; + } + }; + invoke(reassign); + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{shouldReassign: true}], + sequentialRenders: [{shouldReassign: false}, {shouldReassign: true}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { invoke } from "shared-runtime"; + + function Component(t0) { + const $ = _c(2); ++ Object.freeze(t0); + const { shouldReassign } = t0; + let x; + if ($[0] !== shouldReassign) { + x = null; + const reassign = () => { + if (shouldReassign) { + x = 2; + } + }; + + invoke(reassign); + $[0] = shouldReassign; + $[1] = x; + } else { + x = $[1]; + } + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ shouldReassign: true }], + sequentialRenders: [{ shouldReassign: false }, { shouldReassign: true }], + }; + + ``` +  + ### Eval output + (kind: ok) null + 2 + +FAIL: context-variable-as-jsx-element-tag +- Expected ++ Received + + + ## Input + + ```javascript + import {useMemo} from 'react'; + import {Stringify} from 'shared-runtime'; + + function Component(props) { + let Component = Stringify; + + Component = useMemo(() => { + return Component; + }); + + return ; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{name: 'Sathya'}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { useMemo } from "react"; + import { Stringify } from "shared-runtime"; + + function Component(props) { + const $ = _c(3); ++ Object.freeze(props); + let Component; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + Component = Stringify; + + Component; + let t0; + t0 = Component; + Component = t0; + $[0] = Component; + } else { + Component = $[0]; + } + let t0; + if ($[1] !== props) { + t0 = ; + $[1] = props; + $[2] = t0; + } else { + t0 = $[2]; + } + return t0; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ name: "Sathya" }], + }; + + ``` +  + ### Eval output + (kind: ok)
{"name":"Sathya"}
 + +FAIL: constructor +- Expected ++ Received + + + ## Input + + ```javascript + function Foo() {} + + function Component(props) { + const a = []; + const b = {}; + new Foo(a, b); + let _ =
; + new Foo(b); + return
; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Foo() {} + + function Component(props) { + const $ = _c(1); ++ Object.freeze(props); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + const a = []; + const b = {}; + new Foo(a, b); + new Foo(b); +- t0 =
; ++ t0 = ( ++  ++ ); + $[0] = t0; + } else { + t0 = $[0]; + } + return t0; + } + + ``` +  + +FAIL: constant-propagation-unary + >> Unexpected error during test: + + +Found differences in evaluator results +Non-forget (expected): +(kind: ok)
{"value":{"_b":"baz","b0":false,"n0":true,"n1":false,"n2":false,"n3":false,"s0":true,"s1":false,"s2":false,"u":true,"n":true}}
+Forget: +(kind: ok)
{"value":"[[ function params=0 ]]"}
+ +FAIL: constant-propagation-phi +- Expected ++ Received + + + ## Input + + ```javascript + function foo(a, b, c) { + let x; + if (a) { + x = 2 - 1; + } else { + x = 0 + 1; + } + if (x === 1) { + return b; + } else { + return c; + } + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + function foo(a, b, c) { ++ Object.freeze(a); ++ Object.freeze(b); ++ Object.freeze(c); + if (a) { + } + return b; + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: constant-propagation-into-function-expressions +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + const x = 42; + const onEvent = () => { + console.log(x); + }; + return ; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(1); ++ Object.freeze(props); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + const onEvent = () => { + console.log(42); + }; + +- t0 = ; ++ t0 = ( ++  ++ ); + $[0] = t0; + } else { + t0 = $[0]; + } + return t0; + } + + ``` +  + +FAIL: constant-propagation-bit-ops + >> Unexpected error during test: + + +Found differences in evaluator results +Non-forget (expected): +(kind: ok)
{"value":[123,0,123,123,123,123,123,1,122,246,61,61,9,15.588457268119896,12.25,3.3219970854839125,0,1.5,1,0.5]}
+Forget: +(kind: ok)
{"value":"[[ function params=0 ]]"}
+ +FAIL: constant-propagate-global-phis + >> Unexpected error during test: + + +Found differences in evaluator results +Non-forget (expected): +(kind: ok)
global string 1
+Forget: +(kind: ok)
+ +FAIL: constant-propagate-global-phis-constant + >> Unexpected error during test: + + +Found differences in evaluator results +Non-forget (expected): +(kind: ok)
global string 0
+Forget: +(kind: ok)
+logs: ['Warning: Functions are not valid as a React child. This may happen if you return %s instead of <%s /> from render. Or maybe you meant to call this function rather than return it.\n' + + ' <%s>{%s}%s','value','value','div','value','div','\n' + + ' at div\n' + + ' at Text (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/shared-runtime.js:183:61)\n' + + ' at WrapperTestComponent (/Users/mvitousek/react/compiler/packages/snap/dist/sprout/evaluator.js:89:26)'] + +FAIL: constant-computed +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + const index = 'foo'; + const x = {}; + x[index] = x[index] + x['bar']; + x[index](props.foo); + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(2); ++ Object.freeze(props); + let x; + if ($[0] !== props.foo) { + x = {}; + x.foo = x.foo + x.bar; + x.foo(props.foo); + $[0] = props.foo; + $[1] = x; + } else { + x = $[1]; + } + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: const-propagation-phi-nodes +- Expected ++ Received + + + ## Input + + ```javascript + function useFoo(setOne: boolean) { + let x; + let y; + let z; + if (setOne) { + x = y = z = 1; + } else { + x = 2; + y = 3; + z = 5; + } + return {x, y, z}; + } + + export const FIXTURE_ENTRYPOINT = { + fn: useFoo, + params: [true], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function useFoo(setOne) { + const $ = _c(4); ++ Object.freeze(setOne); + let x; + let y; + let z; + if (setOne) { + x = y = z = 1; + } else { + x = 2; + y = 3; + z = 5; + } + let t0; + if ($[0] !== x || $[1] !== y || $[2] !== z) { + t0 = { x, y, z }; + $[0] = x; + $[1] = y; + $[2] = z; + $[3] = t0; + } else { + t0 = $[3]; + } + return t0; + } + + export const FIXTURE_ENTRYPOINT = { + fn: useFoo, + params: [true], + }; + + ``` +  + ### Eval output + (kind: ok) {"x":1,"y":1,"z":1} + +FAIL: const-propagation-into-function-expression-global +- Expected ++ Received + + + ## Input + + ```javascript + function foo() { + const isX = GLOBAL_IS_X; + const getJSX = () => { + return ; + }; + const result = getJSX(); + return result; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function foo() { + const $ = _c(1); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { +- const getJSX = () => ; ++ const getJSX = () => ( ++  ++ ); + + t0 = getJSX(); + $[0] = t0; + } else { + t0 = $[0]; + } + const result = t0; + return result; + } + + ``` +  + +FAIL: console-readonly +- Expected ++ Received + + + ## Input + + ```javascript + import {shallowCopy} from 'shared-runtime'; + + function Component(props) { + const x = shallowCopy(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; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{a: 1, b: 2}], + isComponent: false, + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { shallowCopy } from "shared-runtime"; + + function Component(props) { + const $ = _c(2); ++ Object.freeze(props); + let t0; + if ($[0] !== props) { + t0 = shallowCopy(props); + $[0] = props; + $[1] = t0; + } else { + t0 = $[1]; + } + const x = t0; + + console.log(x); + console.info(x); + console.warn(x); + console.error(x); + console.trace(x); + console.table(x); + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ a: 1, b: 2 }], + isComponent: false, + }; + + ``` +  + ### Eval output + (kind: ok) {"a":1,"b":2} + logs: [{ a: 1, b: 2 },{ a: 1, b: 2 },{ a: 1, b: 2 },{ a: 1, b: 2 },{ a: 1, b: 2 }] + +FAIL: consecutive-use-memo +- Expected ++ Received + + + ## Input + + ```javascript + import {useMemo} from 'react'; + import {identity} from 'shared-runtime'; + + function useHook({a, b}) { + const valA = useMemo(() => identity({a}), [a]); + const valB = useMemo(() => identity([b]), [b]); + return [valA, valB]; + } + + export const FIXTURE_ENTRYPOINT = { + fn: useHook, + params: [{a: 2, b: 3}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { useMemo } from "react"; + import { identity } from "shared-runtime"; + + function useHook(t0) { + const $ = _c(7); ++ Object.freeze(t0); + const { a, b } = t0; + let t1; + let t2; + if ($[0] !== a) { + t2 = identity({ a }); + $[0] = a; + $[1] = t2; + } else { + t2 = $[1]; + } + t1 = t2; + const valA = t1; + let t3; + let t4; + if ($[2] !== b) { + t4 = identity([b]); + $[2] = b; + $[3] = t4; + } else { + t4 = $[3]; + } + t3 = t4; + const valB = t3; + let t5; + if ($[4] !== valA || $[5] !== valB) { + t5 = [valA, valB]; + $[4] = valA; + $[5] = valB; + $[6] = t5; + } else { + t5 = $[6]; + } + return t5; + } + + export const FIXTURE_ENTRYPOINT = { + fn: useHook, + params: [{ a: 2, b: 3 }], + }; + + ``` +  + ### Eval output + (kind: ok) [{"a":2},[3]] + +FAIL: conflicting-dollar-sign-variable +- Expected ++ Received + + + ## Input + + ```javascript + import {identity} from 'shared-runtime'; + + function Component(props) { + const $ = identity('jQuery'); + const t0 = identity([$]); + return t0; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { identity } from "shared-runtime"; + + function Component(props) { + const $0 = _c(1); ++ Object.freeze(props); + let t0; + if ($0[0] === Symbol.for("react.memo_cache_sentinel")) { + const $ = identity("jQuery"); + t0 = identity([$]); + $0[0] = t0; + } else { + t0 = $0[0]; + } + const t0$0 = t0; + return t0$0; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + }; + + ``` +  + ### Eval output + (kind: ok) ["jQuery"] + +FAIL: conditional-set-state-in-render +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + const [x, setX] = useState(0); + + const foo = () => { + setX(1); + }; + + if (props.cond) { + setX(2); + foo(); + } + + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + function Component(props) { +- const [x, setX] = useState(0); ++ Object.freeze(props); ++ const [x, setX] = (function () { ++ const $res$ = useState(Object.freeze(0)); ++ Object.freeze($res$); ++ return $res$; ++ })(); + + const foo = () => { + setX(1); + }; + if (props.cond) { + setX(2); + foo(); + } + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: conditional-on-mutable +- Expected ++ Received + + + ## Input + + ```javascript + 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() {} + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function ComponentA(props) { + const $ = _c(2); ++ Object.freeze(props); + let t0; + if ($[0] !== props) { + const a = []; + const b = []; + if (b) { + a.push(props.p0); + } + if (props.p1) { + b.push(props.p2); + } + +- t0 = ; ++ t0 = ( ++  ++ ); + $[0] = props; + $[1] = t0; + } else { + t0 = $[1]; + } + return t0; + } + + function ComponentB(props) { + const $ = _c(2); ++ Object.freeze(props); + let t0; + if ($[0] !== props) { + const a = []; + const b = []; + if (mayMutate(b)) { + a.push(props.p0); + } + if (props.p1) { + b.push(props.p2); + } + +- t0 = ; ++ t0 = ( ++  ++ ); + $[0] = props; + $[1] = t0; + } else { + t0 = $[1]; + } + return t0; + } + + function Foo() {} + function mayMutate() {} + + ``` +  + +FAIL: conditional-early-return +- Expected ++ Received + + + ## Input + + ```javascript + /** + * 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; + } + + export const FIXTURE_ENTRYPOINT = { + fn: ComponentA, + params: [{a: 1, b: false, d: 3}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; /** + * props.b does *not* influence `a` + */ + function ComponentA(props) { + const $ = _c(3); ++ Object.freeze(props); + let a_DEBUG; + let t0; + if ($[0] !== props) { + t0 = Symbol.for("react.early_return_sentinel"); + bb0: { + a_DEBUG = []; + a_DEBUG.push(props.a); + if (props.b) { + t0 = null; + break bb0; + } + + a_DEBUG.push(props.d); + } + $[0] = props; + $[1] = a_DEBUG; + $[2] = t0; + } else { + a_DEBUG = $[1]; + t0 = $[2]; + } + if (t0 !== Symbol.for("react.early_return_sentinel")) { + return t0; + } + return a_DEBUG; + } + + /** + * props.b *does* influence `a` + */ + function ComponentB(props) { + const $ = _c(2); ++ Object.freeze(props); + let a; + if ($[0] !== props) { + a = []; + a.push(props.a); + if (props.b) { + a.push(props.c); + } + + a.push(props.d); + $[0] = props; + $[1] = a; + } else { + a = $[1]; + } + return a; + } + + /** + * props.b *does* influence `a`, but only in a way that is never observable + */ + function ComponentC(props) { + const $ = _c(3); ++ Object.freeze(props); + let a; + let t0; + if ($[0] !== props) { + t0 = Symbol.for("react.early_return_sentinel"); + bb0: { + a = []; + a.push(props.a); + if (props.b) { + a.push(props.c); + t0 = null; + break bb0; + } + + a.push(props.d); + } + $[0] = props; + $[1] = a; + $[2] = t0; + } else { + a = $[1]; + t0 = $[2]; + } + if (t0 !== Symbol.for("react.early_return_sentinel")) { + return t0; + } + return a; + } + + /** + * props.b *does* influence `a` + */ + function ComponentD(props) { + const $ = _c(3); ++ Object.freeze(props); + let a; + let t0; + if ($[0] !== props) { + t0 = Symbol.for("react.early_return_sentinel"); + bb0: { + a = []; + a.push(props.a); + if (props.b) { + a.push(props.c); + t0 = a; + break bb0; + } + + a.push(props.d); + } + $[0] = props; + $[1] = a; + $[2] = t0; + } else { + a = $[1]; + t0 = $[2]; + } + if (t0 !== Symbol.for("react.early_return_sentinel")) { + return t0; + } + return a; + } + + export const FIXTURE_ENTRYPOINT = { + fn: ComponentA, + params: [{ a: 1, b: false, d: 3 }], + }; + + ``` +  + ### Eval output + (kind: ok) [1,3] + +FAIL: conditional-break-labeled +- Expected ++ Received + + + ## Input + + ```javascript + /** + * 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; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; /** + * props.b *does* influence `a` + */ + function Component(props) { + const $ = _c(2); ++ Object.freeze(props); + let a; + if ($[0] !== props) { + a = []; + a.push(props.a); + bb0: { + if (props.b) { + break bb0; + } + + a.push(props.c); + } + + a.push(props.d); + $[0] = props; + $[1] = a; + } else { + a = $[1]; + } + return a; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: concise-arrow-expr +- Expected ++ Received + + + ## Input + + ```javascript + function component() { + let [x, setX] = useState(0); + const handler = v => setX(v); + return ; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function component() { + const $ = _c(1); +- const [x, setX] = useState(0); ++ const [x, setX] = (function () { ++ const $res$ = useState(Object.freeze(0)); ++ Object.freeze($res$); ++ return $res$; ++ })(); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + const handler = (v) => setX(v); +- t0 = ; ++ t0 = ( ++  ++ ); + $[0] = t0; + } else { + t0 = $[0]; + } + return t0; + } + + ``` +  + +FAIL: computed-store-alias +- Expected ++ Received + + + ## Input + + ```javascript + function component(a, b) { + let y = {a}; + let x = {b}; + x['y'] = y; + mutate(x); + return x; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function component(a, b) { + const $ = _c(3); ++ Object.freeze(a); ++ Object.freeze(b); + let x; + if ($[0] !== a || $[1] !== b) { + const y = { a }; + x = { b }; + x.y = y; + mutate(x); + $[0] = a; + $[1] = b; + $[2] = x; + } else { + x = $[2]; + } + return x; + } + + ``` +  + +FAIL: computed-load-primitive-as-dependency +- Expected ++ Received + + + ## Input + + ```javascript + 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; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(2); ++ Object.freeze(props); + const a = foo(); + + const t0 = a[props.a] + 1; + let t1; + if ($[0] !== t0) { + t1 = bar(t0); + $[0] = t0; + $[1] = t1; + } else { + t1 = $[1]; + } + const b = t1; + return b; + } + + ``` +  + +FAIL: computed-call-spread +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + const x = foo[props.method](...props.a, null, ...props.b); + return x; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(4); ++ Object.freeze(props); + let t0; + if ($[0] !== props.method || $[1] !== props.a || $[2] !== props.b) { + t0 = foo[props.method](...props.a, null, ...props.b); + $[0] = props.method; + $[1] = props.a; + $[2] = props.b; + $[3] = t0; + } else { + t0 = $[3]; + } + const x = t0; + return x; + } + + ``` +  + +FAIL: component +- Expected ++ Received + + + ## Input + + ```javascript + 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} +
 + ); + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(8); ++ Object.freeze(props); + const items = props.items; + const maxItems = props.maxItems; + let renderedItems; + if ($[0] !== maxItems || $[1] !== items) { + renderedItems = []; + const seen = new Set(); + const max = Math.max(0, maxItems); + for (let i = 0; i < items.length; i = i + 1, i) { + const item = items.at(i); + if (item == null || seen.has(item)) { + continue; + } + + seen.add(item); + renderedItems.push(
{item}
); + if (renderedItems.length >= max) { + break; + } + } + $[0] = maxItems; + $[1] = items; + $[2] = renderedItems; + } else { + renderedItems = $[2]; + } + + const count = renderedItems.length; + let t0; + if ($[3] !== count) { + t0 =

{count} Items

; + $[3] = count; + $[4] = t0; + } else { + t0 = $[4]; + } + let t1; + if ($[5] !== t0 || $[6] !== renderedItems) { + t1 = ( +
 + {t0} + {renderedItems} +
 + ); + $[5] = t0; + $[6] = renderedItems; + $[7] = t1; + } else { + t1 = $[7]; + } + return t1; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: component-inner-function-with-many-args + >> Unexpected error during test: + + +Found differences in evaluator results +Non-forget (expected): +(kind: ok)
{"cb":"[[ function params=3 ]]","id":0}
+Forget: +(kind: ok)
{"cb":"[[ function params=0 ]]","id":"[[ function params=0 ]]"}
+ +FAIL: component-declaration-basic.flow +- Expected ++ Received + + + ## Input + + ```javascript + // @flow @compilationMode(infer) + export default component Foo(bar: number) { + return ; + } + + function shouldNotCompile() {} + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + export default function Foo(t0) { + const $ = _c(2); ++ Object.freeze(t0); + const { bar } = t0; + let t1; + if ($[0] !== bar) { +- t1 = ; ++ t1 = ( ++  ++ ); + $[0] = bar; + $[1] = t1; + } else { + t1 = $[1]; + } + return t1; + } + + function shouldNotCompile() {} + + ``` +  + +FAIL: complex-while +- Expected ++ Received + + + ## Input + + ```javascript + function foo(a, b, c) { + label: if (a) { + while (b) { + if (c) { + break label; + } + } + } + return c; + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + function foo(a, b, c) { ++ Object.freeze(a); ++ Object.freeze(b); ++ Object.freeze(c); + bb0: if (a) { + while (b) { + if (c) { + break bb0; + } + } + } + return c; + } + + export const FIXTURE_ENTRYPOINT = { + fn: foo, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: codegen-instrument-forget-test +- Expected ++ Received + + + ## Input + + ```javascript + // @instrumentForget @compilationMode(annotation) + + function Bar(props) { + 'use forget'; + return
{props.bar}
; + } + + function NoForget(props) { + return {props.noForget}; + } + + function Foo(props) { + 'use forget'; + return {props.bar}; + } + + ``` + + ## Code + + ```javascript + import { useRenderCounter, shouldInstrument } from "react-compiler-runtime"; + import { c as _c } from "react/compiler-runtime"; // @instrumentForget @compilationMode(annotation) + + function Bar(props) { +- "use forget"; + if (__DEV__ && shouldInstrument) + useRenderCounter("Bar", "/codegen-instrument-forget-test.ts"); + const $ = _c(2); ++ Object.freeze(props); + let t0; + if ($[0] !== props.bar) { + t0 =
{props.bar}
; + $[0] = props.bar; + $[1] = t0; + } else { + t0 = $[1]; + } + return t0; + } + + function NoForget(props) { + return {props.noForget}; + } + + function Foo(props) { +- "use forget"; + if (__DEV__ && shouldInstrument) + useRenderCounter("Foo", "/codegen-instrument-forget-test.ts"); + const $ = _c(2); ++ Object.freeze(props); + let t0; + if ($[0] !== props.bar) { + t0 = {props.bar}; + $[0] = props.bar; + $[1] = t0; + } else { + t0 = $[1]; + } + return t0; + } + + ``` +  + +FAIL: codegen-instrument-forget-gating-test +- Expected ++ Received + + + ## Input + + ```javascript + // @instrumentForget @compilationMode(annotation) @gating + + function Bar(props) { + 'use forget'; + return
{props.bar}
; + } + + function NoForget(props) { + return {props.noForget}; + } + + function Foo(props) { + 'use forget'; + return {props.bar}; + } + + ``` + + ## Code + + ```javascript + import { isForgetEnabled_Fixtures } from "ReactForgetFeatureFlag"; + import { useRenderCounter, shouldInstrument } from "react-compiler-runtime"; + import { c as _c } from "react/compiler-runtime"; // @instrumentForget @compilationMode(annotation) @gating + const Bar = isForgetEnabled_Fixtures() + ? function Bar(props) { +- "use forget"; + if (__DEV__ && shouldInstrument) + useRenderCounter("Bar", "/codegen-instrument-forget-gating-test.ts"); + const $ = _c(2); ++ Object.freeze(props); + let t0; + if ($[0] !== props.bar) { + t0 =
{props.bar}
; + $[0] = props.bar; + $[1] = t0; + } else { + t0 = $[1]; + } + return t0; + } + : function Bar(props) { + "use forget"; + return
{props.bar}
; + }; + + function NoForget(props) { + return {props.noForget}; + } + const Foo = isForgetEnabled_Fixtures() + ? function Foo(props) { +- "use forget"; + if (__DEV__ && shouldInstrument) + useRenderCounter("Foo", "/codegen-instrument-forget-gating-test.ts"); + const $ = _c(2); ++ Object.freeze(props); + let t0; + if ($[0] !== props.bar) { + t0 = {props.bar}; + $[0] = props.bar; + $[1] = t0; + } else { + t0 = $[1]; + } + return t0; + } + : function Foo(props) { + "use forget"; + return {props.bar}; + }; + + ``` +  + +FAIL: codegen-emit-make-read-only +- Expected ++ Received + + + ## Input + + ```javascript + // @enableEmitFreeze true + + function MyComponentName(props) { + let x = {}; + foo(x, props.a); + foo(x, props.b); + + let y = []; + y.push(x); + return y; + } + + ``` + + ## Code + + ```javascript + import { makeReadOnly } from "react-compiler-runtime"; + import { c as _c } from "react/compiler-runtime"; // @enableEmitFreeze true + + function MyComponentName(props) { + const $ = _c(3); ++ Object.freeze(props); + let y; + if ($[0] !== props.a || $[1] !== props.b) { + const x = {}; + foo(x, props.a); + foo(x, props.b); + + y = []; + y.push(x); + $[0] = props.a; + $[1] = props.b; + $[2] = __DEV__ ? makeReadOnly(y, "MyComponentName") : y; + } else { + y = $[2]; + } + return y; + } + + ``` +  + +FAIL: codegen-emit-imports-same-source +- Expected ++ Received + + + ## Input + + ```javascript + // @enableEmitFreeze @instrumentForget + + function useFoo(props) { + return foo(props.x); + } + + ``` + + ## Code + + ```javascript + import { + useRenderCounter, + shouldInstrument, + makeReadOnly, + } from "react-compiler-runtime"; + import { c as _c } from "react/compiler-runtime"; // @enableEmitFreeze @instrumentForget + + function useFoo(props) { + if (__DEV__ && shouldInstrument) + useRenderCounter("useFoo", "/codegen-emit-imports-same-source.ts"); + const $ = _c(2); ++ Object.freeze(props); + let t0; + if ($[0] !== props.x) { + t0 = foo(props.x); + $[0] = props.x; + $[1] = __DEV__ ? makeReadOnly(t0, "useFoo") : t0; + } else { + t0 = $[1]; + } + return t0; + } + + ``` +  + +FAIL: change-detect-reassign +- Expected ++ Received + + + ## Input + + ```javascript + // @enableChangeDetectionForDebugging + function Component(props) { + let x = null; + if (props.cond) { + x = []; + x.push(props.value); + } + return x; + } + + ``` + + ## Code + + ```javascript + import { $structuralCheck } from "react-compiler-runtime"; + import { c as _c } from "react/compiler-runtime"; // @enableChangeDetectionForDebugging + function Component(props) { + const $ = _c(2); ++ Object.freeze(props); + let x = null; + if (props.cond) { + { + x = []; + x.push(props.value); + let condition = $[0] !== props.value; + if (!condition) { + let old$x = $[1]; + $structuralCheck(old$x, x, "x", "Component", "cached", "(3:6)"); + } + $[0] = props.value; + $[1] = x; + if (condition) { + x = []; + x.push(props.value); + $structuralCheck($[1], x, "x", "Component", "recomputed", "(3:6)"); + x = $[1]; + } + } + } + return x; + } + + ``` +  + +FAIL: capturing-variable-in-nested-function +- Expected ++ Received + + + ## Input + + ```javascript + function component(a) { + let z = {a}; + let x = function () { + (function () { + console.log(z); + })(); + }; + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: component, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function component(a) { + const $ = _c(4); ++ Object.freeze(a); + let t0; + if ($[0] !== a) { + t0 = { a }; + $[0] = a; + $[1] = t0; + } else { + t0 = $[1]; + } + const z = t0; + let t1; + if ($[2] !== z) { + t1 = function () { + (function () { + console.log(z); + })(); + }; + $[2] = z; + $[3] = t1; + } else { + t1 = $[3]; + } + const x = t1; + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: component, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: capturing-variable-in-nested-block +- Expected ++ Received + + + ## Input + + ```javascript + function component(a) { + let z = {a}; + let x = function () { + { + console.log(z); + } + }; + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: component, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function component(a) { + const $ = _c(4); ++ Object.freeze(a); + let t0; + if ($[0] !== a) { + t0 = { a }; + $[0] = a; + $[1] = t0; + } else { + t0 = $[1]; + } + const z = t0; + let t1; + if ($[2] !== z) { + t1 = function () { + console.log(z); + }; + $[2] = z; + $[3] = t1; + } else { + t1 = $[3]; + } + const x = t1; + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: component, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: capturing-reference-changes-type +- Expected ++ Received + + + ## Input + + ```javascript + function component(a) { + let x = {a}; + let y = 1; + (function () { + y = x; + })(); + mutate(y); + return y; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function component(a) { + const $ = _c(2); ++ Object.freeze(a); + let y; + if ($[0] !== a) { + const x = { a }; + y = 1; + + y; + y = x; + + mutate(y); + $[0] = a; + $[1] = y; + } else { + y = $[1]; + } + return y; + } + + ``` +  + +FAIL: capturing-nested-member-expr +- Expected ++ Received + + + ## Input + + ```javascript + function component(a) { + let z = {a: {a}}; + let x = function () { + console.log(z.a.a); + }; + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: component, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function component(a) { + const $ = _c(4); ++ Object.freeze(a); + let t0; + if ($[0] !== a) { + t0 = { a: { a } }; + $[0] = a; + $[1] = t0; + } else { + t0 = $[1]; + } + const z = t0; + let t1; + if ($[2] !== z.a.a) { + t1 = function () { + console.log(z.a.a); + }; + $[2] = z.a.a; + $[3] = t1; + } else { + t1 = $[3]; + } + const x = t1; + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: component, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: capturing-nested-member-expr-in-nested-func +- Expected ++ Received + + + ## Input + + ```javascript + function component(a) { + let z = {a: {a}}; + let x = function () { + (function () { + console.log(z.a.a); + })(); + }; + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: component, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function component(a) { + const $ = _c(4); ++ Object.freeze(a); + let t0; + if ($[0] !== a) { + t0 = { a: { a } }; + $[0] = a; + $[1] = t0; + } else { + t0 = $[1]; + } + const z = t0; + let t1; + if ($[2] !== z.a.a) { + t1 = function () { + (function () { + console.log(z.a.a); + })(); + }; + $[2] = z.a.a; + $[3] = t1; + } else { + t1 = $[3]; + } + const x = t1; + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: component, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: capturing-nested-member-call +- Expected ++ Received + + + ## Input + + ```javascript + function component(a) { + let z = {a: {a}}; + let x = function () { + z.a.a(); + }; + return z; + } + + export const FIXTURE_ENTRYPOINT = { + fn: component, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function component(a) { + const $ = _c(2); ++ Object.freeze(a); + let t0; + if ($[0] !== a) { + t0 = { a: { a } }; + $[0] = a; + $[1] = t0; + } else { + t0 = $[1]; + } + const z = t0; + return z; + } + + export const FIXTURE_ENTRYPOINT = { + fn: component, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: capturing-member-expr +- Expected ++ Received + + + ## Input + + ```javascript + function component(a) { + let z = {a}; + let x = function () { + console.log(z.a); + }; + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: component, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function component(a) { + const $ = _c(4); ++ Object.freeze(a); + let t0; + if ($[0] !== a) { + t0 = { a }; + $[0] = a; + $[1] = t0; + } else { + t0 = $[1]; + } + const z = t0; + let t1; + if ($[2] !== z.a) { + t1 = function () { + console.log(z.a); + }; + $[2] = z.a; + $[3] = t1; + } else { + t1 = $[3]; + } + const x = t1; + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: component, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: capturing-function-within-block +- Expected ++ Received + + + ## Input + + ```javascript + function component(a) { + let z = {a}; + let x; + { + x = function () { + console.log(z); + }; + } + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: component, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function component(a) { + const $ = _c(4); ++ Object.freeze(a); + let t0; + if ($[0] !== a) { + t0 = { a }; + $[0] = a; + $[1] = t0; + } else { + t0 = $[1]; + } + const z = t0; + let x; + let t1; + if ($[2] !== z) { + t1 = function () { + console.log(z); + }; + $[2] = z; + $[3] = t1; + } else { + t1 = $[3]; + } + x = t1; + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: component, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: capturing-function-skip-computed-path +- Expected ++ Received + + + ## Input + + ```javascript + function StoreLandingUnseenGiftModalContainer(a) { + const giftsSeen = {a}; + return (gift => (gift.id ? giftsSeen[gift.id] : false))(); + } + + export const FIXTURE_ENTRYPOINT = { + fn: StoreLandingUnseenGiftModalContainer, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function StoreLandingUnseenGiftModalContainer(a) { + const $ = _c(2); ++ Object.freeze(a); + let t0; + if ($[0] !== a) { + const giftsSeen = { a }; + t0 = ((gift) => (gift.id ? giftsSeen[gift.id] : false))(); + $[0] = a; + $[1] = t0; + } else { + t0 = $[1]; + } + return t0; + } + + export const FIXTURE_ENTRYPOINT = { + fn: StoreLandingUnseenGiftModalContainer, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: capturing-function-shadow-captured +- Expected ++ Received + + + ## Input + + ```javascript + function component(a) { + let z = {a}; + let x = function () { + let z; + mutate(z); + }; + return x; + } + + ``` + + ## Code + + ```javascript + function component(a) { ++ Object.freeze(a); ++ + const x = _temp; + return x; + } + function _temp() { + let z_0; + mutate(z_0); + } + + ``` +  + +FAIL: capturing-function-runs-inference +- Expected ++ Received + + + ## Input + + ```javascript + function component(a, b) { + let z = {a}; + let p = () => {z}; + return p(); + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function component(a, b) { + const $ = _c(6); ++ Object.freeze(a); ++ Object.freeze(b); + let t0; + if ($[0] !== a) { + t0 = { a }; + $[0] = a; + $[1] = t0; + } else { + t0 = $[1]; + } + const z = t0; + let t1; + if ($[2] !== z) { + t1 = () => {z}; + $[2] = z; + $[3] = t1; + } else { + t1 = $[3]; + } + const p = t1; + let t2; + if ($[4] !== p) { + t2 = p(); + $[4] = p; + $[5] = t2; + } else { + t2 = $[5]; + } + return t2; + } + + ``` +  + +FAIL: capturing-function-renamed-ref +- Expected ++ Received + + + ## Input + + ```javascript + function component(a, b) { + let z = {a}; + { + let z = {b}; + (function () { + mutate(z); + })(); + } + return z; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function component(a, b) { + const $ = _c(2); ++ Object.freeze(a); ++ Object.freeze(b); + let t0; + if ($[0] !== a) { + t0 = { a }; + $[0] = a; + $[1] = t0; + } else { + t0 = $[1]; + } + const z = t0; + + const z_0 = { b }; + + mutate(z_0); + return z; + } + + ``` +  + +FAIL: capturing-function-member-expr-call +- Expected ++ Received + + + ## Input + + ```javascript + function component({mutator}) { + const poke = () => { + mutator.poke(); + }; + + const hide = () => { + mutator.user.hide(); + }; + + return ; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function component(t0) { + const $ = _c(7); ++ Object.freeze(t0); + const { mutator } = t0; + let t1; + if ($[0] !== mutator) { + t1 = () => { + mutator.poke(); + }; + $[0] = mutator; + $[1] = t1; + } else { + t1 = $[1]; + } + const poke = t1; + let t2; + if ($[2] !== mutator.user) { + t2 = () => { + mutator.user.hide(); + }; + $[2] = mutator.user; + $[3] = t2; + } else { + t2 = $[3]; + } + const hide = t2; + let t3; + if ($[4] !== poke || $[5] !== hide) { +- t3 = ; ++ t3 = ( ++  ++ ); + $[4] = poke; + $[5] = hide; + $[6] = t3; + } else { + t3 = $[6]; + } + return t3; + } + + ``` +  + +FAIL: capturing-function-member-expr-arguments +- Expected ++ Received + + + ## Input + + ```javascript + function Foo(props) { + const onFoo = useCallback( + reason => { + log(props.router.location); + }, + [props.router.location] + ); + + return onFoo; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Foo(props) { + const $ = _c(2); ++ Object.freeze(props); + let t0; + if ($[0] !== props.router.location) { + t0 = (reason) => { + log(props.router.location); + }; + $[0] = props.router.location; + $[1] = t0; + } else { + t0 = $[1]; + } + const onFoo = t0; + return onFoo; + } + + ``` +  + +FAIL: capturing-function-decl +- Expected ++ Received + + + ## Input + + ```javascript + function component(a) { + let t = {a}; + function x() { + t.foo(); + } + x(t); + return t; + } + + export const FIXTURE_ENTRYPOINT = { + fn: component, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function component(a) { + const $ = _c(2); ++ Object.freeze(a); + let t; + if ($[0] !== a) { + t = { a }; + const x = function x() { + t.foo(); + }; + + x(t); + $[0] = a; + $[1] = t; + } else { + t = $[1]; + } + return t; + } + + export const FIXTURE_ENTRYPOINT = { + fn: component, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: capturing-function-conditional-capture-mutate +- Expected ++ Received + + + ## Input + + ```javascript + // @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; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; // @debug + function component(a, b) { + const $ = _c(5); ++ Object.freeze(a); ++ Object.freeze(b); + let t0; + if ($[0] !== a) { + t0 = { a }; + $[0] = a; + $[1] = t0; + } else { + t0 = $[1]; + } + const z = t0; + const y = b; + let t1; + if ($[2] !== y || $[3] !== z) { + t1 = function () { + if (y) { + maybeMutate(z); + } + }; + $[2] = y; + $[3] = z; + $[4] = t1; + } else { + t1 = $[4]; + } + const x = t1; + return x; + } + + ``` +  + +FAIL: capturing-function-capture-ref-before-rename +- Expected ++ Received + + + ## Input + + ```javascript + 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; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function component(a, b) { + const $ = _c(7); ++ Object.freeze(a); ++ Object.freeze(b); + let z; + if ($[0] !== a) { + z = { a }; + + mutate(z); + $[0] = a; + $[1] = z; + } else { + z = $[1]; + } + + let y = z; + let t0; + if ($[2] !== b) { + t0 = { b }; + $[2] = b; + $[3] = t0; + } else { + t0 = $[3]; + } + const z_0 = t0; + let t1; + if ($[4] !== y || $[5] !== z_0) { + t1 = { y, z: z_0 }; + $[4] = y; + $[5] = z_0; + $[6] = t1; + } else { + t1 = $[6]; + } + y = t1; + return y; + } + + ``` +  + +FAIL: capturing-function-alias-computed-load +- Expected ++ Received + + + ## Input + + ```javascript + function bar(a) { + let x = [a]; + let y = {}; + const f0 = function () { + y = x[0]; + }; + f0(); + + return y; + } + + export const FIXTURE_ENTRYPOINT = { + fn: bar, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function bar(a) { + const $ = _c(2); ++ Object.freeze(a); + let y; + if ($[0] !== a) { + const x = [a]; + y = {}; + const f0 = function () { + y = x[0]; + }; + + f0(); + $[0] = a; + $[1] = y; + } else { + y = $[1]; + } + return y; + } + + export const FIXTURE_ENTRYPOINT = { + fn: bar, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: capturing-function-alias-computed-load-iife +- Expected ++ Received + + + ## Input + + ```javascript + function bar(a) { + let x = [a]; + let y = {}; + (function () { + y = x[0]; + })(); + + return y; + } + + export const FIXTURE_ENTRYPOINT = { + fn: bar, + params: ['TodoAdd'], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function bar(a) { + const $ = _c(2); ++ Object.freeze(a); + let y; + if ($[0] !== a) { + const x = [a]; + y = {}; + + y; + y = x[0]; + $[0] = a; + $[1] = y; + } else { + y = $[1]; + } + return y; + } + + export const FIXTURE_ENTRYPOINT = { + fn: bar, + params: ["TodoAdd"], + }; + + ``` +  + ### Eval output + (kind: ok) "TodoAdd" + +FAIL: capturing-function-alias-computed-load-4 +- Expected ++ Received + + + ## Input + + ```javascript + function bar(a) { + let x = [a]; + let y = {}; + const f0 = function () { + y = x[0].a[1]; + }; + f0(); + + return y; + } + + export const FIXTURE_ENTRYPOINT = { + fn: bar, + params: [{a: ['val1', 'val2']}], + isComponent: false, + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function bar(a) { + const $ = _c(2); ++ Object.freeze(a); + let y; + if ($[0] !== a) { + const x = [a]; + y = {}; + const f0 = function () { + y = x[0].a[1]; + }; + + f0(); + $[0] = a; + $[1] = y; + } else { + y = $[1]; + } + return y; + } + + export const FIXTURE_ENTRYPOINT = { + fn: bar, + params: [{ a: ["val1", "val2"] }], + isComponent: false, + }; + + ``` +  + ### Eval output + (kind: ok) "val2" + +FAIL: capturing-function-alias-computed-load-4-iife +- Expected ++ Received + + + ## Input + + ```javascript + function bar(a) { + let x = [a]; + let y = {}; + (function () { + y = x[0].a[1]; + })(); + + return y; + } + + export const FIXTURE_ENTRYPOINT = { + fn: bar, + params: [{a: ['val1', 'val2']}], + isComponent: false, + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function bar(a) { + const $ = _c(2); ++ Object.freeze(a); + let y; + if ($[0] !== a) { + const x = [a]; + y = {}; + + y; + y = x[0].a[1]; + $[0] = a; + $[1] = y; + } else { + y = $[1]; + } + return y; + } + + export const FIXTURE_ENTRYPOINT = { + fn: bar, + params: [{ a: ["val1", "val2"] }], + isComponent: false, + }; + + ``` +  + ### Eval output + (kind: ok) "val2" + +FAIL: capturing-function-alias-computed-load-3 +- Expected ++ Received + + + ## Input + + ```javascript + function bar(a, b) { + let x = [a, b]; + let y = {}; + let t = {}; + const f0 = function () { + y = x[0][1]; + t = x[1][0]; + }; + f0(); + + return y; + } + + export const FIXTURE_ENTRYPOINT = { + fn: bar, + params: [ + [1, 2], + [2, 3], + ], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function bar(a, b) { + const $ = _c(3); ++ Object.freeze(a); ++ Object.freeze(b); + let y; + if ($[0] !== a || $[1] !== b) { + const x = [a, b]; + y = {}; + let t; + t = {}; + const f0 = function () { + y = x[0][1]; + t = x[1][0]; + }; + + f0(); + $[0] = a; + $[1] = b; + $[2] = y; + } else { + y = $[2]; + } + return y; + } + + export const FIXTURE_ENTRYPOINT = { + fn: bar, + params: [ + [1, 2], + [2, 3], + ], + }; + + ``` +  + ### Eval output + (kind: ok) 2 + +FAIL: capturing-function-alias-computed-load-3-iife +- Expected ++ Received + + + ## Input + + ```javascript + function bar(a, b) { + let x = [a, b]; + let y = {}; + let t = {}; + (function () { + y = x[0][1]; + t = x[1][0]; + })(); + + return y; + } + + export const FIXTURE_ENTRYPOINT = { + fn: bar, + params: [ + [1, 2], + [2, 3], + ], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function bar(a, b) { + const $ = _c(3); ++ Object.freeze(a); ++ Object.freeze(b); + let y; + if ($[0] !== a || $[1] !== b) { + const x = [a, b]; + y = {}; + let t; + t = {}; + + y; + t; + y = x[0][1]; + t = x[1][0]; + $[0] = a; + $[1] = b; + $[2] = y; + } else { + y = $[2]; + } + return y; + } + + export const FIXTURE_ENTRYPOINT = { + fn: bar, + params: [ + [1, 2], + [2, 3], + ], + }; + + ``` +  + ### Eval output + (kind: ok) 2 + +FAIL: capturing-function-alias-computed-load-2 +- Expected ++ Received + + + ## Input + + ```javascript + function bar(a) { + let x = [a]; + let y = {}; + const f0 = function () { + y = x[0][1]; + }; + f0(); + + return y; + } + + export const FIXTURE_ENTRYPOINT = { + fn: bar, + params: [['val1', 'val2']], + isComponent: false, + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function bar(a) { + const $ = _c(2); ++ Object.freeze(a); + let y; + if ($[0] !== a) { + const x = [a]; + y = {}; + const f0 = function () { + y = x[0][1]; + }; + + f0(); + $[0] = a; + $[1] = y; + } else { + y = $[1]; + } + return y; + } + + export const FIXTURE_ENTRYPOINT = { + fn: bar, + params: [["val1", "val2"]], + isComponent: false, + }; + + ``` +  + ### Eval output + (kind: ok) "val2" + +FAIL: capturing-function-alias-computed-load-2-iife +- Expected ++ Received + + + ## Input + + ```javascript + function bar(a) { + let x = [a]; + let y = {}; + (function () { + y = x[0][1]; + })(); + + return y; + } + + export const FIXTURE_ENTRYPOINT = { + fn: bar, + params: [['val1', 'val2']], + isComponent: false, + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function bar(a) { + const $ = _c(2); ++ Object.freeze(a); + let y; + if ($[0] !== a) { + const x = [a]; + y = {}; + + y; + y = x[0][1]; + $[0] = a; + $[1] = y; + } else { + y = $[1]; + } + return y; + } + + export const FIXTURE_ENTRYPOINT = { + fn: bar, + params: [["val1", "val2"]], + isComponent: false, + }; + + ``` +  + ### Eval output + (kind: ok) "val2" + +FAIL: capturing-function-1 +- Expected ++ Received + + + ## Input + + ```javascript + function component(a) { + let z = {a}; + let x = function () { + console.log(z); + }; + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: component, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function component(a) { + const $ = _c(4); ++ Object.freeze(a); + let t0; + if ($[0] !== a) { + t0 = { a }; + $[0] = a; + $[1] = t0; + } else { + t0 = $[1]; + } + const z = t0; + let t1; + if ($[2] !== z) { + t1 = function () { + console.log(z); + }; + $[2] = z; + $[3] = t1; + } else { + t1 = $[3]; + } + const x = t1; + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: component, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: capturing-func-simple-alias +- Expected ++ Received + + + ## Input + + ```javascript + function component(a) { + let x = {a}; + let y = {}; + const f0 = function () { + y = x; + }; + f0(); + mutate(y); + return y; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function component(a) { + const $ = _c(2); ++ Object.freeze(a); + let y; + if ($[0] !== a) { + const x = { a }; + y = {}; + const f0 = function () { + y = x; + }; + + f0(); + mutate(y); + $[0] = a; + $[1] = y; + } else { + y = $[1]; + } + return y; + } + + ``` +  + +FAIL: capturing-func-simple-alias-iife +- Expected ++ Received + + + ## Input + + ```javascript + const {mutate} = require('shared-runtime'); + + function component(a) { + let x = {a}; + let y = {}; + (function () { + y = x; + })(); + mutate(y); + return y; + } + + export const FIXTURE_ENTRYPOINT = { + fn: component, + params: ['foo'], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + const { mutate } = require("shared-runtime"); + + function component(a) { + const $ = _c(2); ++ Object.freeze(a); + let y; + if ($[0] !== a) { + const x = { a }; + y = {}; + + y; + y = x; + + mutate(y); + $[0] = a; + $[1] = y; + } else { + y = $[1]; + } + return y; + } + + export const FIXTURE_ENTRYPOINT = { + fn: component, + params: ["foo"], + }; + + ``` +  + ### Eval output + (kind: ok) {"a":"foo","wat0":"joe"} + +FAIL: capturing-func-mutate +- Expected ++ Received + + + ## Input + + ```javascript + function component(a, b) { + let z = {a}; + let y = {b}; + let x = function () { + z.a = 2; + console.log(y.b); + }; + x(); + return z; + } + + export const FIXTURE_ENTRYPOINT = { + fn: component, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function component(a, b) { + const $ = _c(3); ++ Object.freeze(a); ++ Object.freeze(b); + let z; + if ($[0] !== a || $[1] !== b) { + z = { a }; + const y = { b }; + const x = function () { + z.a = 2; + console.log(y.b); + }; + + x(); + $[0] = a; + $[1] = b; + $[2] = z; + } else { + z = $[2]; + } + return z; + } + + export const FIXTURE_ENTRYPOINT = { + fn: component, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: capturing-func-mutate-nested +- Expected ++ Received + + + ## Input + + ```javascript + function component(a) { + let y = {b: {a}}; + let x = function () { + y.b.a = 2; + }; + x(); + return y; + } + + export const FIXTURE_ENTRYPOINT = { + fn: component, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function component(a) { + const $ = _c(2); ++ Object.freeze(a); + let y; + if ($[0] !== a) { + y = { b: { a } }; + const x = function () { + y.b.a = 2; + }; + + x(); + $[0] = a; + $[1] = y; + } else { + y = $[1]; + } + return y; + } + + export const FIXTURE_ENTRYPOINT = { + fn: component, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: capturing-func-mutate-3 +- Expected ++ Received + + + ## Input + + ```javascript + function component(a, b) { + let y = {b}; + let z = {a}; + let x = function () { + z.a = 2; + y.b; + }; + return z; + } + + export const FIXTURE_ENTRYPOINT = { + fn: component, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function component(a, b) { + const $ = _c(2); ++ Object.freeze(a); ++ Object.freeze(b); + let t0; + if ($[0] !== a) { + t0 = { a }; + $[0] = a; + $[1] = t0; + } else { + t0 = $[1]; + } + const z = t0; + return z; + } + + export const FIXTURE_ENTRYPOINT = { + fn: component, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: capturing-func-mutate-2 +- Expected ++ Received + + + ## Input + + ```javascript + function component(a, b) { + let y = {b}; + let z = {a}; + let x = function () { + z.a = 2; + y.b; + }; + x(); + return z; + } + + export const FIXTURE_ENTRYPOINT = { + fn: component, + params: [{a: 'val1', b: 'val2'}], + isComponent: false, + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function component(a, b) { + const $ = _c(5); ++ Object.freeze(a); ++ Object.freeze(b); + let t0; + if ($[0] !== b) { + t0 = { b }; + $[0] = b; + $[1] = t0; + } else { + t0 = $[1]; + } + const y = t0; + let z; + if ($[2] !== a || $[3] !== y.b) { + z = { a }; + const x = function () { + z.a = 2; + }; + + x(); + $[2] = a; + $[3] = y.b; + $[4] = z; + } else { + z = $[4]; + } + return z; + } + + export const FIXTURE_ENTRYPOINT = { + fn: component, + params: [{ a: "val1", b: "val2" }], + isComponent: false, + }; + + ``` +  + ### Eval output + (kind: ok) {"a":2} + +FAIL: capturing-func-alias-receiver-mutate +- Expected ++ Received + + + ## Input + + ```javascript + function component(a) { + let x = {a}; + let y = {}; + const f0 = function () { + let a = y; + a.x = x; + }; + f0(); + mutate(y); + return y; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function component(a) { + const $ = _c(2); ++ Object.freeze(a); + let y; + if ($[0] !== a) { + const x = { a }; + y = {}; + const f0 = function () { + const a_0 = y; + a_0.x = x; + }; + + f0(); + mutate(y); + $[0] = a; + $[1] = y; + } else { + y = $[1]; + } + return y; + } + + ``` +  + +FAIL: capturing-func-alias-receiver-mutate-iife +- Expected ++ Received + + + ## Input + + ```javascript + const {mutate} = require('shared-runtime'); + + function component(a) { + let x = {a}; + let y = {}; + (function () { + let a = y; + a.x = x; + })(); + mutate(y); + return y; + } + + export const FIXTURE_ENTRYPOINT = { + fn: component, + params: ['foo'], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + const { mutate } = require("shared-runtime"); + + function component(a) { + const $ = _c(2); ++ Object.freeze(a); + let y; + if ($[0] !== a) { + const x = { a }; + y = {}; + + const a_0 = y; + a_0.x = x; + + mutate(y); + $[0] = a; + $[1] = y; + } else { + y = $[1]; + } + return y; + } + + export const FIXTURE_ENTRYPOINT = { + fn: component, + params: ["foo"], + }; + + ``` +  + ### Eval output + (kind: ok) {"x":{"a":"foo"},"wat0":"joe"} + +FAIL: capturing-func-alias-receiver-computed-mutate +- Expected ++ Received + + + ## Input + + ```javascript + function component(a) { + let x = {a}; + let y = {}; + const f0 = function () { + let a = y; + a['x'] = x; + }; + f0(); + mutate(y); + return y; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function component(a) { + const $ = _c(2); ++ Object.freeze(a); + let y; + if ($[0] !== a) { + const x = { a }; + y = {}; + const f0 = function () { + const a_0 = y; + a_0.x = x; + }; + + f0(); + mutate(y); + $[0] = a; + $[1] = y; + } else { + y = $[1]; + } + return y; + } + + ``` +  + +FAIL: capturing-func-alias-receiver-computed-mutate-iife +- Expected ++ Received + + + ## Input + + ```javascript + import {mutate} from 'shared-runtime'; + + function component(a) { + let x = {a}; + let y = {}; + (function () { + let a = y; + a['x'] = x; + })(); + mutate(y); + return y; + } + + export const FIXTURE_ENTRYPOINT = { + fn: component, + params: ['foo'], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { mutate } from "shared-runtime"; + + function component(a) { + const $ = _c(2); ++ Object.freeze(a); + let y; + if ($[0] !== a) { + const x = { a }; + y = {}; + + const a_0 = y; + a_0.x = x; + + mutate(y); + $[0] = a; + $[1] = y; + } else { + y = $[1]; + } + return y; + } + + export const FIXTURE_ENTRYPOINT = { + fn: component, + params: ["foo"], + }; + + ``` +  + ### Eval output + (kind: ok) {"x":{"a":"foo"},"wat0":"joe"} + +FAIL: capturing-func-alias-mutate +- Expected ++ Received + + + ## Input + + ```javascript + function component(a) { + let x = {a}; + let y = {}; + const f0 = function () { + y.x = x; + }; + f0(); + mutate(y); + return y; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function component(a) { + const $ = _c(2); ++ Object.freeze(a); + let y; + if ($[0] !== a) { + const x = { a }; + y = {}; + const f0 = function () { + y.x = x; + }; + + f0(); + mutate(y); + $[0] = a; + $[1] = y; + } else { + y = $[1]; + } + return y; + } + + ``` +  + +FAIL: capturing-func-alias-mutate-iife +- Expected ++ Received + + + ## Input + + ```javascript + const {mutate} = require('shared-runtime'); + + function component(a) { + let x = {a}; + let y = {}; + (function () { + y.x = x; + })(); + mutate(y); + return y; + } + + export const FIXTURE_ENTRYPOINT = { + fn: component, + params: ['foo'], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + const { mutate } = require("shared-runtime"); + + function component(a) { + const $ = _c(2); ++ Object.freeze(a); + let y; + if ($[0] !== a) { + const x = { a }; + y = {}; + + y.x = x; + + mutate(y); + $[0] = a; + $[1] = y; + } else { + y = $[1]; + } + return y; + } + + export const FIXTURE_ENTRYPOINT = { + fn: component, + params: ["foo"], + }; + + ``` +  + ### Eval output + (kind: ok) {"x":{"a":"foo"},"wat0":"joe"} + +FAIL: capturing-func-alias-computed-mutate +- Expected ++ Received + + + ## Input + + ```javascript + function component(a) { + let x = {a}; + let y = {}; + const f0 = function () { + y['x'] = x; + }; + f0(); + mutate(y); + return y; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function component(a) { + const $ = _c(2); ++ Object.freeze(a); + let y; + if ($[0] !== a) { + const x = { a }; + y = {}; + const f0 = function () { + y.x = x; + }; + + f0(); + mutate(y); + $[0] = a; + $[1] = y; + } else { + y = $[1]; + } + return y; + } + + ``` +  + +FAIL: capturing-func-alias-computed-mutate-iife +- Expected ++ Received + + + ## Input + + ```javascript + const {mutate} = require('shared-runtime'); + + function component(a) { + let x = {a}; + let y = {}; + (function () { + y['x'] = x; + })(); + mutate(y); + return y; + } + + export const FIXTURE_ENTRYPOINT = { + fn: component, + params: ['foo'], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + const { mutate } = require("shared-runtime"); + + function component(a) { + const $ = _c(2); ++ Object.freeze(a); + let y; + if ($[0] !== a) { + const x = { a }; + y = {}; + + y.x = x; + + mutate(y); + $[0] = a; + $[1] = y; + } else { + y = $[1]; + } + return y; + } + + export const FIXTURE_ENTRYPOINT = { + fn: component, + params: ["foo"], + }; + + ``` +  + ### Eval output + (kind: ok) {"x":{"a":"foo"},"wat0":"joe"} + +FAIL: capturing-func-alias-captured-mutate +- Expected ++ Received + + + ## Input + + ```javascript + function component(foo, bar) { + let x = {foo}; + let y = {bar}; + const f0 = function () { + let a = {y}; + let b = x; + a.x = b; + }; + f0(); + mutate(y); + return y; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function component(foo, bar) { + const $ = _c(3); ++ Object.freeze(foo); ++ Object.freeze(bar); + let y; + if ($[0] !== foo || $[1] !== bar) { + const x = { foo }; + y = { bar }; + const f0 = function () { + const a = { y }; + const b = x; + a.x = b; + }; + + f0(); + mutate(y); + $[0] = foo; + $[1] = bar; + $[2] = y; + } else { + y = $[2]; + } + return y; + } + + ``` +  + +FAIL: capturing-func-alias-captured-mutate-iife +- Expected ++ Received + + + ## Input + + ```javascript + const {mutate} = require('shared-runtime'); + + function component(foo, bar) { + let x = {foo}; + let y = {bar}; + (function () { + let a = {y}; + let b = x; + a.x = b; + })(); + mutate(y); + return y; + } + + export const FIXTURE_ENTRYPOINT = { + fn: component, + params: ['foo', 'bar'], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + const { mutate } = require("shared-runtime"); + + function component(foo, bar) { + const $ = _c(3); ++ Object.freeze(foo); ++ Object.freeze(bar); + let y; + if ($[0] !== foo || $[1] !== bar) { + const x = { foo }; + y = { bar }; + + const a = { y }; + const b = x; + a.x = b; + + mutate(y); + $[0] = foo; + $[1] = bar; + $[2] = y; + } else { + y = $[2]; + } + return y; + } + + export const FIXTURE_ENTRYPOINT = { + fn: component, + params: ["foo", "bar"], + }; + + ``` +  + ### Eval output + (kind: ok) {"bar":"bar","wat0":"joe"} + +FAIL: capturing-func-alias-captured-mutate-arr +- Expected ++ Received + + + ## Input + + ```javascript + function component(foo, bar) { + let x = {foo}; + let y = {bar}; + const f0 = function () { + let a = [y]; + let b = x; + a.x = b; + }; + f0(); + mutate(y); + return y; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function component(foo, bar) { + const $ = _c(3); ++ Object.freeze(foo); ++ Object.freeze(bar); + let y; + if ($[0] !== foo || $[1] !== bar) { + const x = { foo }; + y = { bar }; + const f0 = function () { + const a = [y]; + const b = x; + a.x = b; + }; + + f0(); + mutate(y); + $[0] = foo; + $[1] = bar; + $[2] = y; + } else { + y = $[2]; + } + return y; + } + + ``` +  + +FAIL: capturing-func-alias-captured-mutate-arr-iife +- Expected ++ Received + + + ## Input + + ```javascript + const {mutate} = require('shared-runtime'); + + function component(foo, bar) { + let x = {foo}; + let y = {bar}; + (function () { + let a = [y]; + let b = x; + a.x = b; + })(); + mutate(y); + return y; + } + + export const FIXTURE_ENTRYPOINT = { + fn: component, + params: ['foo', 'bar'], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + const { mutate } = require("shared-runtime"); + + function component(foo, bar) { + const $ = _c(3); ++ Object.freeze(foo); ++ Object.freeze(bar); + let y; + if ($[0] !== foo || $[1] !== bar) { + const x = { foo }; + y = { bar }; + + const a = [y]; + const b = x; + a.x = b; + + mutate(y); + $[0] = foo; + $[1] = bar; + $[2] = y; + } else { + y = $[2]; + } + return y; + } + + export const FIXTURE_ENTRYPOINT = { + fn: component, + params: ["foo", "bar"], + }; + + ``` +  + ### Eval output + (kind: ok) {"bar":"bar","wat0":"joe"} + +FAIL: capturing-fun-alias-captured-mutate-arr-2 +- Expected ++ Received + + + ## Input + + ```javascript + function component(foo, bar) { + let x = {foo}; + let y = {bar}; + const f0 = function () { + let a = [y]; + let b = x; + a.x = b; + }; + f0(); + mutate(y); + return x; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function component(foo, bar) { + const $ = _c(3); ++ Object.freeze(foo); ++ Object.freeze(bar); + let x; + if ($[0] !== foo || $[1] !== bar) { + x = { foo }; + const y = { bar }; + const f0 = function () { + const a = [y]; + const b = x; + a.x = b; + }; + + f0(); + mutate(y); + $[0] = foo; + $[1] = bar; + $[2] = x; + } else { + x = $[2]; + } + return x; + } + + ``` +  + +FAIL: capturing-fun-alias-captured-mutate-arr-2-iife +- Expected ++ Received + + + ## Input + + ```javascript + const {mutate} = require('shared-runtime'); + + function component(foo, bar) { + let x = {foo}; + let y = {bar}; + (function () { + let a = [y]; + let b = x; + a.x = b; + })(); + mutate(y); + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: component, + params: ['foo', 'bar'], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + const { mutate } = require("shared-runtime"); + + function component(foo, bar) { + const $ = _c(3); ++ Object.freeze(foo); ++ Object.freeze(bar); + let x; + if ($[0] !== foo || $[1] !== bar) { + x = { foo }; + const y = { bar }; + + const a = [y]; + const b = x; + a.x = b; + + mutate(y); + $[0] = foo; + $[1] = bar; + $[2] = x; + } else { + x = $[2]; + } + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: component, + params: ["foo", "bar"], + }; + + ``` +  + ### Eval output + (kind: ok) {"foo":"foo"} + +FAIL: capturing-fun-alias-captured-mutate-2 +- Expected ++ Received + + + ## Input + + ```javascript + function component(foo, bar) { + let x = {foo}; + let y = {bar}; + const f0 = function () { + let a = {y}; + let b = x; + a.x = b; + }; + f0(); + mutate(y); + return x; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function component(foo, bar) { + const $ = _c(3); ++ Object.freeze(foo); ++ Object.freeze(bar); + let x; + if ($[0] !== foo || $[1] !== bar) { + x = { foo }; + const y = { bar }; + const f0 = function () { + const a = { y }; + const b = x; + a.x = b; + }; + + f0(); + mutate(y); + $[0] = foo; + $[1] = bar; + $[2] = x; + } else { + x = $[2]; + } + return x; + } + + ``` +  + +FAIL: capturing-fun-alias-captured-mutate-2-iife +- Expected ++ Received + + + ## Input + + ```javascript + import {mutate} from 'shared-runtime'; + + function component(foo, bar) { + let x = {foo}; + let y = {bar}; + (function () { + let a = {y}; + let b = x; + a.x = b; + })(); + mutate(y); + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: component, + params: ['foo', 'bar'], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { mutate } from "shared-runtime"; + + function component(foo, bar) { + const $ = _c(3); ++ Object.freeze(foo); ++ Object.freeze(bar); + let x; + if ($[0] !== foo || $[1] !== bar) { + x = { foo }; + const y = { bar }; + + const a = { y }; + const b = x; + a.x = b; + + mutate(y); + $[0] = foo; + $[1] = bar; + $[2] = x; + } else { + x = $[2]; + } + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: component, + params: ["foo", "bar"], + }; + + ``` +  + ### Eval output + (kind: ok) {"foo":"foo"} + +FAIL: capturing-arrow-function-1 +- Expected ++ Received + + + ## Input + + ```javascript + function component(a) { + let z = {a}; + let x = () => { + console.log(z); + }; + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: component, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function component(a) { + const $ = _c(4); ++ Object.freeze(a); + let t0; + if ($[0] !== a) { + t0 = { a }; + $[0] = a; + $[1] = t0; + } else { + t0 = $[1]; + } + const z = t0; + let t1; + if ($[2] !== z) { + t1 = () => { + console.log(z); + }; + $[2] = z; + $[3] = t1; + } else { + t1 = $[3]; + } + const x = t1; + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: component, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: capture_mutate-across-fns +- Expected ++ Received + + + ## Input + + ```javascript + function component(a) { + let z = {a}; + const f0 = function () { + const f1 = function () { + z.b = 1; + }; + f1(); + }; + f0(); + return z; + } + + export const FIXTURE_ENTRYPOINT = { + fn: component, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function component(a) { + const $ = _c(2); ++ Object.freeze(a); + let z; + if ($[0] !== a) { + z = { a }; + const f0 = function () { + const f1 = function () { + z.b = 1; + }; + + f1(); + }; + + f0(); + $[0] = a; + $[1] = z; + } else { + z = $[1]; + } + return z; + } + + export const FIXTURE_ENTRYPOINT = { + fn: component, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: capture_mutate-across-fns-iife +- Expected ++ Received + + + ## Input + + ```javascript + function component(a) { + let z = {a}; + (function () { + (function () { + z.b = 1; + })(); + })(); + return z; + } + + export const FIXTURE_ENTRYPOINT = { + fn: component, + params: [2], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function component(a) { + const $ = _c(2); ++ Object.freeze(a); + let z; + if ($[0] !== a) { + z = { a }; + + (function () { + z.b = 1; + })(); + $[0] = a; + $[1] = z; + } else { + z = $[1]; + } + return z; + } + + export const FIXTURE_ENTRYPOINT = { + fn: component, + params: [2], + }; + + ``` +  + ### Eval output + (kind: ok) {"a":2,"b":1} + +FAIL: capture-ref-for-later-mutation +- Expected ++ Received + + + ## Input + + ```javascript + import {useRef} from 'react'; + import {addOne} from 'shared-runtime'; + + function useKeyCommand() { + const currentPosition = useRef(0); + const handleKey = direction => () => { + const position = currentPosition.current; + const nextPosition = direction === 'left' ? addOne(position) : position; + currentPosition.current = nextPosition; + }; + const moveLeft = { + handler: handleKey('left'), + }; + const moveRight = { + handler: handleKey('right'), + }; + return [moveLeft, moveRight]; + } + + export const FIXTURE_ENTRYPOINT = { + fn: useKeyCommand, + params: [], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { useRef } from "react"; + import { addOne } from "shared-runtime"; + + function useKeyCommand() { + const $ = _c(2); +- const currentPosition = useRef(0); ++ const currentPosition = (function () { ++ const $res$ = useRef(Object.freeze(0)); ++ Object.freeze($res$); ++ return $res$; ++ })(); + const handleKey = (direction) => () => { + const position = currentPosition.current; + const nextPosition = direction === "left" ? addOne(position) : position; + currentPosition.current = nextPosition; + }; + + const moveLeft = { handler: handleKey("left") }; + + const t0 = handleKey("right"); + let t1; + if ($[0] !== t0) { + t1 = { handler: t0 }; + $[0] = t0; + $[1] = t1; + } else { + t1 = $[1]; + } + const moveRight = t1; + return [moveLeft, moveRight]; + } + + export const FIXTURE_ENTRYPOINT = { + fn: useKeyCommand, + params: [], + }; + + ``` +  + ### Eval output + (kind: ok) [{"handler":"[[ function params=0 ]]"},{"handler":"[[ function params=0 ]]"}] + +FAIL: capture-param-mutate +- Expected ++ Received + + + ## Input + + ```javascript + 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); + }; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function getNativeLogFunction(level) { + const $ = _c(2); ++ Object.freeze(level); + let t0; + if ($[0] !== level) { + t0 = 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); + }; + $[0] = level; + $[1] = t0; + } else { + t0 = $[1]; + } + return t0; + } + + ``` +  + +FAIL: capture-indirect-mutate-alias +- Expected ++ Received + + + ## Input + + ```javascript + function component(a) { + let x = {a}; + const f0 = function () { + let q = x; + const f1 = function () { + q.b = 1; + }; + f1(); + }; + f0(); + + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: component, + params: ['TodoAdd'], + isComponent: 'TodoAdd', + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function component(a) { + const $ = _c(2); ++ Object.freeze(a); + let x; + if ($[0] !== a) { + x = { a }; + const f0 = function () { + const q = x; + const f1 = function () { + q.b = 1; + }; + + f1(); + }; + + f0(); + $[0] = a; + $[1] = x; + } else { + x = $[1]; + } + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: component, + params: ["TodoAdd"], + isComponent: "TodoAdd", + }; + + ``` +  + +FAIL: capture-indirect-mutate-alias-iife +- Expected ++ Received + + + ## Input + + ```javascript + function component(a) { + let x = {a}; + (function () { + let q = x; + (function () { + q.b = 1; + })(); + })(); + + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: component, + params: [2], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function component(a) { + const $ = _c(2); ++ Object.freeze(a); + let x; + if ($[0] !== a) { + x = { a }; + + const q = x; + (function () { + q.b = 1; + })(); + $[0] = a; + $[1] = x; + } else { + x = $[1]; + } + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: component, + params: [2], + }; + + ``` +  + ### Eval output + (kind: ok) {"a":2,"b":1} + +FAIL: capitalized-function-allowlist +- Expected ++ Received + + + ## Input + + ```javascript + // @validateNoCapitalizedCalls @hookPattern:".*\b(use[^$]+)$" + import * as React from 'react'; + const React$useState = React.useState; + const THIS_IS_A_CONSTANT = () => {}; + function Component() { + const b = Boolean(true); // OK + const n = Number(3); // OK + const s = String('foo'); // OK + const [state, setState] = React$useState(0); // OK + const [state2, setState2] = React.useState(1); // OK + const constant = THIS_IS_A_CONSTANT(); // OK + return 3; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [], + isComponent: true, + }; + + ``` + + ## Code + + ```javascript + // @validateNoCapitalizedCalls @hookPattern:".*\b(use[^$]+)$" + import * as React from "react"; + const React$useState = React.useState; + const THIS_IS_A_CONSTANT = () => {}; + function Component() { + Boolean(true); + Number(3); + String("foo"); +- React$useState(0); +- React.useState(1); ++ (function () { ++ const $res$ = React$useState(Object.freeze(0)); ++ Object.freeze($res$); ++ return $res$; ++ })(); ++ (function () { ++ const $res$ = React.useState(Object.freeze(1)); ++ Object.freeze($res$); ++ return $res$; ++ })(); + THIS_IS_A_CONSTANT(); + return 3; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [], + isComponent: true, + }; + + ``` +  + ### Eval output + (kind: ok) 3 + +FAIL: call +- Expected ++ Received + + + ## Input + + ```javascript + function foo() {} + + function Component(props) { + const a = []; + const b = {}; + foo(a, b); + let _ =
; + foo(b); + return
; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function foo() {} + + function Component(props) { + const $ = _c(1); ++ Object.freeze(props); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + const a = []; + const b = {}; + foo(a, b); + + foo(b); +- t0 =
; ++ t0 = ( ++  ++ ); + $[0] = t0; + } else { + t0 = $[0]; + } + return t0; + } + + ``` +  + +FAIL: call-with-independently-memoizable-arg +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + const x = makeFunction(props); + const y = x( +
 + {props.text} +
 + ); + return y; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(4); ++ Object.freeze(props); + let t0; + if ($[0] !== props) { + const x = makeFunction(props); + let t1; + if ($[2] !== props.text) { + t1 = ( +
 + {props.text} +
 + ); + $[2] = props.text; + $[3] = t1; + } else { + t1 = $[3]; + } + t0 = x(t1); + $[0] = props; + $[1] = t0; + } else { + t0 = $[1]; + } + const y = t0; + return y; + } + + ``` +  + +FAIL: call-spread +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + const x = foo(...props.a, null, ...props.b); + return x; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(3); ++ Object.freeze(props); + let t0; + if ($[0] !== props.a || $[1] !== props.b) { + t0 = foo(...props.a, null, ...props.b); + $[0] = props.a; + $[1] = props.b; + $[2] = t0; + } else { + t0 = $[2]; + } + const x = t0; + return x; + } + + ``` +  + +FAIL: call-args-destructuring-assignment +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + let x = makeObject(); + x.foo(([x] = makeObject())); + return x; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(1); ++ Object.freeze(props); + let x; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + x = makeObject(); + x.foo(([x] = makeObject())); + $[0] = x; + } else { + x = $[0]; + } + return x; + } + + ``` +  + +FAIL: call-args-assignment +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + let x = makeObject(); + x.foo((x = makeObject())); + return x; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(1); ++ Object.freeze(props); + let x; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + x = makeObject(); + x.foo((x = makeObject())); + $[0] = x; + } else { + x = $[0]; + } + return x; + } + + ``` +  + +FAIL: builtin-jsx-tag-lowered-between-mutations +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + const maybeMutable = new MaybeMutable(); + return
{maybeMutate(maybeMutable)}
; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(1); ++ Object.freeze(props); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + const maybeMutable = new MaybeMutable(); + t0 =
{maybeMutate(maybeMutable)}
; + $[0] = t0; + } else { + t0 = $[0]; + } + return t0; + } + + ``` +  + +FAIL: bug-invalid-hoisting-functionexpr +- Expected ++ Received + + + ## Input + + ```javascript + import {Stringify} from 'shared-runtime'; + + /** + * We currently hoist the accessed properties of function expressions, + * regardless of control flow. This is simply because we wrote support for + * function expressions before doing a lot of work in PropagateScopeDeps + * to handle conditionally accessed dependencies. + * + * Current evaluator error: + * Found differences in evaluator results + * Non-forget (expected): + * (kind: ok)
{"shouldInvokeFns":true,"callback":{"kind":"Function","result":null}}
 + * Forget: + * (kind: exception) Cannot read properties of null (reading 'prop') + */ + function Component({obj, isObjNull}) { + const callback = () => { + if (!isObjNull) { + return obj.prop; + } else { + return null; + } + }; + return ; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{obj: null, isObjNull: true}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { Stringify } from "shared-runtime"; + + /** + * We currently hoist the accessed properties of function expressions, + * regardless of control flow. This is simply because we wrote support for + * function expressions before doing a lot of work in PropagateScopeDeps + * to handle conditionally accessed dependencies. + * + * Current evaluator error: + * Found differences in evaluator results + * Non-forget (expected): + * (kind: ok)
{"shouldInvokeFns":true,"callback":{"kind":"Function","result":null}}
 + * Forget: + * (kind: exception) Cannot read properties of null (reading 'prop') + */ + function Component(t0) { + const $ = _c(5); ++ Object.freeze(t0); + const { obj, isObjNull } = t0; + let t1; + if ($[0] !== isObjNull || $[1] !== obj.prop) { + t1 = () => { + if (!isObjNull) { + return obj.prop; + } else { + return null; + } + }; + $[0] = isObjNull; + $[1] = obj.prop; + $[2] = t1; + } else { + t1 = $[2]; + } + const callback = t1; + let t2; + if ($[3] !== callback) { +- t2 = ; ++ t2 = ( ++  ++ ); + $[3] = callback; + $[4] = t2; + } else { + t2 = $[4]; + } + return t2; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ obj: null, isObjNull: true }], + }; + + ``` +  + +FAIL: block-scoping-switch-variable-scoping +- Expected ++ Received + + + ## Input + + ```javascript + import {useMemo} from 'react'; + + function Component(props) { + const outerHandlers = useMemo(() => { + let handlers = {value: props.value}; + switch (props.test) { + case true: { + console.log(handlers.value); + break; + } + default: { + } + } + return handlers; + }); + return outerHandlers; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{test: true, value: 'hello'}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { useMemo } from "react"; + + function Component(props) { + const $ = _c(2); ++ Object.freeze(props); + let t0; + let t1; + if ($[0] !== props.value) { + t1 = { value: props.value }; + $[0] = props.value; + $[1] = t1; + } else { + t1 = $[1]; + } + const handlers = t1; + bb0: switch (props.test) { + case true: { + console.log(handlers.value); + break bb0; + } + default: { + } + } + + t0 = handlers; + const outerHandlers = t0; + return outerHandlers; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ test: true, value: "hello" }], + }; + + ``` +  + ### Eval output + (kind: ok) {"value":"hello"} + logs: ['hello'] + +FAIL: block-scoping-switch-dead-code +- Expected ++ Received + + + ## Input + + ```javascript + function useHook(a, b) { + switch (a) { + case 1: + if (b == null) { + return; + } + console.log(b); + break; + case 2: + return; + default: + return; + } + } + + export const FIXTURE_ENTRYPOINT = { + fn: useHook, + params: [1, 'foo'], + }; + + ``` + + ## Code + + ```javascript + function useHook(a, b) { ++ Object.freeze(a); ++ Object.freeze(b); + bb0: switch (a) { + case 1: { + if (b == null) { + return; + } + + console.log(b); + break bb0; + } + case 2: { + return; + } + default: { + return; + } + } + } + + export const FIXTURE_ENTRYPOINT = { + fn: useHook, + params: [1, "foo"], + }; + + ``` +  + ### Eval output + (kind: ok)  + logs: ['foo'] + +FAIL: babel-existing-react-namespace-import +- Expected ++ Received + + + ## Input + + ```javascript + import * as React from 'react'; + import {calculateExpensiveNumber} from 'shared-runtime'; + + function Component(props) { + const [x] = React.useState(0); + const expensiveNumber = React.useMemo(() => calculateExpensiveNumber(x), [x]); + + return
{expensiveNumber}
; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import * as React from "react"; + import { calculateExpensiveNumber } from "shared-runtime"; + + function Component(props) { + const $ = _c(4); +- const [x] = React.useState(0); ++ Object.freeze(props); ++ const [x] = (function () { ++ const $res$ = React.useState(Object.freeze(0)); ++ Object.freeze($res$); ++ return $res$; ++ })(); + let t0; + let t1; + if ($[0] !== x) { + t1 = calculateExpensiveNumber(x); + $[0] = x; + $[1] = t1; + } else { + t1 = $[1]; + } + t0 = t1; + const expensiveNumber = t0; + let t2; + if ($[2] !== expensiveNumber) { + t2 =
{expensiveNumber}
; + $[2] = expensiveNumber; + $[3] = t2; + } else { + t2 = $[3]; + } + return t2; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [], + }; + + ``` +  + ### Eval output + (kind: ok)
0
 + +FAIL: babel-existing-react-kitchensink-import +- Expected ++ Received + + + ## Input + + ```javascript + 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}
; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import * as React from "react"; + import { useState, useMemo } from "react"; + + function Component(props) { + const $ = _c(4); +- const [x] = useState(0); ++ Object.freeze(props); ++ const [x] = (function () { ++ const $res$ = useState(Object.freeze(0)); ++ Object.freeze($res$); ++ return $res$; ++ })(); + let t0; + let t1; + if ($[0] !== x) { + t1 = calculateExpensiveNumber(x); + $[0] = x; + $[1] = t1; + } else { + t1 = $[1]; + } + t0 = t1; + const expensiveNumber = t0; + let t2; + if ($[2] !== expensiveNumber) { + t2 =
{expensiveNumber}
; + $[2] = expensiveNumber; + $[3] = t2; + } else { + t2 = $[3]; + } + return t2; + } + + function Component2(props) { + const $ = _c(4); +- const [x] = useState(0); ++ Object.freeze(props); ++ const [x] = (function () { ++ const $res$ = useState(Object.freeze(0)); ++ Object.freeze($res$); ++ return $res$; ++ })(); + let t0; + let t1; + if ($[0] !== x) { + t1 = calculateExpensiveNumber(x); + $[0] = x; + $[1] = t1; + } else { + t1 = $[1]; + } + t0 = t1; + const expensiveNumber = t0; + let t2; + if ($[2] !== expensiveNumber) { + t2 =
{expensiveNumber}
; + $[2] = expensiveNumber; + $[3] = t2; + } else { + t2 = $[3]; + } + return t2; + } + + ``` +  + +FAIL: babel-existing-react-import +- Expected ++ Received + + + ## Input + + ```javascript + 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}
; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { useState, useMemo } from "react"; + + function Component(props) { + const $ = _c(4); +- const [x] = useState(0); ++ Object.freeze(props); ++ const [x] = (function () { ++ const $res$ = useState(Object.freeze(0)); ++ Object.freeze($res$); ++ return $res$; ++ })(); + let t0; + let t1; + if ($[0] !== x) { + t1 = calculateExpensiveNumber(x); + $[0] = x; + $[1] = t1; + } else { + t1 = $[1]; + } + t0 = t1; + const expensiveNumber = t0; + let t2; + if ($[2] !== expensiveNumber) { + t2 =
{expensiveNumber}
; + $[2] = expensiveNumber; + $[3] = t2; + } else { + t2 = $[3]; + } + return t2; + } + + function Component2(props) { + const $ = _c(4); +- const [x] = useState(0); ++ Object.freeze(props); ++ const [x] = (function () { ++ const $res$ = useState(Object.freeze(0)); ++ Object.freeze($res$); ++ return $res$; ++ })(); + let t0; + let t1; + if ($[0] !== x) { + t1 = calculateExpensiveNumber(x); + $[0] = x; + $[1] = t1; + } else { + t1 = $[1]; + } + t0 = t1; + const expensiveNumber = t0; + let t2; + if ($[2] !== expensiveNumber) { + t2 =
{expensiveNumber}
; + $[2] = expensiveNumber; + $[3] = t2; + } else { + t2 = $[3]; + } + return t2; + } + + ``` +  + +FAIL: await +- Expected ++ Received + + + ## Input + + ```javascript + async function Component(props) { + const user = await load(props.id); + return
{user.name}
; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + async function Component(props) { + const $ = _c(4); ++ Object.freeze(props); + let t0; + if ($[0] !== props.id) { + t0 = await load(props.id); + $[0] = props.id; + $[1] = t0; + } else { + t0 = $[1]; + } + const user = t0; + let t1; + if ($[2] !== user.name) { + t1 =
{user.name}
; + $[2] = user.name; + $[3] = t1; + } else { + t1 = $[3]; + } + return t1; + } + + ``` +  + +FAIL: await-side-effecting-promise +- Expected ++ Received + + + ## Input + + ```javascript + async function Component(props) { + const x = []; + await populateData(props.id, x); + return x; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + async function Component(props) { + const $ = _c(2); ++ Object.freeze(props); + let x; + if ($[0] !== props.id) { + x = []; + await populateData(props.id, x); + $[0] = props.id; + $[1] = x; + } else { + x = $[1]; + } + return x; + } + + ``` +  + +FAIL: assignment-in-nested-if +- Expected ++ Received + + + ## Input + + ```javascript + function useBar(props) { + let z; + + if (props.a) { + if (props.b) { + z = baz(); + } + } + + return z; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function useBar(props) { + const $ = _c(1); ++ Object.freeze(props); + let z; + if (props.a) { + if (props.b) { + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = baz(); + $[0] = t0; + } else { + t0 = $[0]; + } + z = t0; + } + } + return z; + } + + ``` +  + +FAIL: assignment-expression-nested-path +- Expected ++ Received + + + ## Input + + ```javascript + function g(props) { + const a = {b: {c: props.c}}; + a.b.c = a.b.c + 1; + a.b.c *= 2; + return a; + } + + export const FIXTURE_ENTRYPOINT = { + fn: g, + params: [{c: 2}], + isComponent: false, + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function g(props) { + const $ = _c(2); ++ Object.freeze(props); + let a; + if ($[0] !== props.c) { + a = { b: { c: props.c } }; + a.b.c = a.b.c + 1; + a.b.c = a.b.c * 2; + $[0] = props.c; + $[1] = a; + } else { + a = $[1]; + } + return a; + } + + export const FIXTURE_ENTRYPOINT = { + fn: g, + params: [{ c: 2 }], + isComponent: false, + }; + + ``` +  + ### Eval output + (kind: ok) {"b":{"c":6}} + +FAIL: assignment-expression-computed +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + const x = [props.x]; + const index = 0; + x[index] *= 2; + x['0'] += 3; + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{x: 2}], + isComponent: false, + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(2); ++ Object.freeze(props); + let x; + if ($[0] !== props.x) { + x = [props.x]; + + x[0] = x[0] * 2; + x["0"] = x["0"] + 3; + $[0] = props.x; + $[1] = x; + } else { + x = $[1]; + } + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ x: 2 }], + isComponent: false, + }; + + ``` +  + ### Eval output + (kind: ok) [7] + +FAIL: arrow-function-expr-gating-test +- Expected ++ Received + + + ## Input + + ```javascript + // @gating + const ErrorView = (error, _retry) => ; + + export default ErrorView; + + ``` + + ## Code + + ```javascript + import { isForgetEnabled_Fixtures } from "ReactForgetFeatureFlag"; + import { c as _c } from "react/compiler-runtime"; // @gating + const ErrorView = isForgetEnabled_Fixtures() + ? (error, _retry) => { + const $ = _c(2); ++ Object.freeze(error); ++ Object.freeze(_retry); + let t0; + if ($[0] !== error) { +- t0 = ; ++ t0 = ( ++  ++ ); + $[0] = error; + $[1] = t0; + } else { + t0 = $[1]; + } + return t0; + } + : (error, _retry) => ; + + export default ErrorView; + + ``` +  + +FAIL: arrow-expr-directive +- Expected ++ Received + + + ## Input + + ```javascript + function Component() { + 'use strict'; + let [count, setCount] = React.useState(0); + const update = () => { + 'worklet'; + setCount(count => count + 1); + }; + return ; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component() { +- "use strict"; + const $ = _c(3); + +- const [count, setCount] = React.useState(0); ++ const [count, setCount] = (function () { ++ const $res$ = React.useState(Object.freeze(0)); ++ Object.freeze($res$); ++ return $res$; ++ })(); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = () => { + "worklet"; + + setCount((count_0) => count_0 + 1); + }; + $[0] = t0; + } else { + t0 = $[0]; + } + const update = t0; + let t1; + if ($[1] !== count) { +- t1 = ; ++ t1 = ( ++  ++ {count} ++  ++ ); + $[1] = count; + $[2] = t1; + } else { + t1 = $[2]; + } + return t1; + } + + ``` +  + ### Eval output + (kind: exception) Fixture not implemented + +FAIL: array-push-effect +- Expected ++ Received + + + ## Input + + ```javascript + // 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; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; // arrayInstance.push should have the following effects: + // - read on all args (rest parameter) + // - mutate on receiver + function Component(props) { + const $ = _c(8); ++ Object.freeze(props); + let t0; + if ($[0] !== props.x) { + t0 = foo(props.x); + $[0] = props.x; + $[1] = t0; + } else { + t0 = $[1]; + } + const x = t0; + let t1; + if ($[2] !== props.y) { + t1 = { y: props.y }; + $[2] = props.y; + $[3] = t1; + } else { + t1 = $[3]; + } + const y = t1; + let arr; + if ($[4] !== x || $[5] !== y) { + arr = []; + let t2; + if ($[7] === Symbol.for("react.memo_cache_sentinel")) { + t2 = {}; + $[7] = t2; + } else { + t2 = $[7]; + } + arr.push(t2); + arr.push(x, y); + $[4] = x; + $[5] = y; + $[6] = arr; + } else { + arr = $[6]; + } + return arr; + } + + ``` +  + +FAIL: array-property-call +- Expected ++ Received + + + ## Input + + ```javascript + 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}; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{a: 1, b: 2, c: 0}], + isComponent: false, + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(11); ++ Object.freeze(props); + let t0; + let a; + if ($[0] !== props.a || $[1] !== props.b) { + a = [props.a, props.b, "hello"]; + t0 = a.push(42); + $[0] = props.a; + $[1] = props.b; + $[2] = t0; + $[3] = a; + } else { + t0 = $[2]; + a = $[3]; + } + const x = t0; + let t1; + if ($[4] !== a || $[5] !== props.c) { + t1 = a.at(props.c); + $[4] = a; + $[5] = props.c; + $[6] = t1; + } else { + t1 = $[6]; + } + const y = t1; + let t2; + if ($[7] !== a || $[8] !== x || $[9] !== y) { + t2 = { a, x, y }; + $[7] = a; + $[8] = x; + $[9] = y; + $[10] = t2; + } else { + t2 = $[10]; + } + return t2; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ a: 1, b: 2, c: 0 }], + isComponent: false, + }; + + ``` +  + ### Eval output + (kind: ok) {"a":[1,2,"hello",42],"x":4,"y":1} + +FAIL: array-properties +- Expected ++ Received + + + ## Input + + ```javascript + 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}; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{a: [1, 2], b: 2}], + isComponent: false, + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(7); ++ Object.freeze(props); + let t0; + if ($[0] !== props.a || $[1] !== props.b) { + t0 = [props.a, props.b, "hello"]; + $[0] = props.a; + $[1] = props.b; + $[2] = t0; + } else { + t0 = $[2]; + } + const a = t0; + const x = a.length; + const y = a.push; + let t1; + if ($[3] !== a || $[4] !== x || $[5] !== y) { + t1 = { a, x, y, z: a.concat }; + $[3] = a; + $[4] = x; + $[5] = y; + $[6] = t1; + } else { + t1 = $[6]; + } + return t1; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ a: [1, 2], b: 2 }], + isComponent: false, + }; + + ``` +  + ### Eval output + (kind: ok) {"a":[[1,2],2,"hello"],"x":3,"y":"[[ function params=1 ]]","z":"[[ function params=1 ]]"} + +FAIL: array-pattern-params +- Expected ++ Received + + + ## Input + + ```javascript + function component([a, b]) { + let y = {a}; + let z = {b}; + return [y, z]; + } + + export const FIXTURE_ENTRYPOINT = { + fn: component, + params: [['val1', 'val2']], + isComponent: false, + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function component(t0) { + const $ = _c(7); ++ Object.freeze(t0); + const [a, b] = t0; + let t1; + if ($[0] !== a) { + t1 = { a }; + $[0] = a; + $[1] = t1; + } else { + t1 = $[1]; + } + const y = t1; + let t2; + if ($[2] !== b) { + t2 = { b }; + $[2] = b; + $[3] = t2; + } else { + t2 = $[3]; + } + const z = t2; + let t3; + if ($[4] !== y || $[5] !== z) { + t3 = [y, z]; + $[4] = y; + $[5] = z; + $[6] = t3; + } else { + t3 = $[6]; + } + return t3; + } + + export const FIXTURE_ENTRYPOINT = { + fn: component, + params: [["val1", "val2"]], + isComponent: false, + }; + + ``` +  + ### Eval output + (kind: ok) [{"a":"val1"},{"b":"val2"}] + +FAIL: array-map-noAlias-escaping-function +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + const f = item => item; + const x = [...props.items].map(f); // `f` doesn't escape here... + return [x, f]; // ...but it does here so it's memoized + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{items: [{id: 1}]}], + isComponent: false, + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(4); ++ Object.freeze(props); + const f = _temp; + let t0; + if ($[0] !== props.items) { + t0 = [...props.items].map(f); + $[0] = props.items; + $[1] = t0; + } else { + t0 = $[1]; + } + const x = t0; + let t1; + if ($[2] !== x) { + t1 = [x, f]; + $[2] = x; + $[3] = t1; + } else { + t1 = $[3]; + } + return t1; + } + function _temp(item) { + return item; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ items: [{ id: 1 }] }], + isComponent: false, + }; + + ``` +  + ### Eval output + (kind: ok) [[{"id":1}],"[[ function params=1 ]]"] + +FAIL: array-map-mutable-array-non-mutating-lambda-mutated-result +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + const x = [{}]; + const y = x.map(item => { + return item; + }); + y[0].flag = true; + return [x, y]; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + isComponent: false, + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(1); ++ Object.freeze(props); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + const x = [{}]; + const y = x.map(_temp); + y[0].flag = true; + t0 = [x, y]; + $[0] = t0; + } else { + t0 = $[0]; + } + return t0; + } + function _temp(item) { + return item; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + isComponent: false, + }; + + ``` +  + ### Eval output + (kind: ok) [[{"flag":true}],["[[ cyclic ref *2 ]]"]] + +FAIL: array-map-mutable-array-mutating-lambda +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + const x = []; + const y = x.map(item => { + item.updated = true; + return item; + }); + return [x, y]; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + isComponent: false, + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(1); ++ Object.freeze(props); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + const x = []; + const y = x.map(_temp); + t0 = [x, y]; + $[0] = t0; + } else { + t0 = $[0]; + } + return t0; + } + function _temp(item) { + item.updated = true; + return item; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + isComponent: false, + }; + + ``` +  + ### Eval output + (kind: ok) [[],[]] + +FAIL: array-map-mutable-array-mutating-lambda-noAlias +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + const x = []; + const y = x.map(item => { + item.updated = true; + return item; + }); + return [x, y]; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + isComponent: false, + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(1); ++ Object.freeze(props); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + const x = []; + const y = x.map(_temp); + t0 = [x, y]; + $[0] = t0; + } else { + t0 = $[0]; + } + return t0; + } + function _temp(item) { + item.updated = true; + return item; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + isComponent: false, + }; + + ``` +  + ### Eval output + (kind: ok) [[],[]] + +FAIL: array-map-frozen-array +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + const x = []; + {x}; + const y = x.map(item => item); + return [x, y]; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + isComponent: false, + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(2); ++ Object.freeze(props); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = []; + $[0] = t0; + } else { + t0 = $[0]; + } + const x = t0; + let t1; + if ($[1] === Symbol.for("react.memo_cache_sentinel")) { + const y = x.map(_temp); + t1 = [x, y]; + $[1] = t1; + } else { + t1 = $[1]; + } + return t1; + } + function _temp(item) { + return item; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + isComponent: false, + }; + + ``` +  + ### Eval output + (kind: ok) [[],[]] + +FAIL: array-map-frozen-array-noAlias +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + const x = []; + {x}; + const y = x.map(item => item); + return [x, y]; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + isComponent: false, + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(2); ++ Object.freeze(props); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = []; + $[0] = t0; + } else { + t0 = $[0]; + } + const x = t0; + let t1; + if ($[1] === Symbol.for("react.memo_cache_sentinel")) { + const y = x.map(_temp); + t1 = [x, y]; + $[1] = t1; + } else { + t1 = $[1]; + } + return t1; + } + function _temp(item) { + return item; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + isComponent: false, + }; + + ``` +  + ### Eval output + (kind: ok) [[],[]] + +FAIL: array-map-captures-receiver-noAlias +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + // This item is part of the receiver, should be memoized + const item = {a: props.a}; + const items = [item]; + const mapped = items.map(item => item); + return mapped; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{a: {id: 42}}], + isComponent: false, + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(6); ++ Object.freeze(props); + let t0; + if ($[0] !== props.a) { + t0 = { a: props.a }; + $[0] = props.a; + $[1] = t0; + } else { + t0 = $[1]; + } + const item = t0; + let t1; + if ($[2] !== item) { + t1 = [item]; + $[2] = item; + $[3] = t1; + } else { + t1 = $[3]; + } + const items = t1; + let t2; + if ($[4] !== items) { + t2 = items.map(_temp); + $[4] = items; + $[5] = t2; + } else { + t2 = $[5]; + } + const mapped = t2; + return mapped; + } + function _temp(item_0) { + return item_0; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ a: { id: 42 } }], + isComponent: false, + }; + + ``` +  + ### Eval output + (kind: ok) [{"a":{"id":42}}] + +FAIL: array-join +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + const x = [{}, [], props.value]; + const y = x.join(() => 'this closure gets stringified, not called'); + foo(y); + return [x, y]; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(7); ++ Object.freeze(props); + let t0; + let t1; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = {}; + t1 = []; + $[0] = t0; + $[1] = t1; + } else { + t0 = $[0]; + t1 = $[1]; + } + let t2; + if ($[2] !== props.value) { + t2 = [t0, t1, props.value]; + $[2] = props.value; + $[3] = t2; + } else { + t2 = $[3]; + } + const x = t2; + const y = x.join(_temp); + foo(y); + let t3; + if ($[4] !== x || $[5] !== y) { + t3 = [x, y]; + $[4] = x; + $[5] = y; + $[6] = t3; + } else { + t3 = $[6]; + } + return t3; + } + function _temp() { + return "this closure gets stringified, not called"; + } + + ``` +  + +FAIL: array-expression-spread +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + const x = [0, ...props.foo, null, ...props.bar, 'z']; + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{foo: [1, 2, 3], bar: [4, 5, 6]}], + isComponent: false, + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(3); ++ Object.freeze(props); + let t0; + if ($[0] !== props.foo || $[1] !== props.bar) { + t0 = [0, ...props.foo, null, ...props.bar, "z"]; + $[0] = props.foo; + $[1] = props.bar; + $[2] = t0; + } else { + t0 = $[2]; + } + const x = t0; + return x; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ foo: [1, 2, 3], bar: [4, 5, 6] }], + isComponent: false, + }; + + ``` +  + ### Eval output + (kind: ok) [0,1,2,3,null,4,5,6,"z"] + +FAIL: array-concat-should-capture +- Expected ++ Received + + + ## Input + + ```javascript + import {mutate} from 'shared-runtime'; + + /** + * Fixture showing why `concat` needs to capture both the callee and rest args. + * Here, observe that arr1's values are captured into arr2. + * - Later mutations of arr2 may write to values within arr1. + * - Observe that it's technically valid to separately memoize the array arr1 + * itself. + */ + function Foo({inputNum}) { + const arr1: Array = [{a: 1}, {}]; + const arr2 = arr1.concat([1, inputNum]); + mutate(arr2[0]); + return arr2; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Foo, + params: [{inputNum: 2}], + sequentialRenders: [{inputNum: 2}, {inputNum: 3}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { mutate } from "shared-runtime"; + + /** + * Fixture showing why `concat` needs to capture both the callee and rest args. + * Here, observe that arr1's values are captured into arr2. + * - Later mutations of arr2 may write to values within arr1. + * - Observe that it's technically valid to separately memoize the array arr1 + * itself. + */ + function Foo(t0) { + const $ = _c(2); ++ Object.freeze(t0); + const { inputNum } = t0; + let arr2; + if ($[0] !== inputNum) { + const arr1 = [{ a: 1 }, {}]; + arr2 = arr1.concat([1, inputNum]); + mutate(arr2[0]); + $[0] = inputNum; + $[1] = arr2; + } else { + arr2 = $[1]; + } + return arr2; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Foo, + params: [{ inputNum: 2 }], + sequentialRenders: [{ inputNum: 2 }, { inputNum: 3 }], + }; + + ``` +  + ### Eval output + (kind: ok) [{"a":1,"wat0":"joe"},{},1,2] + [{"a":1,"wat0":"joe"},{},1,3] + +FAIL: array-at-mutate-after-capture +- Expected ++ Received + + + ## Input + + ```javascript + // 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; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; // x's mutable range should extend to `mutate(y)` + + function Component(props) { + const $ = _c(2); ++ Object.freeze(props); + let x; + if ($[0] !== props.b) { + x = [42, {}]; + const idx = foo(props.b); + const y = x.at(idx); + mutate(y); + $[0] = props.b; + $[1] = x; + } else { + x = $[1]; + } + return x; + } + + ``` +  + +FAIL: array-at-effect +- Expected ++ Received + + + ## Input + + ```javascript + // 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; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; // arrayInstance.at should have the following effects: + // - read on arg0 + // - read on receiver + // - mutate on lvalue + function ArrayAtTest(props) { + const $ = _c(9); ++ Object.freeze(props); + let t0; + if ($[0] !== props.x) { + t0 = foo(props.x); + $[0] = props.x; + $[1] = t0; + } else { + t0 = $[1]; + } + let t1; + if ($[2] !== t0) { + t1 = [t0]; + $[2] = t0; + $[3] = t1; + } else { + t1 = $[3]; + } + const arr = t1; + let t2; + if ($[4] !== props.y || $[5] !== arr) { + let t3; + if ($[7] !== props.y) { + t3 = bar(props.y); + $[7] = props.y; + $[8] = t3; + } else { + t3 = $[8]; + } + t2 = arr.at(t3); + $[4] = props.y; + $[5] = arr; + $[6] = t2; + } else { + t2 = $[6]; + } + const result = t2; + return result; + } + + ``` +  + +FAIL: array-at-closure +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + const x = foo(props.x); + const fn = function () { + const arr = [...bar(props)]; + return arr.at(x); + }; + const fnResult = fn(); + return fnResult; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(7); ++ Object.freeze(props); + let t0; + if ($[0] !== props.x) { + t0 = foo(props.x); + $[0] = props.x; + $[1] = t0; + } else { + t0 = $[1]; + } + const x = t0; + let t1; + if ($[2] !== props || $[3] !== x) { + t1 = function () { + const arr = [...bar(props)]; + return arr.at(x); + }; + $[2] = props; + $[3] = x; + $[4] = t1; + } else { + t1 = $[4]; + } + const fn = t1; + let t2; + if ($[5] !== fn) { + t2 = fn(); + $[5] = fn; + $[6] = t2; + } else { + t2 = $[6]; + } + const fnResult = t2; + return fnResult; + } + + ``` +  + +FAIL: array-access-assignment +- Expected ++ Received + + + ## Input + + ```javascript + function Component({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]; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{a: 1, b: 20, c: 300}], + sequentialRenders: [ + {a: 2, b: 20, c: 300}, + {a: 3, b: 20, c: 300}, + {a: 3, b: 21, c: 300}, + {a: 3, b: 22, c: 300}, + {a: 3, b: 22, c: 301}, + ], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(t0) { + const $ = _c(6); ++ Object.freeze(t0); + const { a, b, c } = t0; + let t1; + if ($[0] !== a || $[1] !== b || $[2] !== c) { + const x = [a]; + let t2; + if ($[4] !== b) { + t2 = [null, b]; + $[4] = b; + $[5] = t2; + } else { + t2 = $[5]; + } + const y = t2; + const z = [[], [], [c]]; + x[0] = y[1]; + z[0][0] = x[0]; + t1 = [x, z]; + $[0] = a; + $[1] = b; + $[2] = c; + $[3] = t1; + } else { + t1 = $[3]; + } + return t1; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ a: 1, b: 20, c: 300 }], + sequentialRenders: [ + { a: 2, b: 20, c: 300 }, + { a: 3, b: 20, c: 300 }, + { a: 3, b: 21, c: 300 }, + { a: 3, b: 22, c: 300 }, + { a: 3, b: 22, c: 301 }, + ], + }; + + ``` +  + ### Eval output + (kind: ok) [[20],[[20],[],[300]]] + [[20],[[20],[],[300]]] + [[21],[[21],[],[300]]] + [[22],[[22],[],[300]]] + [[22],[[22],[],[301]]] + +FAIL: allow-ref-access-in-unused-callback-nested +- Expected ++ Received + + + ## Input + + ```javascript + // @validateRefAccessDuringRender + import {useEffect, useRef, useState} from 'react'; + + function Component() { + const ref = useRef(null); + const [state, setState] = useState(false); + useEffect(() => { + const callback = () => { + ref.current = 'Ok'; + }; + }, []); + + useEffect(() => { + setState(true); + }, []); + + // We use state to force a re-render and observe whether the + // ref updated. This lets us check that the effect actually ran + // and wasn't DCE'd + return ; + } + + function Child({ref}) { + // This violates the rules of React, so we access the ref in a child + // component + return ref.current; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; // @validateRefAccessDuringRender + import { useEffect, useRef, useState } from "react"; + + function Component() { + const $ = _c(7); +- const ref = useRef(null); +- const [state, setState] = useState(false); ++ const ref = (function () { ++ const $res$ = useRef(Object.freeze(null)); ++ Object.freeze($res$); ++ return $res$; ++ })(); ++ const [state, setState] = (function () { ++ const $res$ = useState(Object.freeze(false)); ++ Object.freeze($res$); ++ return $res$; ++ })(); + let t0; + let t1; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = () => {}; + + t1 = []; + $[0] = t0; + $[1] = t1; + } else { + t0 = $[0]; + t1 = $[1]; + } +- useEffect(t0, t1); ++ (function () { ++ const $res$ = useEffect(Object.freeze(t0), Object.freeze(t1)); ++ Object.freeze($res$); ++ return $res$; ++ })(); + let t2; + let t3; + if ($[2] === Symbol.for("react.memo_cache_sentinel")) { + t2 = () => { + setState(true); + }; + t3 = []; + $[2] = t2; + $[3] = t3; + } else { + t2 = $[2]; + t3 = $[3]; + } +- useEffect(t2, t3); ++ (function () { ++ const $res$ = useEffect(Object.freeze(t2), Object.freeze(t3)); ++ Object.freeze($res$); ++ return $res$; ++ })(); + + const t4 = String(state); + let t5; + if ($[4] !== t4 || $[5] !== ref) { +- t5 = ; ++ t5 = ( ++  ++ ); + $[4] = t4; + $[5] = ref; + $[6] = t5; + } else { + t5 = $[6]; + } + return t5; + } + + function Child(t0) { ++ Object.freeze(t0); + const { ref } = t0; + return ref.current; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + }; + + ``` +  + ### Eval output + (kind: ok)  + +FAIL: allow-ref-access-in-effect + >> Unexpected error during test: + + +Found differences in evaluator results +Non-forget (expected): +(kind: ok) Ok +Forget: +(kind: exception) Cannot assign to read only property 'current' of object '#' + +FAIL: allow-ref-access-in-effect-indirect + >> Unexpected error during test: + + +Found differences in evaluator results +Non-forget (expected): +(kind: ok) Ok +Forget: +(kind: exception) Cannot assign to read only property 'current' of object '#' + +FAIL: allow-reassignment-to-global-function-jsx-prop +- Expected ++ Received + + + ## Input + + ```javascript + function Component() { + const onClick = () => { + // Cannot assign to globals + someUnknownGlobal = true; + moduleLocal = true; + }; + // It's possible that this could be an event handler / effect function, + // but we don't know that and optimistically assume it will only be + // called by an event handler or effect, where it is allowed to modify globals + return
; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component() { + const $ = _c(1); + const onClick = _temp; + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { +- t0 =
; ++ t0 = ( ++  ++ ); + $[0] = t0; + } else { + t0 = $[0]; + } + return t0; + } + function _temp() { + someUnknownGlobal = true; + moduleLocal = true; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + }; + + ``` +  + ### Eval output + (kind: ok)
 + +FAIL: allow-passing-refs-as-props +- Expected ++ Received + + + ## Input + + ```javascript + function Component(props) { + const ref = useRef(null); + return ; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function Component(props) { + const $ = _c(2); +- const ref = useRef(null); ++ Object.freeze(props); ++ const ref = (function () { ++ const $res$ = useRef(Object.freeze(null)); ++ Object.freeze($res$); ++ return $res$; ++ })(); + let t0; + if ($[0] !== ref) { +- t0 = ; ++ t0 = ( ++  ++ ); + $[0] = ref; + $[1] = t0; + } else { + t0 = $[1]; + } + return t0; + } + + ``` +  + +FAIL: allow-mutating-ref-property-in-callback-passed-to-jsx +- Expected ++ Received + + + ## Input + + ```javascript + // @validateRefAccessDuringRender + import {useRef} from 'react'; + + function Component() { + const ref = useRef(null); + + const onClick = () => { + if (ref.current !== null) { + ref.current.value = ''; + } + }; + + return ( + <> +  +  + +FAIL: allow-mutating-ref-property-in-callback-passed-to-jsx-indirect +- Expected ++ Received + + + ## Input + + ```javascript + // @validateRefAccessDuringRender + import {useRef} from 'react'; + + function Component() { + const ref = useRef(null); + + const setRef = () => { + if (ref.current !== null) { + ref.current.value = ''; + } + }; + + const onClick = () => { + setRef(); + }; + + return ( + <> +  +  + +FAIL: allow-mutating-ref-in-callback-passed-to-jsx +- Expected ++ Received + + + ## Input + + ```javascript + // @validateRefAccessDuringRender + import {useRef} from 'react'; + + function Component() { + const ref = useRef(null); + + const onClick = () => { + if (ref.current !== null) { + ref.current = ''; + } + }; + + return ( + <> +  +  + +FAIL: allow-mutating-ref-in-callback-passed-to-jsx-indirect +- Expected ++ Received + + + ## Input + + ```javascript + // @validateRefAccessDuringRender + import {useRef} from 'react'; + + function Component() { + const ref = useRef(null); + + const setRef = () => { + if (ref.current !== null) { + ref.current = ''; + } + }; + + const onClick = () => { + setRef(); + }; + + return ( + <> +  +  + +FAIL: allow-mutate-global-in-effect-fixpoint + >> Unexpected error during test: + + +Found differences in evaluator results +Non-forget (expected): +(kind: ok)
hello
+Forget: +(kind: exception) Cannot assign to read only property 'value' of object '#' + +FAIL: allow-modify-global-in-callback-jsx +- Expected ++ Received + + + ## Input + + ```javascript + import {useMemo} from 'react'; + + const someGlobal = {value: 0}; + + function Component({value}) { + const onClick = () => { + someGlobal.value = value; + }; + return useMemo(() => { + return
{someGlobal.value}
; + }, []); + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{value: 0}], + sequentialRenders: [ + {value: 1}, + {value: 1}, + {value: 42}, + {value: 42}, + {value: 0}, + ], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { useMemo } from "react"; + + const someGlobal = { value: 0 }; + + function Component(t0) { + const $ = _c(4); ++ Object.freeze(t0); + const { value } = t0; + let t1; + if ($[0] !== value) { + t1 = () => { + someGlobal.value = value; + }; + $[0] = value; + $[1] = t1; + } else { + t1 = $[1]; + } + const onClick = t1; + let t2; + let t3; + if ($[2] !== onClick) { +- t3 =
{someGlobal.value}
; ++ t3 = ( ++  ++ {someGlobal.value} ++  ++ ); + $[2] = onClick; + $[3] = t3; + } else { + t3 = $[3]; + } + t2 = t3; + return t2; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ value: 0 }], + sequentialRenders: [ + { value: 1 }, + { value: 1 }, + { value: 42 }, + { value: 42 }, + { value: 0 }, + ], + }; + + ``` +  + ### Eval output + (kind: ok)
0
 +
0
 +
0
 +
0
 +
0
 + +FAIL: allow-global-reassignment-in-effect +- Expected ++ Received + + + ## Input + + ```javascript + import {useEffect, useState} from 'react'; + + let someGlobal = false; + + function Component() { + const [state, setState] = useState(someGlobal); + + useEffect(() => { + someGlobal = true; + }, []); + + useEffect(() => { + setState(someGlobal); + }, [someGlobal]); + + return
{String(state)}
; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { useEffect, useState } from "react"; + + let someGlobal = false; + + function Component() { + const $ = _c(5); +- const [state, setState] = useState(someGlobal); ++ const [state, setState] = (function () { ++ const $res$ = useState(Object.freeze(someGlobal)); ++ Object.freeze($res$); ++ return $res$; ++ })(); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = []; + $[0] = t0; + } else { + t0 = $[0]; + } +- useEffect(_temp, t0); ++ (function () { ++ const $res$ = useEffect(Object.freeze(_temp), Object.freeze(t0)); ++ Object.freeze($res$); ++ return $res$; ++ })(); + let t1; + let t2; + if ($[1] === Symbol.for("react.memo_cache_sentinel")) { + t1 = () => { + setState(someGlobal); + }; + t2 = [someGlobal]; + $[1] = t1; + $[2] = t2; + } else { + t1 = $[1]; + t2 = $[2]; + } +- useEffect(t1, t2); ++ (function () { ++ const $res$ = useEffect(Object.freeze(t1), Object.freeze(t2)); ++ Object.freeze($res$); ++ return $res$; ++ })(); + + const t3 = String(state); + let t4; + if ($[3] !== t3) { + t4 =
{t3}
; + $[3] = t3; + $[4] = t4; + } else { + t4 = $[4]; + } + return t4; + } + function _temp() { + someGlobal = true; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + }; + + ``` +  + ### Eval output + (kind: ok)
true
 + +FAIL: allow-global-reassignment-in-effect-indirect +- Expected ++ Received + + + ## Input + + ```javascript + import {useEffect, useState} from 'react'; + + let someGlobal = false; + + function Component() { + const [state, setState] = useState(someGlobal); + + const setGlobal = () => { + someGlobal = true; + }; + useEffect(() => { + setGlobal(); + }, []); + + useEffect(() => { + setState(someGlobal); + }, [someGlobal]); + + return
{String(state)}
; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { useEffect, useState } from "react"; + + let someGlobal = false; + + function Component() { + const $ = _c(6); +- const [state, setState] = useState(someGlobal); ++ const [state, setState] = (function () { ++ const $res$ = useState(Object.freeze(someGlobal)); ++ Object.freeze($res$); ++ return $res$; ++ })(); + + const setGlobal = _temp; + let t0; + let t1; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = () => { + setGlobal(); + }; + t1 = []; + $[0] = t0; + $[1] = t1; + } else { + t0 = $[0]; + t1 = $[1]; + } +- useEffect(t0, t1); ++ (function () { ++ const $res$ = useEffect(Object.freeze(t0), Object.freeze(t1)); ++ Object.freeze($res$); ++ return $res$; ++ })(); + let t2; + let t3; + if ($[2] === Symbol.for("react.memo_cache_sentinel")) { + t2 = () => { + setState(someGlobal); + }; + t3 = [someGlobal]; + $[2] = t2; + $[3] = t3; + } else { + t2 = $[2]; + t3 = $[3]; + } +- useEffect(t2, t3); ++ (function () { ++ const $res$ = useEffect(Object.freeze(t2), Object.freeze(t3)); ++ Object.freeze($res$); ++ return $res$; ++ })(); + + const t4 = String(state); + let t5; + if ($[4] !== t4) { + t5 =
{t4}
; + $[4] = t4; + $[5] = t5; + } else { + t5 = $[5]; + } + return t5; + } + function _temp() { + someGlobal = true; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], + }; + + ``` +  + ### Eval output + (kind: ok)
true
 + +FAIL: allow-global-mutation-in-effect-indirect + >> Unexpected error during test: + + +Found differences in evaluator results +Non-forget (expected): +(kind: ok)
true
+Forget: +(kind: exception) Cannot add property value, object is not extensible + +FAIL: allow-global-mutation-in-effect-indirect-usecallback + >> Unexpected error during test: + + +Found differences in evaluator results +Non-forget (expected): +(kind: ok)
true
+Forget: +(kind: exception) Cannot add property value, object is not extensible + +FAIL: allocating-primitive-as-dep +- Expected ++ Received + + + ## Input + + ```javascript + // 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; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; // 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) { + const $ = _c(2); ++ Object.freeze(props); + const t0 = bar(props).b + 1; + let t1; + if ($[0] !== t0) { + t1 = foo(t0); + $[0] = t0; + $[1] = t1; + } else { + t1 = $[1]; + } + const y = t1; + return y; + } + + ``` +  + +FAIL: allocating-primitive-as-dep-nested-scope +- Expected ++ Received + + + ## Input + + ```javascript + // bar(props.b) is an allocating expression that produces a primitive, which means + // that Forget should memoize it. + // Correctness: + + import {identity, mutate, setProperty} from 'shared-runtime'; + + // - y depends on either bar(props.b) or bar(props.b) + 1 + function AllocatingPrimitiveAsDepNested(props) { + let x = {}; + mutate(x); + let y = identity(identity(props.b) + 1); + setProperty(x, props.a); + return [x, y]; + } + + export const FIXTURE_ENTRYPOINT = { + fn: AllocatingPrimitiveAsDepNested, + params: [{a: 1, b: 2}], + sequentialRenders: [ + // change b + {a: 1, b: 3}, + // change b + {a: 1, b: 4}, + // change a + {a: 2, b: 4}, + // change a + {a: 3, b: 4}, + ], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; // bar(props.b) is an allocating expression that produces a primitive, which means + // that Forget should memoize it. + // Correctness: + + import { identity, mutate, setProperty } from "shared-runtime"; + + // - y depends on either bar(props.b) or bar(props.b) + 1 + function AllocatingPrimitiveAsDepNested(props) { + const $ = _c(5); ++ Object.freeze(props); + let t0; + if ($[0] !== props.b || $[1] !== props.a) { + const x = {}; + mutate(x); + const t1 = identity(props.b) + 1; + let t2; + if ($[3] !== t1) { + t2 = identity(t1); + $[3] = t1; + $[4] = t2; + } else { + t2 = $[4]; + } + const y = t2; + setProperty(x, props.a); + t0 = [x, y]; + $[0] = props.b; + $[1] = props.a; + $[2] = t0; + } else { + t0 = $[2]; + } + return t0; + } + + export const FIXTURE_ENTRYPOINT = { + fn: AllocatingPrimitiveAsDepNested, + params: [{ a: 1, b: 2 }], + sequentialRenders: [ + // change b + { a: 1, b: 3 }, + // change b + { a: 1, b: 4 }, + // change a + { a: 2, b: 4 }, + // change a + { a: 3, b: 4 }, + ], + }; + + ``` +  + ### Eval output + (kind: ok) [{"wat0":"joe","wat1":1},4] + [{"wat0":"joe","wat1":1},5] + [{"wat0":"joe","wat1":2},5] + [{"wat0":"joe","wat1":3},5] + +FAIL: allocating-logical-expression-instruction-scope +- Expected ++ Received + + + ## Input + + ```javascript + /** + * This is a weird case as data has type `BuiltInMixedReadonly`. + * The only scoped value we currently infer in this program is the + * PropertyLoad `data?.toString`. + */ + import {useFragment} from 'shared-runtime'; + + function Foo() { + const data = useFragment(); + return [data?.toString() || '']; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Foo, + params: [], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; /** + * This is a weird case as data has type `BuiltInMixedReadonly`. + * The only scoped value we currently infer in this program is the + * PropertyLoad `data?.toString`. + */ + import { useFragment } from "shared-runtime"; + + function Foo() { + const $ = _c(4); +- const data = useFragment(); ++ const data = (function () { ++ const $res$ = useFragment(); ++ Object.freeze($res$); ++ return $res$; ++ })(); + let t0; + if ($[0] !== data) { + t0 = data?.toString() || ""; + $[0] = data; + $[1] = t0; + } else { + t0 = $[1]; + } + let t1; + if ($[2] !== t0) { + t1 = [t0]; + $[2] = t0; + $[3] = t1; + } else { + t1 = $[3]; + } + return t1; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Foo, + params: [], + }; + + ``` +  + ### Eval output + (kind: ok) ["[object Object]"] + +FAIL: align-scopes-within-nested-valueblock-in-array + >> Unexpected error during test: + + +Found differences in evaluator results +Non-forget (expected): +(kind: ok)
foo
{"value":[null,null,null]}
+Forget: +(kind: ok)
foo
{"value":"[[ function params=0 ]]"}
+ +FAIL: align-scopes-reactive-scope-overlaps-try +- Expected ++ Received + + + ## Input + + ```javascript + import {arrayPush, mutate} from 'shared-runtime'; + + function useFoo({value}) { + let items = null; + try { + // Mutable range of `items` begins here, but its reactive scope block + // should be aligned to above the try-block + items = []; + arrayPush(items, value); + } catch { + // ignore + } + mutate(items); + return items; + } + + export const FIXTURE_ENTRYPOINT = { + fn: useFoo, + params: [{value: 2}], + sequentialRenders: [{value: 2}, {value: 2}, {value: 3}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { arrayPush, mutate } from "shared-runtime"; + + function useFoo(t0) { + const $ = _c(2); ++ Object.freeze(t0); + const { value } = t0; + let items; + if ($[0] !== value) { + try { + items = []; + arrayPush(items, value); + } catch {} + + mutate(items); + $[0] = value; + $[1] = items; + } else { + items = $[1]; + } + return items; + } + + export const FIXTURE_ENTRYPOINT = { + fn: useFoo, + params: [{ value: 2 }], + sequentialRenders: [{ value: 2 }, { value: 2 }, { value: 3 }], + }; + + ``` +  + ### Eval output + (kind: ok) [2] + [2] + [3] + +FAIL: align-scopes-reactive-scope-overlaps-label +- Expected ++ Received + + + ## Input + + ```javascript + import {arrayPush} from 'shared-runtime'; + + function useFoo({cond, value}) { + let items; + label: { + items = []; + // Mutable range of `items` begins here, but its reactive scope block + // should be aligned to above the label-block + if (cond) break label; + arrayPush(items, value); + } + arrayPush(items, value); + return items; + } + + export const FIXTURE_ENTRYPOINT = { + fn: useFoo, + params: [{cond: true, value: 2}], + sequentialRenders: [ + {cond: true, value: 2}, + {cond: true, value: 2}, + {cond: true, value: 3}, + {cond: false, value: 3}, + ], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { arrayPush } from "shared-runtime"; + + function useFoo(t0) { + const $ = _c(3); ++ Object.freeze(t0); + const { cond, value } = t0; + let items; + if ($[0] !== cond || $[1] !== value) { + bb0: { + items = []; + if (cond) { + break bb0; + } + arrayPush(items, value); + } + + arrayPush(items, value); + $[0] = cond; + $[1] = value; + $[2] = items; + } else { + items = $[2]; + } + return items; + } + + export const FIXTURE_ENTRYPOINT = { + fn: useFoo, + params: [{ cond: true, value: 2 }], + sequentialRenders: [ + { cond: true, value: 2 }, + { cond: true, value: 2 }, + { cond: true, value: 3 }, + { cond: false, value: 3 }, + ], + }; + + ``` +  + ### Eval output + (kind: ok) [2] + [2] + [3] + [3,3] + +FAIL: align-scopes-reactive-scope-overlaps-if +- Expected ++ Received + + + ## Input + + ```javascript + function useFoo({cond}) { + let items: any = {}; + b0: { + if (cond) { + // Mutable range of `items` begins here, but its reactive scope block + // should be aligned to above the if-branch + items = []; + } else { + break b0; + } + items.push(2); + } + return items; + } + + export const FIXTURE_ENTRYPOINT = { + fn: useFoo, + params: [{cond: true}], + sequentialRenders: [ + {cond: true}, + {cond: true}, + {cond: false}, + {cond: false}, + {cond: true}, + ], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function useFoo(t0) { + const $ = _c(3); ++ Object.freeze(t0); + const { cond } = t0; + let t1; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t1 = {}; + $[0] = t1; + } else { + t1 = $[0]; + } + let items = t1; + bb0: if ($[1] !== cond) { + if (cond) { + items = []; + } else { + break bb0; + } + + items.push(2); + $[1] = cond; + $[2] = items; + } else { + items = $[2]; + } + return items; + } + + export const FIXTURE_ENTRYPOINT = { + fn: useFoo, + params: [{ cond: true }], + sequentialRenders: [ + { cond: true }, + { cond: true }, + { cond: false }, + { cond: false }, + { cond: true }, + ], + }; + + ``` +  + ### Eval output + (kind: ok) [2] + [2] + {} + {} + [2] + +FAIL: align-scopes-nested-block-structure +- Expected ++ Received + + + ## Input + + ```javascript + import {mutate} from 'shared-runtime'; + /** + * Fixture showing that it's not sufficient to only align direct scoped + * accesses of a block-fallthrough pair. + * Below is a simplified view of HIR blocks in this fixture. + * Note that here, s is mutated in both bb1 and bb4. However, neither + * bb1 nor bb4 have terminal fallthroughs or are fallthroughs themselves. + * + * This means that we need to recursively visit all scopes accessed between + * a block and its fallthrough and extend the range of those scopes which overlap + * with an active block/fallthrough pair, + * + * bb0 + * ┌──────────────┐ + * │let s = null │ + * │test cond1 │ + * │ │ + * └┬─────────────┘ + * │ bb1 + * ├─►┌───────┐ + * │ │s = {} ├────┐ + * │ └───────┘ │ + * │ bb2 │ + * └─►┌───────┐ │ + * │return;│ │ + * └───────┘ │ + * bb3 │ + * ┌──────────────┐◄┘ + * │test cond2 │ + * │ │ + * └┬─────────────┘ + * │ bb4 + * ├─►┌─────────┐ + * │ │mutate(s)├─┐ + * ▼ └─────────┘ │ + * bb5 │ + * ┌───────────┐ │ + * │return s; │◄──┘ + * └───────────┘ + */ + function useFoo({cond1, cond2}) { + let s = null; + if (cond1) { + s = {}; + } else { + return null; + } + + if (cond2) { + mutate(s); + } + + return s; + } + + export const FIXTURE_ENTRYPOINT = { + fn: useFoo, + params: [{cond1: true, cond2: false}], + sequentialRenders: [ + {cond1: true, cond2: false}, + {cond1: true, cond2: false}, + {cond1: true, cond2: true}, + {cond1: true, cond2: true}, + {cond1: false, cond2: true}, + ], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { mutate } from "shared-runtime"; + /** + * Fixture showing that it's not sufficient to only align direct scoped + * accesses of a block-fallthrough pair. + * Below is a simplified view of HIR blocks in this fixture. + * Note that here, s is mutated in both bb1 and bb4. However, neither + * bb1 nor bb4 have terminal fallthroughs or are fallthroughs themselves. + * + * This means that we need to recursively visit all scopes accessed between + * a block and its fallthrough and extend the range of those scopes which overlap + * with an active block/fallthrough pair, + * + * bb0 + * ┌──────────────┐ + * │let s = null │ + * │test cond1 │ + * │ │ + * └┬─────────────┘ + * │ bb1 + * ├─►┌───────┐ + * │ │s = {} ├────┐ + * │ └───────┘ │ + * │ bb2 │ + * └─►┌───────┐ │ + * │return;│ │ + * └───────┘ │ + * bb3 │ + * ┌──────────────┐◄┘ + * │test cond2 │ + * │ │ + * └┬─────────────┘ + * │ bb4 + * ├─►┌─────────┐ + * │ │mutate(s)├─┐ + * ▼ └─────────┘ │ + * bb5 │ + * ┌───────────┐ │ + * │return s; │◄──┘ + * └───────────┘ + */ + function useFoo(t0) { + const $ = _c(4); ++ Object.freeze(t0); + const { cond1, cond2 } = t0; + let s; + let t1; + if ($[0] !== cond1 || $[1] !== cond2) { + t1 = Symbol.for("react.early_return_sentinel"); + bb0: { + if (cond1) { + s = {}; + } else { + t1 = null; + break bb0; + } + if (cond2) { + mutate(s); + } + } + $[0] = cond1; + $[1] = cond2; + $[2] = t1; + $[3] = s; + } else { + t1 = $[2]; + s = $[3]; + } + if (t1 !== Symbol.for("react.early_return_sentinel")) { + return t1; + } + return s; + } + + export const FIXTURE_ENTRYPOINT = { + fn: useFoo, + params: [{ cond1: true, cond2: false }], + sequentialRenders: [ + { cond1: true, cond2: false }, + { cond1: true, cond2: false }, + { cond1: true, cond2: true }, + { cond1: true, cond2: true }, + { cond1: false, cond2: true }, + ], + }; + + ``` +  + ### Eval output + (kind: ok) {} + {} + {"wat0":"joe"} + {"wat0":"joe"} + null + +FAIL: align-scopes-iife-return-modified-later-logical +- Expected ++ Received + + + ## Input + + ```javascript + import {getNull} from 'shared-runtime'; + + function Component(props) { + const items = (() => { + return getNull() ?? []; + })(); + items.push(props.a); + return items; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{a: {}}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { getNull } from "shared-runtime"; + + function Component(props) { + const $ = _c(3); ++ Object.freeze(props); + let t0; + let items; + if ($[0] !== props.a) { + t0 = getNull() ?? []; + items = t0; + + items.push(props.a); + $[0] = props.a; + $[1] = items; + $[2] = t0; + } else { + items = $[1]; + t0 = $[2]; + } + return items; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ a: {} }], + }; + + ``` +  + ### Eval output + (kind: ok) [{}] + +FAIL: align-scope-starts-within-cond +- Expected ++ Received + + + ## Input + + ```javascript + import {mutate} from 'shared-runtime'; + + /** + * Similar fixture to `align-scopes-nested-block-structure`, but + * a simpler case. + */ + function useFoo(cond) { + let s = null; + if (cond) { + s = {}; + } else { + return null; + } + mutate(s); + return s; + } + + export const FIXTURE_ENTRYPOINT = { + fn: useFoo, + params: [true], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { mutate } from "shared-runtime"; + + /** + * Similar fixture to `align-scopes-nested-block-structure`, but + * a simpler case. + */ + function useFoo(cond) { + const $ = _c(3); ++ Object.freeze(cond); + let s; + let t0; + if ($[0] !== cond) { + t0 = Symbol.for("react.early_return_sentinel"); + bb0: { + if (cond) { + s = {}; + } else { + t0 = null; + break bb0; + } + + mutate(s); + } + $[0] = cond; + $[1] = t0; + $[2] = s; + } else { + t0 = $[1]; + s = $[2]; + } + if (t0 !== Symbol.for("react.early_return_sentinel")) { + return t0; + } + return s; + } + + export const FIXTURE_ENTRYPOINT = { + fn: useFoo, + params: [true], + }; + + ``` +  + ### Eval output + (kind: ok) {"wat0":"joe"} + +FAIL: alias-while +- Expected ++ Received + + + ## Input + + ```javascript + 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) {} + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function foo(cond) { + const $ = _c(2); ++ Object.freeze(cond); + let a; + if ($[0] !== cond) { + a = {}; + let b = {}; + let c = {}; + while (cond) { + const z = a; + a = b; + b = c; + c = z; + mutate(a, b); + } + $[0] = cond; + $[1] = a; + } else { + a = $[1]; + } + return a; + } + +- function mutate(x, y) {} ++ function mutate(x, y) { ++ Object.freeze(x); ++ Object.freeze(y); ++ } + + ``` +  + +FAIL: alias-computed-load +- Expected ++ Received + + + ## Input + + ```javascript + function component(a) { + let x = {a}; + let y = {}; + + y.x = x['a']; + mutate(y); + return x; + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + function component(a) { + const $ = _c(2); ++ Object.freeze(a); + let x; + if ($[0] !== a) { + x = { a }; + const y = {}; + + y.x = x.a; + mutate(y); + $[0] = a; + $[1] = x; + } else { + x = $[1]; + } + return x; + } + + ``` +  + +FAIL: type-annotations/type-annotation-var-array_.flow +- Expected ++ Received + + + ## Input + + ```javascript + // @flow @enableUseTypeAnnotations + import {identity} from 'shared-runtime'; + + function Component(props: {id: number}) { + const x: Array = makeArray(props.id); + const y = x.at(0); + return y; + } + + function makeArray(x: T): Array { + return [x]; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{id: 42}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { identity } from "shared-runtime"; + + function Component(props) { + const $ = _c(4); ++ Object.freeze(props); + let t0; + if ($[0] !== props.id) { + t0 = makeArray(props.id); + $[0] = props.id; + $[1] = t0; + } else { + t0 = $[1]; + } + const x = t0; + let t1; + if ($[2] !== x) { + t1 = x.at(0); + $[2] = x; + $[3] = t1; + } else { + t1 = $[3]; + } + const y = t1; + return y; + } + + function makeArray(x) { + const $ = _c(2); ++ Object.freeze(x); + let t0; + if ($[0] !== x) { + t0 = [x]; + $[0] = x; + $[1] = t0; + } else { + t0 = $[1]; + } + return t0; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ id: 42 }], + }; + + ``` +  + ### Eval output + (kind: ok) 42 + +FAIL: type-annotations/type-annotation-var-array +- Expected ++ Received + + + ## Input + + ```javascript + // @enableUseTypeAnnotations + function Component(props: {id: number}) { + const x: number[] = makeArray(props.id); + const y = x.at(0); + return y; + } + + function makeArray(x: T): Array { + return [x]; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{id: 42}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; // @enableUseTypeAnnotations + function Component(props) { + const $ = _c(4); ++ Object.freeze(props); + let t0; + if ($[0] !== props.id) { + t0 = makeArray(props.id); + $[0] = props.id; + $[1] = t0; + } else { + t0 = $[1]; + } + const x = t0; + let t1; + if ($[2] !== x) { + t1 = x.at(0); + $[2] = x; + $[3] = t1; + } else { + t1 = $[3]; + } + const y = t1; + return y; + } + + function makeArray(x) { + const $ = _c(2); ++ Object.freeze(x); + let t0; + if ($[0] !== x) { + t0 = [x]; + $[0] = x; + $[1] = t0; + } else { + t0 = $[1]; + } + return t0; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ id: 42 }], + }; + + ``` +  + ### Eval output + (kind: ok) 42 + +FAIL: type-annotations/type-annotation-as-number_.flow +- Expected ++ Received + + + ## Input + + ```javascript + // @flow @enableUseTypeAnnotations + import {identity} from 'shared-runtime'; + + function Component(props: {id: number}) { + const x = identity(props.id); + const y = (x: number); + return y; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{id: 42}], + }; + + ``` + + ## Code + + ```javascript + import { identity } from "shared-runtime"; + + function Component(props) { ++ Object.freeze(props); + const x = identity(props.id); + const y = (x: number); + return y; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ id: 42 }], + }; + + ``` +  + ### Eval output + (kind: ok) 42 + +FAIL: type-annotations/type-annotation-as-number +- Expected ++ Received + + + ## Input + + ```javascript + // @enableUseTypeAnnotations + import {identity} from 'shared-runtime'; + + function Component(props: {id: number}) { + const x = identity(props.id); + const y = x as number; + return y; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{id: 42}], + }; + + ``` + + ## Code + + ```javascript + // @enableUseTypeAnnotations + import { identity } from "shared-runtime"; + + function Component(props) { ++ Object.freeze(props); + const x = identity(props.id); + const y = x as number; + return y; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ id: 42 }], + }; + + ``` +  + ### Eval output + (kind: ok) 42 + +FAIL: type-annotations/type-annotation-as-array_.flow +- Expected ++ Received + + + ## Input + + ```javascript + // @flow @enableUseTypeAnnotations + import {identity, makeArray} from 'shared-runtime'; + + function Component(props: {id: number}) { + const x = (makeArray(props.id): Array); + const y = x.at(0); + return y; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{id: 42}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; + import { identity, makeArray } from "shared-runtime"; + + function Component(props) { + const $ = _c(4); ++ Object.freeze(props); + let t0; + if ($[0] !== props.id) { + t0 = makeArray(props.id); + $[0] = props.id; + $[1] = t0; + } else { + t0 = $[1]; + } + const x = (t0: Array); + let t1; + if ($[2] !== x) { + t1 = x.at(0); + $[2] = x; + $[3] = t1; + } else { + t1 = $[3]; + } + const y = t1; + return y; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ id: 42 }], + }; + + ``` +  + ### Eval output + (kind: ok) 42 + +FAIL: type-annotations/type-annotation-as-array +- Expected ++ Received + + + ## Input + + ```javascript + // @enableUseTypeAnnotations + function Component(props: {id: number}) { + const x = makeArray(props.id) as number[]; + const y = x.at(0); + return y; + } + + function makeArray(x: T): Array { + return [x]; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{id: 42}], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; // @enableUseTypeAnnotations + function Component(props) { + const $ = _c(4); ++ Object.freeze(props); + let t0; + if ($[0] !== props.id) { + t0 = makeArray(props.id); + $[0] = props.id; + $[1] = t0; + } else { + t0 = $[1]; + } + const x = t0 as number[]; + let t1; + if ($[2] !== x) { + t1 = x.at(0); + $[2] = x; + $[3] = t1; + } else { + t1 = $[3]; + } + const y = t1; + return y; + } + + function makeArray(x) { + const $ = _c(2); ++ Object.freeze(x); + let t0; + if ($[0] !== x) { + t0 = [x]; + $[0] = x; + $[1] = t0; + } else { + t0 = $[1]; + } + return t0; + } + + export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ id: 42 }], + }; + + ``` +  + ### Eval output + (kind: ok) 42 + +FAIL: type-annotations/todo_type-annotations-props +- Expected ++ Received + + + ## Input + + ```javascript + // @enableUseTypeAnnotations + function useArray(items: Array) { + // With type information we know that the callback cannot escape + // and does not need to be memoized, only the result needs to be + // memoized: + return items.filter(x => x !== 0); + } + + export const FIXTURE_ENTRYPOINT = { + fn: useArray, + params: [[1, 0, 2, 0, 3, 0, 42]], + }; + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; // @enableUseTypeAnnotations + function useArray(items) { + const $ = _c(2); ++ Object.freeze(items); + let t0; + if ($[0] !== items) { + t0 = items.filter(_temp); + $[0] = items; + $[1] = t0; + } else { + t0 = $[1]; + } + return t0; + } + function _temp(x) { + return x !== 0; + } + + export const FIXTURE_ENTRYPOINT = { + fn: useArray, + params: [[1, 0, 2, 0, 3, 0, 42]], + }; + + ``` +  + ### Eval output + (kind: ok) [1,2,3,42] + +FAIL: rules-of-hooks/todo.invalid.invalid-rules-of-hooks-e675f0a672d8 +- Expected ++ Received + + + ## Input + + ```javascript + // @skip + // Passed but should have failed + + // Invalid because it's dangerous and might not warn otherwise. + // This *must* be invalid. + function renderItem() { + useState(); + } + + function List(props) { + return props.items.map(renderItem); + } + + ``` + + ## Code + + ```javascript + import { c as _c } from "react/compiler-runtime"; // @skip + // Passed but should have failed + + // Invalid because it's dangerous and might not warn otherwise. + // This *must* be invalid. + function renderItem() { +- useState(); ++ (function () { ++ const $res$ = useState(); ++ Object.freeze($res$); ++ return $res$; ++ })(); + } + + function List(props) { + const $ = _c(2); ++ Object.freeze(props); + let t0; + if ($[0] !== props.items) { + t0 = props.items.map(renderItem); + $[0] = props.items; + $[1] = t0; + } else { + t0 = $[1]; + } + return t0; + } + + ``` +  + +FAIL: rules-of-hooks/todo.invalid.invalid-rules-of-hooks-c59788ef5676 +- Expected ++ Received + + + ## Input + + ```javascript + // @skip + // Passed but should have failed + + // Currently invalid because it violates the convention and removes the "taint" + // from a hook. We *could* make it valid to avoid some false positives but let's + // ensure that we don't break the "renderItem" and "normalFunctionWithConditionalHook" + // cases which must remain invalid. + function normalFunctionWithHook() { + useHookInsideNormalFunction(); + } + + ``` + + ## Code + + ```javascript + // @skip + // Passed but should have failed + + // Currently invalid because it violates the convention and removes the "taint" + // from a hook. We *could* make it valid to avoid some false positives but let's + // ensure that we don't break the "renderItem" and "normalFunctionWithConditionalHook" + // cases which must remain invalid. + function normalFunctionWithHook() { +- useHookInsideNormalFunction(); ++ (function () { ++ const $res$ = useHookInsideNormalFunction(); ++ Object.freeze($res$); ++ return $res$; ++ })(); + } + + ``` +  + +FAIL: rules-of-hooks/todo.invalid.invalid-rules-of-hooks-a63fd4f9dcc0 +- Expected ++ Received + + + ## Input + + ```javascript + // @skip + // Passed but should have failed + + // This is invalid because "use"-prefixed functions used in named + // functions are assumed to be hooks. + React.unknownFunction(function notAComponent(foo, bar) { + useProbablyAHook(bar); + }); + + ``` + + ## Code + + ```javascript + // @skip + // Passed but should have failed + + // This is invalid because "use"-prefixed functions used in named + // functions are assumed to be hooks. + React.unknownFunction(function notAComponent(foo, bar) { +- useProbablyAHook(bar); ++ Object.freeze(foo); ++ Object.freeze(bar); ++ (function () { ++ const $res$ = useProbablyAHook(Object.freeze(bar)); ++ Object.freeze($res$); ++ return $res$; ++ })(); + }); + + ``` +  + +FAIL: rules-of-hooks/todo.invalid.invalid-rules-of-hooks-5a7ac9a6e8fa +- Expected ++ Received + + + ## Input + + ```javascript + // @skip + // Passed but should have failed + + // These are neither functions nor hooks. + function _normalFunctionWithHook() { + useHookInsideNormalFunction(); + } + function _useNotAHook() { + useHookInsideNormalFunction(); + } + + ``` + + ## Code + + ```javascript + // @skip + // Passed but should have failed + + // These are neither functions nor hooks. + function _normalFunctionWithHook() { +- useHookInsideNormalFunction(); ++ (function () { ++ const $res$ = useHookInsideNormalFunction(); ++ Object.freeze($res$); ++ return $res$; ++ })(); + } + + function _useNotAHook() { +- useHookInsideNormalFunction(); ++ (function () { ++ const $res$ = useHookInsideNormalFunction(); ++ Object.freeze($res$); ++ return $res$; ++ })(); + } + + ``` +  + +FAIL: rules-of-hooks/todo.bail.rules-of-hooks-fadd52c1e460 +- Expected ++ Received + + + ## Input + + ```javascript + // @skip + // Unsupported input + + // Currently invalid. + // These are variations capturing the current heuristic-- + // we only allow hooks in PascalCase or useFoo functions. + // We *could* make some of these valid. But before doing it, + // consider specific cases documented above that contain reasoning. + function a() { + useState(); + } + const whatever = function b() { + useState(); + }; + const c = () => { + useState(); + }; + let d = () => useState(); + e = () => { + useState(); + }; + ({ + f: () => { + useState(); + }, + }); + ({ + g() { + useState(); + }, + }); + const { + j = () => { + useState(); + }, + } = {}; + ({ + k = () => { + useState(); + }, + } = {}); + + ``` + + ## Code + + ```javascript + // @skip + // Unsupported input + + // Currently invalid. + // These are variations capturing the current heuristic-- + // we only allow hooks in PascalCase or useFoo functions. + // We *could* make some of these valid. But before doing it, + // consider specific cases documented above that contain reasoning. + function a() { +- useState(); ++ (function () { ++ const $res$ = useState(); ++ Object.freeze($res$); ++ return $res$; ++ })(); + } + + const whatever = function b() { +- useState(); ++ (function () { ++ const $res$ = useState(); ++ Object.freeze($res$); ++ return $res$; ++ })(); + }; + + const c = () => { +- useState(); ++ (function () { ++ const $res$ = useState(); ++ Object.freeze($res$); ++ return $res$; ++ })(); + }; + + let d = () => { +- return useState(); ++ return (function () { ++ const $res$ = useState(); ++ Object.freeze($res$); ++ return $res$; ++ })(); + }; + e = () => { +- useState(); ++ (function () { ++ const $res$ = useState(); ++ Object.freeze($res$); ++ return $res$; ++ })(); + }; + + ({ + f: () => { +- useState(); ++ (function () { ++ const $res$ = useState(); ++ Object.freeze($res$); ++ return $res$; ++ })(); + }, + }); + ({ + g() { + useState(); + }, + }); + const { + j = () => { +- useState(); ++ (function () { ++ const $res$ = useState(); ++ Object.freeze($res$); ++ return $res$; ++ })(); + }, + } = {}; + ({ + k = () => { +- useState(); ++ (function () { ++ const $res$ = useState(); ++ Object.freeze($res$); ++ return $res$; ++ })(); + }, + } = {}); + + ``` +  + +FAIL: rules-of-hooks/todo.bail.rules-of-hooks-e9f9bac89f8f +- Expected ++ Received + + + ## Input + + ```javascript + // @skip + // Unsupported input + + // Valid because hooks can be used in anonymous arrow-function arguments + // to forwardRef. + const FancyButton = React.forwardRef((props, ref) => { + useHook(); + return