| /** | |
| * @fileoverview Rule to enforce a particular function style | |
| * @author Nicholas C. Zakas | |
| */ | |
| "use strict"; | |
| //------------------------------------------------------------------------------ | |
| // Rule Definition | |
| //------------------------------------------------------------------------------ | |
| module.exports = { | |
| meta: { | |
| type: "suggestion", | |
| docs: { | |
| description: "enforce the consistent use of either `function` declarations or expressions", | |
| category: "Stylistic Issues", | |
| recommended: false, | |
| url: "https://eslint.org/docs/rules/func-style" | |
| }, | |
| schema: [ | |
| { | |
| enum: ["declaration", "expression"] | |
| }, | |
| { | |
| type: "object", | |
| properties: { | |
| allowArrowFunctions: { | |
| type: "boolean", | |
| default: false | |
| } | |
| }, | |
| additionalProperties: false | |
| } | |
| ], | |
| messages: { | |
| expression: "Expected a function expression.", | |
| declaration: "Expected a function declaration." | |
| } | |
| }, | |
| create(context) { | |
| const style = context.options[0], | |
| allowArrowFunctions = context.options[1] && context.options[1].allowArrowFunctions, | |
| enforceDeclarations = (style === "declaration"), | |
| stack = []; | |
| const nodesToCheck = { | |
| FunctionDeclaration(node) { | |
| stack.push(false); | |
| if (!enforceDeclarations && node.parent.type !== "ExportDefaultDeclaration") { | |
| context.report({ node, messageId: "expression" }); | |
| } | |
| }, | |
| "FunctionDeclaration:exit"() { | |
| stack.pop(); | |
| }, | |
| FunctionExpression(node) { | |
| stack.push(false); | |
| if (enforceDeclarations && node.parent.type === "VariableDeclarator") { | |
| context.report({ node: node.parent, messageId: "declaration" }); | |
| } | |
| }, | |
| "FunctionExpression:exit"() { | |
| stack.pop(); | |
| }, | |
| ThisExpression() { | |
| if (stack.length > 0) { | |
| stack[stack.length - 1] = true; | |
| } | |
| } | |
| }; | |
| if (!allowArrowFunctions) { | |
| nodesToCheck.ArrowFunctionExpression = function() { | |
| stack.push(false); | |
| }; | |
| nodesToCheck["ArrowFunctionExpression:exit"] = function(node) { | |
| const hasThisExpr = stack.pop(); | |
| if (enforceDeclarations && !hasThisExpr && node.parent.type === "VariableDeclarator") { | |
| context.report({ node: node.parent, messageId: "declaration" }); | |
| } | |
| }; | |
| } | |
| return nodesToCheck; | |
| } | |
| }; |