From 738ddf74197d405e03e284d2a48760f23555c197 Mon Sep 17 00:00:00 2001 From: Pieter Vanderwerff Date: Fri, 3 May 2024 13:27:51 -0700 Subject: [PATCH] Support in addition to ghstack-source-id: 1ab99ebb5cef3f42399682a338feb12c4cf55f4c Pull Request resolved: https://github.com/facebook/react-forget/pull/2933 --- .../src/HIR/BuildHIR.ts | 17 +++-- .../MemoizeFbtOperandsInSameScope.ts | 12 +++- .../compiler/fbt/fbs-params.expect.md | 65 +++++++++++++++++++ .../fixtures/compiler/fbt/fbs-params.js | 20 ++++++ 4 files changed, 107 insertions(+), 7 deletions(-) create mode 100644 compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/fbt/fbs-params.expect.md create mode 100644 compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/fbt/fbs-params.js diff --git a/compiler/packages/babel-plugin-react-compiler/src/HIR/BuildHIR.ts b/compiler/packages/babel-plugin-react-compiler/src/HIR/BuildHIR.ts index 8d5e7aa8a5..8a710b4f3a 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/HIR/BuildHIR.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/HIR/BuildHIR.ts @@ -2075,14 +2075,18 @@ function lowerExpression( } props.push({ kind: "JsxAttribute", name: propName, place: value }); } - if (tag.kind === "BuiltinTag" && tag.name === "fbt") { + if ( + tag.kind === "BuiltinTag" && + (tag.name === "fbt" || tag.name === "fbs") + ) { + const tagName = tag.name; const openingIdentifier = opening.get("name"); const tagIdentifier = openingIdentifier.isJSXIdentifier() ? builder.resolveIdentifier(openingIdentifier) : null; if (tagIdentifier != null) { CompilerError.throwTodo({ - reason: `Support tags where 'fbt' is a local variable instead of a global`, + reason: `Support <${tagName}> tags where '${tagName}' is a local variable instead of a global`, loc: openingIdentifier.node.loc ?? GeneratedSource, description: null, suggestions: null, @@ -2092,7 +2096,7 @@ function lowerExpression( expr.traverse({ JSXNamespacedName(path) { if ( - path.node.namespace.name === "fbt" && + path.node.namespace.name === tagName && path.node.name.name === "enum" ) { fbtEnumLocations.push(path.node.loc ?? GeneratedSource); @@ -2101,7 +2105,7 @@ function lowerExpression( }); if (fbtEnumLocations.length > 1) { CompilerError.throwTodo({ - reason: `Support tags with multiple values`, + reason: `Support <${tagName}> tags with multiple <${tagName}:enum> values`, loc: fbtEnumLocations.at(-1) ?? GeneratedSource, description: null, suggestions: null, @@ -2110,7 +2114,10 @@ function lowerExpression( } let children: Array; - if (tag.kind === "BuiltinTag" && tag.name === "fbt") { + if ( + tag.kind === "BuiltinTag" && + (tag.name === "fbt" || tag.name === "fbs") + ) { children = expr .get("children") .map((child) => { diff --git a/compiler/packages/babel-plugin-react-compiler/src/ReactiveScopes/MemoizeFbtOperandsInSameScope.ts b/compiler/packages/babel-plugin-react-compiler/src/ReactiveScopes/MemoizeFbtOperandsInSameScope.ts index 835a8131f9..ce4e3678bc 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/ReactiveScopes/MemoizeFbtOperandsInSameScope.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/ReactiveScopes/MemoizeFbtOperandsInSameScope.ts @@ -39,8 +39,16 @@ export function memoizeFbtOperandsInSameScope(fn: HIRFunction): void { } } -export const FBT_TAGS: Set = new Set(["fbt", "fbt:param"]); -export const SINGLE_CHILD_FBT_TAGS: Set = new Set(["fbt:param"]); +export const FBT_TAGS: Set = new Set([ + "fbt", + "fbt:param", + "fbs", + "fbs:param", +]); +export const SINGLE_CHILD_FBT_TAGS: Set = new Set([ + "fbt:param", + "fbs:param", +]); function visit(fn: HIRFunction, fbtValues: Set): void { for (const [, block] of fn.body.blocks) { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/fbt/fbs-params.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/fbt/fbs-params.expect.md new file mode 100644 index 0000000000..28e7994c7b --- /dev/null +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/fbt/fbs-params.expect.md @@ -0,0 +1,65 @@ + +## Input + +```javascript +import { fbs } from "fbt"; + +function Component(props) { + return ( +
+ Hello {props.name} + + } + > + Hover me +
+ ); +} + +export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ name: "Sathya" }], +}; + +``` + +## Code + +```javascript +import { c as useMemoCache } from "react"; +import { fbs } from "fbt"; + +function Component(props) { + const $ = useMemoCache(2); + let t0; + if ($[0] !== props.name) { + t0 = ( +
+ Hover me +
+ ); + $[0] = props.name; + $[1] = t0; + } else { + t0 = $[1]; + } + return t0; +} + +export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ name: "Sathya" }], +}; + +``` + +### Eval output +(kind: ok)
Hover me
\ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/fbt/fbs-params.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/fbt/fbs-params.js new file mode 100644 index 0000000000..7d5cb6f6be --- /dev/null +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/fbt/fbs-params.js @@ -0,0 +1,20 @@ +import { fbs } from "fbt"; + +function Component(props) { + return ( +
+ Hello {props.name} + + } + > + Hover me +
+ ); +} + +export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ name: "Sathya" }], +};