eslint-plugin-react-x 2.8.1 → 2.8.2-beta.1
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 +203 -203
- package/package.json +6 -6
package/dist/index.js
CHANGED
|
@@ -3,15 +3,14 @@ import { AST_NODE_TYPES } from "@typescript-eslint/types";
|
|
|
3
3
|
import { ESLintUtils } from "@typescript-eslint/utils";
|
|
4
4
|
import { P, isMatching, match } from "ts-pattern";
|
|
5
5
|
import ts from "typescript";
|
|
6
|
-
import
|
|
7
|
-
import * as
|
|
6
|
+
import * as core from "@eslint-react/core";
|
|
7
|
+
import * as ast from "@eslint-react/ast";
|
|
8
8
|
import { findEnclosingAssignmentTarget, findVariable, getChildScopes, getObjectType, getVariableDefinitionNode, isAssignmentTargetEqual } from "@eslint-react/var";
|
|
9
9
|
import { constFalse, constTrue, flow, getOrElseUpdate, identity, unit } from "@eslint-react/eff";
|
|
10
10
|
import { compare } from "compare-versions";
|
|
11
11
|
import { getConstrainedTypeAtLocation, isTypeReadonly } from "@typescript-eslint/type-utils";
|
|
12
12
|
import { getStaticValue, isIdentifier, isVariableDeclarator } from "@typescript-eslint/utils/ast-utils";
|
|
13
13
|
import { isPropertyReadonlyInType, unionConstituents } from "ts-api-utils";
|
|
14
|
-
import "@typescript-eslint/utils/ts-eslint";
|
|
15
14
|
import { getTypeImmutability, isImmutable, isReadonlyDeep, isReadonlyShallow, isUnknown } from "is-immutable-type";
|
|
16
15
|
import { camelCase } from "string-ts";
|
|
17
16
|
|
|
@@ -68,7 +67,7 @@ const rules$7 = {
|
|
|
68
67
|
//#endregion
|
|
69
68
|
//#region package.json
|
|
70
69
|
var name$6 = "eslint-plugin-react-x";
|
|
71
|
-
var version = "2.8.1";
|
|
70
|
+
var version = "2.8.2-beta.1";
|
|
72
71
|
|
|
73
72
|
//#endregion
|
|
74
73
|
//#region src/utils/create-rule.ts
|
|
@@ -244,10 +243,10 @@ var jsx_key_before_spread_default = createRule({
|
|
|
244
243
|
});
|
|
245
244
|
function create$62(context) {
|
|
246
245
|
const { jsx } = {
|
|
247
|
-
...getJsxConfigFromContext(context),
|
|
248
|
-
...getJsxConfigFromAnnotation(context)
|
|
246
|
+
...core.getJsxConfigFromContext(context),
|
|
247
|
+
...core.getJsxConfigFromAnnotation(context)
|
|
249
248
|
};
|
|
250
|
-
if (jsx !== JsxEmit.ReactJSX && jsx !== JsxEmit.ReactJSXDev) return {};
|
|
249
|
+
if (jsx !== core.JsxEmit.ReactJSX && jsx !== core.JsxEmit.ReactJSXDev) return {};
|
|
251
250
|
return { JSXOpeningElement(node) {
|
|
252
251
|
let firstSpreadPropIndex = null;
|
|
253
252
|
for (const [index, prop] of node.attributes.entries()) {
|
|
@@ -280,11 +279,11 @@ var jsx_no_comment_textnodes_default = createRule({
|
|
|
280
279
|
});
|
|
281
280
|
function create$61(context) {
|
|
282
281
|
function hasCommentLike(node) {
|
|
283
|
-
if (
|
|
282
|
+
if (ast.isOneOf([AST_NODE_TYPES.JSXAttribute, AST_NODE_TYPES.JSXExpressionContainer])(node.parent)) return false;
|
|
284
283
|
return /^\s*\/(?:\/|\*)/mu.test(context.sourceCode.getText(node));
|
|
285
284
|
}
|
|
286
285
|
const visitorFunction = (node) => {
|
|
287
|
-
if (!
|
|
286
|
+
if (!ast.isOneOf([AST_NODE_TYPES.JSXElement, AST_NODE_TYPES.JSXFragment])(node.parent)) return;
|
|
288
287
|
if (!hasCommentLike(node)) return;
|
|
289
288
|
context.report({
|
|
290
289
|
messageId: "jsxNoCommentTextnodes",
|
|
@@ -416,7 +415,7 @@ function create$57(context) {
|
|
|
416
415
|
const policy = context.options[0] ?? defaultOptions$4[0];
|
|
417
416
|
return { JSXAttribute(node) {
|
|
418
417
|
const { value } = node;
|
|
419
|
-
const propName = getJsxAttributeName(context, node);
|
|
418
|
+
const propName = core.getJsxAttributeName(context, node);
|
|
420
419
|
switch (true) {
|
|
421
420
|
case policy === 1 && value?.type === AST_NODE_TYPES.JSXExpressionContainer && value.expression.type === AST_NODE_TYPES.Literal && value.expression.value === true:
|
|
422
421
|
context.report({
|
|
@@ -461,12 +460,12 @@ var jsx_shorthand_fragment_default = createRule({
|
|
|
461
460
|
function create$56(context) {
|
|
462
461
|
const policy = context.options[0] ?? defaultOptions$3[0];
|
|
463
462
|
const jsxConfig = {
|
|
464
|
-
...getJsxConfigFromContext(context),
|
|
465
|
-
...getJsxConfigFromAnnotation(context)
|
|
463
|
+
...core.getJsxConfigFromContext(context),
|
|
464
|
+
...core.getJsxConfigFromAnnotation(context)
|
|
466
465
|
};
|
|
467
466
|
const { jsxFragmentFactory } = jsxConfig;
|
|
468
467
|
return match(policy).with(1, () => ({ JSXElement(node) {
|
|
469
|
-
if (!isJsxFragmentElement(context, node, jsxConfig)) return;
|
|
468
|
+
if (!core.isJsxFragmentElement(context, node, jsxConfig)) return;
|
|
470
469
|
if (node.openingElement.attributes.length > 0) return;
|
|
471
470
|
context.report({
|
|
472
471
|
messageId: "jsxShorthandFragment",
|
|
@@ -507,10 +506,10 @@ var jsx_uses_react_default = createRule({
|
|
|
507
506
|
});
|
|
508
507
|
function create$55(context) {
|
|
509
508
|
const { jsx, jsxFactory, jsxFragmentFactory } = {
|
|
510
|
-
...getJsxConfigFromContext(context),
|
|
511
|
-
...getJsxConfigFromAnnotation(context)
|
|
509
|
+
...core.getJsxConfigFromContext(context),
|
|
510
|
+
...core.getJsxConfigFromAnnotation(context)
|
|
512
511
|
};
|
|
513
|
-
if (jsx === JsxEmit.ReactJSX || jsx === JsxEmit.ReactJSXDev) return {};
|
|
512
|
+
if (jsx === core.JsxEmit.ReactJSX || jsx === core.JsxEmit.ReactJSXDev) return {};
|
|
514
513
|
function handleJsxElement(node) {
|
|
515
514
|
context.sourceCode.markVariableAsUsed(jsxFactory, node);
|
|
516
515
|
debugReport(context, node, jsxFactory);
|
|
@@ -591,34 +590,34 @@ function create$53(context) {
|
|
|
591
590
|
const setStateStack = [];
|
|
592
591
|
return {
|
|
593
592
|
CallExpression(node) {
|
|
594
|
-
if (!isThisSetState(node)) return;
|
|
593
|
+
if (!core.isThisSetState(node)) return;
|
|
595
594
|
setStateStack.push([node, false]);
|
|
596
595
|
},
|
|
597
596
|
"CallExpression:exit"(node) {
|
|
598
|
-
if (!isThisSetState(node)) return;
|
|
597
|
+
if (!core.isThisSetState(node)) return;
|
|
599
598
|
setStateStack.pop();
|
|
600
599
|
},
|
|
601
600
|
ClassDeclaration(node) {
|
|
602
|
-
classStack.push([node, isClassComponent(node)]);
|
|
601
|
+
classStack.push([node, core.isClassComponent(node)]);
|
|
603
602
|
},
|
|
604
603
|
"ClassDeclaration:exit"() {
|
|
605
604
|
classStack.pop();
|
|
606
605
|
},
|
|
607
606
|
ClassExpression(node) {
|
|
608
|
-
classStack.push([node, isClassComponent(node)]);
|
|
607
|
+
classStack.push([node, core.isClassComponent(node)]);
|
|
609
608
|
},
|
|
610
609
|
"ClassExpression:exit"() {
|
|
611
610
|
classStack.pop();
|
|
612
611
|
},
|
|
613
612
|
MemberExpression(node) {
|
|
614
|
-
if (!
|
|
613
|
+
if (!ast.isThisExpressionLoose(node.object)) return;
|
|
615
614
|
const [currClass, isComponent = false] = classStack.at(-1) ?? [];
|
|
616
615
|
if (currClass == null || !isComponent) return;
|
|
617
616
|
const [currMethod, isStatic = false] = methodStack.at(-1) ?? [];
|
|
618
617
|
if (currMethod == null || isStatic) return;
|
|
619
618
|
const [setState, hasThisState = false] = setStateStack.at(-1) ?? [];
|
|
620
619
|
if (setState == null || hasThisState) return;
|
|
621
|
-
if (
|
|
620
|
+
if (ast.getPropertyName(node.property) !== "state") return;
|
|
622
621
|
context.report({
|
|
623
622
|
messageId: "noAccessStateInSetstate",
|
|
624
623
|
node
|
|
@@ -643,8 +642,8 @@ function create$53(context) {
|
|
|
643
642
|
if (currMethod == null || isStatic) return;
|
|
644
643
|
const [setState, hasThisState = false] = setStateStack.at(-1) ?? [];
|
|
645
644
|
if (setState == null || hasThisState) return;
|
|
646
|
-
if (node.init == null || !
|
|
647
|
-
if (!node.id.properties.some((prop) => prop.type === AST_NODE_TYPES.Property && isKeyLiteral$2(prop, prop.key) &&
|
|
645
|
+
if (node.init == null || !ast.isThisExpressionLoose(node.init) || node.id.type !== AST_NODE_TYPES.ObjectPattern) return;
|
|
646
|
+
if (!node.id.properties.some((prop) => prop.type === AST_NODE_TYPES.Property && isKeyLiteral$2(prop, prop.key) && ast.getPropertyName(prop.key) === "state")) return;
|
|
648
647
|
context.report({
|
|
649
648
|
messageId: "noAccessStateInSetstate",
|
|
650
649
|
node
|
|
@@ -684,7 +683,7 @@ function isUsingReactChildren(context, node) {
|
|
|
684
683
|
if (!isReactChildrenMethod(callee.property.name)) return false;
|
|
685
684
|
const initialScope = context.sourceCode.getScope(node);
|
|
686
685
|
if (callee.object.type === AST_NODE_TYPES.Identifier && callee.object.name === "Children") return true;
|
|
687
|
-
if (callee.object.type === AST_NODE_TYPES.MemberExpression && "name" in callee.object.object) return isInitializedFromReact(callee.object.object.name, initialScope, importSource);
|
|
686
|
+
if (callee.object.type === AST_NODE_TYPES.MemberExpression && "name" in callee.object.object) return core.isInitializedFromReact(callee.object.object.name, initialScope, importSource);
|
|
688
687
|
return false;
|
|
689
688
|
}
|
|
690
689
|
function getMapIndexParamName(context, node) {
|
|
@@ -696,7 +695,7 @@ function getMapIndexParamName(context, node) {
|
|
|
696
695
|
if (indexPosition === -1) return unit;
|
|
697
696
|
const callbackArg = node.arguments[isUsingReactChildren(context, node) ? 1 : 0];
|
|
698
697
|
if (callbackArg == null) return unit;
|
|
699
|
-
if (!
|
|
698
|
+
if (!ast.isOneOf([AST_NODE_TYPES.ArrowFunctionExpression, AST_NODE_TYPES.FunctionExpression])(callbackArg)) return unit;
|
|
700
699
|
const { params } = callbackArg;
|
|
701
700
|
if (params.length < indexPosition + 1) return unit;
|
|
702
701
|
const param = params.at(indexPosition);
|
|
@@ -724,7 +723,7 @@ function create$52(context) {
|
|
|
724
723
|
return node.type === AST_NODE_TYPES.Identifier && indexParamNames.some((name) => name != null && name === node.name);
|
|
725
724
|
}
|
|
726
725
|
function isCreateOrCloneElementCall(node) {
|
|
727
|
-
return isCreateElementCall(context, node) || isCloneElementCall(context, node);
|
|
726
|
+
return core.isCreateElementCall(context, node) || core.isCloneElementCall(context, node);
|
|
728
727
|
}
|
|
729
728
|
function getReportDescriptors(node) {
|
|
730
729
|
switch (node.type) {
|
|
@@ -798,7 +797,7 @@ var no_children_count_default = createRule({
|
|
|
798
797
|
});
|
|
799
798
|
function create$51(context) {
|
|
800
799
|
return { MemberExpression(node) {
|
|
801
|
-
if (isChildrenCount(context, node)) context.report({
|
|
800
|
+
if (core.isChildrenCount(context, node)) context.report({
|
|
802
801
|
messageId: "noChildrenCount",
|
|
803
802
|
node: node.property
|
|
804
803
|
});
|
|
@@ -821,7 +820,7 @@ var no_children_for_each_default = createRule({
|
|
|
821
820
|
});
|
|
822
821
|
function create$50(context) {
|
|
823
822
|
return { MemberExpression(node) {
|
|
824
|
-
if (isChildrenForEach(context, node)) context.report({
|
|
823
|
+
if (core.isChildrenForEach(context, node)) context.report({
|
|
825
824
|
messageId: "noChildrenForEach",
|
|
826
825
|
node: node.property
|
|
827
826
|
});
|
|
@@ -844,7 +843,7 @@ var no_children_map_default = createRule({
|
|
|
844
843
|
});
|
|
845
844
|
function create$49(context) {
|
|
846
845
|
return { MemberExpression(node) {
|
|
847
|
-
if (isChildrenMap(context, node)) context.report({
|
|
846
|
+
if (core.isChildrenMap(context, node)) context.report({
|
|
848
847
|
messageId: "noChildrenMap",
|
|
849
848
|
node: node.property
|
|
850
849
|
});
|
|
@@ -867,7 +866,7 @@ var no_children_only_default = createRule({
|
|
|
867
866
|
});
|
|
868
867
|
function create$48(context) {
|
|
869
868
|
return { MemberExpression(node) {
|
|
870
|
-
if (isChildrenOnly(context, node)) context.report({
|
|
869
|
+
if (core.isChildrenOnly(context, node)) context.report({
|
|
871
870
|
messageId: "noChildrenOnly",
|
|
872
871
|
node: node.property
|
|
873
872
|
});
|
|
@@ -890,7 +889,7 @@ var no_children_prop_default = createRule({
|
|
|
890
889
|
});
|
|
891
890
|
function create$47(context) {
|
|
892
891
|
return { JSXElement(node) {
|
|
893
|
-
const childrenProp = getJsxAttribute(context, node)("children");
|
|
892
|
+
const childrenProp = core.getJsxAttribute(context, node)("children");
|
|
894
893
|
if (childrenProp != null) context.report({
|
|
895
894
|
messageId: "noChildrenProp",
|
|
896
895
|
node: childrenProp
|
|
@@ -914,7 +913,7 @@ var no_children_to_array_default = createRule({
|
|
|
914
913
|
});
|
|
915
914
|
function create$46(context) {
|
|
916
915
|
return { MemberExpression(node) {
|
|
917
|
-
if (isChildrenToArray(context, node)) context.report({
|
|
916
|
+
if (core.isChildrenToArray(context, node)) context.report({
|
|
918
917
|
messageId: "noChildrenToArray",
|
|
919
918
|
node: node.property
|
|
920
919
|
});
|
|
@@ -937,10 +936,10 @@ var no_class_component_default = createRule({
|
|
|
937
936
|
});
|
|
938
937
|
function create$45(context) {
|
|
939
938
|
if (!context.sourceCode.text.includes("Component")) return {};
|
|
940
|
-
const { ctx, visitor } = useComponentCollectorLegacy(context);
|
|
939
|
+
const { ctx, visitor } = core.useComponentCollectorLegacy(context);
|
|
941
940
|
return defineRuleListener(visitor, { "Program:exit"(program) {
|
|
942
941
|
for (const { name = "anonymous", node: component } of ctx.getAllComponents(program)) {
|
|
943
|
-
if (component.body.body.some((m) => isComponentDidCatch(m) || isGetDerivedStateFromError(m))) continue;
|
|
942
|
+
if (component.body.body.some((m) => core.isComponentDidCatch(m) || core.isGetDerivedStateFromError(m))) continue;
|
|
944
943
|
context.report({
|
|
945
944
|
messageId: "noClassComponent",
|
|
946
945
|
node: component,
|
|
@@ -966,7 +965,7 @@ var no_clone_element_default = createRule({
|
|
|
966
965
|
});
|
|
967
966
|
function create$44(context) {
|
|
968
967
|
return { CallExpression(node) {
|
|
969
|
-
if (isCloneElementCall(context, node)) context.report({
|
|
968
|
+
if (core.isCloneElementCall(context, node)) context.report({
|
|
970
969
|
messageId: "noCloneElement",
|
|
971
970
|
node
|
|
972
971
|
});
|
|
@@ -990,11 +989,11 @@ var no_component_will_mount_default = createRule({
|
|
|
990
989
|
});
|
|
991
990
|
function create$43(context) {
|
|
992
991
|
if (!context.sourceCode.text.includes("componentWillMount")) return {};
|
|
993
|
-
const { ctx, visitor } = useComponentCollectorLegacy(context);
|
|
992
|
+
const { ctx, visitor } = core.useComponentCollectorLegacy(context);
|
|
994
993
|
return defineRuleListener(visitor, { "Program:exit"(program) {
|
|
995
994
|
for (const { node: component } of ctx.getAllComponents(program)) {
|
|
996
995
|
const { body } = component.body;
|
|
997
|
-
for (const member of body) if (isComponentWillMount(member)) context.report({
|
|
996
|
+
for (const member of body) if (core.isComponentWillMount(member)) context.report({
|
|
998
997
|
messageId: "noComponentWillMount",
|
|
999
998
|
node: member,
|
|
1000
999
|
fix(fixer) {
|
|
@@ -1023,11 +1022,11 @@ var no_component_will_receive_props_default = createRule({
|
|
|
1023
1022
|
});
|
|
1024
1023
|
function create$42(context) {
|
|
1025
1024
|
if (!context.sourceCode.text.includes("componentWillReceiveProps")) return {};
|
|
1026
|
-
const { ctx, visitor } = useComponentCollectorLegacy(context);
|
|
1025
|
+
const { ctx, visitor } = core.useComponentCollectorLegacy(context);
|
|
1027
1026
|
return defineRuleListener(visitor, { "Program:exit"(program) {
|
|
1028
1027
|
for (const { node: component } of ctx.getAllComponents(program)) {
|
|
1029
1028
|
const { body } = component.body;
|
|
1030
|
-
for (const member of body) if (isComponentWillReceiveProps(member)) context.report({
|
|
1029
|
+
for (const member of body) if (core.isComponentWillReceiveProps(member)) context.report({
|
|
1031
1030
|
messageId: "noComponentWillReceiveProps",
|
|
1032
1031
|
node: member,
|
|
1033
1032
|
fix(fixer) {
|
|
@@ -1056,11 +1055,11 @@ var no_component_will_update_default = createRule({
|
|
|
1056
1055
|
});
|
|
1057
1056
|
function create$41(context) {
|
|
1058
1057
|
if (!context.sourceCode.text.includes("componentWillUpdate")) return {};
|
|
1059
|
-
const { ctx, visitor } = useComponentCollectorLegacy(context);
|
|
1058
|
+
const { ctx, visitor } = core.useComponentCollectorLegacy(context);
|
|
1060
1059
|
return defineRuleListener(visitor, { "Program:exit"(program) {
|
|
1061
1060
|
for (const { node: component } of ctx.getAllComponents(program)) {
|
|
1062
1061
|
const { body } = component.body;
|
|
1063
|
-
for (const member of body) if (isComponentWillUpdate(member)) context.report({
|
|
1062
|
+
for (const member of body) if (core.isComponentWillUpdate(member)) context.report({
|
|
1064
1063
|
messageId: "noComponentWillUpdate",
|
|
1065
1064
|
node: member,
|
|
1066
1065
|
fix(fixer) {
|
|
@@ -1092,7 +1091,7 @@ function create$40(context) {
|
|
|
1092
1091
|
const { version } = getSettingsFromContext(context);
|
|
1093
1092
|
if (compare(version, "19.0.0", "<")) return {};
|
|
1094
1093
|
return { JSXElement(node) {
|
|
1095
|
-
const parts = getJsxElementType(context, node).split(".");
|
|
1094
|
+
const parts = core.getJsxElementType(context, node).split(".");
|
|
1096
1095
|
const selfName = parts.pop();
|
|
1097
1096
|
const contextFullName = parts.join(".");
|
|
1098
1097
|
const contextSelfName = parts.pop();
|
|
@@ -1102,7 +1101,7 @@ function create$40(context) {
|
|
|
1102
1101
|
messageId: "noContextProvider",
|
|
1103
1102
|
node,
|
|
1104
1103
|
fix(fixer) {
|
|
1105
|
-
if (!isComponentNameLoose(contextSelfName)) return null;
|
|
1104
|
+
if (!core.isComponentNameLoose(contextSelfName)) return null;
|
|
1106
1105
|
const openingElement = node.openingElement;
|
|
1107
1106
|
const closingElement = node.closingElement;
|
|
1108
1107
|
if (closingElement == null) return fixer.replaceText(openingElement.name, contextFullName);
|
|
@@ -1128,7 +1127,7 @@ var no_create_ref_default = createRule({
|
|
|
1128
1127
|
});
|
|
1129
1128
|
function create$39(context) {
|
|
1130
1129
|
return { CallExpression(node) {
|
|
1131
|
-
if (isCreateRefCall(context, node) &&
|
|
1130
|
+
if (core.isCreateRefCall(context, node) && ast.findParentNode(node, core.isClassComponent) == null) context.report({
|
|
1132
1131
|
messageId: "noCreateRef",
|
|
1133
1132
|
node
|
|
1134
1133
|
});
|
|
@@ -1156,10 +1155,10 @@ function create$38(context) {
|
|
|
1156
1155
|
const { object, property } = node.left;
|
|
1157
1156
|
if (object.type !== AST_NODE_TYPES.Identifier) return;
|
|
1158
1157
|
if (property.type !== AST_NODE_TYPES.Identifier || property.name !== "defaultProps") return;
|
|
1159
|
-
if (!isComponentNameLoose(object.name)) return;
|
|
1158
|
+
if (!core.isComponentNameLoose(object.name)) return;
|
|
1160
1159
|
const variableNode = getVariableDefinitionNode(findVariable(object.name, context.sourceCode.getScope(node)), 0);
|
|
1161
1160
|
if (variableNode == null) return;
|
|
1162
|
-
if (!
|
|
1161
|
+
if (!ast.isFunction(variableNode)) return;
|
|
1163
1162
|
context.report({
|
|
1164
1163
|
messageId: "noDefaultProps",
|
|
1165
1164
|
node: property
|
|
@@ -1171,7 +1170,7 @@ function create$38(context) {
|
|
|
1171
1170
|
//#region src/rules/no-direct-mutation-state.ts
|
|
1172
1171
|
const RULE_NAME$37 = "no-direct-mutation-state";
|
|
1173
1172
|
function isConstructorFunction(node) {
|
|
1174
|
-
return
|
|
1173
|
+
return ast.isOneOf([AST_NODE_TYPES.FunctionDeclaration, AST_NODE_TYPES.FunctionExpression])(node) && ast.isMethodOrProperty(node.parent) && node.parent.key.type === AST_NODE_TYPES.Identifier && node.parent.key.name === "constructor";
|
|
1175
1174
|
}
|
|
1176
1175
|
var no_direct_mutation_state_default = createRule({
|
|
1177
1176
|
meta: {
|
|
@@ -1186,10 +1185,10 @@ var no_direct_mutation_state_default = createRule({
|
|
|
1186
1185
|
});
|
|
1187
1186
|
function create$37(context) {
|
|
1188
1187
|
return { AssignmentExpression(node) {
|
|
1189
|
-
if (!isAssignmentToThisState(node)) return;
|
|
1190
|
-
const parentClass =
|
|
1188
|
+
if (!core.isAssignmentToThisState(node)) return;
|
|
1189
|
+
const parentClass = ast.findParentNode(node, ast.isOneOf([AST_NODE_TYPES.ClassDeclaration, AST_NODE_TYPES.ClassExpression]));
|
|
1191
1190
|
if (parentClass == null) return;
|
|
1192
|
-
if (isClassComponent(parentClass) && context.sourceCode.getScope(node).block !==
|
|
1191
|
+
if (core.isClassComponent(parentClass) && context.sourceCode.getScope(node).block !== ast.findParentNode(node, isConstructorFunction)) context.report({
|
|
1193
1192
|
messageId: "noDirectMutationState",
|
|
1194
1193
|
node
|
|
1195
1194
|
});
|
|
@@ -1217,7 +1216,7 @@ function create$36(context) {
|
|
|
1217
1216
|
const aValue = a.value;
|
|
1218
1217
|
const bValue = b.value;
|
|
1219
1218
|
if (aValue == null || bValue == null) return false;
|
|
1220
|
-
return
|
|
1219
|
+
return ast.isNodeEqual(aValue, bValue);
|
|
1221
1220
|
}
|
|
1222
1221
|
return {
|
|
1223
1222
|
"JSXAttribute[name.name='key']"(node) {
|
|
@@ -1236,12 +1235,12 @@ function create$36(context) {
|
|
|
1236
1235
|
break;
|
|
1237
1236
|
}
|
|
1238
1237
|
default: {
|
|
1239
|
-
const call =
|
|
1240
|
-
const iter =
|
|
1241
|
-
if (!
|
|
1238
|
+
const call = ast.findParentNode(jsxElement, (n) => n.type === AST_NODE_TYPES.CallExpression && n.callee.type === AST_NODE_TYPES.MemberExpression && n.callee.property.type === AST_NODE_TYPES.Identifier && n.callee.property.name === "map");
|
|
1239
|
+
const iter = ast.findParentNode(jsxElement, (n) => n === call || ast.isFunction(n));
|
|
1240
|
+
if (!ast.isFunction(iter)) return;
|
|
1242
1241
|
const arg0 = call?.arguments[0];
|
|
1243
1242
|
if (call == null || arg0 == null) return;
|
|
1244
|
-
if (
|
|
1243
|
+
if (ast.getUnderlyingExpression(arg0) !== iter) return;
|
|
1245
1244
|
keyedEntries.set(call, {
|
|
1246
1245
|
hasDuplicate: node.value?.type === AST_NODE_TYPES.Literal,
|
|
1247
1246
|
keys: [node],
|
|
@@ -1283,8 +1282,8 @@ function create$35(context) {
|
|
|
1283
1282
|
const { version } = getSettingsFromContext(context);
|
|
1284
1283
|
if (compare(version, "19.0.0", "<")) return {};
|
|
1285
1284
|
return { CallExpression(node) {
|
|
1286
|
-
if (!isForwardRefCall(context, node)) return;
|
|
1287
|
-
const id =
|
|
1285
|
+
if (!core.isForwardRefCall(context, node)) return;
|
|
1286
|
+
const id = ast.getFunctionId(node);
|
|
1288
1287
|
const fix = canFix(context, node) ? getFix(context, node) : null;
|
|
1289
1288
|
context.report({
|
|
1290
1289
|
messageId: "noForwardRef",
|
|
@@ -1305,8 +1304,8 @@ function canFix(context, node) {
|
|
|
1305
1304
|
const { importSource } = getSettingsFromContext(context);
|
|
1306
1305
|
const initialScope = context.sourceCode.getScope(node);
|
|
1307
1306
|
switch (node.callee.type) {
|
|
1308
|
-
case AST_NODE_TYPES.Identifier: return isInitializedFromReact(node.callee.name, initialScope, importSource);
|
|
1309
|
-
case AST_NODE_TYPES.MemberExpression: return node.callee.object.type === AST_NODE_TYPES.Identifier && isInitializedFromReact(node.callee.object.name, initialScope, importSource);
|
|
1307
|
+
case AST_NODE_TYPES.Identifier: return core.isInitializedFromReact(node.callee.name, initialScope, importSource);
|
|
1308
|
+
case AST_NODE_TYPES.MemberExpression: return node.callee.object.type === AST_NODE_TYPES.Identifier && core.isInitializedFromReact(node.callee.object.name, initialScope, importSource);
|
|
1310
1309
|
default: return false;
|
|
1311
1310
|
}
|
|
1312
1311
|
}
|
|
@@ -1319,7 +1318,7 @@ function canFix(context, node) {
|
|
|
1319
1318
|
function getFix(context, node) {
|
|
1320
1319
|
return (fixer) => {
|
|
1321
1320
|
const [componentNode] = node.arguments;
|
|
1322
|
-
if (componentNode == null || !
|
|
1321
|
+
if (componentNode == null || !ast.isFunction(componentNode)) return [];
|
|
1323
1322
|
return [
|
|
1324
1323
|
fixer.removeRange([node.range[0], componentNode.range[0]]),
|
|
1325
1324
|
fixer.removeRange([componentNode.range[1], node.range[1]]),
|
|
@@ -1387,7 +1386,7 @@ var no_implicit_key_default = createRule({
|
|
|
1387
1386
|
});
|
|
1388
1387
|
function create$34(context) {
|
|
1389
1388
|
return { JSXOpeningElement(node) {
|
|
1390
|
-
const keyProp = getJsxAttribute(context, node.parent)("key");
|
|
1389
|
+
const keyProp = core.getJsxAttribute(context, node.parent)("key");
|
|
1391
1390
|
const isKeyPropOnElement = node.attributes.some((n) => n.type === AST_NODE_TYPES.JSXAttribute && n.name.type === AST_NODE_TYPES.JSXIdentifier && n.name.name === "key");
|
|
1392
1391
|
if (keyProp != null && !isKeyPropOnElement) context.report({
|
|
1393
1392
|
messageId: "noImplicitKey",
|
|
@@ -1434,16 +1433,16 @@ function create$33(context) {
|
|
|
1434
1433
|
*/
|
|
1435
1434
|
function getReportDescriptor(node) {
|
|
1436
1435
|
if (node == null) return unit;
|
|
1437
|
-
if (
|
|
1438
|
-
if (
|
|
1439
|
-
if (
|
|
1436
|
+
if (ast.is(AST_NODE_TYPES.JSXExpressionContainer)(node)) return getReportDescriptor(node.expression);
|
|
1437
|
+
if (ast.isJSX(node)) return unit;
|
|
1438
|
+
if (ast.isTypeExpression(node)) return getReportDescriptor(node.expression);
|
|
1440
1439
|
return match(node).with({
|
|
1441
1440
|
type: AST_NODE_TYPES.LogicalExpression,
|
|
1442
1441
|
operator: "&&"
|
|
1443
1442
|
}, ({ left, right }) => {
|
|
1444
1443
|
if (left.type === AST_NODE_TYPES.UnaryExpression && left.operator === "!") return getReportDescriptor(right);
|
|
1445
1444
|
const initialScope = context.sourceCode.getScope(left);
|
|
1446
|
-
if (
|
|
1445
|
+
if (ast.isIdentifier(left, "NaN") || getStaticValue(left, initialScope)?.value === "NaN") return {
|
|
1447
1446
|
messageId: "noLeakedConditionalRendering",
|
|
1448
1447
|
node: left,
|
|
1449
1448
|
data: { value: context.sourceCode.getText(left) }
|
|
@@ -1481,14 +1480,14 @@ var no_missing_component_display_name_default = createRule({
|
|
|
1481
1480
|
});
|
|
1482
1481
|
function create$32(context) {
|
|
1483
1482
|
if (!context.sourceCode.text.includes("memo") && !context.sourceCode.text.includes("forwardRef")) return {};
|
|
1484
|
-
const { ctx, visitor } = useComponentCollector(context, {
|
|
1483
|
+
const { ctx, visitor } = core.useComponentCollector(context, {
|
|
1485
1484
|
collectDisplayName: true,
|
|
1486
|
-
hint: DEFAULT_COMPONENT_DETECTION_HINT
|
|
1485
|
+
hint: core.DEFAULT_COMPONENT_DETECTION_HINT
|
|
1487
1486
|
});
|
|
1488
1487
|
return defineRuleListener(visitor, { "Program:exit"(program) {
|
|
1489
1488
|
for (const { node, displayName, flag } of ctx.getAllComponents(program)) {
|
|
1490
|
-
const id =
|
|
1491
|
-
const isMemoOrForwardRef = (flag & (ComponentFlag.ForwardRef | ComponentFlag.Memo)) > 0n;
|
|
1489
|
+
const id = ast.getFunctionId(node);
|
|
1490
|
+
const isMemoOrForwardRef = (flag & (core.ComponentFlag.ForwardRef | core.ComponentFlag.Memo)) > 0n;
|
|
1492
1491
|
if (id != null) continue;
|
|
1493
1492
|
if (!isMemoOrForwardRef) continue;
|
|
1494
1493
|
if (displayName == null) context.report({
|
|
@@ -1519,11 +1518,11 @@ function create$31(context) {
|
|
|
1519
1518
|
const createCalls = [];
|
|
1520
1519
|
const displayNameAssignments = [];
|
|
1521
1520
|
return {
|
|
1522
|
-
[
|
|
1521
|
+
[ast.SEL_DISPLAY_NAME_ASSIGNMENT_EXPRESSION](node) {
|
|
1523
1522
|
displayNameAssignments.push(node);
|
|
1524
1523
|
},
|
|
1525
1524
|
CallExpression(node) {
|
|
1526
|
-
if (!isCreateContextCall(context, node)) return;
|
|
1525
|
+
if (!core.isCreateContextCall(context, node)) return;
|
|
1527
1526
|
createCalls.push(node);
|
|
1528
1527
|
},
|
|
1529
1528
|
"Program:exit"() {
|
|
@@ -1584,7 +1583,7 @@ var no_missing_key_default = createRule({
|
|
|
1584
1583
|
function create$30(ctx) {
|
|
1585
1584
|
let inChildrenToArray = false;
|
|
1586
1585
|
function check(node) {
|
|
1587
|
-
if (node.type === AST_NODE_TYPES.JSXElement) return getJsxAttribute(ctx, node)("key") == null ? {
|
|
1586
|
+
if (node.type === AST_NODE_TYPES.JSXElement) return core.getJsxAttribute(ctx, node)("key") == null ? {
|
|
1588
1587
|
messageId: "missingKey",
|
|
1589
1588
|
node
|
|
1590
1589
|
} : null;
|
|
@@ -1604,21 +1603,21 @@ function create$30(ctx) {
|
|
|
1604
1603
|
}
|
|
1605
1604
|
}
|
|
1606
1605
|
function checkBlock(node) {
|
|
1607
|
-
return
|
|
1606
|
+
return ast.getNestedReturnStatements(node).filter((stmt) => stmt.argument != null).map((stmt) => check(stmt.argument)).filter((d) => d != null);
|
|
1608
1607
|
}
|
|
1609
1608
|
return {
|
|
1610
1609
|
ArrayExpression(node) {
|
|
1611
1610
|
if (inChildrenToArray) return;
|
|
1612
|
-
const elements = node.elements.filter(
|
|
1611
|
+
const elements = node.elements.filter(ast.is(AST_NODE_TYPES.JSXElement));
|
|
1613
1612
|
if (elements.length === 0) return;
|
|
1614
1613
|
const scope = ctx.sourceCode.getScope(node);
|
|
1615
|
-
for (const el of elements) if (getJsxAttribute(ctx, el, scope)("key") == null) ctx.report({
|
|
1614
|
+
for (const el of elements) if (core.getJsxAttribute(ctx, el, scope)("key") == null) ctx.report({
|
|
1616
1615
|
messageId: "missingKey",
|
|
1617
1616
|
node: el
|
|
1618
1617
|
});
|
|
1619
1618
|
},
|
|
1620
1619
|
CallExpression(node) {
|
|
1621
|
-
inChildrenToArray ||= isChildrenToArrayCall(ctx, node);
|
|
1620
|
+
inChildrenToArray ||= core.isChildrenToArrayCall(ctx, node);
|
|
1622
1621
|
if (inChildrenToArray) return;
|
|
1623
1622
|
if (node.callee.type !== AST_NODE_TYPES.MemberExpression) return;
|
|
1624
1623
|
if (node.callee.property.type !== AST_NODE_TYPES.Identifier) return;
|
|
@@ -1626,12 +1625,12 @@ function create$30(ctx) {
|
|
|
1626
1625
|
const idx = name === "from" ? 1 : name === "map" ? 0 : -1;
|
|
1627
1626
|
if (idx < 0) return;
|
|
1628
1627
|
const cb = node.arguments[idx];
|
|
1629
|
-
if (!
|
|
1628
|
+
if (!ast.isFunction(cb)) return;
|
|
1630
1629
|
if (cb.body.type === AST_NODE_TYPES.BlockStatement) checkBlock(cb.body).forEach(report(ctx));
|
|
1631
1630
|
else report(ctx)(checkExpr(cb.body));
|
|
1632
1631
|
},
|
|
1633
1632
|
"CallExpression:exit"(node) {
|
|
1634
|
-
if (isChildrenToArrayCall(ctx, node)) inChildrenToArray = false;
|
|
1633
|
+
if (core.isChildrenToArrayCall(ctx, node)) inChildrenToArray = false;
|
|
1635
1634
|
},
|
|
1636
1635
|
JSXFragment(node) {
|
|
1637
1636
|
if (inChildrenToArray) return;
|
|
@@ -1665,8 +1664,8 @@ function create$29(context) {
|
|
|
1665
1664
|
const { importSource } = getSettingsFromContext(context);
|
|
1666
1665
|
return {
|
|
1667
1666
|
CallExpression(node) {
|
|
1668
|
-
if (!isCaptureOwnerStackCall(context, node)) return;
|
|
1669
|
-
if (
|
|
1667
|
+
if (!core.isCaptureOwnerStackCall(context, node)) return;
|
|
1668
|
+
if (ast.findParentNode(node, isDevelopmentOnlyCheck) == null) context.report({
|
|
1670
1669
|
messageId: "missingDevelopmentOnlyCheck",
|
|
1671
1670
|
node
|
|
1672
1671
|
});
|
|
@@ -1686,7 +1685,7 @@ function create$29(context) {
|
|
|
1686
1685
|
}
|
|
1687
1686
|
function isDevelopmentOnlyCheck(node) {
|
|
1688
1687
|
if (node.type !== AST_NODE_TYPES.IfStatement) return false;
|
|
1689
|
-
return
|
|
1688
|
+
return ast.isProcessEnvNodeEnvCompare(node.test, "!==", "production");
|
|
1690
1689
|
}
|
|
1691
1690
|
|
|
1692
1691
|
//#endregion
|
|
@@ -1704,22 +1703,23 @@ var no_nested_component_definitions_default = createRule({
|
|
|
1704
1703
|
defaultOptions: []
|
|
1705
1704
|
});
|
|
1706
1705
|
function create$28(context) {
|
|
1707
|
-
const
|
|
1708
|
-
const
|
|
1706
|
+
const hint = core.ComponentDetectionHint.SkipArrayMapCallback | core.ComponentDetectionHint.SkipNullLiteral | core.ComponentDetectionHint.SkipUndefined | core.ComponentDetectionHint.SkipBooleanLiteral | core.ComponentDetectionHint.SkipStringLiteral | core.ComponentDetectionHint.SkipNumberLiteral | core.ComponentDetectionHint.StrictLogical | core.ComponentDetectionHint.StrictConditional;
|
|
1707
|
+
const fCollector = core.useComponentCollector(context, { hint });
|
|
1708
|
+
const cCollector = core.useComponentCollectorLegacy(context);
|
|
1709
1709
|
return defineRuleListener(fCollector.visitor, cCollector.visitor, { "Program:exit"(program) {
|
|
1710
1710
|
const fComponents = [...fCollector.ctx.getAllComponents(program)];
|
|
1711
1711
|
const cComponents = [...cCollector.ctx.getAllComponents(program)];
|
|
1712
1712
|
const isFunctionComponent = (node) => {
|
|
1713
|
-
return
|
|
1713
|
+
return ast.isFunction(node) && fComponents.some((component) => component.node === node);
|
|
1714
1714
|
};
|
|
1715
1715
|
const isClassComponent = (node) => {
|
|
1716
|
-
return
|
|
1716
|
+
return ast.isClass(node) && cComponents.some((component) => component.node === node);
|
|
1717
1717
|
};
|
|
1718
1718
|
for (const { name, node: component } of fComponents) {
|
|
1719
1719
|
if (name == null) continue;
|
|
1720
|
-
if (isDirectValueOfRenderPropertyLoose(component)) continue;
|
|
1720
|
+
if (core.isDirectValueOfRenderPropertyLoose(component)) continue;
|
|
1721
1721
|
if (isInsideJSXAttributeValue(component)) {
|
|
1722
|
-
if (!isDeclaredInRenderPropLoose(component)) context.report({
|
|
1722
|
+
if (!core.isDeclaredInRenderPropLoose(component)) context.report({
|
|
1723
1723
|
messageId: "noNestedComponentDefinitions",
|
|
1724
1724
|
node: component,
|
|
1725
1725
|
data: {
|
|
@@ -1740,8 +1740,8 @@ function create$28(context) {
|
|
|
1740
1740
|
});
|
|
1741
1741
|
continue;
|
|
1742
1742
|
}
|
|
1743
|
-
const parentComponent =
|
|
1744
|
-
if (parentComponent != null && !isDirectValueOfRenderPropertyLoose(parentComponent)) {
|
|
1743
|
+
const parentComponent = ast.findParentNode(component, isFunctionComponent);
|
|
1744
|
+
if (parentComponent != null && !core.isDirectValueOfRenderPropertyLoose(parentComponent)) {
|
|
1745
1745
|
context.report({
|
|
1746
1746
|
messageId: "noNestedComponentDefinitions",
|
|
1747
1747
|
node: component,
|
|
@@ -1762,7 +1762,7 @@ function create$28(context) {
|
|
|
1762
1762
|
});
|
|
1763
1763
|
}
|
|
1764
1764
|
for (const { name = "unknown", node: component } of cComponents) {
|
|
1765
|
-
if (
|
|
1765
|
+
if (ast.findParentNode(component, (n) => isClassComponent(n) || isFunctionComponent(n)) == null) continue;
|
|
1766
1766
|
context.report({
|
|
1767
1767
|
messageId: "noNestedComponentDefinitions",
|
|
1768
1768
|
node: component,
|
|
@@ -1780,7 +1780,7 @@ function create$28(context) {
|
|
|
1780
1780
|
* @returns `true` if the node is inside JSX attribute value
|
|
1781
1781
|
*/
|
|
1782
1782
|
function isInsideJSXAttributeValue(node) {
|
|
1783
|
-
return node.parent.type === AST_NODE_TYPES.JSXAttribute || findParentJsxAttribute(node, (n) => n.value?.type === AST_NODE_TYPES.JSXExpressionContainer) != null;
|
|
1783
|
+
return node.parent.type === AST_NODE_TYPES.JSXAttribute || core.findParentJsxAttribute(node, (n) => n.value?.type === AST_NODE_TYPES.JSXExpressionContainer) != null;
|
|
1784
1784
|
}
|
|
1785
1785
|
/**
|
|
1786
1786
|
* Check whether a given node is declared inside a class component's render block
|
|
@@ -1789,7 +1789,7 @@ function isInsideJSXAttributeValue(node) {
|
|
|
1789
1789
|
* @returns `true` if the node is inside a class component's render block
|
|
1790
1790
|
*/
|
|
1791
1791
|
function isInsideRenderMethod(node) {
|
|
1792
|
-
return
|
|
1792
|
+
return ast.findParentNode(node, (n) => core.isRenderMethodLike(n) && core.isClassComponent(n.parent.parent)) != null;
|
|
1793
1793
|
}
|
|
1794
1794
|
/**
|
|
1795
1795
|
* Determine whether the node is inside `createElement`'s props argument
|
|
@@ -1798,9 +1798,9 @@ function isInsideRenderMethod(node) {
|
|
|
1798
1798
|
* @returns `true` if the node is inside `createElement`'s props
|
|
1799
1799
|
*/
|
|
1800
1800
|
function isInsideCreateElementProps(context, node) {
|
|
1801
|
-
const call =
|
|
1801
|
+
const call = ast.findParentNode(node, core.isCreateElementCall(context));
|
|
1802
1802
|
if (call == null) return false;
|
|
1803
|
-
const prop =
|
|
1803
|
+
const prop = ast.findParentNode(node, ast.is(AST_NODE_TYPES.ObjectExpression));
|
|
1804
1804
|
if (prop == null) return false;
|
|
1805
1805
|
return prop === call.arguments[1];
|
|
1806
1806
|
}
|
|
@@ -1820,23 +1820,23 @@ var no_nested_lazy_component_declarations_default = createRule({
|
|
|
1820
1820
|
defaultOptions: []
|
|
1821
1821
|
});
|
|
1822
1822
|
function create$27(context) {
|
|
1823
|
-
const hint = ComponentDetectionHint.None;
|
|
1824
|
-
const collector = useComponentCollector(context, { hint });
|
|
1825
|
-
const collectorLegacy = useComponentCollectorLegacy(context);
|
|
1823
|
+
const hint = core.ComponentDetectionHint.None;
|
|
1824
|
+
const collector = core.useComponentCollector(context, { hint });
|
|
1825
|
+
const collectorLegacy = core.useComponentCollectorLegacy(context);
|
|
1826
1826
|
const lazyComponentDeclarations = /* @__PURE__ */ new Set();
|
|
1827
1827
|
return defineRuleListener(collector.visitor, collectorLegacy.visitor, {
|
|
1828
1828
|
ImportExpression(node) {
|
|
1829
|
-
const lazyCall =
|
|
1829
|
+
const lazyCall = ast.findParentNode(node, (n) => core.isLazyCall(context, n));
|
|
1830
1830
|
if (lazyCall != null) lazyComponentDeclarations.add(lazyCall);
|
|
1831
1831
|
},
|
|
1832
1832
|
"Program:exit"(program) {
|
|
1833
1833
|
const functionComponents = collector.ctx.getAllComponents(program);
|
|
1834
1834
|
const classComponents = collectorLegacy.ctx.getAllComponents(program);
|
|
1835
|
-
for (const lazy of lazyComponentDeclarations) if (
|
|
1836
|
-
if (
|
|
1837
|
-
if (n.type === AST_NODE_TYPES.CallExpression) return isHookCall(n) || isCreateElementCall(context, n) || isCreateContextCall(context, n);
|
|
1838
|
-
if (
|
|
1839
|
-
if (
|
|
1835
|
+
for (const lazy of lazyComponentDeclarations) if (ast.findParentNode(lazy, (n) => {
|
|
1836
|
+
if (ast.isJSX(n)) return true;
|
|
1837
|
+
if (n.type === AST_NODE_TYPES.CallExpression) return core.isHookCall(n) || core.isCreateElementCall(context, n) || core.isCreateContextCall(context, n);
|
|
1838
|
+
if (ast.isFunction(n)) return functionComponents.some((c) => c.node === n);
|
|
1839
|
+
if (ast.isClass(n)) return classComponents.some((c) => c.node === n);
|
|
1840
1840
|
return false;
|
|
1841
1841
|
}) != null) context.report({
|
|
1842
1842
|
messageId: "noNestedLazyComponentDeclarations",
|
|
@@ -1868,15 +1868,15 @@ function create$26(context) {
|
|
|
1868
1868
|
const { object, property } = node.left;
|
|
1869
1869
|
if (object.type !== AST_NODE_TYPES.Identifier) return;
|
|
1870
1870
|
if (property.type !== AST_NODE_TYPES.Identifier || property.name !== "propTypes") return;
|
|
1871
|
-
if (!isComponentNameLoose(object.name)) return;
|
|
1871
|
+
if (!core.isComponentNameLoose(object.name)) return;
|
|
1872
1872
|
const variableNode = getVariableDefinitionNode(findVariable(object.name, context.sourceCode.getScope(node)), 0);
|
|
1873
|
-
if (variableNode != null && (
|
|
1873
|
+
if (variableNode != null && (ast.isFunction(variableNode) || core.isClassComponent(variableNode))) context.report({
|
|
1874
1874
|
messageId: "noPropTypes",
|
|
1875
1875
|
node: property
|
|
1876
1876
|
});
|
|
1877
1877
|
},
|
|
1878
1878
|
PropertyDefinition(node) {
|
|
1879
|
-
if (!isClassComponent(node.parent.parent)) return;
|
|
1879
|
+
if (!core.isClassComponent(node.parent.parent)) return;
|
|
1880
1880
|
if (!node.static || node.key.type !== AST_NODE_TYPES.Identifier || node.key.name !== "propTypes") return;
|
|
1881
1881
|
context.report({
|
|
1882
1882
|
messageId: "noPropTypes",
|
|
@@ -1890,7 +1890,7 @@ function create$26(context) {
|
|
|
1890
1890
|
//#region src/rules/no-redundant-should-component-update.ts
|
|
1891
1891
|
const RULE_NAME$25 = "no-redundant-should-component-update";
|
|
1892
1892
|
function isShouldComponentUpdate(node) {
|
|
1893
|
-
return
|
|
1893
|
+
return ast.isMethodOrProperty(node) && node.key.type === AST_NODE_TYPES.Identifier && node.key.name === "shouldComponentUpdate";
|
|
1894
1894
|
}
|
|
1895
1895
|
var no_redundant_should_component_update_default = createRule({
|
|
1896
1896
|
meta: {
|
|
@@ -1905,10 +1905,10 @@ var no_redundant_should_component_update_default = createRule({
|
|
|
1905
1905
|
});
|
|
1906
1906
|
function create$25(context) {
|
|
1907
1907
|
if (!context.sourceCode.text.includes("shouldComponentUpdate")) return {};
|
|
1908
|
-
const { ctx, visitor } = useComponentCollectorLegacy(context);
|
|
1908
|
+
const { ctx, visitor } = core.useComponentCollectorLegacy(context);
|
|
1909
1909
|
return defineRuleListener(visitor, { "Program:exit"(program) {
|
|
1910
1910
|
for (const { name = "PureComponent", node: component, flag } of ctx.getAllComponents(program)) {
|
|
1911
|
-
if ((flag & ComponentFlag.PureComponent) === 0n) continue;
|
|
1911
|
+
if ((flag & core.ComponentFlag.PureComponent) === 0n) continue;
|
|
1912
1912
|
const { body } = component.body;
|
|
1913
1913
|
for (const member of body) if (isShouldComponentUpdate(member)) context.report({
|
|
1914
1914
|
messageId: "noRedundantShouldComponentUpdate",
|
|
@@ -1936,9 +1936,9 @@ var no_set_state_in_component_did_mount_default = createRule({
|
|
|
1936
1936
|
function create$24(context) {
|
|
1937
1937
|
if (!context.sourceCode.text.includes("componentDidMount")) return {};
|
|
1938
1938
|
return { CallExpression(node) {
|
|
1939
|
-
if (!isThisSetState(node)) return;
|
|
1940
|
-
const enclosingClassNode =
|
|
1941
|
-
const enclosingMethodNode =
|
|
1939
|
+
if (!core.isThisSetState(node)) return;
|
|
1940
|
+
const enclosingClassNode = ast.findParentNode(node, core.isClassComponent);
|
|
1941
|
+
const enclosingMethodNode = ast.findParentNode(node, (n) => n === enclosingClassNode || core.isComponentDidMount(n));
|
|
1942
1942
|
if (enclosingClassNode == null || enclosingMethodNode == null || enclosingMethodNode === enclosingClassNode) return;
|
|
1943
1943
|
const enclosingMethodScope = context.sourceCode.getScope(enclosingMethodNode);
|
|
1944
1944
|
const setStateCallParentScope = context.sourceCode.getScope(node).upper;
|
|
@@ -1966,9 +1966,9 @@ var no_set_state_in_component_did_update_default = createRule({
|
|
|
1966
1966
|
function create$23(context) {
|
|
1967
1967
|
if (!context.sourceCode.text.includes("componentDidUpdate")) return {};
|
|
1968
1968
|
return { CallExpression(node) {
|
|
1969
|
-
if (!isThisSetState(node)) return;
|
|
1970
|
-
const enclosingClassNode =
|
|
1971
|
-
const enclosingMethodNode =
|
|
1969
|
+
if (!core.isThisSetState(node)) return;
|
|
1970
|
+
const enclosingClassNode = ast.findParentNode(node, core.isClassComponent);
|
|
1971
|
+
const enclosingMethodNode = ast.findParentNode(node, (n) => n === enclosingClassNode || core.isComponentDidUpdate(n));
|
|
1972
1972
|
if (enclosingClassNode == null || enclosingMethodNode == null || enclosingMethodNode === enclosingClassNode) return;
|
|
1973
1973
|
const enclosingMethodScope = context.sourceCode.getScope(enclosingMethodNode);
|
|
1974
1974
|
const setStateCallParentScope = context.sourceCode.getScope(node).upper;
|
|
@@ -1996,9 +1996,9 @@ var no_set_state_in_component_will_update_default = createRule({
|
|
|
1996
1996
|
function create$22(context) {
|
|
1997
1997
|
if (!context.sourceCode.text.includes("componentWillUpdate")) return {};
|
|
1998
1998
|
return { CallExpression(node) {
|
|
1999
|
-
if (!isThisSetState(node)) return;
|
|
2000
|
-
const enclosingClassNode =
|
|
2001
|
-
const enclosingMethodNode =
|
|
1999
|
+
if (!core.isThisSetState(node)) return;
|
|
2000
|
+
const enclosingClassNode = ast.findParentNode(node, core.isClassComponent);
|
|
2001
|
+
const enclosingMethodNode = ast.findParentNode(node, (n) => n === enclosingClassNode || core.isComponentWillUpdate(n));
|
|
2002
2002
|
if (enclosingClassNode == null || enclosingMethodNode == null || enclosingMethodNode === enclosingClassNode) return;
|
|
2003
2003
|
const enclosingMethodScope = context.sourceCode.getScope(enclosingMethodNode);
|
|
2004
2004
|
const setStateCallParentScope = context.sourceCode.getScope(node).upper;
|
|
@@ -2027,7 +2027,7 @@ var no_string_refs_default = createRule({
|
|
|
2027
2027
|
function create$21(context) {
|
|
2028
2028
|
const state = { isWithinClassComponent: false };
|
|
2029
2029
|
function onClassBodyEnter(node) {
|
|
2030
|
-
if (isClassComponent(node.parent)) state.isWithinClassComponent = true;
|
|
2030
|
+
if (core.isClassComponent(node.parent)) state.isWithinClassComponent = true;
|
|
2031
2031
|
}
|
|
2032
2032
|
function onClassBodyExit() {
|
|
2033
2033
|
state.isWithinClassComponent = false;
|
|
@@ -2084,21 +2084,21 @@ var no_unnecessary_key_default = createRule({
|
|
|
2084
2084
|
function create$20(context) {
|
|
2085
2085
|
if (!context.sourceCode.text.includes("key=")) return {};
|
|
2086
2086
|
const jsxConfig = {
|
|
2087
|
-
...getJsxConfigFromContext(context),
|
|
2088
|
-
...getJsxConfigFromAnnotation(context)
|
|
2087
|
+
...core.getJsxConfigFromContext(context),
|
|
2088
|
+
...core.getJsxConfigFromAnnotation(context)
|
|
2089
2089
|
};
|
|
2090
2090
|
return { JSXAttribute(node) {
|
|
2091
2091
|
if (node.name.name !== "key") return;
|
|
2092
2092
|
const jsxElement = node.parent.parent;
|
|
2093
|
-
if (isJsxFragmentElement(context, jsxElement, jsxConfig)) return;
|
|
2093
|
+
if (core.isJsxFragmentElement(context, jsxElement, jsxConfig)) return;
|
|
2094
2094
|
if (jsxElement.openingElement.attributes.some((attr) => attr.type === AST_NODE_TYPES.JSXSpreadAttribute)) return;
|
|
2095
|
-
if (
|
|
2096
|
-
const mapCallback =
|
|
2097
|
-
if (mapCallback == null ||
|
|
2095
|
+
if (ast.findParentNode(jsxElement, (n) => core.isRenderFunctionLoose(context, n)) != null) return;
|
|
2096
|
+
const mapCallback = ast.findParentNode(jsxElement, isArrayMethodCallback);
|
|
2097
|
+
if (mapCallback == null || ast.findParentNode(jsxElement, ast.isFunction) !== mapCallback) return;
|
|
2098
2098
|
if (context.sourceCode.getScope(mapCallback) !== context.sourceCode.getScope(jsxElement)) return;
|
|
2099
|
-
const keyedElementOrElse =
|
|
2099
|
+
const keyedElementOrElse = ast.findParentNode(jsxElement, (n) => {
|
|
2100
2100
|
if (n === mapCallback) return true;
|
|
2101
|
-
return
|
|
2101
|
+
return ast.isJSXElement(n) && core.getJsxAttribute(context, n)("key") != null;
|
|
2102
2102
|
});
|
|
2103
2103
|
if (keyedElementOrElse == null || keyedElementOrElse === mapCallback) return;
|
|
2104
2104
|
context.report({
|
|
@@ -2149,13 +2149,13 @@ function create$19(context) {
|
|
|
2149
2149
|
if (!context.sourceCode.text.includes("useCallback")) return {};
|
|
2150
2150
|
return { VariableDeclarator(node) {
|
|
2151
2151
|
const { id, init } = node;
|
|
2152
|
-
if (id.type !== AST_NODE_TYPES.Identifier || init?.type !== AST_NODE_TYPES.CallExpression || !isUseCallbackCall(init)) return;
|
|
2152
|
+
if (id.type !== AST_NODE_TYPES.Identifier || init?.type !== AST_NODE_TYPES.CallExpression || !core.isUseCallbackCall(init)) return;
|
|
2153
2153
|
const [cbk, ...rest] = context.sourceCode.getDeclaredVariables(node);
|
|
2154
2154
|
if (cbk == null || rest.length > 0) return;
|
|
2155
2155
|
const checkForUsageInsideUseEffectReport = checkForUsageInsideUseEffect$1(context.sourceCode, init);
|
|
2156
2156
|
const scope = context.sourceCode.getScope(init);
|
|
2157
2157
|
const component = context.sourceCode.getScope(init).block;
|
|
2158
|
-
if (!
|
|
2158
|
+
if (!ast.isFunction(component)) return;
|
|
2159
2159
|
const [arg0, arg1] = init.arguments;
|
|
2160
2160
|
if (arg0 == null || arg1 == null) return;
|
|
2161
2161
|
if (!match(arg1).with({ type: AST_NODE_TYPES.ArrayExpression }, (n) => n.elements.length === 0).with({ type: AST_NODE_TYPES.Identifier }, (n) => {
|
|
@@ -2193,7 +2193,7 @@ function checkForUsageInsideUseEffect$1(sourceCode, node) {
|
|
|
2193
2193
|
if (usages.length === 0) return;
|
|
2194
2194
|
const effectSet = /* @__PURE__ */ new Set();
|
|
2195
2195
|
for (const usage of usages) {
|
|
2196
|
-
const effect =
|
|
2196
|
+
const effect = ast.findParentNode(usage.identifier, core.isUseEffectLikeCall);
|
|
2197
2197
|
if (effect == null) return;
|
|
2198
2198
|
effectSet.add(effect);
|
|
2199
2199
|
if (effectSet.size > 1) return;
|
|
@@ -2226,16 +2226,16 @@ function create$18(context) {
|
|
|
2226
2226
|
if (!context.sourceCode.text.includes("useMemo")) return {};
|
|
2227
2227
|
return { VariableDeclarator(node) {
|
|
2228
2228
|
const { id, init } = node;
|
|
2229
|
-
if (id.type !== AST_NODE_TYPES.Identifier || init?.type !== AST_NODE_TYPES.CallExpression || !isUseMemoCall(init)) return;
|
|
2229
|
+
if (id.type !== AST_NODE_TYPES.Identifier || init?.type !== AST_NODE_TYPES.CallExpression || !core.isUseMemoCall(init)) return;
|
|
2230
2230
|
const [mem, ...rest] = context.sourceCode.getDeclaredVariables(node);
|
|
2231
2231
|
if (mem == null || rest.length > 0) return;
|
|
2232
2232
|
const checkForUsageInsideUseEffectReport = checkForUsageInsideUseEffect(context.sourceCode, init);
|
|
2233
2233
|
const scope = context.sourceCode.getScope(init);
|
|
2234
2234
|
const component = scope.block;
|
|
2235
|
-
if (!
|
|
2235
|
+
if (!ast.isFunction(component)) return;
|
|
2236
2236
|
const [arg0, arg1] = init.arguments;
|
|
2237
2237
|
if (arg0 == null || arg1 == null) return;
|
|
2238
|
-
if (
|
|
2238
|
+
if (ast.isFunction(arg0) && [...ast.getNestedCallExpressions(arg0.body), ...ast.getNestedNewExpressions(arg0.body)].length > 0) {
|
|
2239
2239
|
report(context)(checkForUsageInsideUseEffectReport);
|
|
2240
2240
|
return;
|
|
2241
2241
|
}
|
|
@@ -2274,7 +2274,7 @@ function checkForUsageInsideUseEffect(sourceCode, node) {
|
|
|
2274
2274
|
if (usages.length === 0) return;
|
|
2275
2275
|
const effectSet = /* @__PURE__ */ new Set();
|
|
2276
2276
|
for (const usage of usages) {
|
|
2277
|
-
const effect =
|
|
2277
|
+
const effect = ast.findParentNode(usage.identifier, core.isUseEffectLikeCall);
|
|
2278
2278
|
if (effect == null) return;
|
|
2279
2279
|
effectSet.add(effect);
|
|
2280
2280
|
if (effectSet.size > 1) return;
|
|
@@ -2305,14 +2305,14 @@ var no_unnecessary_use_prefix_default = createRule({
|
|
|
2305
2305
|
defaultOptions: []
|
|
2306
2306
|
});
|
|
2307
2307
|
function create$17(context) {
|
|
2308
|
-
const { ctx, visitor } = useHookCollector(context);
|
|
2308
|
+
const { ctx, visitor } = core.useHookCollector(context);
|
|
2309
2309
|
return defineRuleListener(visitor, { "Program:exit"(program) {
|
|
2310
2310
|
for (const { id, name, node, hookCalls } of ctx.getAllHooks(program)) {
|
|
2311
2311
|
if (hookCalls.length > 0) continue;
|
|
2312
|
-
if (
|
|
2312
|
+
if (ast.isFunctionEmpty(node)) continue;
|
|
2313
2313
|
if (WELL_KNOWN_HOOKS.includes(name)) continue;
|
|
2314
2314
|
if (containsUseComments(context, node)) continue;
|
|
2315
|
-
if (
|
|
2315
|
+
if (ast.findParentNode(node, ast.isViMockCallback) != null) continue;
|
|
2316
2316
|
context.report({
|
|
2317
2317
|
messageId: "noUnnecessaryUsePrefix",
|
|
2318
2318
|
node: id ?? node,
|
|
@@ -2340,7 +2340,7 @@ function create$16(context) {
|
|
|
2340
2340
|
if (!context.sourceCode.text.includes("useRef")) return {};
|
|
2341
2341
|
return { VariableDeclarator(node) {
|
|
2342
2342
|
const { id, init } = node;
|
|
2343
|
-
if (id.type !== AST_NODE_TYPES.Identifier || init == null || !isUseRefCall(init)) return;
|
|
2343
|
+
if (id.type !== AST_NODE_TYPES.Identifier || init == null || !core.isUseRefCall(init)) return;
|
|
2344
2344
|
const [ref, ...rest] = context.sourceCode.getDeclaredVariables(node);
|
|
2345
2345
|
if (ref == null || rest.length > 0) return;
|
|
2346
2346
|
if (ref.name.toLowerCase().startsWith("prev")) return;
|
|
@@ -2348,7 +2348,7 @@ function create$16(context) {
|
|
|
2348
2348
|
let globalUsages = 0;
|
|
2349
2349
|
for (const { identifier, init } of ref.references) {
|
|
2350
2350
|
if (init != null) continue;
|
|
2351
|
-
const effect =
|
|
2351
|
+
const effect = ast.findParentNode(identifier, core.isUseEffectLikeCall);
|
|
2352
2352
|
if (effect == null) globalUsages++;
|
|
2353
2353
|
else effects.add(effect);
|
|
2354
2354
|
}
|
|
@@ -2376,11 +2376,11 @@ var no_unsafe_component_will_mount_default = createRule({
|
|
|
2376
2376
|
});
|
|
2377
2377
|
function create$15(context) {
|
|
2378
2378
|
if (!context.sourceCode.text.includes("UNSAFE_componentWillMount")) return {};
|
|
2379
|
-
const { ctx, visitor } = useComponentCollectorLegacy(context);
|
|
2379
|
+
const { ctx, visitor } = core.useComponentCollectorLegacy(context);
|
|
2380
2380
|
return defineRuleListener(visitor, { "Program:exit"(program) {
|
|
2381
2381
|
for (const { node: component } of ctx.getAllComponents(program)) {
|
|
2382
2382
|
const { body } = component.body;
|
|
2383
|
-
for (const member of body) if (isUnsafeComponentWillMount(member)) context.report({
|
|
2383
|
+
for (const member of body) if (core.isUnsafeComponentWillMount(member)) context.report({
|
|
2384
2384
|
messageId: "noUnsafeComponentWillMount",
|
|
2385
2385
|
node: member
|
|
2386
2386
|
});
|
|
@@ -2404,11 +2404,11 @@ var no_unsafe_component_will_receive_props_default = createRule({
|
|
|
2404
2404
|
});
|
|
2405
2405
|
function create$14(context) {
|
|
2406
2406
|
if (!context.sourceCode.text.includes("UNSAFE_componentWillReceiveProps")) return {};
|
|
2407
|
-
const { ctx, visitor } = useComponentCollectorLegacy(context);
|
|
2407
|
+
const { ctx, visitor } = core.useComponentCollectorLegacy(context);
|
|
2408
2408
|
return defineRuleListener(visitor, { "Program:exit"(program) {
|
|
2409
2409
|
for (const { node: component } of ctx.getAllComponents(program)) {
|
|
2410
2410
|
const { body } = component.body;
|
|
2411
|
-
for (const member of body) if (isUnsafeComponentWillReceiveProps(member)) context.report({
|
|
2411
|
+
for (const member of body) if (core.isUnsafeComponentWillReceiveProps(member)) context.report({
|
|
2412
2412
|
messageId: "noUnsafeComponentWillReceiveProps",
|
|
2413
2413
|
node: member
|
|
2414
2414
|
});
|
|
@@ -2432,11 +2432,11 @@ var no_unsafe_component_will_update_default = createRule({
|
|
|
2432
2432
|
});
|
|
2433
2433
|
function create$13(context) {
|
|
2434
2434
|
if (!context.sourceCode.text.includes("UNSAFE_componentWillUpdate")) return {};
|
|
2435
|
-
const { ctx, visitor } = useComponentCollectorLegacy(context);
|
|
2435
|
+
const { ctx, visitor } = core.useComponentCollectorLegacy(context);
|
|
2436
2436
|
return defineRuleListener(visitor, { "Program:exit"(program) {
|
|
2437
2437
|
for (const { node: component } of ctx.getAllComponents(program)) {
|
|
2438
2438
|
const { body } = component.body;
|
|
2439
|
-
for (const member of body) if (isUnsafeComponentWillUpdate(member)) context.report({
|
|
2439
|
+
for (const member of body) if (core.isUnsafeComponentWillUpdate(member)) context.report({
|
|
2440
2440
|
messageId: "noUnsafeComponentWillUpdate",
|
|
2441
2441
|
node: member
|
|
2442
2442
|
});
|
|
@@ -2459,14 +2459,14 @@ var no_unstable_context_value_default = createRule({
|
|
|
2459
2459
|
defaultOptions: []
|
|
2460
2460
|
});
|
|
2461
2461
|
function create$12(context) {
|
|
2462
|
-
if (
|
|
2462
|
+
if (ast.getFileDirectives(context.sourceCode.ast).some((d) => d.value === "use memo")) return {};
|
|
2463
2463
|
const { version } = getSettingsFromContext(context);
|
|
2464
2464
|
const isReact18OrBelow = compare(version, "19.0.0", "<");
|
|
2465
|
-
const { ctx, visitor } = useComponentCollector(context);
|
|
2465
|
+
const { ctx, visitor } = core.useComponentCollector(context);
|
|
2466
2466
|
const constructions = /* @__PURE__ */ new WeakMap();
|
|
2467
2467
|
return defineRuleListener(visitor, {
|
|
2468
2468
|
JSXOpeningElement(node) {
|
|
2469
|
-
const selfName = getJsxElementType(context, node.parent).split(".").at(-1);
|
|
2469
|
+
const selfName = core.getJsxElementType(context, node.parent).split(".").at(-1);
|
|
2470
2470
|
if (selfName == null) return;
|
|
2471
2471
|
if (!isContextName(selfName, isReact18OrBelow)) return;
|
|
2472
2472
|
const functionEntry = ctx.getCurrentEntry();
|
|
@@ -2478,7 +2478,7 @@ function create$12(context) {
|
|
|
2478
2478
|
const valueExpression = value.expression;
|
|
2479
2479
|
const construction = getObjectType(valueExpression, context.sourceCode.getScope(valueExpression));
|
|
2480
2480
|
if (construction == null) return;
|
|
2481
|
-
if (isHookCall(construction.node)) return;
|
|
2481
|
+
if (core.isHookCall(construction.node)) return;
|
|
2482
2482
|
getOrElseUpdate(constructions, functionEntry.node, () => []).push(construction);
|
|
2483
2483
|
},
|
|
2484
2484
|
"Program:exit"(program) {
|
|
@@ -2490,7 +2490,7 @@ function create$12(context) {
|
|
|
2490
2490
|
messageId: "unstableContextValue",
|
|
2491
2491
|
node: constructionNode,
|
|
2492
2492
|
data: {
|
|
2493
|
-
type:
|
|
2493
|
+
type: ast.toDelimiterFormat(constructionNode),
|
|
2494
2494
|
suggestion
|
|
2495
2495
|
}
|
|
2496
2496
|
});
|
|
@@ -2536,13 +2536,13 @@ function extractIdentifier(node) {
|
|
|
2536
2536
|
return null;
|
|
2537
2537
|
}
|
|
2538
2538
|
function create$11(context, [options]) {
|
|
2539
|
-
if (
|
|
2540
|
-
const { ctx, visitor } = useComponentCollector(context);
|
|
2539
|
+
if (ast.getFileDirectives(context.sourceCode.ast).some((d) => d.value === "use memo")) return {};
|
|
2540
|
+
const { ctx, visitor } = core.useComponentCollector(context);
|
|
2541
2541
|
const declarators = /* @__PURE__ */ new WeakMap();
|
|
2542
2542
|
const { safeDefaultProps = [] } = options;
|
|
2543
2543
|
const safePatterns = safeDefaultProps.map((s) => toRegExp(s));
|
|
2544
2544
|
return defineRuleListener(visitor, {
|
|
2545
|
-
[
|
|
2545
|
+
[ast.SEL_OBJECT_DESTRUCTURING_VARIABLE_DECLARATOR](node) {
|
|
2546
2546
|
const functionEntry = ctx.getCurrentEntry();
|
|
2547
2547
|
if (functionEntry == null) return;
|
|
2548
2548
|
getOrElseUpdate(declarators, functionEntry.node, () => []).push(node);
|
|
@@ -2561,12 +2561,12 @@ function create$11(context, [options]) {
|
|
|
2561
2561
|
const { right } = value;
|
|
2562
2562
|
const construction = getObjectType(value, context.sourceCode.getScope(value));
|
|
2563
2563
|
if (construction == null) continue;
|
|
2564
|
-
if (isHookCall(construction.node)) continue;
|
|
2564
|
+
if (core.isHookCall(construction.node)) continue;
|
|
2565
2565
|
if (safePatterns.length > 0) {
|
|
2566
2566
|
const identifier = extractIdentifier(right);
|
|
2567
2567
|
if (identifier != null && safePatterns.some((pattern) => pattern.test(identifier))) continue;
|
|
2568
2568
|
}
|
|
2569
|
-
const forbiddenType =
|
|
2569
|
+
const forbiddenType = ast.toDelimiterFormat(right);
|
|
2570
2570
|
context.report({
|
|
2571
2571
|
messageId: "noUnstableDefaultProps",
|
|
2572
2572
|
node: right,
|
|
@@ -2622,19 +2622,19 @@ function create$10(context) {
|
|
|
2622
2622
|
const propertyUsages = /* @__PURE__ */ new WeakMap();
|
|
2623
2623
|
function classEnter(node) {
|
|
2624
2624
|
classStack.push(node);
|
|
2625
|
-
if (!isClassComponent(node)) return;
|
|
2625
|
+
if (!core.isClassComponent(node)) return;
|
|
2626
2626
|
propertyDefs.set(node, /* @__PURE__ */ new Set());
|
|
2627
2627
|
propertyUsages.set(node, /* @__PURE__ */ new Set());
|
|
2628
2628
|
}
|
|
2629
2629
|
function classExit() {
|
|
2630
2630
|
const currentClass = classStack.pop();
|
|
2631
|
-
if (currentClass == null || !isClassComponent(currentClass)) return;
|
|
2632
|
-
const id =
|
|
2631
|
+
if (currentClass == null || !core.isClassComponent(currentClass)) return;
|
|
2632
|
+
const id = ast.getClassId(currentClass);
|
|
2633
2633
|
const defs = propertyDefs.get(currentClass);
|
|
2634
2634
|
const usages = propertyUsages.get(currentClass);
|
|
2635
2635
|
if (defs == null) return;
|
|
2636
2636
|
for (const def of defs) {
|
|
2637
|
-
const methodName =
|
|
2637
|
+
const methodName = ast.getPropertyName(def);
|
|
2638
2638
|
if (methodName == null) continue;
|
|
2639
2639
|
if ((usages?.has(methodName) ?? false) || LIFECYCLE_METHODS.has(methodName)) continue;
|
|
2640
2640
|
context.report({
|
|
@@ -2650,7 +2650,7 @@ function create$10(context) {
|
|
|
2650
2650
|
function methodEnter(node) {
|
|
2651
2651
|
methodStack.push(node);
|
|
2652
2652
|
const currentClass = classStack.at(-1);
|
|
2653
|
-
if (currentClass == null || !isClassComponent(currentClass)) return;
|
|
2653
|
+
if (currentClass == null || !core.isClassComponent(currentClass)) return;
|
|
2654
2654
|
if (node.static) return;
|
|
2655
2655
|
if (isKeyLiteral$1(node, node.key)) propertyDefs.get(currentClass)?.add(node.key);
|
|
2656
2656
|
}
|
|
@@ -2666,13 +2666,13 @@ function create$10(context) {
|
|
|
2666
2666
|
const currentClass = classStack.at(-1);
|
|
2667
2667
|
const currentMethod = methodStack.at(-1);
|
|
2668
2668
|
if (currentClass == null || currentMethod == null) return;
|
|
2669
|
-
if (!isClassComponent(currentClass) || currentMethod.static) return;
|
|
2670
|
-
if (!
|
|
2669
|
+
if (!core.isClassComponent(currentClass) || currentMethod.static) return;
|
|
2670
|
+
if (!ast.isThisExpressionLoose(node.object) || !isKeyLiteral$1(node, node.property)) return;
|
|
2671
2671
|
if (node.parent.type === AST_NODE_TYPES.AssignmentExpression && node.parent.left === node) {
|
|
2672
2672
|
propertyDefs.get(currentClass)?.add(node.property);
|
|
2673
2673
|
return;
|
|
2674
2674
|
}
|
|
2675
|
-
const propertyName =
|
|
2675
|
+
const propertyName = ast.getPropertyName(node.property);
|
|
2676
2676
|
if (propertyName != null) propertyUsages.get(currentClass)?.add(propertyName);
|
|
2677
2677
|
},
|
|
2678
2678
|
MethodDefinition: methodEnter,
|
|
@@ -2683,10 +2683,10 @@ function create$10(context) {
|
|
|
2683
2683
|
const currentClass = classStack.at(-1);
|
|
2684
2684
|
const currentMethod = methodStack.at(-1);
|
|
2685
2685
|
if (currentClass == null || currentMethod == null) return;
|
|
2686
|
-
if (!isClassComponent(currentClass) || currentMethod.static) return;
|
|
2687
|
-
if (node.init != null &&
|
|
2686
|
+
if (!core.isClassComponent(currentClass) || currentMethod.static) return;
|
|
2687
|
+
if (node.init != null && ast.isThisExpressionLoose(node.init) && node.id.type === AST_NODE_TYPES.ObjectPattern) {
|
|
2688
2688
|
for (const prop of node.id.properties) if (prop.type === AST_NODE_TYPES.Property && isKeyLiteral$1(prop, prop.key)) {
|
|
2689
|
-
const keyName =
|
|
2689
|
+
const keyName = ast.getPropertyName(prop.key);
|
|
2690
2690
|
if (keyName != null) propertyUsages.get(currentClass)?.add(keyName);
|
|
2691
2691
|
}
|
|
2692
2692
|
}
|
|
@@ -2710,7 +2710,7 @@ var no_unused_props_default = createRule({
|
|
|
2710
2710
|
});
|
|
2711
2711
|
function create$9(context) {
|
|
2712
2712
|
const services = ESLintUtils.getParserServices(context, false);
|
|
2713
|
-
const { ctx, visitor } = useComponentCollector(context);
|
|
2713
|
+
const { ctx, visitor } = core.useComponentCollector(context);
|
|
2714
2714
|
return defineRuleListener(visitor, { "Program:exit"(program) {
|
|
2715
2715
|
const checker = services.program.getTypeChecker();
|
|
2716
2716
|
const totalDeclaredProps = /* @__PURE__ */ new Set();
|
|
@@ -2834,8 +2834,8 @@ function create$8(context) {
|
|
|
2834
2834
|
}
|
|
2835
2835
|
function classExit() {
|
|
2836
2836
|
const currentClass = classStack.pop();
|
|
2837
|
-
if (currentClass == null || !isClassComponent(currentClass)) return;
|
|
2838
|
-
const id =
|
|
2837
|
+
if (currentClass == null || !core.isClassComponent(currentClass)) return;
|
|
2838
|
+
const id = ast.getClassId(currentClass);
|
|
2839
2839
|
const { node: defNode, isUsed = false } = stateDefs.get(currentClass) ?? {};
|
|
2840
2840
|
if (defNode == null || isUsed) return;
|
|
2841
2841
|
context.report({
|
|
@@ -2847,9 +2847,9 @@ function create$8(context) {
|
|
|
2847
2847
|
function methodEnter(node) {
|
|
2848
2848
|
methodStack.push(node);
|
|
2849
2849
|
const currentClass = classStack.at(-1);
|
|
2850
|
-
if (currentClass == null || !isClassComponent(currentClass)) return;
|
|
2850
|
+
if (currentClass == null || !core.isClassComponent(currentClass)) return;
|
|
2851
2851
|
if (node.static) {
|
|
2852
|
-
if (isGetDerivedStateFromProps(node) && isMatching({ params: [P.nonNullable, ...P.array()] })(node.value)) {
|
|
2852
|
+
if (core.isGetDerivedStateFromProps(node) && isMatching({ params: [P.nonNullable, ...P.array()] })(node.value)) {
|
|
2853
2853
|
const defNode = stateDefs.get(currentClass)?.node;
|
|
2854
2854
|
stateDefs.set(currentClass, {
|
|
2855
2855
|
node: defNode,
|
|
@@ -2858,7 +2858,7 @@ function create$8(context) {
|
|
|
2858
2858
|
}
|
|
2859
2859
|
return;
|
|
2860
2860
|
}
|
|
2861
|
-
if (
|
|
2861
|
+
if (ast.getPropertyName(node.key) === "state") stateDefs.set(currentClass, {
|
|
2862
2862
|
node: node.key,
|
|
2863
2863
|
isUsed: false
|
|
2864
2864
|
});
|
|
@@ -2874,9 +2874,9 @@ function create$8(context) {
|
|
|
2874
2874
|
}
|
|
2875
2875
|
return {
|
|
2876
2876
|
AssignmentExpression(node) {
|
|
2877
|
-
if (!isAssignmentToThisState(node)) return;
|
|
2877
|
+
if (!core.isAssignmentToThisState(node)) return;
|
|
2878
2878
|
const currentClass = classStack.at(-1);
|
|
2879
|
-
if (currentClass == null || !isClassComponent(currentClass)) return;
|
|
2879
|
+
if (currentClass == null || !core.isClassComponent(currentClass)) return;
|
|
2880
2880
|
const currentConstructor = constructorStack.at(-1);
|
|
2881
2881
|
if (currentConstructor == null || !currentClass.body.body.includes(currentConstructor)) return;
|
|
2882
2882
|
const isUsed = stateDefs.get(currentClass)?.isUsed ?? false;
|
|
@@ -2890,10 +2890,10 @@ function create$8(context) {
|
|
|
2890
2890
|
ClassExpression: classEnter,
|
|
2891
2891
|
"ClassExpression:exit": classExit,
|
|
2892
2892
|
MemberExpression(node) {
|
|
2893
|
-
if (!
|
|
2894
|
-
if (
|
|
2893
|
+
if (!ast.isThisExpressionLoose(node.object)) return;
|
|
2894
|
+
if (ast.getPropertyName(node.property) !== "state") return;
|
|
2895
2895
|
const currentClass = classStack.at(-1);
|
|
2896
|
-
if (currentClass == null || !isClassComponent(currentClass)) return;
|
|
2896
|
+
if (currentClass == null || !core.isClassComponent(currentClass)) return;
|
|
2897
2897
|
const currentMethod = methodStack.at(-1);
|
|
2898
2898
|
if (currentMethod == null || currentMethod.static) return;
|
|
2899
2899
|
if (currentMethod === constructorStack.at(-1)) return;
|
|
@@ -2912,14 +2912,14 @@ function create$8(context) {
|
|
|
2912
2912
|
"PropertyDefinition:exit": methodExit,
|
|
2913
2913
|
VariableDeclarator(node) {
|
|
2914
2914
|
const currentClass = classStack.at(-1);
|
|
2915
|
-
if (currentClass == null || !isClassComponent(currentClass)) return;
|
|
2915
|
+
if (currentClass == null || !core.isClassComponent(currentClass)) return;
|
|
2916
2916
|
const currentMethod = methodStack.at(-1);
|
|
2917
2917
|
if (currentMethod == null || currentMethod.static) return;
|
|
2918
2918
|
if (currentMethod === constructorStack.at(-1)) return;
|
|
2919
2919
|
if (!currentClass.body.body.includes(currentMethod)) return;
|
|
2920
|
-
if (node.init == null || !
|
|
2920
|
+
if (node.init == null || !ast.isThisExpressionLoose(node.init) || node.id.type !== AST_NODE_TYPES.ObjectPattern) return;
|
|
2921
2921
|
if (!node.id.properties.some((prop) => {
|
|
2922
|
-
if (prop.type === AST_NODE_TYPES.Property && isKeyLiteral(prop, prop.key)) return
|
|
2922
|
+
if (prop.type === AST_NODE_TYPES.Property && isKeyLiteral(prop, prop.key)) return ast.getPropertyName(prop.key) === "state";
|
|
2923
2923
|
return false;
|
|
2924
2924
|
})) return;
|
|
2925
2925
|
const defNode = stateDefs.get(currentClass)?.node;
|
|
@@ -2953,7 +2953,7 @@ function create$7(context) {
|
|
|
2953
2953
|
const hookCalls = /* @__PURE__ */ new Set();
|
|
2954
2954
|
return {
|
|
2955
2955
|
CallExpression(node) {
|
|
2956
|
-
if (!isHookCall(node)) return;
|
|
2956
|
+
if (!core.isHookCall(node)) return;
|
|
2957
2957
|
hookCalls.add(node);
|
|
2958
2958
|
},
|
|
2959
2959
|
ImportDeclaration(node) {
|
|
@@ -2984,7 +2984,7 @@ function create$7(context) {
|
|
|
2984
2984
|
},
|
|
2985
2985
|
"Program:exit"() {
|
|
2986
2986
|
for (const node of hookCalls) {
|
|
2987
|
-
if (!isUseContextCall(node)) continue;
|
|
2987
|
+
if (!core.isUseContextCall(node)) continue;
|
|
2988
2988
|
context.report({
|
|
2989
2989
|
messageId: "noUseContext",
|
|
2990
2990
|
node: node.callee,
|
|
@@ -3025,9 +3025,9 @@ var no_useless_forward_ref_default = createRule({
|
|
|
3025
3025
|
});
|
|
3026
3026
|
function create$6(context) {
|
|
3027
3027
|
return { CallExpression(node) {
|
|
3028
|
-
if (!isForwardRefCall(context, node)) return;
|
|
3028
|
+
if (!core.isForwardRefCall(context, node)) return;
|
|
3029
3029
|
const [component] = node.arguments;
|
|
3030
|
-
if (component == null || !
|
|
3030
|
+
if (component == null || !ast.isFunction(component)) return;
|
|
3031
3031
|
if (component.params[1] != null) return;
|
|
3032
3032
|
context.report({
|
|
3033
3033
|
messageId: "noUselessForwardRef",
|
|
@@ -3073,15 +3073,15 @@ var no_useless_fragment_default = createRule({
|
|
|
3073
3073
|
function create$5(context, [option]) {
|
|
3074
3074
|
const { allowEmptyFragment = false, allowExpressions = true } = option;
|
|
3075
3075
|
const jsxConfig = {
|
|
3076
|
-
...getJsxConfigFromContext(context),
|
|
3077
|
-
...getJsxConfigFromAnnotation(context)
|
|
3076
|
+
...core.getJsxConfigFromContext(context),
|
|
3077
|
+
...core.getJsxConfigFromAnnotation(context)
|
|
3078
3078
|
};
|
|
3079
3079
|
/**
|
|
3080
3080
|
* Check if a fragment node is useless and should be reported
|
|
3081
3081
|
*/
|
|
3082
3082
|
function checkNode(context, node) {
|
|
3083
|
-
if (node.type === AST_NODE_TYPES.JSXElement && getJsxAttribute(context, node)("key") != null) return;
|
|
3084
|
-
if (isJsxHostElement(context, node.parent)) context.report({
|
|
3083
|
+
if (node.type === AST_NODE_TYPES.JSXElement && core.getJsxAttribute(context, node)("key") != null) return;
|
|
3084
|
+
if (core.isJsxHostElement(context, node.parent)) context.report({
|
|
3085
3085
|
messageId: "noUselessFragment",
|
|
3086
3086
|
node,
|
|
3087
3087
|
data: { reason: "placed inside a host component" },
|
|
@@ -3097,9 +3097,9 @@ function create$5(context, [option]) {
|
|
|
3097
3097
|
});
|
|
3098
3098
|
return;
|
|
3099
3099
|
}
|
|
3100
|
-
const isChildElement =
|
|
3100
|
+
const isChildElement = ast.isOneOf([AST_NODE_TYPES.JSXElement, AST_NODE_TYPES.JSXFragment])(node.parent);
|
|
3101
3101
|
switch (true) {
|
|
3102
|
-
case allowExpressions && !isChildElement && node.children.length === 1 && isJsxText(node.children.at(0)): return;
|
|
3102
|
+
case allowExpressions && !isChildElement && node.children.length === 1 && core.isJsxText(node.children.at(0)): return;
|
|
3103
3103
|
case !allowExpressions && isChildElement:
|
|
3104
3104
|
context.report({
|
|
3105
3105
|
messageId: "noUselessFragment",
|
|
@@ -3139,13 +3139,13 @@ function create$5(context, [option]) {
|
|
|
3139
3139
|
* Check if it's safe to automatically fix the fragment
|
|
3140
3140
|
*/
|
|
3141
3141
|
function canFix(context, node) {
|
|
3142
|
-
if (node.parent.type === AST_NODE_TYPES.JSXElement || node.parent.type === AST_NODE_TYPES.JSXFragment) return isJsxHostElement(context, node.parent);
|
|
3142
|
+
if (node.parent.type === AST_NODE_TYPES.JSXElement || node.parent.type === AST_NODE_TYPES.JSXFragment) return core.isJsxHostElement(context, node.parent);
|
|
3143
3143
|
if (node.children.length === 0) return false;
|
|
3144
|
-
return !node.children.some((child) => isJsxText(child) && !isWhiteSpace(child) ||
|
|
3144
|
+
return !node.children.some((child) => core.isJsxText(child) && !isWhiteSpace(child) || ast.is(AST_NODE_TYPES.JSXExpressionContainer)(child));
|
|
3145
3145
|
}
|
|
3146
3146
|
return {
|
|
3147
3147
|
JSXElement(node) {
|
|
3148
|
-
if (!isJsxFragmentElement(context, node, jsxConfig)) return;
|
|
3148
|
+
if (!core.isJsxFragmentElement(context, node, jsxConfig)) return;
|
|
3149
3149
|
checkNode(context, node);
|
|
3150
3150
|
},
|
|
3151
3151
|
JSXFragment(node) {
|
|
@@ -3163,7 +3163,7 @@ function isWhiteSpace(node) {
|
|
|
3163
3163
|
* Check if a node is padding spaces (whitespace with line breaks)
|
|
3164
3164
|
*/
|
|
3165
3165
|
function isPaddingSpaces(node) {
|
|
3166
|
-
return isJsxText(node) && isWhiteSpace(node) && node.raw.includes("\n");
|
|
3166
|
+
return core.isJsxText(node) && isWhiteSpace(node) && node.raw.includes("\n");
|
|
3167
3167
|
}
|
|
3168
3168
|
/**
|
|
3169
3169
|
* Trim whitespace like React would in JSX
|
|
@@ -3191,7 +3191,7 @@ var prefer_destructuring_assignment_default = createRule({
|
|
|
3191
3191
|
defaultOptions: []
|
|
3192
3192
|
});
|
|
3193
3193
|
function create$4(context) {
|
|
3194
|
-
const { ctx, visitor } = useComponentCollector(context);
|
|
3194
|
+
const { ctx, visitor } = core.useComponentCollector(context);
|
|
3195
3195
|
return defineRuleListener(visitor, { "Program:exit"(program) {
|
|
3196
3196
|
for (const component of ctx.getAllComponents(program)) {
|
|
3197
3197
|
if (component.name == null && component.isExportDefaultDeclaration) continue;
|
|
@@ -3266,7 +3266,7 @@ var prefer_read_only_props_default = createRule({
|
|
|
3266
3266
|
function create$2(context) {
|
|
3267
3267
|
const services = ESLintUtils.getParserServices(context, false);
|
|
3268
3268
|
const checker = services.program.getTypeChecker();
|
|
3269
|
-
const { ctx, visitor } = useComponentCollector(context);
|
|
3269
|
+
const { ctx, visitor } = core.useComponentCollector(context);
|
|
3270
3270
|
return defineRuleListener(visitor, { "Program:exit"(program) {
|
|
3271
3271
|
for (const component of ctx.getAllComponents(program)) {
|
|
3272
3272
|
const [props] = component.node.params;
|
|
@@ -3323,23 +3323,23 @@ var prefer_use_state_lazy_initialization_default = createRule({
|
|
|
3323
3323
|
});
|
|
3324
3324
|
function create$1(context) {
|
|
3325
3325
|
return { CallExpression(node) {
|
|
3326
|
-
if (!isUseStateCall(node)) return;
|
|
3326
|
+
if (!core.isUseStateCall(node)) return;
|
|
3327
3327
|
const [useStateInput] = node.arguments;
|
|
3328
3328
|
if (useStateInput == null) return;
|
|
3329
|
-
for (const expr of
|
|
3329
|
+
for (const expr of ast.getNestedNewExpressions(useStateInput)) {
|
|
3330
3330
|
if (!("name" in expr.callee)) continue;
|
|
3331
3331
|
if (ALLOW_LIST.includes(expr.callee.name)) continue;
|
|
3332
|
-
if (
|
|
3332
|
+
if (ast.findParentNode(expr, core.isUseCall) != null) continue;
|
|
3333
3333
|
context.report({
|
|
3334
3334
|
messageId: "preferUseStateLazyInitialization",
|
|
3335
3335
|
node: expr
|
|
3336
3336
|
});
|
|
3337
3337
|
}
|
|
3338
|
-
for (const expr of
|
|
3338
|
+
for (const expr of ast.getNestedCallExpressions(useStateInput)) {
|
|
3339
3339
|
if (!("name" in expr.callee)) continue;
|
|
3340
|
-
if (isHookName(expr.callee.name)) continue;
|
|
3340
|
+
if (core.isHookName(expr.callee.name)) continue;
|
|
3341
3341
|
if (ALLOW_LIST.includes(expr.callee.name)) continue;
|
|
3342
|
-
if (
|
|
3342
|
+
if (ast.findParentNode(expr, core.isUseCall) != null) continue;
|
|
3343
3343
|
context.report({
|
|
3344
3344
|
messageId: "preferUseStateLazyInitialization",
|
|
3345
3345
|
node: expr
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-react-x",
|
|
3
|
-
"version": "2.8.1",
|
|
3
|
+
"version": "2.8.2-beta.1",
|
|
4
4
|
"description": "A set of composable ESLint rules for for libraries and frameworks that use React as a UI runtime.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react",
|
|
@@ -46,11 +46,11 @@
|
|
|
46
46
|
"string-ts": "^2.3.1",
|
|
47
47
|
"ts-api-utils": "^2.4.0",
|
|
48
48
|
"ts-pattern": "^5.9.0",
|
|
49
|
-
"@eslint-react/ast": "2.8.1",
|
|
50
|
-
"@eslint-react/
|
|
51
|
-
"@eslint-react/
|
|
52
|
-
"@eslint-react/
|
|
53
|
-
"@eslint-react/
|
|
49
|
+
"@eslint-react/ast": "2.8.2-beta.1",
|
|
50
|
+
"@eslint-react/core": "2.8.2-beta.1",
|
|
51
|
+
"@eslint-react/eff": "2.8.2-beta.1",
|
|
52
|
+
"@eslint-react/var": "2.8.2-beta.1",
|
|
53
|
+
"@eslint-react/shared": "2.8.2-beta.1"
|
|
54
54
|
},
|
|
55
55
|
"devDependencies": {
|
|
56
56
|
"@types/react": "^19.2.10",
|