@eslint-react/core 1.28.1-beta.0 → 1.28.1-beta.2
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.d.mts +50 -2099
- package/dist/index.d.ts +50 -2099
- package/dist/index.js +105 -118
- package/dist/index.mjs +101 -110
- package/package.json +6 -6
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as AST5 from '@eslint-react/ast';
|
|
2
2
|
import { flip, dual, constFalse, identity, _ } from '@eslint-react/eff';
|
|
3
3
|
import * as JSX3 from '@eslint-react/jsx';
|
|
4
4
|
import { DEFAULT_ESLINT_REACT_SETTINGS as DEFAULT_ESLINT_REACT_SETTINGS$1, unsafeDecodeSettings, getId } from '@eslint-react/shared';
|
|
@@ -9,6 +9,21 @@ import birecord from 'birecord';
|
|
|
9
9
|
|
|
10
10
|
// src/component/component-collector.ts
|
|
11
11
|
|
|
12
|
+
// src/constants.ts
|
|
13
|
+
var DISPLAY_NAME_ASSIGNMENT_SELECTOR = [
|
|
14
|
+
"AssignmentExpression",
|
|
15
|
+
"[type]",
|
|
16
|
+
"[operator='=']",
|
|
17
|
+
"[left.type='MemberExpression']",
|
|
18
|
+
"[left.property.name='displayName']"
|
|
19
|
+
].join("");
|
|
20
|
+
|
|
21
|
+
// src/hook/hook-name.ts
|
|
22
|
+
var RE_HOOK_NAME = /^use[A-Z\d]/u;
|
|
23
|
+
function isReactHookName(name) {
|
|
24
|
+
return name === "use" || RE_HOOK_NAME.test(name);
|
|
25
|
+
}
|
|
26
|
+
|
|
12
27
|
// ../../node_modules/.pnpm/valibot@1.0.0-rc.2_typescript@5.8.1-rc/node_modules/valibot/dist/index.js
|
|
13
28
|
var store;
|
|
14
29
|
// @__NO_SIDE_EFFECTS__
|
|
@@ -499,7 +514,7 @@ function isInitializedFromReact(name, importSource, initialScope) {
|
|
|
499
514
|
}
|
|
500
515
|
const args = getRequireExpressionArguments(init);
|
|
501
516
|
const arg0 = args?.[0];
|
|
502
|
-
if (arg0 == null || !
|
|
517
|
+
if (arg0 == null || !AST5.isKindOfLiteral(arg0, "string")) {
|
|
503
518
|
return false;
|
|
504
519
|
}
|
|
505
520
|
return arg0.value === importSource || arg0.value.startsWith(`${importSource}/`);
|
|
@@ -530,93 +545,74 @@ function isFromReactStrict(node, name, importSource, initialScope) {
|
|
|
530
545
|
}
|
|
531
546
|
}
|
|
532
547
|
function isFromReact(name) {
|
|
533
|
-
return (context, node) => {
|
|
548
|
+
return dual(2, (context, node) => {
|
|
549
|
+
if (node == null) return false;
|
|
534
550
|
const { importSource = defaultImportSource, skipImportCheck = true } = unsafeDecodeSettings(context.settings);
|
|
535
551
|
if (skipImportCheck) return isFromReactLoose(node, name);
|
|
536
552
|
return isFromReactStrict(node, name, importSource, context.sourceCode.getScope(node));
|
|
537
|
-
};
|
|
553
|
+
});
|
|
538
554
|
}
|
|
539
|
-
function
|
|
540
|
-
return (context, node) => {
|
|
555
|
+
function isFromReactObject(objectName, propertyName) {
|
|
556
|
+
return dual(2, (context, node) => {
|
|
557
|
+
if (node?.type !== AST_NODE_TYPES.MemberExpression) return false;
|
|
541
558
|
const { importSource = defaultImportSource, skipImportCheck = true } = unsafeDecodeSettings(context.settings);
|
|
542
559
|
const { object: object2, property } = node;
|
|
543
|
-
if (skipImportCheck) return isFromReactLoose(object2,
|
|
560
|
+
if (skipImportCheck) return isFromReactLoose(object2, objectName) && isFromReactLoose(property, propertyName);
|
|
544
561
|
return isFromReactStrict(
|
|
545
562
|
object2,
|
|
546
|
-
|
|
563
|
+
objectName,
|
|
547
564
|
importSource,
|
|
548
565
|
context.sourceCode.getScope(object2)
|
|
549
|
-
) &&
|
|
550
|
-
};
|
|
566
|
+
) && isFromReactLoose(property, propertyName);
|
|
567
|
+
});
|
|
551
568
|
}
|
|
552
|
-
|
|
553
|
-
// src/utils/is-call-from-react.ts
|
|
554
569
|
function isCallFromReact(name) {
|
|
555
570
|
return dual(2, (context, node) => {
|
|
556
571
|
if (node.type !== AST_NODE_TYPES.CallExpression) return false;
|
|
557
|
-
if (!AST8.isOneOf([AST_NODE_TYPES.Identifier, AST_NODE_TYPES.MemberExpression])(node.callee)) return false;
|
|
558
572
|
return isFromReact(name)(context, node.callee);
|
|
559
573
|
});
|
|
560
574
|
}
|
|
561
|
-
function
|
|
575
|
+
function isCallFromReactObject(objectName, propertyName) {
|
|
562
576
|
return dual(2, (context, node) => {
|
|
563
577
|
if (node.type !== AST_NODE_TYPES.CallExpression) return false;
|
|
564
|
-
|
|
565
|
-
return isFromReactMember(pragmaMemberName, name)(context, node.callee);
|
|
578
|
+
return isFromReactObject(objectName, propertyName)(context, node.callee);
|
|
566
579
|
});
|
|
567
580
|
}
|
|
568
|
-
var DISPLAY_NAME_ASSIGNMENT_SELECTOR = [
|
|
569
|
-
"AssignmentExpression",
|
|
570
|
-
"[type]",
|
|
571
|
-
"[operator='=']",
|
|
572
|
-
"[left.type='MemberExpression']",
|
|
573
|
-
"[left.property.name='displayName']"
|
|
574
|
-
].join("");
|
|
575
|
-
function isDisplayNameAssignment(node) {
|
|
576
|
-
if (node == null) return false;
|
|
577
|
-
return node.type === AST_NODE_TYPES.AssignmentExpression && node.operator === "=" && node.left.type === AST_NODE_TYPES.MemberExpression && node.left.property.type === AST_NODE_TYPES.Identifier && node.left.property.name === "displayName";
|
|
578
|
-
}
|
|
579
581
|
|
|
580
582
|
// src/utils/is-react-api.ts
|
|
581
|
-
function
|
|
582
|
-
return
|
|
583
|
-
}
|
|
584
|
-
function
|
|
585
|
-
return
|
|
586
|
-
}
|
|
587
|
-
var isChildrenCount =
|
|
588
|
-
var isChildrenForEach =
|
|
589
|
-
var isChildrenMap =
|
|
590
|
-
var isChildrenOnly =
|
|
591
|
-
var isChildrenToArray =
|
|
592
|
-
var isCloneElement =
|
|
593
|
-
var isCreateContext =
|
|
594
|
-
var isCreateElement =
|
|
595
|
-
var isCreateRef =
|
|
596
|
-
var isForwardRef =
|
|
597
|
-
var isMemo =
|
|
598
|
-
var isChildrenCountCall =
|
|
599
|
-
var isChildrenForEachCall =
|
|
600
|
-
var isChildrenMapCall =
|
|
601
|
-
var isChildrenOnlyCall =
|
|
602
|
-
var isChildrenToArrayCall =
|
|
603
|
-
var isCloneElementCall =
|
|
604
|
-
var isCreateContextCall =
|
|
605
|
-
var isCreateElementCall =
|
|
606
|
-
var isCreateRefCall =
|
|
607
|
-
var isForwardRefCall =
|
|
608
|
-
var isMemoCall =
|
|
609
|
-
|
|
610
|
-
// src/hook/hook-name.ts
|
|
611
|
-
var RE_HOOK_NAME = /^use[A-Z\d]/u;
|
|
612
|
-
function isReactHookName(name) {
|
|
613
|
-
return name === "use" || RE_HOOK_NAME.test(name);
|
|
614
|
-
}
|
|
583
|
+
function isReactAPI(arg0, arg1) {
|
|
584
|
+
return arg1 == null ? isFromReact(arg0) : isFromReactObject(arg0, arg1);
|
|
585
|
+
}
|
|
586
|
+
function isReactAPICall(arg0, arg1) {
|
|
587
|
+
return arg1 == null ? isCallFromReact(arg0) : isCallFromReactObject(arg0, arg1);
|
|
588
|
+
}
|
|
589
|
+
var isChildrenCount = isReactAPI("Children", "count");
|
|
590
|
+
var isChildrenForEach = isReactAPI("Children", "forEach");
|
|
591
|
+
var isChildrenMap = isReactAPI("Children", "map");
|
|
592
|
+
var isChildrenOnly = isReactAPI("Children", "only");
|
|
593
|
+
var isChildrenToArray = isReactAPI("Children", "toArray");
|
|
594
|
+
var isCloneElement = isReactAPI("cloneElement");
|
|
595
|
+
var isCreateContext = isReactAPI("createContext");
|
|
596
|
+
var isCreateElement = isReactAPI("createElement");
|
|
597
|
+
var isCreateRef = isReactAPI("createRef");
|
|
598
|
+
var isForwardRef = isReactAPI("forwardRef");
|
|
599
|
+
var isMemo = isReactAPI("memo");
|
|
600
|
+
var isChildrenCountCall = isReactAPICall("Children", "count");
|
|
601
|
+
var isChildrenForEachCall = isReactAPICall("Children", "forEach");
|
|
602
|
+
var isChildrenMapCall = isReactAPICall("Children", "map");
|
|
603
|
+
var isChildrenOnlyCall = isReactAPICall("Children", "only");
|
|
604
|
+
var isChildrenToArrayCall = isReactAPICall("Children", "toArray");
|
|
605
|
+
var isCloneElementCall = isReactAPICall("cloneElement");
|
|
606
|
+
var isCreateContextCall = isReactAPICall("createContext");
|
|
607
|
+
var isCreateElementCall = isReactAPICall("createElement");
|
|
608
|
+
var isCreateRefCall = isReactAPICall("createRef");
|
|
609
|
+
var isForwardRefCall = isReactAPICall("forwardRef");
|
|
610
|
+
var isMemoCall = isReactAPICall("memo");
|
|
615
611
|
|
|
616
612
|
// src/hook/is.ts
|
|
617
613
|
function isReactHook(node) {
|
|
618
614
|
if (node == null) return _;
|
|
619
|
-
const id =
|
|
615
|
+
const id = AST5.getFunctionIdentifier(node);
|
|
620
616
|
return id?.name != null && isReactHookName(id.name);
|
|
621
617
|
}
|
|
622
618
|
function isReactHookCall(node) {
|
|
@@ -710,15 +706,12 @@ var isUseStateCall = flip(isReactHookCallWithName)("useState");
|
|
|
710
706
|
var isUseSyncExternalStoreCall = flip(isReactHookCallWithName)("useSyncExternalStore");
|
|
711
707
|
var isUseTransitionCall = flip(isReactHookCallWithName)("useTransition");
|
|
712
708
|
|
|
713
|
-
// src/hook/
|
|
714
|
-
function isInsideReactHook(node) {
|
|
715
|
-
return isReactHook(AST8.findParentNode(node, AST8.isFunction));
|
|
716
|
-
}
|
|
709
|
+
// src/hook/hook-collector.ts
|
|
717
710
|
function useHookCollector() {
|
|
718
711
|
const hooks = /* @__PURE__ */ new Map();
|
|
719
712
|
const functionEntries = [];
|
|
720
713
|
const onFunctionEnter = (node) => {
|
|
721
|
-
const id =
|
|
714
|
+
const id = AST5.getFunctionIdentifier(node);
|
|
722
715
|
const key = getId();
|
|
723
716
|
const name = id?.name;
|
|
724
717
|
if (name != null && isReactHookName(name)) {
|
|
@@ -814,7 +807,7 @@ function isComponentWrapperCall(context, node) {
|
|
|
814
807
|
return isMemoCall(context, node) || isForwardRefCall(context, node) || isReactHookCallWithNameLoose(node)("useCallback");
|
|
815
808
|
}
|
|
816
809
|
function getFunctionComponentIdentifier(context, node) {
|
|
817
|
-
const functionId =
|
|
810
|
+
const functionId = AST5.getFunctionIdentifier(node);
|
|
818
811
|
if (functionId != null) {
|
|
819
812
|
return functionId;
|
|
820
813
|
}
|
|
@@ -841,19 +834,6 @@ function hasNoneOrValidComponentName(context, node) {
|
|
|
841
834
|
const name = Array.isArray(id) ? id.at(-1)?.name : id.name;
|
|
842
835
|
return name != null && isComponentName(name);
|
|
843
836
|
}
|
|
844
|
-
function isInsideCreateElementProps(context, node) {
|
|
845
|
-
const call = AST8.findParentNode(node, isCreateElementCall(context));
|
|
846
|
-
if (call == null) return false;
|
|
847
|
-
const prop = AST8.findParentNode(node, AST8.is(AST_NODE_TYPES.ObjectExpression));
|
|
848
|
-
if (prop == null) return false;
|
|
849
|
-
return prop === call.arguments[1];
|
|
850
|
-
}
|
|
851
|
-
function isChildrenOfCreateElement(context, node) {
|
|
852
|
-
const parent = node.parent;
|
|
853
|
-
if (parent == null || parent.type !== AST_NODE_TYPES.CallExpression) return false;
|
|
854
|
-
if (!isCreateElementCall(context, parent)) return false;
|
|
855
|
-
return parent.arguments.slice(2).some((arg) => arg === node);
|
|
856
|
-
}
|
|
857
837
|
function isClassComponent(node) {
|
|
858
838
|
if ("superClass" in node && node.superClass != null) {
|
|
859
839
|
const re = /^(?:Pure)?Component$/u;
|
|
@@ -881,28 +861,28 @@ function isPureComponent(node) {
|
|
|
881
861
|
|
|
882
862
|
// src/component/component-lifecycle.ts
|
|
883
863
|
function isComponentDidMount(node) {
|
|
884
|
-
return
|
|
864
|
+
return AST5.isMethodOrProperty(node) && node.key.type === AST_NODE_TYPES.Identifier && node.key.name === "componentDidMount";
|
|
885
865
|
}
|
|
886
866
|
function isComponentWillUnmount(node) {
|
|
887
|
-
return
|
|
867
|
+
return AST5.isMethodOrProperty(node) && node.key.type === AST_NODE_TYPES.Identifier && node.key.name === "componentWillUnmount";
|
|
888
868
|
}
|
|
889
869
|
function isComponentDidCatch(node) {
|
|
890
|
-
return
|
|
870
|
+
return AST5.isMethodOrProperty(node) && !node.static && node.key.type === AST_NODE_TYPES.Identifier && node.key.name === "componentDidCatch";
|
|
891
871
|
}
|
|
892
872
|
function isGetDerivedStateFromError(node) {
|
|
893
|
-
return
|
|
873
|
+
return AST5.isMethodOrProperty(node) && node.static && node.key.type === AST_NODE_TYPES.Identifier && node.key.name === "getDerivedStateFromError";
|
|
894
874
|
}
|
|
895
875
|
function isGetDerivedStateFromProps(node) {
|
|
896
|
-
return
|
|
876
|
+
return AST5.isMethodOrProperty(node) && node.static && node.key.type === AST_NODE_TYPES.Identifier && node.key.name === "getDerivedStateFromProps";
|
|
897
877
|
}
|
|
898
878
|
function isFunctionOfComponentDidMount(node) {
|
|
899
|
-
return
|
|
879
|
+
return AST5.isFunction(node) && isComponentDidMount(node.parent) && node.parent.value === node;
|
|
900
880
|
}
|
|
901
881
|
function isFunctionOfComponentWillUnmount(node) {
|
|
902
|
-
return
|
|
882
|
+
return AST5.isFunction(node) && isComponentWillUnmount(node.parent) && node.parent.value === node;
|
|
903
883
|
}
|
|
904
884
|
function isRenderMethodLike(node) {
|
|
905
|
-
return
|
|
885
|
+
return AST5.isMethodOrProperty(node) && node.key.type === AST_NODE_TYPES.Identifier && node.key.name === "render" && node.parent.parent.type === AST_NODE_TYPES.ClassDeclaration;
|
|
906
886
|
}
|
|
907
887
|
function isFunctionOfRenderMethod(node) {
|
|
908
888
|
if (!isRenderMethodLike(node.parent)) {
|
|
@@ -911,7 +891,7 @@ function isFunctionOfRenderMethod(node) {
|
|
|
911
891
|
return isClassComponent(node.parent.parent.parent);
|
|
912
892
|
}
|
|
913
893
|
function isInsideRenderMethod(node) {
|
|
914
|
-
return
|
|
894
|
+
return AST5.findParentNode(node, (node2) => isRenderMethodLike(node2) && isClassComponent(node2.parent.parent)) != null;
|
|
915
895
|
}
|
|
916
896
|
|
|
917
897
|
// src/component/hierarchy.ts
|
|
@@ -919,7 +899,7 @@ function hasValidHierarchy(context, node, hint) {
|
|
|
919
899
|
if (isChildrenOfCreateElement(context, node) || isFunctionOfRenderMethod(node)) {
|
|
920
900
|
return false;
|
|
921
901
|
}
|
|
922
|
-
if (hint & ERComponentHint.SkipMapCallback &&
|
|
902
|
+
if (hint & ERComponentHint.SkipMapCallback && AST5.isMapCallLoose(node.parent)) {
|
|
923
903
|
return false;
|
|
924
904
|
}
|
|
925
905
|
if (hint & ERComponentHint.SkipObjectMethod && isFunctionOfObjectMethod(node.parent)) {
|
|
@@ -931,9 +911,9 @@ function hasValidHierarchy(context, node, hint) {
|
|
|
931
911
|
if (hint & ERComponentHint.SkipClassProperty && isFunctionOfClassProperty(node.parent)) {
|
|
932
912
|
return false;
|
|
933
913
|
}
|
|
934
|
-
const boundaryNode =
|
|
914
|
+
const boundaryNode = AST5.findParentNode(
|
|
935
915
|
node,
|
|
936
|
-
|
|
916
|
+
AST5.isOneOf([
|
|
937
917
|
AST_NODE_TYPES.JSXExpressionContainer,
|
|
938
918
|
AST_NODE_TYPES.ArrowFunctionExpression,
|
|
939
919
|
AST_NODE_TYPES.FunctionExpression,
|
|
@@ -943,6 +923,12 @@ function hasValidHierarchy(context, node, hint) {
|
|
|
943
923
|
);
|
|
944
924
|
return boundaryNode == null || boundaryNode.type !== AST_NODE_TYPES.JSXExpressionContainer;
|
|
945
925
|
}
|
|
926
|
+
function isChildrenOfCreateElement(context, node) {
|
|
927
|
+
const parent = node.parent;
|
|
928
|
+
if (parent == null || parent.type !== AST_NODE_TYPES.CallExpression) return false;
|
|
929
|
+
if (!isCreateElementCall(context, parent)) return false;
|
|
930
|
+
return parent.arguments.slice(2).some((arg) => arg === node);
|
|
931
|
+
}
|
|
946
932
|
function isFunctionOfClassMethod(node) {
|
|
947
933
|
return (node.type === AST_NODE_TYPES.FunctionExpression || node.type === AST_NODE_TYPES.ArrowFunctionExpression) && node.parent.type === AST_NODE_TYPES.MethodDefinition;
|
|
948
934
|
}
|
|
@@ -954,8 +940,12 @@ function isFunctionOfObjectMethod(node) {
|
|
|
954
940
|
}
|
|
955
941
|
|
|
956
942
|
// src/component/component-collector.ts
|
|
957
|
-
function useComponentCollector(context,
|
|
958
|
-
const {
|
|
943
|
+
function useComponentCollector(context, options = {}) {
|
|
944
|
+
const {
|
|
945
|
+
collectDisplayName = false,
|
|
946
|
+
collectHookCalls = false,
|
|
947
|
+
hint = DEFAULT_COMPONENT_HINT
|
|
948
|
+
} = options;
|
|
959
949
|
const jsxCtx = { getScope: (node) => context.sourceCode.getScope(node) };
|
|
960
950
|
const components = /* @__PURE__ */ new Map();
|
|
961
951
|
const functionEntries = [];
|
|
@@ -968,7 +958,7 @@ function useComponentCollector(context, hint = DEFAULT_COMPONENT_HINT, options =
|
|
|
968
958
|
const entry = functionEntries.at(-1);
|
|
969
959
|
if (entry == null) return;
|
|
970
960
|
if (!entry.isComponent) return functionEntries.pop();
|
|
971
|
-
const shouldDrop =
|
|
961
|
+
const shouldDrop = AST5.getNestedReturnStatements(entry.node.body).slice().reverse().some((r) => {
|
|
972
962
|
return context.sourceCode.getScope(r).block === entry.node && r.argument != null && !JSX3.isJSXValue(r.argument, jsxCtx, hint);
|
|
973
963
|
});
|
|
974
964
|
if (shouldDrop) {
|
|
@@ -995,7 +985,7 @@ function useComponentCollector(context, hint = DEFAULT_COMPONENT_HINT, options =
|
|
|
995
985
|
const { body } = entry.node;
|
|
996
986
|
const isComponent = hasNoneOrValidComponentName(context, entry.node) && JSX3.isJSXValue(body, jsxCtx, hint) && hasValidHierarchy(context, entry.node, hint);
|
|
997
987
|
if (!isComponent) return;
|
|
998
|
-
const initPath =
|
|
988
|
+
const initPath = AST5.getFunctionInitPath(entry.node);
|
|
999
989
|
const id = getFunctionComponentIdentifier(context, entry.node);
|
|
1000
990
|
const name = getComponentNameFromIdentifier(id);
|
|
1001
991
|
const key = getId();
|
|
@@ -1036,7 +1026,7 @@ function useComponentCollector(context, hint = DEFAULT_COMPONENT_HINT, options =
|
|
|
1036
1026
|
const isComponent = hasNoneOrValidComponentName(context, entry.node) && JSX3.isJSXValue(node.argument, jsxCtx, hint) && hasValidHierarchy(context, entry.node, hint);
|
|
1037
1027
|
if (!isComponent) return;
|
|
1038
1028
|
entry.isComponent = true;
|
|
1039
|
-
const initPath =
|
|
1029
|
+
const initPath = AST5.getFunctionInitPath(entry.node);
|
|
1040
1030
|
const id = getFunctionComponentIdentifier(context, entry.node);
|
|
1041
1031
|
const name = getComponentNameFromIdentifier(id);
|
|
1042
1032
|
components.set(entry.key, {
|
|
@@ -1057,10 +1047,10 @@ function useComponentCollector(context, hint = DEFAULT_COMPONENT_HINT, options =
|
|
|
1057
1047
|
}
|
|
1058
1048
|
function getComponentFlag(initPath) {
|
|
1059
1049
|
let flag = ERComponentFlag.None;
|
|
1060
|
-
if (initPath != null &&
|
|
1050
|
+
if (initPath != null && AST5.hasCallInFunctionInitPath("memo", initPath)) {
|
|
1061
1051
|
flag |= ERComponentFlag.Memo;
|
|
1062
1052
|
}
|
|
1063
|
-
if (initPath != null &&
|
|
1053
|
+
if (initPath != null && AST5.hasCallInFunctionInitPath("forwardRef", initPath)) {
|
|
1064
1054
|
flag |= ERComponentFlag.ForwardRef;
|
|
1065
1055
|
}
|
|
1066
1056
|
return flag;
|
|
@@ -1077,7 +1067,7 @@ function useComponentCollectorLegacy() {
|
|
|
1077
1067
|
if (!isClassComponent(node)) {
|
|
1078
1068
|
return;
|
|
1079
1069
|
}
|
|
1080
|
-
const id =
|
|
1070
|
+
const id = AST5.getClassIdentifier(node);
|
|
1081
1071
|
const key = getId();
|
|
1082
1072
|
const flag = isPureComponent(node) ? ERComponentFlag.PureComponent : ERComponentFlag.None;
|
|
1083
1073
|
components.set(
|
|
@@ -1110,7 +1100,7 @@ var ERPhaseRelevance = birecord({
|
|
|
1110
1100
|
var isInversePhase = dual(2, (a, b) => ERPhaseRelevance.get(a) === b);
|
|
1111
1101
|
function isRenderFunctionLoose(context, node) {
|
|
1112
1102
|
const { body, parent } = node;
|
|
1113
|
-
if (
|
|
1103
|
+
if (AST5.getFunctionIdentifier(node)?.name.startsWith("render")) {
|
|
1114
1104
|
return parent.type === AST_NODE_TYPES.JSXExpressionContainer && parent.parent.type === AST_NODE_TYPES.JSXAttribute && parent.parent.name.type === AST_NODE_TYPES.JSXIdentifier && parent.parent.name.name.startsWith("render");
|
|
1115
1105
|
}
|
|
1116
1106
|
return JSX3.isJSXValue(
|
|
@@ -1125,7 +1115,7 @@ function isRenderPropLoose(context, node) {
|
|
|
1125
1115
|
if (node.name.type !== AST_NODE_TYPES.JSXIdentifier) {
|
|
1126
1116
|
return false;
|
|
1127
1117
|
}
|
|
1128
|
-
return node.name.name.startsWith("render") && node.value?.type === AST_NODE_TYPES.JSXExpressionContainer &&
|
|
1118
|
+
return node.name.name.startsWith("render") && node.value?.type === AST_NODE_TYPES.JSXExpressionContainer && AST5.isFunction(node.value.expression) && isRenderFunctionLoose(context, node.value.expression);
|
|
1129
1119
|
}
|
|
1130
1120
|
function isDirectValueOfRenderPropertyLoose(node) {
|
|
1131
1121
|
const matching = (node2) => {
|
|
@@ -1137,7 +1127,7 @@ function isDeclaredInRenderPropLoose(node) {
|
|
|
1137
1127
|
if (isDirectValueOfRenderPropertyLoose(node)) {
|
|
1138
1128
|
return true;
|
|
1139
1129
|
}
|
|
1140
|
-
const parent =
|
|
1130
|
+
const parent = AST5.findParentNode(node, AST5.is(AST_NODE_TYPES.JSXExpressionContainer))?.parent;
|
|
1141
1131
|
if (parent?.type !== AST_NODE_TYPES.JSXAttribute) {
|
|
1142
1132
|
return false;
|
|
1143
1133
|
}
|
|
@@ -1145,17 +1135,18 @@ function isDeclaredInRenderPropLoose(node) {
|
|
|
1145
1135
|
}
|
|
1146
1136
|
function isThisSetState(node) {
|
|
1147
1137
|
const { callee } = node;
|
|
1148
|
-
return callee.type === AST_NODE_TYPES.MemberExpression &&
|
|
1138
|
+
return callee.type === AST_NODE_TYPES.MemberExpression && AST5.isThisExpression(callee.object) && callee.property.type === AST_NODE_TYPES.Identifier && callee.property.name === "setState";
|
|
1149
1139
|
}
|
|
1150
1140
|
function isFunctionOfUseEffectSetup(node) {
|
|
1151
1141
|
if (node == null) return _;
|
|
1152
1142
|
return node.parent?.type === AST_NODE_TYPES.CallExpression && node.parent.callee !== node && node.parent.callee.type === AST_NODE_TYPES.Identifier && node.parent.arguments.at(0) === node && isUseEffectCallLoose(node.parent);
|
|
1153
1143
|
}
|
|
1154
1144
|
function isFunctionOfUseEffectCleanup(node) {
|
|
1155
|
-
|
|
1156
|
-
const
|
|
1157
|
-
const
|
|
1158
|
-
|
|
1145
|
+
if (node == null) return _;
|
|
1146
|
+
const returnStatement = AST5.findParentNode(node, AST5.is(AST_NODE_TYPES.ReturnStatement));
|
|
1147
|
+
const enclosingFunction = AST5.findParentNode(node, AST5.isFunction);
|
|
1148
|
+
const functionOfReturnStatement = AST5.findParentNode(returnStatement, AST5.isFunction);
|
|
1149
|
+
return enclosingFunction === functionOfReturnStatement && isFunctionOfUseEffectSetup(enclosingFunction);
|
|
1159
1150
|
}
|
|
1160
1151
|
|
|
1161
|
-
export { DEFAULT_COMPONENT_HINT, DISPLAY_NAME_ASSIGNMENT_SELECTOR, ERComponentFlag, ERComponentHint, ERPhaseRelevance, RE_COMPONENT_NAME, RE_HOOK_NAME, getComponentNameFromIdentifier, getFunctionComponentIdentifier, hasNoneOrValidComponentName, hasValidHierarchy, isCallFromReact,
|
|
1152
|
+
export { DEFAULT_COMPONENT_HINT, DISPLAY_NAME_ASSIGNMENT_SELECTOR, ERComponentFlag, ERComponentHint, ERPhaseRelevance, RE_COMPONENT_NAME, RE_HOOK_NAME, getComponentNameFromIdentifier, getFunctionComponentIdentifier, hasNoneOrValidComponentName, hasValidHierarchy, isCallFromReact, isCallFromReactObject, isChildrenCount, isChildrenCountCall, isChildrenForEach, isChildrenForEachCall, isChildrenMap, isChildrenMapCall, isChildrenOnly, isChildrenOnlyCall, isChildrenToArray, isChildrenToArrayCall, isClassComponent, isCloneElement, isCloneElementCall, isComponentDidCatch, isComponentDidMount, isComponentName, isComponentWillUnmount, isCreateContext, isCreateContextCall, isCreateElement, isCreateElementCall, isCreateRef, isCreateRefCall, isDeclaredInRenderPropLoose, isDirectValueOfRenderPropertyLoose, isForwardRef, isForwardRefCall, isFromReact, isFromReactLoose, isFromReactObject, isFromReactStrict, isFunctionOfComponentDidMount, isFunctionOfComponentWillUnmount, isFunctionOfRenderMethod, isFunctionOfUseEffectCleanup, isFunctionOfUseEffectSetup, isGetDerivedStateFromError, isGetDerivedStateFromProps, isInitializedFromReact, isInsideRenderMethod, isInversePhase, isMemo, isMemoCall, isPureComponent, isReactAPI, isReactAPICall, isReactHook, isReactHookCall, isReactHookCallWithName, isReactHookCallWithNameAlias, isReactHookCallWithNameLoose, isReactHookName, isRenderFunctionLoose, isRenderMethodLike, isRenderPropLoose, isThisSetState, isUseCallbackCall, isUseContextCall, isUseDebugValueCall, isUseDeferredValueCall, isUseEffectCall, isUseEffectCallLoose, isUseIdCall, isUseImperativeHandleCall, isUseInsertionEffectCall, isUseLayoutEffectCall, isUseMemoCall, isUseReducerCall, isUseRefCall, isUseStateCall, isUseSyncExternalStoreCall, isUseTransitionCall, useComponentCollector, useComponentCollectorLegacy, useHookCollector };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eslint-react/core",
|
|
3
|
-
"version": "1.28.1-beta.
|
|
3
|
+
"version": "1.28.1-beta.2",
|
|
4
4
|
"description": "ESLint React's ESLint utility module for static analysis of React core APIs and Patterns.",
|
|
5
5
|
"homepage": "https://github.com/Rel1cx/eslint-react",
|
|
6
6
|
"bugs": {
|
|
@@ -41,11 +41,11 @@
|
|
|
41
41
|
"@typescript-eslint/utils": "^8.25.0",
|
|
42
42
|
"birecord": "^0.1.1",
|
|
43
43
|
"ts-pattern": "^5.6.2",
|
|
44
|
-
"@eslint-react/ast": "1.28.1-beta.
|
|
45
|
-
"@eslint-react/
|
|
46
|
-
"@eslint-react/
|
|
47
|
-
"@eslint-react/
|
|
48
|
-
"@eslint-react/var": "1.28.1-beta.
|
|
44
|
+
"@eslint-react/ast": "1.28.1-beta.2",
|
|
45
|
+
"@eslint-react/shared": "1.28.1-beta.2",
|
|
46
|
+
"@eslint-react/eff": "1.28.1-beta.2",
|
|
47
|
+
"@eslint-react/jsx": "1.28.1-beta.2",
|
|
48
|
+
"@eslint-react/var": "1.28.1-beta.2"
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
51
51
|
"tsup": "^8.4.0",
|