@samitouri / QOS-React-1 / commits / 8a634bc1c0

Add frozen reason for props and hook arguments

Add frozen reason for props and hook arguments Improves the error message when mutating props or hook arguments. Previously, this would print a generic error about mutating global variables.

Jan Kassens committed Jan 12, 2024 at 14:51 UTC 8a634bc1c0a3658a23f50662d1c0225ae6212720
6 files changed +54 -1
compiler/packages/babel-plugin-react-forget/src/HIR/HIR.ts
+5
@@ -982,6 +982,11 @@ export enum ValueReason {
982 */
983 Context = "context",
984
985 + /**
986 + * Props of a component or arguments of a hook.
987 + */
988 + ReactiveFunctionArgument = "reactive-function-argument",
989 +
990 Other = "other",
991 }
992
compiler/packages/babel-plugin-react-forget/src/Inference/InferReferenceEffects.ts
+3 -1
@@ -131,7 +131,7 @@ export default function inferReferenceEffects(
131 }
132 : {
133 kind: ValueKind.Frozen,
134 - reason: new Set([ValueReason.Other]),
134 + reason: new Set([ValueReason.ReactiveFunctionArgument]),
135 };
136 for (const param of fn.params) {
137 let value: InstructionValue;
@@ -1503,6 +1503,8 @@ function getWriteErrorReason(abstractValue: AbstractValue): string {
1503 return `Mutating a value returned from 'useContext()', which should not be mutated.`;
1504 } else if (abstractValue.reason.has(ValueReason.KnownReturnSignature)) {
1505 return "Mutating a value returned from a function that should not be mutated.";
1506 + } else if (abstractValue.reason.has(ValueReason.ReactiveFunctionArgument)) {
1507 + return "Mutating props or hook arguments is not allowed. Consider using a local variable instead.";
1508 } else {
1509 return "This mutates a global or a variable after it was passed to React, which means that React cannot observe changes to it.";
1510 }
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.mutate-hook-argument.expect.md new
+19
@@ -0,0 +1,19 @@
1 +
2 +## Input
3 +
4 +```javascript
5 +function useHook(a, b) {
6 + b.test = 1;
7 + a.test = 2;
8 +}
9 +
10 +```
11 +
12 +
13 +## Error
14 +
15 +```
16 +[ReactForget] InvalidReact: Mutating props or hook arguments is not allowed. Consider using a local variable instead. (2:2)
17 +```
18 +
19 +
\ No newline at end of file
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.mutate-hook-argument.js new
+4
@@ -0,0 +1,4 @@
1 +function useHook(a, b) {
2 + b.test = 1;
3 + a.test = 2;
4 +}
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.mutate-props.expect.md new
+19
@@ -0,0 +1,19 @@
1 +
2 +## Input
3 +
4 +```javascript
5 +function Foo(props) {
6 + props.test = 1;
7 + return null;
8 +}
9 +
10 +```
11 +
12 +
13 +## Error
14 +
15 +```
16 +[ReactForget] InvalidReact: Mutating props or hook arguments is not allowed. Consider using a local variable instead. (2:2)
17 +```
18 +
19 +
\ No newline at end of file
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.mutate-props.js new
+4
@@ -0,0 +1,4 @@
1 +function Foo(props) {
2 + props.test = 1;
3 + return null;
4 +}