UNPKG

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