Change autodeps configuration (#33800)
Jordan Brown committed
Jul 21, 2025 at 13:04 UTC
074e92777c22a56269647d614fdae80bf6406485
28 files changed
+262
-112
compiler/packages/babel-plugin-react-compiler/src/Entrypoint/ValidateNoUntransformedReferences.ts
+39
-7
@@ -35,8 +35,41 @@ function throwInvalidReact(
35
});
36
CompilerError.throw(detail);
37
}
38
+
39
+function isAutodepsSigil(
40
+ arg: NodePath<t.ArgumentPlaceholder | t.SpreadElement | t.Expression>,
41
+): boolean {
42
+ // Check for AUTODEPS identifier imported from React
43
+ if (arg.isIdentifier() && arg.node.name === 'AUTODEPS') {
44
+ const binding = arg.scope.getBinding(arg.node.name);
45
+ if (binding && binding.path.isImportSpecifier()) {
46
+ const importSpecifier = binding.path.node as t.ImportSpecifier;
47
+ if (importSpecifier.imported.type === 'Identifier') {
48
+ return (importSpecifier.imported as t.Identifier).name === 'AUTODEPS';
49
+ }
50
+ }
51
+ return false;
52
+ }
53
+
54
+ // Check for React.AUTODEPS member expression
55
+ if (arg.isMemberExpression() && !arg.node.computed) {
56
+ const object = arg.get('object');
57
+ const property = arg.get('property');
58
+
59
+ if (
60
+ object.isIdentifier() &&
61
+ object.node.name === 'React' &&
62
+ property.isIdentifier() &&
63
+ property.node.name === 'AUTODEPS'
64
+ ) {
65
+ return true;
66
+ }
67
+ }
68
+
69
+ return false;
70
+}
71
function assertValidEffectImportReference(
39
- numArgs: number,
72
+ autodepsIndex: number,
73
paths: Array<NodePath<t.Node>>,
74
context: TraversalState,
75
): void {
@@ -49,11 +82,10 @@ function assertValidEffectImportReference(
82
maybeCalleeLoc != null &&
83
context.inferredEffectLocations.has(maybeCalleeLoc);
84
/**
52
- * Only error on untransformed references of the form `useMyEffect(...)`
53
- * or `moduleNamespace.useMyEffect(...)`, with matching argument counts.
54
- * TODO: do we also want a mode to also hard error on non-call references?
85
+ * Error on effect calls that still have AUTODEPS in their args
86
*/
56
- if (args.length === numArgs && !hasInferredEffect) {
87
+ const hasAutodepsArg = args.some(isAutodepsSigil);
88
+ if (hasAutodepsArg && !hasInferredEffect) {
89
const maybeErrorDiagnostic = matchCompilerDiagnostic(
90
path,
91
context.transformErrors,
@@ -128,12 +160,12 @@ export default function validateNoUntransformedReferences(
160
if (env.inferEffectDependencies) {
161
for (const {
162
function: {source, importSpecifierName},
131
- numRequiredArgs,
163
+ autodepsIndex,
164
} of env.inferEffectDependencies) {
165
const module = getOrInsertWith(moduleLoadChecks, source, () => new Map());
166
module.set(
167
importSpecifierName,
136
- assertValidEffectImportReference.bind(null, numRequiredArgs),
168
+ assertValidEffectImportReference.bind(null, autodepsIndex),
169
);
170
}
171
}
compiler/packages/babel-plugin-react-compiler/src/HIR/Environment.ts
+6
-8
@@ -265,21 +265,19 @@ export const EnvironmentConfigSchema = z.object({
265
* {
266
* module: 'react',
267
* imported: 'useEffect',
268
- * numRequiredArgs: 1,
268
+ * autodepsIndex: 1,
269
* },{
270
* module: 'MyExperimentalEffectHooks',
271
* imported: 'useExperimentalEffect',
272
- * numRequiredArgs: 2,
272
+ * autodepsIndex: 2,
273
* },
274
* ]
275
* would insert dependencies for calls of `useEffect` imported from `react` and calls of
276
* useExperimentalEffect` from `MyExperimentalEffectHooks`.
277
*
278
- * `numRequiredArgs` tells the compiler the amount of arguments required to append a dependency
279
- * array to the end of the call. With the configuration above, we'd insert dependencies for
280
- * `useEffect` if it is only given a single argument and it would be appended to the argument list.
281
- *
282
- * numRequiredArgs must always be greater than 0, otherwise there is no function to analyze for dependencies
278
+ * `autodepsIndex` tells the compiler which index we expect the AUTODEPS to appear in.
279
+ * With the configuration above, we'd insert dependencies for `useEffect` if it has two
280
+ * arguments, and the second is AUTODEPS.
281
*
282
* Still experimental.
283
*/
@@ -288,7 +286,7 @@ export const EnvironmentConfigSchema = z.object({
286
z.array(
287
z.object({
288
function: ExternalFunctionSchema,
291
- numRequiredArgs: z.number().min(1, 'numRequiredArgs must be > 0'),
289
+ autodepsIndex: z.number().min(1, 'autodepsIndex must be > 0'),
290
}),
291
),
292
)
compiler/packages/babel-plugin-react-compiler/src/Inference/InferEffectDependencies.ts
+8
-3
@@ -79,7 +79,7 @@ export function inferEffectDependencies(fn: HIRFunction): void {
79
);
80
moduleTargets.set(
81
effectTarget.function.importSpecifierName,
82
- effectTarget.numRequiredArgs,
82
+ effectTarget.autodepsIndex,
83
);
84
}
85
const autodepFnLoads = new Map<IdentifierId, number>();
@@ -177,9 +177,14 @@ export function inferEffectDependencies(fn: HIRFunction): void {
177
arg.identifier.type.kind === 'Object' &&
178
arg.identifier.type.shapeId === BuiltInAutodepsId,
179
);
180
+ const autodepsArgExpectedIndex = autodepFnLoads.get(
181
+ callee.identifier.id,
182
+ );
183
+
184
if (
181
- value.args.length > 1 &&
182
- autodepsArgIndex > 0 &&
185
+ value.args.length > 0 &&
186
+ autodepsArgExpectedIndex != null &&
187
+ autodepsArgIndex === autodepsArgExpectedIndex &&
188
autodepFnLoads.has(callee.identifier.id) &&
189
value.args[0].kind === 'Identifier'
190
) {
compiler/packages/babel-plugin-react-compiler/src/Utils/TestUtils.ts
+3
-3
@@ -75,21 +75,21 @@ const testComplexConfigDefaults: PartialEnvironmentConfig = {
75
source: 'react',
76
importSpecifierName: 'useEffect',
77
},
78
- numRequiredArgs: 1,
78
+ autodepsIndex: 1,
79
},
80
{
81
function: {
82
source: 'shared-runtime',
83
importSpecifierName: 'useSpecialEffect',
84
},
85
- numRequiredArgs: 2,
85
+ autodepsIndex: 2,
86
},
87
{
88
function: {
89
source: 'useEffectWrapper',
90
importSpecifierName: 'default',
91
},
92
- numRequiredArgs: 1,
92
+ autodepsIndex: 1,
93
},
94
],
95
};
compiler/packages/babel-plugin-react-compiler/src/__tests__/envConfig-test.ts
+2
-2
@@ -33,12 +33,12 @@ describe('parseConfigPragma()', () => {
33
source: 'react',
34
importSpecifierName: 'useEffect',
35
},
36
- numRequiredArgs: 0,
36
+ autodepsIndex: 0,
37
},
38
],
39
} as any);
40
}).toThrowErrorMatchingInlineSnapshot(
41
- `"InvalidConfig: Could not validate environment config. Update React Compiler config to fix the error. Validation error: numRequiredArgs must be > 0 at "inferEffectDependencies[0].numRequiredArgs""`,
41
+ `"InvalidConfig: Could not validate environment config. Update React Compiler config to fix the error. Validation error: autodepsIndex must be > 0 at "inferEffectDependencies[0].autodepsIndex""`,
42
);
43
});
44
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/gating/error.dynamic-gating-invalid-identifier-nopanic-required-feature.expect.md
+4
-4
@@ -3,13 +3,13 @@
3
4
```javascript
5
// @dynamicGating:{"source":"shared-runtime"} @panicThreshold:"none" @inferEffectDependencies
6
-import {useEffect} from 'react';
6
+import {useEffect, AUTODEPS} from 'react';
7
import {print} from 'shared-runtime';
8
9
function ReactiveVariable({propVal}) {
10
'use memo if(invalid identifier)';
11
const arr = [propVal];
12
- useEffect(() => print(arr));
12
+ useEffect(() => print(arr), AUTODEPS);
13
}
14
15
export const FIXTURE_ENTRYPOINT = {
@@ -25,8 +25,8 @@ export const FIXTURE_ENTRYPOINT = {
25
```
26
6 | 'use memo if(invalid identifier)';
27
7 | const arr = [propVal];
28
-> 8 | useEffect(() => print(arr));
29
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ InvalidReact: [InferEffectDependencies] React Compiler is unable to infer dependencies of this effect. This will break your build! To resolve, either pass your own dependency array or fix reported compiler bailout diagnostics. (8:8)
28
+> 8 | useEffect(() => print(arr), AUTODEPS);
29
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ InvalidReact: [InferEffectDependencies] React Compiler is unable to infer dependencies of this effect. This will break your build! To resolve, either pass your own dependency array or fix reported compiler bailout diagnostics. (8:8)
30
9 | }
31
10 |
32
11 | export const FIXTURE_ENTRYPOINT = {
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/gating/error.dynamic-gating-invalid-identifier-nopanic-required-feature.js
+2
-2
@@ -1,11 +1,11 @@
1
// @dynamicGating:{"source":"shared-runtime"} @panicThreshold:"none" @inferEffectDependencies
2
-import {useEffect} from 'react';
2
+import {useEffect, AUTODEPS} from 'react';
3
import {print} from 'shared-runtime';
4
5
function ReactiveVariable({propVal}) {
6
'use memo if(invalid identifier)';
7
const arr = [propVal];
8
- useEffect(() => print(arr));
8
+ useEffect(() => print(arr), AUTODEPS);
9
}
10
11
export const FIXTURE_ENTRYPOINT = {
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/bailout-retry/error.callsite-in-non-react-fn-default-import.expect.md
+8
-7
@@ -4,9 +4,10 @@
4
```javascript
5
// @inferEffectDependencies @compilationMode:"infer" @panicThreshold:"none"
6
import useMyEffect from 'useEffectWrapper';
7
+import {AUTODEPS} from 'react';
8
9
function nonReactFn(arg) {
9
- useMyEffect(() => [1, 2, arg]);
10
+ useMyEffect(() => [1, 2, arg], AUTODEPS);
11
}
12
13
```
@@ -15,12 +16,12 @@ function nonReactFn(arg) {
16
## Error
17
18
```
18
- 3 |
19
- 4 | function nonReactFn(arg) {
20
-> 5 | useMyEffect(() => [1, 2, arg]);
21
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ InvalidReact: [InferEffectDependencies] React Compiler is unable to infer dependencies of this effect. This will break your build! To resolve, either pass your own dependency array or fix reported compiler bailout diagnostics. (5:5)
22
- 6 | }
23
- 7 |
19
+ 4 |
20
+ 5 | function nonReactFn(arg) {
21
+> 6 | useMyEffect(() => [1, 2, arg], AUTODEPS);
22
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ InvalidReact: [InferEffectDependencies] React Compiler is unable to infer dependencies of this effect. This will break your build! To resolve, either pass your own dependency array or fix reported compiler bailout diagnostics. (6:6)
23
+ 7 | }
24
+ 8 |
25
```
26
27
\ No newline at end of file
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/bailout-retry/error.callsite-in-non-react-fn-default-import.js
+2
-1
@@ -1,6 +1,7 @@
1
// @inferEffectDependencies @compilationMode:"infer" @panicThreshold:"none"
2
import useMyEffect from 'useEffectWrapper';
3
+import {AUTODEPS} from 'react';
4
5
function nonReactFn(arg) {
5
- useMyEffect(() => [1, 2, arg]);
6
+ useMyEffect(() => [1, 2, arg], AUTODEPS);
7
}
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/bailout-retry/error.callsite-in-non-react-fn.expect.md
+4
-4
@@ -3,10 +3,10 @@
3
4
```javascript
5
// @inferEffectDependencies @compilationMode:"infer" @panicThreshold:"none"
6
-import {useEffect} from 'react';
6
+import {useEffect, AUTODEPS} from 'react';
7
8
function nonReactFn(arg) {
9
- useEffect(() => [1, 2, arg]);
9
+ useEffect(() => [1, 2, arg], AUTODEPS);
10
}
11
12
```
@@ -17,8 +17,8 @@ function nonReactFn(arg) {
17
```
18
3 |
19
4 | function nonReactFn(arg) {
20
-> 5 | useEffect(() => [1, 2, arg]);
21
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ InvalidReact: [InferEffectDependencies] React Compiler is unable to infer dependencies of this effect. This will break your build! To resolve, either pass your own dependency array or fix reported compiler bailout diagnostics. (5:5)
20
+> 5 | useEffect(() => [1, 2, arg], AUTODEPS);
21
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ InvalidReact: [InferEffectDependencies] React Compiler is unable to infer dependencies of this effect. This will break your build! To resolve, either pass your own dependency array or fix reported compiler bailout diagnostics. (5:5)
22
6 | }
23
7 |
24
```
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/bailout-retry/error.callsite-in-non-react-fn.js
+2
-2
@@ -1,6 +1,6 @@
1
// @inferEffectDependencies @compilationMode:"infer" @panicThreshold:"none"
2
-import {useEffect} from 'react';
2
+import {useEffect, AUTODEPS} from 'react';
3
4
function nonReactFn(arg) {
5
- useEffect(() => [1, 2, arg]);
5
+ useEffect(() => [1, 2, arg], AUTODEPS);
6
}
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/bailout-retry/error.non-inlined-effect-fn.expect.md
+4
-4
@@ -3,7 +3,7 @@
3
4
```javascript
5
// @inferEffectDependencies @panicThreshold:"none"
6
-import {useEffect} from 'react';
6
+import {useEffect, AUTODEPS} from 'react';
7
8
/**
9
* Error on non-inlined effect functions:
@@ -21,7 +21,7 @@ function Component({foo}) {
21
}
22
23
// No inferred dep array, the argument is not a lambda
24
- useEffect(f);
24
+ useEffect(f, AUTODEPS);
25
}
26
27
```
@@ -32,8 +32,8 @@ function Component({foo}) {
32
```
33
18 |
34
19 | // No inferred dep array, the argument is not a lambda
35
-> 20 | useEffect(f);
36
- | ^^^^^^^^^^^^ InvalidReact: [InferEffectDependencies] React Compiler is unable to infer dependencies of this effect. This will break your build! To resolve, either pass your own dependency array or fix reported compiler bailout diagnostics. (20:20)
35
+> 20 | useEffect(f, AUTODEPS);
36
+ | ^^^^^^^^^^^^^^^^^^^^^^ InvalidReact: [InferEffectDependencies] React Compiler is unable to infer dependencies of this effect. This will break your build! To resolve, either pass your own dependency array or fix reported compiler bailout diagnostics. (20:20)
37
21 | }
38
22 |
39
```
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/bailout-retry/error.non-inlined-effect-fn.js
+2
-2
@@ -1,5 +1,5 @@
1
// @inferEffectDependencies @panicThreshold:"none"
2
-import {useEffect} from 'react';
2
+import {useEffect, AUTODEPS} from 'react';
3
4
/**
5
* Error on non-inlined effect functions:
@@ -17,5 +17,5 @@ function Component({foo}) {
17
}
18
19
// No inferred dep array, the argument is not a lambda
20
- useEffect(f);
20
+ useEffect(f, AUTODEPS);
21
}
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/bailout-retry/error.todo-dynamic-gating.expect.md
+9
-8
@@ -5,6 +5,7 @@
5
// @dynamicGating:{"source":"shared-runtime"} @inferEffectDependencies @panicThreshold:"none"
6
7
import useEffectWrapper from 'useEffectWrapper';
8
+import {AUTODEPS} from 'react';
9
10
/**
11
* TODO: run the non-forget enabled version through the effect inference
@@ -13,7 +14,7 @@ import useEffectWrapper from 'useEffectWrapper';
14
function Component({foo}) {
15
'use memo if(getTrue)';
16
const arr = [];
16
- useEffectWrapper(() => arr.push(foo));
17
+ useEffectWrapper(() => arr.push(foo), AUTODEPS);
18
arr.push(2);
19
return arr;
20
}
@@ -30,13 +31,13 @@ export const FIXTURE_ENTRYPOINT = {
31
## Error
32
33
```
33
- 10 | 'use memo if(getTrue)';
34
- 11 | const arr = [];
35
-> 12 | useEffectWrapper(() => arr.push(foo));
36
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ InvalidReact: [InferEffectDependencies] React Compiler is unable to infer dependencies of this effect. This will break your build! To resolve, either pass your own dependency array or fix reported compiler bailout diagnostics. (12:12)
37
- 13 | arr.push(2);
38
- 14 | return arr;
39
- 15 | }
34
+ 11 | 'use memo if(getTrue)';
35
+ 12 | const arr = [];
36
+> 13 | useEffectWrapper(() => arr.push(foo), AUTODEPS);
37
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ InvalidReact: [InferEffectDependencies] React Compiler is unable to infer dependencies of this effect. This will break your build! To resolve, either pass your own dependency array or fix reported compiler bailout diagnostics. (13:13)
38
+ 14 | arr.push(2);
39
+ 15 | return arr;
40
+ 16 | }
41
```
42
43
\ No newline at end of file
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/bailout-retry/error.todo-dynamic-gating.js
+2
-1
@@ -1,6 +1,7 @@
1
// @dynamicGating:{"source":"shared-runtime"} @inferEffectDependencies @panicThreshold:"none"
2
3
import useEffectWrapper from 'useEffectWrapper';
4
+import {AUTODEPS} from 'react';
5
6
/**
7
* TODO: run the non-forget enabled version through the effect inference
@@ -9,7 +10,7 @@ import useEffectWrapper from 'useEffectWrapper';
10
function Component({foo}) {
11
'use memo if(getTrue)';
12
const arr = [];
12
- useEffectWrapper(() => arr.push(foo));
13
+ useEffectWrapper(() => arr.push(foo), AUTODEPS);
14
arr.push(2);
15
return arr;
16
}
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/bailout-retry/error.todo-gating.expect.md
+9
-8
@@ -4,6 +4,7 @@
4
```javascript
5
// @gating @inferEffectDependencies @panicThreshold:"none"
6
import useEffectWrapper from 'useEffectWrapper';
7
+import {AUTODEPS} from 'react';
8
9
/**
10
* TODO: run the non-forget enabled version through the effect inference
@@ -11,7 +12,7 @@ import useEffectWrapper from 'useEffectWrapper';
12
*/
13
function Component({foo}) {
14
const arr = [];
14
- useEffectWrapper(() => arr.push(foo));
15
+ useEffectWrapper(() => arr.push(foo), AUTODEPS);
16
arr.push(2);
17
return arr;
18
}
@@ -28,13 +29,13 @@ export const FIXTURE_ENTRYPOINT = {
29
## Error
30
31
```
31
- 8 | function Component({foo}) {
32
- 9 | const arr = [];
33
-> 10 | useEffectWrapper(() => arr.push(foo));
34
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ InvalidReact: [InferEffectDependencies] React Compiler is unable to infer dependencies of this effect. This will break your build! To resolve, either pass your own dependency array or fix reported compiler bailout diagnostics. (10:10)
35
- 11 | arr.push(2);
36
- 12 | return arr;
37
- 13 | }
32
+ 9 | function Component({foo}) {
33
+ 10 | const arr = [];
34
+> 11 | useEffectWrapper(() => arr.push(foo), AUTODEPS);
35
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ InvalidReact: [InferEffectDependencies] React Compiler is unable to infer dependencies of this effect. This will break your build! To resolve, either pass your own dependency array or fix reported compiler bailout diagnostics. (11:11)
36
+ 12 | arr.push(2);
37
+ 13 | return arr;
38
+ 14 | }
39
```
40
41
\ No newline at end of file
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/bailout-retry/error.todo-gating.js
+2
-1
@@ -1,5 +1,6 @@
1
// @gating @inferEffectDependencies @panicThreshold:"none"
2
import useEffectWrapper from 'useEffectWrapper';
3
+import {AUTODEPS} from 'react';
4
5
/**
6
* TODO: run the non-forget enabled version through the effect inference
@@ -7,7 +8,7 @@ import useEffectWrapper from 'useEffectWrapper';
8
*/
9
function Component({foo}) {
10
const arr = [];
10
- useEffectWrapper(() => arr.push(foo));
11
+ useEffectWrapper(() => arr.push(foo), AUTODEPS);
12
arr.push(2);
13
return arr;
14
}
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/bailout-retry/error.todo-import-default-property-useEffect.expect.md
+3
-3
@@ -7,7 +7,7 @@ import React from 'react';
7
8
function NonReactiveDepInEffect() {
9
const obj = makeObject_Primitives();
10
- React.useEffect(() => print(obj));
10
+ React.useEffect(() => print(obj), React.AUTODEPS);
11
}
12
13
```
@@ -18,8 +18,8 @@ function NonReactiveDepInEffect() {
18
```
19
4 | function NonReactiveDepInEffect() {
20
5 | const obj = makeObject_Primitives();
21
-> 6 | React.useEffect(() => print(obj));
22
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ InvalidReact: [InferEffectDependencies] React Compiler is unable to infer dependencies of this effect. This will break your build! To resolve, either pass your own dependency array or fix reported compiler bailout diagnostics. (6:6)
21
+> 6 | React.useEffect(() => print(obj), React.AUTODEPS);
22
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ InvalidReact: [InferEffectDependencies] React Compiler is unable to infer dependencies of this effect. This will break your build! To resolve, either pass your own dependency array or fix reported compiler bailout diagnostics. (6:6)
23
7 | }
24
8 |
25
```
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/bailout-retry/error.todo-import-default-property-useEffect.js
+1
-1
@@ -3,5 +3,5 @@ import React from 'react';
3
4
function NonReactiveDepInEffect() {
5
const obj = makeObject_Primitives();
6
- React.useEffect(() => print(obj));
6
+ React.useEffect(() => print(obj), React.AUTODEPS);
7
}
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/bailout-retry/error.todo-syntax.expect.md
+39
-26
@@ -4,6 +4,7 @@
4
```javascript
5
// @inferEffectDependencies @panicThreshold:"none"
6
import {useSpecialEffect} from 'shared-runtime';
7
+import {AUTODEPS} from 'react';
8
9
/**
10
* Note that a react compiler-based transform still has limitations on JS syntax.
@@ -11,13 +12,17 @@ import {useSpecialEffect} from 'shared-runtime';
12
*/
13
function Component({prop1}) {
14
'use memo';
14
- useSpecialEffect(() => {
15
- try {
16
- console.log(prop1);
17
- } finally {
18
- console.log('exiting');
19
- }
20
- }, [prop1]);
15
+ useSpecialEffect(
16
+ () => {
17
+ try {
18
+ console.log(prop1);
19
+ } finally {
20
+ console.log('exiting');
21
+ }
22
+ },
23
+ [prop1],
24
+ AUTODEPS
25
+ );
26
return <div>{prop1}</div>;
27
}
28
@@ -27,25 +32,33 @@ function Component({prop1}) {
32
## Error
33
34
```
30
- 8 | function Component({prop1}) {
31
- 9 | 'use memo';
32
-> 10 | useSpecialEffect(() => {
33
- | ^^^^^^^^^^^^^^^^^^^^^^^^
34
-> 11 | try {
35
- | ^^^^^^^^^
36
-> 12 | console.log(prop1);
37
- | ^^^^^^^^^
38
-> 13 | } finally {
39
- | ^^^^^^^^^
40
-> 14 | console.log('exiting');
41
- | ^^^^^^^^^
42
-> 15 | }
43
- | ^^^^^^^^^
44
-> 16 | }, [prop1]);
45
- | ^^^^^^^^^^^^^^ InvalidReact: [InferEffectDependencies] React Compiler is unable to infer dependencies of this effect. This will break your build! To resolve, either pass your own dependency array or fix reported compiler bailout diagnostics.. (Bailout reason: Todo: (BuildHIR::lowerStatement) Handle TryStatement without a catch clause (11:15)) (10:16)
46
- 17 | return <div>{prop1}</div>;
47
- 18 | }
48
- 19 |
35
+ 9 | function Component({prop1}) {
36
+ 10 | 'use memo';
37
+> 11 | useSpecialEffect(
38
+ | ^^^^^^^^^^^^^^^^^
39
+> 12 | () => {
40
+ | ^^^^^^^^^^^
41
+> 13 | try {
42
+ | ^^^^^^^^^^^
43
+> 14 | console.log(prop1);
44
+ | ^^^^^^^^^^^
45
+> 15 | } finally {
46
+ | ^^^^^^^^^^^
47
+> 16 | console.log('exiting');
48
+ | ^^^^^^^^^^^
49
+> 17 | }
50
+ | ^^^^^^^^^^^
51
+> 18 | },
52
+ | ^^^^^^^^^^^
53
+> 19 | [prop1],
54
+ | ^^^^^^^^^^^
55
+> 20 | AUTODEPS
56
+ | ^^^^^^^^^^^
57
+> 21 | );
58
+ | ^^^^ InvalidReact: [InferEffectDependencies] React Compiler is unable to infer dependencies of this effect. This will break your build! To resolve, either pass your own dependency array or fix reported compiler bailout diagnostics.. (Bailout reason: Todo: (BuildHIR::lowerStatement) Handle TryStatement without a catch clause (13:17)) (11:21)
59
+ 22 | return <div>{prop1}</div>;
60
+ 23 | }
61
+ 24 |
62
```
63
64
\ No newline at end of file
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/bailout-retry/error.todo-syntax.js
+12
-7
@@ -1,5 +1,6 @@
1
// @inferEffectDependencies @panicThreshold:"none"
2
import {useSpecialEffect} from 'shared-runtime';
3
+import {AUTODEPS} from 'react';
4
5
/**
6
* Note that a react compiler-based transform still has limitations on JS syntax.
@@ -7,12 +8,16 @@ import {useSpecialEffect} from 'shared-runtime';
8
*/
9
function Component({prop1}) {
10
'use memo';
10
- useSpecialEffect(() => {
11
- try {
12
- console.log(prop1);
13
- } finally {
14
- console.log('exiting');
15
- }
16
- }, [prop1]);
11
+ useSpecialEffect(
12
+ () => {
13
+ try {
14
+ console.log(prop1);
15
+ } finally {
16
+ console.log('exiting');
17
+ }
18
+ },
19
+ [prop1],
20
+ AUTODEPS
21
+ );
22
return <div>{prop1}</div>;
23
}
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/bailout-retry/error.use-no-memo.expect.md
+4
-4
@@ -3,11 +3,11 @@
3
4
```javascript
5
// @inferEffectDependencies @panicThreshold:"none"
6
-import {useEffect} from 'react';
6
+import {useEffect, AUTODEPS} from 'react';
7
8
function Component({propVal}) {
9
'use no memo';
10
- useEffect(() => [propVal]);
10
+ useEffect(() => [propVal], AUTODEPS);
11
}
12
13
```
@@ -18,8 +18,8 @@ function Component({propVal}) {
18
```
19
4 | function Component({propVal}) {
20
5 | 'use no memo';
21
-> 6 | useEffect(() => [propVal]);
22
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^ InvalidReact: [InferEffectDependencies] React Compiler is unable to infer dependencies of this effect. This will break your build! To resolve, either pass your own dependency array or fix reported compiler bailout diagnostics. (6:6)
21
+> 6 | useEffect(() => [propVal], AUTODEPS);
22
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ InvalidReact: [InferEffectDependencies] React Compiler is unable to infer dependencies of this effect. This will break your build! To resolve, either pass your own dependency array or fix reported compiler bailout diagnostics. (6:6)
23
7 | }
24
8 |
25
```
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/bailout-retry/error.use-no-memo.js
+2
-2
@@ -1,7 +1,7 @@
1
// @inferEffectDependencies @panicThreshold:"none"
2
-import {useEffect} from 'react';
2
+import {useEffect, AUTODEPS} from 'react';
3
4
function Component({propVal}) {
5
'use no memo';
6
- useEffect(() => [propVal]);
6
+ useEffect(() => [propVal], AUTODEPS);
7
}
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/error.wrong-index-no-func.expect.md
new
+26
@@ -0,0 +1,26 @@
1
+
2
+## Input
3
+
4
+```javascript
5
+// @inferEffectDependencies
6
+import {useEffect, AUTODEPS} from 'react';
7
+
8
+function Component({foo}) {
9
+ useEffect(AUTODEPS);
10
+}
11
+
12
+```
13
+
14
+
15
+## Error
16
+
17
+```
18
+ 3 |
19
+ 4 | function Component({foo}) {
20
+> 5 | useEffect(AUTODEPS);
21
+ | ^^^^^^^^^^^^^^^^^^^ InvalidReact: [InferEffectDependencies] React Compiler is unable to infer dependencies of this effect. This will break your build! To resolve, either pass your own dependency array or fix reported compiler bailout diagnostics. (5:5)
22
+ 6 | }
23
+ 7 |
24
+```
25
+
26
+
\ No newline at end of file
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/error.wrong-index-no-func.js
new
+6
@@ -0,0 +1,6 @@
1
+// @inferEffectDependencies
2
+import {useEffect, AUTODEPS} from 'react';
3
+
4
+function Component({foo}) {
5
+ useEffect(AUTODEPS);
6
+}
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/error.wrong-index.expect.md
new
+45
@@ -0,0 +1,45 @@
1
+
2
+## Input
3
+
4
+```javascript
5
+// @inferEffectDependencies
6
+import {AUTODEPS} from 'react';
7
+import useEffectWrapper from 'useEffectWrapper';
8
+
9
+function Component({foo}) {
10
+ useEffectWrapper(
11
+ () => {
12
+ console.log(foo);
13
+ },
14
+ [foo],
15
+ AUTODEPS
16
+ );
17
+}
18
+
19
+```
20
+
21
+
22
+## Error
23
+
24
+```
25
+ 4 |
26
+ 5 | function Component({foo}) {
27
+> 6 | useEffectWrapper(
28
+ | ^^^^^^^^^^^^^^^^^
29
+> 7 | () => {
30
+ | ^^^^^^^^^^^
31
+> 8 | console.log(foo);
32
+ | ^^^^^^^^^^^
33
+> 9 | },
34
+ | ^^^^^^^^^^^
35
+> 10 | [foo],
36
+ | ^^^^^^^^^^^
37
+> 11 | AUTODEPS
38
+ | ^^^^^^^^^^^
39
+> 12 | );
40
+ | ^^^^ InvalidReact: [InferEffectDependencies] React Compiler is unable to infer dependencies of this effect. This will break your build! To resolve, either pass your own dependency array or fix reported compiler bailout diagnostics. (6:12)
41
+ 13 | }
42
+ 14 |
43
+```
44
+
45
+
\ No newline at end of file
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/error.wrong-index.js
new
+13
@@ -0,0 +1,13 @@
1
+// @inferEffectDependencies
2
+import {AUTODEPS} from 'react';
3
+import useEffectWrapper from 'useEffectWrapper';
4
+
5
+function Component({foo}) {
6
+ useEffectWrapper(
7
+ () => {
8
+ console.log(foo);
9
+ },
10
+ [foo],
11
+ AUTODEPS
12
+ );
13
+}
compiler/packages/eslint-plugin-react-compiler/__tests__/ReactCompilerRule-test.ts
+3
-2
@@ -250,9 +250,10 @@ const tests: CompilerTestCases = {
250
name: 'Pipeline errors are reported',
251
code: normalizeIndent`
252
import useMyEffect from 'useMyEffect';
253
+ import {AUTODEPS} from 'react';
254
function Component({a}) {
255
'use no memo';
255
- useMyEffect(() => console.log(a.b));
256
+ useMyEffect(() => console.log(a.b), AUTODEPS);
257
return <div>Hello world</div>;
258
}
259
`,
@@ -265,7 +266,7 @@ const tests: CompilerTestCases = {
266
source: 'useMyEffect',
267
importSpecifierName: 'default',
268
},
268
- numRequiredArgs: 1,
269
+ autodepsIndex: 1,
270
},
271
],
272
},