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