eslint-plugin-react-hooks-extra 2.0.1-next.3 → 2.0.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 +14 -14
- package/package.json +7 -7
package/dist/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { getConfigAdapters, getDocsUrl } from "@eslint-react/shared";
|
|
2
2
|
import * as AST from "@eslint-react/ast";
|
|
3
|
-
import
|
|
3
|
+
import { isReactHookName, isUseCallbackCall, isUseEffectLikeCall, isUseMemoCall, isUseStateCall } from "@eslint-react/core";
|
|
4
4
|
import { constVoid, getOrElseUpdate, not } from "@eslint-react/eff";
|
|
5
|
-
import
|
|
5
|
+
import { findVariable, getVariableDefinitionNode } from "@eslint-react/var";
|
|
6
6
|
import { AST_NODE_TYPES } from "@typescript-eslint/types";
|
|
7
7
|
import { getStaticValue } from "@typescript-eslint/utils/ast-utils";
|
|
8
8
|
import { match } from "ts-pattern";
|
|
@@ -31,7 +31,7 @@ const rules = { "react-hooks-extra/no-direct-set-state-in-use-effect": "warn" };
|
|
|
31
31
|
//#endregion
|
|
32
32
|
//#region package.json
|
|
33
33
|
var name = "eslint-plugin-react-hooks-extra";
|
|
34
|
-
var version = "2.0.1
|
|
34
|
+
var version = "2.0.1";
|
|
35
35
|
|
|
36
36
|
//#endregion
|
|
37
37
|
//#region src/utils/create-rule.ts
|
|
@@ -42,8 +42,8 @@ const createRule = ESLintUtils.RuleCreator(getDocsUrl("hooks-extra"));
|
|
|
42
42
|
function isInitFromHookCall(init) {
|
|
43
43
|
if (init?.type !== AST_NODE_TYPES.CallExpression) return false;
|
|
44
44
|
switch (init.callee.type) {
|
|
45
|
-
case AST_NODE_TYPES.Identifier: return
|
|
46
|
-
case AST_NODE_TYPES.MemberExpression: return init.callee.property.type === AST_NODE_TYPES.Identifier &&
|
|
45
|
+
case AST_NODE_TYPES.Identifier: return isReactHookName(init.callee.name);
|
|
46
|
+
case AST_NODE_TYPES.MemberExpression: return init.callee.property.type === AST_NODE_TYPES.Identifier && isReactHookName(init.callee.property.name);
|
|
47
47
|
default: return false;
|
|
48
48
|
}
|
|
49
49
|
}
|
|
@@ -89,14 +89,14 @@ function create(context) {
|
|
|
89
89
|
if (setupFnRef.current === node) setupFnRef.current = null;
|
|
90
90
|
};
|
|
91
91
|
function isFunctionOfUseEffectSetup(node) {
|
|
92
|
-
return node.parent?.type === AST_NODE_TYPES.CallExpression && node.parent.callee !== node &&
|
|
92
|
+
return node.parent?.type === AST_NODE_TYPES.CallExpression && node.parent.callee !== node && isUseEffectLikeCall(node.parent);
|
|
93
93
|
}
|
|
94
94
|
function getCallName(node) {
|
|
95
95
|
if (node.type === AST_NODE_TYPES.CallExpression) return AST.toStringFormat(node.callee, getText);
|
|
96
96
|
return AST.toStringFormat(node, getText);
|
|
97
97
|
}
|
|
98
98
|
function getCallKind(node) {
|
|
99
|
-
return match(node).when(
|
|
99
|
+
return match(node).when(isUseStateCall, () => "useState").when(isUseEffectLikeCall, () => "useEffect").when(isSetStateCall, () => "setState").when(AST.isThenCall, () => "then").otherwise(() => "other");
|
|
100
100
|
}
|
|
101
101
|
function getFunctionKind(node) {
|
|
102
102
|
const parent = AST.findParentNode(node, not(AST.isTypeExpression)) ?? node.parent;
|
|
@@ -109,11 +109,11 @@ function create(context) {
|
|
|
109
109
|
}
|
|
110
110
|
}
|
|
111
111
|
function isIdFromUseStateCall(topLevelId, at) {
|
|
112
|
-
const variable =
|
|
113
|
-
const variableNode =
|
|
112
|
+
const variable = findVariable(topLevelId, context.sourceCode.getScope(topLevelId));
|
|
113
|
+
const variableNode = getVariableDefinitionNode(variable, 0);
|
|
114
114
|
if (variableNode == null) return false;
|
|
115
115
|
if (variableNode.type !== AST_NODE_TYPES.CallExpression) return false;
|
|
116
|
-
if (!
|
|
116
|
+
if (!isUseStateCall(variableNode)) return false;
|
|
117
117
|
const variableNodeParent = variableNode.parent;
|
|
118
118
|
if (!("id" in variableNodeParent) || variableNodeParent.id?.type !== AST_NODE_TYPES.ArrayPattern) return true;
|
|
119
119
|
return variableNodeParent.id.elements.findIndex((e) => e?.type === AST_NODE_TYPES.Identifier && e.name === topLevelId.name) === at;
|
|
@@ -191,24 +191,24 @@ function create(context) {
|
|
|
191
191
|
case AST_NODE_TYPES.ArrowFunctionExpression: {
|
|
192
192
|
const parent = node.parent.parent;
|
|
193
193
|
if (parent.type !== AST_NODE_TYPES.CallExpression) break;
|
|
194
|
-
if (!
|
|
194
|
+
if (!isUseMemoCall(parent)) break;
|
|
195
195
|
const init = AST.findParentNode(parent, isVariableDeclaratorFromHookCall)?.init;
|
|
196
196
|
if (init != null) getOrElseUpdate(setStateInEffectArg, init, () => []).push(node);
|
|
197
197
|
break;
|
|
198
198
|
}
|
|
199
199
|
case AST_NODE_TYPES.CallExpression:
|
|
200
200
|
if (node !== node.parent.arguments.at(0)) break;
|
|
201
|
-
if (
|
|
201
|
+
if (isUseCallbackCall(node.parent)) {
|
|
202
202
|
const init = AST.findParentNode(node.parent, isVariableDeclaratorFromHookCall)?.init;
|
|
203
203
|
if (init != null) getOrElseUpdate(setStateInEffectArg, init, () => []).push(node);
|
|
204
204
|
break;
|
|
205
205
|
}
|
|
206
|
-
if (
|
|
206
|
+
if (isUseEffectLikeCall(node.parent)) getOrElseUpdate(setStateInEffectSetup, node.parent, () => []).push(node);
|
|
207
207
|
}
|
|
208
208
|
},
|
|
209
209
|
"Program:exit"() {
|
|
210
210
|
const getSetStateCalls = (id, initialScope) => {
|
|
211
|
-
const node =
|
|
211
|
+
const node = getVariableDefinitionNode(findVariable(id, initialScope), 0);
|
|
212
212
|
switch (node?.type) {
|
|
213
213
|
case AST_NODE_TYPES.ArrowFunctionExpression:
|
|
214
214
|
case AST_NODE_TYPES.FunctionDeclaration:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-react-hooks-extra",
|
|
3
|
-
"version": "2.0.1
|
|
3
|
+
"version": "2.0.1",
|
|
4
4
|
"description": "ESLint React's ESLint plugin for React Hooks related rules.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react",
|
|
@@ -42,12 +42,12 @@
|
|
|
42
42
|
"@typescript-eslint/utils": "^8.44.1",
|
|
43
43
|
"string-ts": "^2.2.1",
|
|
44
44
|
"ts-pattern": "^5.8.0",
|
|
45
|
-
"@eslint-react/ast": "2.0.1
|
|
46
|
-
"@eslint-react/core": "2.0.1
|
|
47
|
-
"@eslint-react/
|
|
48
|
-
"@eslint-react/
|
|
49
|
-
"@eslint-react/
|
|
50
|
-
"@eslint-react/
|
|
45
|
+
"@eslint-react/ast": "2.0.1",
|
|
46
|
+
"@eslint-react/core": "2.0.1",
|
|
47
|
+
"@eslint-react/eff": "2.0.1",
|
|
48
|
+
"@eslint-react/kit": "2.0.1",
|
|
49
|
+
"@eslint-react/shared": "2.0.1",
|
|
50
|
+
"@eslint-react/var": "2.0.1"
|
|
51
51
|
},
|
|
52
52
|
"devDependencies": {
|
|
53
53
|
"@types/react": "^19.1.14",
|