@whoj/eslint-config 2.2.1 → 2.2.2
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/README.md +21 -21
- package/dist/cli.js +45 -56
- package/dist/index.d.ts +290 -283
- package/dist/index.js +709 -757
- package/package.json +6 -3
- package/dist/chunk-3P3JBQLJ.js +0 -5191
- package/dist/chunk-5NT2OOQW.js +0 -29719
- package/dist/chunk-7F5ASJF4.js +0 -1962
- package/dist/chunk-DLJMV7EV.js +0 -626
- package/dist/chunk-G5WGJHBR.js +0 -149
- package/dist/chunk-IDB36RF3.js +0 -353
- package/dist/chunk-IKAXXATW.js +0 -6400
- package/dist/chunk-MKKAXXPL.js +0 -5769
- package/dist/chunk-MKNYKNDN.js +0 -65
- package/dist/chunk-PVCENCBM.js +0 -1053
- package/dist/chunk-QT5XME2Q.js +0 -209134
- package/dist/chunk-THBKBMVU.js +0 -8352
- package/dist/chunk-VSLGWZT6.js +0 -115
- package/dist/chunk-XZGWRL6X.js +0 -1520
- package/dist/dist-MYXPM6TG.js +0 -4953
- package/dist/dist-ZJ2E2ITJ.js +0 -26233
- package/dist/eslint-plugin-react-hooks-BV2CYKDG.js +0 -2559
- package/dist/eslint-plugin-react-refresh-N5P3A37Z.js +0 -272
- package/dist/lib-C6BFP32Q.js +0 -24437
- package/dist/lib-FENTQ4WJ.js +0 -10106
- package/dist/lib-WKUBBNE4.js +0 -26
- package/dist/lib-XQB7MXK6.js +0 -9
- package/dist/sass.node-L3JPZGSW.js +0 -125580
- package/dist/typescript-LG2A6BNW.js +0 -5
|
@@ -1,2559 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
__commonJS,
|
|
3
|
-
init_esm_shims
|
|
4
|
-
} from "./chunk-MKNYKNDN.js";
|
|
5
|
-
|
|
6
|
-
// node_modules/.pnpm/eslint-plugin-react-hooks@5.1.0_eslint@9.19.0_jiti@2.4.2_/node_modules/eslint-plugin-react-hooks/cjs/eslint-plugin-react-hooks.production.js
|
|
7
|
-
var require_eslint_plugin_react_hooks_production = __commonJS({
|
|
8
|
-
"node_modules/.pnpm/eslint-plugin-react-hooks@5.1.0_eslint@9.19.0_jiti@2.4.2_/node_modules/eslint-plugin-react-hooks/cjs/eslint-plugin-react-hooks.production.js"(exports) {
|
|
9
|
-
"use strict";
|
|
10
|
-
init_esm_shims();
|
|
11
|
-
function _unsupportedIterableToArray(o, minLen) {
|
|
12
|
-
if (o) {
|
|
13
|
-
if ("string" === typeof o) return _arrayLikeToArray(o, minLen);
|
|
14
|
-
var n = Object.prototype.toString.call(o).slice(8, -1);
|
|
15
|
-
"Object" === n && o.constructor && (n = o.constructor.name);
|
|
16
|
-
if ("Map" === n || "Set" === n) return Array.from(o);
|
|
17
|
-
if ("Arguments" === n || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))
|
|
18
|
-
return _arrayLikeToArray(o, minLen);
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
function _arrayLikeToArray(arr, len) {
|
|
22
|
-
if (null == len || len > arr.length) len = arr.length;
|
|
23
|
-
for (var i = 0, arr2 = Array(len); i < len; i++) arr2[i] = arr[i];
|
|
24
|
-
return arr2;
|
|
25
|
-
}
|
|
26
|
-
function _createForOfIteratorHelper(o, allowArrayLike) {
|
|
27
|
-
var it;
|
|
28
|
-
if ("undefined" === typeof Symbol || null == o[Symbol.iterator]) {
|
|
29
|
-
if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && "number" === typeof o.length) {
|
|
30
|
-
it && (o = it);
|
|
31
|
-
var i = 0;
|
|
32
|
-
allowArrayLike = function() {
|
|
33
|
-
};
|
|
34
|
-
return {
|
|
35
|
-
s: allowArrayLike,
|
|
36
|
-
n: function() {
|
|
37
|
-
return i >= o.length ? { done: true } : { done: false, value: o[i++] };
|
|
38
|
-
},
|
|
39
|
-
e: function(e) {
|
|
40
|
-
throw e;
|
|
41
|
-
},
|
|
42
|
-
f: allowArrayLike
|
|
43
|
-
};
|
|
44
|
-
}
|
|
45
|
-
throw new TypeError(
|
|
46
|
-
"Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."
|
|
47
|
-
);
|
|
48
|
-
}
|
|
49
|
-
var normalCompletion = true, didErr = false, err;
|
|
50
|
-
return {
|
|
51
|
-
s: function() {
|
|
52
|
-
it = o[Symbol.iterator]();
|
|
53
|
-
},
|
|
54
|
-
n: function() {
|
|
55
|
-
var step = it.next();
|
|
56
|
-
normalCompletion = step.done;
|
|
57
|
-
return step;
|
|
58
|
-
},
|
|
59
|
-
e: function(e) {
|
|
60
|
-
didErr = true;
|
|
61
|
-
err = e;
|
|
62
|
-
},
|
|
63
|
-
f: function() {
|
|
64
|
-
try {
|
|
65
|
-
normalCompletion || null == it.return || it.return();
|
|
66
|
-
} finally {
|
|
67
|
-
if (didErr) throw err;
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
};
|
|
71
|
-
}
|
|
72
|
-
function isHook(node) {
|
|
73
|
-
if ("Identifier" === node.type)
|
|
74
|
-
return node = node.name, "use" === node || /^use[A-Z0-9]/.test(node);
|
|
75
|
-
if ("MemberExpression" === node.type && !node.computed && isHook(node.property)) {
|
|
76
|
-
node = node.object;
|
|
77
|
-
var isPascalCaseNameSpace = /^[A-Z].*/;
|
|
78
|
-
return "Identifier" === node.type && isPascalCaseNameSpace.test(node.name);
|
|
79
|
-
}
|
|
80
|
-
return false;
|
|
81
|
-
}
|
|
82
|
-
function isComponentName(node) {
|
|
83
|
-
return "Identifier" === node.type && /^[A-Z]/.test(node.name);
|
|
84
|
-
}
|
|
85
|
-
function isReactFunction(node, functionName) {
|
|
86
|
-
return node.name === functionName || "MemberExpression" === node.type && "React" === node.object.name && node.property.name === functionName;
|
|
87
|
-
}
|
|
88
|
-
function isForwardRefCallback(node) {
|
|
89
|
-
return !!(node.parent && node.parent.callee && isReactFunction(node.parent.callee, "forwardRef"));
|
|
90
|
-
}
|
|
91
|
-
function isMemoCallback(node) {
|
|
92
|
-
return !!(node.parent && node.parent.callee && isReactFunction(node.parent.callee, "memo"));
|
|
93
|
-
}
|
|
94
|
-
function isInsideComponentOrHook(node) {
|
|
95
|
-
for (; node; ) {
|
|
96
|
-
var functionName = getFunctionName(node);
|
|
97
|
-
if (functionName && (isComponentName(functionName) || isHook(functionName)) || isForwardRefCallback(node) || isMemoCallback(node))
|
|
98
|
-
return true;
|
|
99
|
-
node = node.parent;
|
|
100
|
-
}
|
|
101
|
-
return false;
|
|
102
|
-
}
|
|
103
|
-
function getFunctionName(node) {
|
|
104
|
-
if ("FunctionDeclaration" === node.type || "FunctionExpression" === node.type && node.id)
|
|
105
|
-
return node.id;
|
|
106
|
-
if ("FunctionExpression" === node.type || "ArrowFunctionExpression" === node.type)
|
|
107
|
-
return "VariableDeclarator" === node.parent.type && node.parent.init === node ? node.parent.id : "AssignmentExpression" === node.parent.type && node.parent.right === node && "=" === node.parent.operator ? node.parent.left : "Property" !== node.parent.type || node.parent.value !== node || node.parent.computed ? "AssignmentPattern" !== node.parent.type || node.parent.right !== node || node.parent.computed ? void 0 : node.parent.left : node.parent.key;
|
|
108
|
-
}
|
|
109
|
-
function collectRecommendations(_ref6) {
|
|
110
|
-
function createDepTree() {
|
|
111
|
-
return {
|
|
112
|
-
isUsed: false,
|
|
113
|
-
isSatisfiedRecursively: false,
|
|
114
|
-
isSubtreeUsed: false,
|
|
115
|
-
children: /* @__PURE__ */ new Map()
|
|
116
|
-
};
|
|
117
|
-
}
|
|
118
|
-
function getOrCreateNodeByPath(rootNode, path) {
|
|
119
|
-
path = path.split(".");
|
|
120
|
-
path = _createForOfIteratorHelper(path);
|
|
121
|
-
var _step4;
|
|
122
|
-
try {
|
|
123
|
-
for (path.s(); !(_step4 = path.n()).done; ) {
|
|
124
|
-
var key = _step4.value, child = rootNode.children.get(key);
|
|
125
|
-
child || (child = createDepTree(), rootNode.children.set(key, child));
|
|
126
|
-
rootNode = child;
|
|
127
|
-
}
|
|
128
|
-
} catch (err) {
|
|
129
|
-
path.e(err);
|
|
130
|
-
} finally {
|
|
131
|
-
path.f();
|
|
132
|
-
}
|
|
133
|
-
return rootNode;
|
|
134
|
-
}
|
|
135
|
-
function markAllParentsByPath(rootNode, path, fn) {
|
|
136
|
-
path = path.split(".");
|
|
137
|
-
path = _createForOfIteratorHelper(path);
|
|
138
|
-
var _step5;
|
|
139
|
-
try {
|
|
140
|
-
for (path.s(); !(_step5 = path.n()).done; ) {
|
|
141
|
-
var child = rootNode.children.get(_step5.value);
|
|
142
|
-
if (!child) break;
|
|
143
|
-
fn(child);
|
|
144
|
-
rootNode = child;
|
|
145
|
-
}
|
|
146
|
-
} catch (err) {
|
|
147
|
-
path.e(err);
|
|
148
|
-
} finally {
|
|
149
|
-
path.f();
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
function scanTreeRecursively(node, missingPaths, satisfyingPaths, keyToPath) {
|
|
153
|
-
node.children.forEach(function(child, key) {
|
|
154
|
-
var path = keyToPath(key);
|
|
155
|
-
child.isSatisfiedRecursively ? child.isSubtreeUsed && satisfyingPaths.add(path) : child.isUsed ? missingPaths.add(path) : scanTreeRecursively(
|
|
156
|
-
child,
|
|
157
|
-
missingPaths,
|
|
158
|
-
satisfyingPaths,
|
|
159
|
-
function(childKey) {
|
|
160
|
-
return path + "." + childKey;
|
|
161
|
-
}
|
|
162
|
-
);
|
|
163
|
-
});
|
|
164
|
-
}
|
|
165
|
-
var dependencies = _ref6.dependencies, declaredDependencies = _ref6.declaredDependencies, stableDependencies = _ref6.stableDependencies, externalDependencies = _ref6.externalDependencies, isEffect = _ref6.isEffect, depTree = createDepTree();
|
|
166
|
-
dependencies.forEach(function(_, key) {
|
|
167
|
-
getOrCreateNodeByPath(depTree, key).isUsed = true;
|
|
168
|
-
markAllParentsByPath(depTree, key, function(parent) {
|
|
169
|
-
parent.isSubtreeUsed = true;
|
|
170
|
-
});
|
|
171
|
-
});
|
|
172
|
-
declaredDependencies.forEach(function(_ref7) {
|
|
173
|
-
getOrCreateNodeByPath(depTree, _ref7.key).isSatisfiedRecursively = true;
|
|
174
|
-
});
|
|
175
|
-
stableDependencies.forEach(function(key) {
|
|
176
|
-
getOrCreateNodeByPath(depTree, key).isSatisfiedRecursively = true;
|
|
177
|
-
});
|
|
178
|
-
_ref6 = /* @__PURE__ */ new Set();
|
|
179
|
-
var satisfyingDependencies = /* @__PURE__ */ new Set();
|
|
180
|
-
scanTreeRecursively(depTree, _ref6, satisfyingDependencies, function(key) {
|
|
181
|
-
return key;
|
|
182
|
-
});
|
|
183
|
-
var suggestedDependencies = [], unnecessaryDependencies = /* @__PURE__ */ new Set(), duplicateDependencies = /* @__PURE__ */ new Set();
|
|
184
|
-
declaredDependencies.forEach(function(_ref8) {
|
|
185
|
-
_ref8 = _ref8.key;
|
|
186
|
-
satisfyingDependencies.has(_ref8) ? -1 === suggestedDependencies.indexOf(_ref8) ? suggestedDependencies.push(_ref8) : duplicateDependencies.add(_ref8) : !isEffect || _ref8.endsWith(".current") || externalDependencies.has(_ref8) ? unnecessaryDependencies.add(_ref8) : -1 === suggestedDependencies.indexOf(_ref8) && suggestedDependencies.push(_ref8);
|
|
187
|
-
});
|
|
188
|
-
_ref6.forEach(function(key) {
|
|
189
|
-
suggestedDependencies.push(key);
|
|
190
|
-
});
|
|
191
|
-
return {
|
|
192
|
-
suggestedDependencies,
|
|
193
|
-
unnecessaryDependencies,
|
|
194
|
-
duplicateDependencies,
|
|
195
|
-
missingDependencies: _ref6
|
|
196
|
-
};
|
|
197
|
-
}
|
|
198
|
-
function getConstructionExpressionType(node) {
|
|
199
|
-
switch (node.type) {
|
|
200
|
-
case "ObjectExpression":
|
|
201
|
-
return "object";
|
|
202
|
-
case "ArrayExpression":
|
|
203
|
-
return "array";
|
|
204
|
-
case "ArrowFunctionExpression":
|
|
205
|
-
case "FunctionExpression":
|
|
206
|
-
return "function";
|
|
207
|
-
case "ClassExpression":
|
|
208
|
-
return "class";
|
|
209
|
-
case "ConditionalExpression":
|
|
210
|
-
if (null != getConstructionExpressionType(node.consequent) || null != getConstructionExpressionType(node.alternate))
|
|
211
|
-
return "conditional";
|
|
212
|
-
break;
|
|
213
|
-
case "LogicalExpression":
|
|
214
|
-
if (null != getConstructionExpressionType(node.left) || null != getConstructionExpressionType(node.right))
|
|
215
|
-
return "logical expression";
|
|
216
|
-
break;
|
|
217
|
-
case "JSXFragment":
|
|
218
|
-
return "JSX fragment";
|
|
219
|
-
case "JSXElement":
|
|
220
|
-
return "JSX element";
|
|
221
|
-
case "AssignmentExpression":
|
|
222
|
-
if (null != getConstructionExpressionType(node.right))
|
|
223
|
-
return "assignment expression";
|
|
224
|
-
break;
|
|
225
|
-
case "NewExpression":
|
|
226
|
-
return "object construction";
|
|
227
|
-
case "Literal":
|
|
228
|
-
if (node.value instanceof RegExp) return "regular expression";
|
|
229
|
-
break;
|
|
230
|
-
case "TypeCastExpression":
|
|
231
|
-
case "AsExpression":
|
|
232
|
-
case "TSAsExpression":
|
|
233
|
-
return getConstructionExpressionType(node.expression);
|
|
234
|
-
}
|
|
235
|
-
return null;
|
|
236
|
-
}
|
|
237
|
-
function scanForConstructions(_ref9) {
|
|
238
|
-
var declaredDependenciesNode = _ref9.declaredDependenciesNode, componentScope = _ref9.componentScope, scope = _ref9.scope;
|
|
239
|
-
return _ref9.declaredDependencies.map(function(_ref10) {
|
|
240
|
-
var key = _ref10.key;
|
|
241
|
-
_ref10 = componentScope.variables.find(function(v) {
|
|
242
|
-
return v.name === key;
|
|
243
|
-
});
|
|
244
|
-
if (null == _ref10) return null;
|
|
245
|
-
var node = _ref10.defs[0];
|
|
246
|
-
if (null == node) return null;
|
|
247
|
-
if ("Variable" === node.type && "VariableDeclarator" === node.node.type && "Identifier" === node.node.id.type && null != node.node.init) {
|
|
248
|
-
var constantExpressionType = getConstructionExpressionType(
|
|
249
|
-
node.node.init
|
|
250
|
-
);
|
|
251
|
-
if (null != constantExpressionType)
|
|
252
|
-
return [_ref10, constantExpressionType];
|
|
253
|
-
}
|
|
254
|
-
return "FunctionName" === node.type && "FunctionDeclaration" === node.node.type ? [_ref10, "function"] : "ClassName" === node.type && "ClassDeclaration" === node.node.type ? [_ref10, "class"] : null;
|
|
255
|
-
}).filter(Boolean).map(function(_ref11) {
|
|
256
|
-
var ref = _ref11[0];
|
|
257
|
-
_ref11 = _ref11[1];
|
|
258
|
-
var JSCompiler_temp_const = ref.defs[0];
|
|
259
|
-
a: {
|
|
260
|
-
for (var foundWriteExpr = false, i = 0; i < ref.references.length; i++) {
|
|
261
|
-
var reference = ref.references[i];
|
|
262
|
-
if (reference.writeExpr)
|
|
263
|
-
if (foundWriteExpr) {
|
|
264
|
-
ref = true;
|
|
265
|
-
break a;
|
|
266
|
-
} else {
|
|
267
|
-
foundWriteExpr = true;
|
|
268
|
-
continue;
|
|
269
|
-
}
|
|
270
|
-
for (var currentScope = reference.from; currentScope !== scope && null != currentScope; )
|
|
271
|
-
currentScope = currentScope.upper;
|
|
272
|
-
if (currentScope !== scope && !isAncestorNodeOf(declaredDependenciesNode, reference.identifier)) {
|
|
273
|
-
ref = true;
|
|
274
|
-
break a;
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
ref = false;
|
|
278
|
-
}
|
|
279
|
-
return {
|
|
280
|
-
construction: JSCompiler_temp_const,
|
|
281
|
-
depType: _ref11,
|
|
282
|
-
isUsedOutsideOfHook: ref
|
|
283
|
-
};
|
|
284
|
-
});
|
|
285
|
-
}
|
|
286
|
-
function getDependency(node) {
|
|
287
|
-
return "MemberExpression" !== node.parent.type && "OptionalMemberExpression" !== node.parent.type || node.parent.object !== node || "current" === node.parent.property.name || node.parent.computed || null != node.parent.parent && ("CallExpression" === node.parent.parent.type || "OptionalCallExpression" === node.parent.parent.type) && node.parent.parent.callee === node.parent ? "MemberExpression" === node.type && node.parent && "AssignmentExpression" === node.parent.type && node.parent.left === node ? node.object : node : getDependency(node.parent);
|
|
288
|
-
}
|
|
289
|
-
function markNode(node, optionalChains, result) {
|
|
290
|
-
optionalChains && (node.optional ? optionalChains.has(result) || optionalChains.set(result, true) : optionalChains.set(result, false));
|
|
291
|
-
}
|
|
292
|
-
function analyzePropertyChain(node, optionalChains) {
|
|
293
|
-
if ("Identifier" === node.type || "JSXIdentifier" === node.type)
|
|
294
|
-
return node = node.name, optionalChains && optionalChains.set(node, false), node;
|
|
295
|
-
if ("MemberExpression" !== node.type || node.computed) {
|
|
296
|
-
if ("OptionalMemberExpression" !== node.type || node.computed) {
|
|
297
|
-
if ("ChainExpression" !== node.type || node.computed)
|
|
298
|
-
throw Error("Unsupported node type: " + node.type);
|
|
299
|
-
node = node.expression;
|
|
300
|
-
if ("CallExpression" === node.type)
|
|
301
|
-
throw Error("Unsupported node type: " + node.type);
|
|
302
|
-
var object$20 = analyzePropertyChain(node.object, optionalChains), property$21 = analyzePropertyChain(node.property, null);
|
|
303
|
-
object$20 = object$20 + "." + property$21;
|
|
304
|
-
markNode(node, optionalChains, object$20);
|
|
305
|
-
return object$20;
|
|
306
|
-
}
|
|
307
|
-
object$20 = analyzePropertyChain(node.object, optionalChains);
|
|
308
|
-
property$21 = analyzePropertyChain(node.property, null);
|
|
309
|
-
object$20 = object$20 + "." + property$21;
|
|
310
|
-
markNode(node, optionalChains, object$20);
|
|
311
|
-
return object$20;
|
|
312
|
-
}
|
|
313
|
-
object$20 = analyzePropertyChain(node.object, optionalChains);
|
|
314
|
-
property$21 = analyzePropertyChain(node.property, null);
|
|
315
|
-
object$20 = object$20 + "." + property$21;
|
|
316
|
-
markNode(node, optionalChains, object$20);
|
|
317
|
-
return object$20;
|
|
318
|
-
}
|
|
319
|
-
function getNodeWithoutReactNamespace(node) {
|
|
320
|
-
return "MemberExpression" !== node.type || "Identifier" !== node.object.type || "React" !== node.object.name || "Identifier" !== node.property.type || node.computed ? node : node.property;
|
|
321
|
-
}
|
|
322
|
-
function getReactiveHookCallbackIndex(calleeNode, options) {
|
|
323
|
-
var node = getNodeWithoutReactNamespace(calleeNode);
|
|
324
|
-
if ("Identifier" !== node.type) return -1;
|
|
325
|
-
switch (node.name) {
|
|
326
|
-
case "useEffect":
|
|
327
|
-
case "useLayoutEffect":
|
|
328
|
-
case "useCallback":
|
|
329
|
-
case "useMemo":
|
|
330
|
-
return 0;
|
|
331
|
-
case "useImperativeHandle":
|
|
332
|
-
return 1;
|
|
333
|
-
default:
|
|
334
|
-
if (node === calleeNode && options && options.additionalHooks) {
|
|
335
|
-
try {
|
|
336
|
-
var name = analyzePropertyChain(node, null);
|
|
337
|
-
} catch (error) {
|
|
338
|
-
if (/Unsupported node type/.test(error.message)) return 0;
|
|
339
|
-
throw error;
|
|
340
|
-
}
|
|
341
|
-
return options.additionalHooks.test(name) ? 0 : -1;
|
|
342
|
-
}
|
|
343
|
-
return -1;
|
|
344
|
-
}
|
|
345
|
-
}
|
|
346
|
-
function fastFindReferenceWithParent(start, target) {
|
|
347
|
-
for (var queue = [start], item = null; queue.length; ) {
|
|
348
|
-
item = queue.shift();
|
|
349
|
-
if (("Identifier" === item.type || "JSXIdentifier" === item.type) && item.type === target.type && item.name === target.name && item.range[0] === target.range[0] && item.range[1] === target.range[1])
|
|
350
|
-
return item;
|
|
351
|
-
if (isAncestorNodeOf(item, target)) {
|
|
352
|
-
start = 0;
|
|
353
|
-
for (var _Object$entries = Object.entries(item); start < _Object$entries.length; start++) {
|
|
354
|
-
var _Object$entries$_i = _Object$entries[start], value = _Object$entries$_i[1];
|
|
355
|
-
"parent" !== _Object$entries$_i[0] && (isNodeLike(value) ? (value.parent = item, queue.push(value)) : Array.isArray(value) && value.forEach(function(val) {
|
|
356
|
-
isNodeLike(val) && (val.parent = item, queue.push(val));
|
|
357
|
-
}));
|
|
358
|
-
}
|
|
359
|
-
}
|
|
360
|
-
}
|
|
361
|
-
return null;
|
|
362
|
-
}
|
|
363
|
-
function joinEnglish(arr) {
|
|
364
|
-
for (var s = "", i = 0; i < arr.length; i++)
|
|
365
|
-
s += arr[i], 0 === i && 2 === arr.length ? s += " and " : i === arr.length - 2 && 2 < arr.length ? s += ", and " : i < arr.length - 1 && (s += ", ");
|
|
366
|
-
return s;
|
|
367
|
-
}
|
|
368
|
-
function isNodeLike(val) {
|
|
369
|
-
return "object" === typeof val && null !== val && !Array.isArray(val) && "string" === typeof val.type;
|
|
370
|
-
}
|
|
371
|
-
function isAncestorNodeOf(a, b) {
|
|
372
|
-
return a.range[0] <= b.range[0] && a.range[1] >= b.range[1];
|
|
373
|
-
}
|
|
374
|
-
exports.configs = {
|
|
375
|
-
recommended: {
|
|
376
|
-
plugins: ["react-hooks"],
|
|
377
|
-
rules: {
|
|
378
|
-
"react-hooks/rules-of-hooks": "error",
|
|
379
|
-
"react-hooks/exhaustive-deps": "warn"
|
|
380
|
-
}
|
|
381
|
-
}
|
|
382
|
-
};
|
|
383
|
-
exports.rules = {
|
|
384
|
-
"rules-of-hooks": {
|
|
385
|
-
meta: {
|
|
386
|
-
type: "problem",
|
|
387
|
-
docs: {
|
|
388
|
-
description: "enforces the Rules of Hooks",
|
|
389
|
-
recommended: true,
|
|
390
|
-
url: "https://reactjs.org/docs/hooks-rules.html"
|
|
391
|
-
}
|
|
392
|
-
},
|
|
393
|
-
create: function(context) {
|
|
394
|
-
function recordAllUseEffectEventFunctions(scope) {
|
|
395
|
-
scope = _createForOfIteratorHelper(scope.references);
|
|
396
|
-
try {
|
|
397
|
-
for (scope.s(); !scope.n().done; ) ;
|
|
398
|
-
} catch (err$1) {
|
|
399
|
-
scope.e(err$1);
|
|
400
|
-
} finally {
|
|
401
|
-
scope.f();
|
|
402
|
-
}
|
|
403
|
-
}
|
|
404
|
-
var lastEffect = null, codePathReactHooksMapStack = [], codePathSegmentStack = [], useEffectEventFunctions = /* @__PURE__ */ new WeakSet(), getSource = "function" === typeof context.getSource ? function(node) {
|
|
405
|
-
return context.getSource(node);
|
|
406
|
-
} : function(node) {
|
|
407
|
-
return context.sourceCode.getText(node);
|
|
408
|
-
}, getScope = "function" === typeof context.getScope ? function() {
|
|
409
|
-
return context.getScope();
|
|
410
|
-
} : function(node) {
|
|
411
|
-
return context.sourceCode.getScope(node);
|
|
412
|
-
}, $jscomp$compprop0 = {};
|
|
413
|
-
return $jscomp$compprop0.onCodePathSegmentStart = function(segment) {
|
|
414
|
-
return codePathSegmentStack.push(segment);
|
|
415
|
-
}, $jscomp$compprop0.onCodePathSegmentEnd = function() {
|
|
416
|
-
return codePathSegmentStack.pop();
|
|
417
|
-
}, $jscomp$compprop0.onCodePathStart = function() {
|
|
418
|
-
return codePathReactHooksMapStack.push(/* @__PURE__ */ new Map());
|
|
419
|
-
}, $jscomp$compprop0.onCodePathEnd = function(codePath, codePathNode) {
|
|
420
|
-
function countPathsFromStart(segment, pathHistory) {
|
|
421
|
-
var cache = countPathsFromStart.cache, paths = cache.get(segment.id);
|
|
422
|
-
pathHistory = new Set(pathHistory);
|
|
423
|
-
if (pathHistory.has(segment.id)) {
|
|
424
|
-
cache = [].concat(pathHistory);
|
|
425
|
-
segment = cache.slice(cache.indexOf(segment.id) + 1);
|
|
426
|
-
segment = _createForOfIteratorHelper(segment);
|
|
427
|
-
var _step3;
|
|
428
|
-
try {
|
|
429
|
-
for (segment.s(); !(_step3 = segment.n()).done; )
|
|
430
|
-
cyclic.add(_step3.value);
|
|
431
|
-
} catch (err) {
|
|
432
|
-
segment.e(err);
|
|
433
|
-
} finally {
|
|
434
|
-
segment.f();
|
|
435
|
-
}
|
|
436
|
-
return BigInt("0");
|
|
437
|
-
}
|
|
438
|
-
pathHistory.add(segment.id);
|
|
439
|
-
if (void 0 !== paths) return paths;
|
|
440
|
-
if (codePath.thrownSegments.includes(segment)) paths = BigInt("0");
|
|
441
|
-
else if (0 === segment.prevSegments.length) paths = BigInt("1");
|
|
442
|
-
else {
|
|
443
|
-
paths = BigInt("0");
|
|
444
|
-
_step3 = _createForOfIteratorHelper(segment.prevSegments);
|
|
445
|
-
var _step4;
|
|
446
|
-
try {
|
|
447
|
-
for (_step3.s(); !(_step4 = _step3.n()).done; )
|
|
448
|
-
paths += countPathsFromStart(_step4.value, pathHistory);
|
|
449
|
-
} catch (err$2) {
|
|
450
|
-
_step3.e(err$2);
|
|
451
|
-
} finally {
|
|
452
|
-
_step3.f();
|
|
453
|
-
}
|
|
454
|
-
}
|
|
455
|
-
segment.reachable && paths === BigInt("0") ? cache.delete(segment.id) : cache.set(segment.id, paths);
|
|
456
|
-
return paths;
|
|
457
|
-
}
|
|
458
|
-
function countPathsToEnd(segment, pathHistory) {
|
|
459
|
-
var cache = countPathsToEnd.cache, paths = cache.get(segment.id);
|
|
460
|
-
pathHistory = new Set(pathHistory);
|
|
461
|
-
if (pathHistory.has(segment.id)) {
|
|
462
|
-
cache = Array.from(pathHistory);
|
|
463
|
-
segment = cache.slice(cache.indexOf(segment.id) - 1);
|
|
464
|
-
segment = _createForOfIteratorHelper(segment);
|
|
465
|
-
var _step5;
|
|
466
|
-
try {
|
|
467
|
-
for (segment.s(); !(_step5 = segment.n()).done; )
|
|
468
|
-
cyclic.add(_step5.value);
|
|
469
|
-
} catch (err) {
|
|
470
|
-
segment.e(err);
|
|
471
|
-
} finally {
|
|
472
|
-
segment.f();
|
|
473
|
-
}
|
|
474
|
-
return BigInt("0");
|
|
475
|
-
}
|
|
476
|
-
pathHistory.add(segment.id);
|
|
477
|
-
if (void 0 !== paths) return paths;
|
|
478
|
-
if (codePath.thrownSegments.includes(segment)) paths = BigInt("0");
|
|
479
|
-
else if (0 === segment.nextSegments.length) paths = BigInt("1");
|
|
480
|
-
else {
|
|
481
|
-
paths = BigInt("0");
|
|
482
|
-
_step5 = _createForOfIteratorHelper(segment.nextSegments);
|
|
483
|
-
var _step6;
|
|
484
|
-
try {
|
|
485
|
-
for (_step5.s(); !(_step6 = _step5.n()).done; )
|
|
486
|
-
paths += countPathsToEnd(_step6.value, pathHistory);
|
|
487
|
-
} catch (err$3) {
|
|
488
|
-
_step5.e(err$3);
|
|
489
|
-
} finally {
|
|
490
|
-
_step5.f();
|
|
491
|
-
}
|
|
492
|
-
}
|
|
493
|
-
cache.set(segment.id, paths);
|
|
494
|
-
return paths;
|
|
495
|
-
}
|
|
496
|
-
function shortestPathLengthToStart(segment) {
|
|
497
|
-
var cache = shortestPathLengthToStart.cache, length = cache.get(segment.id);
|
|
498
|
-
if (null === length) return Infinity;
|
|
499
|
-
if (void 0 !== length) return length;
|
|
500
|
-
cache.set(segment.id, null);
|
|
501
|
-
if (0 === segment.prevSegments.length) length = 1;
|
|
502
|
-
else {
|
|
503
|
-
length = Infinity;
|
|
504
|
-
var _iterator7 = _createForOfIteratorHelper(segment.prevSegments), _step7;
|
|
505
|
-
try {
|
|
506
|
-
for (_iterator7.s(); !(_step7 = _iterator7.n()).done; ) {
|
|
507
|
-
var prevLength = shortestPathLengthToStart(_step7.value);
|
|
508
|
-
prevLength < length && (length = prevLength);
|
|
509
|
-
}
|
|
510
|
-
} catch (err) {
|
|
511
|
-
_iterator7.e(err);
|
|
512
|
-
} finally {
|
|
513
|
-
_iterator7.f();
|
|
514
|
-
}
|
|
515
|
-
length += 1;
|
|
516
|
-
}
|
|
517
|
-
cache.set(segment.id, length);
|
|
518
|
-
return length;
|
|
519
|
-
}
|
|
520
|
-
var reactHooksMap = codePathReactHooksMapStack.pop();
|
|
521
|
-
if (0 !== reactHooksMap.size) {
|
|
522
|
-
var cyclic = /* @__PURE__ */ new Set();
|
|
523
|
-
countPathsFromStart.cache = /* @__PURE__ */ new Map();
|
|
524
|
-
countPathsToEnd.cache = /* @__PURE__ */ new Map();
|
|
525
|
-
shortestPathLengthToStart.cache = /* @__PURE__ */ new Map();
|
|
526
|
-
var allPathsFromStartToEnd = countPathsToEnd(
|
|
527
|
-
codePath.initialSegment
|
|
528
|
-
), codePathFunctionName = getFunctionName(codePathNode), isSomewhereInsideComponentOrHook = isInsideComponentOrHook(codePathNode), isDirectlyInsideComponentOrHook = codePathFunctionName ? isComponentName(codePathFunctionName) || isHook(codePathFunctionName) : isForwardRefCallback(codePathNode) || isMemoCallback(codePathNode), shortestFinalPathLength = Infinity, _iterator8 = _createForOfIteratorHelper(codePath.finalSegments), _step8;
|
|
529
|
-
try {
|
|
530
|
-
for (_iterator8.s(); !(_step8 = _iterator8.n()).done; ) {
|
|
531
|
-
var finalSegment = _step8.value;
|
|
532
|
-
if (finalSegment.reachable) {
|
|
533
|
-
var length$jscomp$0 = shortestPathLengthToStart(finalSegment);
|
|
534
|
-
length$jscomp$0 < shortestFinalPathLength && (shortestFinalPathLength = length$jscomp$0);
|
|
535
|
-
}
|
|
536
|
-
}
|
|
537
|
-
} catch (err) {
|
|
538
|
-
_iterator8.e(err);
|
|
539
|
-
} finally {
|
|
540
|
-
_iterator8.f();
|
|
541
|
-
}
|
|
542
|
-
reactHooksMap = _createForOfIteratorHelper(reactHooksMap);
|
|
543
|
-
var _step9;
|
|
544
|
-
try {
|
|
545
|
-
for (reactHooksMap.s(); !(_step9 = reactHooksMap.n()).done; ) {
|
|
546
|
-
var _step9$value = _step9.value, segment$jscomp$0 = _step9$value[0], reactHooks = _step9$value[1];
|
|
547
|
-
if (segment$jscomp$0.reachable) {
|
|
548
|
-
var possiblyHasEarlyReturn = 0 === segment$jscomp$0.nextSegments.length ? shortestFinalPathLength <= shortestPathLengthToStart(segment$jscomp$0) : shortestFinalPathLength < shortestPathLengthToStart(segment$jscomp$0), pathsFromStartToEnd = countPathsFromStart(segment$jscomp$0) * countPathsToEnd(segment$jscomp$0), cycled = cyclic.has(segment$jscomp$0.id), _iterator10 = _createForOfIteratorHelper(reactHooks), _step10;
|
|
549
|
-
try {
|
|
550
|
-
for (_iterator10.s(); !(_step10 = _iterator10.n()).done; ) {
|
|
551
|
-
var hook = _step10.value;
|
|
552
|
-
cycled && !isReactFunction(hook, "use") && context.report({
|
|
553
|
-
node: hook,
|
|
554
|
-
message: 'React Hook "' + getSource(hook) + '" may be executed more than once. Possibly because it is called in a loop. React Hooks must be called in the exact same order in every component render.'
|
|
555
|
-
});
|
|
556
|
-
if (isDirectlyInsideComponentOrHook) {
|
|
557
|
-
if (codePathNode.async && context.report({
|
|
558
|
-
node: hook,
|
|
559
|
-
message: 'React Hook "' + getSource(hook) + '" cannot be called in an async function.'
|
|
560
|
-
}), !cycled && pathsFromStartToEnd !== allPathsFromStartToEnd && !isReactFunction(hook, "use")) {
|
|
561
|
-
var message = 'React Hook "' + getSource(hook) + '" is called conditionally. React Hooks must be called in the exact same order in every component render.' + (possiblyHasEarlyReturn ? " Did you accidentally call a React Hook after an early return?" : "");
|
|
562
|
-
context.report({ node: hook, message });
|
|
563
|
-
}
|
|
564
|
-
} else if (codePathNode.parent && ("MethodDefinition" === codePathNode.parent.type || "ClassProperty" === codePathNode.parent.type) && codePathNode.parent.value === codePathNode) {
|
|
565
|
-
var message$4 = 'React Hook "' + getSource(hook) + '" cannot be called in a class component. React Hooks must be called in a React function component or a custom React Hook function.';
|
|
566
|
-
context.report({ node: hook, message: message$4 });
|
|
567
|
-
} else if (codePathFunctionName) {
|
|
568
|
-
var message$5 = 'React Hook "' + getSource(hook) + '" is called in function "' + (getSource(codePathFunctionName) + '" that is neither a React function component nor a custom React Hook function. React component names must start with an uppercase letter. React Hook names must start with the word "use".');
|
|
569
|
-
context.report({ node: hook, message: message$5 });
|
|
570
|
-
} else if ("Program" === codePathNode.type) {
|
|
571
|
-
var message$6 = 'React Hook "' + getSource(hook) + '" cannot be called at the top level. React Hooks must be called in a React function component or a custom React Hook function.';
|
|
572
|
-
context.report({ node: hook, message: message$6 });
|
|
573
|
-
} else if (isSomewhereInsideComponentOrHook && !isReactFunction(hook, "use")) {
|
|
574
|
-
var message$7 = 'React Hook "' + getSource(hook) + '" cannot be called inside a callback. React Hooks must be called in a React function component or a custom React Hook function.';
|
|
575
|
-
context.report({ node: hook, message: message$7 });
|
|
576
|
-
}
|
|
577
|
-
}
|
|
578
|
-
} catch (err$8) {
|
|
579
|
-
_iterator10.e(err$8);
|
|
580
|
-
} finally {
|
|
581
|
-
_iterator10.f();
|
|
582
|
-
}
|
|
583
|
-
}
|
|
584
|
-
}
|
|
585
|
-
} catch (err$9) {
|
|
586
|
-
reactHooksMap.e(err$9);
|
|
587
|
-
} finally {
|
|
588
|
-
reactHooksMap.f();
|
|
589
|
-
}
|
|
590
|
-
}
|
|
591
|
-
}, $jscomp$compprop0.CallExpression = function(node) {
|
|
592
|
-
if (isHook(node.callee)) {
|
|
593
|
-
var reactHooksMap = codePathReactHooksMapStack[codePathReactHooksMapStack.length - 1], codePathSegment = codePathSegmentStack[codePathSegmentStack.length - 1], reactHooks = reactHooksMap.get(codePathSegment);
|
|
594
|
-
reactHooks || (reactHooks = [], reactHooksMap.set(codePathSegment, reactHooks));
|
|
595
|
-
reactHooks.push(node.callee);
|
|
596
|
-
}
|
|
597
|
-
"Identifier" === node.callee.type && "useEffect" === node.callee.name && 0 < node.arguments.length && (lastEffect = node);
|
|
598
|
-
}, $jscomp$compprop0.Identifier = function(node) {
|
|
599
|
-
null == lastEffect && useEffectEventFunctions.has(node) && "CallExpression" !== node.parent.type && context.report({
|
|
600
|
-
node,
|
|
601
|
-
message: "`" + getSource(node) + '` is a function created with React Hook "useEffectEvent", and can only be called from the same component. They cannot be assigned to variables or passed down.'
|
|
602
|
-
});
|
|
603
|
-
}, $jscomp$compprop0["CallExpression:exit"] = function(node) {
|
|
604
|
-
node === lastEffect && (lastEffect = null);
|
|
605
|
-
}, $jscomp$compprop0.FunctionDeclaration = function(node) {
|
|
606
|
-
isInsideComponentOrHook(node) && recordAllUseEffectEventFunctions(getScope(node));
|
|
607
|
-
}, $jscomp$compprop0.ArrowFunctionExpression = function(node) {
|
|
608
|
-
isInsideComponentOrHook(node) && recordAllUseEffectEventFunctions(getScope(node));
|
|
609
|
-
}, $jscomp$compprop0;
|
|
610
|
-
}
|
|
611
|
-
},
|
|
612
|
-
"exhaustive-deps": {
|
|
613
|
-
meta: {
|
|
614
|
-
type: "suggestion",
|
|
615
|
-
docs: {
|
|
616
|
-
description: "verifies the list of dependencies for Hooks like useEffect and similar",
|
|
617
|
-
recommended: true,
|
|
618
|
-
url: "https://github.com/facebook/react/issues/14920"
|
|
619
|
-
},
|
|
620
|
-
fixable: "code",
|
|
621
|
-
hasSuggestions: true,
|
|
622
|
-
schema: [
|
|
623
|
-
{
|
|
624
|
-
type: "object",
|
|
625
|
-
additionalProperties: false,
|
|
626
|
-
enableDangerousAutofixThisMayCauseInfiniteLoops: false,
|
|
627
|
-
properties: {
|
|
628
|
-
additionalHooks: { type: "string" },
|
|
629
|
-
enableDangerousAutofixThisMayCauseInfiniteLoops: { type: "boolean" }
|
|
630
|
-
}
|
|
631
|
-
}
|
|
632
|
-
]
|
|
633
|
-
},
|
|
634
|
-
create: function(context) {
|
|
635
|
-
function reportProblem(problem) {
|
|
636
|
-
enableDangerousAutofixThisMayCauseInfiniteLoops && Array.isArray(problem.suggest) && 0 < problem.suggest.length && (problem.fix = problem.suggest[0].fix);
|
|
637
|
-
context.report(problem);
|
|
638
|
-
}
|
|
639
|
-
function memoizeWithWeakMap(fn, map) {
|
|
640
|
-
return function(arg) {
|
|
641
|
-
if (map.has(arg)) return map.get(arg);
|
|
642
|
-
var result = fn(arg);
|
|
643
|
-
map.set(arg, result);
|
|
644
|
-
return result;
|
|
645
|
-
};
|
|
646
|
-
}
|
|
647
|
-
function visitFunctionWithDependencies(node, declaredDependenciesNode, reactiveHook, reactiveHookName, isEffect) {
|
|
648
|
-
function gatherDependenciesRecursively(currentScope2) {
|
|
649
|
-
var _iterator2 = _createForOfIteratorHelper(currentScope2.references), _step2;
|
|
650
|
-
try {
|
|
651
|
-
for (_iterator2.s(); !(_step2 = _iterator2.n()).done; ) {
|
|
652
|
-
var reference = _step2.value;
|
|
653
|
-
if (reference.resolved && pureScopes.has(reference.resolved.scope)) {
|
|
654
|
-
var referenceNode = fastFindReferenceWithParent(
|
|
655
|
-
node,
|
|
656
|
-
reference.identifier
|
|
657
|
-
), dependencyNode = getDependency(referenceNode), dependency = analyzePropertyChain(
|
|
658
|
-
dependencyNode,
|
|
659
|
-
optionalChains
|
|
660
|
-
), JSCompiler_temp;
|
|
661
|
-
if (JSCompiler_temp = isEffect && "Identifier" === dependencyNode.type && ("MemberExpression" === dependencyNode.parent.type || "OptionalMemberExpression" === dependencyNode.parent.type) && !dependencyNode.parent.computed && "Identifier" === dependencyNode.parent.property.type && "current" === dependencyNode.parent.property.name) {
|
|
662
|
-
for (var curScope = reference.from, isInReturnedFunction = false; curScope.block !== node; )
|
|
663
|
-
"function" === curScope.type && (isInReturnedFunction = null != curScope.block.parent && "ReturnStatement" === curScope.block.parent.type), curScope = curScope.upper;
|
|
664
|
-
JSCompiler_temp = isInReturnedFunction;
|
|
665
|
-
}
|
|
666
|
-
JSCompiler_temp && currentRefsInEffectCleanup.set(dependency, {
|
|
667
|
-
reference,
|
|
668
|
-
dependencyNode
|
|
669
|
-
});
|
|
670
|
-
if ("TSTypeQuery" !== dependencyNode.parent.type && "TSTypeReference" !== dependencyNode.parent.type) {
|
|
671
|
-
var def = reference.resolved.defs[0];
|
|
672
|
-
if (null != def && (null == def.node || def.node.init !== node.parent) && "TypeParameter" !== def.type)
|
|
673
|
-
if (dependencies.has(dependency))
|
|
674
|
-
dependencies.get(dependency).references.push(reference);
|
|
675
|
-
else {
|
|
676
|
-
var resolved = reference.resolved, isStable = memoizedIsStableKnownHookValue(resolved) || memoizedIsFunctionWithoutCapturedValues(resolved);
|
|
677
|
-
dependencies.set(dependency, {
|
|
678
|
-
isStable,
|
|
679
|
-
references: [reference]
|
|
680
|
-
});
|
|
681
|
-
}
|
|
682
|
-
}
|
|
683
|
-
}
|
|
684
|
-
}
|
|
685
|
-
} catch (err) {
|
|
686
|
-
_iterator2.e(err);
|
|
687
|
-
} finally {
|
|
688
|
-
_iterator2.f();
|
|
689
|
-
}
|
|
690
|
-
currentScope2 = _createForOfIteratorHelper(currentScope2.childScopes);
|
|
691
|
-
var _step3;
|
|
692
|
-
try {
|
|
693
|
-
for (currentScope2.s(); !(_step3 = currentScope2.n()).done; )
|
|
694
|
-
gatherDependenciesRecursively(_step3.value);
|
|
695
|
-
} catch (err$12) {
|
|
696
|
-
currentScope2.e(err$12);
|
|
697
|
-
} finally {
|
|
698
|
-
currentScope2.f();
|
|
699
|
-
}
|
|
700
|
-
}
|
|
701
|
-
function formatDependency(path) {
|
|
702
|
-
path = path.split(".");
|
|
703
|
-
for (var finalPath = "", i = 0; i < path.length; i++) {
|
|
704
|
-
if (0 !== i) {
|
|
705
|
-
var pathSoFar = path.slice(0, i + 1).join(".");
|
|
706
|
-
pathSoFar = true === optionalChains.get(pathSoFar);
|
|
707
|
-
finalPath += pathSoFar ? "?." : ".";
|
|
708
|
-
}
|
|
709
|
-
finalPath += path[i];
|
|
710
|
-
}
|
|
711
|
-
return finalPath;
|
|
712
|
-
}
|
|
713
|
-
function getWarningMessage(deps, singlePrefix, label, fixVerb) {
|
|
714
|
-
return 0 === deps.size ? null : (1 < deps.size ? "" : singlePrefix + " ") + label + " " + (1 < deps.size ? "dependencies" : "dependency") + ": " + joinEnglish(
|
|
715
|
-
Array.from(deps).sort().map(function(name) {
|
|
716
|
-
return "'" + formatDependency(name) + "'";
|
|
717
|
-
})
|
|
718
|
-
) + (". Either " + fixVerb + " " + (1 < deps.size ? "them" : "it") + " or remove the dependency array.");
|
|
719
|
-
}
|
|
720
|
-
isEffect && node.async && reportProblem({
|
|
721
|
-
node,
|
|
722
|
-
message: "Effect callbacks are synchronous to prevent race conditions. Put the async function inside:\n\nuseEffect(() => {\n async function fetchData() {\n // You can await here\n const response = await MyAPI.getData(someId);\n // ...\n }\n fetchData();\n}, [someId]); // Or [] if effect doesn't need props or state\n\nLearn more about data fetching with Hooks: https://react.dev/link/hooks-data-fetching"
|
|
723
|
-
});
|
|
724
|
-
for (var scope = scopeManager.acquire(node), pureScopes = /* @__PURE__ */ new Set(), componentScope = null, currentScope = scope.upper; currentScope; ) {
|
|
725
|
-
pureScopes.add(currentScope);
|
|
726
|
-
if ("function" === currentScope.type) break;
|
|
727
|
-
currentScope = currentScope.upper;
|
|
728
|
-
}
|
|
729
|
-
if (currentScope) {
|
|
730
|
-
componentScope = currentScope;
|
|
731
|
-
var isArray = Array.isArray, memoizedIsStableKnownHookValue = memoizeWithWeakMap(function(resolved) {
|
|
732
|
-
if (!isArray(resolved.defs)) return false;
|
|
733
|
-
var def = resolved.defs[0];
|
|
734
|
-
if (null == def || "VariableDeclarator" !== def.node.type)
|
|
735
|
-
return false;
|
|
736
|
-
var init = def.node.init;
|
|
737
|
-
if (null == init) return false;
|
|
738
|
-
for (; "TSAsExpression" === init.type || "AsExpression" === init.type; )
|
|
739
|
-
init = init.expression;
|
|
740
|
-
var declaration = def.node.parent;
|
|
741
|
-
if (null == declaration && (fastFindReferenceWithParent(componentScope.block, def.node.id), declaration = def.node.parent, null == declaration))
|
|
742
|
-
return false;
|
|
743
|
-
if ("const" === declaration.kind && "Literal" === init.type && ("string" === typeof init.value || "number" === typeof init.value || null === init.value))
|
|
744
|
-
return true;
|
|
745
|
-
if ("CallExpression" !== init.type) return false;
|
|
746
|
-
init = init.callee;
|
|
747
|
-
"MemberExpression" !== init.type || "React" !== init.object.name || null == init.property || init.computed || (init = init.property);
|
|
748
|
-
if ("Identifier" !== init.type) return false;
|
|
749
|
-
def = def.node.id;
|
|
750
|
-
init = init.name;
|
|
751
|
-
if ("useRef" === init && "Identifier" === def.type) return true;
|
|
752
|
-
if ("useState" === init || "useReducer" === init || "useActionState" === init) {
|
|
753
|
-
if ("ArrayPattern" === def.type && 2 === def.elements.length && isArray(resolved.identifiers)) {
|
|
754
|
-
if (def.elements[1] === resolved.identifiers[0]) {
|
|
755
|
-
if ("useState" === init)
|
|
756
|
-
for (resolved = resolved.references, declaration = init = 0; declaration < resolved.length; declaration++) {
|
|
757
|
-
resolved[declaration].isWrite() && init++;
|
|
758
|
-
if (1 < init) return false;
|
|
759
|
-
setStateCallSites.set(
|
|
760
|
-
resolved[declaration].identifier,
|
|
761
|
-
def.elements[0]
|
|
762
|
-
);
|
|
763
|
-
}
|
|
764
|
-
return true;
|
|
765
|
-
}
|
|
766
|
-
if (def.elements[0] === resolved.identifiers[0] && "useState" === init)
|
|
767
|
-
for (resolved = resolved.references, def = 0; def < resolved.length; def++)
|
|
768
|
-
stateVariables.add(resolved[def].identifier);
|
|
769
|
-
}
|
|
770
|
-
} else if ("useTransition" === init && "ArrayPattern" === def.type && 2 === def.elements.length && Array.isArray(resolved.identifiers) && def.elements[1] === resolved.identifiers[0])
|
|
771
|
-
return true;
|
|
772
|
-
return false;
|
|
773
|
-
}, stableKnownValueCache), memoizedIsFunctionWithoutCapturedValues = memoizeWithWeakMap(
|
|
774
|
-
function(resolved) {
|
|
775
|
-
if (!isArray(resolved.defs)) return false;
|
|
776
|
-
resolved = resolved.defs[0];
|
|
777
|
-
if (null == resolved || null == resolved.node || null == resolved.node.id)
|
|
778
|
-
return false;
|
|
779
|
-
var fnNode = resolved.node, childScopes = componentScope.childScopes;
|
|
780
|
-
resolved = null;
|
|
781
|
-
var i;
|
|
782
|
-
for (i = 0; i < childScopes.length; i++) {
|
|
783
|
-
var childScope = childScopes[i], childScopeBlock = childScope.block;
|
|
784
|
-
if ("FunctionDeclaration" === fnNode.type && childScopeBlock === fnNode || "VariableDeclarator" === fnNode.type && childScopeBlock.parent === fnNode) {
|
|
785
|
-
resolved = childScope;
|
|
786
|
-
break;
|
|
787
|
-
}
|
|
788
|
-
}
|
|
789
|
-
if (null == resolved) return false;
|
|
790
|
-
for (i = 0; i < resolved.through.length; i++)
|
|
791
|
-
if (fnNode = resolved.through[i], null != fnNode.resolved && pureScopes.has(fnNode.resolved.scope) && !memoizedIsStableKnownHookValue(fnNode.resolved))
|
|
792
|
-
return false;
|
|
793
|
-
return true;
|
|
794
|
-
},
|
|
795
|
-
functionWithoutCapturedValueCache
|
|
796
|
-
), currentRefsInEffectCleanup = /* @__PURE__ */ new Map(), dependencies = /* @__PURE__ */ new Map(), optionalChains = /* @__PURE__ */ new Map();
|
|
797
|
-
gatherDependenciesRecursively(scope);
|
|
798
|
-
currentRefsInEffectCleanup.forEach(function(_ref, dependency) {
|
|
799
|
-
var dependencyNode = _ref.dependencyNode;
|
|
800
|
-
_ref = _ref.reference.resolved.references;
|
|
801
|
-
for (var foundCurrentAssignment = false, i = 0; i < _ref.length; i++) {
|
|
802
|
-
var parent = _ref[i].identifier.parent;
|
|
803
|
-
if (null != parent && "MemberExpression" === parent.type && !parent.computed && "Identifier" === parent.property.type && "current" === parent.property.name && "AssignmentExpression" === parent.parent.type && parent.parent.left === parent) {
|
|
804
|
-
foundCurrentAssignment = true;
|
|
805
|
-
break;
|
|
806
|
-
}
|
|
807
|
-
}
|
|
808
|
-
foundCurrentAssignment || reportProblem({
|
|
809
|
-
node: dependencyNode.parent.property,
|
|
810
|
-
message: "The ref value '" + dependency + ".current' will likely have changed by the time this effect cleanup function runs. If this ref points to a node rendered by React, copy '" + (dependency + ".current' to a variable inside the effect, and use that variable in the cleanup function.")
|
|
811
|
-
});
|
|
812
|
-
});
|
|
813
|
-
var staleAssignments = /* @__PURE__ */ new Set(), stableDependencies = /* @__PURE__ */ new Set();
|
|
814
|
-
dependencies.forEach(function(_ref2, key) {
|
|
815
|
-
var references = _ref2.references;
|
|
816
|
-
_ref2.isStable && stableDependencies.add(key);
|
|
817
|
-
references.forEach(function(reference) {
|
|
818
|
-
reference.writeExpr && (reference = reference.writeExpr, staleAssignments.has(key) || (staleAssignments.add(key), reportProblem({
|
|
819
|
-
node: reference,
|
|
820
|
-
message: "Assignments to the '" + key + "' variable from inside React Hook " + (getSource(reactiveHook) + " will be lost after each render. To preserve the value over time, store it in a useRef Hook and keep the mutable value in the '.current' property. Otherwise, you can move this variable directly inside ") + (getSource(reactiveHook) + ".")
|
|
821
|
-
})));
|
|
822
|
-
});
|
|
823
|
-
});
|
|
824
|
-
if (!(0 < staleAssignments.size))
|
|
825
|
-
if (declaredDependenciesNode) {
|
|
826
|
-
var declaredDependencies = [], externalDependencies = /* @__PURE__ */ new Set();
|
|
827
|
-
currentScope = "TSAsExpression" === declaredDependenciesNode.type && "ArrayExpression" === declaredDependenciesNode.expression.type;
|
|
828
|
-
"ArrayExpression" === declaredDependenciesNode.type || currentScope ? (currentScope ? declaredDependenciesNode.expression : declaredDependenciesNode).elements.forEach(function(declaredDependencyNode) {
|
|
829
|
-
if (null !== declaredDependencyNode)
|
|
830
|
-
if ("SpreadElement" === declaredDependencyNode.type)
|
|
831
|
-
reportProblem({
|
|
832
|
-
node: declaredDependencyNode,
|
|
833
|
-
message: "React Hook " + getSource(reactiveHook) + " has a spread element in its dependency array. This means we can't statically verify whether you've passed the correct dependencies."
|
|
834
|
-
});
|
|
835
|
-
else {
|
|
836
|
-
useEffectEventVariables.has(declaredDependencyNode) && reportProblem({
|
|
837
|
-
node: declaredDependencyNode,
|
|
838
|
-
message: "Functions returned from `useEffectEvent` must not be included in the dependency array. Remove `" + (getSource(declaredDependencyNode) + "` from the list."),
|
|
839
|
-
suggest: [
|
|
840
|
-
{
|
|
841
|
-
desc: "Remove the dependency `" + getSource(declaredDependencyNode) + "`",
|
|
842
|
-
fix: function(fixer) {
|
|
843
|
-
return fixer.removeRange(
|
|
844
|
-
declaredDependencyNode.range
|
|
845
|
-
);
|
|
846
|
-
}
|
|
847
|
-
}
|
|
848
|
-
]
|
|
849
|
-
});
|
|
850
|
-
try {
|
|
851
|
-
var declaredDependency = analyzePropertyChain(
|
|
852
|
-
declaredDependencyNode,
|
|
853
|
-
null
|
|
854
|
-
);
|
|
855
|
-
} catch (error) {
|
|
856
|
-
if (/Unsupported node type/.test(error.message)) {
|
|
857
|
-
"Literal" === declaredDependencyNode.type ? dependencies.has(declaredDependencyNode.value) ? reportProblem({
|
|
858
|
-
node: declaredDependencyNode,
|
|
859
|
-
message: "The " + declaredDependencyNode.raw + " literal is not a valid dependency because it never changes. Did you mean to include " + (declaredDependencyNode.value + " in the array instead?")
|
|
860
|
-
}) : reportProblem({
|
|
861
|
-
node: declaredDependencyNode,
|
|
862
|
-
message: "The " + declaredDependencyNode.raw + " literal is not a valid dependency because it never changes. You can safely remove it."
|
|
863
|
-
}) : reportProblem({
|
|
864
|
-
node: declaredDependencyNode,
|
|
865
|
-
message: "React Hook " + getSource(reactiveHook) + " has a complex expression in the dependency array. Extract it to a separate variable so it can be statically checked."
|
|
866
|
-
});
|
|
867
|
-
return;
|
|
868
|
-
}
|
|
869
|
-
throw error;
|
|
870
|
-
}
|
|
871
|
-
for (var maybeID = declaredDependencyNode; "MemberExpression" === maybeID.type || "OptionalMemberExpression" === maybeID.type || "ChainExpression" === maybeID.type; )
|
|
872
|
-
maybeID = maybeID.object || maybeID.expression.object;
|
|
873
|
-
var isDeclaredInComponent = !componentScope.through.some(function(ref) {
|
|
874
|
-
return ref.identifier === maybeID;
|
|
875
|
-
});
|
|
876
|
-
declaredDependencies.push({
|
|
877
|
-
key: declaredDependency,
|
|
878
|
-
node: declaredDependencyNode
|
|
879
|
-
});
|
|
880
|
-
isDeclaredInComponent || externalDependencies.add(declaredDependency);
|
|
881
|
-
}
|
|
882
|
-
}) : reportProblem({
|
|
883
|
-
node: declaredDependenciesNode,
|
|
884
|
-
message: "React Hook " + getSource(reactiveHook) + " was passed a dependency list that is not an array literal. This means we can't statically verify whether you've passed the correct dependencies."
|
|
885
|
-
});
|
|
886
|
-
var _collectRecommendatio2 = collectRecommendations({
|
|
887
|
-
dependencies,
|
|
888
|
-
declaredDependencies,
|
|
889
|
-
stableDependencies,
|
|
890
|
-
externalDependencies,
|
|
891
|
-
isEffect
|
|
892
|
-
});
|
|
893
|
-
currentScope = _collectRecommendatio2.unnecessaryDependencies;
|
|
894
|
-
var missingDependencies = _collectRecommendatio2.missingDependencies, duplicateDependencies = _collectRecommendatio2.duplicateDependencies, suggestedDeps = _collectRecommendatio2.suggestedDependencies;
|
|
895
|
-
if (0 === duplicateDependencies.size + missingDependencies.size + currentScope.size)
|
|
896
|
-
scanForConstructions({
|
|
897
|
-
declaredDependencies,
|
|
898
|
-
declaredDependenciesNode,
|
|
899
|
-
componentScope,
|
|
900
|
-
scope
|
|
901
|
-
}).forEach(function(_ref4) {
|
|
902
|
-
var construction = _ref4.construction, isUsedOutsideOfHook = _ref4.isUsedOutsideOfHook;
|
|
903
|
-
_ref4 = _ref4.depType;
|
|
904
|
-
var wrapperHook = "function" === _ref4 ? "useCallback" : "useMemo", constructionType = "function" === _ref4 ? "definition" : "initialization", defaultAdvice = "wrap the " + constructionType + " of '" + construction.name.name + "' in its own " + wrapperHook + "() Hook.";
|
|
905
|
-
defaultAdvice = "The '" + construction.name.name + "' " + _ref4 + " " + ("conditional" === _ref4 || "logical expression" === _ref4 ? "could make" : "makes") + " the dependencies of " + (reactiveHookName + " Hook (at line " + declaredDependenciesNode.loc.start.line + ") change on every render. ") + (isUsedOutsideOfHook ? "To fix this, " + defaultAdvice : "Move it inside the " + reactiveHookName + " callback. Alternatively, " + defaultAdvice);
|
|
906
|
-
var suggest;
|
|
907
|
-
isUsedOutsideOfHook && "Variable" === construction.type && "function" === _ref4 && (suggest = [
|
|
908
|
-
{
|
|
909
|
-
desc: "Wrap the " + constructionType + " of '" + construction.name.name + "' in its own " + wrapperHook + "() Hook.",
|
|
910
|
-
fix: function(fixer) {
|
|
911
|
-
var _ref5 = "useMemo" === wrapperHook ? ["useMemo(() => { return ", "; })"] : ["useCallback(", ")"], after = _ref5[1];
|
|
912
|
-
return [
|
|
913
|
-
fixer.insertTextBefore(
|
|
914
|
-
construction.node.init,
|
|
915
|
-
_ref5[0]
|
|
916
|
-
),
|
|
917
|
-
fixer.insertTextAfter(construction.node.init, after)
|
|
918
|
-
];
|
|
919
|
-
}
|
|
920
|
-
}
|
|
921
|
-
]);
|
|
922
|
-
reportProblem({
|
|
923
|
-
node: construction.node,
|
|
924
|
-
message: defaultAdvice,
|
|
925
|
-
suggest
|
|
926
|
-
});
|
|
927
|
-
});
|
|
928
|
-
else {
|
|
929
|
-
!isEffect && 0 < missingDependencies.size && (suggestedDeps = collectRecommendations({
|
|
930
|
-
dependencies,
|
|
931
|
-
declaredDependencies: [],
|
|
932
|
-
stableDependencies,
|
|
933
|
-
externalDependencies,
|
|
934
|
-
isEffect
|
|
935
|
-
}).suggestedDependencies);
|
|
936
|
-
(function() {
|
|
937
|
-
if (0 === declaredDependencies.length) return true;
|
|
938
|
-
var declaredDepKeys = declaredDependencies.map(
|
|
939
|
-
function(dep2) {
|
|
940
|
-
return dep2.key;
|
|
941
|
-
}
|
|
942
|
-
), sortedDeclaredDepKeys = declaredDepKeys.slice().sort();
|
|
943
|
-
return declaredDepKeys.join(",") === sortedDeclaredDepKeys.join(",");
|
|
944
|
-
})() && suggestedDeps.sort();
|
|
945
|
-
_collectRecommendatio2 = "";
|
|
946
|
-
if (0 < currentScope.size) {
|
|
947
|
-
var badRef = null;
|
|
948
|
-
Array.from(currentScope.keys()).forEach(function(key) {
|
|
949
|
-
null === badRef && key.endsWith(".current") && (badRef = key);
|
|
950
|
-
});
|
|
951
|
-
if (null !== badRef)
|
|
952
|
-
_collectRecommendatio2 = " Mutable values like '" + badRef + "' aren't valid dependencies because mutating them doesn't re-render the component.";
|
|
953
|
-
else if (0 < externalDependencies.size) {
|
|
954
|
-
var dep = Array.from(externalDependencies)[0];
|
|
955
|
-
scope.set.has(dep) || (_collectRecommendatio2 = " Outer scope values like '" + dep + "' aren't valid dependencies because mutating them doesn't re-render the component.");
|
|
956
|
-
}
|
|
957
|
-
}
|
|
958
|
-
if (!_collectRecommendatio2 && missingDependencies.has("props")) {
|
|
959
|
-
scope = dependencies.get("props");
|
|
960
|
-
if (null == scope) return;
|
|
961
|
-
scope = scope.references;
|
|
962
|
-
if (!Array.isArray(scope)) return;
|
|
963
|
-
dep = true;
|
|
964
|
-
for (var i$jscomp$0 = 0; i$jscomp$0 < scope.length; i$jscomp$0++) {
|
|
965
|
-
var id = fastFindReferenceWithParent(
|
|
966
|
-
componentScope.block,
|
|
967
|
-
scope[i$jscomp$0].identifier
|
|
968
|
-
);
|
|
969
|
-
if (!id) {
|
|
970
|
-
dep = false;
|
|
971
|
-
break;
|
|
972
|
-
}
|
|
973
|
-
id = id.parent;
|
|
974
|
-
if (null == id) {
|
|
975
|
-
dep = false;
|
|
976
|
-
break;
|
|
977
|
-
}
|
|
978
|
-
if ("MemberExpression" !== id.type && "OptionalMemberExpression" !== id.type) {
|
|
979
|
-
dep = false;
|
|
980
|
-
break;
|
|
981
|
-
}
|
|
982
|
-
}
|
|
983
|
-
dep && (_collectRecommendatio2 = " However, 'props' will change when *any* prop changes, so the preferred fix is to destructure the 'props' object outside of the " + (reactiveHookName + " call and refer to those specific props inside ") + (getSource(reactiveHook) + "."));
|
|
984
|
-
}
|
|
985
|
-
if (!_collectRecommendatio2 && 0 < missingDependencies.size) {
|
|
986
|
-
var missingCallbackDep = null;
|
|
987
|
-
missingDependencies.forEach(function(missingDep) {
|
|
988
|
-
if (!missingCallbackDep) {
|
|
989
|
-
var topScopeRef = componentScope.set.get(missingDep), usedDep = dependencies.get(missingDep);
|
|
990
|
-
if (usedDep.references[0].resolved === topScopeRef && (topScopeRef = topScopeRef.defs[0], null != topScopeRef && null != topScopeRef.name && "Parameter" === topScopeRef.type)) {
|
|
991
|
-
topScopeRef = false;
|
|
992
|
-
for (var id2, i$14 = 0; i$14 < usedDep.references.length; i$14++)
|
|
993
|
-
if (id2 = usedDep.references[i$14].identifier, null != id2 && null != id2.parent && ("CallExpression" === id2.parent.type || "OptionalCallExpression" === id2.parent.type) && id2.parent.callee === id2) {
|
|
994
|
-
topScopeRef = true;
|
|
995
|
-
break;
|
|
996
|
-
}
|
|
997
|
-
topScopeRef && (missingCallbackDep = missingDep);
|
|
998
|
-
}
|
|
999
|
-
}
|
|
1000
|
-
});
|
|
1001
|
-
null !== missingCallbackDep && (_collectRecommendatio2 = " If '" + missingCallbackDep + "' changes too often, find the parent component that defines it and wrap that definition in useCallback.");
|
|
1002
|
-
}
|
|
1003
|
-
if (!_collectRecommendatio2 && 0 < missingDependencies.size) {
|
|
1004
|
-
var setStateRecommendation = null;
|
|
1005
|
-
missingDependencies.forEach(function(missingDep) {
|
|
1006
|
-
if (null === setStateRecommendation)
|
|
1007
|
-
for (var references = dependencies.get(missingDep).references, id2, maybeCall, i$15 = 0; i$15 < references.length; i$15++) {
|
|
1008
|
-
id2 = references[i$15].identifier;
|
|
1009
|
-
for (maybeCall = id2.parent; null != maybeCall && maybeCall !== componentScope.block; ) {
|
|
1010
|
-
if ("CallExpression" === maybeCall.type) {
|
|
1011
|
-
var correspondingStateVariable = setStateCallSites.get(maybeCall.callee);
|
|
1012
|
-
if (null != correspondingStateVariable) {
|
|
1013
|
-
correspondingStateVariable.name === missingDep ? setStateRecommendation = {
|
|
1014
|
-
missingDep,
|
|
1015
|
-
setter: maybeCall.callee.name,
|
|
1016
|
-
form: "updater"
|
|
1017
|
-
} : stateVariables.has(id2) ? setStateRecommendation = {
|
|
1018
|
-
missingDep,
|
|
1019
|
-
setter: maybeCall.callee.name,
|
|
1020
|
-
form: "reducer"
|
|
1021
|
-
} : (id2 = references[i$15].resolved, null != id2 && (id2 = id2.defs[0], null != id2 && "Parameter" === id2.type && (setStateRecommendation = {
|
|
1022
|
-
missingDep,
|
|
1023
|
-
setter: maybeCall.callee.name,
|
|
1024
|
-
form: "inlineReducer"
|
|
1025
|
-
})));
|
|
1026
|
-
break;
|
|
1027
|
-
}
|
|
1028
|
-
}
|
|
1029
|
-
maybeCall = maybeCall.parent;
|
|
1030
|
-
}
|
|
1031
|
-
if (null !== setStateRecommendation) break;
|
|
1032
|
-
}
|
|
1033
|
-
});
|
|
1034
|
-
if (null !== setStateRecommendation)
|
|
1035
|
-
switch (setStateRecommendation.form) {
|
|
1036
|
-
case "reducer":
|
|
1037
|
-
_collectRecommendatio2 = " You can also replace multiple useState variables with useReducer if '" + (setStateRecommendation.setter + "' needs the current value of '") + (setStateRecommendation.missingDep + "'.");
|
|
1038
|
-
break;
|
|
1039
|
-
case "inlineReducer":
|
|
1040
|
-
_collectRecommendatio2 = " If '" + setStateRecommendation.setter + "' needs the current value of '" + (setStateRecommendation.missingDep + "', you can also switch to useReducer instead of useState and read '") + (setStateRecommendation.missingDep + "' in the reducer.");
|
|
1041
|
-
break;
|
|
1042
|
-
case "updater":
|
|
1043
|
-
_collectRecommendatio2 = " You can also do a functional update '" + setStateRecommendation.setter + "(" + setStateRecommendation.missingDep.slice(0, 1) + " => ...)' if you only need '" + setStateRecommendation.missingDep + "' in the '" + (setStateRecommendation.setter + "' call.");
|
|
1044
|
-
break;
|
|
1045
|
-
default:
|
|
1046
|
-
throw Error("Unknown case.");
|
|
1047
|
-
}
|
|
1048
|
-
}
|
|
1049
|
-
reportProblem({
|
|
1050
|
-
node: declaredDependenciesNode,
|
|
1051
|
-
message: "React Hook " + getSource(reactiveHook) + " has " + (getWarningMessage(
|
|
1052
|
-
missingDependencies,
|
|
1053
|
-
"a",
|
|
1054
|
-
"missing",
|
|
1055
|
-
"include"
|
|
1056
|
-
) || getWarningMessage(
|
|
1057
|
-
currentScope,
|
|
1058
|
-
"an",
|
|
1059
|
-
"unnecessary",
|
|
1060
|
-
"exclude"
|
|
1061
|
-
) || getWarningMessage(
|
|
1062
|
-
duplicateDependencies,
|
|
1063
|
-
"a",
|
|
1064
|
-
"duplicate",
|
|
1065
|
-
"omit"
|
|
1066
|
-
)) + _collectRecommendatio2,
|
|
1067
|
-
suggest: [
|
|
1068
|
-
{
|
|
1069
|
-
desc: "Update the dependencies array to be: [" + suggestedDeps.map(formatDependency).join(", ") + "]",
|
|
1070
|
-
fix: function(fixer) {
|
|
1071
|
-
return fixer.replaceText(
|
|
1072
|
-
declaredDependenciesNode,
|
|
1073
|
-
"[" + suggestedDeps.map(formatDependency).join(", ") + "]"
|
|
1074
|
-
);
|
|
1075
|
-
}
|
|
1076
|
-
}
|
|
1077
|
-
]
|
|
1078
|
-
});
|
|
1079
|
-
}
|
|
1080
|
-
} else {
|
|
1081
|
-
var setStateInsideEffectWithoutDeps = null;
|
|
1082
|
-
dependencies.forEach(function(_ref3, key) {
|
|
1083
|
-
setStateInsideEffectWithoutDeps || _ref3.references.forEach(function(reference) {
|
|
1084
|
-
if (!setStateInsideEffectWithoutDeps && setStateCallSites.has(reference.identifier)) {
|
|
1085
|
-
for (reference = reference.from; "function" !== reference.type; )
|
|
1086
|
-
reference = reference.upper;
|
|
1087
|
-
reference.block === node && (setStateInsideEffectWithoutDeps = key);
|
|
1088
|
-
}
|
|
1089
|
-
});
|
|
1090
|
-
});
|
|
1091
|
-
if (setStateInsideEffectWithoutDeps) {
|
|
1092
|
-
var suggestedDependencies$13 = collectRecommendations({
|
|
1093
|
-
dependencies,
|
|
1094
|
-
declaredDependencies: [],
|
|
1095
|
-
stableDependencies,
|
|
1096
|
-
externalDependencies: /* @__PURE__ */ new Set(),
|
|
1097
|
-
isEffect: true
|
|
1098
|
-
}).suggestedDependencies;
|
|
1099
|
-
reportProblem({
|
|
1100
|
-
node: reactiveHook,
|
|
1101
|
-
message: "React Hook " + reactiveHookName + " contains a call to '" + setStateInsideEffectWithoutDeps + "'. Without a list of dependencies, this can lead to an infinite chain of updates. To fix this, pass [" + suggestedDependencies$13.join(", ") + ("] as a second argument to the " + reactiveHookName + " Hook."),
|
|
1102
|
-
suggest: [
|
|
1103
|
-
{
|
|
1104
|
-
desc: "Add dependencies array: [" + suggestedDependencies$13.join(", ") + "]",
|
|
1105
|
-
fix: function(fixer) {
|
|
1106
|
-
return fixer.insertTextAfter(
|
|
1107
|
-
node,
|
|
1108
|
-
", [" + suggestedDependencies$13.join(", ") + "]"
|
|
1109
|
-
);
|
|
1110
|
-
}
|
|
1111
|
-
}
|
|
1112
|
-
]
|
|
1113
|
-
});
|
|
1114
|
-
}
|
|
1115
|
-
}
|
|
1116
|
-
}
|
|
1117
|
-
}
|
|
1118
|
-
var enableDangerousAutofixThisMayCauseInfiniteLoops = context.options && context.options[0] && context.options[0].enableDangerousAutofixThisMayCauseInfiniteLoops || false, options = {
|
|
1119
|
-
additionalHooks: context.options && context.options[0] && context.options[0].additionalHooks ? new RegExp(context.options[0].additionalHooks) : void 0,
|
|
1120
|
-
enableDangerousAutofixThisMayCauseInfiniteLoops
|
|
1121
|
-
}, getSource = "function" === typeof context.getSource ? function(node) {
|
|
1122
|
-
return context.getSource(node);
|
|
1123
|
-
} : function(node) {
|
|
1124
|
-
return context.sourceCode.getText(node);
|
|
1125
|
-
}, getScope = "function" === typeof context.getScope ? function() {
|
|
1126
|
-
return context.getScope();
|
|
1127
|
-
} : function(node) {
|
|
1128
|
-
return context.sourceCode.getScope(node);
|
|
1129
|
-
}, scopeManager = context.getSourceCode().scopeManager, setStateCallSites = /* @__PURE__ */ new WeakMap(), stateVariables = /* @__PURE__ */ new WeakSet(), stableKnownValueCache = /* @__PURE__ */ new WeakMap(), functionWithoutCapturedValueCache = /* @__PURE__ */ new WeakMap(), useEffectEventVariables = /* @__PURE__ */ new WeakSet();
|
|
1130
|
-
return {
|
|
1131
|
-
CallExpression: function(node) {
|
|
1132
|
-
var callbackIndex = getReactiveHookCallbackIndex(
|
|
1133
|
-
node.callee,
|
|
1134
|
-
options
|
|
1135
|
-
);
|
|
1136
|
-
if (-1 !== callbackIndex) {
|
|
1137
|
-
var callback = node.arguments[callbackIndex], reactiveHook = node.callee, reactiveHookName = getNodeWithoutReactNamespace(reactiveHook).name;
|
|
1138
|
-
node = node.arguments[callbackIndex + 1];
|
|
1139
|
-
var declaredDependenciesNode = !node || "Identifier" === node.type && "undefined" === node.name ? void 0 : node;
|
|
1140
|
-
node = /Effect($|[^a-z])/g.test(reactiveHookName);
|
|
1141
|
-
if (callback)
|
|
1142
|
-
if (declaredDependenciesNode || node) {
|
|
1143
|
-
switch (callback.type) {
|
|
1144
|
-
case "FunctionExpression":
|
|
1145
|
-
case "ArrowFunctionExpression":
|
|
1146
|
-
visitFunctionWithDependencies(
|
|
1147
|
-
callback,
|
|
1148
|
-
declaredDependenciesNode,
|
|
1149
|
-
reactiveHook,
|
|
1150
|
-
reactiveHookName,
|
|
1151
|
-
node
|
|
1152
|
-
);
|
|
1153
|
-
return;
|
|
1154
|
-
case "TSAsExpression":
|
|
1155
|
-
visitFunctionWithDependencies(
|
|
1156
|
-
callback.expression,
|
|
1157
|
-
declaredDependenciesNode,
|
|
1158
|
-
reactiveHook,
|
|
1159
|
-
reactiveHookName,
|
|
1160
|
-
node
|
|
1161
|
-
);
|
|
1162
|
-
return;
|
|
1163
|
-
case "Identifier":
|
|
1164
|
-
if (!declaredDependenciesNode || declaredDependenciesNode.elements && declaredDependenciesNode.elements.some(function(el) {
|
|
1165
|
-
return el && "Identifier" === el.type && el.name === callback.name;
|
|
1166
|
-
}))
|
|
1167
|
-
return;
|
|
1168
|
-
callbackIndex = getScope(callback).set.get(callback.name);
|
|
1169
|
-
if (null == callbackIndex || null == callbackIndex.defs)
|
|
1170
|
-
return;
|
|
1171
|
-
callbackIndex = callbackIndex.defs[0];
|
|
1172
|
-
if (!callbackIndex || !callbackIndex.node) break;
|
|
1173
|
-
if ("Variable" !== callbackIndex.type && "FunctionName" !== callbackIndex.type)
|
|
1174
|
-
break;
|
|
1175
|
-
switch (callbackIndex.node.type) {
|
|
1176
|
-
case "FunctionDeclaration":
|
|
1177
|
-
visitFunctionWithDependencies(
|
|
1178
|
-
callbackIndex.node,
|
|
1179
|
-
declaredDependenciesNode,
|
|
1180
|
-
reactiveHook,
|
|
1181
|
-
reactiveHookName,
|
|
1182
|
-
node
|
|
1183
|
-
);
|
|
1184
|
-
return;
|
|
1185
|
-
case "VariableDeclarator":
|
|
1186
|
-
if (callbackIndex = callbackIndex.node.init)
|
|
1187
|
-
switch (callbackIndex.type) {
|
|
1188
|
-
case "ArrowFunctionExpression":
|
|
1189
|
-
case "FunctionExpression":
|
|
1190
|
-
visitFunctionWithDependencies(
|
|
1191
|
-
callbackIndex,
|
|
1192
|
-
declaredDependenciesNode,
|
|
1193
|
-
reactiveHook,
|
|
1194
|
-
reactiveHookName,
|
|
1195
|
-
node
|
|
1196
|
-
);
|
|
1197
|
-
return;
|
|
1198
|
-
}
|
|
1199
|
-
}
|
|
1200
|
-
break;
|
|
1201
|
-
default:
|
|
1202
|
-
reportProblem({
|
|
1203
|
-
node: reactiveHook,
|
|
1204
|
-
message: "React Hook " + reactiveHookName + " received a function whose dependencies are unknown. Pass an inline function instead."
|
|
1205
|
-
});
|
|
1206
|
-
return;
|
|
1207
|
-
}
|
|
1208
|
-
reportProblem({
|
|
1209
|
-
node: reactiveHook,
|
|
1210
|
-
message: "React Hook " + reactiveHookName + " has a missing dependency: '" + callback.name + "'. Either include it or remove the dependency array.",
|
|
1211
|
-
suggest: [
|
|
1212
|
-
{
|
|
1213
|
-
desc: "Update the dependencies array to be: [" + callback.name + "]",
|
|
1214
|
-
fix: function(fixer) {
|
|
1215
|
-
return fixer.replaceText(
|
|
1216
|
-
declaredDependenciesNode,
|
|
1217
|
-
"[" + callback.name + "]"
|
|
1218
|
-
);
|
|
1219
|
-
}
|
|
1220
|
-
}
|
|
1221
|
-
]
|
|
1222
|
-
});
|
|
1223
|
-
} else
|
|
1224
|
-
"useMemo" !== reactiveHookName && "useCallback" !== reactiveHookName || reportProblem({
|
|
1225
|
-
node: reactiveHook,
|
|
1226
|
-
message: "React Hook " + reactiveHookName + " does nothing when called with only one argument. Did you forget to pass an array of dependencies?"
|
|
1227
|
-
});
|
|
1228
|
-
else
|
|
1229
|
-
reportProblem({
|
|
1230
|
-
node: reactiveHook,
|
|
1231
|
-
message: "React Hook " + reactiveHookName + " requires an effect callback. Did you forget to pass a callback to the hook?"
|
|
1232
|
-
});
|
|
1233
|
-
}
|
|
1234
|
-
}
|
|
1235
|
-
};
|
|
1236
|
-
}
|
|
1237
|
-
}
|
|
1238
|
-
};
|
|
1239
|
-
}
|
|
1240
|
-
});
|
|
1241
|
-
|
|
1242
|
-
// node_modules/.pnpm/eslint-plugin-react-hooks@5.1.0_eslint@9.19.0_jiti@2.4.2_/node_modules/eslint-plugin-react-hooks/cjs/eslint-plugin-react-hooks.development.js
|
|
1243
|
-
var require_eslint_plugin_react_hooks_development = __commonJS({
|
|
1244
|
-
"node_modules/.pnpm/eslint-plugin-react-hooks@5.1.0_eslint@9.19.0_jiti@2.4.2_/node_modules/eslint-plugin-react-hooks/cjs/eslint-plugin-react-hooks.development.js"(exports) {
|
|
1245
|
-
"use strict";
|
|
1246
|
-
init_esm_shims();
|
|
1247
|
-
"production" !== process.env.NODE_ENV && function() {
|
|
1248
|
-
function _unsupportedIterableToArray(o, minLen) {
|
|
1249
|
-
if (o) {
|
|
1250
|
-
if ("string" === typeof o) return _arrayLikeToArray(o, minLen);
|
|
1251
|
-
var n = Object.prototype.toString.call(o).slice(8, -1);
|
|
1252
|
-
"Object" === n && o.constructor && (n = o.constructor.name);
|
|
1253
|
-
if ("Map" === n || "Set" === n) return Array.from(o);
|
|
1254
|
-
if ("Arguments" === n || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))
|
|
1255
|
-
return _arrayLikeToArray(o, minLen);
|
|
1256
|
-
}
|
|
1257
|
-
}
|
|
1258
|
-
function _arrayLikeToArray(arr, len) {
|
|
1259
|
-
if (null == len || len > arr.length) len = arr.length;
|
|
1260
|
-
for (var i = 0, arr2 = Array(len); i < len; i++) arr2[i] = arr[i];
|
|
1261
|
-
return arr2;
|
|
1262
|
-
}
|
|
1263
|
-
function _createForOfIteratorHelper(o, allowArrayLike) {
|
|
1264
|
-
var it;
|
|
1265
|
-
if ("undefined" === typeof Symbol || null == o[Symbol.iterator]) {
|
|
1266
|
-
if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && "number" === typeof o.length) {
|
|
1267
|
-
it && (o = it);
|
|
1268
|
-
var i = 0;
|
|
1269
|
-
allowArrayLike = function() {
|
|
1270
|
-
};
|
|
1271
|
-
return {
|
|
1272
|
-
s: allowArrayLike,
|
|
1273
|
-
n: function() {
|
|
1274
|
-
return i >= o.length ? { done: true } : { done: false, value: o[i++] };
|
|
1275
|
-
},
|
|
1276
|
-
e: function(e) {
|
|
1277
|
-
throw e;
|
|
1278
|
-
},
|
|
1279
|
-
f: allowArrayLike
|
|
1280
|
-
};
|
|
1281
|
-
}
|
|
1282
|
-
throw new TypeError(
|
|
1283
|
-
"Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."
|
|
1284
|
-
);
|
|
1285
|
-
}
|
|
1286
|
-
var normalCompletion = true, didErr = false, err;
|
|
1287
|
-
return {
|
|
1288
|
-
s: function() {
|
|
1289
|
-
it = o[Symbol.iterator]();
|
|
1290
|
-
},
|
|
1291
|
-
n: function() {
|
|
1292
|
-
var step = it.next();
|
|
1293
|
-
normalCompletion = step.done;
|
|
1294
|
-
return step;
|
|
1295
|
-
},
|
|
1296
|
-
e: function(e) {
|
|
1297
|
-
didErr = true;
|
|
1298
|
-
err = e;
|
|
1299
|
-
},
|
|
1300
|
-
f: function() {
|
|
1301
|
-
try {
|
|
1302
|
-
normalCompletion || null == it.return || it.return();
|
|
1303
|
-
} finally {
|
|
1304
|
-
if (didErr) throw err;
|
|
1305
|
-
}
|
|
1306
|
-
}
|
|
1307
|
-
};
|
|
1308
|
-
}
|
|
1309
|
-
function isHook(node) {
|
|
1310
|
-
if ("Identifier" === node.type)
|
|
1311
|
-
return node = node.name, "use" === node || /^use[A-Z0-9]/.test(node);
|
|
1312
|
-
if ("MemberExpression" === node.type && !node.computed && isHook(node.property)) {
|
|
1313
|
-
node = node.object;
|
|
1314
|
-
var isPascalCaseNameSpace = /^[A-Z].*/;
|
|
1315
|
-
return "Identifier" === node.type && isPascalCaseNameSpace.test(node.name);
|
|
1316
|
-
}
|
|
1317
|
-
return false;
|
|
1318
|
-
}
|
|
1319
|
-
function isComponentName(node) {
|
|
1320
|
-
return "Identifier" === node.type && /^[A-Z]/.test(node.name);
|
|
1321
|
-
}
|
|
1322
|
-
function isReactFunction(node, functionName) {
|
|
1323
|
-
return node.name === functionName || "MemberExpression" === node.type && "React" === node.object.name && node.property.name === functionName;
|
|
1324
|
-
}
|
|
1325
|
-
function isForwardRefCallback(node) {
|
|
1326
|
-
return !!(node.parent && node.parent.callee && isReactFunction(node.parent.callee, "forwardRef"));
|
|
1327
|
-
}
|
|
1328
|
-
function isMemoCallback(node) {
|
|
1329
|
-
return !!(node.parent && node.parent.callee && isReactFunction(node.parent.callee, "memo"));
|
|
1330
|
-
}
|
|
1331
|
-
function isInsideComponentOrHook(node) {
|
|
1332
|
-
for (; node; ) {
|
|
1333
|
-
var functionName = getFunctionName(node);
|
|
1334
|
-
if (functionName && (isComponentName(functionName) || isHook(functionName)) || isForwardRefCallback(node) || isMemoCallback(node))
|
|
1335
|
-
return true;
|
|
1336
|
-
node = node.parent;
|
|
1337
|
-
}
|
|
1338
|
-
return false;
|
|
1339
|
-
}
|
|
1340
|
-
function getFunctionName(node) {
|
|
1341
|
-
if ("FunctionDeclaration" === node.type || "FunctionExpression" === node.type && node.id)
|
|
1342
|
-
return node.id;
|
|
1343
|
-
if ("FunctionExpression" === node.type || "ArrowFunctionExpression" === node.type)
|
|
1344
|
-
return "VariableDeclarator" === node.parent.type && node.parent.init === node ? node.parent.id : "AssignmentExpression" === node.parent.type && node.parent.right === node && "=" === node.parent.operator ? node.parent.left : "Property" !== node.parent.type || node.parent.value !== node || node.parent.computed ? "AssignmentPattern" !== node.parent.type || node.parent.right !== node || node.parent.computed ? void 0 : node.parent.left : node.parent.key;
|
|
1345
|
-
}
|
|
1346
|
-
function collectRecommendations(_ref6) {
|
|
1347
|
-
function createDepTree() {
|
|
1348
|
-
return {
|
|
1349
|
-
isUsed: false,
|
|
1350
|
-
isSatisfiedRecursively: false,
|
|
1351
|
-
isSubtreeUsed: false,
|
|
1352
|
-
children: /* @__PURE__ */ new Map()
|
|
1353
|
-
};
|
|
1354
|
-
}
|
|
1355
|
-
function getOrCreateNodeByPath(rootNode, path) {
|
|
1356
|
-
path = path.split(".");
|
|
1357
|
-
path = _createForOfIteratorHelper(path);
|
|
1358
|
-
var _step4;
|
|
1359
|
-
try {
|
|
1360
|
-
for (path.s(); !(_step4 = path.n()).done; ) {
|
|
1361
|
-
var key = _step4.value, child = rootNode.children.get(key);
|
|
1362
|
-
child || (child = createDepTree(), rootNode.children.set(key, child));
|
|
1363
|
-
rootNode = child;
|
|
1364
|
-
}
|
|
1365
|
-
} catch (err) {
|
|
1366
|
-
path.e(err);
|
|
1367
|
-
} finally {
|
|
1368
|
-
path.f();
|
|
1369
|
-
}
|
|
1370
|
-
return rootNode;
|
|
1371
|
-
}
|
|
1372
|
-
function markAllParentsByPath(rootNode, path, fn) {
|
|
1373
|
-
path = path.split(".");
|
|
1374
|
-
path = _createForOfIteratorHelper(path);
|
|
1375
|
-
var _step5;
|
|
1376
|
-
try {
|
|
1377
|
-
for (path.s(); !(_step5 = path.n()).done; ) {
|
|
1378
|
-
var child = rootNode.children.get(_step5.value);
|
|
1379
|
-
if (!child) break;
|
|
1380
|
-
fn(child);
|
|
1381
|
-
rootNode = child;
|
|
1382
|
-
}
|
|
1383
|
-
} catch (err) {
|
|
1384
|
-
path.e(err);
|
|
1385
|
-
} finally {
|
|
1386
|
-
path.f();
|
|
1387
|
-
}
|
|
1388
|
-
}
|
|
1389
|
-
function scanTreeRecursively(node, missingPaths, satisfyingPaths, keyToPath) {
|
|
1390
|
-
node.children.forEach(function(child, key) {
|
|
1391
|
-
var path = keyToPath(key);
|
|
1392
|
-
child.isSatisfiedRecursively ? child.isSubtreeUsed && satisfyingPaths.add(path) : child.isUsed ? missingPaths.add(path) : scanTreeRecursively(
|
|
1393
|
-
child,
|
|
1394
|
-
missingPaths,
|
|
1395
|
-
satisfyingPaths,
|
|
1396
|
-
function(childKey) {
|
|
1397
|
-
return path + "." + childKey;
|
|
1398
|
-
}
|
|
1399
|
-
);
|
|
1400
|
-
});
|
|
1401
|
-
}
|
|
1402
|
-
var dependencies = _ref6.dependencies, declaredDependencies = _ref6.declaredDependencies, stableDependencies = _ref6.stableDependencies, externalDependencies = _ref6.externalDependencies, isEffect = _ref6.isEffect, depTree = createDepTree();
|
|
1403
|
-
dependencies.forEach(function(_, key) {
|
|
1404
|
-
getOrCreateNodeByPath(depTree, key).isUsed = true;
|
|
1405
|
-
markAllParentsByPath(depTree, key, function(parent) {
|
|
1406
|
-
parent.isSubtreeUsed = true;
|
|
1407
|
-
});
|
|
1408
|
-
});
|
|
1409
|
-
declaredDependencies.forEach(function(_ref7) {
|
|
1410
|
-
getOrCreateNodeByPath(depTree, _ref7.key).isSatisfiedRecursively = true;
|
|
1411
|
-
});
|
|
1412
|
-
stableDependencies.forEach(function(key) {
|
|
1413
|
-
getOrCreateNodeByPath(depTree, key).isSatisfiedRecursively = true;
|
|
1414
|
-
});
|
|
1415
|
-
_ref6 = /* @__PURE__ */ new Set();
|
|
1416
|
-
var satisfyingDependencies = /* @__PURE__ */ new Set();
|
|
1417
|
-
scanTreeRecursively(
|
|
1418
|
-
depTree,
|
|
1419
|
-
_ref6,
|
|
1420
|
-
satisfyingDependencies,
|
|
1421
|
-
function(key) {
|
|
1422
|
-
return key;
|
|
1423
|
-
}
|
|
1424
|
-
);
|
|
1425
|
-
var suggestedDependencies = [], unnecessaryDependencies = /* @__PURE__ */ new Set(), duplicateDependencies = /* @__PURE__ */ new Set();
|
|
1426
|
-
declaredDependencies.forEach(function(_ref8) {
|
|
1427
|
-
_ref8 = _ref8.key;
|
|
1428
|
-
satisfyingDependencies.has(_ref8) ? -1 === suggestedDependencies.indexOf(_ref8) ? suggestedDependencies.push(_ref8) : duplicateDependencies.add(_ref8) : !isEffect || _ref8.endsWith(".current") || externalDependencies.has(_ref8) ? unnecessaryDependencies.add(_ref8) : -1 === suggestedDependencies.indexOf(_ref8) && suggestedDependencies.push(_ref8);
|
|
1429
|
-
});
|
|
1430
|
-
_ref6.forEach(function(key) {
|
|
1431
|
-
suggestedDependencies.push(key);
|
|
1432
|
-
});
|
|
1433
|
-
return {
|
|
1434
|
-
suggestedDependencies,
|
|
1435
|
-
unnecessaryDependencies,
|
|
1436
|
-
duplicateDependencies,
|
|
1437
|
-
missingDependencies: _ref6
|
|
1438
|
-
};
|
|
1439
|
-
}
|
|
1440
|
-
function getConstructionExpressionType(node) {
|
|
1441
|
-
switch (node.type) {
|
|
1442
|
-
case "ObjectExpression":
|
|
1443
|
-
return "object";
|
|
1444
|
-
case "ArrayExpression":
|
|
1445
|
-
return "array";
|
|
1446
|
-
case "ArrowFunctionExpression":
|
|
1447
|
-
case "FunctionExpression":
|
|
1448
|
-
return "function";
|
|
1449
|
-
case "ClassExpression":
|
|
1450
|
-
return "class";
|
|
1451
|
-
case "ConditionalExpression":
|
|
1452
|
-
if (null != getConstructionExpressionType(node.consequent) || null != getConstructionExpressionType(node.alternate))
|
|
1453
|
-
return "conditional";
|
|
1454
|
-
break;
|
|
1455
|
-
case "LogicalExpression":
|
|
1456
|
-
if (null != getConstructionExpressionType(node.left) || null != getConstructionExpressionType(node.right))
|
|
1457
|
-
return "logical expression";
|
|
1458
|
-
break;
|
|
1459
|
-
case "JSXFragment":
|
|
1460
|
-
return "JSX fragment";
|
|
1461
|
-
case "JSXElement":
|
|
1462
|
-
return "JSX element";
|
|
1463
|
-
case "AssignmentExpression":
|
|
1464
|
-
if (null != getConstructionExpressionType(node.right))
|
|
1465
|
-
return "assignment expression";
|
|
1466
|
-
break;
|
|
1467
|
-
case "NewExpression":
|
|
1468
|
-
return "object construction";
|
|
1469
|
-
case "Literal":
|
|
1470
|
-
if (node.value instanceof RegExp) return "regular expression";
|
|
1471
|
-
break;
|
|
1472
|
-
case "TypeCastExpression":
|
|
1473
|
-
case "AsExpression":
|
|
1474
|
-
case "TSAsExpression":
|
|
1475
|
-
return getConstructionExpressionType(node.expression);
|
|
1476
|
-
}
|
|
1477
|
-
return null;
|
|
1478
|
-
}
|
|
1479
|
-
function scanForConstructions(_ref9) {
|
|
1480
|
-
var declaredDependenciesNode = _ref9.declaredDependenciesNode, componentScope = _ref9.componentScope, scope = _ref9.scope;
|
|
1481
|
-
return _ref9.declaredDependencies.map(function(_ref10) {
|
|
1482
|
-
var key = _ref10.key;
|
|
1483
|
-
_ref10 = componentScope.variables.find(function(v) {
|
|
1484
|
-
return v.name === key;
|
|
1485
|
-
});
|
|
1486
|
-
if (null == _ref10) return null;
|
|
1487
|
-
var node = _ref10.defs[0];
|
|
1488
|
-
if (null == node) return null;
|
|
1489
|
-
if ("Variable" === node.type && "VariableDeclarator" === node.node.type && "Identifier" === node.node.id.type && null != node.node.init) {
|
|
1490
|
-
var constantExpressionType = getConstructionExpressionType(
|
|
1491
|
-
node.node.init
|
|
1492
|
-
);
|
|
1493
|
-
if (null != constantExpressionType)
|
|
1494
|
-
return [_ref10, constantExpressionType];
|
|
1495
|
-
}
|
|
1496
|
-
return "FunctionName" === node.type && "FunctionDeclaration" === node.node.type ? [_ref10, "function"] : "ClassName" === node.type && "ClassDeclaration" === node.node.type ? [_ref10, "class"] : null;
|
|
1497
|
-
}).filter(Boolean).map(function(_ref11) {
|
|
1498
|
-
var ref = _ref11[0];
|
|
1499
|
-
_ref11 = _ref11[1];
|
|
1500
|
-
var JSCompiler_temp_const = ref.defs[0];
|
|
1501
|
-
a: {
|
|
1502
|
-
for (var foundWriteExpr = false, i = 0; i < ref.references.length; i++) {
|
|
1503
|
-
var reference = ref.references[i];
|
|
1504
|
-
if (reference.writeExpr)
|
|
1505
|
-
if (foundWriteExpr) {
|
|
1506
|
-
ref = true;
|
|
1507
|
-
break a;
|
|
1508
|
-
} else {
|
|
1509
|
-
foundWriteExpr = true;
|
|
1510
|
-
continue;
|
|
1511
|
-
}
|
|
1512
|
-
for (var currentScope = reference.from; currentScope !== scope && null != currentScope; )
|
|
1513
|
-
currentScope = currentScope.upper;
|
|
1514
|
-
if (currentScope !== scope && !isAncestorNodeOf(
|
|
1515
|
-
declaredDependenciesNode,
|
|
1516
|
-
reference.identifier
|
|
1517
|
-
)) {
|
|
1518
|
-
ref = true;
|
|
1519
|
-
break a;
|
|
1520
|
-
}
|
|
1521
|
-
}
|
|
1522
|
-
ref = false;
|
|
1523
|
-
}
|
|
1524
|
-
return {
|
|
1525
|
-
construction: JSCompiler_temp_const,
|
|
1526
|
-
depType: _ref11,
|
|
1527
|
-
isUsedOutsideOfHook: ref
|
|
1528
|
-
};
|
|
1529
|
-
});
|
|
1530
|
-
}
|
|
1531
|
-
function getDependency(node) {
|
|
1532
|
-
return "MemberExpression" !== node.parent.type && "OptionalMemberExpression" !== node.parent.type || node.parent.object !== node || "current" === node.parent.property.name || node.parent.computed || null != node.parent.parent && ("CallExpression" === node.parent.parent.type || "OptionalCallExpression" === node.parent.parent.type) && node.parent.parent.callee === node.parent ? "MemberExpression" === node.type && node.parent && "AssignmentExpression" === node.parent.type && node.parent.left === node ? node.object : node : getDependency(node.parent);
|
|
1533
|
-
}
|
|
1534
|
-
function markNode(node, optionalChains, result) {
|
|
1535
|
-
optionalChains && (node.optional ? optionalChains.has(result) || optionalChains.set(result, true) : optionalChains.set(result, false));
|
|
1536
|
-
}
|
|
1537
|
-
function analyzePropertyChain(node, optionalChains) {
|
|
1538
|
-
if ("Identifier" === node.type || "JSXIdentifier" === node.type)
|
|
1539
|
-
return node = node.name, optionalChains && optionalChains.set(node, false), node;
|
|
1540
|
-
if ("MemberExpression" !== node.type || node.computed) {
|
|
1541
|
-
if ("OptionalMemberExpression" !== node.type || node.computed) {
|
|
1542
|
-
if ("ChainExpression" !== node.type || node.computed)
|
|
1543
|
-
throw Error("Unsupported node type: " + node.type);
|
|
1544
|
-
node = node.expression;
|
|
1545
|
-
if ("CallExpression" === node.type)
|
|
1546
|
-
throw Error("Unsupported node type: " + node.type);
|
|
1547
|
-
var _object2 = analyzePropertyChain(node.object, optionalChains), _property2 = analyzePropertyChain(node.property, null);
|
|
1548
|
-
_object2 = _object2 + "." + _property2;
|
|
1549
|
-
markNode(node, optionalChains, _object2);
|
|
1550
|
-
return _object2;
|
|
1551
|
-
}
|
|
1552
|
-
_object2 = analyzePropertyChain(node.object, optionalChains);
|
|
1553
|
-
_property2 = analyzePropertyChain(node.property, null);
|
|
1554
|
-
_object2 = _object2 + "." + _property2;
|
|
1555
|
-
markNode(node, optionalChains, _object2);
|
|
1556
|
-
return _object2;
|
|
1557
|
-
}
|
|
1558
|
-
_object2 = analyzePropertyChain(node.object, optionalChains);
|
|
1559
|
-
_property2 = analyzePropertyChain(node.property, null);
|
|
1560
|
-
_object2 = _object2 + "." + _property2;
|
|
1561
|
-
markNode(node, optionalChains, _object2);
|
|
1562
|
-
return _object2;
|
|
1563
|
-
}
|
|
1564
|
-
function getNodeWithoutReactNamespace(node) {
|
|
1565
|
-
return "MemberExpression" !== node.type || "Identifier" !== node.object.type || "React" !== node.object.name || "Identifier" !== node.property.type || node.computed ? node : node.property;
|
|
1566
|
-
}
|
|
1567
|
-
function getReactiveHookCallbackIndex(calleeNode, options) {
|
|
1568
|
-
var node = getNodeWithoutReactNamespace(calleeNode);
|
|
1569
|
-
if ("Identifier" !== node.type) return -1;
|
|
1570
|
-
switch (node.name) {
|
|
1571
|
-
case "useEffect":
|
|
1572
|
-
case "useLayoutEffect":
|
|
1573
|
-
case "useCallback":
|
|
1574
|
-
case "useMemo":
|
|
1575
|
-
return 0;
|
|
1576
|
-
case "useImperativeHandle":
|
|
1577
|
-
return 1;
|
|
1578
|
-
default:
|
|
1579
|
-
if (node === calleeNode && options && options.additionalHooks) {
|
|
1580
|
-
try {
|
|
1581
|
-
var name = analyzePropertyChain(node, null);
|
|
1582
|
-
} catch (error) {
|
|
1583
|
-
if (/Unsupported node type/.test(error.message)) return 0;
|
|
1584
|
-
throw error;
|
|
1585
|
-
}
|
|
1586
|
-
return options.additionalHooks.test(name) ? 0 : -1;
|
|
1587
|
-
}
|
|
1588
|
-
return -1;
|
|
1589
|
-
}
|
|
1590
|
-
}
|
|
1591
|
-
function fastFindReferenceWithParent(start, target) {
|
|
1592
|
-
for (var queue = [start], item = null; queue.length; ) {
|
|
1593
|
-
item = queue.shift();
|
|
1594
|
-
if (("Identifier" === item.type || "JSXIdentifier" === item.type) && item.type === target.type && item.name === target.name && item.range[0] === target.range[0] && item.range[1] === target.range[1])
|
|
1595
|
-
return item;
|
|
1596
|
-
if (isAncestorNodeOf(item, target)) {
|
|
1597
|
-
start = 0;
|
|
1598
|
-
for (var _Object$entries = Object.entries(item); start < _Object$entries.length; start++) {
|
|
1599
|
-
var _Object$entries$_i = _Object$entries[start], value = _Object$entries$_i[1];
|
|
1600
|
-
"parent" !== _Object$entries$_i[0] && (isNodeLike(value) ? (value.parent = item, queue.push(value)) : Array.isArray(value) && value.forEach(function(val) {
|
|
1601
|
-
isNodeLike(val) && (val.parent = item, queue.push(val));
|
|
1602
|
-
}));
|
|
1603
|
-
}
|
|
1604
|
-
}
|
|
1605
|
-
}
|
|
1606
|
-
return null;
|
|
1607
|
-
}
|
|
1608
|
-
function joinEnglish(arr) {
|
|
1609
|
-
for (var s = "", i = 0; i < arr.length; i++)
|
|
1610
|
-
s += arr[i], 0 === i && 2 === arr.length ? s += " and " : i === arr.length - 2 && 2 < arr.length ? s += ", and " : i < arr.length - 1 && (s += ", ");
|
|
1611
|
-
return s;
|
|
1612
|
-
}
|
|
1613
|
-
function isNodeLike(val) {
|
|
1614
|
-
return "object" === typeof val && null !== val && !Array.isArray(val) && "string" === typeof val.type;
|
|
1615
|
-
}
|
|
1616
|
-
function isAncestorNodeOf(a, b) {
|
|
1617
|
-
return a.range[0] <= b.range[0] && a.range[1] >= b.range[1];
|
|
1618
|
-
}
|
|
1619
|
-
exports.configs = {
|
|
1620
|
-
recommended: {
|
|
1621
|
-
plugins: ["react-hooks"],
|
|
1622
|
-
rules: {
|
|
1623
|
-
"react-hooks/rules-of-hooks": "error",
|
|
1624
|
-
"react-hooks/exhaustive-deps": "warn"
|
|
1625
|
-
}
|
|
1626
|
-
}
|
|
1627
|
-
};
|
|
1628
|
-
exports.rules = {
|
|
1629
|
-
"rules-of-hooks": {
|
|
1630
|
-
meta: {
|
|
1631
|
-
type: "problem",
|
|
1632
|
-
docs: {
|
|
1633
|
-
description: "enforces the Rules of Hooks",
|
|
1634
|
-
recommended: true,
|
|
1635
|
-
url: "https://reactjs.org/docs/hooks-rules.html"
|
|
1636
|
-
}
|
|
1637
|
-
},
|
|
1638
|
-
create: function(context) {
|
|
1639
|
-
function recordAllUseEffectEventFunctions(scope) {
|
|
1640
|
-
scope = _createForOfIteratorHelper(scope.references);
|
|
1641
|
-
try {
|
|
1642
|
-
for (scope.s(); !scope.n().done; ) ;
|
|
1643
|
-
} catch (err$0) {
|
|
1644
|
-
scope.e(err$0);
|
|
1645
|
-
} finally {
|
|
1646
|
-
scope.f();
|
|
1647
|
-
}
|
|
1648
|
-
}
|
|
1649
|
-
var lastEffect = null, codePathReactHooksMapStack = [], codePathSegmentStack = [], useEffectEventFunctions = /* @__PURE__ */ new WeakSet(), getSource = "function" === typeof context.getSource ? function(node) {
|
|
1650
|
-
return context.getSource(node);
|
|
1651
|
-
} : function(node) {
|
|
1652
|
-
return context.sourceCode.getText(node);
|
|
1653
|
-
}, getScope = "function" === typeof context.getScope ? function() {
|
|
1654
|
-
return context.getScope();
|
|
1655
|
-
} : function(node) {
|
|
1656
|
-
return context.sourceCode.getScope(node);
|
|
1657
|
-
};
|
|
1658
|
-
return {
|
|
1659
|
-
onCodePathSegmentStart: function(segment) {
|
|
1660
|
-
return codePathSegmentStack.push(segment);
|
|
1661
|
-
},
|
|
1662
|
-
onCodePathSegmentEnd: function() {
|
|
1663
|
-
return codePathSegmentStack.pop();
|
|
1664
|
-
},
|
|
1665
|
-
onCodePathStart: function() {
|
|
1666
|
-
return codePathReactHooksMapStack.push(/* @__PURE__ */ new Map());
|
|
1667
|
-
},
|
|
1668
|
-
onCodePathEnd: function(codePath, codePathNode) {
|
|
1669
|
-
function countPathsFromStart(segment, pathHistory) {
|
|
1670
|
-
var cache = countPathsFromStart.cache, paths = cache.get(segment.id);
|
|
1671
|
-
pathHistory = new Set(pathHistory);
|
|
1672
|
-
if (pathHistory.has(segment.id)) {
|
|
1673
|
-
cache = [].concat(pathHistory);
|
|
1674
|
-
segment = cache.slice(cache.indexOf(segment.id) + 1);
|
|
1675
|
-
segment = _createForOfIteratorHelper(segment);
|
|
1676
|
-
var _step3;
|
|
1677
|
-
try {
|
|
1678
|
-
for (segment.s(); !(_step3 = segment.n()).done; )
|
|
1679
|
-
cyclic.add(_step3.value);
|
|
1680
|
-
} catch (err) {
|
|
1681
|
-
segment.e(err);
|
|
1682
|
-
} finally {
|
|
1683
|
-
segment.f();
|
|
1684
|
-
}
|
|
1685
|
-
return BigInt("0");
|
|
1686
|
-
}
|
|
1687
|
-
pathHistory.add(segment.id);
|
|
1688
|
-
if (void 0 !== paths) return paths;
|
|
1689
|
-
if (codePath.thrownSegments.includes(segment))
|
|
1690
|
-
paths = BigInt("0");
|
|
1691
|
-
else if (0 === segment.prevSegments.length) paths = BigInt("1");
|
|
1692
|
-
else {
|
|
1693
|
-
paths = BigInt("0");
|
|
1694
|
-
_step3 = _createForOfIteratorHelper(segment.prevSegments);
|
|
1695
|
-
var _step4;
|
|
1696
|
-
try {
|
|
1697
|
-
for (_step3.s(); !(_step4 = _step3.n()).done; )
|
|
1698
|
-
paths += countPathsFromStart(_step4.value, pathHistory);
|
|
1699
|
-
} catch (err$1) {
|
|
1700
|
-
_step3.e(err$1);
|
|
1701
|
-
} finally {
|
|
1702
|
-
_step3.f();
|
|
1703
|
-
}
|
|
1704
|
-
}
|
|
1705
|
-
segment.reachable && paths === BigInt("0") ? cache.delete(segment.id) : cache.set(segment.id, paths);
|
|
1706
|
-
return paths;
|
|
1707
|
-
}
|
|
1708
|
-
function countPathsToEnd(segment, pathHistory) {
|
|
1709
|
-
var cache = countPathsToEnd.cache, paths = cache.get(segment.id);
|
|
1710
|
-
pathHistory = new Set(pathHistory);
|
|
1711
|
-
if (pathHistory.has(segment.id)) {
|
|
1712
|
-
cache = Array.from(pathHistory);
|
|
1713
|
-
segment = cache.slice(cache.indexOf(segment.id) - 1);
|
|
1714
|
-
segment = _createForOfIteratorHelper(segment);
|
|
1715
|
-
var _step5;
|
|
1716
|
-
try {
|
|
1717
|
-
for (segment.s(); !(_step5 = segment.n()).done; )
|
|
1718
|
-
cyclic.add(_step5.value);
|
|
1719
|
-
} catch (err) {
|
|
1720
|
-
segment.e(err);
|
|
1721
|
-
} finally {
|
|
1722
|
-
segment.f();
|
|
1723
|
-
}
|
|
1724
|
-
return BigInt("0");
|
|
1725
|
-
}
|
|
1726
|
-
pathHistory.add(segment.id);
|
|
1727
|
-
if (void 0 !== paths) return paths;
|
|
1728
|
-
if (codePath.thrownSegments.includes(segment))
|
|
1729
|
-
paths = BigInt("0");
|
|
1730
|
-
else if (0 === segment.nextSegments.length) paths = BigInt("1");
|
|
1731
|
-
else {
|
|
1732
|
-
paths = BigInt("0");
|
|
1733
|
-
_step5 = _createForOfIteratorHelper(segment.nextSegments);
|
|
1734
|
-
var _step6;
|
|
1735
|
-
try {
|
|
1736
|
-
for (_step5.s(); !(_step6 = _step5.n()).done; )
|
|
1737
|
-
paths += countPathsToEnd(_step6.value, pathHistory);
|
|
1738
|
-
} catch (err$2) {
|
|
1739
|
-
_step5.e(err$2);
|
|
1740
|
-
} finally {
|
|
1741
|
-
_step5.f();
|
|
1742
|
-
}
|
|
1743
|
-
}
|
|
1744
|
-
cache.set(segment.id, paths);
|
|
1745
|
-
return paths;
|
|
1746
|
-
}
|
|
1747
|
-
function shortestPathLengthToStart(segment) {
|
|
1748
|
-
var cache = shortestPathLengthToStart.cache, length = cache.get(segment.id);
|
|
1749
|
-
if (null === length) return Infinity;
|
|
1750
|
-
if (void 0 !== length) return length;
|
|
1751
|
-
cache.set(segment.id, null);
|
|
1752
|
-
if (0 === segment.prevSegments.length) length = 1;
|
|
1753
|
-
else {
|
|
1754
|
-
length = Infinity;
|
|
1755
|
-
var _iterator7 = _createForOfIteratorHelper(
|
|
1756
|
-
segment.prevSegments
|
|
1757
|
-
), _step7;
|
|
1758
|
-
try {
|
|
1759
|
-
for (_iterator7.s(); !(_step7 = _iterator7.n()).done; ) {
|
|
1760
|
-
var prevLength = shortestPathLengthToStart(_step7.value);
|
|
1761
|
-
prevLength < length && (length = prevLength);
|
|
1762
|
-
}
|
|
1763
|
-
} catch (err) {
|
|
1764
|
-
_iterator7.e(err);
|
|
1765
|
-
} finally {
|
|
1766
|
-
_iterator7.f();
|
|
1767
|
-
}
|
|
1768
|
-
length += 1;
|
|
1769
|
-
}
|
|
1770
|
-
cache.set(segment.id, length);
|
|
1771
|
-
return length;
|
|
1772
|
-
}
|
|
1773
|
-
var reactHooksMap = codePathReactHooksMapStack.pop();
|
|
1774
|
-
if (0 !== reactHooksMap.size) {
|
|
1775
|
-
var cyclic = /* @__PURE__ */ new Set();
|
|
1776
|
-
countPathsFromStart.cache = /* @__PURE__ */ new Map();
|
|
1777
|
-
countPathsToEnd.cache = /* @__PURE__ */ new Map();
|
|
1778
|
-
shortestPathLengthToStart.cache = /* @__PURE__ */ new Map();
|
|
1779
|
-
var allPathsFromStartToEnd = countPathsToEnd(
|
|
1780
|
-
codePath.initialSegment
|
|
1781
|
-
), codePathFunctionName = getFunctionName(codePathNode), isSomewhereInsideComponentOrHook = isInsideComponentOrHook(codePathNode), isDirectlyInsideComponentOrHook = codePathFunctionName ? isComponentName(codePathFunctionName) || isHook(codePathFunctionName) : isForwardRefCallback(codePathNode) || isMemoCallback(codePathNode), shortestFinalPathLength = Infinity, _iterator8 = _createForOfIteratorHelper(
|
|
1782
|
-
codePath.finalSegments
|
|
1783
|
-
), _step8;
|
|
1784
|
-
try {
|
|
1785
|
-
for (_iterator8.s(); !(_step8 = _iterator8.n()).done; ) {
|
|
1786
|
-
var finalSegment = _step8.value;
|
|
1787
|
-
if (finalSegment.reachable) {
|
|
1788
|
-
var length$jscomp$0 = shortestPathLengthToStart(finalSegment);
|
|
1789
|
-
length$jscomp$0 < shortestFinalPathLength && (shortestFinalPathLength = length$jscomp$0);
|
|
1790
|
-
}
|
|
1791
|
-
}
|
|
1792
|
-
} catch (err) {
|
|
1793
|
-
_iterator8.e(err);
|
|
1794
|
-
} finally {
|
|
1795
|
-
_iterator8.f();
|
|
1796
|
-
}
|
|
1797
|
-
reactHooksMap = _createForOfIteratorHelper(reactHooksMap);
|
|
1798
|
-
var _step9;
|
|
1799
|
-
try {
|
|
1800
|
-
for (reactHooksMap.s(); !(_step9 = reactHooksMap.n()).done; ) {
|
|
1801
|
-
var _step9$value = _step9.value, segment$jscomp$0 = _step9$value[0], reactHooks = _step9$value[1];
|
|
1802
|
-
if (segment$jscomp$0.reachable) {
|
|
1803
|
-
var possiblyHasEarlyReturn = 0 === segment$jscomp$0.nextSegments.length ? shortestFinalPathLength <= shortestPathLengthToStart(segment$jscomp$0) : shortestFinalPathLength < shortestPathLengthToStart(segment$jscomp$0), pathsFromStartToEnd = countPathsFromStart(segment$jscomp$0) * countPathsToEnd(segment$jscomp$0), cycled = cyclic.has(segment$jscomp$0.id), _iterator10 = _createForOfIteratorHelper(reactHooks), _step10;
|
|
1804
|
-
try {
|
|
1805
|
-
for (_iterator10.s(); !(_step10 = _iterator10.n()).done; ) {
|
|
1806
|
-
var hook = _step10.value;
|
|
1807
|
-
cycled && !isReactFunction(hook, "use") && context.report({
|
|
1808
|
-
node: hook,
|
|
1809
|
-
message: 'React Hook "' + getSource(hook) + '" may be executed more than once. Possibly because it is called in a loop. React Hooks must be called in the exact same order in every component render.'
|
|
1810
|
-
});
|
|
1811
|
-
if (isDirectlyInsideComponentOrHook) {
|
|
1812
|
-
if (codePathNode.async && context.report({
|
|
1813
|
-
node: hook,
|
|
1814
|
-
message: 'React Hook "' + getSource(hook) + '" cannot be called in an async function.'
|
|
1815
|
-
}), !cycled && pathsFromStartToEnd !== allPathsFromStartToEnd && !isReactFunction(hook, "use")) {
|
|
1816
|
-
var message = 'React Hook "' + getSource(hook) + '" is called conditionally. React Hooks must be called in the exact same order in every component render.' + (possiblyHasEarlyReturn ? " Did you accidentally call a React Hook after an early return?" : "");
|
|
1817
|
-
context.report({ node: hook, message });
|
|
1818
|
-
}
|
|
1819
|
-
} else if (codePathNode.parent && ("MethodDefinition" === codePathNode.parent.type || "ClassProperty" === codePathNode.parent.type) && codePathNode.parent.value === codePathNode) {
|
|
1820
|
-
var _message = 'React Hook "' + getSource(hook) + '" cannot be called in a class component. React Hooks must be called in a React function component or a custom React Hook function.';
|
|
1821
|
-
context.report({ node: hook, message: _message });
|
|
1822
|
-
} else if (codePathFunctionName) {
|
|
1823
|
-
var _message2 = 'React Hook "' + getSource(hook) + '" is called in function "' + (getSource(codePathFunctionName) + '" that is neither a React function component nor a custom React Hook function. React component names must start with an uppercase letter. React Hook names must start with the word "use".');
|
|
1824
|
-
context.report({ node: hook, message: _message2 });
|
|
1825
|
-
} else if ("Program" === codePathNode.type) {
|
|
1826
|
-
var _message3 = 'React Hook "' + getSource(hook) + '" cannot be called at the top level. React Hooks must be called in a React function component or a custom React Hook function.';
|
|
1827
|
-
context.report({ node: hook, message: _message3 });
|
|
1828
|
-
} else if (isSomewhereInsideComponentOrHook && !isReactFunction(hook, "use")) {
|
|
1829
|
-
var _message4 = 'React Hook "' + getSource(hook) + '" cannot be called inside a callback. React Hooks must be called in a React function component or a custom React Hook function.';
|
|
1830
|
-
context.report({ node: hook, message: _message4 });
|
|
1831
|
-
}
|
|
1832
|
-
}
|
|
1833
|
-
} catch (err$3) {
|
|
1834
|
-
_iterator10.e(err$3);
|
|
1835
|
-
} finally {
|
|
1836
|
-
_iterator10.f();
|
|
1837
|
-
}
|
|
1838
|
-
}
|
|
1839
|
-
}
|
|
1840
|
-
} catch (err$4) {
|
|
1841
|
-
reactHooksMap.e(err$4);
|
|
1842
|
-
} finally {
|
|
1843
|
-
reactHooksMap.f();
|
|
1844
|
-
}
|
|
1845
|
-
}
|
|
1846
|
-
},
|
|
1847
|
-
CallExpression: function(node) {
|
|
1848
|
-
if (isHook(node.callee)) {
|
|
1849
|
-
var reactHooksMap = codePathReactHooksMapStack[codePathReactHooksMapStack.length - 1], codePathSegment = codePathSegmentStack[codePathSegmentStack.length - 1], reactHooks = reactHooksMap.get(codePathSegment);
|
|
1850
|
-
reactHooks || (reactHooks = [], reactHooksMap.set(codePathSegment, reactHooks));
|
|
1851
|
-
reactHooks.push(node.callee);
|
|
1852
|
-
}
|
|
1853
|
-
"Identifier" === node.callee.type && "useEffect" === node.callee.name && 0 < node.arguments.length && (lastEffect = node);
|
|
1854
|
-
},
|
|
1855
|
-
Identifier: function(node) {
|
|
1856
|
-
null == lastEffect && useEffectEventFunctions.has(node) && "CallExpression" !== node.parent.type && context.report({
|
|
1857
|
-
node,
|
|
1858
|
-
message: "`" + getSource(node) + '` is a function created with React Hook "useEffectEvent", and can only be called from the same component. They cannot be assigned to variables or passed down.'
|
|
1859
|
-
});
|
|
1860
|
-
},
|
|
1861
|
-
"CallExpression:exit": function(node) {
|
|
1862
|
-
node === lastEffect && (lastEffect = null);
|
|
1863
|
-
},
|
|
1864
|
-
FunctionDeclaration: function(node) {
|
|
1865
|
-
isInsideComponentOrHook(node) && recordAllUseEffectEventFunctions(getScope(node));
|
|
1866
|
-
},
|
|
1867
|
-
ArrowFunctionExpression: function(node) {
|
|
1868
|
-
isInsideComponentOrHook(node) && recordAllUseEffectEventFunctions(getScope(node));
|
|
1869
|
-
}
|
|
1870
|
-
};
|
|
1871
|
-
}
|
|
1872
|
-
},
|
|
1873
|
-
"exhaustive-deps": {
|
|
1874
|
-
meta: {
|
|
1875
|
-
type: "suggestion",
|
|
1876
|
-
docs: {
|
|
1877
|
-
description: "verifies the list of dependencies for Hooks like useEffect and similar",
|
|
1878
|
-
recommended: true,
|
|
1879
|
-
url: "https://github.com/facebook/react/issues/14920"
|
|
1880
|
-
},
|
|
1881
|
-
fixable: "code",
|
|
1882
|
-
hasSuggestions: true,
|
|
1883
|
-
schema: [
|
|
1884
|
-
{
|
|
1885
|
-
type: "object",
|
|
1886
|
-
additionalProperties: false,
|
|
1887
|
-
enableDangerousAutofixThisMayCauseInfiniteLoops: false,
|
|
1888
|
-
properties: {
|
|
1889
|
-
additionalHooks: { type: "string" },
|
|
1890
|
-
enableDangerousAutofixThisMayCauseInfiniteLoops: {
|
|
1891
|
-
type: "boolean"
|
|
1892
|
-
}
|
|
1893
|
-
}
|
|
1894
|
-
}
|
|
1895
|
-
]
|
|
1896
|
-
},
|
|
1897
|
-
create: function(context) {
|
|
1898
|
-
function reportProblem(problem) {
|
|
1899
|
-
enableDangerousAutofixThisMayCauseInfiniteLoops && Array.isArray(problem.suggest) && 0 < problem.suggest.length && (problem.fix = problem.suggest[0].fix);
|
|
1900
|
-
context.report(problem);
|
|
1901
|
-
}
|
|
1902
|
-
function memoizeWithWeakMap(fn, map) {
|
|
1903
|
-
return function(arg) {
|
|
1904
|
-
if (map.has(arg)) return map.get(arg);
|
|
1905
|
-
var result = fn(arg);
|
|
1906
|
-
map.set(arg, result);
|
|
1907
|
-
return result;
|
|
1908
|
-
};
|
|
1909
|
-
}
|
|
1910
|
-
function visitFunctionWithDependencies(node, declaredDependenciesNode, reactiveHook, reactiveHookName, isEffect) {
|
|
1911
|
-
function gatherDependenciesRecursively(currentScope2) {
|
|
1912
|
-
var _iterator2 = _createForOfIteratorHelper(
|
|
1913
|
-
currentScope2.references
|
|
1914
|
-
), _step2;
|
|
1915
|
-
try {
|
|
1916
|
-
for (_iterator2.s(); !(_step2 = _iterator2.n()).done; ) {
|
|
1917
|
-
var reference = _step2.value;
|
|
1918
|
-
if (reference.resolved && pureScopes.has(reference.resolved.scope)) {
|
|
1919
|
-
var referenceNode = fastFindReferenceWithParent(
|
|
1920
|
-
node,
|
|
1921
|
-
reference.identifier
|
|
1922
|
-
), dependencyNode = getDependency(referenceNode), dependency = analyzePropertyChain(
|
|
1923
|
-
dependencyNode,
|
|
1924
|
-
optionalChains
|
|
1925
|
-
), JSCompiler_temp;
|
|
1926
|
-
if (JSCompiler_temp = isEffect && "Identifier" === dependencyNode.type && ("MemberExpression" === dependencyNode.parent.type || "OptionalMemberExpression" === dependencyNode.parent.type) && !dependencyNode.parent.computed && "Identifier" === dependencyNode.parent.property.type && "current" === dependencyNode.parent.property.name) {
|
|
1927
|
-
for (var curScope = reference.from, isInReturnedFunction = false; curScope.block !== node; )
|
|
1928
|
-
"function" === curScope.type && (isInReturnedFunction = null != curScope.block.parent && "ReturnStatement" === curScope.block.parent.type), curScope = curScope.upper;
|
|
1929
|
-
JSCompiler_temp = isInReturnedFunction;
|
|
1930
|
-
}
|
|
1931
|
-
JSCompiler_temp && currentRefsInEffectCleanup.set(dependency, {
|
|
1932
|
-
reference,
|
|
1933
|
-
dependencyNode
|
|
1934
|
-
});
|
|
1935
|
-
if ("TSTypeQuery" !== dependencyNode.parent.type && "TSTypeReference" !== dependencyNode.parent.type) {
|
|
1936
|
-
var def = reference.resolved.defs[0];
|
|
1937
|
-
if (null != def && (null == def.node || def.node.init !== node.parent) && "TypeParameter" !== def.type)
|
|
1938
|
-
if (dependencies.has(dependency))
|
|
1939
|
-
dependencies.get(dependency).references.push(reference);
|
|
1940
|
-
else {
|
|
1941
|
-
var resolved = reference.resolved, isStable = memoizedIsStableKnownHookValue(resolved) || memoizedIsFunctionWithoutCapturedValues(resolved);
|
|
1942
|
-
dependencies.set(dependency, {
|
|
1943
|
-
isStable,
|
|
1944
|
-
references: [reference]
|
|
1945
|
-
});
|
|
1946
|
-
}
|
|
1947
|
-
}
|
|
1948
|
-
}
|
|
1949
|
-
}
|
|
1950
|
-
} catch (err) {
|
|
1951
|
-
_iterator2.e(err);
|
|
1952
|
-
} finally {
|
|
1953
|
-
_iterator2.f();
|
|
1954
|
-
}
|
|
1955
|
-
currentScope2 = _createForOfIteratorHelper(
|
|
1956
|
-
currentScope2.childScopes
|
|
1957
|
-
);
|
|
1958
|
-
var _step3;
|
|
1959
|
-
try {
|
|
1960
|
-
for (currentScope2.s(); !(_step3 = currentScope2.n()).done; )
|
|
1961
|
-
gatherDependenciesRecursively(_step3.value);
|
|
1962
|
-
} catch (err$5) {
|
|
1963
|
-
currentScope2.e(err$5);
|
|
1964
|
-
} finally {
|
|
1965
|
-
currentScope2.f();
|
|
1966
|
-
}
|
|
1967
|
-
}
|
|
1968
|
-
function formatDependency(path) {
|
|
1969
|
-
path = path.split(".");
|
|
1970
|
-
for (var finalPath = "", i = 0; i < path.length; i++) {
|
|
1971
|
-
if (0 !== i) {
|
|
1972
|
-
var pathSoFar = path.slice(0, i + 1).join(".");
|
|
1973
|
-
pathSoFar = true === optionalChains.get(pathSoFar);
|
|
1974
|
-
finalPath += pathSoFar ? "?." : ".";
|
|
1975
|
-
}
|
|
1976
|
-
finalPath += path[i];
|
|
1977
|
-
}
|
|
1978
|
-
return finalPath;
|
|
1979
|
-
}
|
|
1980
|
-
function getWarningMessage(deps, singlePrefix, label, fixVerb) {
|
|
1981
|
-
return 0 === deps.size ? null : (1 < deps.size ? "" : singlePrefix + " ") + label + " " + (1 < deps.size ? "dependencies" : "dependency") + ": " + joinEnglish(
|
|
1982
|
-
Array.from(deps).sort().map(function(name) {
|
|
1983
|
-
return "'" + formatDependency(name) + "'";
|
|
1984
|
-
})
|
|
1985
|
-
) + (". Either " + fixVerb + " " + (1 < deps.size ? "them" : "it") + " or remove the dependency array.");
|
|
1986
|
-
}
|
|
1987
|
-
isEffect && node.async && reportProblem({
|
|
1988
|
-
node,
|
|
1989
|
-
message: "Effect callbacks are synchronous to prevent race conditions. Put the async function inside:\n\nuseEffect(() => {\n async function fetchData() {\n // You can await here\n const response = await MyAPI.getData(someId);\n // ...\n }\n fetchData();\n}, [someId]); // Or [] if effect doesn't need props or state\n\nLearn more about data fetching with Hooks: https://react.dev/link/hooks-data-fetching"
|
|
1990
|
-
});
|
|
1991
|
-
for (var scope = scopeManager.acquire(node), pureScopes = /* @__PURE__ */ new Set(), componentScope = null, currentScope = scope.upper; currentScope; ) {
|
|
1992
|
-
pureScopes.add(currentScope);
|
|
1993
|
-
if ("function" === currentScope.type) break;
|
|
1994
|
-
currentScope = currentScope.upper;
|
|
1995
|
-
}
|
|
1996
|
-
if (currentScope) {
|
|
1997
|
-
componentScope = currentScope;
|
|
1998
|
-
var isArray = Array.isArray, memoizedIsStableKnownHookValue = memoizeWithWeakMap(function(resolved) {
|
|
1999
|
-
if (!isArray(resolved.defs)) return false;
|
|
2000
|
-
var def = resolved.defs[0];
|
|
2001
|
-
if (null == def || "VariableDeclarator" !== def.node.type)
|
|
2002
|
-
return false;
|
|
2003
|
-
var init = def.node.init;
|
|
2004
|
-
if (null == init) return false;
|
|
2005
|
-
for (; "TSAsExpression" === init.type || "AsExpression" === init.type; )
|
|
2006
|
-
init = init.expression;
|
|
2007
|
-
var declaration = def.node.parent;
|
|
2008
|
-
if (null == declaration && (fastFindReferenceWithParent(
|
|
2009
|
-
componentScope.block,
|
|
2010
|
-
def.node.id
|
|
2011
|
-
), declaration = def.node.parent, null == declaration))
|
|
2012
|
-
return false;
|
|
2013
|
-
if ("const" === declaration.kind && "Literal" === init.type && ("string" === typeof init.value || "number" === typeof init.value || null === init.value))
|
|
2014
|
-
return true;
|
|
2015
|
-
if ("CallExpression" !== init.type) return false;
|
|
2016
|
-
init = init.callee;
|
|
2017
|
-
"MemberExpression" !== init.type || "React" !== init.object.name || null == init.property || init.computed || (init = init.property);
|
|
2018
|
-
if ("Identifier" !== init.type) return false;
|
|
2019
|
-
def = def.node.id;
|
|
2020
|
-
init = init.name;
|
|
2021
|
-
if ("useRef" === init && "Identifier" === def.type) return true;
|
|
2022
|
-
if ("useState" === init || "useReducer" === init || "useActionState" === init) {
|
|
2023
|
-
if ("ArrayPattern" === def.type && 2 === def.elements.length && isArray(resolved.identifiers)) {
|
|
2024
|
-
if (def.elements[1] === resolved.identifiers[0]) {
|
|
2025
|
-
if ("useState" === init)
|
|
2026
|
-
for (resolved = resolved.references, declaration = init = 0; declaration < resolved.length; declaration++) {
|
|
2027
|
-
resolved[declaration].isWrite() && init++;
|
|
2028
|
-
if (1 < init) return false;
|
|
2029
|
-
setStateCallSites.set(
|
|
2030
|
-
resolved[declaration].identifier,
|
|
2031
|
-
def.elements[0]
|
|
2032
|
-
);
|
|
2033
|
-
}
|
|
2034
|
-
return true;
|
|
2035
|
-
}
|
|
2036
|
-
if (def.elements[0] === resolved.identifiers[0] && "useState" === init)
|
|
2037
|
-
for (resolved = resolved.references, def = 0; def < resolved.length; def++)
|
|
2038
|
-
stateVariables.add(resolved[def].identifier);
|
|
2039
|
-
}
|
|
2040
|
-
} else if ("useTransition" === init && "ArrayPattern" === def.type && 2 === def.elements.length && Array.isArray(resolved.identifiers) && def.elements[1] === resolved.identifiers[0])
|
|
2041
|
-
return true;
|
|
2042
|
-
return false;
|
|
2043
|
-
}, stableKnownValueCache), memoizedIsFunctionWithoutCapturedValues = memoizeWithWeakMap(
|
|
2044
|
-
function(resolved) {
|
|
2045
|
-
if (!isArray(resolved.defs)) return false;
|
|
2046
|
-
resolved = resolved.defs[0];
|
|
2047
|
-
if (null == resolved || null == resolved.node || null == resolved.node.id)
|
|
2048
|
-
return false;
|
|
2049
|
-
var fnNode = resolved.node, childScopes = componentScope.childScopes;
|
|
2050
|
-
resolved = null;
|
|
2051
|
-
var i;
|
|
2052
|
-
for (i = 0; i < childScopes.length; i++) {
|
|
2053
|
-
var childScope = childScopes[i], childScopeBlock = childScope.block;
|
|
2054
|
-
if ("FunctionDeclaration" === fnNode.type && childScopeBlock === fnNode || "VariableDeclarator" === fnNode.type && childScopeBlock.parent === fnNode) {
|
|
2055
|
-
resolved = childScope;
|
|
2056
|
-
break;
|
|
2057
|
-
}
|
|
2058
|
-
}
|
|
2059
|
-
if (null == resolved) return false;
|
|
2060
|
-
for (i = 0; i < resolved.through.length; i++)
|
|
2061
|
-
if (fnNode = resolved.through[i], null != fnNode.resolved && pureScopes.has(fnNode.resolved.scope) && !memoizedIsStableKnownHookValue(fnNode.resolved))
|
|
2062
|
-
return false;
|
|
2063
|
-
return true;
|
|
2064
|
-
},
|
|
2065
|
-
functionWithoutCapturedValueCache
|
|
2066
|
-
), currentRefsInEffectCleanup = /* @__PURE__ */ new Map(), dependencies = /* @__PURE__ */ new Map(), optionalChains = /* @__PURE__ */ new Map();
|
|
2067
|
-
gatherDependenciesRecursively(scope);
|
|
2068
|
-
currentRefsInEffectCleanup.forEach(function(_ref, dependency) {
|
|
2069
|
-
var dependencyNode = _ref.dependencyNode;
|
|
2070
|
-
_ref = _ref.reference.resolved.references;
|
|
2071
|
-
for (var foundCurrentAssignment = false, i = 0; i < _ref.length; i++) {
|
|
2072
|
-
var parent = _ref[i].identifier.parent;
|
|
2073
|
-
if (null != parent && "MemberExpression" === parent.type && !parent.computed && "Identifier" === parent.property.type && "current" === parent.property.name && "AssignmentExpression" === parent.parent.type && parent.parent.left === parent) {
|
|
2074
|
-
foundCurrentAssignment = true;
|
|
2075
|
-
break;
|
|
2076
|
-
}
|
|
2077
|
-
}
|
|
2078
|
-
foundCurrentAssignment || reportProblem({
|
|
2079
|
-
node: dependencyNode.parent.property,
|
|
2080
|
-
message: "The ref value '" + dependency + ".current' will likely have changed by the time this effect cleanup function runs. If this ref points to a node rendered by React, copy '" + (dependency + ".current' to a variable inside the effect, and use that variable in the cleanup function.")
|
|
2081
|
-
});
|
|
2082
|
-
});
|
|
2083
|
-
var staleAssignments = /* @__PURE__ */ new Set(), stableDependencies = /* @__PURE__ */ new Set();
|
|
2084
|
-
dependencies.forEach(function(_ref2, key) {
|
|
2085
|
-
var references = _ref2.references;
|
|
2086
|
-
_ref2.isStable && stableDependencies.add(key);
|
|
2087
|
-
references.forEach(function(reference) {
|
|
2088
|
-
reference.writeExpr && (reference = reference.writeExpr, staleAssignments.has(key) || (staleAssignments.add(key), reportProblem({
|
|
2089
|
-
node: reference,
|
|
2090
|
-
message: "Assignments to the '" + key + "' variable from inside React Hook " + (getSource(reactiveHook) + " will be lost after each render. To preserve the value over time, store it in a useRef Hook and keep the mutable value in the '.current' property. Otherwise, you can move this variable directly inside ") + (getSource(reactiveHook) + ".")
|
|
2091
|
-
})));
|
|
2092
|
-
});
|
|
2093
|
-
});
|
|
2094
|
-
if (!(0 < staleAssignments.size))
|
|
2095
|
-
if (declaredDependenciesNode) {
|
|
2096
|
-
var declaredDependencies = [], externalDependencies = /* @__PURE__ */ new Set();
|
|
2097
|
-
currentScope = "TSAsExpression" === declaredDependenciesNode.type && "ArrayExpression" === declaredDependenciesNode.expression.type;
|
|
2098
|
-
"ArrayExpression" === declaredDependenciesNode.type || currentScope ? (currentScope ? declaredDependenciesNode.expression : declaredDependenciesNode).elements.forEach(function(declaredDependencyNode) {
|
|
2099
|
-
if (null !== declaredDependencyNode)
|
|
2100
|
-
if ("SpreadElement" === declaredDependencyNode.type)
|
|
2101
|
-
reportProblem({
|
|
2102
|
-
node: declaredDependencyNode,
|
|
2103
|
-
message: "React Hook " + getSource(reactiveHook) + " has a spread element in its dependency array. This means we can't statically verify whether you've passed the correct dependencies."
|
|
2104
|
-
});
|
|
2105
|
-
else {
|
|
2106
|
-
useEffectEventVariables.has(
|
|
2107
|
-
declaredDependencyNode
|
|
2108
|
-
) && reportProblem({
|
|
2109
|
-
node: declaredDependencyNode,
|
|
2110
|
-
message: "Functions returned from `useEffectEvent` must not be included in the dependency array. Remove `" + (getSource(declaredDependencyNode) + "` from the list."),
|
|
2111
|
-
suggest: [
|
|
2112
|
-
{
|
|
2113
|
-
desc: "Remove the dependency `" + getSource(declaredDependencyNode) + "`",
|
|
2114
|
-
fix: function(fixer) {
|
|
2115
|
-
return fixer.removeRange(
|
|
2116
|
-
declaredDependencyNode.range
|
|
2117
|
-
);
|
|
2118
|
-
}
|
|
2119
|
-
}
|
|
2120
|
-
]
|
|
2121
|
-
});
|
|
2122
|
-
try {
|
|
2123
|
-
var declaredDependency = analyzePropertyChain(
|
|
2124
|
-
declaredDependencyNode,
|
|
2125
|
-
null
|
|
2126
|
-
);
|
|
2127
|
-
} catch (error) {
|
|
2128
|
-
if (/Unsupported node type/.test(error.message)) {
|
|
2129
|
-
"Literal" === declaredDependencyNode.type ? dependencies.has(
|
|
2130
|
-
declaredDependencyNode.value
|
|
2131
|
-
) ? reportProblem({
|
|
2132
|
-
node: declaredDependencyNode,
|
|
2133
|
-
message: "The " + declaredDependencyNode.raw + " literal is not a valid dependency because it never changes. Did you mean to include " + (declaredDependencyNode.value + " in the array instead?")
|
|
2134
|
-
}) : reportProblem({
|
|
2135
|
-
node: declaredDependencyNode,
|
|
2136
|
-
message: "The " + declaredDependencyNode.raw + " literal is not a valid dependency because it never changes. You can safely remove it."
|
|
2137
|
-
}) : reportProblem({
|
|
2138
|
-
node: declaredDependencyNode,
|
|
2139
|
-
message: "React Hook " + getSource(reactiveHook) + " has a complex expression in the dependency array. Extract it to a separate variable so it can be statically checked."
|
|
2140
|
-
});
|
|
2141
|
-
return;
|
|
2142
|
-
}
|
|
2143
|
-
throw error;
|
|
2144
|
-
}
|
|
2145
|
-
for (var maybeID = declaredDependencyNode; "MemberExpression" === maybeID.type || "OptionalMemberExpression" === maybeID.type || "ChainExpression" === maybeID.type; )
|
|
2146
|
-
maybeID = maybeID.object || maybeID.expression.object;
|
|
2147
|
-
var isDeclaredInComponent = !componentScope.through.some(function(ref) {
|
|
2148
|
-
return ref.identifier === maybeID;
|
|
2149
|
-
});
|
|
2150
|
-
declaredDependencies.push({
|
|
2151
|
-
key: declaredDependency,
|
|
2152
|
-
node: declaredDependencyNode
|
|
2153
|
-
});
|
|
2154
|
-
isDeclaredInComponent || externalDependencies.add(declaredDependency);
|
|
2155
|
-
}
|
|
2156
|
-
}) : reportProblem({
|
|
2157
|
-
node: declaredDependenciesNode,
|
|
2158
|
-
message: "React Hook " + getSource(reactiveHook) + " was passed a dependency list that is not an array literal. This means we can't statically verify whether you've passed the correct dependencies."
|
|
2159
|
-
});
|
|
2160
|
-
var _collectRecommendatio2 = collectRecommendations({
|
|
2161
|
-
dependencies,
|
|
2162
|
-
declaredDependencies,
|
|
2163
|
-
stableDependencies,
|
|
2164
|
-
externalDependencies,
|
|
2165
|
-
isEffect
|
|
2166
|
-
});
|
|
2167
|
-
currentScope = _collectRecommendatio2.unnecessaryDependencies;
|
|
2168
|
-
var missingDependencies = _collectRecommendatio2.missingDependencies, duplicateDependencies = _collectRecommendatio2.duplicateDependencies, suggestedDeps = _collectRecommendatio2.suggestedDependencies;
|
|
2169
|
-
if (0 === duplicateDependencies.size + missingDependencies.size + currentScope.size)
|
|
2170
|
-
scanForConstructions({
|
|
2171
|
-
declaredDependencies,
|
|
2172
|
-
declaredDependenciesNode,
|
|
2173
|
-
componentScope,
|
|
2174
|
-
scope
|
|
2175
|
-
}).forEach(function(_ref4) {
|
|
2176
|
-
var construction = _ref4.construction, isUsedOutsideOfHook = _ref4.isUsedOutsideOfHook;
|
|
2177
|
-
_ref4 = _ref4.depType;
|
|
2178
|
-
var wrapperHook = "function" === _ref4 ? "useCallback" : "useMemo", constructionType = "function" === _ref4 ? "definition" : "initialization", defaultAdvice = "wrap the " + constructionType + " of '" + construction.name.name + "' in its own " + wrapperHook + "() Hook.";
|
|
2179
|
-
defaultAdvice = "The '" + construction.name.name + "' " + _ref4 + " " + ("conditional" === _ref4 || "logical expression" === _ref4 ? "could make" : "makes") + " the dependencies of " + (reactiveHookName + " Hook (at line " + declaredDependenciesNode.loc.start.line + ") change on every render. ") + (isUsedOutsideOfHook ? "To fix this, " + defaultAdvice : "Move it inside the " + reactiveHookName + " callback. Alternatively, " + defaultAdvice);
|
|
2180
|
-
var suggest;
|
|
2181
|
-
isUsedOutsideOfHook && "Variable" === construction.type && "function" === _ref4 && (suggest = [
|
|
2182
|
-
{
|
|
2183
|
-
desc: "Wrap the " + constructionType + " of '" + construction.name.name + "' in its own " + wrapperHook + "() Hook.",
|
|
2184
|
-
fix: function(fixer) {
|
|
2185
|
-
var _ref5 = "useMemo" === wrapperHook ? ["useMemo(() => { return ", "; })"] : ["useCallback(", ")"], after = _ref5[1];
|
|
2186
|
-
return [
|
|
2187
|
-
fixer.insertTextBefore(
|
|
2188
|
-
construction.node.init,
|
|
2189
|
-
_ref5[0]
|
|
2190
|
-
),
|
|
2191
|
-
fixer.insertTextAfter(
|
|
2192
|
-
construction.node.init,
|
|
2193
|
-
after
|
|
2194
|
-
)
|
|
2195
|
-
];
|
|
2196
|
-
}
|
|
2197
|
-
}
|
|
2198
|
-
]);
|
|
2199
|
-
reportProblem({
|
|
2200
|
-
node: construction.node,
|
|
2201
|
-
message: defaultAdvice,
|
|
2202
|
-
suggest
|
|
2203
|
-
});
|
|
2204
|
-
});
|
|
2205
|
-
else {
|
|
2206
|
-
!isEffect && 0 < missingDependencies.size && (suggestedDeps = collectRecommendations({
|
|
2207
|
-
dependencies,
|
|
2208
|
-
declaredDependencies: [],
|
|
2209
|
-
stableDependencies,
|
|
2210
|
-
externalDependencies,
|
|
2211
|
-
isEffect
|
|
2212
|
-
}).suggestedDependencies);
|
|
2213
|
-
(function() {
|
|
2214
|
-
if (0 === declaredDependencies.length) return true;
|
|
2215
|
-
var declaredDepKeys = declaredDependencies.map(
|
|
2216
|
-
function(dep2) {
|
|
2217
|
-
return dep2.key;
|
|
2218
|
-
}
|
|
2219
|
-
), sortedDeclaredDepKeys = declaredDepKeys.slice().sort();
|
|
2220
|
-
return declaredDepKeys.join(",") === sortedDeclaredDepKeys.join(",");
|
|
2221
|
-
})() && suggestedDeps.sort();
|
|
2222
|
-
_collectRecommendatio2 = "";
|
|
2223
|
-
if (0 < currentScope.size) {
|
|
2224
|
-
var badRef = null;
|
|
2225
|
-
Array.from(currentScope.keys()).forEach(function(key) {
|
|
2226
|
-
null === badRef && key.endsWith(".current") && (badRef = key);
|
|
2227
|
-
});
|
|
2228
|
-
if (null !== badRef)
|
|
2229
|
-
_collectRecommendatio2 = " Mutable values like '" + badRef + "' aren't valid dependencies because mutating them doesn't re-render the component.";
|
|
2230
|
-
else if (0 < externalDependencies.size) {
|
|
2231
|
-
var dep = Array.from(externalDependencies)[0];
|
|
2232
|
-
scope.set.has(dep) || (_collectRecommendatio2 = " Outer scope values like '" + dep + "' aren't valid dependencies because mutating them doesn't re-render the component.");
|
|
2233
|
-
}
|
|
2234
|
-
}
|
|
2235
|
-
if (!_collectRecommendatio2 && missingDependencies.has("props")) {
|
|
2236
|
-
scope = dependencies.get("props");
|
|
2237
|
-
if (null == scope) return;
|
|
2238
|
-
scope = scope.references;
|
|
2239
|
-
if (!Array.isArray(scope)) return;
|
|
2240
|
-
dep = true;
|
|
2241
|
-
for (var i$jscomp$0 = 0; i$jscomp$0 < scope.length; i$jscomp$0++) {
|
|
2242
|
-
var id = fastFindReferenceWithParent(
|
|
2243
|
-
componentScope.block,
|
|
2244
|
-
scope[i$jscomp$0].identifier
|
|
2245
|
-
);
|
|
2246
|
-
if (!id) {
|
|
2247
|
-
dep = false;
|
|
2248
|
-
break;
|
|
2249
|
-
}
|
|
2250
|
-
id = id.parent;
|
|
2251
|
-
if (null == id) {
|
|
2252
|
-
dep = false;
|
|
2253
|
-
break;
|
|
2254
|
-
}
|
|
2255
|
-
if ("MemberExpression" !== id.type && "OptionalMemberExpression" !== id.type) {
|
|
2256
|
-
dep = false;
|
|
2257
|
-
break;
|
|
2258
|
-
}
|
|
2259
|
-
}
|
|
2260
|
-
dep && (_collectRecommendatio2 = " However, 'props' will change when *any* prop changes, so the preferred fix is to destructure the 'props' object outside of the " + (reactiveHookName + " call and refer to those specific props inside ") + (getSource(reactiveHook) + "."));
|
|
2261
|
-
}
|
|
2262
|
-
if (!_collectRecommendatio2 && 0 < missingDependencies.size) {
|
|
2263
|
-
var missingCallbackDep = null;
|
|
2264
|
-
missingDependencies.forEach(function(missingDep) {
|
|
2265
|
-
if (!missingCallbackDep) {
|
|
2266
|
-
var topScopeRef = componentScope.set.get(missingDep), usedDep = dependencies.get(missingDep);
|
|
2267
|
-
if (usedDep.references[0].resolved === topScopeRef && (topScopeRef = topScopeRef.defs[0], null != topScopeRef && null != topScopeRef.name && "Parameter" === topScopeRef.type)) {
|
|
2268
|
-
topScopeRef = false;
|
|
2269
|
-
for (var id2, _i2 = 0; _i2 < usedDep.references.length; _i2++)
|
|
2270
|
-
if (id2 = usedDep.references[_i2].identifier, null != id2 && null != id2.parent && ("CallExpression" === id2.parent.type || "OptionalCallExpression" === id2.parent.type) && id2.parent.callee === id2) {
|
|
2271
|
-
topScopeRef = true;
|
|
2272
|
-
break;
|
|
2273
|
-
}
|
|
2274
|
-
topScopeRef && (missingCallbackDep = missingDep);
|
|
2275
|
-
}
|
|
2276
|
-
}
|
|
2277
|
-
});
|
|
2278
|
-
null !== missingCallbackDep && (_collectRecommendatio2 = " If '" + missingCallbackDep + "' changes too often, find the parent component that defines it and wrap that definition in useCallback.");
|
|
2279
|
-
}
|
|
2280
|
-
if (!_collectRecommendatio2 && 0 < missingDependencies.size) {
|
|
2281
|
-
var setStateRecommendation = null;
|
|
2282
|
-
missingDependencies.forEach(function(missingDep) {
|
|
2283
|
-
if (null === setStateRecommendation)
|
|
2284
|
-
for (var references = dependencies.get(missingDep).references, id2, maybeCall, _i3 = 0; _i3 < references.length; _i3++) {
|
|
2285
|
-
id2 = references[_i3].identifier;
|
|
2286
|
-
for (maybeCall = id2.parent; null != maybeCall && maybeCall !== componentScope.block; ) {
|
|
2287
|
-
if ("CallExpression" === maybeCall.type) {
|
|
2288
|
-
var correspondingStateVariable = setStateCallSites.get(maybeCall.callee);
|
|
2289
|
-
if (null != correspondingStateVariable) {
|
|
2290
|
-
correspondingStateVariable.name === missingDep ? setStateRecommendation = {
|
|
2291
|
-
missingDep,
|
|
2292
|
-
setter: maybeCall.callee.name,
|
|
2293
|
-
form: "updater"
|
|
2294
|
-
} : stateVariables.has(id2) ? setStateRecommendation = {
|
|
2295
|
-
missingDep,
|
|
2296
|
-
setter: maybeCall.callee.name,
|
|
2297
|
-
form: "reducer"
|
|
2298
|
-
} : (id2 = references[_i3].resolved, null != id2 && (id2 = id2.defs[0], null != id2 && "Parameter" === id2.type && (setStateRecommendation = {
|
|
2299
|
-
missingDep,
|
|
2300
|
-
setter: maybeCall.callee.name,
|
|
2301
|
-
form: "inlineReducer"
|
|
2302
|
-
})));
|
|
2303
|
-
break;
|
|
2304
|
-
}
|
|
2305
|
-
}
|
|
2306
|
-
maybeCall = maybeCall.parent;
|
|
2307
|
-
}
|
|
2308
|
-
if (null !== setStateRecommendation) break;
|
|
2309
|
-
}
|
|
2310
|
-
});
|
|
2311
|
-
if (null !== setStateRecommendation)
|
|
2312
|
-
switch (setStateRecommendation.form) {
|
|
2313
|
-
case "reducer":
|
|
2314
|
-
_collectRecommendatio2 = " You can also replace multiple useState variables with useReducer if '" + (setStateRecommendation.setter + "' needs the current value of '") + (setStateRecommendation.missingDep + "'.");
|
|
2315
|
-
break;
|
|
2316
|
-
case "inlineReducer":
|
|
2317
|
-
_collectRecommendatio2 = " If '" + setStateRecommendation.setter + "' needs the current value of '" + (setStateRecommendation.missingDep + "', you can also switch to useReducer instead of useState and read '") + (setStateRecommendation.missingDep + "' in the reducer.");
|
|
2318
|
-
break;
|
|
2319
|
-
case "updater":
|
|
2320
|
-
_collectRecommendatio2 = " You can also do a functional update '" + setStateRecommendation.setter + "(" + setStateRecommendation.missingDep.slice(0, 1) + " => ...)' if you only need '" + setStateRecommendation.missingDep + "' in the '" + (setStateRecommendation.setter + "' call.");
|
|
2321
|
-
break;
|
|
2322
|
-
default:
|
|
2323
|
-
throw Error("Unknown case.");
|
|
2324
|
-
}
|
|
2325
|
-
}
|
|
2326
|
-
reportProblem({
|
|
2327
|
-
node: declaredDependenciesNode,
|
|
2328
|
-
message: "React Hook " + getSource(reactiveHook) + " has " + (getWarningMessage(
|
|
2329
|
-
missingDependencies,
|
|
2330
|
-
"a",
|
|
2331
|
-
"missing",
|
|
2332
|
-
"include"
|
|
2333
|
-
) || getWarningMessage(
|
|
2334
|
-
currentScope,
|
|
2335
|
-
"an",
|
|
2336
|
-
"unnecessary",
|
|
2337
|
-
"exclude"
|
|
2338
|
-
) || getWarningMessage(
|
|
2339
|
-
duplicateDependencies,
|
|
2340
|
-
"a",
|
|
2341
|
-
"duplicate",
|
|
2342
|
-
"omit"
|
|
2343
|
-
)) + _collectRecommendatio2,
|
|
2344
|
-
suggest: [
|
|
2345
|
-
{
|
|
2346
|
-
desc: "Update the dependencies array to be: [" + suggestedDeps.map(formatDependency).join(", ") + "]",
|
|
2347
|
-
fix: function(fixer) {
|
|
2348
|
-
return fixer.replaceText(
|
|
2349
|
-
declaredDependenciesNode,
|
|
2350
|
-
"[" + suggestedDeps.map(formatDependency).join(", ") + "]"
|
|
2351
|
-
);
|
|
2352
|
-
}
|
|
2353
|
-
}
|
|
2354
|
-
]
|
|
2355
|
-
});
|
|
2356
|
-
}
|
|
2357
|
-
} else {
|
|
2358
|
-
var setStateInsideEffectWithoutDeps = null;
|
|
2359
|
-
dependencies.forEach(function(_ref3, key) {
|
|
2360
|
-
setStateInsideEffectWithoutDeps || _ref3.references.forEach(function(reference) {
|
|
2361
|
-
if (!setStateInsideEffectWithoutDeps && setStateCallSites.has(reference.identifier)) {
|
|
2362
|
-
for (reference = reference.from; "function" !== reference.type; )
|
|
2363
|
-
reference = reference.upper;
|
|
2364
|
-
reference.block === node && (setStateInsideEffectWithoutDeps = key);
|
|
2365
|
-
}
|
|
2366
|
-
});
|
|
2367
|
-
});
|
|
2368
|
-
if (setStateInsideEffectWithoutDeps) {
|
|
2369
|
-
var _suggestedDependencies = collectRecommendations({
|
|
2370
|
-
dependencies,
|
|
2371
|
-
declaredDependencies: [],
|
|
2372
|
-
stableDependencies,
|
|
2373
|
-
externalDependencies: /* @__PURE__ */ new Set(),
|
|
2374
|
-
isEffect: true
|
|
2375
|
-
}).suggestedDependencies;
|
|
2376
|
-
reportProblem({
|
|
2377
|
-
node: reactiveHook,
|
|
2378
|
-
message: "React Hook " + reactiveHookName + " contains a call to '" + setStateInsideEffectWithoutDeps + "'. Without a list of dependencies, this can lead to an infinite chain of updates. To fix this, pass [" + _suggestedDependencies.join(", ") + ("] as a second argument to the " + reactiveHookName + " Hook."),
|
|
2379
|
-
suggest: [
|
|
2380
|
-
{
|
|
2381
|
-
desc: "Add dependencies array: [" + _suggestedDependencies.join(", ") + "]",
|
|
2382
|
-
fix: function(fixer) {
|
|
2383
|
-
return fixer.insertTextAfter(
|
|
2384
|
-
node,
|
|
2385
|
-
", [" + _suggestedDependencies.join(", ") + "]"
|
|
2386
|
-
);
|
|
2387
|
-
}
|
|
2388
|
-
}
|
|
2389
|
-
]
|
|
2390
|
-
});
|
|
2391
|
-
}
|
|
2392
|
-
}
|
|
2393
|
-
}
|
|
2394
|
-
}
|
|
2395
|
-
var enableDangerousAutofixThisMayCauseInfiniteLoops = context.options && context.options[0] && context.options[0].enableDangerousAutofixThisMayCauseInfiniteLoops || false, options = {
|
|
2396
|
-
additionalHooks: context.options && context.options[0] && context.options[0].additionalHooks ? new RegExp(context.options[0].additionalHooks) : void 0,
|
|
2397
|
-
enableDangerousAutofixThisMayCauseInfiniteLoops
|
|
2398
|
-
}, getSource = "function" === typeof context.getSource ? function(node) {
|
|
2399
|
-
return context.getSource(node);
|
|
2400
|
-
} : function(node) {
|
|
2401
|
-
return context.sourceCode.getText(node);
|
|
2402
|
-
}, getScope = "function" === typeof context.getScope ? function() {
|
|
2403
|
-
return context.getScope();
|
|
2404
|
-
} : function(node) {
|
|
2405
|
-
return context.sourceCode.getScope(node);
|
|
2406
|
-
}, scopeManager = context.getSourceCode().scopeManager, setStateCallSites = /* @__PURE__ */ new WeakMap(), stateVariables = /* @__PURE__ */ new WeakSet(), stableKnownValueCache = /* @__PURE__ */ new WeakMap(), functionWithoutCapturedValueCache = /* @__PURE__ */ new WeakMap(), useEffectEventVariables = /* @__PURE__ */ new WeakSet();
|
|
2407
|
-
return {
|
|
2408
|
-
CallExpression: function(node) {
|
|
2409
|
-
var callbackIndex = getReactiveHookCallbackIndex(
|
|
2410
|
-
node.callee,
|
|
2411
|
-
options
|
|
2412
|
-
);
|
|
2413
|
-
if (-1 !== callbackIndex) {
|
|
2414
|
-
var callback = node.arguments[callbackIndex], reactiveHook = node.callee, reactiveHookName = getNodeWithoutReactNamespace(reactiveHook).name;
|
|
2415
|
-
node = node.arguments[callbackIndex + 1];
|
|
2416
|
-
var declaredDependenciesNode = !node || "Identifier" === node.type && "undefined" === node.name ? void 0 : node;
|
|
2417
|
-
node = /Effect($|[^a-z])/g.test(reactiveHookName);
|
|
2418
|
-
if (callback)
|
|
2419
|
-
if (declaredDependenciesNode || node) {
|
|
2420
|
-
switch (callback.type) {
|
|
2421
|
-
case "FunctionExpression":
|
|
2422
|
-
case "ArrowFunctionExpression":
|
|
2423
|
-
visitFunctionWithDependencies(
|
|
2424
|
-
callback,
|
|
2425
|
-
declaredDependenciesNode,
|
|
2426
|
-
reactiveHook,
|
|
2427
|
-
reactiveHookName,
|
|
2428
|
-
node
|
|
2429
|
-
);
|
|
2430
|
-
return;
|
|
2431
|
-
case "TSAsExpression":
|
|
2432
|
-
visitFunctionWithDependencies(
|
|
2433
|
-
callback.expression,
|
|
2434
|
-
declaredDependenciesNode,
|
|
2435
|
-
reactiveHook,
|
|
2436
|
-
reactiveHookName,
|
|
2437
|
-
node
|
|
2438
|
-
);
|
|
2439
|
-
return;
|
|
2440
|
-
case "Identifier":
|
|
2441
|
-
if (!declaredDependenciesNode || declaredDependenciesNode.elements && declaredDependenciesNode.elements.some(
|
|
2442
|
-
function(el) {
|
|
2443
|
-
return el && "Identifier" === el.type && el.name === callback.name;
|
|
2444
|
-
}
|
|
2445
|
-
))
|
|
2446
|
-
return;
|
|
2447
|
-
callbackIndex = getScope(callback).set.get(
|
|
2448
|
-
callback.name
|
|
2449
|
-
);
|
|
2450
|
-
if (null == callbackIndex || null == callbackIndex.defs)
|
|
2451
|
-
return;
|
|
2452
|
-
callbackIndex = callbackIndex.defs[0];
|
|
2453
|
-
if (!callbackIndex || !callbackIndex.node) break;
|
|
2454
|
-
if ("Variable" !== callbackIndex.type && "FunctionName" !== callbackIndex.type)
|
|
2455
|
-
break;
|
|
2456
|
-
switch (callbackIndex.node.type) {
|
|
2457
|
-
case "FunctionDeclaration":
|
|
2458
|
-
visitFunctionWithDependencies(
|
|
2459
|
-
callbackIndex.node,
|
|
2460
|
-
declaredDependenciesNode,
|
|
2461
|
-
reactiveHook,
|
|
2462
|
-
reactiveHookName,
|
|
2463
|
-
node
|
|
2464
|
-
);
|
|
2465
|
-
return;
|
|
2466
|
-
case "VariableDeclarator":
|
|
2467
|
-
if (callbackIndex = callbackIndex.node.init)
|
|
2468
|
-
switch (callbackIndex.type) {
|
|
2469
|
-
case "ArrowFunctionExpression":
|
|
2470
|
-
case "FunctionExpression":
|
|
2471
|
-
visitFunctionWithDependencies(
|
|
2472
|
-
callbackIndex,
|
|
2473
|
-
declaredDependenciesNode,
|
|
2474
|
-
reactiveHook,
|
|
2475
|
-
reactiveHookName,
|
|
2476
|
-
node
|
|
2477
|
-
);
|
|
2478
|
-
return;
|
|
2479
|
-
}
|
|
2480
|
-
}
|
|
2481
|
-
break;
|
|
2482
|
-
default:
|
|
2483
|
-
reportProblem({
|
|
2484
|
-
node: reactiveHook,
|
|
2485
|
-
message: "React Hook " + reactiveHookName + " received a function whose dependencies are unknown. Pass an inline function instead."
|
|
2486
|
-
});
|
|
2487
|
-
return;
|
|
2488
|
-
}
|
|
2489
|
-
reportProblem({
|
|
2490
|
-
node: reactiveHook,
|
|
2491
|
-
message: "React Hook " + reactiveHookName + " has a missing dependency: '" + callback.name + "'. Either include it or remove the dependency array.",
|
|
2492
|
-
suggest: [
|
|
2493
|
-
{
|
|
2494
|
-
desc: "Update the dependencies array to be: [" + callback.name + "]",
|
|
2495
|
-
fix: function(fixer) {
|
|
2496
|
-
return fixer.replaceText(
|
|
2497
|
-
declaredDependenciesNode,
|
|
2498
|
-
"[" + callback.name + "]"
|
|
2499
|
-
);
|
|
2500
|
-
}
|
|
2501
|
-
}
|
|
2502
|
-
]
|
|
2503
|
-
});
|
|
2504
|
-
} else
|
|
2505
|
-
"useMemo" !== reactiveHookName && "useCallback" !== reactiveHookName || reportProblem({
|
|
2506
|
-
node: reactiveHook,
|
|
2507
|
-
message: "React Hook " + reactiveHookName + " does nothing when called with only one argument. Did you forget to pass an array of dependencies?"
|
|
2508
|
-
});
|
|
2509
|
-
else
|
|
2510
|
-
reportProblem({
|
|
2511
|
-
node: reactiveHook,
|
|
2512
|
-
message: "React Hook " + reactiveHookName + " requires an effect callback. Did you forget to pass a callback to the hook?"
|
|
2513
|
-
});
|
|
2514
|
-
}
|
|
2515
|
-
}
|
|
2516
|
-
};
|
|
2517
|
-
}
|
|
2518
|
-
}
|
|
2519
|
-
};
|
|
2520
|
-
}();
|
|
2521
|
-
}
|
|
2522
|
-
});
|
|
2523
|
-
|
|
2524
|
-
// node_modules/.pnpm/eslint-plugin-react-hooks@5.1.0_eslint@9.19.0_jiti@2.4.2_/node_modules/eslint-plugin-react-hooks/index.js
|
|
2525
|
-
var require_eslint_plugin_react_hooks = __commonJS({
|
|
2526
|
-
"node_modules/.pnpm/eslint-plugin-react-hooks@5.1.0_eslint@9.19.0_jiti@2.4.2_/node_modules/eslint-plugin-react-hooks/index.js"(exports, module) {
|
|
2527
|
-
init_esm_shims();
|
|
2528
|
-
if (process.env.NODE_ENV === "production") {
|
|
2529
|
-
module.exports = require_eslint_plugin_react_hooks_production();
|
|
2530
|
-
} else {
|
|
2531
|
-
module.exports = require_eslint_plugin_react_hooks_development();
|
|
2532
|
-
}
|
|
2533
|
-
}
|
|
2534
|
-
});
|
|
2535
|
-
export default require_eslint_plugin_react_hooks();
|
|
2536
|
-
/*! Bundled license information:
|
|
2537
|
-
|
|
2538
|
-
eslint-plugin-react-hooks/cjs/eslint-plugin-react-hooks.production.js:
|
|
2539
|
-
(**
|
|
2540
|
-
* @license React
|
|
2541
|
-
* eslint-plugin-react-hooks.production.js
|
|
2542
|
-
*
|
|
2543
|
-
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2544
|
-
*
|
|
2545
|
-
* This source code is licensed under the MIT license found in the
|
|
2546
|
-
* LICENSE file in the root directory of this source tree.
|
|
2547
|
-
*)
|
|
2548
|
-
|
|
2549
|
-
eslint-plugin-react-hooks/cjs/eslint-plugin-react-hooks.development.js:
|
|
2550
|
-
(**
|
|
2551
|
-
* @license React
|
|
2552
|
-
* eslint-plugin-react-hooks.development.js
|
|
2553
|
-
*
|
|
2554
|
-
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2555
|
-
*
|
|
2556
|
-
* This source code is licensed under the MIT license found in the
|
|
2557
|
-
* LICENSE file in the root directory of this source tree.
|
|
2558
|
-
*)
|
|
2559
|
-
*/
|