eslint-plugin-react-hooks-extra 1.5.28-beta.3 → 1.5.28-beta.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +69 -65
- package/dist/index.mjs +70 -66
- package/package.json +8 -8
package/dist/index.js
CHANGED
|
@@ -9,7 +9,7 @@ var astUtils = require('@typescript-eslint/utils/ast-utils');
|
|
|
9
9
|
|
|
10
10
|
// package.json
|
|
11
11
|
var name = "eslint-plugin-react-hooks-extra";
|
|
12
|
-
var version = "1.5.28-beta.
|
|
12
|
+
var version = "1.5.28-beta.4";
|
|
13
13
|
var createRule = shared.createRuleForPlugin("hooks-extra");
|
|
14
14
|
|
|
15
15
|
// src/rules/ensure-custom-hooks-using-other-hooks.ts
|
|
@@ -470,20 +470,24 @@ var no_direct_set_state_in_use_effect_default = createRule({
|
|
|
470
470
|
const functionStack = tools.MutList.make();
|
|
471
471
|
const effectFunctionRef = tools.MutRef.make(null);
|
|
472
472
|
const cleanUpFunctionRef = tools.MutRef.make(null);
|
|
473
|
-
const indirectFunctionCalls =
|
|
473
|
+
const indirectFunctionCalls = tools.MutRef.make(tools.Chunk.empty());
|
|
474
474
|
const indirectSetStateCalls = /* @__PURE__ */ new Map();
|
|
475
475
|
return {
|
|
476
|
-
|
|
477
|
-
const
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
476
|
+
":function"(node) {
|
|
477
|
+
const functionKind = getFunctionKind(node);
|
|
478
|
+
tools.MutList.append(functionStack, [node, functionKind]);
|
|
479
|
+
$(functionKind).with("effect", () => {
|
|
480
|
+
tools.MutRef.set(effectFunctionRef, node);
|
|
481
|
+
}).with("cleanup", () => {
|
|
482
|
+
tools.MutRef.set(cleanUpFunctionRef, node);
|
|
483
|
+
}).otherwise(tools.F.constVoid);
|
|
484
|
+
},
|
|
485
|
+
":function:exit"(node) {
|
|
486
|
+
const effectFn = tools.MutRef.get(effectFunctionRef);
|
|
487
|
+
if (effectFn === node) {
|
|
488
|
+
tools.MutRef.set(effectFunctionRef, null);
|
|
486
489
|
}
|
|
490
|
+
tools.MutList.pop(functionStack);
|
|
487
491
|
},
|
|
488
492
|
CallExpression(node) {
|
|
489
493
|
const effectFn = tools.MutRef.get(effectFunctionRef);
|
|
@@ -493,42 +497,39 @@ var no_direct_set_state_in_use_effect_default = createRule({
|
|
|
493
497
|
$(callKind).with("setState", () => {
|
|
494
498
|
if (!parentFn) return;
|
|
495
499
|
if (parentFn !== effectFn && parentFnKind !== "immediate") {
|
|
496
|
-
|
|
500
|
+
const calls = indirectSetStateCalls.get(parentFn) ?? tools.Chunk.empty();
|
|
501
|
+
indirectSetStateCalls.set(parentFn, tools.Chunk.append(calls, node));
|
|
497
502
|
return;
|
|
498
503
|
}
|
|
499
504
|
context.report({
|
|
500
|
-
|
|
501
|
-
|
|
505
|
+
messageId: "NO_DIRECT_SET_STATE_IN_USE_EFFECT",
|
|
506
|
+
node
|
|
502
507
|
});
|
|
503
508
|
}).with("useEffect", () => {
|
|
504
509
|
tools.MutRef.set(useEffectCallRef, node);
|
|
505
510
|
}).with("other", () => {
|
|
506
|
-
indirectFunctionCalls.
|
|
507
|
-
}).otherwise(tools.F.constVoid);
|
|
508
|
-
},
|
|
509
|
-
":function"(node) {
|
|
510
|
-
const functionKind = getFunctionKind(node);
|
|
511
|
-
tools.MutList.append(functionStack, [node, functionKind]);
|
|
512
|
-
$(functionKind).with("effect", () => {
|
|
513
|
-
tools.MutRef.set(effectFunctionRef, node);
|
|
514
|
-
}).with("cleanup", () => {
|
|
515
|
-
tools.MutRef.set(cleanUpFunctionRef, node);
|
|
511
|
+
tools.MutRef.update(indirectFunctionCalls, tools.Chunk.append(node));
|
|
516
512
|
}).otherwise(tools.F.constVoid);
|
|
517
513
|
},
|
|
518
|
-
":function:exit"(node) {
|
|
519
|
-
const effectFn = tools.MutRef.get(effectFunctionRef);
|
|
520
|
-
if (effectFn === node) {
|
|
521
|
-
tools.MutRef.set(effectFunctionRef, null);
|
|
522
|
-
}
|
|
523
|
-
tools.MutList.pop(functionStack);
|
|
524
|
-
},
|
|
525
514
|
"CallExpression:exit"(node) {
|
|
526
515
|
if (tools.MutRef.get(useEffectCallRef) === node) {
|
|
527
516
|
tools.MutRef.set(useEffectCallRef, null);
|
|
528
517
|
}
|
|
529
518
|
},
|
|
519
|
+
Identifier(node) {
|
|
520
|
+
const isInUseEffectCall = tools.MutRef.get(useEffectCallRef) !== null;
|
|
521
|
+
const parentFn = tools.MutList.tail(functionStack)?.[0];
|
|
522
|
+
const useEffectCall = tools.MutRef.get(useEffectCallRef);
|
|
523
|
+
const isEffectFunction2 = useEffectCall && tools.O.isSome(ast.traverseUp(useEffectCall, (n2) => n2 === parentFn));
|
|
524
|
+
if (isFromUseStateCall(node) && isInUseEffectCall && isEffectFunction2) {
|
|
525
|
+
context.report({
|
|
526
|
+
messageId: "NO_DIRECT_SET_STATE_IN_USE_EFFECT",
|
|
527
|
+
node
|
|
528
|
+
});
|
|
529
|
+
}
|
|
530
|
+
},
|
|
530
531
|
"Program:exit"() {
|
|
531
|
-
for (const call of indirectFunctionCalls) {
|
|
532
|
+
for (const call of tools.Chunk.toReadonlyArray(tools.MutRef.get(indirectFunctionCalls))) {
|
|
532
533
|
if (!("name" in call.callee)) continue;
|
|
533
534
|
const { name: name2 } = call.callee;
|
|
534
535
|
const setStateCalls = tools.F.pipe(
|
|
@@ -536,6 +537,7 @@ var no_direct_set_state_in_use_effect_default = createRule({
|
|
|
536
537
|
tools.O.flatMap(_var.getVariableInit(0)),
|
|
537
538
|
tools.O.filter(ast.isFunction),
|
|
538
539
|
tools.O.flatMapNullable((init) => indirectSetStateCalls.get(init)),
|
|
540
|
+
tools.O.map(tools.Chunk.toReadonlyArray),
|
|
539
541
|
tools.O.getOrElse(() => [])
|
|
540
542
|
);
|
|
541
543
|
for (const setStateCall of setStateCalls) {
|
|
@@ -635,20 +637,24 @@ var no_direct_set_state_in_use_layout_effect_default = createRule({
|
|
|
635
637
|
const functionStack = tools.MutList.make();
|
|
636
638
|
const effectFunctionRef = tools.MutRef.make(null);
|
|
637
639
|
const cleanUpFunctionRef = tools.MutRef.make(null);
|
|
638
|
-
const indirectFunctionCalls =
|
|
640
|
+
const indirectFunctionCalls = tools.MutRef.make(tools.Chunk.empty());
|
|
639
641
|
const indirectSetStateCalls = /* @__PURE__ */ new Map();
|
|
640
642
|
return {
|
|
641
|
-
|
|
642
|
-
const
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
643
|
+
":function"(node) {
|
|
644
|
+
const functionKind = getFunctionKind(node);
|
|
645
|
+
tools.MutList.append(functionStack, [node, functionKind]);
|
|
646
|
+
$(functionKind).with("effect", () => {
|
|
647
|
+
tools.MutRef.set(effectFunctionRef, node);
|
|
648
|
+
}).with("cleanup", () => {
|
|
649
|
+
tools.MutRef.set(cleanUpFunctionRef, node);
|
|
650
|
+
}).otherwise(tools.F.constVoid);
|
|
651
|
+
},
|
|
652
|
+
":function:exit"(node) {
|
|
653
|
+
const effectFn = tools.MutRef.get(effectFunctionRef);
|
|
654
|
+
if (effectFn === node) {
|
|
655
|
+
tools.MutRef.set(effectFunctionRef, null);
|
|
651
656
|
}
|
|
657
|
+
tools.MutList.pop(functionStack);
|
|
652
658
|
},
|
|
653
659
|
CallExpression(node) {
|
|
654
660
|
const effectFn = tools.MutRef.get(effectFunctionRef);
|
|
@@ -658,42 +664,39 @@ var no_direct_set_state_in_use_layout_effect_default = createRule({
|
|
|
658
664
|
$(callKind).with("setState", () => {
|
|
659
665
|
if (!parentFn) return;
|
|
660
666
|
if (parentFn !== effectFn && parentFnKind !== "immediate") {
|
|
661
|
-
|
|
667
|
+
const calls = indirectSetStateCalls.get(parentFn) ?? tools.Chunk.empty();
|
|
668
|
+
indirectSetStateCalls.set(parentFn, tools.Chunk.append(calls, node));
|
|
662
669
|
return;
|
|
663
670
|
}
|
|
664
671
|
context.report({
|
|
665
|
-
|
|
666
|
-
|
|
672
|
+
messageId: "NO_DIRECT_SET_STATE_IN_USE_LAYOUT_EFFECT",
|
|
673
|
+
node
|
|
667
674
|
});
|
|
668
675
|
}).with("useLayoutEffect", () => {
|
|
669
676
|
tools.MutRef.set(useLayoutEffectCallRef, node);
|
|
670
677
|
}).with("other", () => {
|
|
671
|
-
indirectFunctionCalls.
|
|
672
|
-
}).otherwise(tools.F.constVoid);
|
|
673
|
-
},
|
|
674
|
-
":function"(node) {
|
|
675
|
-
const functionKind = getFunctionKind(node);
|
|
676
|
-
tools.MutList.append(functionStack, [node, functionKind]);
|
|
677
|
-
$(functionKind).with("effect", () => {
|
|
678
|
-
tools.MutRef.set(effectFunctionRef, node);
|
|
679
|
-
}).with("cleanup", () => {
|
|
680
|
-
tools.MutRef.set(cleanUpFunctionRef, node);
|
|
678
|
+
tools.MutRef.update(indirectFunctionCalls, tools.Chunk.append(node));
|
|
681
679
|
}).otherwise(tools.F.constVoid);
|
|
682
680
|
},
|
|
683
|
-
":function:exit"(node) {
|
|
684
|
-
const effectFn = tools.MutRef.get(effectFunctionRef);
|
|
685
|
-
if (effectFn === node) {
|
|
686
|
-
tools.MutRef.set(effectFunctionRef, null);
|
|
687
|
-
}
|
|
688
|
-
tools.MutList.pop(functionStack);
|
|
689
|
-
},
|
|
690
681
|
"CallExpression:exit"(node) {
|
|
691
682
|
if (tools.MutRef.get(useLayoutEffectCallRef) === node) {
|
|
692
683
|
tools.MutRef.set(useLayoutEffectCallRef, null);
|
|
693
684
|
}
|
|
694
685
|
},
|
|
686
|
+
Identifier(node) {
|
|
687
|
+
const isInUseLayoutEffectCall = tools.MutRef.get(useLayoutEffectCallRef) !== null;
|
|
688
|
+
const parentFn = tools.MutList.tail(functionStack)?.[0];
|
|
689
|
+
const useLayoutEffectCall = tools.MutRef.get(useLayoutEffectCallRef);
|
|
690
|
+
const isEffectFunction2 = useLayoutEffectCall && tools.O.isSome(ast.traverseUp(useLayoutEffectCall, (n2) => n2 === parentFn));
|
|
691
|
+
if (isFromUseStateCall(node) && isInUseLayoutEffectCall && isEffectFunction2) {
|
|
692
|
+
context.report({
|
|
693
|
+
messageId: "NO_DIRECT_SET_STATE_IN_USE_LAYOUT_EFFECT",
|
|
694
|
+
node
|
|
695
|
+
});
|
|
696
|
+
}
|
|
697
|
+
},
|
|
695
698
|
"Program:exit"() {
|
|
696
|
-
for (const call of indirectFunctionCalls) {
|
|
699
|
+
for (const call of tools.Chunk.toReadonlyArray(tools.MutRef.get(indirectFunctionCalls))) {
|
|
697
700
|
if (!("name" in call.callee)) continue;
|
|
698
701
|
const { name: name2 } = call.callee;
|
|
699
702
|
const setStateCalls = tools.F.pipe(
|
|
@@ -701,6 +704,7 @@ var no_direct_set_state_in_use_layout_effect_default = createRule({
|
|
|
701
704
|
tools.O.flatMap(_var.getVariableInit(0)),
|
|
702
705
|
tools.O.filter(ast.isFunction),
|
|
703
706
|
tools.O.flatMapNullable((init) => indirectSetStateCalls.get(init)),
|
|
707
|
+
tools.O.map(tools.Chunk.toReadonlyArray),
|
|
704
708
|
tools.O.getOrElse(() => [])
|
|
705
709
|
);
|
|
706
710
|
for (const setStateCall of setStateCalls) {
|
package/dist/index.mjs
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { useHookCollector, isReactHookCall, isUseCallbackCall, isReactHookCallWithNameLoose, isUseMemoCall, isUseStateCall, isUseEffectCall, isUseLayoutEffectCall } from '@eslint-react/core';
|
|
2
2
|
import { createRuleForPlugin, getESLintReactSettings } from '@eslint-react/shared';
|
|
3
3
|
import { isFunction, NodeType, is, traverseUp, getNestedCallExpressions, isIIFE } from '@eslint-react/ast';
|
|
4
|
-
import { F, O, MutRef, MutList } from '@eslint-react/tools';
|
|
4
|
+
import { F, O, MutRef, MutList, Chunk } from '@eslint-react/tools';
|
|
5
5
|
import { findVariable, getVariableInit } from '@eslint-react/var';
|
|
6
6
|
import { getStaticValue } from '@typescript-eslint/utils/ast-utils';
|
|
7
7
|
|
|
8
8
|
// package.json
|
|
9
9
|
var name = "eslint-plugin-react-hooks-extra";
|
|
10
|
-
var version = "1.5.28-beta.
|
|
10
|
+
var version = "1.5.28-beta.4";
|
|
11
11
|
var createRule = createRuleForPlugin("hooks-extra");
|
|
12
12
|
|
|
13
13
|
// src/rules/ensure-custom-hooks-using-other-hooks.ts
|
|
@@ -468,20 +468,24 @@ var no_direct_set_state_in_use_effect_default = createRule({
|
|
|
468
468
|
const functionStack = MutList.make();
|
|
469
469
|
const effectFunctionRef = MutRef.make(null);
|
|
470
470
|
const cleanUpFunctionRef = MutRef.make(null);
|
|
471
|
-
const indirectFunctionCalls =
|
|
471
|
+
const indirectFunctionCalls = MutRef.make(Chunk.empty());
|
|
472
472
|
const indirectSetStateCalls = /* @__PURE__ */ new Map();
|
|
473
473
|
return {
|
|
474
|
-
|
|
475
|
-
const
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
474
|
+
":function"(node) {
|
|
475
|
+
const functionKind = getFunctionKind(node);
|
|
476
|
+
MutList.append(functionStack, [node, functionKind]);
|
|
477
|
+
$(functionKind).with("effect", () => {
|
|
478
|
+
MutRef.set(effectFunctionRef, node);
|
|
479
|
+
}).with("cleanup", () => {
|
|
480
|
+
MutRef.set(cleanUpFunctionRef, node);
|
|
481
|
+
}).otherwise(F.constVoid);
|
|
482
|
+
},
|
|
483
|
+
":function:exit"(node) {
|
|
484
|
+
const effectFn = MutRef.get(effectFunctionRef);
|
|
485
|
+
if (effectFn === node) {
|
|
486
|
+
MutRef.set(effectFunctionRef, null);
|
|
484
487
|
}
|
|
488
|
+
MutList.pop(functionStack);
|
|
485
489
|
},
|
|
486
490
|
CallExpression(node) {
|
|
487
491
|
const effectFn = MutRef.get(effectFunctionRef);
|
|
@@ -491,42 +495,39 @@ var no_direct_set_state_in_use_effect_default = createRule({
|
|
|
491
495
|
$(callKind).with("setState", () => {
|
|
492
496
|
if (!parentFn) return;
|
|
493
497
|
if (parentFn !== effectFn && parentFnKind !== "immediate") {
|
|
494
|
-
|
|
498
|
+
const calls = indirectSetStateCalls.get(parentFn) ?? Chunk.empty();
|
|
499
|
+
indirectSetStateCalls.set(parentFn, Chunk.append(calls, node));
|
|
495
500
|
return;
|
|
496
501
|
}
|
|
497
502
|
context.report({
|
|
498
|
-
|
|
499
|
-
|
|
503
|
+
messageId: "NO_DIRECT_SET_STATE_IN_USE_EFFECT",
|
|
504
|
+
node
|
|
500
505
|
});
|
|
501
506
|
}).with("useEffect", () => {
|
|
502
507
|
MutRef.set(useEffectCallRef, node);
|
|
503
508
|
}).with("other", () => {
|
|
504
|
-
indirectFunctionCalls.
|
|
505
|
-
}).otherwise(F.constVoid);
|
|
506
|
-
},
|
|
507
|
-
":function"(node) {
|
|
508
|
-
const functionKind = getFunctionKind(node);
|
|
509
|
-
MutList.append(functionStack, [node, functionKind]);
|
|
510
|
-
$(functionKind).with("effect", () => {
|
|
511
|
-
MutRef.set(effectFunctionRef, node);
|
|
512
|
-
}).with("cleanup", () => {
|
|
513
|
-
MutRef.set(cleanUpFunctionRef, node);
|
|
509
|
+
MutRef.update(indirectFunctionCalls, Chunk.append(node));
|
|
514
510
|
}).otherwise(F.constVoid);
|
|
515
511
|
},
|
|
516
|
-
":function:exit"(node) {
|
|
517
|
-
const effectFn = MutRef.get(effectFunctionRef);
|
|
518
|
-
if (effectFn === node) {
|
|
519
|
-
MutRef.set(effectFunctionRef, null);
|
|
520
|
-
}
|
|
521
|
-
MutList.pop(functionStack);
|
|
522
|
-
},
|
|
523
512
|
"CallExpression:exit"(node) {
|
|
524
513
|
if (MutRef.get(useEffectCallRef) === node) {
|
|
525
514
|
MutRef.set(useEffectCallRef, null);
|
|
526
515
|
}
|
|
527
516
|
},
|
|
517
|
+
Identifier(node) {
|
|
518
|
+
const isInUseEffectCall = MutRef.get(useEffectCallRef) !== null;
|
|
519
|
+
const parentFn = MutList.tail(functionStack)?.[0];
|
|
520
|
+
const useEffectCall = MutRef.get(useEffectCallRef);
|
|
521
|
+
const isEffectFunction2 = useEffectCall && O.isSome(traverseUp(useEffectCall, (n2) => n2 === parentFn));
|
|
522
|
+
if (isFromUseStateCall(node) && isInUseEffectCall && isEffectFunction2) {
|
|
523
|
+
context.report({
|
|
524
|
+
messageId: "NO_DIRECT_SET_STATE_IN_USE_EFFECT",
|
|
525
|
+
node
|
|
526
|
+
});
|
|
527
|
+
}
|
|
528
|
+
},
|
|
528
529
|
"Program:exit"() {
|
|
529
|
-
for (const call of indirectFunctionCalls) {
|
|
530
|
+
for (const call of Chunk.toReadonlyArray(MutRef.get(indirectFunctionCalls))) {
|
|
530
531
|
if (!("name" in call.callee)) continue;
|
|
531
532
|
const { name: name2 } = call.callee;
|
|
532
533
|
const setStateCalls = F.pipe(
|
|
@@ -534,6 +535,7 @@ var no_direct_set_state_in_use_effect_default = createRule({
|
|
|
534
535
|
O.flatMap(getVariableInit(0)),
|
|
535
536
|
O.filter(isFunction),
|
|
536
537
|
O.flatMapNullable((init) => indirectSetStateCalls.get(init)),
|
|
538
|
+
O.map(Chunk.toReadonlyArray),
|
|
537
539
|
O.getOrElse(() => [])
|
|
538
540
|
);
|
|
539
541
|
for (const setStateCall of setStateCalls) {
|
|
@@ -633,20 +635,24 @@ var no_direct_set_state_in_use_layout_effect_default = createRule({
|
|
|
633
635
|
const functionStack = MutList.make();
|
|
634
636
|
const effectFunctionRef = MutRef.make(null);
|
|
635
637
|
const cleanUpFunctionRef = MutRef.make(null);
|
|
636
|
-
const indirectFunctionCalls =
|
|
638
|
+
const indirectFunctionCalls = MutRef.make(Chunk.empty());
|
|
637
639
|
const indirectSetStateCalls = /* @__PURE__ */ new Map();
|
|
638
640
|
return {
|
|
639
|
-
|
|
640
|
-
const
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
641
|
+
":function"(node) {
|
|
642
|
+
const functionKind = getFunctionKind(node);
|
|
643
|
+
MutList.append(functionStack, [node, functionKind]);
|
|
644
|
+
$(functionKind).with("effect", () => {
|
|
645
|
+
MutRef.set(effectFunctionRef, node);
|
|
646
|
+
}).with("cleanup", () => {
|
|
647
|
+
MutRef.set(cleanUpFunctionRef, node);
|
|
648
|
+
}).otherwise(F.constVoid);
|
|
649
|
+
},
|
|
650
|
+
":function:exit"(node) {
|
|
651
|
+
const effectFn = MutRef.get(effectFunctionRef);
|
|
652
|
+
if (effectFn === node) {
|
|
653
|
+
MutRef.set(effectFunctionRef, null);
|
|
649
654
|
}
|
|
655
|
+
MutList.pop(functionStack);
|
|
650
656
|
},
|
|
651
657
|
CallExpression(node) {
|
|
652
658
|
const effectFn = MutRef.get(effectFunctionRef);
|
|
@@ -656,42 +662,39 @@ var no_direct_set_state_in_use_layout_effect_default = createRule({
|
|
|
656
662
|
$(callKind).with("setState", () => {
|
|
657
663
|
if (!parentFn) return;
|
|
658
664
|
if (parentFn !== effectFn && parentFnKind !== "immediate") {
|
|
659
|
-
|
|
665
|
+
const calls = indirectSetStateCalls.get(parentFn) ?? Chunk.empty();
|
|
666
|
+
indirectSetStateCalls.set(parentFn, Chunk.append(calls, node));
|
|
660
667
|
return;
|
|
661
668
|
}
|
|
662
669
|
context.report({
|
|
663
|
-
|
|
664
|
-
|
|
670
|
+
messageId: "NO_DIRECT_SET_STATE_IN_USE_LAYOUT_EFFECT",
|
|
671
|
+
node
|
|
665
672
|
});
|
|
666
673
|
}).with("useLayoutEffect", () => {
|
|
667
674
|
MutRef.set(useLayoutEffectCallRef, node);
|
|
668
675
|
}).with("other", () => {
|
|
669
|
-
indirectFunctionCalls.
|
|
670
|
-
}).otherwise(F.constVoid);
|
|
671
|
-
},
|
|
672
|
-
":function"(node) {
|
|
673
|
-
const functionKind = getFunctionKind(node);
|
|
674
|
-
MutList.append(functionStack, [node, functionKind]);
|
|
675
|
-
$(functionKind).with("effect", () => {
|
|
676
|
-
MutRef.set(effectFunctionRef, node);
|
|
677
|
-
}).with("cleanup", () => {
|
|
678
|
-
MutRef.set(cleanUpFunctionRef, node);
|
|
676
|
+
MutRef.update(indirectFunctionCalls, Chunk.append(node));
|
|
679
677
|
}).otherwise(F.constVoid);
|
|
680
678
|
},
|
|
681
|
-
":function:exit"(node) {
|
|
682
|
-
const effectFn = MutRef.get(effectFunctionRef);
|
|
683
|
-
if (effectFn === node) {
|
|
684
|
-
MutRef.set(effectFunctionRef, null);
|
|
685
|
-
}
|
|
686
|
-
MutList.pop(functionStack);
|
|
687
|
-
},
|
|
688
679
|
"CallExpression:exit"(node) {
|
|
689
680
|
if (MutRef.get(useLayoutEffectCallRef) === node) {
|
|
690
681
|
MutRef.set(useLayoutEffectCallRef, null);
|
|
691
682
|
}
|
|
692
683
|
},
|
|
684
|
+
Identifier(node) {
|
|
685
|
+
const isInUseLayoutEffectCall = MutRef.get(useLayoutEffectCallRef) !== null;
|
|
686
|
+
const parentFn = MutList.tail(functionStack)?.[0];
|
|
687
|
+
const useLayoutEffectCall = MutRef.get(useLayoutEffectCallRef);
|
|
688
|
+
const isEffectFunction2 = useLayoutEffectCall && O.isSome(traverseUp(useLayoutEffectCall, (n2) => n2 === parentFn));
|
|
689
|
+
if (isFromUseStateCall(node) && isInUseLayoutEffectCall && isEffectFunction2) {
|
|
690
|
+
context.report({
|
|
691
|
+
messageId: "NO_DIRECT_SET_STATE_IN_USE_LAYOUT_EFFECT",
|
|
692
|
+
node
|
|
693
|
+
});
|
|
694
|
+
}
|
|
695
|
+
},
|
|
693
696
|
"Program:exit"() {
|
|
694
|
-
for (const call of indirectFunctionCalls) {
|
|
697
|
+
for (const call of Chunk.toReadonlyArray(MutRef.get(indirectFunctionCalls))) {
|
|
695
698
|
if (!("name" in call.callee)) continue;
|
|
696
699
|
const { name: name2 } = call.callee;
|
|
697
700
|
const setStateCalls = F.pipe(
|
|
@@ -699,6 +702,7 @@ var no_direct_set_state_in_use_layout_effect_default = createRule({
|
|
|
699
702
|
O.flatMap(getVariableInit(0)),
|
|
700
703
|
O.filter(isFunction),
|
|
701
704
|
O.flatMapNullable((init) => indirectSetStateCalls.get(init)),
|
|
705
|
+
O.map(Chunk.toReadonlyArray),
|
|
702
706
|
O.getOrElse(() => [])
|
|
703
707
|
);
|
|
704
708
|
for (const setStateCall of setStateCalls) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-react-hooks-extra",
|
|
3
|
-
"version": "1.5.28-beta.
|
|
3
|
+
"version": "1.5.28-beta.4",
|
|
4
4
|
"description": "ESLint React's ESLint plugin for React Hooks related rules.",
|
|
5
5
|
"homepage": "https://github.com/rel1cx/eslint-react",
|
|
6
6
|
"bugs": {
|
|
@@ -39,13 +39,13 @@
|
|
|
39
39
|
"@typescript-eslint/type-utils": "^7.16.1",
|
|
40
40
|
"@typescript-eslint/types": "^7.16.1",
|
|
41
41
|
"@typescript-eslint/utils": "^7.16.1",
|
|
42
|
-
"@eslint-react/ast": "1.5.28-beta.
|
|
43
|
-
"@eslint-react/core": "1.5.28-beta.
|
|
44
|
-
"@eslint-react/
|
|
45
|
-
"@eslint-react/
|
|
46
|
-
"@eslint-react/tools": "1.5.28-beta.
|
|
47
|
-
"@eslint-react/
|
|
48
|
-
"@eslint-react/
|
|
42
|
+
"@eslint-react/ast": "1.5.28-beta.4",
|
|
43
|
+
"@eslint-react/core": "1.5.28-beta.4",
|
|
44
|
+
"@eslint-react/shared": "1.5.28-beta.4",
|
|
45
|
+
"@eslint-react/jsx": "1.5.28-beta.4",
|
|
46
|
+
"@eslint-react/tools": "1.5.28-beta.4",
|
|
47
|
+
"@eslint-react/var": "1.5.28-beta.4",
|
|
48
|
+
"@eslint-react/types": "1.5.28-beta.4"
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
51
51
|
"string-ts": "2.2.0",
|