]> git.proxmox.com Git - pve-eslint.git/blob - eslint/lib/rules/no-empty-function.js
8b1073a59d86444d89bf1cb16b0a274507a3fb6f
[pve-eslint.git] / eslint / lib / rules / no-empty-function.js
1 /**
2 * @fileoverview Rule to disallow empty functions.
3 * @author Toru Nagashima
4 */
5
6 "use strict";
7
8 //------------------------------------------------------------------------------
9 // Requirements
10 //------------------------------------------------------------------------------
11
12 const astUtils = require("./utils/ast-utils");
13
14 //------------------------------------------------------------------------------
15 // Helpers
16 //------------------------------------------------------------------------------
17
18 const ALLOW_OPTIONS = Object.freeze([
19 "functions",
20 "arrowFunctions",
21 "generatorFunctions",
22 "methods",
23 "generatorMethods",
24 "getters",
25 "setters",
26 "constructors",
27 "asyncFunctions",
28 "asyncMethods"
29 ]);
30
31 /**
32 * Gets the kind of a given function node.
33 * @param {ASTNode} node A function node to get. This is one of
34 * an ArrowFunctionExpression, a FunctionDeclaration, or a
35 * FunctionExpression.
36 * @returns {string} The kind of the function. This is one of "functions",
37 * "arrowFunctions", "generatorFunctions", "asyncFunctions", "methods",
38 * "generatorMethods", "asyncMethods", "getters", "setters", and
39 * "constructors".
40 */
41 function getKind(node) {
42 const parent = node.parent;
43 let kind = "";
44
45 if (node.type === "ArrowFunctionExpression") {
46 return "arrowFunctions";
47 }
48
49 // Detects main kind.
50 if (parent.type === "Property") {
51 if (parent.kind === "get") {
52 return "getters";
53 }
54 if (parent.kind === "set") {
55 return "setters";
56 }
57 kind = parent.method ? "methods" : "functions";
58
59 } else if (parent.type === "MethodDefinition") {
60 if (parent.kind === "get") {
61 return "getters";
62 }
63 if (parent.kind === "set") {
64 return "setters";
65 }
66 if (parent.kind === "constructor") {
67 return "constructors";
68 }
69 kind = "methods";
70
71 } else {
72 kind = "functions";
73 }
74
75 // Detects prefix.
76 let prefix = "";
77
78 if (node.generator) {
79 prefix = "generator";
80 } else if (node.async) {
81 prefix = "async";
82 } else {
83 return kind;
84 }
85 return prefix + kind[0].toUpperCase() + kind.slice(1);
86 }
87
88 //------------------------------------------------------------------------------
89 // Rule Definition
90 //------------------------------------------------------------------------------
91
92 module.exports = {
93 meta: {
94 type: "suggestion",
95
96 docs: {
97 description: "disallow empty functions",
98 recommended: false,
99 url: "https://eslint.org/docs/rules/no-empty-function"
100 },
101
102 schema: [
103 {
104 type: "object",
105 properties: {
106 allow: {
107 type: "array",
108 items: { enum: ALLOW_OPTIONS },
109 uniqueItems: true
110 }
111 },
112 additionalProperties: false
113 }
114 ],
115
116 messages: {
117 unexpected: "Unexpected empty {{name}}."
118 }
119 },
120
121 create(context) {
122 const options = context.options[0] || {};
123 const allowed = options.allow || [];
124
125 const sourceCode = context.getSourceCode();
126
127 /**
128 * Reports a given function node if the node matches the following patterns.
129 *
130 * - Not allowed by options.
131 * - The body is empty.
132 * - The body doesn't have any comments.
133 * @param {ASTNode} node A function node to report. This is one of
134 * an ArrowFunctionExpression, a FunctionDeclaration, or a
135 * FunctionExpression.
136 * @returns {void}
137 */
138 function reportIfEmpty(node) {
139 const kind = getKind(node);
140 const name = astUtils.getFunctionNameWithKind(node);
141 const innerComments = sourceCode.getTokens(node.body, {
142 includeComments: true,
143 filter: astUtils.isCommentToken
144 });
145
146 if (allowed.indexOf(kind) === -1 &&
147 node.body.type === "BlockStatement" &&
148 node.body.body.length === 0 &&
149 innerComments.length === 0
150 ) {
151 context.report({
152 node,
153 loc: node.body.loc,
154 messageId: "unexpected",
155 data: { name }
156 });
157 }
158 }
159
160 return {
161 ArrowFunctionExpression: reportIfEmpty,
162 FunctionDeclaration: reportIfEmpty,
163 FunctionExpression: reportIfEmpty
164 };
165 }
166 };