InferEffectDeps takes a React.AUTODEPS sigil (#33799)
--- [//]: # (BEGIN SAPLING FOOTER) Stack created with [Sapling](https://sapling-scm.com). Best reviewed with [ReviewStack](https://reviewstack.dev/facebook/react/pull/33799). * #33800 * __->__ #33799
Jordan Brown committed
Jul 17, 2025 at 05:31 UTC
dffacc7b8094576c19790fe8341996f743ba4a89
69 files changed
+246
-272
compiler/packages/babel-plugin-react-compiler/src/HIR/Globals.ts
+2
@@ -9,6 +9,7 @@ import {Effect, ValueKind, ValueReason} from './HIR';
9
import {
10
BUILTIN_SHAPES,
11
BuiltInArrayId,
12
+ BuiltInAutodepsId,
13
BuiltInFireFunctionId,
14
BuiltInFireId,
15
BuiltInMapId,
@@ -780,6 +781,7 @@ const REACT_APIS: Array<[string, BuiltInType]> = [
781
BuiltInUseEffectEventId,
782
),
783
],
784
+ ['AUTODEPS', addObject(DEFAULT_SHAPES, BuiltInAutodepsId, [])],
785
];
786
787
TYPED_GLOBALS.push(
compiler/packages/babel-plugin-react-compiler/src/HIR/ObjectShape.ts
+1
@@ -384,6 +384,7 @@ export const BuiltInFireId = 'BuiltInFire';
384
export const BuiltInFireFunctionId = 'BuiltInFireFunction';
385
export const BuiltInUseEffectEventId = 'BuiltInUseEffectEvent';
386
export const BuiltinEffectEventId = 'BuiltInEffectEventFunction';
387
+export const BuiltInAutodepsId = 'BuiltInAutoDepsId';
388
389
// See getReanimatedModuleType() in Globals.ts — this is part of supporting Reanimated's ref-like types
390
export const ReanimatedSharedValueId = 'ReanimatedSharedValueId';
compiler/packages/babel-plugin-react-compiler/src/Inference/InferEffectDependencies.ts
+23
-5
@@ -57,6 +57,8 @@ import {
57
} from '../HIR/visitors';
58
import {empty} from '../Utils/Stack';
59
import {getOrInsertWith} from '../Utils/utils';
60
+import {deadCodeElimination} from '../Optimization';
61
+import {BuiltInAutodepsId} from '../HIR/ObjectShape';
62
63
/**
64
* Infers reactive dependencies captured by useEffect lambdas and adds them as
@@ -135,7 +137,6 @@ export function inferEffectDependencies(fn: HIRFunction): void {
137
}
138
} else if (value.kind === 'LoadGlobal') {
139
loadGlobals.add(lvalue.identifier.id);
138
-
140
/*
141
* TODO: Handle properties on default exports, like
142
* import React from 'react';
@@ -169,8 +170,17 @@ export function inferEffectDependencies(fn: HIRFunction): void {
170
) {
171
const callee =
172
value.kind === 'CallExpression' ? value.callee : value.property;
173
+
174
+ const autodepsArgIndex = value.args.findIndex(
175
+ arg =>
176
+ arg.kind === 'Identifier' &&
177
+ arg.identifier.type.kind === 'Object' &&
178
+ arg.identifier.type.shapeId === BuiltInAutodepsId,
179
+ );
180
if (
173
- value.args.length === autodepFnLoads.get(callee.identifier.id) &&
181
+ value.args.length > 1 &&
182
+ autodepsArgIndex > 0 &&
183
+ autodepFnLoads.has(callee.identifier.id) &&
184
value.args[0].kind === 'Identifier'
185
) {
186
// We have a useEffect call with no deps array, so we need to infer the deps
@@ -260,7 +270,10 @@ export function inferEffectDependencies(fn: HIRFunction): void {
270
effects: null,
271
},
272
});
263
- value.args.push({...depsPlace, effect: Effect.Freeze});
273
+ value.args[autodepsArgIndex] = {
274
+ ...depsPlace,
275
+ effect: Effect.Freeze,
276
+ };
277
fn.env.inferredEffectLocations.add(callee.loc);
278
} else if (loadGlobals.has(value.args[0].identifier.id)) {
279
// Global functions have no reactive dependencies, so we can insert an empty array
@@ -275,7 +288,10 @@ export function inferEffectDependencies(fn: HIRFunction): void {
288
effects: null,
289
},
290
});
278
- value.args.push({...depsPlace, effect: Effect.Freeze});
291
+ value.args[autodepsArgIndex] = {
292
+ ...depsPlace,
293
+ effect: Effect.Freeze,
294
+ };
295
fn.env.inferredEffectLocations.add(callee.loc);
296
}
297
} else if (
@@ -323,6 +339,7 @@ export function inferEffectDependencies(fn: HIRFunction): void {
339
// Renumber instructions and fix scope ranges
340
markInstructionIds(fn.body);
341
fixScopeAndIdentifierRanges(fn.body);
342
+ deadCodeElimination(fn);
343
344
fn.env.hasInferredEffect = true;
345
}
@@ -408,6 +425,7 @@ function rewriteSplices(
425
rewriteBlocks.push(currBlock);
426
427
let cursor = 0;
428
+
429
for (const rewrite of splices) {
430
while (originalInstrs[cursor].id < rewrite.location) {
431
CompilerError.invariant(
@@ -429,7 +447,7 @@ function rewriteSplices(
447
448
if (rewrite.kind === 'instr') {
449
currBlock.instructions.push(rewrite.value);
432
- } else {
450
+ } else if (rewrite.kind === 'block') {
451
const {entry, blocks} = rewrite.value;
452
const entryBlock = blocks.get(entry)!;
453
// splice in all instructions from the entry block
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/bailout-retry/mutate-after-useeffect-granular-access.expect.md
+3
-3
@@ -3,14 +3,14 @@
3
4
```javascript
5
// @inferEffectDependencies @panicThreshold:"none"
6
-import {useEffect} from 'react';
6
+import {useEffect, AUTODEPS} from 'react';
7
import {print} from 'shared-runtime';
8
9
function Component({foo}) {
10
const arr = [];
11
// Taking either arr[0].value or arr as a dependency is reasonable
12
// as long as developers know what to expect.
13
- useEffect(() => print(arr[0].value));
13
+ useEffect(() => print(arr[0].value), AUTODEPS);
14
arr.push({value: foo});
15
return arr;
16
}
@@ -21,7 +21,7 @@ function Component({foo}) {
21
22
```javascript
23
// @inferEffectDependencies @panicThreshold:"none"
24
-import { useEffect } from "react";
24
+import { useEffect, AUTODEPS } from "react";
25
import { print } from "shared-runtime";
26
27
function Component(t0) {
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/bailout-retry/mutate-after-useeffect-granular-access.js
+2
-2
@@ -1,12 +1,12 @@
1
// @inferEffectDependencies @panicThreshold:"none"
2
-import {useEffect} from 'react';
2
+import {useEffect, AUTODEPS} from 'react';
3
import {print} from 'shared-runtime';
4
5
function Component({foo}) {
6
const arr = [];
7
// Taking either arr[0].value or arr as a dependency is reasonable
8
// as long as developers know what to expect.
9
- useEffect(() => print(arr[0].value));
9
+ useEffect(() => print(arr[0].value), AUTODEPS);
10
arr.push({value: foo});
11
return arr;
12
}
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/bailout-retry/mutate-after-useeffect-optional-chain.expect.md
+6
-6
@@ -3,14 +3,14 @@
3
4
```javascript
5
// @inferEffectDependencies @panicThreshold:"none" @loggerTestOnly
6
-import {useEffect} from 'react';
6
+import {useEffect, AUTODEPS} from 'react';
7
import {print} from 'shared-runtime';
8
9
function Component({foo}) {
10
const arr = [];
11
// Taking either arr[0].value or arr as a dependency is reasonable
12
// as long as developers know what to expect.
13
- useEffect(() => print(arr[0]?.value));
13
+ useEffect(() => print(arr[0]?.value), AUTODEPS);
14
arr.push({value: foo});
15
return arr;
16
}
@@ -26,7 +26,7 @@ export const FIXTURE_ENTRYPOINT = {
26
27
```javascript
28
// @inferEffectDependencies @panicThreshold:"none" @loggerTestOnly
29
-import { useEffect } from "react";
29
+import { useEffect, AUTODEPS } from "react";
30
import { print } from "shared-runtime";
31
32
function Component(t0) {
@@ -48,9 +48,9 @@ export const FIXTURE_ENTRYPOINT = {
48
## Logs
49
50
```
51
-{"kind":"CompileError","fnLoc":{"start":{"line":5,"column":0,"index":139},"end":{"line":12,"column":1,"index":384},"filename":"mutate-after-useeffect-optional-chain.ts"},"detail":{"reason":"Updating a value used previously in an effect function or as an effect dependency is not allowed. Consider moving the mutation before calling useEffect()","description":null,"severity":"InvalidReact","suggestions":null,"loc":{"start":{"line":10,"column":2,"index":345},"end":{"line":10,"column":5,"index":348},"filename":"mutate-after-useeffect-optional-chain.ts","identifierName":"arr"}}}
52
-{"kind":"AutoDepsDecorations","fnLoc":{"start":{"line":9,"column":2,"index":304},"end":{"line":9,"column":39,"index":341},"filename":"mutate-after-useeffect-optional-chain.ts"},"decorations":[{"start":{"line":9,"column":24,"index":326},"end":{"line":9,"column":27,"index":329},"filename":"mutate-after-useeffect-optional-chain.ts","identifierName":"arr"}]}
53
-{"kind":"CompileSuccess","fnLoc":{"start":{"line":5,"column":0,"index":139},"end":{"line":12,"column":1,"index":384},"filename":"mutate-after-useeffect-optional-chain.ts"},"fnName":"Component","memoSlots":0,"memoBlocks":0,"memoValues":0,"prunedMemoBlocks":0,"prunedMemoValues":0}
51
+{"kind":"CompileError","fnLoc":{"start":{"line":5,"column":0,"index":149},"end":{"line":12,"column":1,"index":404},"filename":"mutate-after-useeffect-optional-chain.ts"},"detail":{"reason":"Updating a value used previously in an effect function or as an effect dependency is not allowed. Consider moving the mutation before calling useEffect()","description":null,"severity":"InvalidReact","suggestions":null,"loc":{"start":{"line":10,"column":2,"index":365},"end":{"line":10,"column":5,"index":368},"filename":"mutate-after-useeffect-optional-chain.ts","identifierName":"arr"}}}
52
+{"kind":"AutoDepsDecorations","fnLoc":{"start":{"line":9,"column":2,"index":314},"end":{"line":9,"column":49,"index":361},"filename":"mutate-after-useeffect-optional-chain.ts"},"decorations":[{"start":{"line":9,"column":24,"index":336},"end":{"line":9,"column":27,"index":339},"filename":"mutate-after-useeffect-optional-chain.ts","identifierName":"arr"}]}
53
+{"kind":"CompileSuccess","fnLoc":{"start":{"line":5,"column":0,"index":149},"end":{"line":12,"column":1,"index":404},"filename":"mutate-after-useeffect-optional-chain.ts"},"fnName":"Component","memoSlots":0,"memoBlocks":0,"memoValues":0,"prunedMemoBlocks":0,"prunedMemoValues":0}
54
```
55
56
### Eval output
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/bailout-retry/mutate-after-useeffect-optional-chain.js
+2
-2
@@ -1,12 +1,12 @@
1
// @inferEffectDependencies @panicThreshold:"none" @loggerTestOnly
2
-import {useEffect} from 'react';
2
+import {useEffect, AUTODEPS} from 'react';
3
import {print} from 'shared-runtime';
4
5
function Component({foo}) {
6
const arr = [];
7
// Taking either arr[0].value or arr as a dependency is reasonable
8
// as long as developers know what to expect.
9
- useEffect(() => print(arr[0]?.value));
9
+ useEffect(() => print(arr[0]?.value), AUTODEPS);
10
arr.push({value: foo});
11
return arr;
12
}
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/bailout-retry/mutate-after-useeffect-ref-access.expect.md
+6
-6
@@ -4,12 +4,12 @@
4
```javascript
5
// @inferEffectDependencies @panicThreshold:"none" @loggerTestOnly
6
7
-import {useEffect, useRef} from 'react';
7
+import {useEffect, useRef, AUTODEPS} from 'react';
8
import {print} from 'shared-runtime';
9
10
function Component({arrRef}) {
11
// Avoid taking arr.current as a dependency
12
- useEffect(() => print(arrRef.current));
12
+ useEffect(() => print(arrRef.current), AUTODEPS);
13
arrRef.current.val = 2;
14
return arrRef;
15
}
@@ -26,7 +26,7 @@ export const FIXTURE_ENTRYPOINT = {
26
```javascript
27
// @inferEffectDependencies @panicThreshold:"none" @loggerTestOnly
28
29
-import { useEffect, useRef } from "react";
29
+import { useEffect, useRef, AUTODEPS } from "react";
30
import { print } from "shared-runtime";
31
32
function Component(t0) {
@@ -47,9 +47,9 @@ export const FIXTURE_ENTRYPOINT = {
47
## Logs
48
49
```
50
-{"kind":"CompileError","fnLoc":{"start":{"line":6,"column":0,"index":148},"end":{"line":11,"column":1,"index":311},"filename":"mutate-after-useeffect-ref-access.ts"},"detail":{"reason":"Mutating component props or hook arguments is not allowed. Consider using a local variable instead","description":null,"severity":"InvalidReact","suggestions":null,"loc":{"start":{"line":9,"column":2,"index":269},"end":{"line":9,"column":16,"index":283},"filename":"mutate-after-useeffect-ref-access.ts"}}}
51
-{"kind":"AutoDepsDecorations","fnLoc":{"start":{"line":8,"column":2,"index":227},"end":{"line":8,"column":40,"index":265},"filename":"mutate-after-useeffect-ref-access.ts"},"decorations":[{"start":{"line":8,"column":24,"index":249},"end":{"line":8,"column":30,"index":255},"filename":"mutate-after-useeffect-ref-access.ts","identifierName":"arrRef"}]}
52
-{"kind":"CompileSuccess","fnLoc":{"start":{"line":6,"column":0,"index":148},"end":{"line":11,"column":1,"index":311},"filename":"mutate-after-useeffect-ref-access.ts"},"fnName":"Component","memoSlots":0,"memoBlocks":0,"memoValues":0,"prunedMemoBlocks":0,"prunedMemoValues":0}
50
+{"kind":"CompileError","fnLoc":{"start":{"line":6,"column":0,"index":158},"end":{"line":11,"column":1,"index":331},"filename":"mutate-after-useeffect-ref-access.ts"},"detail":{"reason":"Mutating component props or hook arguments is not allowed. Consider using a local variable instead","description":null,"severity":"InvalidReact","suggestions":null,"loc":{"start":{"line":9,"column":2,"index":289},"end":{"line":9,"column":16,"index":303},"filename":"mutate-after-useeffect-ref-access.ts"}}}
51
+{"kind":"AutoDepsDecorations","fnLoc":{"start":{"line":8,"column":2,"index":237},"end":{"line":8,"column":50,"index":285},"filename":"mutate-after-useeffect-ref-access.ts"},"decorations":[{"start":{"line":8,"column":24,"index":259},"end":{"line":8,"column":30,"index":265},"filename":"mutate-after-useeffect-ref-access.ts","identifierName":"arrRef"}]}
52
+{"kind":"CompileSuccess","fnLoc":{"start":{"line":6,"column":0,"index":158},"end":{"line":11,"column":1,"index":331},"filename":"mutate-after-useeffect-ref-access.ts"},"fnName":"Component","memoSlots":0,"memoBlocks":0,"memoValues":0,"prunedMemoBlocks":0,"prunedMemoValues":0}
53
```
54
55
### Eval output
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/bailout-retry/mutate-after-useeffect-ref-access.js
+2
-2
@@ -1,11 +1,11 @@
1
// @inferEffectDependencies @panicThreshold:"none" @loggerTestOnly
2
3
-import {useEffect, useRef} from 'react';
3
+import {useEffect, useRef, AUTODEPS} from 'react';
4
import {print} from 'shared-runtime';
5
6
function Component({arrRef}) {
7
// Avoid taking arr.current as a dependency
8
- useEffect(() => print(arrRef.current));
8
+ useEffect(() => print(arrRef.current), AUTODEPS);
9
arrRef.current.val = 2;
10
return arrRef;
11
}
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/bailout-retry/mutate-after-useeffect.expect.md
+6
-6
@@ -3,13 +3,13 @@
3
4
```javascript
5
// @inferEffectDependencies @panicThreshold:"none" @loggerTestOnly
6
-import {useEffect} from 'react';
6
+import {useEffect, AUTODEPS} from 'react';
7
8
function Component({foo}) {
9
const arr = [];
10
useEffect(() => {
11
arr.push(foo);
12
- });
12
+ }, AUTODEPS);
13
arr.push(2);
14
return arr;
15
}
@@ -25,7 +25,7 @@ export const FIXTURE_ENTRYPOINT = {
25
26
```javascript
27
// @inferEffectDependencies @panicThreshold:"none" @loggerTestOnly
28
-import { useEffect } from "react";
28
+import { useEffect, AUTODEPS } from "react";
29
30
function Component(t0) {
31
const { foo } = t0;
@@ -47,9 +47,9 @@ export const FIXTURE_ENTRYPOINT = {
47
## Logs
48
49
```
50
-{"kind":"CompileError","fnLoc":{"start":{"line":4,"column":0,"index":101},"end":{"line":11,"column":1,"index":222},"filename":"mutate-after-useeffect.ts"},"detail":{"reason":"Updating a value used previously in an effect function or as an effect dependency is not allowed. Consider moving the mutation before calling useEffect()","description":null,"severity":"InvalidReact","suggestions":null,"loc":{"start":{"line":9,"column":2,"index":194},"end":{"line":9,"column":5,"index":197},"filename":"mutate-after-useeffect.ts","identifierName":"arr"}}}
51
-{"kind":"AutoDepsDecorations","fnLoc":{"start":{"line":6,"column":2,"index":149},"end":{"line":8,"column":4,"index":190},"filename":"mutate-after-useeffect.ts"},"decorations":[{"start":{"line":7,"column":4,"index":171},"end":{"line":7,"column":7,"index":174},"filename":"mutate-after-useeffect.ts","identifierName":"arr"},{"start":{"line":7,"column":4,"index":171},"end":{"line":7,"column":7,"index":174},"filename":"mutate-after-useeffect.ts","identifierName":"arr"},{"start":{"line":7,"column":13,"index":180},"end":{"line":7,"column":16,"index":183},"filename":"mutate-after-useeffect.ts","identifierName":"foo"}]}
52
-{"kind":"CompileSuccess","fnLoc":{"start":{"line":4,"column":0,"index":101},"end":{"line":11,"column":1,"index":222},"filename":"mutate-after-useeffect.ts"},"fnName":"Component","memoSlots":0,"memoBlocks":0,"memoValues":0,"prunedMemoBlocks":0,"prunedMemoValues":0}
50
+{"kind":"CompileError","fnLoc":{"start":{"line":4,"column":0,"index":111},"end":{"line":11,"column":1,"index":242},"filename":"mutate-after-useeffect.ts"},"detail":{"reason":"Updating a value used previously in an effect function or as an effect dependency is not allowed. Consider moving the mutation before calling useEffect()","description":null,"severity":"InvalidReact","suggestions":null,"loc":{"start":{"line":9,"column":2,"index":214},"end":{"line":9,"column":5,"index":217},"filename":"mutate-after-useeffect.ts","identifierName":"arr"}}}
51
+{"kind":"AutoDepsDecorations","fnLoc":{"start":{"line":6,"column":2,"index":159},"end":{"line":8,"column":14,"index":210},"filename":"mutate-after-useeffect.ts"},"decorations":[{"start":{"line":7,"column":4,"index":181},"end":{"line":7,"column":7,"index":184},"filename":"mutate-after-useeffect.ts","identifierName":"arr"},{"start":{"line":7,"column":4,"index":181},"end":{"line":7,"column":7,"index":184},"filename":"mutate-after-useeffect.ts","identifierName":"arr"},{"start":{"line":7,"column":13,"index":190},"end":{"line":7,"column":16,"index":193},"filename":"mutate-after-useeffect.ts","identifierName":"foo"}]}
52
+{"kind":"CompileSuccess","fnLoc":{"start":{"line":4,"column":0,"index":111},"end":{"line":11,"column":1,"index":242},"filename":"mutate-after-useeffect.ts"},"fnName":"Component","memoSlots":0,"memoBlocks":0,"memoValues":0,"prunedMemoBlocks":0,"prunedMemoValues":0}
53
```
54
55
### Eval output
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/bailout-retry/mutate-after-useeffect.js
+2
-2
@@ -1,11 +1,11 @@
1
// @inferEffectDependencies @panicThreshold:"none" @loggerTestOnly
2
-import {useEffect} from 'react';
2
+import {useEffect, AUTODEPS} from 'react';
3
4
function Component({foo}) {
5
const arr = [];
6
useEffect(() => {
7
arr.push(foo);
8
- });
8
+ }, AUTODEPS);
9
arr.push(2);
10
return arr;
11
}
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/helper-nonreactive.expect.md
+3
-3
@@ -3,7 +3,7 @@
3
4
```javascript
5
// @inferEffectDependencies
6
-import {useEffect, useRef} from 'react';
6
+import {useEffect, useRef, AUTODEPS} from 'react';
7
function useCustomRef() {
8
const ref = useRef();
9
return ref;
@@ -12,7 +12,7 @@ function NonReactiveWrapper() {
12
const ref = useCustomRef();
13
useEffect(() => {
14
print(ref);
15
- });
15
+ }, AUTODEPS);
16
}
17
18
```
@@ -21,7 +21,7 @@ function NonReactiveWrapper() {
21
22
```javascript
23
import { c as _c } from "react/compiler-runtime"; // @inferEffectDependencies
24
-import { useEffect, useRef } from "react";
24
+import { useEffect, useRef, AUTODEPS } from "react";
25
function useCustomRef() {
26
const ref = useRef();
27
return ref;
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/helper-nonreactive.js
+2
-2
@@ -1,5 +1,5 @@
1
// @inferEffectDependencies
2
-import {useEffect, useRef} from 'react';
2
+import {useEffect, useRef, AUTODEPS} from 'react';
3
function useCustomRef() {
4
const ref = useRef();
5
return ref;
@@ -8,5 +8,5 @@ function NonReactiveWrapper() {
8
const ref = useCustomRef();
9
useEffect(() => {
10
print(ref);
11
- });
11
+ }, AUTODEPS);
12
}
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/import-namespace-useEffect.expect.md
+2
-2
@@ -8,8 +8,8 @@ import * as SharedRuntime from 'shared-runtime';
8
9
function NonReactiveDepInEffect() {
10
const obj = makeObject_Primitives();
11
- React.useEffect(() => print(obj));
12
- SharedRuntime.useSpecialEffect(() => print(obj), [obj]);
11
+ React.useEffect(() => print(obj), React.AUTODEPS);
12
+ SharedRuntime.useSpecialEffect(() => print(obj), [obj], React.AUTODEPS);
13
}
14
15
```
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/import-namespace-useEffect.js
+2
-2
@@ -4,6 +4,6 @@ import * as SharedRuntime from 'shared-runtime';
4
5
function NonReactiveDepInEffect() {
6
const obj = makeObject_Primitives();
7
- React.useEffect(() => print(obj));
8
- SharedRuntime.useSpecialEffect(() => print(obj), [obj]);
7
+ React.useEffect(() => print(obj), React.AUTODEPS);
8
+ SharedRuntime.useSpecialEffect(() => print(obj), [obj], React.AUTODEPS);
9
}
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/infer-deps-custom-config.expect.md
+3
-1
@@ -4,10 +4,11 @@
4
```javascript
5
// @inferEffectDependencies
6
import {print, useSpecialEffect} from 'shared-runtime';
7
+import {AUTODEPS} from 'react';
8
9
function CustomConfig({propVal}) {
10
// Insertion
10
- useSpecialEffect(() => print(propVal), [propVal]);
11
+ useSpecialEffect(() => print(propVal), [propVal], AUTODEPS);
12
// No insertion
13
useSpecialEffect(() => print(propVal), [propVal], [propVal]);
14
}
@@ -19,6 +20,7 @@ function CustomConfig({propVal}) {
20
```javascript
21
import { c as _c } from "react/compiler-runtime"; // @inferEffectDependencies
22
import { print, useSpecialEffect } from "shared-runtime";
23
+import { AUTODEPS } from "react";
24
25
function CustomConfig(t0) {
26
const $ = _c(7);
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/infer-deps-custom-config.js
+2
-1
@@ -1,9 +1,10 @@
1
// @inferEffectDependencies
2
import {print, useSpecialEffect} from 'shared-runtime';
3
+import {AUTODEPS} from 'react';
4
5
function CustomConfig({propVal}) {
6
// Insertion
6
- useSpecialEffect(() => print(propVal), [propVal]);
7
+ useSpecialEffect(() => print(propVal), [propVal], AUTODEPS);
8
// No insertion
9
useSpecialEffect(() => print(propVal), [propVal], [propVal]);
10
}
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/infer-effect-dependencies.expect.md
+5
-5
@@ -3,7 +3,7 @@
3
4
```javascript
5
// @inferEffectDependencies
6
-import {useEffect, useRef} from 'react';
6
+import {useEffect, useRef, AUTODEPS} from 'react';
7
import useEffectWrapper from 'useEffectWrapper';
8
9
const moduleNonReactive = 0;
@@ -24,7 +24,7 @@ function Component({foo, bar}) {
24
console.log(ref.current);
25
console.log(localNonPrimitiveReactive);
26
console.log(localNonPrimitiveNonreactive);
27
- });
27
+ }, AUTODEPS);
28
29
// Optional chains and property accesses
30
// TODO: we may be able to save bytes by omitting property accesses if the
@@ -32,11 +32,11 @@ function Component({foo, bar}) {
32
useEffect(() => {
33
console.log(bar?.baz);
34
console.log(bar.qux);
35
- });
35
+ }, AUTODEPS);
36
37
useEffectWrapper(() => {
38
console.log(foo);
39
- });
39
+ }, AUTODEPS);
40
}
41
42
```
@@ -45,7 +45,7 @@ function Component({foo, bar}) {
45
46
```javascript
47
import { c as _c } from "react/compiler-runtime"; // @inferEffectDependencies
48
-import { useEffect, useRef } from "react";
48
+import { useEffect, useRef, AUTODEPS } from "react";
49
import useEffectWrapper from "useEffectWrapper";
50
51
const moduleNonReactive = 0;
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/infer-effect-dependencies.js
+4
-4
@@ -1,5 +1,5 @@
1
// @inferEffectDependencies
2
-import {useEffect, useRef} from 'react';
2
+import {useEffect, useRef, AUTODEPS} from 'react';
3
import useEffectWrapper from 'useEffectWrapper';
4
5
const moduleNonReactive = 0;
@@ -20,7 +20,7 @@ function Component({foo, bar}) {
20
console.log(ref.current);
21
console.log(localNonPrimitiveReactive);
22
console.log(localNonPrimitiveNonreactive);
23
- });
23
+ }, AUTODEPS);
24
25
// Optional chains and property accesses
26
// TODO: we may be able to save bytes by omitting property accesses if the
@@ -28,9 +28,9 @@ function Component({foo, bar}) {
28
useEffect(() => {
29
console.log(bar?.baz);
30
console.log(bar.qux);
31
- });
31
+ }, AUTODEPS);
32
33
useEffectWrapper(() => {
34
console.log(foo);
35
- });
35
+ }, AUTODEPS);
36
}
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/no-emit/no-emit-lint-repro.expect.md
+4
-2
@@ -5,10 +5,11 @@
5
// @inferEffectDependencies @noEmit
6
import {print} from 'shared-runtime';
7
import useEffectWrapper from 'useEffectWrapper';
8
+import {AUTODEPS} from 'react';
9
10
function ReactiveVariable({propVal}) {
11
const arr = [propVal];
11
- useEffectWrapper(() => print(arr));
12
+ useEffectWrapper(() => print(arr), AUTODEPS);
13
}
14
15
```
@@ -19,10 +20,11 @@ function ReactiveVariable({propVal}) {
20
// @inferEffectDependencies @noEmit
21
import { print } from "shared-runtime";
22
import useEffectWrapper from "useEffectWrapper";
23
+import { AUTODEPS } from "react";
24
25
function ReactiveVariable({ propVal }) {
26
const arr = [propVal];
25
- useEffectWrapper(() => print(arr));
27
+ useEffectWrapper(() => print(arr), AUTODEPS);
28
}
29
30
```
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/no-emit/no-emit-lint-repro.js
+2
-1
@@ -1,8 +1,9 @@
1
// @inferEffectDependencies @noEmit
2
import {print} from 'shared-runtime';
3
import useEffectWrapper from 'useEffectWrapper';
4
+import {AUTODEPS} from 'react';
5
6
function ReactiveVariable({propVal}) {
7
const arr = [propVal];
7
- useEffectWrapper(() => print(arr));
8
+ useEffectWrapper(() => print(arr), AUTODEPS);
9
}
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/no-emit/retry-no-emit.expect.md
+10
-8
@@ -5,13 +5,14 @@
5
// @inferEffectDependencies @noEmit @panicThreshold:"none" @loggerTestOnly
6
import {print} from 'shared-runtime';
7
import useEffectWrapper from 'useEffectWrapper';
8
+import {AUTODEPS} from 'react';
9
10
function Foo({propVal}) {
11
const arr = [propVal];
11
- useEffectWrapper(() => print(arr));
12
+ useEffectWrapper(() => print(arr), AUTODEPS);
13
14
const arr2 = [];
14
- useEffectWrapper(() => arr2.push(propVal));
15
+ useEffectWrapper(() => arr2.push(propVal), AUTODEPS);
16
arr2.push(2);
17
return {arr, arr2};
18
}
@@ -30,13 +31,14 @@ export const FIXTURE_ENTRYPOINT = {
31
// @inferEffectDependencies @noEmit @panicThreshold:"none" @loggerTestOnly
32
import { print } from "shared-runtime";
33
import useEffectWrapper from "useEffectWrapper";
34
+import { AUTODEPS } from "react";
35
36
function Foo({ propVal }) {
37
const arr = [propVal];
36
- useEffectWrapper(() => print(arr));
38
+ useEffectWrapper(() => print(arr), AUTODEPS);
39
40
const arr2 = [];
39
- useEffectWrapper(() => arr2.push(propVal));
41
+ useEffectWrapper(() => arr2.push(propVal), AUTODEPS);
42
arr2.push(2);
43
return { arr, arr2 };
44
}
@@ -52,10 +54,10 @@ export const FIXTURE_ENTRYPOINT = {
54
## Logs
55
56
```
55
-{"kind":"CompileError","fnLoc":{"start":{"line":5,"column":0,"index":163},"end":{"line":13,"column":1,"index":357},"filename":"retry-no-emit.ts"},"detail":{"reason":"Updating a value previously passed as an argument to a hook is not allowed. Consider moving the mutation before calling the hook","description":null,"severity":"InvalidReact","suggestions":null,"loc":{"start":{"line":11,"column":2,"index":320},"end":{"line":11,"column":6,"index":324},"filename":"retry-no-emit.ts","identifierName":"arr2"}}}
56
-{"kind":"AutoDepsDecorations","fnLoc":{"start":{"line":7,"column":2,"index":216},"end":{"line":7,"column":36,"index":250},"filename":"retry-no-emit.ts"},"decorations":[{"start":{"line":7,"column":31,"index":245},"end":{"line":7,"column":34,"index":248},"filename":"retry-no-emit.ts","identifierName":"arr"}]}
57
-{"kind":"AutoDepsDecorations","fnLoc":{"start":{"line":10,"column":2,"index":274},"end":{"line":10,"column":44,"index":316},"filename":"retry-no-emit.ts"},"decorations":[{"start":{"line":10,"column":25,"index":297},"end":{"line":10,"column":29,"index":301},"filename":"retry-no-emit.ts","identifierName":"arr2"},{"start":{"line":10,"column":25,"index":297},"end":{"line":10,"column":29,"index":301},"filename":"retry-no-emit.ts","identifierName":"arr2"},{"start":{"line":10,"column":35,"index":307},"end":{"line":10,"column":42,"index":314},"filename":"retry-no-emit.ts","identifierName":"propVal"}]}
58
-{"kind":"CompileSuccess","fnLoc":{"start":{"line":5,"column":0,"index":163},"end":{"line":13,"column":1,"index":357},"filename":"retry-no-emit.ts"},"fnName":"Foo","memoSlots":0,"memoBlocks":0,"memoValues":0,"prunedMemoBlocks":0,"prunedMemoValues":0}
57
+{"kind":"CompileError","fnLoc":{"start":{"line":6,"column":0,"index":195},"end":{"line":14,"column":1,"index":409},"filename":"retry-no-emit.ts"},"detail":{"reason":"Updating a value previously passed as an argument to a hook is not allowed. Consider moving the mutation before calling the hook","description":null,"severity":"InvalidReact","suggestions":null,"loc":{"start":{"line":12,"column":2,"index":372},"end":{"line":12,"column":6,"index":376},"filename":"retry-no-emit.ts","identifierName":"arr2"}}}
58
+{"kind":"AutoDepsDecorations","fnLoc":{"start":{"line":8,"column":2,"index":248},"end":{"line":8,"column":46,"index":292},"filename":"retry-no-emit.ts"},"decorations":[{"start":{"line":8,"column":31,"index":277},"end":{"line":8,"column":34,"index":280},"filename":"retry-no-emit.ts","identifierName":"arr"}]}
59
+{"kind":"AutoDepsDecorations","fnLoc":{"start":{"line":11,"column":2,"index":316},"end":{"line":11,"column":54,"index":368},"filename":"retry-no-emit.ts"},"decorations":[{"start":{"line":11,"column":25,"index":339},"end":{"line":11,"column":29,"index":343},"filename":"retry-no-emit.ts","identifierName":"arr2"},{"start":{"line":11,"column":25,"index":339},"end":{"line":11,"column":29,"index":343},"filename":"retry-no-emit.ts","identifierName":"arr2"},{"start":{"line":11,"column":35,"index":349},"end":{"line":11,"column":42,"index":356},"filename":"retry-no-emit.ts","identifierName":"propVal"}]}
60
+{"kind":"CompileSuccess","fnLoc":{"start":{"line":6,"column":0,"index":195},"end":{"line":14,"column":1,"index":409},"filename":"retry-no-emit.ts"},"fnName":"Foo","memoSlots":0,"memoBlocks":0,"memoValues":0,"prunedMemoBlocks":0,"prunedMemoValues":0}
61
```
62
63
### Eval output
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/no-emit/retry-no-emit.js
+3
-2
@@ -1,13 +1,14 @@
1
// @inferEffectDependencies @noEmit @panicThreshold:"none" @loggerTestOnly
2
import {print} from 'shared-runtime';
3
import useEffectWrapper from 'useEffectWrapper';
4
+import {AUTODEPS} from 'react';
5
6
function Foo({propVal}) {
7
const arr = [propVal];
7
- useEffectWrapper(() => print(arr));
8
+ useEffectWrapper(() => print(arr), AUTODEPS);
9
10
const arr2 = [];
10
- useEffectWrapper(() => arr2.push(propVal));
11
+ useEffectWrapper(() => arr2.push(propVal), AUTODEPS);
12
arr2.push(2);
13
return {arr, arr2};
14
}
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/no-emit/retry-opt-in--no-emit.expect.md
+6
-4
@@ -4,15 +4,16 @@
4
```javascript
5
// @compilationMode:"all" @inferEffectDependencies @panicThreshold:"none" @noEmit
6
import {print} from 'shared-runtime';
7
+import {AUTODEPS} from 'react';
8
import useEffectWrapper from 'useEffectWrapper';
9
10
function Foo({propVal}) {
11
'use memo';
12
const arr = [propVal];
12
- useEffectWrapper(() => print(arr));
13
+ useEffectWrapper(() => print(arr), AUTODEPS);
14
15
const arr2 = [];
15
- useEffectWrapper(() => arr2.push(propVal));
16
+ useEffectWrapper(() => arr2.push(propVal), AUTODEPS);
17
arr2.push(2);
18
19
return {arr, arr2};
@@ -31,15 +32,16 @@ export const FIXTURE_ENTRYPOINT = {
32
```javascript
33
// @compilationMode:"all" @inferEffectDependencies @panicThreshold:"none" @noEmit
34
import { print } from "shared-runtime";
35
+import { AUTODEPS } from "react";
36
import useEffectWrapper from "useEffectWrapper";
37
38
function Foo({ propVal }) {
39
"use memo";
40
const arr = [propVal];
39
- useEffectWrapper(() => print(arr));
41
+ useEffectWrapper(() => print(arr), AUTODEPS);
42
43
const arr2 = [];
42
- useEffectWrapper(() => arr2.push(propVal));
44
+ useEffectWrapper(() => arr2.push(propVal), AUTODEPS);
45
arr2.push(2);
46
47
return { arr, arr2 };
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/no-emit/retry-opt-in--no-emit.js
+3
-2
@@ -1,14 +1,15 @@
1
// @compilationMode:"all" @inferEffectDependencies @panicThreshold:"none" @noEmit
2
import {print} from 'shared-runtime';
3
+import {AUTODEPS} from 'react';
4
import useEffectWrapper from 'useEffectWrapper';
5
6
function Foo({propVal}) {
7
'use memo';
8
const arr = [propVal];
8
- useEffectWrapper(() => print(arr));
9
+ useEffectWrapper(() => print(arr), AUTODEPS);
10
11
const arr2 = [];
11
- useEffectWrapper(() => arr2.push(propVal));
12
+ useEffectWrapper(() => arr2.push(propVal), AUTODEPS);
13
arr2.push(2);
14
15
return {arr, arr2};
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/nonreactive-dep.expect.md
+3
-3
@@ -3,7 +3,7 @@
3
4
```javascript
5
// @inferEffectDependencies
6
-import {useEffect} from 'react';
6
+import {useEffect, AUTODEPS} from 'react';
7
import {makeObject_Primitives, print} from 'shared-runtime';
8
9
/**
@@ -25,7 +25,7 @@ import {makeObject_Primitives, print} from 'shared-runtime';
25
*/
26
function NonReactiveDepInEffect() {
27
const obj = makeObject_Primitives();
28
- useEffect(() => print(obj));
28
+ useEffect(() => print(obj), AUTODEPS);
29
}
30
31
```
@@ -34,7 +34,7 @@ function NonReactiveDepInEffect() {
34
35
```javascript
36
import { c as _c } from "react/compiler-runtime"; // @inferEffectDependencies
37
-import { useEffect } from "react";
37
+import { useEffect, AUTODEPS } from "react";
38
import { makeObject_Primitives, print } from "shared-runtime";
39
40
/**
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/nonreactive-dep.js
+2
-2
@@ -1,5 +1,5 @@
1
// @inferEffectDependencies
2
-import {useEffect} from 'react';
2
+import {useEffect, AUTODEPS} from 'react';
3
import {makeObject_Primitives, print} from 'shared-runtime';
4
5
/**
@@ -21,5 +21,5 @@ import {makeObject_Primitives, print} from 'shared-runtime';
21
*/
22
function NonReactiveDepInEffect() {
23
const obj = makeObject_Primitives();
24
- useEffect(() => print(obj));
24
+ useEffect(() => print(obj), AUTODEPS);
25
}
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/nonreactive-effect-event.expect.md
+3
-3
@@ -3,7 +3,7 @@
3
4
```javascript
5
// @inferEffectDependencies
6
-import {useEffect, useEffectEvent} from 'react';
6
+import {useEffect, useEffectEvent, AUTODEPS} from 'react';
7
import {print} from 'shared-runtime';
8
9
/**
@@ -11,7 +11,7 @@ import {print} from 'shared-runtime';
11
*/
12
function NonReactiveEffectEvent() {
13
const fn = useEffectEvent(() => print('hello world'));
14
- useEffect(() => fn());
14
+ useEffect(() => fn(), AUTODEPS);
15
}
16
17
```
@@ -20,7 +20,7 @@ function NonReactiveEffectEvent() {
20
21
```javascript
22
import { c as _c } from "react/compiler-runtime"; // @inferEffectDependencies
23
-import { useEffect, useEffectEvent } from "react";
23
+import { useEffect, useEffectEvent, AUTODEPS } from "react";
24
import { print } from "shared-runtime";
25
26
/**
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/nonreactive-effect-event.js
+2
-2
@@ -1,5 +1,5 @@
1
// @inferEffectDependencies
2
-import {useEffect, useEffectEvent} from 'react';
2
+import {useEffect, useEffectEvent, AUTODEPS} from 'react';
3
import {print} from 'shared-runtime';
4
5
/**
@@ -7,5 +7,5 @@ import {print} from 'shared-runtime';
7
*/
8
function NonReactiveEffectEvent() {
9
const fn = useEffectEvent(() => print('hello world'));
10
- useEffect(() => fn());
10
+ useEffect(() => fn(), AUTODEPS);
11
}
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/nonreactive-ref-helper.expect.md
+3
-3
@@ -3,7 +3,7 @@
3
4
```javascript
5
// @inferEffectDependencies
6
-import {useEffect} from 'react';
6
+import {useEffect, AUTODEPS} from 'react';
7
import {print} from 'shared-runtime';
8
9
/**
@@ -19,7 +19,7 @@ function RefsInEffects() {
19
useEffect(() => {
20
print(ref.current);
21
print(wrapped.foo.current);
22
- });
22
+ }, AUTODEPS);
23
}
24
25
function useRefHelper() {
@@ -36,7 +36,7 @@ function useDeeperRefHelper() {
36
37
```javascript
38
import { c as _c } from "react/compiler-runtime"; // @inferEffectDependencies
39
-import { useEffect } from "react";
39
+import { useEffect, AUTODEPS } from "react";
40
import { print } from "shared-runtime";
41
42
/**
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/nonreactive-ref-helper.js
+2
-2
@@ -1,5 +1,5 @@
1
// @inferEffectDependencies
2
-import {useEffect} from 'react';
2
+import {useEffect, AUTODEPS} from 'react';
3
import {print} from 'shared-runtime';
4
5
/**
@@ -15,7 +15,7 @@ function RefsInEffects() {
15
useEffect(() => {
16
print(ref.current);
17
print(wrapped.foo.current);
18
- });
18
+ }, AUTODEPS);
19
}
20
21
function useRefHelper() {
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/nonreactive-ref.expect.md
+3
-3
@@ -3,7 +3,7 @@
3
4
```javascript
5
// @inferEffectDependencies
6
-import {useEffect, useRef} from 'react';
6
+import {useEffect, useRef, AUTODEPS} from 'react';
7
import {print} from 'shared-runtime';
8
9
/**
@@ -14,7 +14,7 @@ import {print} from 'shared-runtime';
14
*/
15
function NonReactiveRefInEffect() {
16
const ref = useRef('initial value');
17
- useEffect(() => print(ref.current));
17
+ useEffect(() => print(ref.current), AUTODEPS);
18
}
19
20
```
@@ -23,7 +23,7 @@ function NonReactiveRefInEffect() {
23
24
```javascript
25
import { c as _c } from "react/compiler-runtime"; // @inferEffectDependencies
26
-import { useEffect, useRef } from "react";
26
+import { useEffect, useRef, AUTODEPS } from "react";
27
import { print } from "shared-runtime";
28
29
/**
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/nonreactive-ref.js
+2
-2
@@ -1,5 +1,5 @@
1
// @inferEffectDependencies
2
-import {useEffect, useRef} from 'react';
2
+import {useEffect, useRef, AUTODEPS} from 'react';
3
import {print} from 'shared-runtime';
4
5
/**
@@ -10,5 +10,5 @@ import {print} from 'shared-runtime';
10
*/
11
function NonReactiveRefInEffect() {
12
const ref = useRef('initial value');
13
- useEffect(() => print(ref.current));
13
+ useEffect(() => print(ref.current), AUTODEPS);
14
}
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/nonreactive-setState.expect.md
+3
-3
@@ -3,7 +3,7 @@
3
4
```javascript
5
// @inferEffectDependencies
6
-import {useEffect, useState} from 'react';
6
+import {useEffect, useState, AUTODEPS} from 'react';
7
import {print} from 'shared-runtime';
8
9
/**
@@ -14,7 +14,7 @@ import {print} from 'shared-runtime';
14
*/
15
function NonReactiveSetStateInEffect() {
16
const [_, setState] = useState('initial value');
17
- useEffect(() => print(setState));
17
+ useEffect(() => print(setState), AUTODEPS);
18
}
19
20
```
@@ -23,7 +23,7 @@ function NonReactiveSetStateInEffect() {
23
24
```javascript
25
import { c as _c } from "react/compiler-runtime"; // @inferEffectDependencies
26
-import { useEffect, useState } from "react";
26
+import { useEffect, useState, AUTODEPS } from "react";
27
import { print } from "shared-runtime";
28
29
/**
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/nonreactive-setState.js
+2
-2
@@ -1,5 +1,5 @@
1
// @inferEffectDependencies
2
-import {useEffect, useState} from 'react';
2
+import {useEffect, useState, AUTODEPS} from 'react';
3
import {print} from 'shared-runtime';
4
5
/**
@@ -10,5 +10,5 @@ import {print} from 'shared-runtime';
10
*/
11
function NonReactiveSetStateInEffect() {
12
const [_, setState] = useState('initial value');
13
- useEffect(() => print(setState));
13
+ useEffect(() => print(setState), AUTODEPS);
14
}
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/outlined-function.expect.md
+3
-3
@@ -3,7 +3,7 @@
3
4
```javascript
5
// @inferEffectDependencies
6
-import {useEffect} from 'react';
6
+import {useEffect, AUTODEPS} from 'react';
7
import {print} from 'shared-runtime';
8
/**
9
* This compiled output is technically incorrect but this is currently the same
@@ -14,7 +14,7 @@ import {print} from 'shared-runtime';
14
* before OutlineFunctions
15
*/
16
function OutlinedFunctionInEffect() {
17
- useEffect(() => print('hello world!'));
17
+ useEffect(() => print('hello world!'), AUTODEPS);
18
}
19
20
```
@@ -23,7 +23,7 @@ function OutlinedFunctionInEffect() {
23
24
```javascript
25
// @inferEffectDependencies
26
-import { useEffect } from "react";
26
+import { useEffect, AUTODEPS } from "react";
27
import { print } from "shared-runtime";
28
/**
29
* This compiled output is technically incorrect but this is currently the same
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/outlined-function.js
+2
-2
@@ -1,5 +1,5 @@
1
// @inferEffectDependencies
2
-import {useEffect} from 'react';
2
+import {useEffect, AUTODEPS} from 'react';
3
import {print} from 'shared-runtime';
4
/**
5
* This compiled output is technically incorrect but this is currently the same
@@ -10,5 +10,5 @@ import {print} from 'shared-runtime';
10
* before OutlineFunctions
11
*/
12
function OutlinedFunctionInEffect() {
13
- useEffect(() => print('hello world!'));
13
+ useEffect(() => print('hello world!'), AUTODEPS);
14
}
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/pruned-nonreactive-obj.expect.md
+3
-3
@@ -4,7 +4,7 @@
4
```javascript
5
// @inferEffectDependencies
6
import {useIdentity, mutate, makeObject} from 'shared-runtime';
7
-import {useEffect} from 'react';
7
+import {useEffect, AUTODEPS} from 'react';
8
9
/**
10
* When a semantically non-reactive value has a pruned scope (i.e. the object
@@ -48,7 +48,7 @@ function PrunedNonReactive() {
48
useIdentity(null);
49
mutate(obj);
50
51
- useEffect(() => print(obj.value));
51
+ useEffect(() => print(obj.value), AUTODEPS);
52
}
53
54
```
@@ -58,7 +58,7 @@ function PrunedNonReactive() {
58
```javascript
59
import { c as _c } from "react/compiler-runtime"; // @inferEffectDependencies
60
import { useIdentity, mutate, makeObject } from "shared-runtime";
61
-import { useEffect } from "react";
61
+import { useEffect, AUTODEPS } from "react";
62
63
/**
64
* When a semantically non-reactive value has a pruned scope (i.e. the object
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/pruned-nonreactive-obj.js
+2
-2
@@ -1,6 +1,6 @@
1
// @inferEffectDependencies
2
import {useIdentity, mutate, makeObject} from 'shared-runtime';
3
-import {useEffect} from 'react';
3
+import {useEffect, AUTODEPS} from 'react';
4
5
/**
6
* When a semantically non-reactive value has a pruned scope (i.e. the object
@@ -44,5 +44,5 @@ function PrunedNonReactive() {
44
useIdentity(null);
45
mutate(obj);
46
47
- useEffect(() => print(obj.value));
47
+ useEffect(() => print(obj.value), AUTODEPS);
48
}
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/reactive-memberexpr-merge.expect.md
+3
-3
@@ -3,12 +3,12 @@
3
4
```javascript
5
// @inferEffectDependencies
6
-import {useEffect} from 'react';
6
+import {useEffect, AUTODEPS} from 'react';
7
import {print} from 'shared-runtime';
8
9
function ReactiveMemberExprMerge({propVal}) {
10
const obj = {a: {b: propVal}};
11
- useEffect(() => print(obj.a, obj.a.b));
11
+ useEffect(() => print(obj.a, obj.a.b), AUTODEPS);
12
}
13
14
```
@@ -17,7 +17,7 @@ function ReactiveMemberExprMerge({propVal}) {
17
18
```javascript
19
import { c as _c } from "react/compiler-runtime"; // @inferEffectDependencies
20
-import { useEffect } from "react";
20
+import { useEffect, AUTODEPS } from "react";
21
import { print } from "shared-runtime";
22
23
function ReactiveMemberExprMerge(t0) {
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/reactive-memberexpr-merge.js
+2
-2
@@ -1,8 +1,8 @@
1
// @inferEffectDependencies
2
-import {useEffect} from 'react';
2
+import {useEffect, AUTODEPS} from 'react';
3
import {print} from 'shared-runtime';
4
5
function ReactiveMemberExprMerge({propVal}) {
6
const obj = {a: {b: propVal}};
7
- useEffect(() => print(obj.a, obj.a.b));
7
+ useEffect(() => print(obj.a, obj.a.b), AUTODEPS);
8
}
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/reactive-memberexpr.expect.md
+3
-3
@@ -3,12 +3,12 @@
3
4
```javascript
5
// @inferEffectDependencies
6
-import {useEffect} from 'react';
6
+import {useEffect, AUTODEPS} from 'react';
7
import {print} from 'shared-runtime';
8
9
function ReactiveMemberExpr({propVal}) {
10
const obj = {a: {b: propVal}};
11
- useEffect(() => print(obj.a.b));
11
+ useEffect(() => print(obj.a.b), AUTODEPS);
12
}
13
14
```
@@ -17,7 +17,7 @@ function ReactiveMemberExpr({propVal}) {
17
18
```javascript
19
import { c as _c } from "react/compiler-runtime"; // @inferEffectDependencies
20
-import { useEffect } from "react";
20
+import { useEffect, AUTODEPS } from "react";
21
import { print } from "shared-runtime";
22
23
function ReactiveMemberExpr(t0) {
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/reactive-memberexpr.js
+2
-2
@@ -1,8 +1,8 @@
1
// @inferEffectDependencies
2
-import {useEffect} from 'react';
2
+import {useEffect, AUTODEPS} from 'react';
3
import {print} from 'shared-runtime';
4
5
function ReactiveMemberExpr({propVal}) {
6
const obj = {a: {b: propVal}};
7
- useEffect(() => print(obj.a.b));
7
+ useEffect(() => print(obj.a.b), AUTODEPS);
8
}
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/reactive-optional-chain-complex.expect.md
+5
-4
@@ -3,15 +3,16 @@
3
4
```javascript
5
// @inferEffectDependencies
6
-import {useEffect} from 'react';
6
+import {useEffect, AUTODEPS} from 'react';
7
import {print, shallowCopy} from 'shared-runtime';
8
9
function ReactiveMemberExpr({cond, propVal}) {
10
const obj = {a: cond ? {b: propVal} : null, c: null};
11
const other = shallowCopy({a: {b: {c: {d: {e: {f: propVal + 1}}}}}});
12
const primitive = shallowCopy(propVal);
13
- useEffect(() =>
14
- print(obj.a?.b, other?.a?.b?.c?.d?.e.f, primitive.a?.b.c?.d?.e.f)
13
+ useEffect(
14
+ () => print(obj.a?.b, other?.a?.b?.c?.d?.e.f, primitive.a?.b.c?.d?.e.f),
15
+ AUTODEPS
16
);
17
}
18
@@ -26,7 +27,7 @@ export const FIXTURE_ENTRYPOINT = {
27
28
```javascript
29
import { c as _c } from "react/compiler-runtime"; // @inferEffectDependencies
29
-import { useEffect } from "react";
30
+import { useEffect, AUTODEPS } from "react";
31
import { print, shallowCopy } from "shared-runtime";
32
33
function ReactiveMemberExpr(t0) {
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/reactive-optional-chain-complex.js
+4
-3
@@ -1,13 +1,14 @@
1
// @inferEffectDependencies
2
-import {useEffect} from 'react';
2
+import {useEffect, AUTODEPS} from 'react';
3
import {print, shallowCopy} from 'shared-runtime';
4
5
function ReactiveMemberExpr({cond, propVal}) {
6
const obj = {a: cond ? {b: propVal} : null, c: null};
7
const other = shallowCopy({a: {b: {c: {d: {e: {f: propVal + 1}}}}}});
8
const primitive = shallowCopy(propVal);
9
- useEffect(() =>
10
- print(obj.a?.b, other?.a?.b?.c?.d?.e.f, primitive.a?.b.c?.d?.e.f)
9
+ useEffect(
10
+ () => print(obj.a?.b, other?.a?.b?.c?.d?.e.f, primitive.a?.b.c?.d?.e.f),
11
+ AUTODEPS
12
);
13
}
14
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/reactive-optional-chain.expect.md
+4
-4
@@ -3,13 +3,13 @@
3
4
```javascript
5
// @inferEffectDependencies
6
-import {useEffect} from 'react';
6
+import {useEffect, AUTODEPS} from 'react';
7
import {print} from 'shared-runtime';
8
9
function ReactiveMemberExpr({cond, propVal}) {
10
const obj = {a: cond ? {b: propVal} : null, c: null};
11
- useEffect(() => print(obj.a?.b));
12
- useEffect(() => print(obj.c?.d));
11
+ useEffect(() => print(obj.a?.b), AUTODEPS);
12
+ useEffect(() => print(obj.c?.d), AUTODEPS);
13
}
14
15
export const FIXTURE_ENTRYPOINT = {
@@ -23,7 +23,7 @@ export const FIXTURE_ENTRYPOINT = {
23
24
```javascript
25
import { c as _c } from "react/compiler-runtime"; // @inferEffectDependencies
26
-import { useEffect } from "react";
26
+import { useEffect, AUTODEPS } from "react";
27
import { print } from "shared-runtime";
28
29
function ReactiveMemberExpr(t0) {
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/reactive-optional-chain.js
+3
-3
@@ -1,11 +1,11 @@
1
// @inferEffectDependencies
2
-import {useEffect} from 'react';
2
+import {useEffect, AUTODEPS} from 'react';
3
import {print} from 'shared-runtime';
4
5
function ReactiveMemberExpr({cond, propVal}) {
6
const obj = {a: cond ? {b: propVal} : null, c: null};
7
- useEffect(() => print(obj.a?.b));
8
- useEffect(() => print(obj.c?.d));
7
+ useEffect(() => print(obj.a?.b), AUTODEPS);
8
+ useEffect(() => print(obj.c?.d), AUTODEPS);
9
}
10
11
export const FIXTURE_ENTRYPOINT = {
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/reactive-ref-ternary.expect.md
+3
-3
@@ -3,7 +3,7 @@
3
4
```javascript
5
// @inferEffectDependencies
6
-import {useRef, useEffect} from 'react';
6
+import {useRef, useEffect, AUTODEPS} from 'react';
7
import {print, mutate} from 'shared-runtime';
8
9
function Component({cond}) {
@@ -14,7 +14,7 @@ function Component({cond}) {
14
useEffect(() => {
15
mutate(derived.current);
16
print(derived.current);
17
- });
17
+ }, AUTODEPS);
18
return arr;
19
}
20
@@ -24,7 +24,7 @@ function Component({cond}) {
24
25
```javascript
26
import { c as _c } from "react/compiler-runtime"; // @inferEffectDependencies
27
-import { useRef, useEffect } from "react";
27
+import { useRef, useEffect, AUTODEPS } from "react";
28
import { print, mutate } from "shared-runtime";
29
30
function Component(t0) {
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/reactive-ref-ternary.js
+2
-2
@@ -1,5 +1,5 @@
1
// @inferEffectDependencies
2
-import {useRef, useEffect} from 'react';
2
+import {useRef, useEffect, AUTODEPS} from 'react';
3
import {print, mutate} from 'shared-runtime';
4
5
function Component({cond}) {
@@ -10,6 +10,6 @@ function Component({cond}) {
10
useEffect(() => {
11
mutate(derived.current);
12
print(derived.current);
13
- });
13
+ }, AUTODEPS);
14
return arr;
15
}
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/reactive-ref.expect.md
+3
-3
@@ -3,7 +3,7 @@
3
4
```javascript
5
// @inferEffectDependencies
6
-import {useEffect, useRef} from 'react';
6
+import {useEffect, useRef, AUTODEPS} from 'react';
7
import {print} from 'shared-runtime';
8
9
/*
@@ -18,7 +18,7 @@ function ReactiveRefInEffect(props) {
18
} else {
19
ref = ref2;
20
}
21
- useEffect(() => print(ref));
21
+ useEffect(() => print(ref), AUTODEPS);
22
}
23
24
```
@@ -27,7 +27,7 @@ function ReactiveRefInEffect(props) {
27
28
```javascript
29
import { c as _c } from "react/compiler-runtime"; // @inferEffectDependencies
30
-import { useEffect, useRef } from "react";
30
+import { useEffect, useRef, AUTODEPS } from "react";
31
import { print } from "shared-runtime";
32
33
/*
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/reactive-ref.js
+2
-2
@@ -1,5 +1,5 @@
1
// @inferEffectDependencies
2
-import {useEffect, useRef} from 'react';
2
+import {useEffect, useRef, AUTODEPS} from 'react';
3
import {print} from 'shared-runtime';
4
5
/*
@@ -14,5 +14,5 @@ function ReactiveRefInEffect(props) {
14
} else {
15
ref = ref2;
16
}
17
- useEffect(() => print(ref));
17
+ useEffect(() => print(ref), AUTODEPS);
18
}
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/reactive-setState.expect.md
+3
-3
@@ -3,7 +3,7 @@
3
4
```javascript
5
// @inferEffectDependencies
6
-import {useEffect, useState} from 'react';
6
+import {useEffect, useState, AUTODEPS} from 'react';
7
import {print} from 'shared-runtime';
8
9
/*
@@ -18,7 +18,7 @@ function ReactiveRefInEffect(props) {
18
} else {
19
setState = setState2;
20
}
21
- useEffect(() => print(setState));
21
+ useEffect(() => print(setState), AUTODEPS);
22
}
23
24
```
@@ -27,7 +27,7 @@ function ReactiveRefInEffect(props) {
27
28
```javascript
29
import { c as _c } from "react/compiler-runtime"; // @inferEffectDependencies
30
-import { useEffect, useState } from "react";
30
+import { useEffect, useState, AUTODEPS } from "react";
31
import { print } from "shared-runtime";
32
33
/*
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/reactive-setState.js
+2
-2
@@ -1,5 +1,5 @@
1
// @inferEffectDependencies
2
-import {useEffect, useState} from 'react';
2
+import {useEffect, useState, AUTODEPS} from 'react';
3
import {print} from 'shared-runtime';
4
5
/*
@@ -14,5 +14,5 @@ function ReactiveRefInEffect(props) {
14
} else {
15
setState = setState2;
16
}
17
- useEffect(() => print(setState));
17
+ useEffect(() => print(setState), AUTODEPS);
18
}
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/reactive-variable.expect.md
+3
-3
@@ -3,12 +3,12 @@
3
4
```javascript
5
// @inferEffectDependencies
6
-import {useEffect} from 'react';
6
+import {useEffect, AUTODEPS} from 'react';
7
import {print} from 'shared-runtime';
8
9
function ReactiveVariable({propVal}) {
10
const arr = [propVal];
11
- useEffect(() => print(arr));
11
+ useEffect(() => print(arr), AUTODEPS);
12
}
13
14
```
@@ -17,7 +17,7 @@ function ReactiveVariable({propVal}) {
17
18
```javascript
19
import { c as _c } from "react/compiler-runtime"; // @inferEffectDependencies
20
-import { useEffect } from "react";
20
+import { useEffect, AUTODEPS } from "react";
21
import { print } from "shared-runtime";
22
23
function ReactiveVariable(t0) {
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/reactive-variable.js
+2
-2
@@ -1,8 +1,8 @@
1
// @inferEffectDependencies
2
-import {useEffect} from 'react';
2
+import {useEffect, AUTODEPS} from 'react';
3
import {print} from 'shared-runtime';
4
5
function ReactiveVariable({propVal}) {
6
const arr = [propVal];
7
- useEffect(() => print(arr));
7
+ useEffect(() => print(arr), AUTODEPS);
8
}
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/mutate-after-useeffect-optional-chain.expect.md
+6
-6
@@ -3,14 +3,14 @@
3
4
```javascript
5
// @inferEffectDependencies @panicThreshold:"none" @loggerTestOnly @enableNewMutationAliasingModel
6
-import {useEffect} from 'react';
6
+import {useEffect, AUTODEPS} from 'react';
7
import {print} from 'shared-runtime';
8
9
function Component({foo}) {
10
const arr = [];
11
// Taking either arr[0].value or arr as a dependency is reasonable
12
// as long as developers know what to expect.
13
- useEffect(() => print(arr[0]?.value));
13
+ useEffect(() => print(arr[0]?.value), AUTODEPS);
14
arr.push({value: foo});
15
return arr;
16
}
@@ -26,7 +26,7 @@ export const FIXTURE_ENTRYPOINT = {
26
27
```javascript
28
// @inferEffectDependencies @panicThreshold:"none" @loggerTestOnly @enableNewMutationAliasingModel
29
-import { useEffect } from "react";
29
+import { useEffect, AUTODEPS } from "react";
30
import { print } from "shared-runtime";
31
32
function Component(t0) {
@@ -48,9 +48,9 @@ export const FIXTURE_ENTRYPOINT = {
48
## Logs
49
50
```
51
-{"kind":"CompileError","fnLoc":{"start":{"line":5,"column":0,"index":171},"end":{"line":12,"column":1,"index":416},"filename":"mutate-after-useeffect-optional-chain.ts"},"detail":{"reason":"Updating a value used previously in an effect function or as an effect dependency is not allowed. Consider moving the mutation before calling useEffect()","description":null,"severity":"InvalidReact","suggestions":null,"loc":{"start":{"line":10,"column":2,"index":377},"end":{"line":10,"column":5,"index":380},"filename":"mutate-after-useeffect-optional-chain.ts","identifierName":"arr"}}}
52
-{"kind":"AutoDepsDecorations","fnLoc":{"start":{"line":9,"column":2,"index":336},"end":{"line":9,"column":39,"index":373},"filename":"mutate-after-useeffect-optional-chain.ts"},"decorations":[{"start":{"line":9,"column":24,"index":358},"end":{"line":9,"column":27,"index":361},"filename":"mutate-after-useeffect-optional-chain.ts","identifierName":"arr"}]}
53
-{"kind":"CompileSuccess","fnLoc":{"start":{"line":5,"column":0,"index":171},"end":{"line":12,"column":1,"index":416},"filename":"mutate-after-useeffect-optional-chain.ts"},"fnName":"Component","memoSlots":0,"memoBlocks":0,"memoValues":0,"prunedMemoBlocks":0,"prunedMemoValues":0}
51
+{"kind":"CompileError","fnLoc":{"start":{"line":5,"column":0,"index":181},"end":{"line":12,"column":1,"index":436},"filename":"mutate-after-useeffect-optional-chain.ts"},"detail":{"reason":"Updating a value used previously in an effect function or as an effect dependency is not allowed. Consider moving the mutation before calling useEffect()","description":null,"severity":"InvalidReact","suggestions":null,"loc":{"start":{"line":10,"column":2,"index":397},"end":{"line":10,"column":5,"index":400},"filename":"mutate-after-useeffect-optional-chain.ts","identifierName":"arr"}}}
52
+{"kind":"AutoDepsDecorations","fnLoc":{"start":{"line":9,"column":2,"index":346},"end":{"line":9,"column":49,"index":393},"filename":"mutate-after-useeffect-optional-chain.ts"},"decorations":[{"start":{"line":9,"column":24,"index":368},"end":{"line":9,"column":27,"index":371},"filename":"mutate-after-useeffect-optional-chain.ts","identifierName":"arr"}]}
53
+{"kind":"CompileSuccess","fnLoc":{"start":{"line":5,"column":0,"index":181},"end":{"line":12,"column":1,"index":436},"filename":"mutate-after-useeffect-optional-chain.ts"},"fnName":"Component","memoSlots":0,"memoBlocks":0,"memoValues":0,"prunedMemoBlocks":0,"prunedMemoValues":0}
54
```
55
56
### Eval output
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/mutate-after-useeffect-optional-chain.js
+2
-2
@@ -1,12 +1,12 @@
1
// @inferEffectDependencies @panicThreshold:"none" @loggerTestOnly @enableNewMutationAliasingModel
2
-import {useEffect} from 'react';
2
+import {useEffect, AUTODEPS} from 'react';
3
import {print} from 'shared-runtime';
4
5
function Component({foo}) {
6
const arr = [];
7
// Taking either arr[0].value or arr as a dependency is reasonable
8
// as long as developers know what to expect.
9
- useEffect(() => print(arr[0]?.value));
9
+ useEffect(() => print(arr[0]?.value), AUTODEPS);
10
arr.push({value: foo});
11
return arr;
12
}
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/mutate-after-useeffect-ref-access.expect.md
+6
-6
@@ -4,12 +4,12 @@
4
```javascript
5
// @inferEffectDependencies @panicThreshold:"none" @loggerTestOnly @enableNewMutationAliasingModel
6
7
-import {useEffect, useRef} from 'react';
7
+import {useEffect, useRef, AUTODEPS} from 'react';
8
import {print} from 'shared-runtime';
9
10
function Component({arrRef}) {
11
// Avoid taking arr.current as a dependency
12
- useEffect(() => print(arrRef.current));
12
+ useEffect(() => print(arrRef.current), AUTODEPS);
13
arrRef.current.val = 2;
14
return arrRef;
15
}
@@ -26,7 +26,7 @@ export const FIXTURE_ENTRYPOINT = {
26
```javascript
27
// @inferEffectDependencies @panicThreshold:"none" @loggerTestOnly @enableNewMutationAliasingModel
28
29
-import { useEffect, useRef } from "react";
29
+import { useEffect, useRef, AUTODEPS } from "react";
30
import { print } from "shared-runtime";
31
32
function Component(t0) {
@@ -47,9 +47,9 @@ export const FIXTURE_ENTRYPOINT = {
47
## Logs
48
49
```
50
-{"kind":"CompileError","fnLoc":{"start":{"line":6,"column":0,"index":180},"end":{"line":11,"column":1,"index":343},"filename":"mutate-after-useeffect-ref-access.ts"},"detail":{"reason":"Mutating component props or hook arguments is not allowed. Consider using a local variable instead","description":null,"severity":"InvalidReact","suggestions":null,"loc":{"start":{"line":9,"column":2,"index":301},"end":{"line":9,"column":16,"index":315},"filename":"mutate-after-useeffect-ref-access.ts"}}}
51
-{"kind":"AutoDepsDecorations","fnLoc":{"start":{"line":8,"column":2,"index":259},"end":{"line":8,"column":40,"index":297},"filename":"mutate-after-useeffect-ref-access.ts"},"decorations":[{"start":{"line":8,"column":24,"index":281},"end":{"line":8,"column":30,"index":287},"filename":"mutate-after-useeffect-ref-access.ts","identifierName":"arrRef"}]}
52
-{"kind":"CompileSuccess","fnLoc":{"start":{"line":6,"column":0,"index":180},"end":{"line":11,"column":1,"index":343},"filename":"mutate-after-useeffect-ref-access.ts"},"fnName":"Component","memoSlots":0,"memoBlocks":0,"memoValues":0,"prunedMemoBlocks":0,"prunedMemoValues":0}
50
+{"kind":"CompileError","fnLoc":{"start":{"line":6,"column":0,"index":190},"end":{"line":11,"column":1,"index":363},"filename":"mutate-after-useeffect-ref-access.ts"},"detail":{"reason":"Mutating component props or hook arguments is not allowed. Consider using a local variable instead","description":null,"severity":"InvalidReact","suggestions":null,"loc":{"start":{"line":9,"column":2,"index":321},"end":{"line":9,"column":16,"index":335},"filename":"mutate-after-useeffect-ref-access.ts"}}}
51
+{"kind":"AutoDepsDecorations","fnLoc":{"start":{"line":8,"column":2,"index":269},"end":{"line":8,"column":50,"index":317},"filename":"mutate-after-useeffect-ref-access.ts"},"decorations":[{"start":{"line":8,"column":24,"index":291},"end":{"line":8,"column":30,"index":297},"filename":"mutate-after-useeffect-ref-access.ts","identifierName":"arrRef"}]}
52
+{"kind":"CompileSuccess","fnLoc":{"start":{"line":6,"column":0,"index":190},"end":{"line":11,"column":1,"index":363},"filename":"mutate-after-useeffect-ref-access.ts"},"fnName":"Component","memoSlots":0,"memoBlocks":0,"memoValues":0,"prunedMemoBlocks":0,"prunedMemoValues":0}
53
```
54
55
### Eval output
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/mutate-after-useeffect-ref-access.js
+2
-2
@@ -1,11 +1,11 @@
1
// @inferEffectDependencies @panicThreshold:"none" @loggerTestOnly @enableNewMutationAliasingModel
2
3
-import {useEffect, useRef} from 'react';
3
+import {useEffect, useRef, AUTODEPS} from 'react';
4
import {print} from 'shared-runtime';
5
6
function Component({arrRef}) {
7
// Avoid taking arr.current as a dependency
8
- useEffect(() => print(arrRef.current));
8
+ useEffect(() => print(arrRef.current), AUTODEPS);
9
arrRef.current.val = 2;
10
return arrRef;
11
}
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/mutate-after-useeffect.expect.md
+6
-6
@@ -3,13 +3,13 @@
3
4
```javascript
5
// @inferEffectDependencies @panicThreshold:"none" @loggerTestOnly @enableNewMutationAliasingModel
6
-import {useEffect} from 'react';
6
+import {useEffect, AUTODEPS} from 'react';
7
8
function Component({foo}) {
9
const arr = [];
10
useEffect(() => {
11
arr.push(foo);
12
- });
12
+ }, AUTODEPS);
13
arr.push(2);
14
return arr;
15
}
@@ -25,7 +25,7 @@ export const FIXTURE_ENTRYPOINT = {
25
26
```javascript
27
// @inferEffectDependencies @panicThreshold:"none" @loggerTestOnly @enableNewMutationAliasingModel
28
-import { useEffect } from "react";
28
+import { useEffect, AUTODEPS } from "react";
29
30
function Component(t0) {
31
const { foo } = t0;
@@ -47,9 +47,9 @@ export const FIXTURE_ENTRYPOINT = {
47
## Logs
48
49
```
50
-{"kind":"CompileError","fnLoc":{"start":{"line":4,"column":0,"index":133},"end":{"line":11,"column":1,"index":254},"filename":"mutate-after-useeffect.ts"},"detail":{"reason":"Updating a value used previously in an effect function or as an effect dependency is not allowed. Consider moving the mutation before calling useEffect()","description":null,"severity":"InvalidReact","suggestions":null,"loc":{"start":{"line":9,"column":2,"index":226},"end":{"line":9,"column":5,"index":229},"filename":"mutate-after-useeffect.ts","identifierName":"arr"}}}
51
-{"kind":"AutoDepsDecorations","fnLoc":{"start":{"line":6,"column":2,"index":181},"end":{"line":8,"column":4,"index":222},"filename":"mutate-after-useeffect.ts"},"decorations":[{"start":{"line":7,"column":4,"index":203},"end":{"line":7,"column":7,"index":206},"filename":"mutate-after-useeffect.ts","identifierName":"arr"},{"start":{"line":7,"column":4,"index":203},"end":{"line":7,"column":7,"index":206},"filename":"mutate-after-useeffect.ts","identifierName":"arr"},{"start":{"line":7,"column":13,"index":212},"end":{"line":7,"column":16,"index":215},"filename":"mutate-after-useeffect.ts","identifierName":"foo"}]}
52
-{"kind":"CompileSuccess","fnLoc":{"start":{"line":4,"column":0,"index":133},"end":{"line":11,"column":1,"index":254},"filename":"mutate-after-useeffect.ts"},"fnName":"Component","memoSlots":0,"memoBlocks":0,"memoValues":0,"prunedMemoBlocks":0,"prunedMemoValues":0}
50
+{"kind":"CompileError","fnLoc":{"start":{"line":4,"column":0,"index":143},"end":{"line":11,"column":1,"index":274},"filename":"mutate-after-useeffect.ts"},"detail":{"reason":"Updating a value used previously in an effect function or as an effect dependency is not allowed. Consider moving the mutation before calling useEffect()","description":null,"severity":"InvalidReact","suggestions":null,"loc":{"start":{"line":9,"column":2,"index":246},"end":{"line":9,"column":5,"index":249},"filename":"mutate-after-useeffect.ts","identifierName":"arr"}}}
51
+{"kind":"AutoDepsDecorations","fnLoc":{"start":{"line":6,"column":2,"index":191},"end":{"line":8,"column":14,"index":242},"filename":"mutate-after-useeffect.ts"},"decorations":[{"start":{"line":7,"column":4,"index":213},"end":{"line":7,"column":7,"index":216},"filename":"mutate-after-useeffect.ts","identifierName":"arr"},{"start":{"line":7,"column":4,"index":213},"end":{"line":7,"column":7,"index":216},"filename":"mutate-after-useeffect.ts","identifierName":"arr"},{"start":{"line":7,"column":13,"index":222},"end":{"line":7,"column":16,"index":225},"filename":"mutate-after-useeffect.ts","identifierName":"foo"}]}
52
+{"kind":"CompileSuccess","fnLoc":{"start":{"line":4,"column":0,"index":143},"end":{"line":11,"column":1,"index":274},"filename":"mutate-after-useeffect.ts"},"fnName":"Component","memoSlots":0,"memoBlocks":0,"memoValues":0,"prunedMemoBlocks":0,"prunedMemoValues":0}
53
```
54
55
### Eval output
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/mutate-after-useeffect.js
+2
-2
@@ -1,11 +1,11 @@
1
// @inferEffectDependencies @panicThreshold:"none" @loggerTestOnly @enableNewMutationAliasingModel
2
-import {useEffect} from 'react';
2
+import {useEffect, AUTODEPS} from 'react';
3
4
function Component({foo}) {
5
const arr = [];
6
useEffect(() => {
7
arr.push(foo);
8
- });
8
+ }, AUTODEPS);
9
arr.push(2);
10
return arr;
11
}
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/reactive-setState.expect.md
+3
-3
@@ -3,7 +3,7 @@
3
4
```javascript
5
// @inferEffectDependencies @enableNewMutationAliasingModel
6
-import {useEffect, useState} from 'react';
6
+import {useEffect, useState, AUTODEPS} from 'react';
7
import {print} from 'shared-runtime';
8
9
/*
@@ -18,7 +18,7 @@ function ReactiveRefInEffect(props) {
18
} else {
19
setState = setState2;
20
}
21
- useEffect(() => print(setState));
21
+ useEffect(() => print(setState), AUTODEPS);
22
}
23
24
```
@@ -27,7 +27,7 @@ function ReactiveRefInEffect(props) {
27
28
```javascript
29
import { c as _c } from "react/compiler-runtime"; // @inferEffectDependencies @enableNewMutationAliasingModel
30
-import { useEffect, useState } from "react";
30
+import { useEffect, useState, AUTODEPS } from "react";
31
import { print } from "shared-runtime";
32
33
/*
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/reactive-setState.js
+2
-2
@@ -1,5 +1,5 @@
1
// @inferEffectDependencies @enableNewMutationAliasingModel
2
-import {useEffect, useState} from 'react';
2
+import {useEffect, useState, AUTODEPS} from 'react';
3
import {print} from 'shared-runtime';
4
5
/*
@@ -14,5 +14,5 @@ function ReactiveRefInEffect(props) {
14
} else {
15
setState = setState2;
16
}
17
- useEffect(() => print(setState));
17
+ useEffect(() => print(setState), AUTODEPS);
18
}
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/retry-no-emit.expect.md
+10
-8
@@ -5,13 +5,14 @@
5
// @inferEffectDependencies @noEmit @panicThreshold:"none" @loggerTestOnly @enableNewMutationAliasingModel
6
import {print} from 'shared-runtime';
7
import useEffectWrapper from 'useEffectWrapper';
8
+import {AUTODEPS} from 'react';
9
10
function Foo({propVal}) {
11
const arr = [propVal];
11
- useEffectWrapper(() => print(arr));
12
+ useEffectWrapper(() => print(arr), AUTODEPS);
13
14
const arr2 = [];
14
- useEffectWrapper(() => arr2.push(propVal));
15
+ useEffectWrapper(() => arr2.push(propVal), AUTODEPS);
16
arr2.push(2);
17
return {arr, arr2};
18
}
@@ -30,13 +31,14 @@ export const FIXTURE_ENTRYPOINT = {
31
// @inferEffectDependencies @noEmit @panicThreshold:"none" @loggerTestOnly @enableNewMutationAliasingModel
32
import { print } from "shared-runtime";
33
import useEffectWrapper from "useEffectWrapper";
34
+import { AUTODEPS } from "react";
35
36
function Foo({ propVal }) {
37
const arr = [propVal];
36
- useEffectWrapper(() => print(arr));
38
+ useEffectWrapper(() => print(arr), AUTODEPS);
39
40
const arr2 = [];
39
- useEffectWrapper(() => arr2.push(propVal));
41
+ useEffectWrapper(() => arr2.push(propVal), AUTODEPS);
42
arr2.push(2);
43
return { arr, arr2 };
44
}
@@ -52,10 +54,10 @@ export const FIXTURE_ENTRYPOINT = {
54
## Logs
55
56
```
55
-{"kind":"CompileError","fnLoc":{"start":{"line":5,"column":0,"index":195},"end":{"line":13,"column":1,"index":389},"filename":"retry-no-emit.ts"},"detail":{"reason":"Updating a value previously passed as an argument to a hook is not allowed. Consider moving the mutation before calling the hook","description":null,"severity":"InvalidReact","suggestions":null,"loc":{"start":{"line":11,"column":2,"index":352},"end":{"line":11,"column":6,"index":356},"filename":"retry-no-emit.ts","identifierName":"arr2"}}}
56
-{"kind":"AutoDepsDecorations","fnLoc":{"start":{"line":7,"column":2,"index":248},"end":{"line":7,"column":36,"index":282},"filename":"retry-no-emit.ts"},"decorations":[{"start":{"line":7,"column":31,"index":277},"end":{"line":7,"column":34,"index":280},"filename":"retry-no-emit.ts","identifierName":"arr"}]}
57
-{"kind":"AutoDepsDecorations","fnLoc":{"start":{"line":10,"column":2,"index":306},"end":{"line":10,"column":44,"index":348},"filename":"retry-no-emit.ts"},"decorations":[{"start":{"line":10,"column":25,"index":329},"end":{"line":10,"column":29,"index":333},"filename":"retry-no-emit.ts","identifierName":"arr2"},{"start":{"line":10,"column":25,"index":329},"end":{"line":10,"column":29,"index":333},"filename":"retry-no-emit.ts","identifierName":"arr2"},{"start":{"line":10,"column":35,"index":339},"end":{"line":10,"column":42,"index":346},"filename":"retry-no-emit.ts","identifierName":"propVal"}]}
58
-{"kind":"CompileSuccess","fnLoc":{"start":{"line":5,"column":0,"index":195},"end":{"line":13,"column":1,"index":389},"filename":"retry-no-emit.ts"},"fnName":"Foo","memoSlots":0,"memoBlocks":0,"memoValues":0,"prunedMemoBlocks":0,"prunedMemoValues":0}
57
+{"kind":"CompileError","fnLoc":{"start":{"line":6,"column":0,"index":227},"end":{"line":14,"column":1,"index":441},"filename":"retry-no-emit.ts"},"detail":{"reason":"Updating a value previously passed as an argument to a hook is not allowed. Consider moving the mutation before calling the hook","description":null,"severity":"InvalidReact","suggestions":null,"loc":{"start":{"line":12,"column":2,"index":404},"end":{"line":12,"column":6,"index":408},"filename":"retry-no-emit.ts","identifierName":"arr2"}}}
58
+{"kind":"AutoDepsDecorations","fnLoc":{"start":{"line":8,"column":2,"index":280},"end":{"line":8,"column":46,"index":324},"filename":"retry-no-emit.ts"},"decorations":[{"start":{"line":8,"column":31,"index":309},"end":{"line":8,"column":34,"index":312},"filename":"retry-no-emit.ts","identifierName":"arr"}]}
59
+{"kind":"AutoDepsDecorations","fnLoc":{"start":{"line":11,"column":2,"index":348},"end":{"line":11,"column":54,"index":400},"filename":"retry-no-emit.ts"},"decorations":[{"start":{"line":11,"column":25,"index":371},"end":{"line":11,"column":29,"index":375},"filename":"retry-no-emit.ts","identifierName":"arr2"},{"start":{"line":11,"column":25,"index":371},"end":{"line":11,"column":29,"index":375},"filename":"retry-no-emit.ts","identifierName":"arr2"},{"start":{"line":11,"column":35,"index":381},"end":{"line":11,"column":42,"index":388},"filename":"retry-no-emit.ts","identifierName":"propVal"}]}
60
+{"kind":"CompileSuccess","fnLoc":{"start":{"line":6,"column":0,"index":227},"end":{"line":14,"column":1,"index":441},"filename":"retry-no-emit.ts"},"fnName":"Foo","memoSlots":0,"memoBlocks":0,"memoValues":0,"prunedMemoBlocks":0,"prunedMemoValues":0}
61
```
62
63
### Eval output
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/retry-no-emit.js
+3
-2
@@ -1,13 +1,14 @@
1
// @inferEffectDependencies @noEmit @panicThreshold:"none" @loggerTestOnly @enableNewMutationAliasingModel
2
import {print} from 'shared-runtime';
3
import useEffectWrapper from 'useEffectWrapper';
4
+import {AUTODEPS} from 'react';
5
6
function Foo({propVal}) {
7
const arr = [propVal];
7
- useEffectWrapper(() => print(arr));
8
+ useEffectWrapper(() => print(arr), AUTODEPS);
9
10
const arr2 = [];
10
- useEffectWrapper(() => arr2.push(propVal));
11
+ useEffectWrapper(() => arr2.push(propVal), AUTODEPS);
12
arr2.push(2);
13
return {arr, arr2};
14
}
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/transform-fire/bailout-retry/infer-deps-on-retry.expect.md
+9
-5
@@ -3,7 +3,7 @@
3
4
```javascript
5
// @inferEffectDependencies @panicThreshold:"none"
6
-import {useRef} from 'react';
6
+import {useRef, AUTODEPS} from 'react';
7
import {useSpecialEffect} from 'shared-runtime';
8
9
/**
@@ -14,9 +14,13 @@ import {useSpecialEffect} from 'shared-runtime';
14
function useFoo({cond}) {
15
const ref = useRef();
16
const derived = cond ? ref.current : makeObject();
17
- useSpecialEffect(() => {
18
- log(derived);
19
- }, [derived]);
17
+ useSpecialEffect(
18
+ () => {
19
+ log(derived);
20
+ },
21
+ [derived],
22
+ AUTODEPS
23
+ );
24
return ref;
25
}
26
@@ -26,7 +30,7 @@ function useFoo({cond}) {
30
31
```javascript
32
// @inferEffectDependencies @panicThreshold:"none"
29
-import { useRef } from "react";
33
+import { useRef, AUTODEPS } from "react";
34
import { useSpecialEffect } from "shared-runtime";
35
36
/**
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/transform-fire/bailout-retry/infer-deps-on-retry.js
+8
-4
@@ -1,5 +1,5 @@
1
// @inferEffectDependencies @panicThreshold:"none"
2
-import {useRef} from 'react';
2
+import {useRef, AUTODEPS} from 'react';
3
import {useSpecialEffect} from 'shared-runtime';
4
5
/**
@@ -10,8 +10,12 @@ import {useSpecialEffect} from 'shared-runtime';
10
function useFoo({cond}) {
11
const ref = useRef();
12
const derived = cond ? ref.current : makeObject();
13
- useSpecialEffect(() => {
14
- log(derived);
15
- }, [derived]);
13
+ useSpecialEffect(
14
+ () => {
15
+ log(derived);
16
+ },
17
+ [derived],
18
+ AUTODEPS
19
+ );
20
return ref;
21
}
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/transform-fire/fire-and-autodeps.expect.md
deleted
-59
@@ -1,59 +0,0 @@
1
-
2
-## Input
3
-
4
-```javascript
5
-// @enableFire @inferEffectDependencies
6
-import {fire, useEffect} from 'react';
7
-
8
-function Component(props) {
9
- const foo = arg => {
10
- console.log(arg, props.bar);
11
- };
12
- useEffect(() => {
13
- fire(foo(props));
14
- });
15
-
16
- return null;
17
-}
18
-
19
-```
20
-
21
-## Code
22
-
23
-```javascript
24
-import { c as _c, useFire } from "react/compiler-runtime"; // @enableFire @inferEffectDependencies
25
-import { fire, useEffect } from "react";
26
-
27
-function Component(props) {
28
- const $ = _c(5);
29
- let t0;
30
- if ($[0] !== props.bar) {
31
- t0 = (arg) => {
32
- console.log(arg, props.bar);
33
- };
34
- $[0] = props.bar;
35
- $[1] = t0;
36
- } else {
37
- t0 = $[1];
38
- }
39
- const foo = t0;
40
- const t1 = useFire(foo);
41
- let t2;
42
- if ($[2] !== props || $[3] !== t1) {
43
- t2 = () => {
44
- t1(props);
45
- };
46
- $[2] = props;
47
- $[3] = t1;
48
- $[4] = t2;
49
- } else {
50
- t2 = $[4];
51
- }
52
- useEffect(t2, [props]);
53
- return null;
54
-}
55
-
56
-```
57
-
58
-### Eval output
59
-(kind: exception) Fixture not implemented
\ No newline at end of file
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/transform-fire/fire-and-autodeps.js
deleted
-13
@@ -1,13 +0,0 @@
1
-// @enableFire @inferEffectDependencies
2
-import {fire, useEffect} from 'react';
3
-
4
-function Component(props) {
5
- const foo = arg => {
6
- console.log(arg, props.bar);
7
- };
8
- useEffect(() => {
9
- fire(foo(props));
10
- });
11
-
12
- return null;
13
-}