[hir] Check for globals while lowering UpdateExpression
lowerIdentifierForAssignment does extra checks such as checking if globals are lvalues. UpdateExpression lowers into an assignment and previously we missed out on such checks.
Sathya Gunasekaran committed
Jul 5, 2023 at 20:21 UTC
4a8b36b8b12d4df5aa930c7adeaafc66d924cd3b
4 files changed
+27
-34
compiler/forget/packages/babel-plugin-react-forget/src/HIR/BuildHIR.ts
+6
-1
@@ -1790,10 +1790,15 @@ function lowerExpression(
1790
builder,
1791
expr.node.loc ?? GeneratedSource
1792
);
1793
- const identifier = lowerIdentifier(
1793
+ const identifier = lowerIdentifierForAssignment(
1794
builder,
1795
+ argument.node.loc ?? GeneratedSource,
1796
+ InstructionKind.Reassign,
1797
argument as NodePath<t.Identifier>
1798
);
1799
+ if (identifier === null) {
1800
+ return { kind: "UnsupportedNode", node: exprNode, loc: exprLoc };
1801
+ }
1802
builder.push({
1803
id: makeInstructionId(0),
1804
lvalue: { ...temp },
compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.mutate-global-increment-op-invalid-react.expect.md
new
+21
@@ -0,0 +1,21 @@
1
+
2
+## Input
3
+
4
+```javascript
5
+let renderCount = 0;
6
+
7
+function NoHooks() {
8
+ renderCount++;
9
+ return <div />;
10
+}
11
+
12
+```
13
+
14
+
15
+## Error
16
+
17
+```
18
+[ReactForget] 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)
19
+```
20
+
21
+
\ No newline at end of file
compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.mutate-global-increment-op-invalid-react.js
renamed
compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/mutate-global-increment-op-invalid-react.expect.md
deleted
-33
@@ -1,33 +0,0 @@
1
-
2
-## Input
3
-
4
-```javascript
5
-let renderCount = 0;
6
-
7
-function NoHooks() {
8
- renderCount++;
9
- return <div />;
10
-}
11
-
12
-```
13
-
14
-## Code
15
-
16
-```javascript
17
-import { unstable_useMemoCache as useMemoCache } from "react";
18
-let renderCount = 0;
19
-
20
-function NoHooks() {
21
- const $ = useMemoCache(1);
22
- let t0;
23
- if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
24
- t0 = <div />;
25
- $[0] = t0;
26
- } else {
27
- t0 = $[0];
28
- }
29
- return t0;
30
-}
31
-
32
-```
33
-
\ No newline at end of file