.gitignore added
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-prettier / node_modules / 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             category: "Best Practices",
99             recommended: false,
100             url: "https://eslint.org/docs/rules/no-empty-function"
101         },
102
103         schema: [
104             {
105                 type: "object",
106                 properties: {
107                     allow: {
108                         type: "array",
109                         items: { enum: ALLOW_OPTIONS },
110                         uniqueItems: true
111                     }
112                 },
113                 additionalProperties: false
114             }
115         ],
116
117         messages: {
118             unexpected: "Unexpected empty {{name}}."
119         }
120     },
121
122     create(context) {
123         const options = context.options[0] || {};
124         const allowed = options.allow || [];
125
126         const sourceCode = context.getSourceCode();
127
128         /**
129          * Reports a given function node if the node matches the following patterns.
130          *
131          * - Not allowed by options.
132          * - The body is empty.
133          * - The body doesn't have any comments.
134          * @param {ASTNode} node A function node to report. This is one of
135          *      an ArrowFunctionExpression, a FunctionDeclaration, or a
136          *      FunctionExpression.
137          * @returns {void}
138          */
139         function reportIfEmpty(node) {
140             const kind = getKind(node);
141             const name = astUtils.getFunctionNameWithKind(node);
142             const innerComments = sourceCode.getTokens(node.body, {
143                 includeComments: true,
144                 filter: astUtils.isCommentToken
145             });
146
147             if (allowed.indexOf(kind) === -1 &&
148                 node.body.type === "BlockStatement" &&
149                 node.body.body.length === 0 &&
150                 innerComments.length === 0
151             ) {
152                 context.report({
153                     node,
154                     loc: node.body.loc,
155                     messageId: "unexpected",
156                     data: { name }
157                 });
158             }
159         }
160
161         return {
162             ArrowFunctionExpression: reportIfEmpty,
163             FunctionDeclaration: reportIfEmpty,
164             FunctionExpression: reportIfEmpty
165         };
166     }
167 };