UNPKG

5.14 kBJavaScriptView Raw
1/**
2 * @fileoverview Rule to define spacing before/after arrow function's arrow.
3 * @author Jxck
4 */
5"use strict";
6
7//------------------------------------------------------------------------------
8// Requirements
9//------------------------------------------------------------------------------
10
11const astUtils = require("../ast-utils");
12
13//------------------------------------------------------------------------------
14// Rule Definition
15//------------------------------------------------------------------------------
16
17module.exports = {
18 meta: {
19 docs: {
20 description: "enforce consistent spacing before and after the arrow in arrow functions",
21 category: "ECMAScript 6",
22 recommended: false,
23 url: "https://eslint.org/docs/rules/arrow-spacing"
24 },
25
26 fixable: "whitespace",
27
28 schema: [
29 {
30 type: "object",
31 properties: {
32 before: {
33 type: "boolean"
34 },
35 after: {
36 type: "boolean"
37 }
38 },
39 additionalProperties: false
40 }
41 ],
42
43 messages: {
44 expectedBefore: "Missing space before =>.",
45 unexpectedBefore: "Unexpected space before =>.",
46
47 expectedAfter: "Missing space after =>.",
48 unexpectedAfter: "Unexpected space after =>."
49 }
50 },
51
52 create(context) {
53
54 // merge rules with default
55 const rule = { before: true, after: true },
56 option = context.options[0] || {};
57
58 rule.before = option.before !== false;
59 rule.after = option.after !== false;
60
61 const sourceCode = context.getSourceCode();
62
63 /**
64 * Get tokens of arrow(`=>`) and before/after arrow.
65 * @param {ASTNode} node The arrow function node.
66 * @returns {Object} Tokens of arrow and before/after arrow.
67 */
68 function getTokens(node) {
69 const arrow = sourceCode.getTokenBefore(node.body, astUtils.isArrowToken);
70
71 return {
72 before: sourceCode.getTokenBefore(arrow),
73 arrow,
74 after: sourceCode.getTokenAfter(arrow)
75 };
76 }
77
78 /**
79 * Count spaces before/after arrow(`=>`) token.
80 * @param {Object} tokens Tokens before/after arrow.
81 * @returns {Object} count of space before/after arrow.
82 */
83 function countSpaces(tokens) {
84 const before = tokens.arrow.range[0] - tokens.before.range[1];
85 const after = tokens.after.range[0] - tokens.arrow.range[1];
86
87 return { before, after };
88 }
89
90 /**
91 * Determines whether space(s) before after arrow(`=>`) is satisfy rule.
92 * if before/after value is `true`, there should be space(s).
93 * if before/after value is `false`, there should be no space.
94 * @param {ASTNode} node The arrow function node.
95 * @returns {void}
96 */
97 function spaces(node) {
98 const tokens = getTokens(node);
99 const countSpace = countSpaces(tokens);
100
101 if (rule.before) {
102
103 // should be space(s) before arrow
104 if (countSpace.before === 0) {
105 context.report({
106 node: tokens.before,
107 messageId: "expectedBefore",
108 fix(fixer) {
109 return fixer.insertTextBefore(tokens.arrow, " ");
110 }
111 });
112 }
113 } else {
114
115 // should be no space before arrow
116 if (countSpace.before > 0) {
117 context.report({
118 node: tokens.before,
119 messageId: "unexpectedBefore",
120 fix(fixer) {
121 return fixer.removeRange([tokens.before.range[1], tokens.arrow.range[0]]);
122 }
123 });
124 }
125 }
126
127 if (rule.after) {
128
129 // should be space(s) after arrow
130 if (countSpace.after === 0) {
131 context.report({
132 node: tokens.after,
133 messageId: "expectedAfter",
134 fix(fixer) {
135 return fixer.insertTextAfter(tokens.arrow, " ");
136 }
137 });
138 }
139 } else {
140
141 // should be no space after arrow
142 if (countSpace.after > 0) {
143 context.report({
144 node: tokens.after,
145 messageId: "unexpectedAfter",
146 fix(fixer) {
147 return fixer.removeRange([tokens.arrow.range[1], tokens.after.range[0]]);
148 }
149 });
150 }
151 }
152 }
153
154 return {
155 ArrowFunctionExpression: spaces
156 };
157 }
158};