UNPKG

2.76 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 docs: {
14 description: "enforce the consistent use of either `function` declarations or expressions",
15 category: "Stylistic Issues",
16 recommended: false,
17 url: "https://eslint.org/docs/rules/func-style"
18 },
19
20 schema: [
21 {
22 enum: ["declaration", "expression"]
23 },
24 {
25 type: "object",
26 properties: {
27 allowArrowFunctions: {
28 type: "boolean"
29 }
30 },
31 additionalProperties: false
32 }
33 ]
34 },
35
36 create(context) {
37
38 const style = context.options[0],
39 allowArrowFunctions = context.options[1] && context.options[1].allowArrowFunctions === true,
40 enforceDeclarations = (style === "declaration"),
41 stack = [];
42
43 const nodesToCheck = {
44 FunctionDeclaration(node) {
45 stack.push(false);
46
47 if (!enforceDeclarations && node.parent.type !== "ExportDefaultDeclaration") {
48 context.report({ node, message: "Expected a function expression." });
49 }
50 },
51 "FunctionDeclaration:exit"() {
52 stack.pop();
53 },
54
55 FunctionExpression(node) {
56 stack.push(false);
57
58 if (enforceDeclarations && node.parent.type === "VariableDeclarator") {
59 context.report({ node: node.parent, message: "Expected a function declaration." });
60 }
61 },
62 "FunctionExpression:exit"() {
63 stack.pop();
64 },
65
66 ThisExpression() {
67 if (stack.length > 0) {
68 stack[stack.length - 1] = true;
69 }
70 }
71 };
72
73 if (!allowArrowFunctions) {
74 nodesToCheck.ArrowFunctionExpression = function() {
75 stack.push(false);
76 };
77
78 nodesToCheck["ArrowFunctionExpression:exit"] = function(node) {
79 const hasThisExpr = stack.pop();
80
81 if (enforceDeclarations && !hasThisExpr && node.parent.type === "VariableDeclarator") {
82 context.report({ node: node.parent, message: "Expected a function declaration." });
83 }
84 };
85 }
86
87 return nodesToCheck;
88
89 }
90};