diff --git a/compiler/packages/babel-plugin-react-compiler/src/ReactiveScopes/CodegenReactiveFunction.ts b/compiler/packages/babel-plugin-react-compiler/src/ReactiveScopes/CodegenReactiveFunction.ts index 486773d5eb91..f0c1a6b6e393 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/ReactiveScopes/CodegenReactiveFunction.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/ReactiveScopes/CodegenReactiveFunction.ts @@ -462,7 +462,10 @@ class Context { } let validated = makeIdentifierName(name).value; let index = 0; - while (this.uniqueIdentifiers.has(validated)) { + while ( + this.uniqueIdentifiers.has(validated) || + this.env.programContext.hasReference(validated) + ) { validated = makeIdentifierName(`${name}${index++}`).value; } this.uniqueIdentifiers.add(validated); diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/jsx-dollar-sign-component-imported.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/jsx-dollar-sign-component-imported.expect.md new file mode 100644 index 000000000000..5927ddb17ca9 --- /dev/null +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/jsx-dollar-sign-component-imported.expect.md @@ -0,0 +1,56 @@ + +## Input + +```javascript +import {Stringify as $} from 'shared-runtime'; + +// Regression test: when $ is imported as a binding, the compiler should not +// use $ as the name for its synthesized memo cache variable — that would +// shadow the import. The memo cache should be renamed to $0 (or similar). +// See https://github.com/facebook/react/issues/36167 + +function Component({x}: {x: number}) { + return <$ value={x} />; +} + +export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{x: 1}], +}; + +``` + +## Code + +```javascript +import { c as _c } from "react/compiler-runtime"; +import { Stringify as $ } from "shared-runtime"; + +// Regression test: when $ is imported as a binding, the compiler should not +// use $ as the name for its synthesized memo cache variable — that would +// shadow the import. The memo cache should be renamed to $0 (or similar). +// See https://github.com/facebook/react/issues/36167 + +function Component(t0) { + const $0 = _c(2); + const { x } = t0; + let t1; + if ($0[0] !== x) { + t1 = <$ value={x} />; + $0[0] = x; + $0[1] = t1; + } else { + t1 = $0[1]; + } + return t1; +} + +export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ x: 1 }], +}; + +``` + +### Eval output +(kind: ok)
{"value":1}
\ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/jsx-dollar-sign-component-imported.tsx b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/jsx-dollar-sign-component-imported.tsx new file mode 100644 index 000000000000..a19d52631efd --- /dev/null +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/jsx-dollar-sign-component-imported.tsx @@ -0,0 +1,15 @@ +import {Stringify as $} from 'shared-runtime'; + +// Regression test: when $ is imported as a binding, the compiler should not +// use $ as the name for its synthesized memo cache variable — that would +// shadow the import. The memo cache should be renamed to $0 (or similar). +// See https://github.com/facebook/react/issues/36167 + +function Component({x}: {x: number}) { + return <$ value={x} />; +} + +export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{x: 1}], +}; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/jsx-dollar-sign-component.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/jsx-dollar-sign-component.expect.md new file mode 100644 index 000000000000..1619cc10badf --- /dev/null +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/jsx-dollar-sign-component.expect.md @@ -0,0 +1,67 @@ + +## Input + +```javascript +// Regression test: when a function is named `$`, the compiler should not +// use `$` as the name for its synthesized memo cache variable — that would +// shadow the function name. The memo cache should be renamed to $0 (or similar). +// See https://github.com/facebook/react/issues/36167 + +function $(n: number) { + return n * 2; +} + +function Component({x}: {x: number}) { + return
{$(x)}
; +} + +export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{x: 5}], +}; + +``` + +## Code + +```javascript +import { c as _c } from "react/compiler-runtime"; // Regression test: when a function is named `$`, the compiler should not +// use `$` as the name for its synthesized memo cache variable — that would +// shadow the function name. The memo cache should be renamed to $0 (or similar). +// See https://github.com/facebook/react/issues/36167 + +function $(n) { + return n * 2; +} + +function Component(t0) { + const $0 = _c(4); + const { x } = t0; + let t1; + if ($0[0] !== x) { + t1 = $(x); + $0[0] = x; + $0[1] = t1; + } else { + t1 = $0[1]; + } + let t2; + if ($0[2] !== t1) { + t2 =
{t1}
; + $0[2] = t1; + $0[3] = t2; + } else { + t2 = $0[3]; + } + return t2; +} + +export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ x: 5 }], +}; + +``` + +### Eval output +(kind: ok)
10
\ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/jsx-dollar-sign-component.tsx b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/jsx-dollar-sign-component.tsx new file mode 100644 index 000000000000..d2ccbc0288e0 --- /dev/null +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/jsx-dollar-sign-component.tsx @@ -0,0 +1,17 @@ +// Regression test: when a function is named `$`, the compiler should not +// use `$` as the name for its synthesized memo cache variable — that would +// shadow the function name. The memo cache should be renamed to $0 (or similar). +// See https://github.com/facebook/react/issues/36167 + +function $(n: number) { + return n * 2; +} + +function Component({x}: {x: number}) { + return
{$(x)}
; +} + +export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{x: 5}], +};