11
11
12
12
export default {
13
13
meta : {
14
+ fixable : 'code' ,
14
15
schema : [
15
16
{
16
17
type : 'object' ,
17
18
additionalProperties : false ,
19
+ enableDangerousAutofixThisMayCauseInfiniteLoops : false ,
18
20
properties : {
19
21
additionalHooks : {
20
22
type : 'string' ,
21
23
} ,
24
+ enableDangerousAutofixThisMayCauseInfiniteLoops : {
25
+ type : 'boolean' ,
26
+ } ,
22
27
} ,
23
28
} ,
24
29
] ,
@@ -31,7 +36,28 @@ export default {
31
36
context . options [ 0 ] . additionalHooks
32
37
? new RegExp ( context . options [ 0 ] . additionalHooks )
33
38
: undefined ;
34
- const options = { additionalHooks} ;
39
+
40
+ const enableDangerousAutofixThisMayCauseInfiniteLoops =
41
+ ( context . options &&
42
+ context . options [ 0 ] &&
43
+ context . options [ 0 ] . enableDangerousAutofixThisMayCauseInfiniteLoops ) ||
44
+ false ;
45
+
46
+ const options = {
47
+ additionalHooks,
48
+ enableDangerousAutofixThisMayCauseInfiniteLoops,
49
+ } ;
50
+
51
+ function reportProblem ( problem ) {
52
+ if ( enableDangerousAutofixThisMayCauseInfiniteLoops ) {
53
+ // Used to enable legacy behavior. Dangerous.
54
+ // Keep this as an option until major IDEs upgrade (including VSCode FB ESLint extension).
55
+ if ( Array . isArray ( problem . suggest ) && problem . suggest . length > 0 ) {
56
+ problem . fix = problem . suggest [ 0 ] . fix ;
57
+ }
58
+ }
59
+ context . report ( problem ) ;
60
+ }
35
61
36
62
const scopeManager = context . getSourceCode ( ) . scopeManager ;
37
63
@@ -140,7 +166,7 @@ export default {
140
166
break ; // Unhandled
141
167
default :
142
168
// useEffect(generateEffectBody(), []);
143
- context . report ( {
169
+ reportProblem ( {
144
170
node : reactiveHook ,
145
171
message :
146
172
`React Hook ${ reactiveHookName } received a function whose dependencies ` +
@@ -150,7 +176,7 @@ export default {
150
176
}
151
177
152
178
// Something unusual. Fall back to suggesting to add the body itself as a dep.
153
- context . report ( {
179
+ reportProblem ( {
154
180
node : reactiveHook ,
155
181
message :
156
182
`React Hook ${ reactiveHookName } has a missing dependency: '${ callback . name } '. ` +
@@ -190,7 +216,7 @@ export default {
190
216
reactiveHookName === 'useCallback'
191
217
) {
192
218
// TODO: Can this have a suggestion?
193
- context . report ( {
219
+ reportProblem ( {
194
220
node : reactiveHook ,
195
221
message :
196
222
`React Hook ${ reactiveHookName } does nothing when called with ` +
@@ -202,7 +228,7 @@ export default {
202
228
}
203
229
204
230
if ( isEffect && node . async ) {
205
- context . report ( {
231
+ reportProblem ( {
206
232
node : node ,
207
233
message :
208
234
`Effect callbacks are synchronous to prevent race conditions. ` +
@@ -557,7 +583,7 @@ export default {
557
583
if ( foundCurrentAssignment ) {
558
584
return ;
559
585
}
560
- context . report ( {
586
+ reportProblem ( {
561
587
node : dependencyNode . parent . property ,
562
588
message :
563
589
`The ref value '${ dependency } .current' will likely have ` +
@@ -577,7 +603,7 @@ export default {
577
603
return ;
578
604
}
579
605
staleAssignments . add ( key ) ;
580
- context . report ( {
606
+ reportProblem ( {
581
607
node : writeExpr ,
582
608
message :
583
609
`Assignments to the '${ key } ' variable from inside React Hook ` +
@@ -645,7 +671,7 @@ export default {
645
671
externalDependencies : new Set ( ) ,
646
672
isEffect : true ,
647
673
} ) ;
648
- context . report ( {
674
+ reportProblem ( {
649
675
node : reactiveHook ,
650
676
message :
651
677
`React Hook ${ reactiveHookName } contains a call to '${ setStateInsideEffectWithoutDeps } '. ` +
@@ -677,7 +703,7 @@ export default {
677
703
// If the declared dependencies are not an array expression then we
678
704
// can't verify that the user provided the correct dependencies. Tell
679
705
// the user this in an error.
680
- context . report ( {
706
+ reportProblem ( {
681
707
node : declaredDependenciesNode ,
682
708
message :
683
709
`React Hook ${ context . getSource ( reactiveHook ) } was passed a ` +
@@ -693,7 +719,7 @@ export default {
693
719
}
694
720
// If we see a spread element then add a special warning.
695
721
if ( declaredDependencyNode . type === 'SpreadElement' ) {
696
- context . report ( {
722
+ reportProblem ( {
697
723
node : declaredDependencyNode ,
698
724
message :
699
725
`React Hook ${ context . getSource ( reactiveHook ) } has a spread ` +
@@ -712,23 +738,23 @@ export default {
712
738
if ( / U n s u p p o r t e d n o d e t y p e / . test ( error . message ) ) {
713
739
if ( declaredDependencyNode . type === 'Literal' ) {
714
740
if ( dependencies . has ( declaredDependencyNode . value ) ) {
715
- context . report ( {
741
+ reportProblem ( {
716
742
node : declaredDependencyNode ,
717
743
message :
718
744
`The ${ declaredDependencyNode . raw } literal is not a valid dependency ` +
719
745
`because it never changes. ` +
720
746
`Did you mean to include ${ declaredDependencyNode . value } in the array instead?` ,
721
747
} ) ;
722
748
} else {
723
- context . report ( {
749
+ reportProblem ( {
724
750
node : declaredDependencyNode ,
725
751
message :
726
752
`The ${ declaredDependencyNode . raw } literal is not a valid dependency ` +
727
753
'because it never changes. You can safely remove it.' ,
728
754
} ) ;
729
755
}
730
756
} else {
731
- context . report ( {
757
+ reportProblem ( {
732
758
node : declaredDependencyNode ,
733
759
message :
734
760
`React Hook ${ context . getSource ( reactiveHook ) } has a ` +
@@ -828,7 +854,7 @@ export default {
828
854
}
829
855
// TODO: What if the function needs to change on every render anyway?
830
856
// Should we suggest removing effect deps as an appropriate fix too?
831
- context . report ( {
857
+ reportProblem ( {
832
858
// TODO: Why not report this at the dependency site?
833
859
node : fn . node ,
834
860
message,
@@ -1099,7 +1125,7 @@ export default {
1099
1125
}
1100
1126
}
1101
1127
1102
- context . report ( {
1128
+ reportProblem ( {
1103
1129
node : declaredDependenciesNode ,
1104
1130
message :
1105
1131
`React Hook ${ context . getSource ( reactiveHook ) } has ` +
0 commit comments