UNPKG

2.91 kBJavaScriptView Raw
1/**
2 * @fileoverview Rule to enforce a particular function style
3 * @author Nicholas C. Zakas
4 */
5"use strict";
6
7//------------------------------------------------------------------------------
8// Rule Definition
9//------------------------------------------------------------------------------
10
11module.exports = {
12 meta: {
13 type: "suggestion",
14
15 docs: {
16 description: "enforce the consistent use of either `function` declarations or expressions",
17 category: "Stylistic Issues",
18 recommended: false,
19 url: "https://eslint.org/docs/rules/func-style"
20 },
21
22 schema: [
23 {
24 enum: ["declaration", "expression"]
25 },
26 {
27 type: "object",
28 properties: {
29 allowArrowFunctions: {
30 type: "boolean",
31 default: false
32 }
33 },
34 additionalProperties: false
35 }
36 ],
37
38 messages: {
39 expression: "Expected a function expression.",
40 declaration: "Expected a function declaration."
41 }
42 },
43
44 create(context) {
45
46 const style = context.options[0],
47 allowArrowFunctions = context.options[1] && context.options[1].allowArrowFunctions,
48 enforceDeclarations = (style === "declaration"),
49 stack = [];
50
51 const nodesToCheck = {
52 FunctionDeclaration(node) {
53 stack.push(false);
54
55 if (!enforceDeclarations && node.parent.type !== "ExportDefaultDeclaration") {
56 context.report({ node, messageId: "expression" });
57 }
58 },
59 "FunctionDeclaration:exit"() {
60 stack.pop();
61 },
62
63 FunctionExpression(node) {
64 stack.push(false);
65
66 if (enforceDeclarations && node.parent.type === "VariableDeclarator") {
67 context.report({ node: node.parent, messageId: "declaration" });
68 }
69 },
70 "FunctionExpression:exit"() {
71 stack.pop();
72 },
73
74 ThisExpression() {
75 if (stack.length > 0) {
76 stack[stack.length - 1] = true;
77 }
78 }
79 };
80
81 if (!allowArrowFunctions) {
82 nodesToCheck.ArrowFunctionExpression = function() {
83 stack.push(false);
84 };
85
86 nodesToCheck["ArrowFunctionExpression:exit"] = function(node) {
87 const hasThisExpr = stack.pop();
88
89 if (enforceDeclarations && !hasThisExpr && node.parent.type === "VariableDeclarator") {
90 context.report({ node: node.parent, messageId: "declaration" });
91 }
92 };
93 }
94
95 return nodesToCheck;
96
97 }
98};