[dx] Update error message for reassigning globals

ghstack-source-id: 48ce4b55a8b4b5a22c8ec29f6787732ab2a67778
Pull Request resolved: https://github.com/facebook/react-forget/pull/2860
This commit is contained in:
Joe Savona
2024-04-18 07:46:22 -07:00
parent 87993f333a
commit c84ff16afb
6 changed files with 29 additions and 8 deletions
@@ -16,7 +16,7 @@ import {
} from "../CompilerError";
import { Err, Ok, Result } from "../Utils/Result";
import { assertExhaustive, hasNode } from "../Utils/utils";
import { Environment } from "./Environment";
import { Environment, printFunctionType } from "./Environment";
import {
ArrayExpression,
ArrayPattern,
@@ -3273,9 +3273,16 @@ function lowerIdentifierForAssignment(
const identifier = builder.resolveIdentifier(path);
if (identifier == null) {
if (kind === InstructionKind.Reassign) {
// Trying to reassign a global is not allowed
/*
* Trying to reassign a global is not allowed
* TODO: add support for StoreGlobal or similar, and move this error to run conditionally only for render-phase
* functions in InferReferenceEffects
*/
builder.errors.push({
reason: `This reassigns a variable which was not defined inside of the component. Components should be pure and side-effect free. If this variable is used in rendering, use useState instead. (https://react.dev/learn/keeping-components-pure)`,
reason: `Unexpected reassignment of a variable which was defined outside of the ${printFunctionType(
builder.environment.fnType
)}`,
description: `Components and hooks should be pure and side-effect free, but variable reassignment is a form of side-effect. If this variable is used in rendering, use useState instead. (https://react.dev/reference/rules/components-and-hooks-must-be-pure#side-effects-must-run-outside-of-render)`,
severity: ErrorSeverity.InvalidReact,
loc: path.parentPath.node.loc ?? null,
suggestions: null,
@@ -405,6 +405,20 @@ export type PartialEnvironmentConfig = Partial<EnvironmentConfig>;
export type ReactFunctionType = "Component" | "Hook" | "Other";
export function printFunctionType(type: ReactFunctionType): string {
switch (type) {
case "Component": {
return "component";
}
case "Hook": {
return "hook";
}
default: {
return "function";
}
}
}
export class Environment {
#globals: GlobalRegistry;
#shapes: ShapeRegistry;
@@ -15,7 +15,7 @@ function useFoo(props) {
```
1 | function useFoo(props) {
> 2 | [x] = props;
| ^^^ InvalidReact: This reassigns a variable which was not defined inside of the component. Components should be pure and side-effect free. If this variable is used in rendering, use useState instead. (https://react.dev/learn/keeping-components-pure) (2:2)
| ^^^ InvalidReact: Unexpected reassignment of a variable which was defined outside of the function. Components and hooks should be pure and side-effect free, but variable reassignment is a form of side-effect. If this variable is used in rendering, use useState instead. (https://react.dev/reference/rules/components-and-hooks-must-be-pure#side-effects-must-run-outside-of-render) (2:2)
3 | return { x };
4 | }
5 |
@@ -18,7 +18,7 @@ function Component(props) {
1 | function Component(props) {
2 | let a;
> 3 | [a, b] = props.value;
| ^^^^^^ InvalidReact: This reassigns a variable which was not defined inside of the component. Components should be pure and side-effect free. If this variable is used in rendering, use useState instead. (https://react.dev/learn/keeping-components-pure) (3:3)
| ^^^^^^ InvalidReact: Unexpected reassignment of a variable which was defined outside of the function. Components and hooks should be pure and side-effect free, but variable reassignment is a form of side-effect. If this variable is used in rendering, use useState instead. (https://react.dev/reference/rules/components-and-hooks-must-be-pure#side-effects-must-run-outside-of-render) (3:3)
4 |
5 | return [a, b];
6 | }
@@ -18,7 +18,7 @@ function NoHooks() {
2 |
3 | function NoHooks() {
> 4 | renderCount++;
| ^^^^^^^^^^^^^ InvalidReact: This reassigns a variable which was not defined inside of the component. Components should be pure and side-effect free. If this variable is used in rendering, use useState instead. (https://react.dev/learn/keeping-components-pure) (4:4)
| ^^^^^^^^^^^^^ InvalidReact: Unexpected reassignment of a variable which was defined outside of the component. Components and hooks should be pure and side-effect free, but variable reassignment is a form of side-effect. If this variable is used in rendering, use useState instead. (https://react.dev/reference/rules/components-and-hooks-must-be-pure#side-effects-must-run-outside-of-render) (4:4)
5 | return <div />;
6 | }
7 |
@@ -17,9 +17,9 @@ function Component() {
1 | function Component() {
2 | // Cannot assign to globals
> 3 | someUnknownGlobal = true;
| ^^^^^^^^^^^^^^^^^^^^^^^^ InvalidReact: This reassigns a variable which was not defined inside of the component. Components should be pure and side-effect free. If this variable is used in rendering, use useState instead. (https://react.dev/learn/keeping-components-pure) (3:3)
| ^^^^^^^^^^^^^^^^^^^^^^^^ InvalidReact: Unexpected reassignment of a variable which was defined outside of the function. Components and hooks should be pure and side-effect free, but variable reassignment is a form of side-effect. If this variable is used in rendering, use useState instead. (https://react.dev/reference/rules/components-and-hooks-must-be-pure#side-effects-must-run-outside-of-render) (3:3)
InvalidReact: This reassigns a variable which was not defined inside of the component. Components should be pure and side-effect free. If this variable is used in rendering, use useState instead. (https://react.dev/learn/keeping-components-pure) (4:4)
InvalidReact: Unexpected reassignment of a variable which was defined outside of the function. Components and hooks should be pure and side-effect free, but variable reassignment is a form of side-effect. If this variable is used in rendering, use useState instead. (https://react.dev/reference/rules/components-and-hooks-must-be-pure#side-effects-must-run-outside-of-render) (4:4)
4 | moduleLocal = true;
5 | }
6 |