eslint-plugin-react-hooks-extra 2.8.1 → 2.8.2-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +20 -20
- package/package.json +6 -6
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { WEBSITE_URL, getConfigAdapters, getSettingsFromContext } from "@eslint-react/shared";
|
|
2
|
-
import * as
|
|
3
|
-
import
|
|
2
|
+
import * as ast from "@eslint-react/ast";
|
|
3
|
+
import * as core from "@eslint-react/core";
|
|
4
4
|
import { constVoid, getOrElseUpdate, not } from "@eslint-react/eff";
|
|
5
5
|
import { findVariable, getVariableDefinitionNode } from "@eslint-react/var";
|
|
6
6
|
import { AST_NODE_TYPES } from "@typescript-eslint/types";
|
|
@@ -36,7 +36,7 @@ const rules = { "react-hooks-extra/no-direct-set-state-in-use-effect": "warn" };
|
|
|
36
36
|
//#endregion
|
|
37
37
|
//#region package.json
|
|
38
38
|
var name = "eslint-plugin-react-hooks-extra";
|
|
39
|
-
var version = "2.8.1";
|
|
39
|
+
var version = "2.8.2-beta.1";
|
|
40
40
|
|
|
41
41
|
//#endregion
|
|
42
42
|
//#region src/utils/create-rule.ts
|
|
@@ -50,8 +50,8 @@ const createRule = ESLintUtils.RuleCreator(getDocsUrl);
|
|
|
50
50
|
function isInitFromHookCall(init) {
|
|
51
51
|
if (init?.type !== AST_NODE_TYPES.CallExpression) return false;
|
|
52
52
|
switch (init.callee.type) {
|
|
53
|
-
case AST_NODE_TYPES.Identifier: return isHookName(init.callee.name);
|
|
54
|
-
case AST_NODE_TYPES.MemberExpression: return init.callee.property.type === AST_NODE_TYPES.Identifier && isHookName(init.callee.property.name);
|
|
53
|
+
case AST_NODE_TYPES.Identifier: return core.isHookName(init.callee.name);
|
|
54
|
+
case AST_NODE_TYPES.MemberExpression: return init.callee.property.type === AST_NODE_TYPES.Identifier && core.isHookName(init.callee.property.name);
|
|
55
55
|
default: return false;
|
|
56
56
|
}
|
|
57
57
|
}
|
|
@@ -97,20 +97,20 @@ function create(context) {
|
|
|
97
97
|
return node.callee.type === AST_NODE_TYPES.MemberExpression && node.callee.property.type === AST_NODE_TYPES.Identifier && node.callee.property.name === "then";
|
|
98
98
|
}
|
|
99
99
|
function isUseStateCall(node) {
|
|
100
|
-
return isUseStateLikeCall(node, additionalStateHooks);
|
|
100
|
+
return core.isUseStateLikeCall(node, additionalStateHooks);
|
|
101
101
|
}
|
|
102
102
|
function isUseEffectSetupCallback(node) {
|
|
103
|
-
return node.parent?.type === AST_NODE_TYPES.CallExpression && node.parent.callee !== node && isUseEffectLikeCall(node.parent);
|
|
103
|
+
return node.parent?.type === AST_NODE_TYPES.CallExpression && node.parent.callee !== node && core.isUseEffectLikeCall(node.parent);
|
|
104
104
|
}
|
|
105
105
|
function getCallName(node) {
|
|
106
|
-
if (node.type === AST_NODE_TYPES.CallExpression) return
|
|
107
|
-
return
|
|
106
|
+
if (node.type === AST_NODE_TYPES.CallExpression) return ast.toStringFormat(node.callee, getText);
|
|
107
|
+
return ast.toStringFormat(node, getText);
|
|
108
108
|
}
|
|
109
109
|
function getCallKind(node) {
|
|
110
|
-
return match(node).when(isUseStateCall, () => "useState").when(isUseEffectLikeCall, () => "useEffect").when(isSetStateCall, () => "setState").when(isThenCall, () => "then").otherwise(() => "other");
|
|
110
|
+
return match(node).when(isUseStateCall, () => "useState").when(core.isUseEffectLikeCall, () => "useEffect").when(isSetStateCall, () => "setState").when(isThenCall, () => "then").otherwise(() => "other");
|
|
111
111
|
}
|
|
112
112
|
function getFunctionKind(node) {
|
|
113
|
-
const parent =
|
|
113
|
+
const parent = ast.findParentNode(node, not(ast.isTypeExpression)) ?? node.parent;
|
|
114
114
|
switch (true) {
|
|
115
115
|
case node.async:
|
|
116
116
|
case parent.type === AST_NODE_TYPES.CallExpression && isThenCall(parent): return "deferred";
|
|
@@ -171,7 +171,7 @@ function create(context) {
|
|
|
171
171
|
case pEntry.kind === "deferred":
|
|
172
172
|
case pEntry.node.async: break;
|
|
173
173
|
case pEntry.node === setupFunction:
|
|
174
|
-
case pEntry.kind === "immediate" &&
|
|
174
|
+
case pEntry.kind === "immediate" && ast.findParentNode(pEntry.node, ast.isFunction) === setupFunction:
|
|
175
175
|
context.report({
|
|
176
176
|
messageId: "noDirectSetStateInUseEffect",
|
|
177
177
|
node,
|
|
@@ -179,14 +179,14 @@ function create(context) {
|
|
|
179
179
|
});
|
|
180
180
|
return;
|
|
181
181
|
default: {
|
|
182
|
-
const init =
|
|
182
|
+
const init = ast.findParentNode(node, isVariableDeclaratorFromHookCall)?.init;
|
|
183
183
|
if (init == null) getOrElseUpdate(setStateCallsByFn, pEntry.node, () => []).push(node);
|
|
184
184
|
else getOrElseUpdate(setStateInHookCallbacks, init, () => []).push(node);
|
|
185
185
|
}
|
|
186
186
|
}
|
|
187
187
|
}).with("useEffect", () => {
|
|
188
|
-
if (
|
|
189
|
-
setupFnIds.push(...
|
|
188
|
+
if (ast.isFunction(node.arguments.at(0))) return;
|
|
189
|
+
setupFnIds.push(...ast.getNestedIdentifiers(node));
|
|
190
190
|
}).with("other", () => {
|
|
191
191
|
if (pEntry.node !== setupFunction) return;
|
|
192
192
|
trackedFnCalls.push(node);
|
|
@@ -199,19 +199,19 @@ function create(context) {
|
|
|
199
199
|
case AST_NODE_TYPES.ArrowFunctionExpression: {
|
|
200
200
|
const parent = node.parent.parent;
|
|
201
201
|
if (parent.type !== AST_NODE_TYPES.CallExpression) break;
|
|
202
|
-
if (!isUseMemoCall(parent)) break;
|
|
203
|
-
const init =
|
|
202
|
+
if (!core.isUseMemoCall(parent)) break;
|
|
203
|
+
const init = ast.findParentNode(parent, isVariableDeclaratorFromHookCall)?.init;
|
|
204
204
|
if (init != null) getOrElseUpdate(setStateInEffectArg, init, () => []).push(node);
|
|
205
205
|
break;
|
|
206
206
|
}
|
|
207
207
|
case AST_NODE_TYPES.CallExpression:
|
|
208
208
|
if (node !== node.parent.arguments.at(0)) break;
|
|
209
|
-
if (isUseCallbackCall(node.parent)) {
|
|
210
|
-
const init =
|
|
209
|
+
if (core.isUseCallbackCall(node.parent)) {
|
|
210
|
+
const init = ast.findParentNode(node.parent, isVariableDeclaratorFromHookCall)?.init;
|
|
211
211
|
if (init != null) getOrElseUpdate(setStateInEffectArg, init, () => []).push(node);
|
|
212
212
|
break;
|
|
213
213
|
}
|
|
214
|
-
if (isUseEffectLikeCall(node.parent)) getOrElseUpdate(setStateInEffectSetup, node.parent, () => []).push(node);
|
|
214
|
+
if (core.isUseEffectLikeCall(node.parent)) getOrElseUpdate(setStateInEffectSetup, node.parent, () => []).push(node);
|
|
215
215
|
}
|
|
216
216
|
},
|
|
217
217
|
"Program:exit"() {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-react-hooks-extra",
|
|
3
|
-
"version": "2.8.1",
|
|
3
|
+
"version": "2.8.2-beta.1",
|
|
4
4
|
"description": "ESLint React's ESLint plugin for React Hooks related rules.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react",
|
|
@@ -45,11 +45,11 @@
|
|
|
45
45
|
"@typescript-eslint/utils": "^8.54.0",
|
|
46
46
|
"string-ts": "^2.3.1",
|
|
47
47
|
"ts-pattern": "^5.9.0",
|
|
48
|
-
"@eslint-react/
|
|
49
|
-
"@eslint-react/
|
|
50
|
-
"@eslint-react/
|
|
51
|
-
"@eslint-react/
|
|
52
|
-
"@eslint-react/
|
|
48
|
+
"@eslint-react/ast": "2.8.2-beta.1",
|
|
49
|
+
"@eslint-react/core": "2.8.2-beta.1",
|
|
50
|
+
"@eslint-react/eff": "2.8.2-beta.1",
|
|
51
|
+
"@eslint-react/shared": "2.8.2-beta.1",
|
|
52
|
+
"@eslint-react/var": "2.8.2-beta.1"
|
|
53
53
|
},
|
|
54
54
|
"devDependencies": {
|
|
55
55
|
"@types/react": "^19.2.10",
|