2 * @fileoverview A rule to set the maximum number of statements in a function.
3 * @author Ian Christian Myers
8 //------------------------------------------------------------------------------
10 //------------------------------------------------------------------------------
12 const lodash = require("lodash");
14 const astUtils = require("./utils/ast-utils");
16 //------------------------------------------------------------------------------
18 //------------------------------------------------------------------------------
25 description: "enforce a maximum number of statements allowed in function blocks",
26 category: "Stylistic Issues",
28 url: "https://eslint.org/docs/rules/max-statements"
50 additionalProperties: false
57 ignoreTopLevelFunctions: {
61 additionalProperties: false
65 exceed: "{{name}} has too many statements ({{count}}). Maximum allowed is {{max}}."
71 //--------------------------------------------------------------------------
73 //--------------------------------------------------------------------------
75 const functionStack = [],
76 option = context.options[0],
77 ignoreTopLevelFunctions = context.options[1] && context.options[1].ignoreTopLevelFunctions || false,
78 topLevelFunctions = [];
79 let maxStatements = 10;
82 typeof option === "object" &&
83 (Object.prototype.hasOwnProperty.call(option, "maximum") || Object.prototype.hasOwnProperty.call(option, "max"))
85 maxStatements = option.maximum || option.max;
86 } else if (typeof option === "number") {
87 maxStatements = option;
91 * Reports a node if it has too many statements
92 * @param {ASTNode} node node to evaluate
93 * @param {int} count Number of statements in node
94 * @param {int} max Maximum number of statements allowed
98 function reportIfTooManyStatements(node, count, max) {
100 const name = lodash.upperFirst(astUtils.getFunctionNameWithKind(node));
105 data: { name, count, max }
111 * When parsing a new function, store it in our function stack
115 function startFunction() {
116 functionStack.push(0);
120 * Evaluate the node at the end of function
121 * @param {ASTNode} node node to evaluate
125 function endFunction(node) {
126 const count = functionStack.pop();
128 if (ignoreTopLevelFunctions && functionStack.length === 0) {
129 topLevelFunctions.push({ node, count });
131 reportIfTooManyStatements(node, count, maxStatements);
136 * Increment the count of the functions
137 * @param {ASTNode} node node to evaluate
141 function countStatements(node) {
142 functionStack[functionStack.length - 1] += node.body.length;
145 //--------------------------------------------------------------------------
147 //--------------------------------------------------------------------------
150 FunctionDeclaration: startFunction,
151 FunctionExpression: startFunction,
152 ArrowFunctionExpression: startFunction,
154 BlockStatement: countStatements,
156 "FunctionDeclaration:exit": endFunction,
157 "FunctionExpression:exit": endFunction,
158 "ArrowFunctionExpression:exit": endFunction,
161 if (topLevelFunctions.length === 1) {
165 topLevelFunctions.forEach(element => {
166 const count = element.count;
167 const node = element.node;
169 reportIfTooManyStatements(node, count, maxStatements);