Permalink
Cannot retrieve contributors at this time
| /** | |
| * @fileoverview Rule to disallow empty functions. | |
| * @author Toru Nagashima | |
| */ | |
| "use strict"; | |
| //------------------------------------------------------------------------------ | |
| // Requirements | |
| //------------------------------------------------------------------------------ | |
| const astUtils = require("./utils/ast-utils"); | |
| //------------------------------------------------------------------------------ | |
| // Helpers | |
| //------------------------------------------------------------------------------ | |
| const ALLOW_OPTIONS = Object.freeze([ | |
| "functions", | |
| "arrowFunctions", | |
| "generatorFunctions", | |
| "methods", | |
| "generatorMethods", | |
| "getters", | |
| "setters", | |
| "constructors" | |
| ]); | |
| /** | |
| * Gets the kind of a given function node. | |
| * @param {ASTNode} node A function node to get. This is one of | |
| * an ArrowFunctionExpression, a FunctionDeclaration, or a | |
| * FunctionExpression. | |
| * @returns {string} The kind of the function. This is one of "functions", | |
| * "arrowFunctions", "generatorFunctions", "asyncFunctions", "methods", | |
| * "generatorMethods", "asyncMethods", "getters", "setters", and | |
| * "constructors". | |
| */ | |
| function getKind(node) { | |
| const parent = node.parent; | |
| let kind = ""; | |
| if (node.type === "ArrowFunctionExpression") { | |
| return "arrowFunctions"; | |
| } | |
| // Detects main kind. | |
| if (parent.type === "Property") { | |
| if (parent.kind === "get") { | |
| return "getters"; | |
| } | |
| if (parent.kind === "set") { | |
| return "setters"; | |
| } | |
| kind = parent.method ? "methods" : "functions"; | |
| } else if (parent.type === "MethodDefinition") { | |
| if (parent.kind === "get") { | |
| return "getters"; | |
| } | |
| if (parent.kind === "set") { | |
| return "setters"; | |
| } | |
| if (parent.kind === "constructor") { | |
| return "constructors"; | |
| } | |
| kind = "methods"; | |
| } else { | |
| kind = "functions"; | |
| } | |
| // Detects prefix. | |
| let prefix = ""; | |
| if (node.generator) { | |
| prefix = "generator"; | |
| } else if (node.async) { | |
| prefix = "async"; | |
| } else { | |
| return kind; | |
| } | |
| return prefix + kind[0].toUpperCase() + kind.slice(1); | |
| } | |
| //------------------------------------------------------------------------------ | |
| // Rule Definition | |
| //------------------------------------------------------------------------------ | |
| module.exports = { | |
| meta: { | |
| type: "suggestion", | |
| docs: { | |
| description: "disallow empty functions", | |
| category: "Best Practices", | |
| recommended: false, | |
| url: "https://eslint.org/docs/rules/no-empty-function" | |
| }, | |
| schema: [ | |
| { | |
| type: "object", | |
| properties: { | |
| allow: { | |
| type: "array", | |
| items: { enum: ALLOW_OPTIONS }, | |
| uniqueItems: true | |
| } | |
| }, | |
| additionalProperties: false | |
| } | |
| ], | |
| messages: { | |
| unexpected: "Unexpected empty {{name}}." | |
| } | |
| }, | |
| create(context) { | |
| const options = context.options[0] || {}; | |
| const allowed = options.allow || []; | |
| const sourceCode = context.getSourceCode(); | |
| /** | |
| * Reports a given function node if the node matches the following patterns. | |
| * | |
| * - Not allowed by options. | |
| * - The body is empty. | |
| * - The body doesn't have any comments. | |
| * @param {ASTNode} node A function node to report. This is one of | |
| * an ArrowFunctionExpression, a FunctionDeclaration, or a | |
| * FunctionExpression. | |
| * @returns {void} | |
| */ | |
| function reportIfEmpty(node) { | |
| const kind = getKind(node); | |
| const name = astUtils.getFunctionNameWithKind(node); | |
| const innerComments = sourceCode.getTokens(node.body, { | |
| includeComments: true, | |
| filter: astUtils.isCommentToken | |
| }); | |
| if (allowed.indexOf(kind) === -1 && | |
| node.body.type === "BlockStatement" && | |
| node.body.body.length === 0 && | |
| innerComments.length === 0 | |
| ) { | |
| context.report({ | |
| node, | |
| loc: node.body.loc.start, | |
| messageId: "unexpected", | |
| data: { name } | |
| }); | |
| } | |
| } | |
| return { | |
| ArrowFunctionExpression: reportIfEmpty, | |
| FunctionDeclaration: reportIfEmpty, | |
| FunctionExpression: reportIfEmpty | |
| }; | |
| } | |
| }; |