@samitouri / QOS-React-1 / commits / 738ddf7419

Support <fbs> in addition to <fbt>

ghstack-source-id: 1ab99ebb5cef3f42399682a338feb12c4cf55f4c Pull Request resolved: https://github.com/facebook/react-forget/pull/2933

Pieter Vanderwerff committed May 3, 2024 at 13:27 UTC 738ddf74197d405e03e284d2a48760f23555c197
4 files changed +107 -7
compiler/packages/babel-plugin-react-compiler/src/HIR/BuildHIR.ts
+12 -5
@@ -2075,14 +2075,18 @@ function lowerExpression(
2075 }
2076 props.push({ kind: "JsxAttribute", name: propName, place: value });
2077 }
2078 - if (tag.kind === "BuiltinTag" && tag.name === "fbt") {
2078 + if (
2079 + tag.kind === "BuiltinTag" &&
2080 + (tag.name === "fbt" || tag.name === "fbs")
2081 + ) {
2082 + const tagName = tag.name;
2083 const openingIdentifier = opening.get("name");
2084 const tagIdentifier = openingIdentifier.isJSXIdentifier()
2085 ? builder.resolveIdentifier(openingIdentifier)
2086 : null;
2087 if (tagIdentifier != null) {
2088 CompilerError.throwTodo({
2085 - reason: `Support <fbt> tags where 'fbt' is a local variable instead of a global`,
2089 + reason: `Support <${tagName}> tags where '${tagName}' is a local variable instead of a global`,
2090 loc: openingIdentifier.node.loc ?? GeneratedSource,
2091 description: null,
2092 suggestions: null,
@@ -2092,7 +2096,7 @@ function lowerExpression(
2096 expr.traverse({
2097 JSXNamespacedName(path) {
2098 if (
2095 - path.node.namespace.name === "fbt" &&
2099 + path.node.namespace.name === tagName &&
2100 path.node.name.name === "enum"
2101 ) {
2102 fbtEnumLocations.push(path.node.loc ?? GeneratedSource);
@@ -2101,7 +2105,7 @@ function lowerExpression(
2105 });
2106 if (fbtEnumLocations.length > 1) {
2107 CompilerError.throwTodo({
2104 - reason: `Support <fbt> tags with multiple <fbt:enum> values`,
2108 + reason: `Support <${tagName}> tags with multiple <${tagName}:enum> values`,
2109 loc: fbtEnumLocations.at(-1) ?? GeneratedSource,
2110 description: null,
2111 suggestions: null,
@@ -2110,7 +2114,10 @@ function lowerExpression(
2114 }
2115
2116 let children: Array<Place>;
2113 - if (tag.kind === "BuiltinTag" && tag.name === "fbt") {
2117 + if (
2118 + tag.kind === "BuiltinTag" &&
2119 + (tag.name === "fbt" || tag.name === "fbs")
2120 + ) {
2121 children = expr
2122 .get("children")
2123 .map((child) => {
compiler/packages/babel-plugin-react-compiler/src/ReactiveScopes/MemoizeFbtOperandsInSameScope.ts
+10 -2
@@ -39,8 +39,16 @@ export function memoizeFbtOperandsInSameScope(fn: HIRFunction): void {
39 }
40 }
41
42 -export const FBT_TAGS: Set<string> = new Set(["fbt", "fbt:param"]);
43 -export const SINGLE_CHILD_FBT_TAGS: Set<string> = new Set(["fbt:param"]);
42 +export const FBT_TAGS: Set<string> = new Set([
43 + "fbt",
44 + "fbt:param",
45 + "fbs",
46 + "fbs:param",
47 +]);
48 +export const SINGLE_CHILD_FBT_TAGS: Set<string> = new Set([
49 + "fbt:param",
50 + "fbs:param",
51 +]);
52
53 function visit(fn: HIRFunction, fbtValues: Set<IdentifierId>): void {
54 for (const [, block] of fn.body.blocks) {
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/fbt/fbs-params.expect.md new
+65
@@ -0,0 +1,65 @@
1 +
2 +## Input
3 +
4 +```javascript
5 +import { fbs } from "fbt";
6 +
7 +function Component(props) {
8 + return (
9 + <div
10 + title={
11 + <fbs desc={"Dialog to show to user"}>
12 + Hello <fbs:param name="user name">{props.name}</fbs:param>
13 + </fbs>
14 + }
15 + >
16 + Hover me
17 + </div>
18 + );
19 +}
20 +
21 +export const FIXTURE_ENTRYPOINT = {
22 + fn: Component,
23 + params: [{ name: "Sathya" }],
24 +};
25 +
26 +```
27 +
28 +## Code
29 +
30 +```javascript
31 +import { c as useMemoCache } from "react";
32 +import { fbs } from "fbt";
33 +
34 +function Component(props) {
35 + const $ = useMemoCache(2);
36 + let t0;
37 + if ($[0] !== props.name) {
38 + t0 = (
39 + <div
40 + title={fbs._(
41 + "Hello {user name}",
42 + [fbs._param("user name", props.name)],
43 + { hk: "2zEDKF" }
44 + )}
45 + >
46 + Hover me
47 + </div>
48 + );
49 + $[0] = props.name;
50 + $[1] = t0;
51 + } else {
52 + t0 = $[1];
53 + }
54 + return t0;
55 +}
56 +
57 +export const FIXTURE_ENTRYPOINT = {
58 + fn: Component,
59 + params: [{ name: "Sathya" }],
60 +};
61 +
62 +```
63 +
64 +### Eval output
65 +(kind: ok) <div title="Hello Sathya">Hover me</div>
\ No newline at end of file
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/fbt/fbs-params.js new
+20
@@ -0,0 +1,20 @@
1 +import { fbs } from "fbt";
2 +
3 +function Component(props) {
4 + return (
5 + <div
6 + title={
7 + <fbs desc={"Dialog to show to user"}>
8 + Hello <fbs:param name="user name">{props.name}</fbs:param>
9 + </fbs>
10 + }
11 + >
12 + Hover me
13 + </div>
14 + );
15 +}
16 +
17 +export const FIXTURE_ENTRYPOINT = {
18 + fn: Component,
19 + params: [{ name: "Sathya" }],
20 +};