eslint-plugin-react-hooks-extra 1.9.1 → 1.9.2-beta.4
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/LICENSE +1 -1
- package/dist/index.js +76 -259
- package/dist/index.mjs +77 -260
- package/package.json +9 -8
package/LICENSE
CHANGED
package/dist/index.js
CHANGED
|
@@ -5,18 +5,20 @@ var shared = require('@eslint-react/shared');
|
|
|
5
5
|
var ast = require('@eslint-react/ast');
|
|
6
6
|
var tools = require('@eslint-react/tools');
|
|
7
7
|
var _var = require('@eslint-react/var');
|
|
8
|
+
var types = require('@typescript-eslint/types');
|
|
8
9
|
var astUtils = require('@typescript-eslint/utils/ast-utils');
|
|
10
|
+
var tsPattern = require('ts-pattern');
|
|
9
11
|
|
|
10
12
|
// package.json
|
|
11
13
|
var name = "eslint-plugin-react-hooks-extra";
|
|
12
|
-
var version = "1.9.
|
|
14
|
+
var version = "1.9.2-beta.4";
|
|
13
15
|
var createRule = shared.createRuleForPlugin("hooks-extra");
|
|
14
16
|
function isFromHookCall(name2, context, settings, predicate = tools.F.constTrue) {
|
|
15
17
|
const hookAlias = settings.additionalHooks?.[name2] ?? [];
|
|
16
18
|
return (topLevelId) => tools.F.pipe(
|
|
17
19
|
_var.findVariable(topLevelId, context.sourceCode.getScope(topLevelId)),
|
|
18
20
|
tools.O.flatMap(_var.getVariableNode(0)),
|
|
19
|
-
tools.O.filter(ast.is(
|
|
21
|
+
tools.O.filter(ast.is(types.AST_NODE_TYPES.CallExpression)),
|
|
20
22
|
tools.O.filter(core.isReactHookCallWithNameAlias(name2, context, hookAlias)),
|
|
21
23
|
tools.O.exists((call) => predicate(topLevelId, call))
|
|
22
24
|
);
|
|
@@ -24,218 +26,33 @@ function isFromHookCall(name2, context, settings, predicate = tools.F.constTrue)
|
|
|
24
26
|
function isFromUseStateCall(context, settings) {
|
|
25
27
|
const predicate = (topLevelId, call) => {
|
|
26
28
|
const { parent } = call;
|
|
27
|
-
if (!("id" in parent && parent.id?.type ===
|
|
28
|
-
return parent.id.elements.findIndex((
|
|
29
|
+
if (!("id" in parent && parent.id?.type === types.AST_NODE_TYPES.ArrayPattern)) return true;
|
|
30
|
+
return parent.id.elements.findIndex((e) => e?.type === types.AST_NODE_TYPES.Identifier && e.name === topLevelId.name) === 1;
|
|
29
31
|
};
|
|
30
32
|
return isFromHookCall("useState", context, settings, predicate);
|
|
31
33
|
}
|
|
32
|
-
|
|
33
|
-
// ../../../node_modules/.pnpm/ts-pattern@5.2.0/node_modules/ts-pattern/dist/index.js
|
|
34
|
-
var t = Symbol.for("@ts-pattern/matcher");
|
|
35
|
-
var e = Symbol.for("@ts-pattern/isVariadic");
|
|
36
|
-
var n = "@ts-pattern/anonymous-select-key";
|
|
37
|
-
var r = (t2) => Boolean(t2 && "object" == typeof t2);
|
|
38
|
-
var i = (e2) => e2 && !!e2[t];
|
|
39
|
-
var o = (n2, s2, c2) => {
|
|
40
|
-
if (i(n2)) {
|
|
41
|
-
const e2 = n2[t](), { matched: r2, selections: i2 } = e2.match(s2);
|
|
42
|
-
return r2 && i2 && Object.keys(i2).forEach((t2) => c2(t2, i2[t2])), r2;
|
|
43
|
-
}
|
|
44
|
-
if (r(n2)) {
|
|
45
|
-
if (!r(s2)) return false;
|
|
46
|
-
if (Array.isArray(n2)) {
|
|
47
|
-
if (!Array.isArray(s2)) return false;
|
|
48
|
-
let t2 = [], r2 = [], a2 = [];
|
|
49
|
-
for (const o2 of n2.keys()) {
|
|
50
|
-
const s3 = n2[o2];
|
|
51
|
-
i(s3) && s3[e] ? a2.push(s3) : a2.length ? r2.push(s3) : t2.push(s3);
|
|
52
|
-
}
|
|
53
|
-
if (a2.length) {
|
|
54
|
-
if (a2.length > 1) throw new Error("Pattern error: Using `...P.array(...)` several times in a single pattern is not allowed.");
|
|
55
|
-
if (s2.length < t2.length + r2.length) return false;
|
|
56
|
-
const e2 = s2.slice(0, t2.length), n3 = 0 === r2.length ? [] : s2.slice(-r2.length), i2 = s2.slice(t2.length, 0 === r2.length ? Infinity : -r2.length);
|
|
57
|
-
return t2.every((t3, n4) => o(t3, e2[n4], c2)) && r2.every((t3, e3) => o(t3, n3[e3], c2)) && (0 === a2.length || o(a2[0], i2, c2));
|
|
58
|
-
}
|
|
59
|
-
return n2.length === s2.length && n2.every((t3, e2) => o(t3, s2[e2], c2));
|
|
60
|
-
}
|
|
61
|
-
return Object.keys(n2).every((e2) => {
|
|
62
|
-
const r2 = n2[e2];
|
|
63
|
-
return (e2 in s2 || i(a2 = r2) && "optional" === a2[t]().matcherType) && o(r2, s2[e2], c2);
|
|
64
|
-
var a2;
|
|
65
|
-
});
|
|
66
|
-
}
|
|
67
|
-
return Object.is(s2, n2);
|
|
68
|
-
};
|
|
69
|
-
var s = (e2) => {
|
|
70
|
-
var n2, o2, a2;
|
|
71
|
-
return r(e2) ? i(e2) ? null != (n2 = null == (o2 = (a2 = e2[t]()).getSelectionKeys) ? void 0 : o2.call(a2)) ? n2 : [] : Array.isArray(e2) ? c(e2, s) : c(Object.values(e2), s) : [];
|
|
72
|
-
};
|
|
73
|
-
var c = (t2, e2) => t2.reduce((t3, n2) => t3.concat(e2(n2)), []);
|
|
74
|
-
function a(...t2) {
|
|
75
|
-
if (1 === t2.length) {
|
|
76
|
-
const [e2] = t2;
|
|
77
|
-
return (t3) => o(e2, t3, () => {
|
|
78
|
-
});
|
|
79
|
-
}
|
|
80
|
-
if (2 === t2.length) {
|
|
81
|
-
const [e2, n2] = t2;
|
|
82
|
-
return o(e2, n2, () => {
|
|
83
|
-
});
|
|
84
|
-
}
|
|
85
|
-
throw new Error(`isMatching wasn't given the right number of arguments: expected 1 or 2, received ${t2.length}.`);
|
|
86
|
-
}
|
|
87
|
-
function u(t2) {
|
|
88
|
-
return Object.assign(t2, { optional: () => l(t2), and: (e2) => m(t2, e2), or: (e2) => d(t2, e2), select: (e2) => void 0 === e2 ? p(t2) : p(e2, t2) });
|
|
89
|
-
}
|
|
90
|
-
function l(e2) {
|
|
91
|
-
return u({ [t]: () => ({ match: (t2) => {
|
|
92
|
-
let n2 = {};
|
|
93
|
-
const r2 = (t3, e3) => {
|
|
94
|
-
n2[t3] = e3;
|
|
95
|
-
};
|
|
96
|
-
return void 0 === t2 ? (s(e2).forEach((t3) => r2(t3, void 0)), { matched: true, selections: n2 }) : { matched: o(e2, t2, r2), selections: n2 };
|
|
97
|
-
}, getSelectionKeys: () => s(e2), matcherType: "optional" }) });
|
|
98
|
-
}
|
|
99
|
-
function m(...e2) {
|
|
100
|
-
return u({ [t]: () => ({ match: (t2) => {
|
|
101
|
-
let n2 = {};
|
|
102
|
-
const r2 = (t3, e3) => {
|
|
103
|
-
n2[t3] = e3;
|
|
104
|
-
};
|
|
105
|
-
return { matched: e2.every((e3) => o(e3, t2, r2)), selections: n2 };
|
|
106
|
-
}, getSelectionKeys: () => c(e2, s), matcherType: "and" }) });
|
|
107
|
-
}
|
|
108
|
-
function d(...e2) {
|
|
109
|
-
return u({ [t]: () => ({ match: (t2) => {
|
|
110
|
-
let n2 = {};
|
|
111
|
-
const r2 = (t3, e3) => {
|
|
112
|
-
n2[t3] = e3;
|
|
113
|
-
};
|
|
114
|
-
return c(e2, s).forEach((t3) => r2(t3, void 0)), { matched: e2.some((e3) => o(e3, t2, r2)), selections: n2 };
|
|
115
|
-
}, getSelectionKeys: () => c(e2, s), matcherType: "or" }) });
|
|
116
|
-
}
|
|
117
|
-
function y(e2) {
|
|
118
|
-
return { [t]: () => ({ match: (t2) => ({ matched: Boolean(e2(t2)) }) }) };
|
|
119
|
-
}
|
|
120
|
-
function p(...e2) {
|
|
121
|
-
const r2 = "string" == typeof e2[0] ? e2[0] : void 0, i2 = 2 === e2.length ? e2[1] : "string" == typeof e2[0] ? void 0 : e2[0];
|
|
122
|
-
return u({ [t]: () => ({ match: (t2) => {
|
|
123
|
-
let e3 = { [null != r2 ? r2 : n]: t2 };
|
|
124
|
-
return { matched: void 0 === i2 || o(i2, t2, (t3, n2) => {
|
|
125
|
-
e3[t3] = n2;
|
|
126
|
-
}), selections: e3 };
|
|
127
|
-
}, getSelectionKeys: () => [null != r2 ? r2 : n].concat(void 0 === i2 ? [] : s(i2)) }) });
|
|
128
|
-
}
|
|
129
|
-
function v(t2) {
|
|
130
|
-
return "number" == typeof t2;
|
|
131
|
-
}
|
|
132
|
-
function b(t2) {
|
|
133
|
-
return "string" == typeof t2;
|
|
134
|
-
}
|
|
135
|
-
function w(t2) {
|
|
136
|
-
return "bigint" == typeof t2;
|
|
137
|
-
}
|
|
138
|
-
u(y(function(t2) {
|
|
139
|
-
return true;
|
|
140
|
-
}));
|
|
141
|
-
var j = (t2) => Object.assign(u(t2), { startsWith: (e2) => {
|
|
142
|
-
return j(m(t2, (n2 = e2, y((t3) => b(t3) && t3.startsWith(n2)))));
|
|
143
|
-
var n2;
|
|
144
|
-
}, endsWith: (e2) => {
|
|
145
|
-
return j(m(t2, (n2 = e2, y((t3) => b(t3) && t3.endsWith(n2)))));
|
|
146
|
-
var n2;
|
|
147
|
-
}, minLength: (e2) => j(m(t2, ((t3) => y((e3) => b(e3) && e3.length >= t3))(e2))), length: (e2) => j(m(t2, ((t3) => y((e3) => b(e3) && e3.length === t3))(e2))), maxLength: (e2) => j(m(t2, ((t3) => y((e3) => b(e3) && e3.length <= t3))(e2))), includes: (e2) => {
|
|
148
|
-
return j(m(t2, (n2 = e2, y((t3) => b(t3) && t3.includes(n2)))));
|
|
149
|
-
var n2;
|
|
150
|
-
}, regex: (e2) => {
|
|
151
|
-
return j(m(t2, (n2 = e2, y((t3) => b(t3) && Boolean(t3.match(n2))))));
|
|
152
|
-
var n2;
|
|
153
|
-
} });
|
|
154
|
-
j(y(b));
|
|
155
|
-
var K = (t2) => Object.assign(u(t2), { between: (e2, n2) => K(m(t2, ((t3, e3) => y((n3) => v(n3) && t3 <= n3 && e3 >= n3))(e2, n2))), lt: (e2) => K(m(t2, ((t3) => y((e3) => v(e3) && e3 < t3))(e2))), gt: (e2) => K(m(t2, ((t3) => y((e3) => v(e3) && e3 > t3))(e2))), lte: (e2) => K(m(t2, ((t3) => y((e3) => v(e3) && e3 <= t3))(e2))), gte: (e2) => K(m(t2, ((t3) => y((e3) => v(e3) && e3 >= t3))(e2))), int: () => K(m(t2, y((t3) => v(t3) && Number.isInteger(t3)))), finite: () => K(m(t2, y((t3) => v(t3) && Number.isFinite(t3)))), positive: () => K(m(t2, y((t3) => v(t3) && t3 > 0))), negative: () => K(m(t2, y((t3) => v(t3) && t3 < 0))) });
|
|
156
|
-
K(y(v));
|
|
157
|
-
var A = (t2) => Object.assign(u(t2), { between: (e2, n2) => A(m(t2, ((t3, e3) => y((n3) => w(n3) && t3 <= n3 && e3 >= n3))(e2, n2))), lt: (e2) => A(m(t2, ((t3) => y((e3) => w(e3) && e3 < t3))(e2))), gt: (e2) => A(m(t2, ((t3) => y((e3) => w(e3) && e3 > t3))(e2))), lte: (e2) => A(m(t2, ((t3) => y((e3) => w(e3) && e3 <= t3))(e2))), gte: (e2) => A(m(t2, ((t3) => y((e3) => w(e3) && e3 >= t3))(e2))), positive: () => A(m(t2, y((t3) => w(t3) && t3 > 0))), negative: () => A(m(t2, y((t3) => w(t3) && t3 < 0))) });
|
|
158
|
-
A(y(w));
|
|
159
|
-
u(y(function(t2) {
|
|
160
|
-
return "boolean" == typeof t2;
|
|
161
|
-
}));
|
|
162
|
-
u(y(function(t2) {
|
|
163
|
-
return "symbol" == typeof t2;
|
|
164
|
-
}));
|
|
165
|
-
u(y(function(t2) {
|
|
166
|
-
return null == t2;
|
|
167
|
-
}));
|
|
168
|
-
u(y(function(t2) {
|
|
169
|
-
return null != t2;
|
|
170
|
-
}));
|
|
171
|
-
var W = { matched: false, value: void 0 };
|
|
172
|
-
function $(t2) {
|
|
173
|
-
return new z(t2, W);
|
|
174
|
-
}
|
|
175
|
-
var z = class _z {
|
|
176
|
-
constructor(t2, e2) {
|
|
177
|
-
this.input = void 0, this.state = void 0, this.input = t2, this.state = e2;
|
|
178
|
-
}
|
|
179
|
-
with(...t2) {
|
|
180
|
-
if (this.state.matched) return this;
|
|
181
|
-
const e2 = t2[t2.length - 1], r2 = [t2[0]];
|
|
182
|
-
let i2;
|
|
183
|
-
3 === t2.length && "function" == typeof t2[1] ? i2 = t2[1] : t2.length > 2 && r2.push(...t2.slice(1, t2.length - 1));
|
|
184
|
-
let s2 = false, c2 = {};
|
|
185
|
-
const a2 = (t3, e3) => {
|
|
186
|
-
s2 = true, c2[t3] = e3;
|
|
187
|
-
}, u2 = !r2.some((t3) => o(t3, this.input, a2)) || i2 && !Boolean(i2(this.input)) ? W : { matched: true, value: e2(s2 ? n in c2 ? c2[n] : c2 : this.input, this.input) };
|
|
188
|
-
return new _z(this.input, u2);
|
|
189
|
-
}
|
|
190
|
-
when(t2, e2) {
|
|
191
|
-
if (this.state.matched) return this;
|
|
192
|
-
const n2 = Boolean(t2(this.input));
|
|
193
|
-
return new _z(this.input, n2 ? { matched: true, value: e2(this.input, this.input) } : W);
|
|
194
|
-
}
|
|
195
|
-
otherwise(t2) {
|
|
196
|
-
return this.state.matched ? this.state.value : t2(this.input);
|
|
197
|
-
}
|
|
198
|
-
exhaustive() {
|
|
199
|
-
if (this.state.matched) return this.state.value;
|
|
200
|
-
let t2;
|
|
201
|
-
try {
|
|
202
|
-
t2 = JSON.stringify(this.input);
|
|
203
|
-
} catch (e2) {
|
|
204
|
-
t2 = this.input;
|
|
205
|
-
}
|
|
206
|
-
throw new Error(`Pattern matching error: no pattern matches value ${t2}`);
|
|
207
|
-
}
|
|
208
|
-
run() {
|
|
209
|
-
return this.exhaustive();
|
|
210
|
-
}
|
|
211
|
-
returnType() {
|
|
212
|
-
return this;
|
|
213
|
-
}
|
|
214
|
-
};
|
|
215
|
-
|
|
216
|
-
// src/utils/is-set-function-call.ts
|
|
217
34
|
function isSetFunctionCall(context, settings) {
|
|
218
35
|
const isIdFromUseStateCall = isFromUseStateCall(context, settings);
|
|
219
36
|
return (node) => {
|
|
220
37
|
switch (node.callee.type) {
|
|
221
|
-
case
|
|
38
|
+
case types.AST_NODE_TYPES.Identifier: {
|
|
222
39
|
return isIdFromUseStateCall(node.callee);
|
|
223
40
|
}
|
|
224
|
-
case
|
|
41
|
+
case types.AST_NODE_TYPES.MemberExpression: {
|
|
225
42
|
if (!("name" in node.callee.object)) return false;
|
|
226
43
|
const initialScope = context.sourceCode.getScope(node);
|
|
227
44
|
const property = astUtils.getStaticValue(node.callee.property, initialScope);
|
|
228
45
|
if (property?.value === 1) return isIdFromUseStateCall(node.callee.object);
|
|
229
46
|
return false;
|
|
230
47
|
}
|
|
231
|
-
case
|
|
48
|
+
case types.AST_NODE_TYPES.CallExpression: {
|
|
232
49
|
const callee = node.callee.callee;
|
|
233
|
-
if (callee.type !==
|
|
50
|
+
if (callee.type !== types.AST_NODE_TYPES.MemberExpression) return false;
|
|
234
51
|
if (!("name" in callee.object)) return false;
|
|
235
|
-
const isAt =
|
|
236
|
-
type:
|
|
52
|
+
const isAt = tsPattern.isMatching({
|
|
53
|
+
type: types.AST_NODE_TYPES.MemberExpression,
|
|
237
54
|
property: {
|
|
238
|
-
type:
|
|
55
|
+
type: types.AST_NODE_TYPES.Identifier,
|
|
239
56
|
name: "at"
|
|
240
57
|
}
|
|
241
58
|
}, callee);
|
|
@@ -253,17 +70,17 @@ function isSetFunctionCall(context, settings) {
|
|
|
253
70
|
};
|
|
254
71
|
}
|
|
255
72
|
function isThenCall(node) {
|
|
256
|
-
return node.callee.type ===
|
|
73
|
+
return node.callee.type === types.AST_NODE_TYPES.MemberExpression && node.callee.property.type === types.AST_NODE_TYPES.Identifier && node.callee.property.name === "then";
|
|
257
74
|
}
|
|
258
75
|
function isVariableDeclaratorFromHookCall(node) {
|
|
259
|
-
if (node.type !==
|
|
260
|
-
if (node.id.type !==
|
|
261
|
-
if (node.init?.type !==
|
|
76
|
+
if (node.type !== types.AST_NODE_TYPES.VariableDeclarator) return false;
|
|
77
|
+
if (node.id.type !== types.AST_NODE_TYPES.Identifier) return false;
|
|
78
|
+
if (node.init?.type !== types.AST_NODE_TYPES.CallExpression) return false;
|
|
262
79
|
switch (node.init.callee.type) {
|
|
263
|
-
case
|
|
80
|
+
case types.AST_NODE_TYPES.Identifier:
|
|
264
81
|
return core.isReactHookName(node.init.callee.name);
|
|
265
|
-
case
|
|
266
|
-
return node.init.callee.property.type ===
|
|
82
|
+
case types.AST_NODE_TYPES.MemberExpression:
|
|
83
|
+
return node.init.callee.property.type === types.AST_NODE_TYPES.Identifier && core.isReactHookName(node.init.callee.property.name);
|
|
267
84
|
default:
|
|
268
85
|
return false;
|
|
269
86
|
}
|
|
@@ -338,14 +155,14 @@ var ensure_use_callback_has_non_empty_deps_default = createRule({
|
|
|
338
155
|
return;
|
|
339
156
|
}
|
|
340
157
|
const hasEmptyDeps = tools.F.pipe(
|
|
341
|
-
|
|
158
|
+
tsPattern.match(deps).with({ type: types.AST_NODE_TYPES.ArrayExpression }, tools.O.some).with({ type: types.AST_NODE_TYPES.Identifier }, (n) => {
|
|
342
159
|
return tools.F.pipe(
|
|
343
|
-
_var.findVariable(
|
|
160
|
+
_var.findVariable(n.name, initialScope),
|
|
344
161
|
tools.O.flatMap(_var.getVariableNode(0)),
|
|
345
|
-
tools.O.filter(ast.is(
|
|
162
|
+
tools.O.filter(ast.is(types.AST_NODE_TYPES.ArrayExpression))
|
|
346
163
|
);
|
|
347
164
|
}).otherwise(tools.O.none),
|
|
348
|
-
tools.O.exists((
|
|
165
|
+
tools.O.exists((x) => x.elements.length === 0)
|
|
349
166
|
);
|
|
350
167
|
if (!hasEmptyDeps) return;
|
|
351
168
|
if (!cb) {
|
|
@@ -356,21 +173,21 @@ var ensure_use_callback_has_non_empty_deps_default = createRule({
|
|
|
356
173
|
return;
|
|
357
174
|
}
|
|
358
175
|
const isReferencedToComponentScope = tools.F.pipe(
|
|
359
|
-
|
|
360
|
-
if (
|
|
361
|
-
return tools.O.some(
|
|
176
|
+
tsPattern.match(cb).with({ type: types.AST_NODE_TYPES.ArrowFunctionExpression }, (n) => {
|
|
177
|
+
if (n.body.type === types.AST_NODE_TYPES.ArrowFunctionExpression) {
|
|
178
|
+
return tools.O.some(n.body);
|
|
362
179
|
}
|
|
363
|
-
return tools.O.some(
|
|
364
|
-
}).with({ type:
|
|
180
|
+
return tools.O.some(n);
|
|
181
|
+
}).with({ type: types.AST_NODE_TYPES.FunctionExpression }, tools.O.some).with({ type: types.AST_NODE_TYPES.Identifier }, (n) => {
|
|
365
182
|
return tools.F.pipe(
|
|
366
|
-
_var.findVariable(
|
|
183
|
+
_var.findVariable(n.name, initialScope),
|
|
367
184
|
tools.O.flatMap(_var.getVariableNode(0)),
|
|
368
185
|
tools.O.filter(ast.isFunction)
|
|
369
186
|
);
|
|
370
187
|
}).otherwise(tools.O.none),
|
|
371
|
-
tools.O.map((
|
|
372
|
-
tools.O.map((
|
|
373
|
-
tools.O.exists((refs) => refs.some((
|
|
188
|
+
tools.O.map((n) => context.sourceCode.getScope(n)),
|
|
189
|
+
tools.O.map((s) => [...s.childScopes, s].flatMap((x) => x.references)),
|
|
190
|
+
tools.O.exists((refs) => refs.some((x) => x.resolved?.scope.block === component))
|
|
374
191
|
);
|
|
375
192
|
if (isReferencedToComponentScope) return;
|
|
376
193
|
context.report({
|
|
@@ -416,14 +233,14 @@ var ensure_use_memo_has_non_empty_deps_default = createRule({
|
|
|
416
233
|
return;
|
|
417
234
|
}
|
|
418
235
|
const hasEmptyDeps = tools.F.pipe(
|
|
419
|
-
|
|
236
|
+
tsPattern.match(deps).with({ type: types.AST_NODE_TYPES.ArrayExpression }, tools.O.some).with({ type: types.AST_NODE_TYPES.Identifier }, (n) => {
|
|
420
237
|
return tools.F.pipe(
|
|
421
|
-
_var.findVariable(
|
|
238
|
+
_var.findVariable(n.name, initialScope),
|
|
422
239
|
tools.O.flatMap(_var.getVariableNode(0)),
|
|
423
|
-
tools.O.filter(ast.is(
|
|
240
|
+
tools.O.filter(ast.is(types.AST_NODE_TYPES.ArrayExpression))
|
|
424
241
|
);
|
|
425
242
|
}).otherwise(tools.O.none),
|
|
426
|
-
tools.O.exists((
|
|
243
|
+
tools.O.exists((x) => x.elements.length === 0)
|
|
427
244
|
);
|
|
428
245
|
if (!hasEmptyDeps) return;
|
|
429
246
|
if (!cb) {
|
|
@@ -434,21 +251,21 @@ var ensure_use_memo_has_non_empty_deps_default = createRule({
|
|
|
434
251
|
return;
|
|
435
252
|
}
|
|
436
253
|
const isReferencedToComponentScope = tools.F.pipe(
|
|
437
|
-
|
|
438
|
-
if (
|
|
439
|
-
return tools.O.some(
|
|
254
|
+
tsPattern.match(cb).with({ type: types.AST_NODE_TYPES.ArrowFunctionExpression }, (n) => {
|
|
255
|
+
if (n.body.type === types.AST_NODE_TYPES.ArrowFunctionExpression) {
|
|
256
|
+
return tools.O.some(n.body);
|
|
440
257
|
}
|
|
441
|
-
return tools.O.some(
|
|
442
|
-
}).with({ type:
|
|
258
|
+
return tools.O.some(n);
|
|
259
|
+
}).with({ type: types.AST_NODE_TYPES.FunctionExpression }, tools.O.some).with({ type: types.AST_NODE_TYPES.Identifier }, (n) => {
|
|
443
260
|
return tools.F.pipe(
|
|
444
|
-
_var.findVariable(
|
|
261
|
+
_var.findVariable(n.name, initialScope),
|
|
445
262
|
tools.O.flatMap(_var.getVariableNode(0)),
|
|
446
263
|
tools.O.filter(ast.isFunction)
|
|
447
264
|
);
|
|
448
265
|
}).otherwise(tools.O.none),
|
|
449
|
-
tools.O.map((
|
|
450
|
-
tools.O.map((
|
|
451
|
-
tools.O.exists((refs) => refs.some((
|
|
266
|
+
tools.O.map((n) => context.sourceCode.getScope(n)),
|
|
267
|
+
tools.O.map((s) => [...s.childScopes, s].flatMap((x) => x.references)),
|
|
268
|
+
tools.O.exists((refs) => refs.some((x) => x.resolved?.scope.block === component))
|
|
452
269
|
);
|
|
453
270
|
if (isReferencedToComponentScope) return;
|
|
454
271
|
context.report({
|
|
@@ -497,13 +314,13 @@ var no_direct_set_state_in_use_effect_default = createRule({
|
|
|
497
314
|
tools.MutRef.update(effectFunctionRef, (current) => current === node ? null : current);
|
|
498
315
|
};
|
|
499
316
|
function isEffectFunction(node) {
|
|
500
|
-
return node.parent?.type ===
|
|
317
|
+
return node.parent?.type === types.AST_NODE_TYPES.CallExpression && node.parent.callee !== node && isUseEffectCall(node.parent);
|
|
501
318
|
}
|
|
502
319
|
function getCallKind(node) {
|
|
503
|
-
return
|
|
320
|
+
return tsPattern.match(node).when(isUseStateCall2, () => "useState").when(isUseEffectCall, () => "useEffect").when(isSetStateCall, () => "setState").when(isThenCall, () => "then").otherwise(() => "other");
|
|
504
321
|
}
|
|
505
322
|
function getFunctionKind(node) {
|
|
506
|
-
return
|
|
323
|
+
return tsPattern.match(node).when(isEffectFunction, () => "effect").when(ast.isFunctionOfImmediatelyInvoked, () => "immediate").otherwise(() => "other");
|
|
507
324
|
}
|
|
508
325
|
return {
|
|
509
326
|
":function"(node) {
|
|
@@ -512,7 +329,7 @@ var no_direct_set_state_in_use_effect_default = createRule({
|
|
|
512
329
|
if (functionKind === "effect") onEffectFunctionEnter(node);
|
|
513
330
|
},
|
|
514
331
|
":function:exit"(node) {
|
|
515
|
-
const [
|
|
332
|
+
const [_, functionKind] = functionStack.at(-1) ?? [];
|
|
516
333
|
functionStack.pop();
|
|
517
334
|
if (functionKind === "effect") onEffectFunctionExit(node);
|
|
518
335
|
},
|
|
@@ -520,7 +337,7 @@ var no_direct_set_state_in_use_effect_default = createRule({
|
|
|
520
337
|
const effectFn = tools.MutRef.get(effectFunctionRef);
|
|
521
338
|
const [parentFn, parentFnKind] = functionStack.at(-1) ?? [];
|
|
522
339
|
if (parentFn?.async) return;
|
|
523
|
-
|
|
340
|
+
tsPattern.match(getCallKind(node)).with("setState", () => {
|
|
524
341
|
if (!parentFn) return;
|
|
525
342
|
if (parentFn !== effectFn && parentFnKind !== "immediate") {
|
|
526
343
|
const maybeVd = ast.traverseUpGuard(node, isVariableDeclaratorFromHookCall);
|
|
@@ -550,10 +367,10 @@ var no_direct_set_state_in_use_effect_default = createRule({
|
|
|
550
367
|
}).otherwise(tools.F.constVoid);
|
|
551
368
|
},
|
|
552
369
|
Identifier(node) {
|
|
553
|
-
if (node.parent.type ===
|
|
370
|
+
if (node.parent.type === types.AST_NODE_TYPES.CallExpression && node.parent.callee === node) return;
|
|
554
371
|
if (!isIdFromUseStateCall(node)) return;
|
|
555
372
|
switch (node.parent.type) {
|
|
556
|
-
case
|
|
373
|
+
case types.AST_NODE_TYPES.CallExpression: {
|
|
557
374
|
const [firstArg] = node.parent.arguments;
|
|
558
375
|
if (node !== firstArg) break;
|
|
559
376
|
if (isUseCallbackCall2(node.parent)) {
|
|
@@ -569,9 +386,9 @@ var no_direct_set_state_in_use_effect_default = createRule({
|
|
|
569
386
|
}
|
|
570
387
|
break;
|
|
571
388
|
}
|
|
572
|
-
case
|
|
389
|
+
case types.AST_NODE_TYPES.ArrowFunctionExpression: {
|
|
573
390
|
const parent = node.parent.parent;
|
|
574
|
-
if (parent.type !==
|
|
391
|
+
if (parent.type !== types.AST_NODE_TYPES.CallExpression) break;
|
|
575
392
|
if (!isUseMemoCall2(parent)) break;
|
|
576
393
|
const maybeVd = ast.traverseUpGuard(parent, isVariableDeclaratorFromHookCall);
|
|
577
394
|
if (tools.O.isNone(maybeVd)) break;
|
|
@@ -585,16 +402,16 @@ var no_direct_set_state_in_use_effect_default = createRule({
|
|
|
585
402
|
const getSetStateCalls = (id, initialScope) => {
|
|
586
403
|
const node = tools.O.flatMap(_var.findVariable(id, initialScope), _var.getVariableNode(0)).pipe(tools.O.getOrNull);
|
|
587
404
|
switch (node?.type) {
|
|
588
|
-
case
|
|
589
|
-
case
|
|
590
|
-
case
|
|
405
|
+
case types.AST_NODE_TYPES.FunctionDeclaration:
|
|
406
|
+
case types.AST_NODE_TYPES.FunctionExpression:
|
|
407
|
+
case types.AST_NODE_TYPES.ArrowFunctionExpression:
|
|
591
408
|
return indirectSetStateCalls.get(node) ?? [];
|
|
592
|
-
case
|
|
409
|
+
case types.AST_NODE_TYPES.CallExpression:
|
|
593
410
|
return indirectSetStateCallsInHooks.get(node) ?? indirectSetStateCallsAsArgs.get(node) ?? [];
|
|
594
411
|
}
|
|
595
412
|
return [];
|
|
596
413
|
};
|
|
597
|
-
for (const [
|
|
414
|
+
for (const [_, calls] of indirectSetStateCallsAsEFs) {
|
|
598
415
|
for (const call of calls) {
|
|
599
416
|
context.report({
|
|
600
417
|
data: { name: call.name },
|
|
@@ -671,13 +488,13 @@ var no_direct_set_state_in_use_layout_effect_default = createRule({
|
|
|
671
488
|
tools.MutRef.update(effectFunctionRef, (current) => current === node ? null : current);
|
|
672
489
|
};
|
|
673
490
|
function isEffectFunction(node) {
|
|
674
|
-
return node.parent?.type ===
|
|
491
|
+
return node.parent?.type === types.AST_NODE_TYPES.CallExpression && node.parent.callee !== node && isUseEffectCall(node.parent);
|
|
675
492
|
}
|
|
676
493
|
function getCallKind(node) {
|
|
677
|
-
return
|
|
494
|
+
return tsPattern.match(node).when(isUseStateCall2, () => "useState").when(isUseEffectCall, () => "useLayoutEffect").when(isSetStateCall, () => "setState").when(isThenCall, () => "then").otherwise(() => "other");
|
|
678
495
|
}
|
|
679
496
|
function getFunctionKind(node) {
|
|
680
|
-
return
|
|
497
|
+
return tsPattern.match(node).when(isEffectFunction, () => "effect").when(ast.isFunctionOfImmediatelyInvoked, () => "immediate").otherwise(() => "other");
|
|
681
498
|
}
|
|
682
499
|
return {
|
|
683
500
|
":function"(node) {
|
|
@@ -686,7 +503,7 @@ var no_direct_set_state_in_use_layout_effect_default = createRule({
|
|
|
686
503
|
if (functionKind === "effect") onEffectFunctionEnter(node);
|
|
687
504
|
},
|
|
688
505
|
":function:exit"(node) {
|
|
689
|
-
const [
|
|
506
|
+
const [_, functionKind] = functionStack.at(-1) ?? [];
|
|
690
507
|
functionStack.pop();
|
|
691
508
|
if (functionKind === "effect") onEffectFunctionExit(node);
|
|
692
509
|
},
|
|
@@ -694,7 +511,7 @@ var no_direct_set_state_in_use_layout_effect_default = createRule({
|
|
|
694
511
|
const effectFn = tools.MutRef.get(effectFunctionRef);
|
|
695
512
|
const [parentFn, parentFnKind] = functionStack.at(-1) ?? [];
|
|
696
513
|
if (parentFn?.async) return;
|
|
697
|
-
|
|
514
|
+
tsPattern.match(getCallKind(node)).with("setState", () => {
|
|
698
515
|
if (!parentFn) return;
|
|
699
516
|
if (parentFn !== effectFn && parentFnKind !== "immediate") {
|
|
700
517
|
const maybeVd = ast.traverseUpGuard(node, isVariableDeclaratorFromHookCall);
|
|
@@ -724,10 +541,10 @@ var no_direct_set_state_in_use_layout_effect_default = createRule({
|
|
|
724
541
|
}).otherwise(tools.F.constVoid);
|
|
725
542
|
},
|
|
726
543
|
Identifier(node) {
|
|
727
|
-
if (node.parent.type ===
|
|
544
|
+
if (node.parent.type === types.AST_NODE_TYPES.CallExpression && node.parent.callee === node) return;
|
|
728
545
|
if (!isIdFromUseStateCall(node)) return;
|
|
729
546
|
switch (node.parent.type) {
|
|
730
|
-
case
|
|
547
|
+
case types.AST_NODE_TYPES.CallExpression: {
|
|
731
548
|
const [firstArg] = node.parent.arguments;
|
|
732
549
|
if (node !== firstArg) break;
|
|
733
550
|
if (isUseCallbackCall2(node.parent)) {
|
|
@@ -743,9 +560,9 @@ var no_direct_set_state_in_use_layout_effect_default = createRule({
|
|
|
743
560
|
}
|
|
744
561
|
break;
|
|
745
562
|
}
|
|
746
|
-
case
|
|
563
|
+
case types.AST_NODE_TYPES.ArrowFunctionExpression: {
|
|
747
564
|
const parent = node.parent.parent;
|
|
748
|
-
if (parent.type !==
|
|
565
|
+
if (parent.type !== types.AST_NODE_TYPES.CallExpression) break;
|
|
749
566
|
if (!isUseMemoCall2(parent)) break;
|
|
750
567
|
const maybeVd = ast.traverseUpGuard(parent, isVariableDeclaratorFromHookCall);
|
|
751
568
|
if (tools.O.isNone(maybeVd)) break;
|
|
@@ -759,16 +576,16 @@ var no_direct_set_state_in_use_layout_effect_default = createRule({
|
|
|
759
576
|
const getSetStateCalls = (id, initialScope) => {
|
|
760
577
|
const node = tools.O.flatMap(_var.findVariable(id, initialScope), _var.getVariableNode(0)).pipe(tools.O.getOrNull);
|
|
761
578
|
switch (node?.type) {
|
|
762
|
-
case
|
|
763
|
-
case
|
|
764
|
-
case
|
|
579
|
+
case types.AST_NODE_TYPES.FunctionDeclaration:
|
|
580
|
+
case types.AST_NODE_TYPES.FunctionExpression:
|
|
581
|
+
case types.AST_NODE_TYPES.ArrowFunctionExpression:
|
|
765
582
|
return indirectSetStateCalls.get(node) ?? [];
|
|
766
|
-
case
|
|
583
|
+
case types.AST_NODE_TYPES.CallExpression:
|
|
767
584
|
return indirectSetStateCallsInHooks.get(node) ?? indirectSetStateCallsAsArgs.get(node) ?? [];
|
|
768
585
|
}
|
|
769
586
|
return [];
|
|
770
587
|
};
|
|
771
|
-
for (const [
|
|
588
|
+
for (const [_, calls] of indirectSetStateCallsAsEFs) {
|
|
772
589
|
for (const call of calls) {
|
|
773
590
|
context.report({
|
|
774
591
|
data: { name: call.name },
|
|
@@ -827,8 +644,8 @@ var prefer_use_state_lazy_initialization_default = createRule({
|
|
|
827
644
|
const [useStateInput] = node.arguments;
|
|
828
645
|
if (!useStateInput) return;
|
|
829
646
|
const nestedCallExpressions = ast.getNestedCallExpressions(useStateInput);
|
|
830
|
-
const hasFunctionCall = nestedCallExpressions.some((
|
|
831
|
-
return "name" in
|
|
647
|
+
const hasFunctionCall = nestedCallExpressions.some((n) => {
|
|
648
|
+
return "name" in n.callee && !ALLOW_LIST.includes(n.callee.name);
|
|
832
649
|
});
|
|
833
650
|
if (!hasFunctionCall) return;
|
|
834
651
|
context.report({
|
package/dist/index.mjs
CHANGED
|
@@ -1,20 +1,22 @@
|
|
|
1
1
|
import { useHookCollector, isReactHookCall, isUseCallbackCall, isReactHookCallWithNameLoose, isUseMemoCall, isReactHookCallWithNameAlias, isUseStateCall, isReactHookName } from '@eslint-react/core';
|
|
2
2
|
import { createRuleForPlugin, decodeSettings } from '@eslint-react/shared';
|
|
3
|
-
import { isFunction,
|
|
3
|
+
import { isFunction, is, traverseUpGuard, getNestedIdentifiers, getNestedCallExpressions, isFunctionOfImmediatelyInvoked } from '@eslint-react/ast';
|
|
4
4
|
import { F, O, MutRef } from '@eslint-react/tools';
|
|
5
5
|
import { findVariable, getVariableNode } from '@eslint-react/var';
|
|
6
|
+
import { AST_NODE_TYPES } from '@typescript-eslint/types';
|
|
6
7
|
import { getStaticValue } from '@typescript-eslint/utils/ast-utils';
|
|
8
|
+
import { match, isMatching } from 'ts-pattern';
|
|
7
9
|
|
|
8
10
|
// package.json
|
|
9
11
|
var name = "eslint-plugin-react-hooks-extra";
|
|
10
|
-
var version = "1.9.
|
|
12
|
+
var version = "1.9.2-beta.4";
|
|
11
13
|
var createRule = createRuleForPlugin("hooks-extra");
|
|
12
14
|
function isFromHookCall(name2, context, settings, predicate = F.constTrue) {
|
|
13
15
|
const hookAlias = settings.additionalHooks?.[name2] ?? [];
|
|
14
16
|
return (topLevelId) => F.pipe(
|
|
15
17
|
findVariable(topLevelId, context.sourceCode.getScope(topLevelId)),
|
|
16
18
|
O.flatMap(getVariableNode(0)),
|
|
17
|
-
O.filter(is(
|
|
19
|
+
O.filter(is(AST_NODE_TYPES.CallExpression)),
|
|
18
20
|
O.filter(isReactHookCallWithNameAlias(name2, context, hookAlias)),
|
|
19
21
|
O.exists((call) => predicate(topLevelId, call))
|
|
20
22
|
);
|
|
@@ -22,218 +24,33 @@ function isFromHookCall(name2, context, settings, predicate = F.constTrue) {
|
|
|
22
24
|
function isFromUseStateCall(context, settings) {
|
|
23
25
|
const predicate = (topLevelId, call) => {
|
|
24
26
|
const { parent } = call;
|
|
25
|
-
if (!("id" in parent && parent.id?.type ===
|
|
26
|
-
return parent.id.elements.findIndex((
|
|
27
|
+
if (!("id" in parent && parent.id?.type === AST_NODE_TYPES.ArrayPattern)) return true;
|
|
28
|
+
return parent.id.elements.findIndex((e) => e?.type === AST_NODE_TYPES.Identifier && e.name === topLevelId.name) === 1;
|
|
27
29
|
};
|
|
28
30
|
return isFromHookCall("useState", context, settings, predicate);
|
|
29
31
|
}
|
|
30
|
-
|
|
31
|
-
// ../../../node_modules/.pnpm/ts-pattern@5.2.0/node_modules/ts-pattern/dist/index.js
|
|
32
|
-
var t = Symbol.for("@ts-pattern/matcher");
|
|
33
|
-
var e = Symbol.for("@ts-pattern/isVariadic");
|
|
34
|
-
var n = "@ts-pattern/anonymous-select-key";
|
|
35
|
-
var r = (t2) => Boolean(t2 && "object" == typeof t2);
|
|
36
|
-
var i = (e2) => e2 && !!e2[t];
|
|
37
|
-
var o = (n2, s2, c2) => {
|
|
38
|
-
if (i(n2)) {
|
|
39
|
-
const e2 = n2[t](), { matched: r2, selections: i2 } = e2.match(s2);
|
|
40
|
-
return r2 && i2 && Object.keys(i2).forEach((t2) => c2(t2, i2[t2])), r2;
|
|
41
|
-
}
|
|
42
|
-
if (r(n2)) {
|
|
43
|
-
if (!r(s2)) return false;
|
|
44
|
-
if (Array.isArray(n2)) {
|
|
45
|
-
if (!Array.isArray(s2)) return false;
|
|
46
|
-
let t2 = [], r2 = [], a2 = [];
|
|
47
|
-
for (const o2 of n2.keys()) {
|
|
48
|
-
const s3 = n2[o2];
|
|
49
|
-
i(s3) && s3[e] ? a2.push(s3) : a2.length ? r2.push(s3) : t2.push(s3);
|
|
50
|
-
}
|
|
51
|
-
if (a2.length) {
|
|
52
|
-
if (a2.length > 1) throw new Error("Pattern error: Using `...P.array(...)` several times in a single pattern is not allowed.");
|
|
53
|
-
if (s2.length < t2.length + r2.length) return false;
|
|
54
|
-
const e2 = s2.slice(0, t2.length), n3 = 0 === r2.length ? [] : s2.slice(-r2.length), i2 = s2.slice(t2.length, 0 === r2.length ? Infinity : -r2.length);
|
|
55
|
-
return t2.every((t3, n4) => o(t3, e2[n4], c2)) && r2.every((t3, e3) => o(t3, n3[e3], c2)) && (0 === a2.length || o(a2[0], i2, c2));
|
|
56
|
-
}
|
|
57
|
-
return n2.length === s2.length && n2.every((t3, e2) => o(t3, s2[e2], c2));
|
|
58
|
-
}
|
|
59
|
-
return Object.keys(n2).every((e2) => {
|
|
60
|
-
const r2 = n2[e2];
|
|
61
|
-
return (e2 in s2 || i(a2 = r2) && "optional" === a2[t]().matcherType) && o(r2, s2[e2], c2);
|
|
62
|
-
var a2;
|
|
63
|
-
});
|
|
64
|
-
}
|
|
65
|
-
return Object.is(s2, n2);
|
|
66
|
-
};
|
|
67
|
-
var s = (e2) => {
|
|
68
|
-
var n2, o2, a2;
|
|
69
|
-
return r(e2) ? i(e2) ? null != (n2 = null == (o2 = (a2 = e2[t]()).getSelectionKeys) ? void 0 : o2.call(a2)) ? n2 : [] : Array.isArray(e2) ? c(e2, s) : c(Object.values(e2), s) : [];
|
|
70
|
-
};
|
|
71
|
-
var c = (t2, e2) => t2.reduce((t3, n2) => t3.concat(e2(n2)), []);
|
|
72
|
-
function a(...t2) {
|
|
73
|
-
if (1 === t2.length) {
|
|
74
|
-
const [e2] = t2;
|
|
75
|
-
return (t3) => o(e2, t3, () => {
|
|
76
|
-
});
|
|
77
|
-
}
|
|
78
|
-
if (2 === t2.length) {
|
|
79
|
-
const [e2, n2] = t2;
|
|
80
|
-
return o(e2, n2, () => {
|
|
81
|
-
});
|
|
82
|
-
}
|
|
83
|
-
throw new Error(`isMatching wasn't given the right number of arguments: expected 1 or 2, received ${t2.length}.`);
|
|
84
|
-
}
|
|
85
|
-
function u(t2) {
|
|
86
|
-
return Object.assign(t2, { optional: () => l(t2), and: (e2) => m(t2, e2), or: (e2) => d(t2, e2), select: (e2) => void 0 === e2 ? p(t2) : p(e2, t2) });
|
|
87
|
-
}
|
|
88
|
-
function l(e2) {
|
|
89
|
-
return u({ [t]: () => ({ match: (t2) => {
|
|
90
|
-
let n2 = {};
|
|
91
|
-
const r2 = (t3, e3) => {
|
|
92
|
-
n2[t3] = e3;
|
|
93
|
-
};
|
|
94
|
-
return void 0 === t2 ? (s(e2).forEach((t3) => r2(t3, void 0)), { matched: true, selections: n2 }) : { matched: o(e2, t2, r2), selections: n2 };
|
|
95
|
-
}, getSelectionKeys: () => s(e2), matcherType: "optional" }) });
|
|
96
|
-
}
|
|
97
|
-
function m(...e2) {
|
|
98
|
-
return u({ [t]: () => ({ match: (t2) => {
|
|
99
|
-
let n2 = {};
|
|
100
|
-
const r2 = (t3, e3) => {
|
|
101
|
-
n2[t3] = e3;
|
|
102
|
-
};
|
|
103
|
-
return { matched: e2.every((e3) => o(e3, t2, r2)), selections: n2 };
|
|
104
|
-
}, getSelectionKeys: () => c(e2, s), matcherType: "and" }) });
|
|
105
|
-
}
|
|
106
|
-
function d(...e2) {
|
|
107
|
-
return u({ [t]: () => ({ match: (t2) => {
|
|
108
|
-
let n2 = {};
|
|
109
|
-
const r2 = (t3, e3) => {
|
|
110
|
-
n2[t3] = e3;
|
|
111
|
-
};
|
|
112
|
-
return c(e2, s).forEach((t3) => r2(t3, void 0)), { matched: e2.some((e3) => o(e3, t2, r2)), selections: n2 };
|
|
113
|
-
}, getSelectionKeys: () => c(e2, s), matcherType: "or" }) });
|
|
114
|
-
}
|
|
115
|
-
function y(e2) {
|
|
116
|
-
return { [t]: () => ({ match: (t2) => ({ matched: Boolean(e2(t2)) }) }) };
|
|
117
|
-
}
|
|
118
|
-
function p(...e2) {
|
|
119
|
-
const r2 = "string" == typeof e2[0] ? e2[0] : void 0, i2 = 2 === e2.length ? e2[1] : "string" == typeof e2[0] ? void 0 : e2[0];
|
|
120
|
-
return u({ [t]: () => ({ match: (t2) => {
|
|
121
|
-
let e3 = { [null != r2 ? r2 : n]: t2 };
|
|
122
|
-
return { matched: void 0 === i2 || o(i2, t2, (t3, n2) => {
|
|
123
|
-
e3[t3] = n2;
|
|
124
|
-
}), selections: e3 };
|
|
125
|
-
}, getSelectionKeys: () => [null != r2 ? r2 : n].concat(void 0 === i2 ? [] : s(i2)) }) });
|
|
126
|
-
}
|
|
127
|
-
function v(t2) {
|
|
128
|
-
return "number" == typeof t2;
|
|
129
|
-
}
|
|
130
|
-
function b(t2) {
|
|
131
|
-
return "string" == typeof t2;
|
|
132
|
-
}
|
|
133
|
-
function w(t2) {
|
|
134
|
-
return "bigint" == typeof t2;
|
|
135
|
-
}
|
|
136
|
-
u(y(function(t2) {
|
|
137
|
-
return true;
|
|
138
|
-
}));
|
|
139
|
-
var j = (t2) => Object.assign(u(t2), { startsWith: (e2) => {
|
|
140
|
-
return j(m(t2, (n2 = e2, y((t3) => b(t3) && t3.startsWith(n2)))));
|
|
141
|
-
var n2;
|
|
142
|
-
}, endsWith: (e2) => {
|
|
143
|
-
return j(m(t2, (n2 = e2, y((t3) => b(t3) && t3.endsWith(n2)))));
|
|
144
|
-
var n2;
|
|
145
|
-
}, minLength: (e2) => j(m(t2, ((t3) => y((e3) => b(e3) && e3.length >= t3))(e2))), length: (e2) => j(m(t2, ((t3) => y((e3) => b(e3) && e3.length === t3))(e2))), maxLength: (e2) => j(m(t2, ((t3) => y((e3) => b(e3) && e3.length <= t3))(e2))), includes: (e2) => {
|
|
146
|
-
return j(m(t2, (n2 = e2, y((t3) => b(t3) && t3.includes(n2)))));
|
|
147
|
-
var n2;
|
|
148
|
-
}, regex: (e2) => {
|
|
149
|
-
return j(m(t2, (n2 = e2, y((t3) => b(t3) && Boolean(t3.match(n2))))));
|
|
150
|
-
var n2;
|
|
151
|
-
} });
|
|
152
|
-
j(y(b));
|
|
153
|
-
var K = (t2) => Object.assign(u(t2), { between: (e2, n2) => K(m(t2, ((t3, e3) => y((n3) => v(n3) && t3 <= n3 && e3 >= n3))(e2, n2))), lt: (e2) => K(m(t2, ((t3) => y((e3) => v(e3) && e3 < t3))(e2))), gt: (e2) => K(m(t2, ((t3) => y((e3) => v(e3) && e3 > t3))(e2))), lte: (e2) => K(m(t2, ((t3) => y((e3) => v(e3) && e3 <= t3))(e2))), gte: (e2) => K(m(t2, ((t3) => y((e3) => v(e3) && e3 >= t3))(e2))), int: () => K(m(t2, y((t3) => v(t3) && Number.isInteger(t3)))), finite: () => K(m(t2, y((t3) => v(t3) && Number.isFinite(t3)))), positive: () => K(m(t2, y((t3) => v(t3) && t3 > 0))), negative: () => K(m(t2, y((t3) => v(t3) && t3 < 0))) });
|
|
154
|
-
K(y(v));
|
|
155
|
-
var A = (t2) => Object.assign(u(t2), { between: (e2, n2) => A(m(t2, ((t3, e3) => y((n3) => w(n3) && t3 <= n3 && e3 >= n3))(e2, n2))), lt: (e2) => A(m(t2, ((t3) => y((e3) => w(e3) && e3 < t3))(e2))), gt: (e2) => A(m(t2, ((t3) => y((e3) => w(e3) && e3 > t3))(e2))), lte: (e2) => A(m(t2, ((t3) => y((e3) => w(e3) && e3 <= t3))(e2))), gte: (e2) => A(m(t2, ((t3) => y((e3) => w(e3) && e3 >= t3))(e2))), positive: () => A(m(t2, y((t3) => w(t3) && t3 > 0))), negative: () => A(m(t2, y((t3) => w(t3) && t3 < 0))) });
|
|
156
|
-
A(y(w));
|
|
157
|
-
u(y(function(t2) {
|
|
158
|
-
return "boolean" == typeof t2;
|
|
159
|
-
}));
|
|
160
|
-
u(y(function(t2) {
|
|
161
|
-
return "symbol" == typeof t2;
|
|
162
|
-
}));
|
|
163
|
-
u(y(function(t2) {
|
|
164
|
-
return null == t2;
|
|
165
|
-
}));
|
|
166
|
-
u(y(function(t2) {
|
|
167
|
-
return null != t2;
|
|
168
|
-
}));
|
|
169
|
-
var W = { matched: false, value: void 0 };
|
|
170
|
-
function $(t2) {
|
|
171
|
-
return new z(t2, W);
|
|
172
|
-
}
|
|
173
|
-
var z = class _z {
|
|
174
|
-
constructor(t2, e2) {
|
|
175
|
-
this.input = void 0, this.state = void 0, this.input = t2, this.state = e2;
|
|
176
|
-
}
|
|
177
|
-
with(...t2) {
|
|
178
|
-
if (this.state.matched) return this;
|
|
179
|
-
const e2 = t2[t2.length - 1], r2 = [t2[0]];
|
|
180
|
-
let i2;
|
|
181
|
-
3 === t2.length && "function" == typeof t2[1] ? i2 = t2[1] : t2.length > 2 && r2.push(...t2.slice(1, t2.length - 1));
|
|
182
|
-
let s2 = false, c2 = {};
|
|
183
|
-
const a2 = (t3, e3) => {
|
|
184
|
-
s2 = true, c2[t3] = e3;
|
|
185
|
-
}, u2 = !r2.some((t3) => o(t3, this.input, a2)) || i2 && !Boolean(i2(this.input)) ? W : { matched: true, value: e2(s2 ? n in c2 ? c2[n] : c2 : this.input, this.input) };
|
|
186
|
-
return new _z(this.input, u2);
|
|
187
|
-
}
|
|
188
|
-
when(t2, e2) {
|
|
189
|
-
if (this.state.matched) return this;
|
|
190
|
-
const n2 = Boolean(t2(this.input));
|
|
191
|
-
return new _z(this.input, n2 ? { matched: true, value: e2(this.input, this.input) } : W);
|
|
192
|
-
}
|
|
193
|
-
otherwise(t2) {
|
|
194
|
-
return this.state.matched ? this.state.value : t2(this.input);
|
|
195
|
-
}
|
|
196
|
-
exhaustive() {
|
|
197
|
-
if (this.state.matched) return this.state.value;
|
|
198
|
-
let t2;
|
|
199
|
-
try {
|
|
200
|
-
t2 = JSON.stringify(this.input);
|
|
201
|
-
} catch (e2) {
|
|
202
|
-
t2 = this.input;
|
|
203
|
-
}
|
|
204
|
-
throw new Error(`Pattern matching error: no pattern matches value ${t2}`);
|
|
205
|
-
}
|
|
206
|
-
run() {
|
|
207
|
-
return this.exhaustive();
|
|
208
|
-
}
|
|
209
|
-
returnType() {
|
|
210
|
-
return this;
|
|
211
|
-
}
|
|
212
|
-
};
|
|
213
|
-
|
|
214
|
-
// src/utils/is-set-function-call.ts
|
|
215
32
|
function isSetFunctionCall(context, settings) {
|
|
216
33
|
const isIdFromUseStateCall = isFromUseStateCall(context, settings);
|
|
217
34
|
return (node) => {
|
|
218
35
|
switch (node.callee.type) {
|
|
219
|
-
case
|
|
36
|
+
case AST_NODE_TYPES.Identifier: {
|
|
220
37
|
return isIdFromUseStateCall(node.callee);
|
|
221
38
|
}
|
|
222
|
-
case
|
|
39
|
+
case AST_NODE_TYPES.MemberExpression: {
|
|
223
40
|
if (!("name" in node.callee.object)) return false;
|
|
224
41
|
const initialScope = context.sourceCode.getScope(node);
|
|
225
42
|
const property = getStaticValue(node.callee.property, initialScope);
|
|
226
43
|
if (property?.value === 1) return isIdFromUseStateCall(node.callee.object);
|
|
227
44
|
return false;
|
|
228
45
|
}
|
|
229
|
-
case
|
|
46
|
+
case AST_NODE_TYPES.CallExpression: {
|
|
230
47
|
const callee = node.callee.callee;
|
|
231
|
-
if (callee.type !==
|
|
48
|
+
if (callee.type !== AST_NODE_TYPES.MemberExpression) return false;
|
|
232
49
|
if (!("name" in callee.object)) return false;
|
|
233
|
-
const isAt =
|
|
234
|
-
type:
|
|
50
|
+
const isAt = isMatching({
|
|
51
|
+
type: AST_NODE_TYPES.MemberExpression,
|
|
235
52
|
property: {
|
|
236
|
-
type:
|
|
53
|
+
type: AST_NODE_TYPES.Identifier,
|
|
237
54
|
name: "at"
|
|
238
55
|
}
|
|
239
56
|
}, callee);
|
|
@@ -251,17 +68,17 @@ function isSetFunctionCall(context, settings) {
|
|
|
251
68
|
};
|
|
252
69
|
}
|
|
253
70
|
function isThenCall(node) {
|
|
254
|
-
return node.callee.type ===
|
|
71
|
+
return node.callee.type === AST_NODE_TYPES.MemberExpression && node.callee.property.type === AST_NODE_TYPES.Identifier && node.callee.property.name === "then";
|
|
255
72
|
}
|
|
256
73
|
function isVariableDeclaratorFromHookCall(node) {
|
|
257
|
-
if (node.type !==
|
|
258
|
-
if (node.id.type !==
|
|
259
|
-
if (node.init?.type !==
|
|
74
|
+
if (node.type !== AST_NODE_TYPES.VariableDeclarator) return false;
|
|
75
|
+
if (node.id.type !== AST_NODE_TYPES.Identifier) return false;
|
|
76
|
+
if (node.init?.type !== AST_NODE_TYPES.CallExpression) return false;
|
|
260
77
|
switch (node.init.callee.type) {
|
|
261
|
-
case
|
|
78
|
+
case AST_NODE_TYPES.Identifier:
|
|
262
79
|
return isReactHookName(node.init.callee.name);
|
|
263
|
-
case
|
|
264
|
-
return node.init.callee.property.type ===
|
|
80
|
+
case AST_NODE_TYPES.MemberExpression:
|
|
81
|
+
return node.init.callee.property.type === AST_NODE_TYPES.Identifier && isReactHookName(node.init.callee.property.name);
|
|
265
82
|
default:
|
|
266
83
|
return false;
|
|
267
84
|
}
|
|
@@ -336,14 +153,14 @@ var ensure_use_callback_has_non_empty_deps_default = createRule({
|
|
|
336
153
|
return;
|
|
337
154
|
}
|
|
338
155
|
const hasEmptyDeps = F.pipe(
|
|
339
|
-
|
|
156
|
+
match(deps).with({ type: AST_NODE_TYPES.ArrayExpression }, O.some).with({ type: AST_NODE_TYPES.Identifier }, (n) => {
|
|
340
157
|
return F.pipe(
|
|
341
|
-
findVariable(
|
|
158
|
+
findVariable(n.name, initialScope),
|
|
342
159
|
O.flatMap(getVariableNode(0)),
|
|
343
|
-
O.filter(is(
|
|
160
|
+
O.filter(is(AST_NODE_TYPES.ArrayExpression))
|
|
344
161
|
);
|
|
345
162
|
}).otherwise(O.none),
|
|
346
|
-
O.exists((
|
|
163
|
+
O.exists((x) => x.elements.length === 0)
|
|
347
164
|
);
|
|
348
165
|
if (!hasEmptyDeps) return;
|
|
349
166
|
if (!cb) {
|
|
@@ -354,21 +171,21 @@ var ensure_use_callback_has_non_empty_deps_default = createRule({
|
|
|
354
171
|
return;
|
|
355
172
|
}
|
|
356
173
|
const isReferencedToComponentScope = F.pipe(
|
|
357
|
-
|
|
358
|
-
if (
|
|
359
|
-
return O.some(
|
|
174
|
+
match(cb).with({ type: AST_NODE_TYPES.ArrowFunctionExpression }, (n) => {
|
|
175
|
+
if (n.body.type === AST_NODE_TYPES.ArrowFunctionExpression) {
|
|
176
|
+
return O.some(n.body);
|
|
360
177
|
}
|
|
361
|
-
return O.some(
|
|
362
|
-
}).with({ type:
|
|
178
|
+
return O.some(n);
|
|
179
|
+
}).with({ type: AST_NODE_TYPES.FunctionExpression }, O.some).with({ type: AST_NODE_TYPES.Identifier }, (n) => {
|
|
363
180
|
return F.pipe(
|
|
364
|
-
findVariable(
|
|
181
|
+
findVariable(n.name, initialScope),
|
|
365
182
|
O.flatMap(getVariableNode(0)),
|
|
366
183
|
O.filter(isFunction)
|
|
367
184
|
);
|
|
368
185
|
}).otherwise(O.none),
|
|
369
|
-
O.map((
|
|
370
|
-
O.map((
|
|
371
|
-
O.exists((refs) => refs.some((
|
|
186
|
+
O.map((n) => context.sourceCode.getScope(n)),
|
|
187
|
+
O.map((s) => [...s.childScopes, s].flatMap((x) => x.references)),
|
|
188
|
+
O.exists((refs) => refs.some((x) => x.resolved?.scope.block === component))
|
|
372
189
|
);
|
|
373
190
|
if (isReferencedToComponentScope) return;
|
|
374
191
|
context.report({
|
|
@@ -414,14 +231,14 @@ var ensure_use_memo_has_non_empty_deps_default = createRule({
|
|
|
414
231
|
return;
|
|
415
232
|
}
|
|
416
233
|
const hasEmptyDeps = F.pipe(
|
|
417
|
-
|
|
234
|
+
match(deps).with({ type: AST_NODE_TYPES.ArrayExpression }, O.some).with({ type: AST_NODE_TYPES.Identifier }, (n) => {
|
|
418
235
|
return F.pipe(
|
|
419
|
-
findVariable(
|
|
236
|
+
findVariable(n.name, initialScope),
|
|
420
237
|
O.flatMap(getVariableNode(0)),
|
|
421
|
-
O.filter(is(
|
|
238
|
+
O.filter(is(AST_NODE_TYPES.ArrayExpression))
|
|
422
239
|
);
|
|
423
240
|
}).otherwise(O.none),
|
|
424
|
-
O.exists((
|
|
241
|
+
O.exists((x) => x.elements.length === 0)
|
|
425
242
|
);
|
|
426
243
|
if (!hasEmptyDeps) return;
|
|
427
244
|
if (!cb) {
|
|
@@ -432,21 +249,21 @@ var ensure_use_memo_has_non_empty_deps_default = createRule({
|
|
|
432
249
|
return;
|
|
433
250
|
}
|
|
434
251
|
const isReferencedToComponentScope = F.pipe(
|
|
435
|
-
|
|
436
|
-
if (
|
|
437
|
-
return O.some(
|
|
252
|
+
match(cb).with({ type: AST_NODE_TYPES.ArrowFunctionExpression }, (n) => {
|
|
253
|
+
if (n.body.type === AST_NODE_TYPES.ArrowFunctionExpression) {
|
|
254
|
+
return O.some(n.body);
|
|
438
255
|
}
|
|
439
|
-
return O.some(
|
|
440
|
-
}).with({ type:
|
|
256
|
+
return O.some(n);
|
|
257
|
+
}).with({ type: AST_NODE_TYPES.FunctionExpression }, O.some).with({ type: AST_NODE_TYPES.Identifier }, (n) => {
|
|
441
258
|
return F.pipe(
|
|
442
|
-
findVariable(
|
|
259
|
+
findVariable(n.name, initialScope),
|
|
443
260
|
O.flatMap(getVariableNode(0)),
|
|
444
261
|
O.filter(isFunction)
|
|
445
262
|
);
|
|
446
263
|
}).otherwise(O.none),
|
|
447
|
-
O.map((
|
|
448
|
-
O.map((
|
|
449
|
-
O.exists((refs) => refs.some((
|
|
264
|
+
O.map((n) => context.sourceCode.getScope(n)),
|
|
265
|
+
O.map((s) => [...s.childScopes, s].flatMap((x) => x.references)),
|
|
266
|
+
O.exists((refs) => refs.some((x) => x.resolved?.scope.block === component))
|
|
450
267
|
);
|
|
451
268
|
if (isReferencedToComponentScope) return;
|
|
452
269
|
context.report({
|
|
@@ -495,13 +312,13 @@ var no_direct_set_state_in_use_effect_default = createRule({
|
|
|
495
312
|
MutRef.update(effectFunctionRef, (current) => current === node ? null : current);
|
|
496
313
|
};
|
|
497
314
|
function isEffectFunction(node) {
|
|
498
|
-
return node.parent?.type ===
|
|
315
|
+
return node.parent?.type === AST_NODE_TYPES.CallExpression && node.parent.callee !== node && isUseEffectCall(node.parent);
|
|
499
316
|
}
|
|
500
317
|
function getCallKind(node) {
|
|
501
|
-
return
|
|
318
|
+
return match(node).when(isUseStateCall2, () => "useState").when(isUseEffectCall, () => "useEffect").when(isSetStateCall, () => "setState").when(isThenCall, () => "then").otherwise(() => "other");
|
|
502
319
|
}
|
|
503
320
|
function getFunctionKind(node) {
|
|
504
|
-
return
|
|
321
|
+
return match(node).when(isEffectFunction, () => "effect").when(isFunctionOfImmediatelyInvoked, () => "immediate").otherwise(() => "other");
|
|
505
322
|
}
|
|
506
323
|
return {
|
|
507
324
|
":function"(node) {
|
|
@@ -510,7 +327,7 @@ var no_direct_set_state_in_use_effect_default = createRule({
|
|
|
510
327
|
if (functionKind === "effect") onEffectFunctionEnter(node);
|
|
511
328
|
},
|
|
512
329
|
":function:exit"(node) {
|
|
513
|
-
const [
|
|
330
|
+
const [_, functionKind] = functionStack.at(-1) ?? [];
|
|
514
331
|
functionStack.pop();
|
|
515
332
|
if (functionKind === "effect") onEffectFunctionExit(node);
|
|
516
333
|
},
|
|
@@ -518,7 +335,7 @@ var no_direct_set_state_in_use_effect_default = createRule({
|
|
|
518
335
|
const effectFn = MutRef.get(effectFunctionRef);
|
|
519
336
|
const [parentFn, parentFnKind] = functionStack.at(-1) ?? [];
|
|
520
337
|
if (parentFn?.async) return;
|
|
521
|
-
|
|
338
|
+
match(getCallKind(node)).with("setState", () => {
|
|
522
339
|
if (!parentFn) return;
|
|
523
340
|
if (parentFn !== effectFn && parentFnKind !== "immediate") {
|
|
524
341
|
const maybeVd = traverseUpGuard(node, isVariableDeclaratorFromHookCall);
|
|
@@ -548,10 +365,10 @@ var no_direct_set_state_in_use_effect_default = createRule({
|
|
|
548
365
|
}).otherwise(F.constVoid);
|
|
549
366
|
},
|
|
550
367
|
Identifier(node) {
|
|
551
|
-
if (node.parent.type ===
|
|
368
|
+
if (node.parent.type === AST_NODE_TYPES.CallExpression && node.parent.callee === node) return;
|
|
552
369
|
if (!isIdFromUseStateCall(node)) return;
|
|
553
370
|
switch (node.parent.type) {
|
|
554
|
-
case
|
|
371
|
+
case AST_NODE_TYPES.CallExpression: {
|
|
555
372
|
const [firstArg] = node.parent.arguments;
|
|
556
373
|
if (node !== firstArg) break;
|
|
557
374
|
if (isUseCallbackCall2(node.parent)) {
|
|
@@ -567,9 +384,9 @@ var no_direct_set_state_in_use_effect_default = createRule({
|
|
|
567
384
|
}
|
|
568
385
|
break;
|
|
569
386
|
}
|
|
570
|
-
case
|
|
387
|
+
case AST_NODE_TYPES.ArrowFunctionExpression: {
|
|
571
388
|
const parent = node.parent.parent;
|
|
572
|
-
if (parent.type !==
|
|
389
|
+
if (parent.type !== AST_NODE_TYPES.CallExpression) break;
|
|
573
390
|
if (!isUseMemoCall2(parent)) break;
|
|
574
391
|
const maybeVd = traverseUpGuard(parent, isVariableDeclaratorFromHookCall);
|
|
575
392
|
if (O.isNone(maybeVd)) break;
|
|
@@ -583,16 +400,16 @@ var no_direct_set_state_in_use_effect_default = createRule({
|
|
|
583
400
|
const getSetStateCalls = (id, initialScope) => {
|
|
584
401
|
const node = O.flatMap(findVariable(id, initialScope), getVariableNode(0)).pipe(O.getOrNull);
|
|
585
402
|
switch (node?.type) {
|
|
586
|
-
case
|
|
587
|
-
case
|
|
588
|
-
case
|
|
403
|
+
case AST_NODE_TYPES.FunctionDeclaration:
|
|
404
|
+
case AST_NODE_TYPES.FunctionExpression:
|
|
405
|
+
case AST_NODE_TYPES.ArrowFunctionExpression:
|
|
589
406
|
return indirectSetStateCalls.get(node) ?? [];
|
|
590
|
-
case
|
|
407
|
+
case AST_NODE_TYPES.CallExpression:
|
|
591
408
|
return indirectSetStateCallsInHooks.get(node) ?? indirectSetStateCallsAsArgs.get(node) ?? [];
|
|
592
409
|
}
|
|
593
410
|
return [];
|
|
594
411
|
};
|
|
595
|
-
for (const [
|
|
412
|
+
for (const [_, calls] of indirectSetStateCallsAsEFs) {
|
|
596
413
|
for (const call of calls) {
|
|
597
414
|
context.report({
|
|
598
415
|
data: { name: call.name },
|
|
@@ -669,13 +486,13 @@ var no_direct_set_state_in_use_layout_effect_default = createRule({
|
|
|
669
486
|
MutRef.update(effectFunctionRef, (current) => current === node ? null : current);
|
|
670
487
|
};
|
|
671
488
|
function isEffectFunction(node) {
|
|
672
|
-
return node.parent?.type ===
|
|
489
|
+
return node.parent?.type === AST_NODE_TYPES.CallExpression && node.parent.callee !== node && isUseEffectCall(node.parent);
|
|
673
490
|
}
|
|
674
491
|
function getCallKind(node) {
|
|
675
|
-
return
|
|
492
|
+
return match(node).when(isUseStateCall2, () => "useState").when(isUseEffectCall, () => "useLayoutEffect").when(isSetStateCall, () => "setState").when(isThenCall, () => "then").otherwise(() => "other");
|
|
676
493
|
}
|
|
677
494
|
function getFunctionKind(node) {
|
|
678
|
-
return
|
|
495
|
+
return match(node).when(isEffectFunction, () => "effect").when(isFunctionOfImmediatelyInvoked, () => "immediate").otherwise(() => "other");
|
|
679
496
|
}
|
|
680
497
|
return {
|
|
681
498
|
":function"(node) {
|
|
@@ -684,7 +501,7 @@ var no_direct_set_state_in_use_layout_effect_default = createRule({
|
|
|
684
501
|
if (functionKind === "effect") onEffectFunctionEnter(node);
|
|
685
502
|
},
|
|
686
503
|
":function:exit"(node) {
|
|
687
|
-
const [
|
|
504
|
+
const [_, functionKind] = functionStack.at(-1) ?? [];
|
|
688
505
|
functionStack.pop();
|
|
689
506
|
if (functionKind === "effect") onEffectFunctionExit(node);
|
|
690
507
|
},
|
|
@@ -692,7 +509,7 @@ var no_direct_set_state_in_use_layout_effect_default = createRule({
|
|
|
692
509
|
const effectFn = MutRef.get(effectFunctionRef);
|
|
693
510
|
const [parentFn, parentFnKind] = functionStack.at(-1) ?? [];
|
|
694
511
|
if (parentFn?.async) return;
|
|
695
|
-
|
|
512
|
+
match(getCallKind(node)).with("setState", () => {
|
|
696
513
|
if (!parentFn) return;
|
|
697
514
|
if (parentFn !== effectFn && parentFnKind !== "immediate") {
|
|
698
515
|
const maybeVd = traverseUpGuard(node, isVariableDeclaratorFromHookCall);
|
|
@@ -722,10 +539,10 @@ var no_direct_set_state_in_use_layout_effect_default = createRule({
|
|
|
722
539
|
}).otherwise(F.constVoid);
|
|
723
540
|
},
|
|
724
541
|
Identifier(node) {
|
|
725
|
-
if (node.parent.type ===
|
|
542
|
+
if (node.parent.type === AST_NODE_TYPES.CallExpression && node.parent.callee === node) return;
|
|
726
543
|
if (!isIdFromUseStateCall(node)) return;
|
|
727
544
|
switch (node.parent.type) {
|
|
728
|
-
case
|
|
545
|
+
case AST_NODE_TYPES.CallExpression: {
|
|
729
546
|
const [firstArg] = node.parent.arguments;
|
|
730
547
|
if (node !== firstArg) break;
|
|
731
548
|
if (isUseCallbackCall2(node.parent)) {
|
|
@@ -741,9 +558,9 @@ var no_direct_set_state_in_use_layout_effect_default = createRule({
|
|
|
741
558
|
}
|
|
742
559
|
break;
|
|
743
560
|
}
|
|
744
|
-
case
|
|
561
|
+
case AST_NODE_TYPES.ArrowFunctionExpression: {
|
|
745
562
|
const parent = node.parent.parent;
|
|
746
|
-
if (parent.type !==
|
|
563
|
+
if (parent.type !== AST_NODE_TYPES.CallExpression) break;
|
|
747
564
|
if (!isUseMemoCall2(parent)) break;
|
|
748
565
|
const maybeVd = traverseUpGuard(parent, isVariableDeclaratorFromHookCall);
|
|
749
566
|
if (O.isNone(maybeVd)) break;
|
|
@@ -757,16 +574,16 @@ var no_direct_set_state_in_use_layout_effect_default = createRule({
|
|
|
757
574
|
const getSetStateCalls = (id, initialScope) => {
|
|
758
575
|
const node = O.flatMap(findVariable(id, initialScope), getVariableNode(0)).pipe(O.getOrNull);
|
|
759
576
|
switch (node?.type) {
|
|
760
|
-
case
|
|
761
|
-
case
|
|
762
|
-
case
|
|
577
|
+
case AST_NODE_TYPES.FunctionDeclaration:
|
|
578
|
+
case AST_NODE_TYPES.FunctionExpression:
|
|
579
|
+
case AST_NODE_TYPES.ArrowFunctionExpression:
|
|
763
580
|
return indirectSetStateCalls.get(node) ?? [];
|
|
764
|
-
case
|
|
581
|
+
case AST_NODE_TYPES.CallExpression:
|
|
765
582
|
return indirectSetStateCallsInHooks.get(node) ?? indirectSetStateCallsAsArgs.get(node) ?? [];
|
|
766
583
|
}
|
|
767
584
|
return [];
|
|
768
585
|
};
|
|
769
|
-
for (const [
|
|
586
|
+
for (const [_, calls] of indirectSetStateCallsAsEFs) {
|
|
770
587
|
for (const call of calls) {
|
|
771
588
|
context.report({
|
|
772
589
|
data: { name: call.name },
|
|
@@ -825,8 +642,8 @@ var prefer_use_state_lazy_initialization_default = createRule({
|
|
|
825
642
|
const [useStateInput] = node.arguments;
|
|
826
643
|
if (!useStateInput) return;
|
|
827
644
|
const nestedCallExpressions = getNestedCallExpressions(useStateInput);
|
|
828
|
-
const hasFunctionCall = nestedCallExpressions.some((
|
|
829
|
-
return "name" in
|
|
645
|
+
const hasFunctionCall = nestedCallExpressions.some((n) => {
|
|
646
|
+
return "name" in n.callee && !ALLOW_LIST.includes(n.callee.name);
|
|
830
647
|
});
|
|
831
648
|
if (!hasFunctionCall) return;
|
|
832
649
|
context.report({
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-react-hooks-extra",
|
|
3
|
-
"version": "1.9.
|
|
3
|
+
"version": "1.9.2-beta.4",
|
|
4
4
|
"description": "ESLint React's ESLint plugin for React Hooks related rules.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"eslint",
|
|
@@ -45,13 +45,14 @@
|
|
|
45
45
|
"@typescript-eslint/type-utils": "^8.0.1",
|
|
46
46
|
"@typescript-eslint/types": "^8.0.1",
|
|
47
47
|
"@typescript-eslint/utils": "^8.0.1",
|
|
48
|
-
"
|
|
49
|
-
"@eslint-react/
|
|
50
|
-
"@eslint-react/
|
|
51
|
-
"@eslint-react/core": "1.9.
|
|
52
|
-
"@eslint-react/
|
|
53
|
-
"@eslint-react/
|
|
54
|
-
"@eslint-react/var": "1.9.
|
|
48
|
+
"ts-pattern": "^5.2.0",
|
|
49
|
+
"@eslint-react/ast": "1.9.2-beta.4",
|
|
50
|
+
"@eslint-react/jsx": "1.9.2-beta.4",
|
|
51
|
+
"@eslint-react/core": "1.9.2-beta.4",
|
|
52
|
+
"@eslint-react/shared": "1.9.2-beta.4",
|
|
53
|
+
"@eslint-react/tools": "1.9.2-beta.4",
|
|
54
|
+
"@eslint-react/var": "1.9.2-beta.4",
|
|
55
|
+
"@eslint-react/types": "1.9.2-beta.4"
|
|
55
56
|
},
|
|
56
57
|
"devDependencies": {
|
|
57
58
|
"@types/react": "^18.3.3",
|