massive update, probably broken
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-prettier / node_modules / eslint / lib / rules / complexity.js
1 /**
2  * @fileoverview Counts the cyclomatic complexity of each function of the script. See http://en.wikipedia.org/wiki/Cyclomatic_complexity.
3  * Counts the number of if, conditional, for, while, try, switch/case,
4  * @author Patrick Brosset
5  */
6
7 "use strict";
8
9 //------------------------------------------------------------------------------
10 // Requirements
11 //------------------------------------------------------------------------------
12
13 const astUtils = require("./utils/ast-utils");
14 const { upperCaseFirst } = require("../shared/string-utils");
15
16 //------------------------------------------------------------------------------
17 // Rule Definition
18 //------------------------------------------------------------------------------
19
20 module.exports = {
21     meta: {
22         type: "suggestion",
23
24         docs: {
25             description: "enforce a maximum cyclomatic complexity allowed in a program",
26             category: "Best Practices",
27             recommended: false,
28             url: "https://eslint.org/docs/rules/complexity"
29         },
30
31         schema: [
32             {
33                 oneOf: [
34                     {
35                         type: "integer",
36                         minimum: 0
37                     },
38                     {
39                         type: "object",
40                         properties: {
41                             maximum: {
42                                 type: "integer",
43                                 minimum: 0
44                             },
45                             max: {
46                                 type: "integer",
47                                 minimum: 0
48                             }
49                         },
50                         additionalProperties: false
51                     }
52                 ]
53             }
54         ],
55
56         messages: {
57             complex: "{{name}} has a complexity of {{complexity}}. Maximum allowed is {{max}}."
58         }
59     },
60
61     create(context) {
62         const option = context.options[0];
63         let THRESHOLD = 20;
64
65         if (
66             typeof option === "object" &&
67             (Object.prototype.hasOwnProperty.call(option, "maximum") || Object.prototype.hasOwnProperty.call(option, "max"))
68         ) {
69             THRESHOLD = option.maximum || option.max;
70         } else if (typeof option === "number") {
71             THRESHOLD = option;
72         }
73
74         //--------------------------------------------------------------------------
75         // Helpers
76         //--------------------------------------------------------------------------
77
78         // Using a stack to store complexity (handling nested functions)
79         const fns = [];
80
81         /**
82          * When parsing a new function, store it in our function stack
83          * @returns {void}
84          * @private
85          */
86         function startFunction() {
87             fns.push(1);
88         }
89
90         /**
91          * Evaluate the node at the end of function
92          * @param {ASTNode} node node to evaluate
93          * @returns {void}
94          * @private
95          */
96         function endFunction(node) {
97             const name = upperCaseFirst(astUtils.getFunctionNameWithKind(node));
98             const complexity = fns.pop();
99
100             if (complexity > THRESHOLD) {
101                 context.report({
102                     node,
103                     messageId: "complex",
104                     data: { name, complexity, max: THRESHOLD }
105                 });
106             }
107         }
108
109         /**
110          * Increase the complexity of the function in context
111          * @returns {void}
112          * @private
113          */
114         function increaseComplexity() {
115             if (fns.length) {
116                 fns[fns.length - 1]++;
117             }
118         }
119
120         /**
121          * Increase the switch complexity in context
122          * @param {ASTNode} node node to evaluate
123          * @returns {void}
124          * @private
125          */
126         function increaseSwitchComplexity(node) {
127
128             // Avoiding `default`
129             if (node.test) {
130                 increaseComplexity();
131             }
132         }
133
134         //--------------------------------------------------------------------------
135         // Public API
136         //--------------------------------------------------------------------------
137
138         return {
139             FunctionDeclaration: startFunction,
140             FunctionExpression: startFunction,
141             ArrowFunctionExpression: startFunction,
142             "FunctionDeclaration:exit": endFunction,
143             "FunctionExpression:exit": endFunction,
144             "ArrowFunctionExpression:exit": endFunction,
145
146             CatchClause: increaseComplexity,
147             ConditionalExpression: increaseComplexity,
148             LogicalExpression: increaseComplexity,
149             ForStatement: increaseComplexity,
150             ForInStatement: increaseComplexity,
151             ForOfStatement: increaseComplexity,
152             IfStatement: increaseComplexity,
153             SwitchCase: increaseSwitchComplexity,
154             WhileStatement: increaseComplexity,
155             DoWhileStatement: increaseComplexity,
156
157             AssignmentExpression(node) {
158                 if (astUtils.isLogicalAssignmentOperator(node.operator)) {
159                     increaseComplexity();
160                 }
161             }
162         };
163
164     }
165 };