Skip to content

Commit 59bc1b7

Browse files
committed
Update on "compiler: revert #29720 to unbreak filter mode in snap"
[ghstack-poisoned]
2 parents 88b9e8c + 7f7d339 commit 59bc1b7

File tree

64 files changed

+2566
-1002
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

64 files changed

+2566
-1002
lines changed

.eslintrc.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -486,6 +486,7 @@ module.exports = {
486486
$ReadOnlyArray: 'readonly',
487487
$ArrayBufferView: 'readonly',
488488
$Shape: 'readonly',
489+
CallSite: 'readonly',
489490
ConsoleTask: 'readonly', // TOOD: Figure out what the official name of this will be.
490491
ReturnType: 'readonly',
491492
AnimationFrameID: 'readonly',

compiler/packages/babel-plugin-react-compiler/src/Babel/BabelPlugin.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,16 @@ export default function BabelPluginReactCompiler(
3030
*/
3131
Program(prog, pass): void {
3232
let opts = parsePluginOptions(pass.opts);
33+
const isDev =
34+
(typeof __DEV__ !== "undefined" && __DEV__ === true) ||
35+
process.env["NODE_ENV"] === "development";
3336
if (
3437
opts.enableReanimatedCheck === true &&
3538
pipelineUsesReanimatedPlugin(pass.file.opts.plugins)
3639
) {
3740
opts = injectReanimatedFlag(opts);
3841
}
39-
if (process.env["NODE_ENV"] === "development") {
42+
if (isDev) {
4043
opts = {
4144
...opts,
4245
environment: {

compiler/packages/babel-plugin-react-compiler/src/HIR/Globals.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
BuiltInUseInsertionEffectHookId,
1414
BuiltInUseLayoutEffectHookId,
1515
BuiltInUseOperatorId,
16+
BuiltInUseReducerId,
1617
BuiltInUseRefId,
1718
BuiltInUseStateId,
1819
ShapeRegistry,
@@ -265,6 +266,18 @@ const REACT_APIS: Array<[string, BuiltInType]> = [
265266
returnValueReason: ValueReason.State,
266267
}),
267268
],
269+
[
270+
"useReducer",
271+
addHook(DEFAULT_SHAPES, {
272+
positionalParams: [],
273+
restParam: Effect.Freeze,
274+
returnType: { kind: "Object", shapeId: BuiltInUseReducerId },
275+
calleeEffect: Effect.Read,
276+
hookKind: "useReducer",
277+
returnValueKind: ValueKind.Frozen,
278+
returnValueReason: ValueReason.ReducerState,
279+
}),
280+
],
268281
[
269282
"useRef",
270283
addHook(DEFAULT_SHAPES, {

compiler/packages/babel-plugin-react-compiler/src/HIR/HIR.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1254,6 +1254,11 @@ export enum ValueReason {
12541254
*/
12551255
State = "state",
12561256

1257+
/**
1258+
* A value returned from `useReducer`
1259+
*/
1260+
ReducerState = "reducer-state",
1261+
12571262
/**
12581263
* Props of a component or arguments of a hook.
12591264
*/
@@ -1493,6 +1498,14 @@ export function isSetStateType(id: Identifier): boolean {
14931498
return id.type.kind === "Function" && id.type.shapeId === "BuiltInSetState";
14941499
}
14951500

1501+
export function isUseReducerType(id: Identifier): boolean {
1502+
return id.type.kind === "Function" && id.type.shapeId === "BuiltInUseReducer";
1503+
}
1504+
1505+
export function isDispatcherType(id: Identifier): boolean {
1506+
return id.type.kind === "Function" && id.type.shapeId === "BuiltInDispatch";
1507+
}
1508+
14961509
export function isUseEffectHookType(id: Identifier): boolean {
14971510
return (
14981511
id.type.kind === "Function" && id.type.shapeId === "BuiltInUseEffectHook"

compiler/packages/babel-plugin-react-compiler/src/HIR/ObjectShape.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ function addShape(
118118
export type HookKind =
119119
| "useContext"
120120
| "useState"
121+
| "useReducer"
121122
| "useRef"
122123
| "useEffect"
123124
| "useLayoutEffect"
@@ -200,6 +201,8 @@ export const BuiltInUseEffectHookId = "BuiltInUseEffectHook";
200201
export const BuiltInUseLayoutEffectHookId = "BuiltInUseLayoutEffectHook";
201202
export const BuiltInUseInsertionEffectHookId = "BuiltInUseInsertionEffectHook";
202203
export const BuiltInUseOperatorId = "BuiltInUseOperator";
204+
export const BuiltInUseReducerId = "BuiltInUseReducer";
205+
export const BuiltInDispatchId = "BuiltInDispatch";
203206

204207
// ShapeRegistry with default definitions for built-ins.
205208
export const BUILTIN_SHAPES: ShapeRegistry = new Map();
@@ -387,6 +390,25 @@ addObject(BUILTIN_SHAPES, BuiltInUseStateId, [
387390
],
388391
]);
389392

393+
addObject(BUILTIN_SHAPES, BuiltInUseReducerId, [
394+
["0", { kind: "Poly" }],
395+
[
396+
"1",
397+
addFunction(
398+
BUILTIN_SHAPES,
399+
[],
400+
{
401+
positionalParams: [],
402+
restParam: Effect.Freeze,
403+
returnType: PRIMITIVE_TYPE,
404+
calleeEffect: Effect.Read,
405+
returnValueKind: ValueKind.Primitive,
406+
},
407+
BuiltInDispatchId
408+
),
409+
],
410+
]);
411+
390412
addObject(BUILTIN_SHAPES, BuiltInUseRefId, [
391413
["current", { kind: "Object", shapeId: BuiltInRefValueId }],
392414
]);

compiler/packages/babel-plugin-react-compiler/src/Inference/InferReactivePlaces.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import {
1515
Place,
1616
computePostDominatorTree,
1717
getHookKind,
18+
isDispatcherType,
1819
isSetStateType,
1920
isUseOperator,
2021
} from "../HIR";
@@ -219,7 +220,10 @@ export function inferReactivePlaces(fn: HIRFunction): void {
219220

220221
if (hasReactiveInput) {
221222
for (const lvalue of eachInstructionLValue(instruction)) {
222-
if (isSetStateType(lvalue.identifier)) {
223+
if (
224+
isSetStateType(lvalue.identifier) ||
225+
isDispatcherType(lvalue.identifier)
226+
) {
223227
continue;
224228
}
225229
reactiveIdentifiers.markReactive(lvalue);

compiler/packages/babel-plugin-react-compiler/src/Inference/InferReferenceEffects.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2117,6 +2117,8 @@ function getWriteErrorReason(abstractValue: AbstractValue): string {
21172117
return "Mutating component props or hook arguments is not allowed. Consider using a local variable instead";
21182118
} else if (abstractValue.reason.has(ValueReason.State)) {
21192119
return "Mutating a value returned from 'useState()', which should not be mutated. Use the setter function to update instead";
2120+
} else if (abstractValue.reason.has(ValueReason.ReducerState)) {
2121+
return "Mutating a value returned from 'useReducer()', which should not be mutated. Use the dispatch function to update instead";
21202122
} else {
21212123
return "This mutates a variable that React considers immutable";
21222124
}

compiler/packages/babel-plugin-react-compiler/src/ReactiveScopes/PruneNonReactiveDependencies.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
ReactiveFunction,
1111
ReactiveInstruction,
1212
ReactiveScopeBlock,
13+
isDispatcherType,
1314
isSetStateType,
1415
} from "../HIR";
1516
import { eachPatternOperand } from "../HIR/visitors";
@@ -56,7 +57,10 @@ class Visitor extends ReactiveFunctionVisitor<ReactiveIdentifiers> {
5657
case "Destructure": {
5758
if (state.has(value.value.identifier.id)) {
5859
for (const lvalue of eachPatternOperand(value.lvalue.pattern)) {
59-
if (isSetStateType(lvalue.identifier)) {
60+
if (
61+
isSetStateType(lvalue.identifier) ||
62+
isDispatcherType(lvalue.identifier)
63+
) {
6064
continue;
6165
}
6266
state.add(lvalue.identifier.id);
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
2+
## Input
3+
4+
```javascript
5+
import { useReducer } from "react";
6+
7+
function Foo() {
8+
let [state, setState] = useReducer({ foo: 1 });
9+
state.foo = 1;
10+
return state;
11+
}
12+
13+
```
14+
15+
16+
## Error
17+
18+
```
19+
3 | function Foo() {
20+
4 | let [state, setState] = useReducer({ foo: 1 });
21+
> 5 | state.foo = 1;
22+
| ^^^^^ InvalidReact: Mutating a value returned from 'useReducer()', which should not be mutated. Use the dispatch function to update instead (5:5)
23+
6 | return state;
24+
7 | }
25+
8 |
26+
```
27+
28+
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { useReducer } from "react";
2+
3+
function Foo() {
4+
let [state, setState] = useReducer({ foo: 1 });
5+
state.foo = 1;
6+
return state;
7+
}

0 commit comments

Comments
 (0)