eslint-plugin-react-x 2.6.1 → 2.6.2-beta.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 +31 -18
- package/package.json +6 -6
package/dist/index.js
CHANGED
|
@@ -3,7 +3,7 @@ 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 { ComponentDetectionHint, ComponentFlag, DEFAULT_COMPONENT_DETECTION_HINT, JsxEmit, findEnclosingAssignmentTarget, findParentJsxAttribute, getJsxAttribute, getJsxAttributeName, getJsxConfigFromAnnotation, getJsxConfigFromContext, getJsxElementType, isAssignmentToThisState, isCaptureOwnerStackCall, isChildrenCount, isChildrenForEach, isChildrenMap, isChildrenOnly, isChildrenToArray, isChildrenToArrayCall, isClassComponent, isCloneElementCall, isComponentDidCatch, isComponentDidMount, isComponentDidUpdate, isComponentNameLoose, isComponentWillMount, isComponentWillReceiveProps, isComponentWillUpdate, isCreateContextCall, isCreateElementCall, isCreateRefCall, isDeclaredInRenderPropLoose, isDirectValueOfRenderPropertyLoose, isForwardRefCall, isGetDerivedStateFromError, isGetDerivedStateFromProps, isInitializedFromReact, isInstanceIdEqual, isJsxFragmentElement, isJsxHostElement, isJsxText, isLazyCall, isReactHookCall, isReactHookName, isRenderMethodLike, isThisSetState, isUnsafeComponentWillMount, isUnsafeComponentWillReceiveProps, isUnsafeComponentWillUpdate, isUseCall, isUseCallbackCall, isUseContextCall, isUseEffectLikeCall, isUseMemoCall, isUseRefCall, isUseStateCall, useComponentCollector, useComponentCollectorLegacy, useHookCollector } from "@eslint-react/core";
|
|
6
|
+
import { ComponentDetectionHint, ComponentFlag, DEFAULT_COMPONENT_DETECTION_HINT, JsxEmit, findEnclosingAssignmentTarget, findParentJsxAttribute, getJsxAttribute, getJsxAttributeName, getJsxConfigFromAnnotation, getJsxConfigFromContext, getJsxElementType, isAssignmentToThisState, isCaptureOwnerStackCall, isChildrenCount, isChildrenForEach, isChildrenMap, isChildrenOnly, isChildrenToArray, isChildrenToArrayCall, isClassComponent, isCloneElementCall, isComponentDidCatch, isComponentDidMount, isComponentDidUpdate, isComponentNameLoose, isComponentWillMount, isComponentWillReceiveProps, isComponentWillUpdate, isCreateContextCall, isCreateElementCall, isCreateRefCall, isDeclaredInRenderPropLoose, isDirectValueOfRenderPropertyLoose, isForwardRefCall, isGetDerivedStateFromError, isGetDerivedStateFromProps, isInitializedFromReact, isInstanceIdEqual, isJsxFragmentElement, isJsxHostElement, isJsxText, isLazyCall, isReactHookCall, isReactHookName, isRenderFunctionLoose, isRenderMethodLike, isThisSetState, isUnsafeComponentWillMount, isUnsafeComponentWillReceiveProps, isUnsafeComponentWillUpdate, isUseCall, isUseCallbackCall, isUseContextCall, isUseEffectLikeCall, isUseMemoCall, isUseRefCall, isUseStateCall, useComponentCollector, useComponentCollectorLegacy, useHookCollector } from "@eslint-react/core";
|
|
7
7
|
import * as AST from "@eslint-react/ast";
|
|
8
8
|
import { findVariable, getChildScopes, getObjectType, getVariableDefinitionNode } from "@eslint-react/var";
|
|
9
9
|
import { constFalse, constTrue, flow, getOrElseUpdate, identity, unit } from "@eslint-react/eff";
|
|
@@ -34,7 +34,7 @@ var __exportAll = (all, symbols) => {
|
|
|
34
34
|
//#endregion
|
|
35
35
|
//#region package.json
|
|
36
36
|
var name$6 = "eslint-plugin-react-x";
|
|
37
|
-
var version = "2.6.
|
|
37
|
+
var version = "2.6.2-beta.0";
|
|
38
38
|
|
|
39
39
|
//#endregion
|
|
40
40
|
//#region src/utils/create-rule.ts
|
|
@@ -577,7 +577,7 @@ function create$53(context) {
|
|
|
577
577
|
classStack.pop();
|
|
578
578
|
},
|
|
579
579
|
MemberExpression(node) {
|
|
580
|
-
if (!AST.
|
|
580
|
+
if (!AST.isThisExpressionLoose(node.object)) return;
|
|
581
581
|
const [currClass, isComponent = false] = classStack.at(-1) ?? [];
|
|
582
582
|
if (currClass == null || !isComponent) return;
|
|
583
583
|
const [currMethod, isStatic = false] = methodStack.at(-1) ?? [];
|
|
@@ -609,7 +609,7 @@ function create$53(context) {
|
|
|
609
609
|
if (currMethod == null || isStatic) return;
|
|
610
610
|
const [setState, hasThisState = false] = setStateStack.at(-1) ?? [];
|
|
611
611
|
if (setState == null || hasThisState) return;
|
|
612
|
-
if (node.init == null || !AST.
|
|
612
|
+
if (node.init == null || !AST.isThisExpressionLoose(node.init) || node.id.type !== AST_NODE_TYPES.ObjectPattern) return;
|
|
613
613
|
if (!node.id.properties.some((prop) => prop.type === AST_NODE_TYPES.Property && isKeyLiteral$2(prop, prop.key) && AST.getPropertyName(prop.key) === "state")) return;
|
|
614
614
|
context.report({
|
|
615
615
|
messageId: "noAccessStateInSetstate",
|
|
@@ -623,6 +623,23 @@ function create$53(context) {
|
|
|
623
623
|
//#region src/rules/no-array-index-key.ts
|
|
624
624
|
const RULE_NAME$52 = "no-array-index-key";
|
|
625
625
|
const REACT_CHILDREN_METHOD = ["forEach", "map"];
|
|
626
|
+
const arrayIndexParamPosition = new Map([
|
|
627
|
+
["every", 1],
|
|
628
|
+
["filter", 1],
|
|
629
|
+
["find", 1],
|
|
630
|
+
["findIndex", 1],
|
|
631
|
+
["findLast", 1],
|
|
632
|
+
["findLastIndex", 1],
|
|
633
|
+
["flatMap", 1],
|
|
634
|
+
["forEach", 1],
|
|
635
|
+
["map", 1],
|
|
636
|
+
["reduce", 2],
|
|
637
|
+
["reduceRight", 2],
|
|
638
|
+
["some", 1]
|
|
639
|
+
]);
|
|
640
|
+
function getArrayIndexParamPosition(methodName) {
|
|
641
|
+
return arrayIndexParamPosition.get(methodName) ?? -1;
|
|
642
|
+
}
|
|
626
643
|
function isReactChildrenMethod(name$7) {
|
|
627
644
|
return REACT_CHILDREN_METHOD.includes(name$7);
|
|
628
645
|
}
|
|
@@ -641,7 +658,7 @@ function getMapIndexParamName(context, node) {
|
|
|
641
658
|
if (callee.type !== AST_NODE_TYPES.MemberExpression) return unit;
|
|
642
659
|
if (callee.property.type !== AST_NODE_TYPES.Identifier) return unit;
|
|
643
660
|
const { name: name$7 } = callee.property;
|
|
644
|
-
const indexPosition =
|
|
661
|
+
const indexPosition = getArrayIndexParamPosition(name$7);
|
|
645
662
|
if (indexPosition === -1) return unit;
|
|
646
663
|
const callbackArg = node.arguments[isUsingReactChildren(context, node) ? 1 : 0];
|
|
647
664
|
if (callbackArg == null) return unit;
|
|
@@ -2079,7 +2096,8 @@ function create$20(context) {
|
|
|
2079
2096
|
const jsxElement = node.parent.parent;
|
|
2080
2097
|
if (isJsxFragmentElement(context, jsxElement, jsxConfig)) return;
|
|
2081
2098
|
if (jsxElement.openingElement.attributes.some((attr) => attr.type === AST_NODE_TYPES.JSXSpreadAttribute)) return;
|
|
2082
|
-
|
|
2099
|
+
if (AST.findParentNode(jsxElement, (n) => isRenderFunctionLoose(context, n)) != null) return;
|
|
2100
|
+
const mapCallback = AST.findParentNode(jsxElement, isArrayMethodCallback);
|
|
2083
2101
|
if (mapCallback == null || AST.findParentNode(jsxElement, AST.isFunction) !== mapCallback) {
|
|
2084
2102
|
if (!(AST.findParentNode(jsxElement, (n) => AST.isConditional(n) || AST.isControlFlow(n) || findEnclosingAssignmentTarget(n) != null) != null)) context.report({
|
|
2085
2103
|
messageId: "noUnnecessaryKey",
|
|
@@ -2101,14 +2119,9 @@ function create$20(context) {
|
|
|
2101
2119
|
});
|
|
2102
2120
|
} };
|
|
2103
2121
|
}
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
* @returns `true` if the node is a map callback, `false` otherwise
|
|
2108
|
-
*/
|
|
2109
|
-
function isMapCallback(node) {
|
|
2110
|
-
if (node.parent == null) return false;
|
|
2111
|
-
if (!AST.isArrayMapCall(node.parent)) return false;
|
|
2122
|
+
function isArrayMethodCallback(node) {
|
|
2123
|
+
if (node.parent?.type !== AST_NODE_TYPES.CallExpression) return false;
|
|
2124
|
+
if (!AST.isArrayMapCall(node.parent) && !AST.isArrayFromCall(node.parent)) return false;
|
|
2112
2125
|
return AST.isOneOf([AST_NODE_TYPES.ArrowFunctionExpression, AST_NODE_TYPES.FunctionExpression])(AST.getUnderlyingExpression(node));
|
|
2113
2126
|
}
|
|
2114
2127
|
|
|
@@ -2653,7 +2666,7 @@ function create$10(context) {
|
|
|
2653
2666
|
const currentMethod = methodStack.at(-1);
|
|
2654
2667
|
if (currentClass == null || currentMethod == null) return;
|
|
2655
2668
|
if (!isClassComponent(currentClass) || currentMethod.static) return;
|
|
2656
|
-
if (!AST.
|
|
2669
|
+
if (!AST.isThisExpressionLoose(node.object) || !isKeyLiteral$1(node, node.property)) return;
|
|
2657
2670
|
if (node.parent.type === AST_NODE_TYPES.AssignmentExpression && node.parent.left === node) {
|
|
2658
2671
|
propertyDefs.get(currentClass)?.add(node.property);
|
|
2659
2672
|
return;
|
|
@@ -2670,7 +2683,7 @@ function create$10(context) {
|
|
|
2670
2683
|
const currentMethod = methodStack.at(-1);
|
|
2671
2684
|
if (currentClass == null || currentMethod == null) return;
|
|
2672
2685
|
if (!isClassComponent(currentClass) || currentMethod.static) return;
|
|
2673
|
-
if (node.init != null && AST.
|
|
2686
|
+
if (node.init != null && AST.isThisExpressionLoose(node.init) && node.id.type === AST_NODE_TYPES.ObjectPattern) {
|
|
2674
2687
|
for (const prop of node.id.properties) if (prop.type === AST_NODE_TYPES.Property && isKeyLiteral$1(prop, prop.key)) {
|
|
2675
2688
|
const keyName = AST.getPropertyName(prop.key);
|
|
2676
2689
|
if (keyName != null) propertyUsages.get(currentClass)?.add(keyName);
|
|
@@ -2879,7 +2892,7 @@ function create$8(context) {
|
|
|
2879
2892
|
ClassExpression: classEnter,
|
|
2880
2893
|
"ClassExpression:exit": classExit,
|
|
2881
2894
|
MemberExpression(node) {
|
|
2882
|
-
if (!AST.
|
|
2895
|
+
if (!AST.isThisExpressionLoose(node.object)) return;
|
|
2883
2896
|
if (AST.getPropertyName(node.property) !== "state") return;
|
|
2884
2897
|
const currentClass = classStack.at(-1);
|
|
2885
2898
|
if (currentClass == null || !isClassComponent(currentClass)) return;
|
|
@@ -2906,7 +2919,7 @@ function create$8(context) {
|
|
|
2906
2919
|
if (currentMethod == null || currentMethod.static) return;
|
|
2907
2920
|
if (currentMethod === constructorStack.at(-1)) return;
|
|
2908
2921
|
if (!currentClass.body.body.includes(currentMethod)) return;
|
|
2909
|
-
if (node.init == null || !AST.
|
|
2922
|
+
if (node.init == null || !AST.isThisExpressionLoose(node.init) || node.id.type !== AST_NODE_TYPES.ObjectPattern) return;
|
|
2910
2923
|
if (!node.id.properties.some((prop) => {
|
|
2911
2924
|
if (prop.type === AST_NODE_TYPES.Property && isKeyLiteral(prop, prop.key)) return AST.getPropertyName(prop.key) === "state";
|
|
2912
2925
|
return false;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-react-x",
|
|
3
|
-
"version": "2.6.
|
|
3
|
+
"version": "2.6.2-beta.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.6.
|
|
50
|
-
"@eslint-react/core": "2.6.
|
|
51
|
-
"@eslint-react/eff": "2.6.
|
|
52
|
-
"@eslint-react/
|
|
53
|
-
"@eslint-react/
|
|
49
|
+
"@eslint-react/ast": "2.6.2-beta.0",
|
|
50
|
+
"@eslint-react/core": "2.6.2-beta.0",
|
|
51
|
+
"@eslint-react/eff": "2.6.2-beta.0",
|
|
52
|
+
"@eslint-react/shared": "2.6.2-beta.0",
|
|
53
|
+
"@eslint-react/var": "2.6.2-beta.0"
|
|
54
54
|
},
|
|
55
55
|
"devDependencies": {
|
|
56
56
|
"@types/react": "^19.2.8",
|