mirror of
https://github.com/facebook/react.git
synced 2026-02-21 19:31:52 +00:00
[compiler] Todo for fbt with multiple pronoun/plural
ghstack-source-id: 77b6980c2b
Pull Request resolved: https://github.com/facebook/react/pull/30437
This commit is contained in:
@@ -2130,24 +2130,41 @@ function lowerExpression(
|
||||
suggestions: null,
|
||||
});
|
||||
}
|
||||
const fbtEnumLocations: Array<SourceLocation> = [];
|
||||
// see `error.todo-multiple-fbt-plural` fixture for explanation
|
||||
const fbtLocations = {
|
||||
enum: new Array<SourceLocation>(),
|
||||
plural: new Array<SourceLocation>(),
|
||||
pronoun: new Array<SourceLocation>(),
|
||||
};
|
||||
expr.traverse({
|
||||
JSXClosingElement(path) {
|
||||
path.skip();
|
||||
},
|
||||
JSXNamespacedName(path) {
|
||||
if (
|
||||
path.node.namespace.name === tagName &&
|
||||
path.node.name.name === 'enum'
|
||||
) {
|
||||
fbtEnumLocations.push(path.node.loc ?? GeneratedSource);
|
||||
if (path.node.namespace.name === tagName) {
|
||||
switch (path.node.name.name) {
|
||||
case 'enum':
|
||||
fbtLocations.enum.push(path.node.loc ?? GeneratedSource);
|
||||
break;
|
||||
case 'plural':
|
||||
fbtLocations.plural.push(path.node.loc ?? GeneratedSource);
|
||||
break;
|
||||
case 'pronoun':
|
||||
fbtLocations.pronoun.push(path.node.loc ?? GeneratedSource);
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
if (fbtEnumLocations.length > 1) {
|
||||
CompilerError.throwTodo({
|
||||
reason: `Support <${tagName}> tags with multiple <${tagName}:enum> values`,
|
||||
loc: fbtEnumLocations.at(-1) ?? GeneratedSource,
|
||||
description: null,
|
||||
suggestions: null,
|
||||
});
|
||||
for (const [name, locations] of Object.entries(fbtLocations)) {
|
||||
if (locations.length > 1) {
|
||||
CompilerError.throwTodo({
|
||||
reason: `Support <${tagName}> tags with multiple <${tagName}:${name}> values`,
|
||||
loc: locations.at(-1) ?? GeneratedSource,
|
||||
description: null,
|
||||
suggestions: null,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,110 +0,0 @@
|
||||
|
||||
## Input
|
||||
|
||||
```javascript
|
||||
import fbt from 'fbt';
|
||||
|
||||
/**
|
||||
* Forget + fbt inconsistency. Evaluator errors with the following
|
||||
* Found differences in evaluator results
|
||||
* Non-forget (expected):
|
||||
* (kind: ok) 1 rewrite to Rust · 2 months traveling
|
||||
* Forget:
|
||||
* (kind: ok) 1 rewrites to Rust · 2 months traveling
|
||||
*
|
||||
* The root issue here is that fbt:plural reads `.start` and `.end` from
|
||||
* babel nodes to slice into source strings. (fbt:enum suffers from the same
|
||||
* problem).
|
||||
* See:
|
||||
* - [getRawSource](https://github.com/facebook/fbt/blob/main/packages/babel-plugin-fbt/src/FbtUtil.js#L666-L673)
|
||||
* - [getArgCode](https://github.com/facebook/fbt/blob/main/packages/babel-plugin-fbt/src/fbt-nodes/FbtArguments.js#L88-L97)
|
||||
* - [_getStringVariationCombinations](https://github.com/facebook/fbt/blob/main/packages/babel-plugin-fbt/src/JSFbtBuilder.js#L297)
|
||||
*
|
||||
* Specifically, the `count` node requires that a `.start/.end` be attached
|
||||
* (see [code in FbtPluralNode](https://github.com/facebook/fbt/blob/main/packages/babel-plugin-fbt/src/fbt-nodes/FbtPluralNode.js#L87-L90))
|
||||
*
|
||||
* In this fixture, `count` nodes are the `rewrites` and `months` identifiers.
|
||||
*/
|
||||
function Foo({rewrites, months}) {
|
||||
return (
|
||||
<fbt desc="Test fbt description">
|
||||
<fbt:plural count={rewrites} name="number of rewrites" showCount="yes">
|
||||
rewrite
|
||||
</fbt:plural>
|
||||
to Rust ·
|
||||
<fbt:plural count={months} name="number of months" showCount="yes">
|
||||
month
|
||||
</fbt:plural>
|
||||
traveling
|
||||
</fbt>
|
||||
);
|
||||
}
|
||||
|
||||
export const FIXTURE_ENTRYPOINT = {
|
||||
fn: Foo,
|
||||
params: [{rewrites: 1, months: 2}],
|
||||
};
|
||||
|
||||
```
|
||||
|
||||
## Code
|
||||
|
||||
```javascript
|
||||
import { c as _c } from "react/compiler-runtime";
|
||||
import fbt from "fbt";
|
||||
|
||||
/**
|
||||
* Forget + fbt inconsistency. Evaluator errors with the following
|
||||
* Found differences in evaluator results
|
||||
* Non-forget (expected):
|
||||
* (kind: ok) 1 rewrite to Rust · 2 months traveling
|
||||
* Forget:
|
||||
* (kind: ok) 1 rewrites to Rust · 2 months traveling
|
||||
*
|
||||
* The root issue here is that fbt:plural reads `.start` and `.end` from
|
||||
* babel nodes to slice into source strings. (fbt:enum suffers from the same
|
||||
* problem).
|
||||
* See:
|
||||
* - [getRawSource](https://github.com/facebook/fbt/blob/main/packages/babel-plugin-fbt/src/FbtUtil.js#L666-L673)
|
||||
* - [getArgCode](https://github.com/facebook/fbt/blob/main/packages/babel-plugin-fbt/src/fbt-nodes/FbtArguments.js#L88-L97)
|
||||
* - [_getStringVariationCombinations](https://github.com/facebook/fbt/blob/main/packages/babel-plugin-fbt/src/JSFbtBuilder.js#L297)
|
||||
*
|
||||
* Specifically, the `count` node requires that a `.start/.end` be attached
|
||||
* (see [code in FbtPluralNode](https://github.com/facebook/fbt/blob/main/packages/babel-plugin-fbt/src/fbt-nodes/FbtPluralNode.js#L87-L90))
|
||||
*
|
||||
* In this fixture, `count` nodes are the `rewrites` and `months` identifiers.
|
||||
*/
|
||||
function Foo(t0) {
|
||||
const $ = _c(3);
|
||||
const { rewrites, months } = t0;
|
||||
let t1;
|
||||
if ($[0] !== rewrites || $[1] !== months) {
|
||||
t1 = fbt._(
|
||||
{
|
||||
"*": {
|
||||
"*": "{number of rewrites} rewrites to Rust · {number of months} months traveling",
|
||||
},
|
||||
_1: { _1: "1 rewrite to Rust · 1 month traveling" },
|
||||
},
|
||||
[
|
||||
fbt._plural(rewrites, "number of rewrites"),
|
||||
fbt._plural(months, "number of months"),
|
||||
],
|
||||
{ hk: "49MfZA" },
|
||||
);
|
||||
$[0] = rewrites;
|
||||
$[1] = months;
|
||||
$[2] = t1;
|
||||
} else {
|
||||
t1 = $[2];
|
||||
}
|
||||
return t1;
|
||||
}
|
||||
|
||||
export const FIXTURE_ENTRYPOINT = {
|
||||
fn: Foo,
|
||||
params: [{ rewrites: 1, months: 2 }],
|
||||
};
|
||||
|
||||
```
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
|
||||
## Input
|
||||
|
||||
```javascript
|
||||
import fbt from 'fbt';
|
||||
|
||||
/**
|
||||
* Forget + fbt inconsistency. Evaluator errors with the following
|
||||
* Found differences in evaluator results
|
||||
* Non-forget (expected):
|
||||
* (kind: ok) 1 rewrite to Rust · 2 months traveling
|
||||
* Forget:
|
||||
* (kind: ok) 1 rewrites to Rust · 2 months traveling
|
||||
*
|
||||
* The root issue here is that fbt:plural/enum/pronoun read `.start` and `.end` from
|
||||
* babel nodes to slice into source strings for some complex dedupe logic
|
||||
* (see [_getStringVariationCombinations](https://github.com/facebook/fbt/blob/main/packages/babel-plugin-fbt/src/JSFbtBuilder.js#L297))
|
||||
*
|
||||
*
|
||||
* Since Forget does not add `.start` and `.end` for babel nodes it synthesizes,
|
||||
* [getRawSource](https://github.com/facebook/fbt/blob/main/packages/babel-plugin-fbt/src/FbtUtil.js#L666-L673)
|
||||
* simply returns the whole source code string. As a result, all fbt nodes dedupe together
|
||||
* and _getStringVariationCombinations ends up early exiting (before adding valid candidate values).
|
||||
*
|
||||
*
|
||||
*
|
||||
* For fbt:plural tags specifically, the `count` node require that a `.start/.end`
|
||||
* (see [code in FbtPluralNode](https://github.com/facebook/fbt/blob/main/packages/babel-plugin-fbt/src/fbt-nodes/FbtPluralNode.js#L87-L90))
|
||||
*/
|
||||
function Foo({rewrites, months}) {
|
||||
return (
|
||||
<fbt desc="Test fbt description">
|
||||
<fbt:plural count={rewrites} name="number of rewrites" showCount="yes">
|
||||
rewrite
|
||||
</fbt:plural>
|
||||
to Rust ·
|
||||
<fbt:plural count={months} name="number of months" showCount="yes">
|
||||
month
|
||||
</fbt:plural>
|
||||
traveling
|
||||
</fbt>
|
||||
);
|
||||
}
|
||||
|
||||
export const FIXTURE_ENTRYPOINT = {
|
||||
fn: Foo,
|
||||
params: [{rewrites: 1, months: 2}],
|
||||
};
|
||||
|
||||
```
|
||||
|
||||
|
||||
## Error
|
||||
|
||||
```
|
||||
31 | </fbt:plural>
|
||||
32 | to Rust ·
|
||||
> 33 | <fbt:plural count={months} name="number of months" showCount="yes">
|
||||
| ^^^^^^^^^^ Todo: Support <fbt> tags with multiple <fbt:plural> values (33:33)
|
||||
34 | month
|
||||
35 | </fbt:plural>
|
||||
36 | traveling
|
||||
```
|
||||
|
||||
|
||||
@@ -8,18 +8,20 @@ import fbt from 'fbt';
|
||||
* Forget:
|
||||
* (kind: ok) 1 rewrites to Rust · 2 months traveling
|
||||
*
|
||||
* The root issue here is that fbt:plural reads `.start` and `.end` from
|
||||
* babel nodes to slice into source strings. (fbt:enum suffers from the same
|
||||
* problem).
|
||||
* See:
|
||||
* - [getRawSource](https://github.com/facebook/fbt/blob/main/packages/babel-plugin-fbt/src/FbtUtil.js#L666-L673)
|
||||
* - [getArgCode](https://github.com/facebook/fbt/blob/main/packages/babel-plugin-fbt/src/fbt-nodes/FbtArguments.js#L88-L97)
|
||||
* - [_getStringVariationCombinations](https://github.com/facebook/fbt/blob/main/packages/babel-plugin-fbt/src/JSFbtBuilder.js#L297)
|
||||
* The root issue here is that fbt:plural/enum/pronoun read `.start` and `.end` from
|
||||
* babel nodes to slice into source strings for some complex dedupe logic
|
||||
* (see [_getStringVariationCombinations](https://github.com/facebook/fbt/blob/main/packages/babel-plugin-fbt/src/JSFbtBuilder.js#L297))
|
||||
*
|
||||
* Specifically, the `count` node requires that a `.start/.end` be attached
|
||||
*
|
||||
* Since Forget does not add `.start` and `.end` for babel nodes it synthesizes,
|
||||
* [getRawSource](https://github.com/facebook/fbt/blob/main/packages/babel-plugin-fbt/src/FbtUtil.js#L666-L673)
|
||||
* simply returns the whole source code string. As a result, all fbt nodes dedupe together
|
||||
* and _getStringVariationCombinations ends up early exiting (before adding valid candidate values).
|
||||
*
|
||||
*
|
||||
*
|
||||
* For fbt:plural tags specifically, the `count` node require that a `.start/.end`
|
||||
* (see [code in FbtPluralNode](https://github.com/facebook/fbt/blob/main/packages/babel-plugin-fbt/src/fbt-nodes/FbtPluralNode.js#L87-L90))
|
||||
*
|
||||
* In this fixture, `count` nodes are the `rewrites` and `months` identifiers.
|
||||
*/
|
||||
function Foo({rewrites, months}) {
|
||||
return (
|
||||
@@ -17,6 +17,12 @@ function Foo(props) {
|
||||
);
|
||||
}
|
||||
|
||||
export const FIXTURE_ENTRYPOINT = {
|
||||
fn: Foo,
|
||||
params: [{value: 1}],
|
||||
sequentialRenders: [{value: 1}, {value: 0}],
|
||||
};
|
||||
|
||||
```
|
||||
|
||||
## Code
|
||||
@@ -49,5 +55,14 @@ function Foo(props) {
|
||||
return t0;
|
||||
}
|
||||
|
||||
export const FIXTURE_ENTRYPOINT = {
|
||||
fn: Foo,
|
||||
params: [{ value: 1 }],
|
||||
sequentialRenders: [{ value: 1 }, { value: 0 }],
|
||||
};
|
||||
|
||||
```
|
||||
|
||||
|
||||
### Eval output
|
||||
(kind: ok) hello 1,
|
||||
goodbye 0,
|
||||
@@ -12,3 +12,9 @@ function Foo(props) {
|
||||
</fbt>
|
||||
);
|
||||
}
|
||||
|
||||
export const FIXTURE_ENTRYPOINT = {
|
||||
fn: Foo,
|
||||
params: [{value: 1}],
|
||||
sequentialRenders: [{value: 1}, {value: 0}],
|
||||
};
|
||||
|
||||
@@ -440,7 +440,6 @@ const skipFilter = new Set([
|
||||
'fbt/fbtparam-with-jsx-element-content',
|
||||
'fbt/fbtparam-text-must-use-expression-container',
|
||||
'fbt/fbtparam-with-jsx-fragment-value',
|
||||
'fbt/fbt-preserve-jsxtext',
|
||||
'todo.useContext-mutate-context-in-callback',
|
||||
'loop-unused-let',
|
||||
'reanimated-no-memo-arg',
|
||||
@@ -485,7 +484,6 @@ const skipFilter = new Set([
|
||||
'rules-of-hooks/rules-of-hooks-69521d94fa03',
|
||||
|
||||
// bugs
|
||||
'fbt/bug-multiple-fbt-plural',
|
||||
'fbt/bug-fbt-preserve-whitespace-param',
|
||||
'bug-invalid-hoisting-functionexpr',
|
||||
'original-reactive-scopes-fork/bug-nonmutating-capture-in-unsplittable-memo-block',
|
||||
|
||||
Reference in New Issue
Block a user