UNPKG

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