@@ -100,6 +100,16 @@ function isInsideComponentOrHook(node) {
100
100
return false ;
101
101
}
102
102
103
+ function isInsideDoWhileLoop ( node ) {
104
+ while ( node ) {
105
+ if ( node . type === 'DoWhileStatement' ) {
106
+ return true ;
107
+ }
108
+ node = node . parent ;
109
+ }
110
+ return false ;
111
+ }
112
+
103
113
function isUseEffectEventIdentifier ( node ) {
104
114
if ( __EXPERIMENTAL__ ) {
105
115
return node . type === 'Identifier' && node . name === 'useEffectEvent' ;
@@ -295,7 +305,7 @@ export default {
295
305
if ( pathList . has ( segment . id ) ) {
296
306
const pathArray = Array . from ( pathList ) ;
297
307
const cyclicSegments = pathArray . slice (
298
- pathArray . indexOf ( segment . id ) - 1 ,
308
+ pathArray . indexOf ( segment . id ) + 1 ,
299
309
) ;
300
310
for ( const cyclicSegment of cyclicSegments ) {
301
311
cyclic . add ( cyclicSegment ) ;
@@ -485,7 +495,10 @@ export default {
485
495
for ( const hook of reactHooks ) {
486
496
// Report an error if a hook may be called more then once.
487
497
// `use(...)` can be called in loops.
488
- if ( cycled && ! isUseIdentifier ( hook ) ) {
498
+ if (
499
+ ( cycled || isInsideDoWhileLoop ( hook ) ) &&
500
+ ! isUseIdentifier ( hook )
501
+ ) {
489
502
context . report ( {
490
503
node : hook ,
491
504
message :
@@ -520,7 +533,8 @@ export default {
520
533
if (
521
534
! cycled &&
522
535
pathsFromStartToEnd !== allPathsFromStartToEnd &&
523
- ! isUseIdentifier ( hook ) // `use(...)` can be called conditionally.
536
+ ! isUseIdentifier ( hook ) && // `use(...)` can be called conditionally.
537
+ ! isInsideDoWhileLoop ( hook ) // wrapping do/while loops are checked separately.
524
538
) {
525
539
const message =
526
540
`React Hook "${ getSource ( hook ) } " is called ` +
0 commit comments