Assignment5_new/node_modules/eslint-plugin-react-hooks/cjs/eslint-plugin-react-hooks.development.js

2039 lines
85 KiB
JavaScript
Raw Normal View History

2025-01-07 05:14:59 +00:00
/**
* @license React
* eslint-plugin-react-hooks.development.js
*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
"use strict";
"production" !== process.env.NODE_ENV &&
(function () {
function _unsupportedIterableToArray(o, minLen) {
if (o) {
if ("string" === typeof o) return _arrayLikeToArray(o, minLen);
var n = Object.prototype.toString.call(o).slice(8, -1);
"Object" === n && o.constructor && (n = o.constructor.name);
if ("Map" === n || "Set" === n) return Array.from(o);
if (
"Arguments" === n ||
/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)
)
return _arrayLikeToArray(o, minLen);
}
}
function _arrayLikeToArray(arr, len) {
if (null == len || len > arr.length) len = arr.length;
for (var i = 0, arr2 = Array(len); i < len; i++) arr2[i] = arr[i];
return arr2;
}
function _createForOfIteratorHelper(o, allowArrayLike) {
var it;
if ("undefined" === typeof Symbol || null == o[Symbol.iterator]) {
if (
Array.isArray(o) ||
(it = _unsupportedIterableToArray(o)) ||
(allowArrayLike && o && "number" === typeof o.length)
) {
it && (o = it);
var i = 0;
allowArrayLike = function () {};
return {
s: allowArrayLike,
n: function () {
return i >= o.length ? { done: !0 } : { done: !1, value: o[i++] };
},
e: function (e) {
throw e;
},
f: allowArrayLike
};
}
throw new TypeError(
"Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."
);
}
var normalCompletion = !0,
didErr = !1,
err;
return {
s: function () {
it = o[Symbol.iterator]();
},
n: function () {
var step = it.next();
normalCompletion = step.done;
return step;
},
e: function (e) {
didErr = !0;
err = e;
},
f: function () {
try {
normalCompletion || null == it.return || it.return();
} finally {
if (didErr) throw err;
}
}
};
}
function isHook(node) {
if ("Identifier" === node.type)
return (node = node.name), "use" === node || /^use[A-Z0-9]/.test(node);
if (
"MemberExpression" === node.type &&
!node.computed &&
isHook(node.property)
) {
node = node.object;
var isPascalCaseNameSpace = /^[A-Z].*/;
return (
"Identifier" === node.type && isPascalCaseNameSpace.test(node.name)
);
}
return !1;
}
function isComponentName(node) {
return "Identifier" === node.type && /^[A-Z]/.test(node.name);
}
function isReactFunction(node, functionName) {
return (
node.name === functionName ||
("MemberExpression" === node.type &&
"React" === node.object.name &&
node.property.name === functionName)
);
}
function isForwardRefCallback(node) {
return !!(
node.parent &&
node.parent.callee &&
isReactFunction(node.parent.callee, "forwardRef")
);
}
function isMemoCallback(node) {
return !!(
node.parent &&
node.parent.callee &&
isReactFunction(node.parent.callee, "memo")
);
}
function isInsideComponentOrHook(node) {
for (; node; ) {
var functionName = getFunctionName(node);
if (
(functionName &&
(isComponentName(functionName) || isHook(functionName))) ||
isForwardRefCallback(node) ||
isMemoCallback(node)
)
return !0;
node = node.parent;
}
return !1;
}
function getFunctionName(node) {
if (
"FunctionDeclaration" === node.type ||
("FunctionExpression" === node.type && node.id)
)
return node.id;
if (
"FunctionExpression" === node.type ||
"ArrowFunctionExpression" === node.type
)
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;
}
function collectRecommendations(_ref6) {
function createDepTree() {
return {
isUsed: !1,
isSatisfiedRecursively: !1,
isSubtreeUsed: !1,
children: new Map()
};
}
function getOrCreateNodeByPath(rootNode, path) {
path = path.split(".");
path = _createForOfIteratorHelper(path);
var _step4;
try {
for (path.s(); !(_step4 = path.n()).done; ) {
var key = _step4.value,
child = rootNode.children.get(key);
child ||
((child = createDepTree()), rootNode.children.set(key, child));
rootNode = child;
}
} catch (err) {
path.e(err);
} finally {
path.f();
}
return rootNode;
}
function markAllParentsByPath(rootNode, path, fn) {
path = path.split(".");
path = _createForOfIteratorHelper(path);
var _step5;
try {
for (path.s(); !(_step5 = path.n()).done; ) {
var child = rootNode.children.get(_step5.value);
if (!child) break;
fn(child);
rootNode = child;
}
} catch (err) {
path.e(err);
} finally {
path.f();
}
}
function scanTreeRecursively(
node,
missingPaths,
satisfyingPaths,
keyToPath
) {
node.children.forEach(function (child, key) {
var path = keyToPath(key);
child.isSatisfiedRecursively
? child.isSubtreeUsed && satisfyingPaths.add(path)
: child.isUsed
? missingPaths.add(path)
: scanTreeRecursively(
child,
missingPaths,
satisfyingPaths,
function (childKey) {
return path + "." + childKey;
}
);
});
}
var dependencies = _ref6.dependencies,
declaredDependencies = _ref6.declaredDependencies,
stableDependencies = _ref6.stableDependencies,
externalDependencies = _ref6.externalDependencies,
isEffect = _ref6.isEffect,
depTree = createDepTree();
dependencies.forEach(function (_, key) {
getOrCreateNodeByPath(depTree, key).isUsed = !0;
markAllParentsByPath(depTree, key, function (parent) {
parent.isSubtreeUsed = !0;
});
});
declaredDependencies.forEach(function (_ref7) {
getOrCreateNodeByPath(depTree, _ref7.key).isSatisfiedRecursively = !0;
});
stableDependencies.forEach(function (key) {
getOrCreateNodeByPath(depTree, key).isSatisfiedRecursively = !0;
});
_ref6 = new Set();
var satisfyingDependencies = new Set();
scanTreeRecursively(
depTree,
_ref6,
satisfyingDependencies,
function (key) {
return key;
}
);
var suggestedDependencies = [],
unnecessaryDependencies = new Set(),
duplicateDependencies = new Set();
declaredDependencies.forEach(function (_ref8) {
_ref8 = _ref8.key;
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);
});
_ref6.forEach(function (key) {
suggestedDependencies.push(key);
});
return {
suggestedDependencies: suggestedDependencies,
unnecessaryDependencies: unnecessaryDependencies,
duplicateDependencies: duplicateDependencies,
missingDependencies: _ref6
};
}
function getConstructionExpressionType(node) {
switch (node.type) {
case "ObjectExpression":
return "object";
case "ArrayExpression":
return "array";
case "ArrowFunctionExpression":
case "FunctionExpression":
return "function";
case "ClassExpression":
return "class";
case "ConditionalExpression":
if (
null != getConstructionExpressionType(node.consequent) ||
null != getConstructionExpressionType(node.alternate)
)
return "conditional";
break;
case "LogicalExpression":
if (
null != getConstructionExpressionType(node.left) ||
null != getConstructionExpressionType(node.right)
)
return "logical expression";
break;
case "JSXFragment":
return "JSX fragment";
case "JSXElement":
return "JSX element";
case "AssignmentExpression":
if (null != getConstructionExpressionType(node.right))
return "assignment expression";
break;
case "NewExpression":
return "object construction";
case "Literal":
if (node.value instanceof RegExp) return "regular expression";
break;
case "TypeCastExpression":
case "AsExpression":
case "TSAsExpression":
return getConstructionExpressionType(node.expression);
}
return null;
}
function scanForConstructions(_ref9) {
var declaredDependenciesNode = _ref9.declaredDependenciesNode,
componentScope = _ref9.componentScope,
scope = _ref9.scope;
return _ref9.declaredDependencies
.map(function (_ref10) {
var key = _ref10.key;
_ref10 = componentScope.variables.find(function (v) {
return v.name === key;
});
if (null == _ref10) return null;
var node = _ref10.defs[0];
if (null == node) return null;
if (
"Variable" === node.type &&
"VariableDeclarator" === node.node.type &&
"Identifier" === node.node.id.type &&
null != node.node.init
) {
var constantExpressionType = getConstructionExpressionType(
node.node.init
);
if (null != constantExpressionType)
return [_ref10, constantExpressionType];
}
return "FunctionName" === node.type &&
"FunctionDeclaration" === node.node.type
? [_ref10, "function"]
: "ClassName" === node.type && "ClassDeclaration" === node.node.type
? [_ref10, "class"]
: null;
})
.filter(Boolean)
.map(function (_ref11) {
var ref = _ref11[0];
_ref11 = _ref11[1];
var JSCompiler_temp_const = ref.defs[0];
a: {
for (
var foundWriteExpr = !1, i = 0;
i < ref.references.length;
i++
) {
var reference = ref.references[i];
if (reference.writeExpr)
if (foundWriteExpr) {
ref = !0;
break a;
} else {
foundWriteExpr = !0;
continue;
}
for (
var currentScope = reference.from;
currentScope !== scope && null != currentScope;
)
currentScope = currentScope.upper;
if (
currentScope !== scope &&
!isAncestorNodeOf(
declaredDependenciesNode,
reference.identifier
)
) {
ref = !0;
break a;
}
}
ref = !1;
}
return {
construction: JSCompiler_temp_const,
depType: _ref11,
isUsedOutsideOfHook: ref
};
});
}
function getDependency(node) {
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);
}
function markNode(node, optionalChains, result) {
optionalChains &&
(node.optional
? optionalChains.has(result) || optionalChains.set(result, !0)
: optionalChains.set(result, !1));
}
function analyzePropertyChain(node, optionalChains) {
if ("Identifier" === node.type || "JSXIdentifier" === node.type)
return (
(node = node.name),
optionalChains && optionalChains.set(node, !1),
node
);
if ("MemberExpression" !== node.type || node.computed) {
if ("OptionalMemberExpression" !== node.type || node.computed) {
if ("ChainExpression" !== node.type || node.computed)
throw Error("Unsupported node type: " + node.type);
node = node.expression;
if ("CallExpression" === node.type)
throw Error("Unsupported node type: " + node.type);
var _object2 = analyzePropertyChain(node.object, optionalChains),
_property2 = analyzePropertyChain(node.property, null);
_object2 = _object2 + "." + _property2;
markNode(node, optionalChains, _object2);
return _object2;
}
_object2 = analyzePropertyChain(node.object, optionalChains);
_property2 = analyzePropertyChain(node.property, null);
_object2 = _object2 + "." + _property2;
markNode(node, optionalChains, _object2);
return _object2;
}
_object2 = analyzePropertyChain(node.object, optionalChains);
_property2 = analyzePropertyChain(node.property, null);
_object2 = _object2 + "." + _property2;
markNode(node, optionalChains, _object2);
return _object2;
}
function getNodeWithoutReactNamespace(node) {
return "MemberExpression" !== node.type ||
"Identifier" !== node.object.type ||
"React" !== node.object.name ||
"Identifier" !== node.property.type ||
node.computed
? node
: node.property;
}
function getReactiveHookCallbackIndex(calleeNode, options) {
var node = getNodeWithoutReactNamespace(calleeNode);
if ("Identifier" !== node.type) return -1;
switch (node.name) {
case "useEffect":
case "useLayoutEffect":
case "useCallback":
case "useMemo":
return 0;
case "useImperativeHandle":
return 1;
default:
if (node === calleeNode && options && options.additionalHooks) {
try {
var name = analyzePropertyChain(node, null);
} catch (error) {
if (/Unsupported node type/.test(error.message)) return 0;
throw error;
}
return options.additionalHooks.test(name) ? 0 : -1;
}
return -1;
}
}
function fastFindReferenceWithParent(start, target) {
for (var queue = [start], item = null; queue.length; ) {
item = queue.shift();
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]
)
return item;
if (isAncestorNodeOf(item, target)) {
start = 0;
for (
var _Object$entries = Object.entries(item);
start < _Object$entries.length;
start++
) {
var _Object$entries$_i = _Object$entries[start],
value = _Object$entries$_i[1];
"parent" !== _Object$entries$_i[0] &&
(isNodeLike(value)
? ((value.parent = item), queue.push(value))
: Array.isArray(value) &&
value.forEach(function (val) {
isNodeLike(val) && ((val.parent = item), queue.push(val));
}));
}
}
}
return null;
}
function joinEnglish(arr) {
for (var s = "", i = 0; i < arr.length; i++)
(s += arr[i]),
0 === i && 2 === arr.length
? (s += " and ")
: i === arr.length - 2 && 2 < arr.length
? (s += ", and ")
: i < arr.length - 1 && (s += ", ");
return s;
}
function isNodeLike(val) {
return (
"object" === typeof val &&
null !== val &&
!Array.isArray(val) &&
"string" === typeof val.type
);
}
function isAncestorNodeOf(a, b) {
return a.range[0] <= b.range[0] && a.range[1] >= b.range[1];
}
exports.configs = {
recommended: {
plugins: ["react-hooks"],
rules: {
"react-hooks/rules-of-hooks": "error",
"react-hooks/exhaustive-deps": "warn"
}
}
};
exports.rules = {
"rules-of-hooks": {
meta: {
type: "problem",
docs: {
description: "enforces the Rules of Hooks",
recommended: !0,
url: "https://reactjs.org/docs/hooks-rules.html"
}
},
create: function (context) {
function recordAllUseEffectEventFunctions(scope) {
scope = _createForOfIteratorHelper(scope.references);
try {
for (scope.s(); !scope.n().done; );
} catch (err$0) {
scope.e(err$0);
} finally {
scope.f();
}
}
var lastEffect = null,
codePathReactHooksMapStack = [],
codePathSegmentStack = [],
useEffectEventFunctions = new WeakSet(),
getSource =
"function" === typeof context.getSource
? function (node) {
return context.getSource(node);
}
: function (node) {
return context.sourceCode.getText(node);
},
getScope =
"function" === typeof context.getScope
? function () {
return context.getScope();
}
: function (node) {
return context.sourceCode.getScope(node);
};
return {
onCodePathSegmentStart: function (segment) {
return codePathSegmentStack.push(segment);
},
onCodePathSegmentEnd: function () {
return codePathSegmentStack.pop();
},
onCodePathStart: function () {
return codePathReactHooksMapStack.push(new Map());
},
onCodePathEnd: function (codePath, codePathNode) {
function countPathsFromStart(segment, pathHistory) {
var cache = countPathsFromStart.cache,
paths = cache.get(segment.id);
pathHistory = new Set(pathHistory);
if (pathHistory.has(segment.id)) {
cache = [].concat(pathHistory);
segment = cache.slice(cache.indexOf(segment.id) + 1);
segment = _createForOfIteratorHelper(segment);
var _step3;
try {
for (segment.s(); !(_step3 = segment.n()).done; )
cyclic.add(_step3.value);
} catch (err) {
segment.e(err);
} finally {
segment.f();
}
return BigInt("0");
}
pathHistory.add(segment.id);
if (void 0 !== paths) return paths;
if (codePath.thrownSegments.includes(segment))
paths = BigInt("0");
else if (0 === segment.prevSegments.length) paths = BigInt("1");
else {
paths = BigInt("0");
_step3 = _createForOfIteratorHelper(segment.prevSegments);
var _step4;
try {
for (_step3.s(); !(_step4 = _step3.n()).done; )
paths += countPathsFromStart(_step4.value, pathHistory);
} catch (err$1) {
_step3.e(err$1);
} finally {
_step3.f();
}
}
segment.reachable && paths === BigInt("0")
? cache.delete(segment.id)
: cache.set(segment.id, paths);
return paths;
}
function countPathsToEnd(segment, pathHistory) {
var cache = countPathsToEnd.cache,
paths = cache.get(segment.id);
pathHistory = new Set(pathHistory);
if (pathHistory.has(segment.id)) {
cache = Array.from(pathHistory);
segment = cache.slice(cache.indexOf(segment.id) - 1);
segment = _createForOfIteratorHelper(segment);
var _step5;
try {
for (segment.s(); !(_step5 = segment.n()).done; )
cyclic.add(_step5.value);
} catch (err) {
segment.e(err);
} finally {
segment.f();
}
return BigInt("0");
}
pathHistory.add(segment.id);
if (void 0 !== paths) return paths;
if (codePath.thrownSegments.includes(segment))
paths = BigInt("0");
else if (0 === segment.nextSegments.length) paths = BigInt("1");
else {
paths = BigInt("0");
_step5 = _createForOfIteratorHelper(segment.nextSegments);
var _step6;
try {
for (_step5.s(); !(_step6 = _step5.n()).done; )
paths += countPathsToEnd(_step6.value, pathHistory);
} catch (err$2) {
_step5.e(err$2);
} finally {
_step5.f();
}
}
cache.set(segment.id, paths);
return paths;
}
function shortestPathLengthToStart(segment) {
var cache = shortestPathLengthToStart.cache,
length = cache.get(segment.id);
if (null === length) return Infinity;
if (void 0 !== length) return length;
cache.set(segment.id, null);
if (0 === segment.prevSegments.length) length = 1;
else {
length = Infinity;
var _iterator7 = _createForOfIteratorHelper(
segment.prevSegments
),
_step7;
try {
for (_iterator7.s(); !(_step7 = _iterator7.n()).done; ) {
var prevLength = shortestPathLengthToStart(_step7.value);
prevLength < length && (length = prevLength);
}
} catch (err) {
_iterator7.e(err);
} finally {
_iterator7.f();
}
length += 1;
}
cache.set(segment.id, length);
return length;
}
var reactHooksMap = codePathReactHooksMapStack.pop();
if (0 !== reactHooksMap.size) {
var cyclic = new Set();
countPathsFromStart.cache = new Map();
countPathsToEnd.cache = new Map();
shortestPathLengthToStart.cache = new Map();
var allPathsFromStartToEnd = countPathsToEnd(
codePath.initialSegment
),
codePathFunctionName = getFunctionName(codePathNode),
isSomewhereInsideComponentOrHook =
isInsideComponentOrHook(codePathNode),
isDirectlyInsideComponentOrHook = codePathFunctionName
? isComponentName(codePathFunctionName) ||
isHook(codePathFunctionName)
: isForwardRefCallback(codePathNode) ||
isMemoCallback(codePathNode),
shortestFinalPathLength = Infinity,
_iterator8 = _createForOfIteratorHelper(
codePath.finalSegments
),
_step8;
try {
for (_iterator8.s(); !(_step8 = _iterator8.n()).done; ) {
var finalSegment = _step8.value;
if (finalSegment.reachable) {
var length$jscomp$0 =
shortestPathLengthToStart(finalSegment);
length$jscomp$0 < shortestFinalPathLength &&
(shortestFinalPathLength = length$jscomp$0);
}
}
} catch (err) {
_iterator8.e(err);
} finally {
_iterator8.f();
}
reactHooksMap = _createForOfIteratorHelper(reactHooksMap);
var _step9;
try {
for (
reactHooksMap.s();
!(_step9 = reactHooksMap.n()).done;
) {
var _step9$value = _step9.value,
segment$jscomp$0 = _step9$value[0],
reactHooks = _step9$value[1];
if (segment$jscomp$0.reachable) {
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;
try {
for (
_iterator10.s();
!(_step10 = _iterator10.n()).done;
) {
var hook = _step10.value;
cycled &&
!isReactFunction(hook, "use") &&
context.report({
node: hook,
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.'
});
if (isDirectlyInsideComponentOrHook) {
if (
(codePathNode.async &&
context.report({
node: hook,
message:
'React Hook "' +
getSource(hook) +
'" cannot be called in an async function.'
}),
!cycled &&
pathsFromStartToEnd !==
allPathsFromStartToEnd &&
!isReactFunction(hook, "use"))
) {
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?"
: "");
context.report({ node: hook, message: message });
}
} else if (
codePathNode.parent &&
("MethodDefinition" === codePathNode.parent.type ||
"ClassProperty" === codePathNode.parent.type) &&
codePathNode.parent.value === codePathNode
) {
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.';
context.report({ node: hook, message: _message });
} else if (codePathFunctionName) {
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".');
context.report({ node: hook, message: _message2 });
} else if ("Program" === codePathNode.type) {
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.';
context.report({ node: hook, message: _message3 });
} else if (
isSomewhereInsideComponentOrHook &&
!isReactFunction(hook, "use")
) {
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.';
context.report({ node: hook, message: _message4 });
}
}
} catch (err$3) {
_iterator10.e(err$3);
} finally {
_iterator10.f();
}
}
}
} catch (err$4) {
reactHooksMap.e(err$4);
} finally {
reactHooksMap.f();
}
}
},
CallExpression: function (node) {
if (isHook(node.callee)) {
var reactHooksMap =
codePathReactHooksMapStack[
codePathReactHooksMapStack.length - 1
],
codePathSegment =
codePathSegmentStack[codePathSegmentStack.length - 1],
reactHooks = reactHooksMap.get(codePathSegment);
reactHooks ||
((reactHooks = []),
reactHooksMap.set(codePathSegment, reactHooks));
reactHooks.push(node.callee);
}
"Identifier" === node.callee.type &&
"useEffect" === node.callee.name &&
0 < node.arguments.length &&
(lastEffect = node);
},
Identifier: function (node) {
null == lastEffect &&
useEffectEventFunctions.has(node) &&
"CallExpression" !== node.parent.type &&
context.report({
node: node,
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.'
});
},
"CallExpression:exit": function (node) {
node === lastEffect && (lastEffect = null);
},
FunctionDeclaration: function (node) {
isInsideComponentOrHook(node) &&
recordAllUseEffectEventFunctions(getScope(node));
},
ArrowFunctionExpression: function (node) {
isInsideComponentOrHook(node) &&
recordAllUseEffectEventFunctions(getScope(node));
}
};
}
},
"exhaustive-deps": {
meta: {
type: "suggestion",
docs: {
description:
"verifies the list of dependencies for Hooks like useEffect and similar",
recommended: !0,
url: "https://github.com/facebook/react/issues/14920"
},
fixable: "code",
hasSuggestions: !0,
schema: [
{
type: "object",
additionalProperties: !1,
enableDangerousAutofixThisMayCauseInfiniteLoops: !1,
properties: {
additionalHooks: { type: "string" },
enableDangerousAutofixThisMayCauseInfiniteLoops: {
type: "boolean"
}
}
}
]
},
create: function (context) {
function reportProblem(problem) {
enableDangerousAutofixThisMayCauseInfiniteLoops &&
Array.isArray(problem.suggest) &&
0 < problem.suggest.length &&
(problem.fix = problem.suggest[0].fix);
context.report(problem);
}
function memoizeWithWeakMap(fn, map) {
return function (arg) {
if (map.has(arg)) return map.get(arg);
var result = fn(arg);
map.set(arg, result);
return result;
};
}
function visitFunctionWithDependencies(
node,
declaredDependenciesNode,
reactiveHook,
reactiveHookName,
isEffect
) {
function gatherDependenciesRecursively(currentScope) {
var _iterator2 = _createForOfIteratorHelper(
currentScope.references
),
_step2;
try {
for (_iterator2.s(); !(_step2 = _iterator2.n()).done; ) {
var reference = _step2.value;
if (
reference.resolved &&
pureScopes.has(reference.resolved.scope)
) {
var referenceNode = fastFindReferenceWithParent(
node,
reference.identifier
),
dependencyNode = getDependency(referenceNode),
dependency = analyzePropertyChain(
dependencyNode,
optionalChains
),
JSCompiler_temp;
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)
) {
for (
var curScope = reference.from,
isInReturnedFunction = !1;
curScope.block !== node;
)
"function" === curScope.type &&
(isInReturnedFunction =
null != curScope.block.parent &&
"ReturnStatement" === curScope.block.parent.type),
(curScope = curScope.upper);
JSCompiler_temp = isInReturnedFunction;
}
JSCompiler_temp &&
currentRefsInEffectCleanup.set(dependency, {
reference: reference,
dependencyNode: dependencyNode
});
if (
"TSTypeQuery" !== dependencyNode.parent.type &&
"TSTypeReference" !== dependencyNode.parent.type
) {
var def = reference.resolved.defs[0];
if (
null != def &&
(null == def.node || def.node.init !== node.parent) &&
"TypeParameter" !== def.type
)
if (dependencies.has(dependency))
dependencies
.get(dependency)
.references.push(reference);
else {
var resolved = reference.resolved,
isStable =
memoizedIsStableKnownHookValue(resolved) ||
memoizedIsFunctionWithoutCapturedValues(resolved);
dependencies.set(dependency, {
isStable: isStable,
references: [reference]
});
}
}
}
}
} catch (err) {
_iterator2.e(err);
} finally {
_iterator2.f();
}
currentScope = _createForOfIteratorHelper(
currentScope.childScopes
);
var _step3;
try {
for (currentScope.s(); !(_step3 = currentScope.n()).done; )
gatherDependenciesRecursively(_step3.value);
} catch (err$5) {
currentScope.e(err$5);
} finally {
currentScope.f();
}
}
function formatDependency(path) {
path = path.split(".");
for (var finalPath = "", i = 0; i < path.length; i++) {
if (0 !== i) {
var pathSoFar = path.slice(0, i + 1).join(".");
pathSoFar = !0 === optionalChains.get(pathSoFar);
finalPath += pathSoFar ? "?." : ".";
}
finalPath += path[i];
}
return finalPath;
}
function getWarningMessage(deps, singlePrefix, label, fixVerb) {
return 0 === deps.size
? null
: (1 < deps.size ? "" : singlePrefix + " ") +
label +
" " +
(1 < deps.size ? "dependencies" : "dependency") +
": " +
joinEnglish(
Array.from(deps)
.sort()
.map(function (name) {
return "'" + formatDependency(name) + "'";
})
) +
(". Either " +
fixVerb +
" " +
(1 < deps.size ? "them" : "it") +
" or remove the dependency array.");
}
isEffect &&
node.async &&
reportProblem({
node: node,
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"
});
for (
var scope = scopeManager.acquire(node),
pureScopes = new Set(),
componentScope = null,
currentScope = scope.upper;
currentScope;
) {
pureScopes.add(currentScope);
if ("function" === currentScope.type) break;
currentScope = currentScope.upper;
}
if (currentScope) {
componentScope = currentScope;
var isArray = Array.isArray,
memoizedIsStableKnownHookValue = memoizeWithWeakMap(function (
resolved
) {
if (!isArray(resolved.defs)) return !1;
var def = resolved.defs[0];
if (null == def || "VariableDeclarator" !== def.node.type)
return !1;
var init = def.node.init;
if (null == init) return !1;
for (
;
"TSAsExpression" === init.type ||
"AsExpression" === init.type;
)
init = init.expression;
var declaration = def.node.parent;
if (
null == declaration &&
(fastFindReferenceWithParent(
componentScope.block,
def.node.id
),
(declaration = def.node.parent),
null == declaration)
)
return !1;
if (
"const" === declaration.kind &&
"Literal" === init.type &&
("string" === typeof init.value ||
"number" === typeof init.value ||
null === init.value)
)
return !0;
if ("CallExpression" !== init.type) return !1;
init = init.callee;
"MemberExpression" !== init.type ||
"React" !== init.object.name ||
null == init.property ||
init.computed ||
(init = init.property);
if ("Identifier" !== init.type) return !1;
def = def.node.id;
init = init.name;
if ("useRef" === init && "Identifier" === def.type) return !0;
if (
"useState" === init ||
"useReducer" === init ||
"useActionState" === init
) {
if (
"ArrayPattern" === def.type &&
2 === def.elements.length &&
isArray(resolved.identifiers)
) {
if (def.elements[1] === resolved.identifiers[0]) {
if ("useState" === init)
for (
resolved = resolved.references,
declaration = init = 0;
declaration < resolved.length;
declaration++
) {
resolved[declaration].isWrite() && init++;
if (1 < init) return !1;
setStateCallSites.set(
resolved[declaration].identifier,
def.elements[0]
);
}
return !0;
}
if (
def.elements[0] === resolved.identifiers[0] &&
"useState" === init
)
for (
resolved = resolved.references, def = 0;
def < resolved.length;
def++
)
stateVariables.add(resolved[def].identifier);
}
} else if (
"useTransition" === init &&
"ArrayPattern" === def.type &&
2 === def.elements.length &&
Array.isArray(resolved.identifiers) &&
def.elements[1] === resolved.identifiers[0]
)
return !0;
return !1;
}, stableKnownValueCache),
memoizedIsFunctionWithoutCapturedValues = memoizeWithWeakMap(
function (resolved) {
if (!isArray(resolved.defs)) return !1;
resolved = resolved.defs[0];
if (
null == resolved ||
null == resolved.node ||
null == resolved.node.id
)
return !1;
var fnNode = resolved.node,
childScopes = componentScope.childScopes;
resolved = null;
var i;
for (i = 0; i < childScopes.length; i++) {
var childScope = childScopes[i],
childScopeBlock = childScope.block;
if (
("FunctionDeclaration" === fnNode.type &&
childScopeBlock === fnNode) ||
("VariableDeclarator" === fnNode.type &&
childScopeBlock.parent === fnNode)
) {
resolved = childScope;
break;
}
}
if (null == resolved) return !1;
for (i = 0; i < resolved.through.length; i++)
if (
((fnNode = resolved.through[i]),
null != fnNode.resolved &&
pureScopes.has(fnNode.resolved.scope) &&
!memoizedIsStableKnownHookValue(fnNode.resolved))
)
return !1;
return !0;
},
functionWithoutCapturedValueCache
),
currentRefsInEffectCleanup = new Map(),
dependencies = new Map(),
optionalChains = new Map();
gatherDependenciesRecursively(scope);
currentRefsInEffectCleanup.forEach(function (_ref, dependency) {
var dependencyNode = _ref.dependencyNode;
_ref = _ref.reference.resolved.references;
for (
var foundCurrentAssignment = !1, i = 0;
i < _ref.length;
i++
) {
var parent = _ref[i].identifier.parent;
if (
null != parent &&
"MemberExpression" === parent.type &&
!parent.computed &&
"Identifier" === parent.property.type &&
"current" === parent.property.name &&
"AssignmentExpression" === parent.parent.type &&
parent.parent.left === parent
) {
foundCurrentAssignment = !0;
break;
}
}
foundCurrentAssignment ||
reportProblem({
node: dependencyNode.parent.property,
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.")
});
});
var staleAssignments = new Set(),
stableDependencies = new Set();
dependencies.forEach(function (_ref2, key) {
var references = _ref2.references;
_ref2.isStable && stableDependencies.add(key);
references.forEach(function (reference) {
reference.writeExpr &&
((reference = reference.writeExpr),
staleAssignments.has(key) ||
(staleAssignments.add(key),
reportProblem({
node: reference,
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) + ".")
})));
});
});
if (!(0 < staleAssignments.size))
if (declaredDependenciesNode) {
var declaredDependencies = [],
externalDependencies = new Set();
currentScope =
"TSAsExpression" === declaredDependenciesNode.type &&
"ArrayExpression" ===
declaredDependenciesNode.expression.type;
"ArrayExpression" === declaredDependenciesNode.type ||
currentScope
? (currentScope
? declaredDependenciesNode.expression
: declaredDependenciesNode
).elements.forEach(function (declaredDependencyNode) {
if (null !== declaredDependencyNode)
if ("SpreadElement" === declaredDependencyNode.type)
reportProblem({
node: declaredDependencyNode,
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."
});
else {
useEffectEventVariables.has(
declaredDependencyNode
) &&
reportProblem({
node: declaredDependencyNode,
message:
"Functions returned from `useEffectEvent` must not be included in the dependency array. Remove `" +
(getSource(declaredDependencyNode) +
"` from the list."),
suggest: [
{
desc:
"Remove the dependency `" +
getSource(declaredDependencyNode) +
"`",
fix: function (fixer) {
return fixer.removeRange(
declaredDependencyNode.range
);
}
}
]
});
try {
var declaredDependency = analyzePropertyChain(
declaredDependencyNode,
null
);
} catch (error) {
if (/Unsupported node type/.test(error.message)) {
"Literal" === declaredDependencyNode.type
? dependencies.has(
declaredDependencyNode.value
)
? reportProblem({
node: declaredDependencyNode,
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?")
})
: reportProblem({
node: declaredDependencyNode,
message:
"The " +
declaredDependencyNode.raw +
" literal is not a valid dependency because it never changes. You can safely remove it."
})
: reportProblem({
node: declaredDependencyNode,
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."
});
return;
}
throw error;
}
for (
var maybeID = declaredDependencyNode;
"MemberExpression" === maybeID.type ||
"OptionalMemberExpression" === maybeID.type ||
"ChainExpression" === maybeID.type;
)
maybeID =
maybeID.object || maybeID.expression.object;
var isDeclaredInComponent =
!componentScope.through.some(function (ref) {
return ref.identifier === maybeID;
});
declaredDependencies.push({
key: declaredDependency,
node: declaredDependencyNode
});
isDeclaredInComponent ||
externalDependencies.add(declaredDependency);
}
})
: reportProblem({
node: declaredDependenciesNode,
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."
});
var _collectRecommendatio2 = collectRecommendations({
dependencies: dependencies,
declaredDependencies: declaredDependencies,
stableDependencies: stableDependencies,
externalDependencies: externalDependencies,
isEffect: isEffect
});
currentScope = _collectRecommendatio2.unnecessaryDependencies;
var missingDependencies =
_collectRecommendatio2.missingDependencies,
duplicateDependencies =
_collectRecommendatio2.duplicateDependencies,
suggestedDeps =
_collectRecommendatio2.suggestedDependencies;
if (
0 ===
duplicateDependencies.size +
missingDependencies.size +
currentScope.size
)
scanForConstructions({
declaredDependencies: declaredDependencies,
declaredDependenciesNode: declaredDependenciesNode,
componentScope: componentScope,
scope: scope
}).forEach(function (_ref4) {
var construction = _ref4.construction,
isUsedOutsideOfHook = _ref4.isUsedOutsideOfHook;
_ref4 = _ref4.depType;
var wrapperHook =
"function" === _ref4 ? "useCallback" : "useMemo",
constructionType =
"function" === _ref4
? "definition"
: "initialization",
defaultAdvice =
"wrap the " +
constructionType +
" of '" +
construction.name.name +
"' in its own " +
wrapperHook +
"() Hook.";
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);
var suggest;
isUsedOutsideOfHook &&
"Variable" === construction.type &&
"function" === _ref4 &&
(suggest = [
{
desc:
"Wrap the " +
constructionType +
" of '" +
construction.name.name +
"' in its own " +
wrapperHook +
"() Hook.",
fix: function (fixer) {
var _ref5 =
"useMemo" === wrapperHook
? ["useMemo(() => { return ", "; })"]
: ["useCallback(", ")"],
after = _ref5[1];
return [
fixer.insertTextBefore(
construction.node.init,
_ref5[0]
),
fixer.insertTextAfter(
construction.node.init,
after
)
];
}
}
]);
reportProblem({
node: construction.node,
message: defaultAdvice,
suggest: suggest
});
});
else {
!isEffect &&
0 < missingDependencies.size &&
(suggestedDeps = collectRecommendations({
dependencies: dependencies,
declaredDependencies: [],
stableDependencies: stableDependencies,
externalDependencies: externalDependencies,
isEffect: isEffect
}).suggestedDependencies);
(function () {
if (0 === declaredDependencies.length) return !0;
var declaredDepKeys = declaredDependencies.map(
function (dep) {
return dep.key;
}
),
sortedDeclaredDepKeys = declaredDepKeys.slice().sort();
return (
declaredDepKeys.join(",") ===
sortedDeclaredDepKeys.join(",")
);
})() && suggestedDeps.sort();
_collectRecommendatio2 = "";
if (0 < currentScope.size) {
var badRef = null;
Array.from(currentScope.keys()).forEach(function (key) {
null === badRef &&
key.endsWith(".current") &&
(badRef = key);
});
if (null !== badRef)
_collectRecommendatio2 =
" Mutable values like '" +
badRef +
"' aren't valid dependencies because mutating them doesn't re-render the component.";
else if (0 < externalDependencies.size) {
var dep = Array.from(externalDependencies)[0];
scope.set.has(dep) ||
(_collectRecommendatio2 =
" Outer scope values like '" +
dep +
"' aren't valid dependencies because mutating them doesn't re-render the component.");
}
}
if (
!_collectRecommendatio2 &&
missingDependencies.has("props")
) {
scope = dependencies.get("props");
if (null == scope) return;
scope = scope.references;
if (!Array.isArray(scope)) return;
dep = !0;
for (
var i$jscomp$0 = 0;
i$jscomp$0 < scope.length;
i$jscomp$0++
) {
var id = fastFindReferenceWithParent(
componentScope.block,
scope[i$jscomp$0].identifier
);
if (!id) {
dep = !1;
break;
}
id = id.parent;
if (null == id) {
dep = !1;
break;
}
if (
"MemberExpression" !== id.type &&
"OptionalMemberExpression" !== id.type
) {
dep = !1;
break;
}
}
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) + "."));
}
if (
!_collectRecommendatio2 &&
0 < missingDependencies.size
) {
var missingCallbackDep = null;
missingDependencies.forEach(function (missingDep) {
if (!missingCallbackDep) {
var topScopeRef = componentScope.set.get(missingDep),
usedDep = dependencies.get(missingDep);
if (
usedDep.references[0].resolved === topScopeRef &&
((topScopeRef = topScopeRef.defs[0]),
null != topScopeRef &&
null != topScopeRef.name &&
"Parameter" === topScopeRef.type)
) {
topScopeRef = !1;
for (
var id, _i2 = 0;
_i2 < usedDep.references.length;
_i2++
)
if (
((id = usedDep.references[_i2].identifier),
null != id &&
null != id.parent &&
("CallExpression" === id.parent.type ||
"OptionalCallExpression" ===
id.parent.type) &&
id.parent.callee === id)
) {
topScopeRef = !0;
break;
}
topScopeRef && (missingCallbackDep = missingDep);
}
}
});
null !== missingCallbackDep &&
(_collectRecommendatio2 =
" If '" +
missingCallbackDep +
"' changes too often, find the parent component that defines it and wrap that definition in useCallback.");
}
if (
!_collectRecommendatio2 &&
0 < missingDependencies.size
) {
var setStateRecommendation = null;
missingDependencies.forEach(function (missingDep) {
if (null === setStateRecommendation)
for (
var references =
dependencies.get(missingDep).references,
id,
maybeCall,
_i3 = 0;
_i3 < references.length;
_i3++
) {
id = references[_i3].identifier;
for (
maybeCall = id.parent;
null != maybeCall &&
maybeCall !== componentScope.block;
) {
if ("CallExpression" === maybeCall.type) {
var correspondingStateVariable =
setStateCallSites.get(maybeCall.callee);
if (null != correspondingStateVariable) {
correspondingStateVariable.name === missingDep
? (setStateRecommendation = {
missingDep: missingDep,
setter: maybeCall.callee.name,
form: "updater"
})
: stateVariables.has(id)
? (setStateRecommendation = {
missingDep: missingDep,
setter: maybeCall.callee.name,
form: "reducer"
})
: ((id = references[_i3].resolved),
null != id &&
((id = id.defs[0]),
null != id &&
"Parameter" === id.type &&
(setStateRecommendation = {
missingDep: missingDep,
setter: maybeCall.callee.name,
form: "inlineReducer"
})));
break;
}
}
maybeCall = maybeCall.parent;
}
if (null !== setStateRecommendation) break;
}
});
if (null !== setStateRecommendation)
switch (setStateRecommendation.form) {
case "reducer":
_collectRecommendatio2 =
" You can also replace multiple useState variables with useReducer if '" +
(setStateRecommendation.setter +
"' needs the current value of '") +
(setStateRecommendation.missingDep + "'.");
break;
case "inlineReducer":
_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.");
break;
case "updater":
_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.");
break;
default:
throw Error("Unknown case.");
}
}
reportProblem({
node: declaredDependenciesNode,
message:
"React Hook " +
getSource(reactiveHook) +
" has " +
(getWarningMessage(
missingDependencies,
"a",
"missing",
"include"
) ||
getWarningMessage(
currentScope,
"an",
"unnecessary",
"exclude"
) ||
getWarningMessage(
duplicateDependencies,
"a",
"duplicate",
"omit"
)) +
_collectRecommendatio2,
suggest: [
{
desc:
"Update the dependencies array to be: [" +
suggestedDeps.map(formatDependency).join(", ") +
"]",
fix: function (fixer) {
return fixer.replaceText(
declaredDependenciesNode,
"[" +
suggestedDeps.map(formatDependency).join(", ") +
"]"
);
}
}
]
});
}
} else {
var setStateInsideEffectWithoutDeps = null;
dependencies.forEach(function (_ref3, key) {
setStateInsideEffectWithoutDeps ||
_ref3.references.forEach(function (reference) {
if (
!setStateInsideEffectWithoutDeps &&
setStateCallSites.has(reference.identifier)
) {
for (
reference = reference.from;
"function" !== reference.type;
)
reference = reference.upper;
reference.block === node &&
(setStateInsideEffectWithoutDeps = key);
}
});
});
if (setStateInsideEffectWithoutDeps) {
var _suggestedDependencies = collectRecommendations({
dependencies: dependencies,
declaredDependencies: [],
stableDependencies: stableDependencies,
externalDependencies: new Set(),
isEffect: !0
}).suggestedDependencies;
reportProblem({
node: reactiveHook,
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."),
suggest: [
{
desc:
"Add dependencies array: [" +
_suggestedDependencies.join(", ") +
"]",
fix: function (fixer) {
return fixer.insertTextAfter(
node,
", [" + _suggestedDependencies.join(", ") + "]"
);
}
}
]
});
}
}
}
}
var enableDangerousAutofixThisMayCauseInfiniteLoops =
(context.options &&
context.options[0] &&
context.options[0]
.enableDangerousAutofixThisMayCauseInfiniteLoops) ||
!1,
options = {
additionalHooks:
context.options &&
context.options[0] &&
context.options[0].additionalHooks
? new RegExp(context.options[0].additionalHooks)
: void 0,
enableDangerousAutofixThisMayCauseInfiniteLoops:
enableDangerousAutofixThisMayCauseInfiniteLoops
},
getSource =
"function" === typeof context.getSource
? function (node) {
return context.getSource(node);
}
: function (node) {
return context.sourceCode.getText(node);
},
getScope =
"function" === typeof context.getScope
? function () {
return context.getScope();
}
: function (node) {
return context.sourceCode.getScope(node);
},
scopeManager = context.getSourceCode().scopeManager,
setStateCallSites = new WeakMap(),
stateVariables = new WeakSet(),
stableKnownValueCache = new WeakMap(),
functionWithoutCapturedValueCache = new WeakMap(),
useEffectEventVariables = new WeakSet();
return {
CallExpression: function (node) {
var callbackIndex = getReactiveHookCallbackIndex(
node.callee,
options
);
if (-1 !== callbackIndex) {
var callback = node.arguments[callbackIndex],
reactiveHook = node.callee,
reactiveHookName =
getNodeWithoutReactNamespace(reactiveHook).name;
node = node.arguments[callbackIndex + 1];
var declaredDependenciesNode =
!node ||
("Identifier" === node.type && "undefined" === node.name)
? void 0
: node;
node = /Effect($|[^a-z])/g.test(reactiveHookName);
if (callback)
if (declaredDependenciesNode || node) {
switch (callback.type) {
case "FunctionExpression":
case "ArrowFunctionExpression":
visitFunctionWithDependencies(
callback,
declaredDependenciesNode,
reactiveHook,
reactiveHookName,
node
);
return;
case "TSAsExpression":
visitFunctionWithDependencies(
callback.expression,
declaredDependenciesNode,
reactiveHook,
reactiveHookName,
node
);
return;
case "Identifier":
if (
!declaredDependenciesNode ||
(declaredDependenciesNode.elements &&
declaredDependenciesNode.elements.some(
function (el) {
return (
el &&
"Identifier" === el.type &&
el.name === callback.name
);
}
))
)
return;
callbackIndex = getScope(callback).set.get(
callback.name
);
if (null == callbackIndex || null == callbackIndex.defs)
return;
callbackIndex = callbackIndex.defs[0];
if (!callbackIndex || !callbackIndex.node) break;
if (
"Variable" !== callbackIndex.type &&
"FunctionName" !== callbackIndex.type
)
break;
switch (callbackIndex.node.type) {
case "FunctionDeclaration":
visitFunctionWithDependencies(
callbackIndex.node,
declaredDependenciesNode,
reactiveHook,
reactiveHookName,
node
);
return;
case "VariableDeclarator":
if ((callbackIndex = callbackIndex.node.init))
switch (callbackIndex.type) {
case "ArrowFunctionExpression":
case "FunctionExpression":
visitFunctionWithDependencies(
callbackIndex,
declaredDependenciesNode,
reactiveHook,
reactiveHookName,
node
);
return;
}
}
break;
default:
reportProblem({
node: reactiveHook,
message:
"React Hook " +
reactiveHookName +
" received a function whose dependencies are unknown. Pass an inline function instead."
});
return;
}
reportProblem({
node: reactiveHook,
message:
"React Hook " +
reactiveHookName +
" has a missing dependency: '" +
callback.name +
"'. Either include it or remove the dependency array.",
suggest: [
{
desc:
"Update the dependencies array to be: [" +
callback.name +
"]",
fix: function (fixer) {
return fixer.replaceText(
declaredDependenciesNode,
"[" + callback.name + "]"
);
}
}
]
});
} else
("useMemo" !== reactiveHookName &&
"useCallback" !== reactiveHookName) ||
reportProblem({
node: reactiveHook,
message:
"React Hook " +
reactiveHookName +
" does nothing when called with only one argument. Did you forget to pass an array of dependencies?"
});
else
reportProblem({
node: reactiveHook,
message:
"React Hook " +
reactiveHookName +
" requires an effect callback. Did you forget to pass a callback to the hook?"
});
}
}
};
}
}
};
})();