.gitignore added
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-prettier / node_modules / 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             category: "Stylistic Issues",
19             recommended: false,
20             url: "https://eslint.org/docs/rules/max-depth"
21         },
22
23         schema: [
24             {
25                 oneOf: [
26                     {
27                         type: "integer",
28                         minimum: 0
29                     },
30                     {
31                         type: "object",
32                         properties: {
33                             maximum: {
34                                 type: "integer",
35                                 minimum: 0
36                             },
37                             max: {
38                                 type: "integer",
39                                 minimum: 0
40                             }
41                         },
42                         additionalProperties: false
43                     }
44                 ]
45             }
46         ],
47         messages: {
48             tooDeeply: "Blocks are nested too deeply ({{depth}}). Maximum allowed is {{maxDepth}}."
49         }
50     },
51
52     create(context) {
53
54         //--------------------------------------------------------------------------
55         // Helpers
56         //--------------------------------------------------------------------------
57
58         const functionStack = [],
59             option = context.options[0];
60         let maxDepth = 4;
61
62         if (
63             typeof option === "object" &&
64             (Object.prototype.hasOwnProperty.call(option, "maximum") || Object.prototype.hasOwnProperty.call(option, "max"))
65         ) {
66             maxDepth = option.maximum || option.max;
67         }
68         if (typeof option === "number") {
69             maxDepth = option;
70         }
71
72         /**
73          * When parsing a new function, store it in our function stack
74          * @returns {void}
75          * @private
76          */
77         function startFunction() {
78             functionStack.push(0);
79         }
80
81         /**
82          * When parsing is done then pop out the reference
83          * @returns {void}
84          * @private
85          */
86         function endFunction() {
87             functionStack.pop();
88         }
89
90         /**
91          * Save the block and Evaluate the node
92          * @param {ASTNode} node node to evaluate
93          * @returns {void}
94          * @private
95          */
96         function pushBlock(node) {
97             const len = ++functionStack[functionStack.length - 1];
98
99             if (len > maxDepth) {
100                 context.report({ node, messageId: "tooDeeply", data: { depth: len, maxDepth } });
101             }
102         }
103
104         /**
105          * Pop the saved block
106          * @returns {void}
107          * @private
108          */
109         function popBlock() {
110             functionStack[functionStack.length - 1]--;
111         }
112
113         //--------------------------------------------------------------------------
114         // Public API
115         //--------------------------------------------------------------------------
116
117         return {
118             Program: startFunction,
119             FunctionDeclaration: startFunction,
120             FunctionExpression: startFunction,
121             ArrowFunctionExpression: 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             "Program:exit": endFunction
151         };
152
153     }
154 };