UNPKG

4.04 kBJavaScriptView Raw
1/**
2 * @fileoverview Enforce spacing between rest and spread operators and their expressions.
3 * @author Kai Cataldo
4 */
5
6"use strict";
7
8//------------------------------------------------------------------------------
9// Rule Definition
10//------------------------------------------------------------------------------
11
12module.exports = {
13 meta: {
14 type: "layout",
15
16 docs: {
17 description: "enforce spacing between rest and spread operators and their expressions",
18 category: "ECMAScript 6",
19 recommended: false,
20 url: "https://eslint.org/docs/rules/rest-spread-spacing"
21 },
22
23 fixable: "whitespace",
24
25 schema: [
26 {
27 enum: ["always", "never"]
28 }
29 ],
30
31 messages: {
32 unexpectedWhitespace: "Unexpected whitespace after {{type}} operator.",
33 expectedWhitespace: "Expected whitespace after {{type}} operator."
34 }
35 },
36
37 create(context) {
38 const sourceCode = context.getSourceCode(),
39 alwaysSpace = context.options[0] === "always";
40
41 //--------------------------------------------------------------------------
42 // Helpers
43 //--------------------------------------------------------------------------
44
45 /**
46 * Checks whitespace between rest/spread operators and their expressions
47 * @param {ASTNode} node The node to check
48 * @returns {void}
49 */
50 function checkWhiteSpace(node) {
51 const operator = sourceCode.getFirstToken(node),
52 nextToken = sourceCode.getTokenAfter(operator),
53 hasWhitespace = sourceCode.isSpaceBetweenTokens(operator, nextToken);
54 let type;
55
56 switch (node.type) {
57 case "SpreadElement":
58 type = "spread";
59 if (node.parent.type === "ObjectExpression") {
60 type += " property";
61 }
62 break;
63 case "RestElement":
64 type = "rest";
65 if (node.parent.type === "ObjectPattern") {
66 type += " property";
67 }
68 break;
69 case "ExperimentalSpreadProperty":
70 type = "spread property";
71 break;
72 case "ExperimentalRestProperty":
73 type = "rest property";
74 break;
75 default:
76 return;
77 }
78
79 if (alwaysSpace && !hasWhitespace) {
80 context.report({
81 node,
82 loc: operator.loc,
83 messageId: "expectedWhitespace",
84 data: {
85 type
86 },
87 fix(fixer) {
88 return fixer.replaceTextRange([operator.range[1], nextToken.range[0]], " ");
89 }
90 });
91 } else if (!alwaysSpace && hasWhitespace) {
92 context.report({
93 node,
94 loc: {
95 start: operator.loc.end,
96 end: nextToken.loc.start
97 },
98 messageId: "unexpectedWhitespace",
99 data: {
100 type
101 },
102 fix(fixer) {
103 return fixer.removeRange([operator.range[1], nextToken.range[0]]);
104 }
105 });
106 }
107 }
108
109 //--------------------------------------------------------------------------
110 // Public
111 //--------------------------------------------------------------------------
112
113 return {
114 SpreadElement: checkWhiteSpace,
115 RestElement: checkWhiteSpace,
116 ExperimentalSpreadProperty: checkWhiteSpace,
117 ExperimentalRestProperty: checkWhiteSpace
118 };
119 }
120};