]> git.proxmox.com Git - pve-eslint.git/blob - eslint/lib/rules/max-depth.js
import 8.3.0 source
[pve-eslint.git] / eslint / lib / rules / max-depth.js
1 /**
2 * @fileoverview A rule to set the maximum depth block can be nested in a function.
3 * @author Ian Christian Myers
4 */
5
6 "use strict";
7
8 //------------------------------------------------------------------------------
9 // Rule Definition
10 //------------------------------------------------------------------------------
11
12 module.exports = {
13 meta: {
14 type: "suggestion",
15
16 docs: {
17 description: "enforce a maximum depth that blocks can be nested",
18 recommended: false,
19 url: "https://eslint.org/docs/rules/max-depth"
20 },
21
22 schema: [
23 {
24 oneOf: [
25 {
26 type: "integer",
27 minimum: 0
28 },
29 {
30 type: "object",
31 properties: {
32 maximum: {
33 type: "integer",
34 minimum: 0
35 },
36 max: {
37 type: "integer",
38 minimum: 0
39 }
40 },
41 additionalProperties: false
42 }
43 ]
44 }
45 ],
46 messages: {
47 tooDeeply: "Blocks are nested too deeply ({{depth}}). Maximum allowed is {{maxDepth}}."
48 }
49 },
50
51 create(context) {
52
53 //--------------------------------------------------------------------------
54 // Helpers
55 //--------------------------------------------------------------------------
56
57 const functionStack = [],
58 option = context.options[0];
59 let maxDepth = 4;
60
61 if (
62 typeof option === "object" &&
63 (Object.prototype.hasOwnProperty.call(option, "maximum") || Object.prototype.hasOwnProperty.call(option, "max"))
64 ) {
65 maxDepth = option.maximum || option.max;
66 }
67 if (typeof option === "number") {
68 maxDepth = option;
69 }
70
71 /**
72 * When parsing a new function, store it in our function stack
73 * @returns {void}
74 * @private
75 */
76 function startFunction() {
77 functionStack.push(0);
78 }
79
80 /**
81 * When parsing is done then pop out the reference
82 * @returns {void}
83 * @private
84 */
85 function endFunction() {
86 functionStack.pop();
87 }
88
89 /**
90 * Save the block and Evaluate the node
91 * @param {ASTNode} node node to evaluate
92 * @returns {void}
93 * @private
94 */
95 function pushBlock(node) {
96 const len = ++functionStack[functionStack.length - 1];
97
98 if (len > maxDepth) {
99 context.report({ node, messageId: "tooDeeply", data: { depth: len, maxDepth } });
100 }
101 }
102
103 /**
104 * Pop the saved block
105 * @returns {void}
106 * @private
107 */
108 function popBlock() {
109 functionStack[functionStack.length - 1]--;
110 }
111
112 //--------------------------------------------------------------------------
113 // Public API
114 //--------------------------------------------------------------------------
115
116 return {
117 Program: startFunction,
118 FunctionDeclaration: startFunction,
119 FunctionExpression: startFunction,
120 ArrowFunctionExpression: startFunction,
121 StaticBlock: startFunction,
122
123 IfStatement(node) {
124 if (node.parent.type !== "IfStatement") {
125 pushBlock(node);
126 }
127 },
128 SwitchStatement: pushBlock,
129 TryStatement: pushBlock,
130 DoWhileStatement: pushBlock,
131 WhileStatement: pushBlock,
132 WithStatement: pushBlock,
133 ForStatement: pushBlock,
134 ForInStatement: pushBlock,
135 ForOfStatement: pushBlock,
136
137 "IfStatement:exit": popBlock,
138 "SwitchStatement:exit": popBlock,
139 "TryStatement:exit": popBlock,
140 "DoWhileStatement:exit": popBlock,
141 "WhileStatement:exit": popBlock,
142 "WithStatement:exit": popBlock,
143 "ForStatement:exit": popBlock,
144 "ForInStatement:exit": popBlock,
145 "ForOfStatement:exit": popBlock,
146
147 "FunctionDeclaration:exit": endFunction,
148 "FunctionExpression:exit": endFunction,
149 "ArrowFunctionExpression:exit": endFunction,
150 "StaticBlock:exit": endFunction,
151 "Program:exit": endFunction
152 };
153
154 }
155 };