Skip to content

Commit 9f6ff54

Browse files
committed
s/InvalidJS/InvalidReact/ on "[compiler] Validate against locals being reassigned after render"
Adds a pass which validates that local variables are not reassigned by functions which may be called after render. This is a straightforward forward data-flow analysis, where we: 1. Build up a mapping of context variables in the outer component/hook 2. Find ObjectMethod/FunctionExpressions which may reassign those context variables 3. Propagate aliases of those functions via StoreLocal/LoadLocal 4. Disallow passing those functions with a Freeze effect. This includes JSX arguments, hook arguments, hook return types, etc. Conceptually, a function that reassigns a local is inherently mutable. Frozen functions must be side-effect free, so these two categories are incompatible and we can use the freeze effect to find all instances of where such functions are disallowed rather than special-casing eg hook calls and JSX. [ghstack-poisoned]
2 parents 9b9537e + 91bb840 commit 9f6ff54

5 files changed

+5
-5
lines changed

compiler/packages/babel-plugin-react-compiler/src/Validation/ValidateLocalsNotReassignedAfterRender.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ export function validateLocalsNotReassignedAfterRender(fn: HIRFunction): void {
2121
const contextVariables = new Set<IdentifierId>();
2222
const reassignment = getContextReassignment(fn, contextVariables, false);
2323
if (reassignment !== null) {
24-
CompilerError.throwInvalidJS({
24+
CompilerError.throwInvalidReact({
2525
reason:
2626
"Reassigning a variable after render has completed can cause inconsistent behavior on subsequent renders. Consider using state instead",
2727
description:

compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-reassign-local-in-hook-return-value.expect.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ function useFoo() {
1818
2 | let x = 0;
1919
3 | return (value) => {
2020
> 4 | x = value;
21-
| ^ InvalidJS: Reassigning a variable after render has completed can cause inconsistent behavior on subsequent renders. Consider using state instead. Variable `x` cannot be reassigned after render (4:4)
21+
| ^ InvalidReact: Reassigning a variable after render has completed can cause inconsistent behavior on subsequent renders. Consider using state instead. Variable `x` cannot be reassigned after render (4:4)
2222
5 | };
2323
6 | }
2424
7 |

compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-reassign-local-variable-in-effect.expect.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ function Component() {
5050
5 |
5151
6 | const reassignLocal = (newValue) => {
5252
> 7 | local = newValue;
53-
| ^^^^^ InvalidJS: Reassigning a variable after render has completed can cause inconsistent behavior on subsequent renders. Consider using state instead. Variable `local` cannot be reassigned after render (7:7)
53+
| ^^^^^ InvalidReact: Reassigning a variable after render has completed can cause inconsistent behavior on subsequent renders. Consider using state instead. Variable `local` cannot be reassigned after render (7:7)
5454
8 | };
5555
9 |
5656
10 | const onMount = (newValue) => {

compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-reassign-local-variable-in-hook-argument.expect.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ function Component() {
5151
6 |
5252
7 | const reassignLocal = (newValue) => {
5353
> 8 | local = newValue;
54-
| ^^^^^ InvalidJS: Reassigning a variable after render has completed can cause inconsistent behavior on subsequent renders. Consider using state instead. Variable `local` cannot be reassigned after render (8:8)
54+
| ^^^^^ InvalidReact: Reassigning a variable after render has completed can cause inconsistent behavior on subsequent renders. Consider using state instead. Variable `local` cannot be reassigned after render (8:8)
5555
9 | };
5656
10 |
5757
11 | const callback = (newValue) => {

compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-reassign-local-variable-in-jsx-callback.expect.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ function Component() {
4444
3 |
4545
4 | const reassignLocal = (newValue) => {
4646
> 5 | local = newValue;
47-
| ^^^^^ InvalidJS: Reassigning a variable after render has completed can cause inconsistent behavior on subsequent renders. Consider using state instead. Variable `local` cannot be reassigned after render (5:5)
47+
| ^^^^^ InvalidReact: Reassigning a variable after render has completed can cause inconsistent behavior on subsequent renders. Consider using state instead. Variable `local` cannot be reassigned after render (5:5)
4848
6 | };
4949
7 |
5050
8 | const onClick = (newValue) => {

0 commit comments

Comments
 (0)