]> git.proxmox.com Git - pve-eslint.git/blob - eslint/lib/rules/max-statements.js
import 8.23.1 source
[pve-eslint.git] / eslint / lib / rules / max-statements.js
1 /**
2 * @fileoverview A rule to set the maximum number of statements in a function.
3 * @author Ian Christian Myers
4 */
5
6 "use strict";
7
8 //------------------------------------------------------------------------------
9 // Requirements
10 //------------------------------------------------------------------------------
11
12 const astUtils = require("./utils/ast-utils");
13 const { upperCaseFirst } = require("../shared/string-utils");
14
15 //------------------------------------------------------------------------------
16 // Rule Definition
17 //------------------------------------------------------------------------------
18
19 /** @type {import('../shared/types').Rule} */
20 module.exports = {
21 meta: {
22 type: "suggestion",
23
24 docs: {
25 description: "Enforce a maximum number of statements allowed in function blocks",
26 recommended: false,
27 url: "https://eslint.org/docs/rules/max-statements"
28 },
29
30 schema: [
31 {
32 oneOf: [
33 {
34 type: "integer",
35 minimum: 0
36 },
37 {
38 type: "object",
39 properties: {
40 maximum: {
41 type: "integer",
42 minimum: 0
43 },
44 max: {
45 type: "integer",
46 minimum: 0
47 }
48 },
49 additionalProperties: false
50 }
51 ]
52 },
53 {
54 type: "object",
55 properties: {
56 ignoreTopLevelFunctions: {
57 type: "boolean"
58 }
59 },
60 additionalProperties: false
61 }
62 ],
63 messages: {
64 exceed: "{{name}} has too many statements ({{count}}). Maximum allowed is {{max}}."
65 }
66 },
67
68 create(context) {
69
70 //--------------------------------------------------------------------------
71 // Helpers
72 //--------------------------------------------------------------------------
73
74 const functionStack = [],
75 option = context.options[0],
76 ignoreTopLevelFunctions = context.options[1] && context.options[1].ignoreTopLevelFunctions || false,
77 topLevelFunctions = [];
78 let maxStatements = 10;
79
80 if (
81 typeof option === "object" &&
82 (Object.prototype.hasOwnProperty.call(option, "maximum") || Object.prototype.hasOwnProperty.call(option, "max"))
83 ) {
84 maxStatements = option.maximum || option.max;
85 } else if (typeof option === "number") {
86 maxStatements = option;
87 }
88
89 /**
90 * Reports a node if it has too many statements
91 * @param {ASTNode} node node to evaluate
92 * @param {int} count Number of statements in node
93 * @param {int} max Maximum number of statements allowed
94 * @returns {void}
95 * @private
96 */
97 function reportIfTooManyStatements(node, count, max) {
98 if (count > max) {
99 const name = upperCaseFirst(astUtils.getFunctionNameWithKind(node));
100
101 context.report({
102 node,
103 messageId: "exceed",
104 data: { name, count, max }
105 });
106 }
107 }
108
109 /**
110 * When parsing a new function, store it in our function stack
111 * @returns {void}
112 * @private
113 */
114 function startFunction() {
115 functionStack.push(0);
116 }
117
118 /**
119 * Evaluate the node at the end of function
120 * @param {ASTNode} node node to evaluate
121 * @returns {void}
122 * @private
123 */
124 function endFunction(node) {
125 const count = functionStack.pop();
126
127 /*
128 * This rule does not apply to class static blocks, but we have to track them so
129 * that statements in them do not count as statements in the enclosing function.
130 */
131 if (node.type === "StaticBlock") {
132 return;
133 }
134
135 if (ignoreTopLevelFunctions && functionStack.length === 0) {
136 topLevelFunctions.push({ node, count });
137 } else {
138 reportIfTooManyStatements(node, count, maxStatements);
139 }
140 }
141
142 /**
143 * Increment the count of the functions
144 * @param {ASTNode} node node to evaluate
145 * @returns {void}
146 * @private
147 */
148 function countStatements(node) {
149 functionStack[functionStack.length - 1] += node.body.length;
150 }
151
152 //--------------------------------------------------------------------------
153 // Public API
154 //--------------------------------------------------------------------------
155
156 return {
157 FunctionDeclaration: startFunction,
158 FunctionExpression: startFunction,
159 ArrowFunctionExpression: startFunction,
160 StaticBlock: startFunction,
161
162 BlockStatement: countStatements,
163
164 "FunctionDeclaration:exit": endFunction,
165 "FunctionExpression:exit": endFunction,
166 "ArrowFunctionExpression:exit": endFunction,
167 "StaticBlock:exit": endFunction,
168
169 "Program:exit"() {
170 if (topLevelFunctions.length === 1) {
171 return;
172 }
173
174 topLevelFunctions.forEach(element => {
175 const count = element.count;
176 const node = element.node;
177
178 reportIfTooManyStatements(node, count, maxStatements);
179 });
180 }
181 };
182
183 }
184 };