2 * @fileoverview Rule to enforce a maximum number of nested callbacks.
3 * @author Ian Christian Myers
8 //------------------------------------------------------------------------------
10 //------------------------------------------------------------------------------
17 description: "enforce a maximum depth that callbacks can be nested",
18 category: "Stylistic Issues",
20 url: "https://eslint.org/docs/rules/max-nested-callbacks"
42 additionalProperties: false
48 exceed: "Too many nested callbacks ({{num}}). Maximum allowed is {{max}}."
54 //--------------------------------------------------------------------------
56 //--------------------------------------------------------------------------
57 const option = context.options[0];
61 typeof option === "object" &&
62 (Object.prototype.hasOwnProperty.call(option, "maximum") || Object.prototype.hasOwnProperty.call(option, "max"))
64 THRESHOLD = option.maximum || option.max;
65 } else if (typeof option === "number") {
69 //--------------------------------------------------------------------------
71 //--------------------------------------------------------------------------
73 const callbackStack = [];
76 * Checks a given function node for too many callbacks.
77 * @param {ASTNode} node The node to check.
81 function checkFunction(node) {
82 const parent = node.parent;
84 if (parent.type === "CallExpression") {
85 callbackStack.push(node);
88 if (callbackStack.length > THRESHOLD) {
89 const opts = { num: callbackStack.length, max: THRESHOLD };
91 context.report({ node, messageId: "exceed", data: opts });
96 * Pops the call stack.
100 function popStack() {
104 //--------------------------------------------------------------------------
106 //--------------------------------------------------------------------------
109 ArrowFunctionExpression: checkFunction,
110 "ArrowFunctionExpression:exit": popStack,
112 FunctionExpression: checkFunction,
113 "FunctionExpression:exit": popStack