Skip to content

Commit b2ec044

Browse files
committed
[compiler][patch] Don't wrap non-ascii fbt operands in JSXExpressionContainer
ghstack-source-id: 4b5505a Pull Request resolved: #30389
1 parent 378ab81 commit b2ec044

12 files changed

+227
-102
lines changed

compiler/packages/babel-plugin-react-compiler/src/Entrypoint/Pipeline.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,7 @@ function* runWithEnvironment(
262262
value: hir,
263263
});
264264

265-
memoizeFbtOperandsInSameScope(hir);
265+
const fbtOperands = memoizeFbtOperandsInSameScope(hir);
266266
yield log({
267267
kind: "hir",
268268
name: "MemoizeFbtAndMacroOperandsInSameScope",
@@ -484,7 +484,10 @@ function* runWithEnvironment(
484484
validatePreservedManualMemoization(reactiveFunction);
485485
}
486486

487-
const ast = codegenFunction(reactiveFunction, uniqueIdentifiers).unwrap();
487+
const ast = codegenFunction(reactiveFunction, {
488+
uniqueIdentifiers,
489+
fbtOperands,
490+
}).unwrap();
488491
yield log({ kind: "ast", name: "Codegen", value: ast });
489492
for (const outlined of ast.outlined) {
490493
yield log({ kind: "ast", name: "Codegen (outlined)", value: outlined.fn });

compiler/packages/babel-plugin-react-compiler/src/ReactiveScopes/CodegenReactiveFunction.ts

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -100,12 +100,19 @@ export type CodegenFunction = {
100100

101101
export function codegenFunction(
102102
fn: ReactiveFunction,
103-
uniqueIdentifiers: Set<string>
103+
{
104+
uniqueIdentifiers,
105+
fbtOperands,
106+
}: {
107+
uniqueIdentifiers: Set<string>;
108+
fbtOperands: Set<IdentifierId>;
109+
}
104110
): Result<CodegenFunction, CompilerError> {
105111
const cx = new Context(
106112
fn.env,
107113
fn.id ?? "[[ anonymous ]]",
108114
uniqueIdentifiers,
115+
fbtOperands,
109116
null
110117
);
111118

@@ -281,7 +288,8 @@ export function codegenFunction(
281288
new Context(
282289
cx.env,
283290
reactiveFunction.id ?? "[[ anonymous ]]",
284-
identifiers
291+
identifiers,
292+
cx.fbtOperands
285293
),
286294
reactiveFunction
287295
);
@@ -391,17 +399,20 @@ class Context {
391399
errors: CompilerError = new CompilerError();
392400
objectMethods: Map<IdentifierId, ObjectMethod> = new Map();
393401
uniqueIdentifiers: Set<string>;
402+
fbtOperands: Set<IdentifierId>;
394403
synthesizedNames: Map<string, ValidIdentifierName> = new Map();
395404

396405
constructor(
397406
env: Environment,
398407
fnName: string,
399408
uniqueIdentifiers: Set<string>,
409+
fbtOperands: Set<IdentifierId>,
400410
temporaries: Temporaries | null = null
401411
) {
402412
this.env = env;
403413
this.fnName = fnName;
404414
this.uniqueIdentifiers = uniqueIdentifiers;
415+
this.fbtOperands = fbtOperands;
405416
this.temp = temporaries !== null ? new Map(temporaries) : new Map();
406417
}
407418
get nextCacheIndex(): number {
@@ -1776,6 +1787,7 @@ function codegenInstructionValue(
17761787
cx.env,
17771788
reactiveFunction.id ?? "[[ anonymous ]]",
17781789
cx.uniqueIdentifiers,
1790+
cx.fbtOperands,
17791791
cx.temp
17801792
),
17811793
reactiveFunction
@@ -1979,6 +1991,7 @@ function codegenInstructionValue(
19791991
cx.env,
19801992
reactiveFunction.id ?? "[[ anonymous ]]",
19811993
cx.uniqueIdentifiers,
1994+
cx.fbtOperands,
19821995
cx.temp
19831996
),
19841997
reactiveFunction
@@ -2229,7 +2242,10 @@ function codegenJsxAttribute(
22292242
switch (innerValue.type) {
22302243
case "StringLiteral": {
22312244
value = innerValue;
2232-
if (STRING_REQUIRES_EXPR_CONTAINER_PATTERN.test(value.value)) {
2245+
if (
2246+
STRING_REQUIRES_EXPR_CONTAINER_PATTERN.test(value.value) &&
2247+
!cx.fbtOperands.has(attribute.place.identifier.id)
2248+
) {
22332249
value = createJsxExpressionContainer(value.loc, value);
22342250
}
22352251
break;

compiler/packages/babel-plugin-react-compiler/src/ReactiveScopes/MemoizeFbtAndMacroOperandsInSameScope.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,9 @@ import { eachReactiveValueOperand } from "./visitors";
3939
* Users can also specify their own functions to be treated similarly to fbt via the
4040
* `customMacros` environment configuration.
4141
*/
42-
export function memoizeFbtAndMacroOperandsInSameScope(fn: HIRFunction): void {
42+
export function memoizeFbtAndMacroOperandsInSameScope(
43+
fn: HIRFunction
44+
): Set<IdentifierId> {
4345
const fbtMacroTags = new Set([
4446
...FBT_TAGS,
4547
...(fn.env.config.customMacros ?? []),
@@ -52,6 +54,7 @@ export function memoizeFbtAndMacroOperandsInSameScope(fn: HIRFunction): void {
5254
break;
5355
}
5456
}
57+
return fbtValues;
5558
}
5659

5760
export const FBT_TAGS: Set<string> = new Set([

compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/fbt/error.todo-fbt-param-with-newline.expect.md

Lines changed: 0 additions & 36 deletions
This file was deleted.

compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/fbt/error.todo-fbt-param-with-quotes.expect.md

Lines changed: 0 additions & 30 deletions
This file was deleted.

compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/fbt/error.todo-fbt-param-with-unicode.expect.md

Lines changed: 0 additions & 30 deletions
This file was deleted.
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
2+
## Input
3+
4+
```javascript
5+
import fbt from "fbt";
6+
7+
function Component(props) {
8+
const element = (
9+
<fbt desc={"Dialog to show to user"}>
10+
Hello{" "}
11+
<fbt:param
12+
name="a really long description
13+
that got split into multiple lines"
14+
>
15+
{props.name}
16+
</fbt:param>
17+
</fbt>
18+
);
19+
return element.toString();
20+
}
21+
22+
export const FIXTURE_ENTRYPOINT = {
23+
fn: Component,
24+
params: [{ name: "Jason" }],
25+
};
26+
27+
```
28+
29+
## Code
30+
31+
```javascript
32+
import { c as _c } from "react/compiler-runtime";
33+
import fbt from "fbt";
34+
35+
function Component(props) {
36+
const $ = _c(4);
37+
let t0;
38+
if ($[0] !== props.name) {
39+
t0 = fbt._(
40+
"Hello {a really long description that got split into multiple lines}",
41+
[
42+
fbt._param(
43+
"a really long description that got split into multiple lines",
44+
45+
props.name,
46+
),
47+
],
48+
{ hk: "1euPUp" },
49+
);
50+
$[0] = props.name;
51+
$[1] = t0;
52+
} else {
53+
t0 = $[1];
54+
}
55+
const element = t0;
56+
let t1;
57+
if ($[2] !== element) {
58+
t1 = element.toString();
59+
$[2] = element;
60+
$[3] = t1;
61+
} else {
62+
t1 = $[3];
63+
}
64+
return t1;
65+
}
66+
67+
export const FIXTURE_ENTRYPOINT = {
68+
fn: Component,
69+
params: [{ name: "Jason" }],
70+
};
71+
72+
```
73+
74+
### Eval output
75+
(kind: ok) "Hello Jason"

compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/fbt/error.todo-fbt-param-with-newline.js renamed to compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/fbt/fbt-param-with-newline.js

File renamed without changes.
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
2+
## Input
3+
4+
```javascript
5+
import fbt from "fbt";
6+
7+
function Component(props) {
8+
const element = (
9+
<fbt desc={"Dialog to show to user"}>
10+
Hello <fbt:param name='"user" name'>{props.name}</fbt:param>
11+
</fbt>
12+
);
13+
return element.toString();
14+
}
15+
16+
export const FIXTURE_ENTRYPOINT = {
17+
fn: Component,
18+
params: [{ name: "Jason" }],
19+
};
20+
21+
```
22+
23+
## Code
24+
25+
```javascript
26+
import { c as _c } from "react/compiler-runtime";
27+
import fbt from "fbt";
28+
29+
function Component(props) {
30+
const $ = _c(4);
31+
let t0;
32+
if ($[0] !== props.name) {
33+
t0 = fbt._('Hello {"user" name}', [fbt._param('"user" name', props.name)], {
34+
hk: "S0vMe",
35+
});
36+
$[0] = props.name;
37+
$[1] = t0;
38+
} else {
39+
t0 = $[1];
40+
}
41+
const element = t0;
42+
let t1;
43+
if ($[2] !== element) {
44+
t1 = element.toString();
45+
$[2] = element;
46+
$[3] = t1;
47+
} else {
48+
t1 = $[3];
49+
}
50+
return t1;
51+
}
52+
53+
export const FIXTURE_ENTRYPOINT = {
54+
fn: Component,
55+
params: [{ name: "Jason" }],
56+
};
57+
58+
```
59+
60+
### Eval output
61+
(kind: ok) "Hello Jason"

compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/fbt/error.todo-fbt-param-with-quotes.js renamed to compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/fbt/fbt-param-with-quotes.js

File renamed without changes.

0 commit comments

Comments
 (0)