From 212d5ae8cbdb16788bcbb8c7f0c35369968eff5e Mon Sep 17 00:00:00 2001 From: Mofei Zhang Date: Tue, 30 Jul 2024 16:24:45 -0400 Subject: [PATCH] [compiler][repro] fixtures for fbt plural and macro bugs ghstack-source-id: 8ccf49bb40cd634932b84dd637439042aa60fd46 Pull Request resolved: https://github.com/facebook/react/pull/30535 --- ...t-plural-multiple-function-calls.expect.md | 87 ++++++++++++++++ .../bug-fbt-plural-multiple-function-calls.ts | 27 +++++ ...t-plural-multiple-mixed-call-tag.expect.md | 98 +++++++++++++++++++ ...bug-fbt-plural-multiple-mixed-call-tag.tsx | 34 +++++++ ...repro-macro-property-not-handled.expect.md | 79 +++++++++++++++ .../fbt/repro-macro-property-not-handled.tsx | 23 +++++ .../packages/snap/src/SproutTodoFilter.ts | 2 + 7 files changed, 350 insertions(+) create mode 100644 compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/fbt/bug-fbt-plural-multiple-function-calls.expect.md create mode 100644 compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/fbt/bug-fbt-plural-multiple-function-calls.ts create mode 100644 compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/fbt/bug-fbt-plural-multiple-mixed-call-tag.expect.md create mode 100644 compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/fbt/bug-fbt-plural-multiple-mixed-call-tag.tsx create mode 100644 compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/fbt/repro-macro-property-not-handled.expect.md create mode 100644 compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/fbt/repro-macro-property-not-handled.tsx diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/fbt/bug-fbt-plural-multiple-function-calls.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/fbt/bug-fbt-plural-multiple-function-calls.expect.md new file mode 100644 index 0000000000..650d828bd2 --- /dev/null +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/fbt/bug-fbt-plural-multiple-function-calls.expect.md @@ -0,0 +1,87 @@ + +## Input + +```javascript +import fbt from 'fbt'; + +/** + * Similar to error.todo-multiple-fbt-plural + * + * Evaluator error: + * Found differences in evaluator results + * Non-forget (expected): + * (kind: ok)
1 apple and 2 bananas
+ * Forget: + * (kind: ok)
1 apples and 2 bananas
+ */ + +function useFoo({apples, bananas}) { + return fbt( + `${fbt.param('number of apples', apples)} ` + + fbt.plural('apple', apples) + + ` and ${fbt.param('number of bananas', bananas)} ` + + fbt.plural('banana', bananas), + 'TestDescription', + ); +} + +export const FIXTURE_ENTRYPOINT = { + fn: useFoo, + params: [{apples: 1, bananas: 2}], +}; + +``` + +## Code + +```javascript +import { c as _c } from "react/compiler-runtime"; +import fbt from "fbt"; + +/** + * Similar to error.todo-multiple-fbt-plural + * + * Evaluator error: + * Found differences in evaluator results + * Non-forget (expected): + * (kind: ok)
1 apple and 2 bananas
+ * Forget: + * (kind: ok)
1 apples and 2 bananas
+ */ + +function useFoo(t0) { + const $ = _c(3); + const { apples, bananas } = t0; + let t1; + if ($[0] !== apples || $[1] !== bananas) { + t1 = fbt._( + { + "*": { + "*": "{number of apples} apples and {number of bananas} bananas", + }, + _1: { _1: "{number of apples} apple and {number of bananas} banana" }, + }, + [ + fbt._plural(apples), + fbt._plural(bananas), + fbt._param("number of apples", apples), + fbt._param("number of bananas", bananas), + ], + { hk: "3vKunl" }, + ); + $[0] = apples; + $[1] = bananas; + $[2] = t1; + } else { + t1 = $[2]; + } + return t1; +} + +export const FIXTURE_ENTRYPOINT = { + fn: useFoo, + params: [{ apples: 1, bananas: 2 }], +}; + +``` + \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/fbt/bug-fbt-plural-multiple-function-calls.ts b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/fbt/bug-fbt-plural-multiple-function-calls.ts new file mode 100644 index 0000000000..20b14c5c50 --- /dev/null +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/fbt/bug-fbt-plural-multiple-function-calls.ts @@ -0,0 +1,27 @@ +import fbt from 'fbt'; + +/** + * Similar to error.todo-multiple-fbt-plural + * + * Evaluator error: + * Found differences in evaluator results + * Non-forget (expected): + * (kind: ok)
1 apple and 2 bananas
+ * Forget: + * (kind: ok)
1 apples and 2 bananas
+ */ + +function useFoo({apples, bananas}) { + return fbt( + `${fbt.param('number of apples', apples)} ` + + fbt.plural('apple', apples) + + ` and ${fbt.param('number of bananas', bananas)} ` + + fbt.plural('banana', bananas), + 'TestDescription', + ); +} + +export const FIXTURE_ENTRYPOINT = { + fn: useFoo, + params: [{apples: 1, bananas: 2}], +}; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/fbt/bug-fbt-plural-multiple-mixed-call-tag.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/fbt/bug-fbt-plural-multiple-mixed-call-tag.expect.md new file mode 100644 index 0000000000..21b0dd2486 --- /dev/null +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/fbt/bug-fbt-plural-multiple-mixed-call-tag.expect.md @@ -0,0 +1,98 @@ + +## Input + +```javascript +import fbt from 'fbt'; + +/** + * Similar to error.todo-multiple-fbt-plural, but note that we must + * count fbt plurals across both namespaced jsx tags + * and fbt.plural(...) call expressions. + * + * Evaluator error: + * Found differences in evaluator results + * Non-forget (expected): + * (kind: ok)
1 apple and 2 bananas
+ * Forget: + * (kind: ok)
1 apples and 2 bananas
+ */ +function useFoo({apples, bananas}) { + return ( +
+ + {fbt.param('number of apples', apples)} + {' '} + {fbt.plural('apple', apples)} and + {' '} + + banana + + +
+ ); +} + +export const FIXTURE_ENTRYPOINT = { + fn: useFoo, + params: [{apples: 1, bananas: 2}], +}; + +``` + +## Code + +```javascript +import { c as _c } from "react/compiler-runtime"; +import fbt from "fbt"; + +/** + * Similar to error.todo-multiple-fbt-plural, but note that we must + * count fbt plurals across both namespaced jsx tags + * and fbt.plural(...) call expressions. + * + * Evaluator error: + * Found differences in evaluator results + * Non-forget (expected): + * (kind: ok)
1 apple and 2 bananas
+ * Forget: + * (kind: ok)
1 apples and 2 bananas
+ */ +function useFoo(t0) { + const $ = _c(3); + const { apples, bananas } = t0; + let t1; + if ($[0] !== apples || $[1] !== bananas) { + t1 = ( +
+ {fbt._( + { + "*": { + "*": "{number of apples} apples and {number of bananas} bananas", + }, + _1: { _1: "{number of apples} apple and 1 banana" }, + }, + [ + fbt._plural(apples), + fbt._plural(bananas, "number of bananas"), + fbt._param("number of apples", apples), + ], + { hk: "2xXrUW" }, + )} +
+ ); + $[0] = apples; + $[1] = bananas; + $[2] = t1; + } else { + t1 = $[2]; + } + return t1; +} + +export const FIXTURE_ENTRYPOINT = { + fn: useFoo, + params: [{ apples: 1, bananas: 2 }], +}; + +``` + \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/fbt/bug-fbt-plural-multiple-mixed-call-tag.tsx b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/fbt/bug-fbt-plural-multiple-mixed-call-tag.tsx new file mode 100644 index 0000000000..fe18eeeb7b --- /dev/null +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/fbt/bug-fbt-plural-multiple-mixed-call-tag.tsx @@ -0,0 +1,34 @@ +import fbt from 'fbt'; + +/** + * Similar to error.todo-multiple-fbt-plural, but note that we must + * count fbt plurals across both namespaced jsx tags + * and fbt.plural(...) call expressions. + * + * Evaluator error: + * Found differences in evaluator results + * Non-forget (expected): + * (kind: ok)
1 apple and 2 bananas
+ * Forget: + * (kind: ok)
1 apples and 2 bananas
+ */ +function useFoo({apples, bananas}) { + return ( +
+ + {fbt.param('number of apples', apples)} + {' '} + {fbt.plural('apple', apples)} and + {' '} + + banana + + +
+ ); +} + +export const FIXTURE_ENTRYPOINT = { + fn: useFoo, + params: [{apples: 1, bananas: 2}], +}; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/fbt/repro-macro-property-not-handled.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/fbt/repro-macro-property-not-handled.expect.md new file mode 100644 index 0000000000..a06b283d04 --- /dev/null +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/fbt/repro-macro-property-not-handled.expect.md @@ -0,0 +1,79 @@ + +## Input + +```javascript +import fbt from 'fbt'; +import {useIdentity} from 'shared-runtime'; + +/** + * MemoizeFbtAndMacroOperandsInSameScope should also track PropertyLoads (e.g. fbt.plural). + * This doesn't seem to be an issue for fbt, but affects other internal macros invoked as + * `importSpecifier.funcName` (see https://fburl.com/code/72icxwmn) + */ +function useFoo({items}: {items: Array}) { + return fbt( + 'There ' + + fbt.plural('is', useIdentity([...items]).length, {many: 'are'}) + + ' ' + + fbt.param('number of items', items.length) + + ' items', + 'Error content when there are unsupported locales.', + ); +} + +export const FIXTURE_ENTRYPOINT = { + fn: useFoo, + params: [{items: [2, 3]}], +}; + +``` + +## Code + +```javascript +import { c as _c } from "react/compiler-runtime"; +import fbt from "fbt"; +import { useIdentity } from "shared-runtime"; + +/** + * MemoizeFbtAndMacroOperandsInSameScope should also track PropertyLoads (e.g. fbt.plural). + * This doesn't seem to be an issue for fbt, but affects other internal macros invoked as + * `importSpecifier.funcName` (see https://fburl.com/code/72icxwmn) + */ +function useFoo(t0) { + const $ = _c(2); + const { items } = t0; + let t1; + if ($[0] !== items) { + t1 = [...items]; + $[0] = items; + $[1] = t1; + } else { + t1 = $[1]; + } + return fbt._( + { + "*": "There are {number of items} items", + _1: "There is {number of items} items", + }, + [ + fbt._plural(useIdentity(t1).length), + fbt._param( + "number of items", + + items.length, + ), + ], + { hk: "xsa7w" }, + ); +} + +export const FIXTURE_ENTRYPOINT = { + fn: useFoo, + params: [{ items: [2, 3] }], +}; + +``` + +### Eval output +(kind: ok) There are 2 items \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/fbt/repro-macro-property-not-handled.tsx b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/fbt/repro-macro-property-not-handled.tsx new file mode 100644 index 0000000000..6847159a85 --- /dev/null +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/fbt/repro-macro-property-not-handled.tsx @@ -0,0 +1,23 @@ +import fbt from 'fbt'; +import {useIdentity} from 'shared-runtime'; + +/** + * MemoizeFbtAndMacroOperandsInSameScope should also track PropertyLoads (e.g. fbt.plural). + * This doesn't seem to be an issue for fbt, but affects other internal macros invoked as + * `importSpecifier.funcName` (see https://fburl.com/code/72icxwmn) + */ +function useFoo({items}: {items: Array}) { + return fbt( + 'There ' + + fbt.plural('is', useIdentity([...items]).length, {many: 'are'}) + + ' ' + + fbt.param('number of items', items.length) + + ' items', + 'Error content when there are unsupported locales.', + ); +} + +export const FIXTURE_ENTRYPOINT = { + fn: useFoo, + params: [{items: [2, 3]}], +}; diff --git a/compiler/packages/snap/src/SproutTodoFilter.ts b/compiler/packages/snap/src/SproutTodoFilter.ts index ff542dfb97..256a4bdd7d 100644 --- a/compiler/packages/snap/src/SproutTodoFilter.ts +++ b/compiler/packages/snap/src/SproutTodoFilter.ts @@ -484,6 +484,8 @@ const skipFilter = new Set([ 'rules-of-hooks/rules-of-hooks-69521d94fa03', // bugs + 'fbt/bug-fbt-plural-multiple-function-calls', + 'fbt/bug-fbt-plural-multiple-mixed-call-tag', 'bug-invalid-hoisting-functionexpr', 'original-reactive-scopes-fork/bug-nonmutating-capture-in-unsplittable-memo-block', 'original-reactive-scopes-fork/bug-hoisted-declaration-with-scope',