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