]> git.proxmox.com Git - pve-eslint.git/blob - eslint/lib/rules/computed-property-spacing.js
import 8.3.0 source
[pve-eslint.git] / eslint / lib / rules / computed-property-spacing.js
1 /**
2 * @fileoverview Disallows or enforces spaces inside computed properties.
3 * @author Jamund Ferguson
4 */
5 "use strict";
6
7 const astUtils = require("./utils/ast-utils");
8
9 //------------------------------------------------------------------------------
10 // Rule Definition
11 //------------------------------------------------------------------------------
12
13 module.exports = {
14 meta: {
15 type: "layout",
16
17 docs: {
18 description: "enforce consistent spacing inside computed property brackets",
19 recommended: false,
20 url: "https://eslint.org/docs/rules/computed-property-spacing"
21 },
22
23 fixable: "whitespace",
24
25 schema: [
26 {
27 enum: ["always", "never"]
28 },
29 {
30 type: "object",
31 properties: {
32 enforceForClassMembers: {
33 type: "boolean",
34 default: true
35 }
36 },
37 additionalProperties: false
38 }
39 ],
40
41 messages: {
42 unexpectedSpaceBefore: "There should be no space before '{{tokenValue}}'.",
43 unexpectedSpaceAfter: "There should be no space after '{{tokenValue}}'.",
44
45 missingSpaceBefore: "A space is required before '{{tokenValue}}'.",
46 missingSpaceAfter: "A space is required after '{{tokenValue}}'."
47 }
48 },
49
50 create(context) {
51 const sourceCode = context.getSourceCode();
52 const propertyNameMustBeSpaced = context.options[0] === "always"; // default is "never"
53 const enforceForClassMembers = !context.options[1] || context.options[1].enforceForClassMembers;
54
55 //--------------------------------------------------------------------------
56 // Helpers
57 //--------------------------------------------------------------------------
58
59 /**
60 * Reports that there shouldn't be a space after the first token
61 * @param {ASTNode} node The node to report in the event of an error.
62 * @param {Token} token The token to use for the report.
63 * @param {Token} tokenAfter The token after `token`.
64 * @returns {void}
65 */
66 function reportNoBeginningSpace(node, token, tokenAfter) {
67 context.report({
68 node,
69 loc: { start: token.loc.end, end: tokenAfter.loc.start },
70 messageId: "unexpectedSpaceAfter",
71 data: {
72 tokenValue: token.value
73 },
74 fix(fixer) {
75 return fixer.removeRange([token.range[1], tokenAfter.range[0]]);
76 }
77 });
78 }
79
80 /**
81 * Reports that there shouldn't be a space before the last token
82 * @param {ASTNode} node The node to report in the event of an error.
83 * @param {Token} token The token to use for the report.
84 * @param {Token} tokenBefore The token before `token`.
85 * @returns {void}
86 */
87 function reportNoEndingSpace(node, token, tokenBefore) {
88 context.report({
89 node,
90 loc: { start: tokenBefore.loc.end, end: token.loc.start },
91 messageId: "unexpectedSpaceBefore",
92 data: {
93 tokenValue: token.value
94 },
95 fix(fixer) {
96 return fixer.removeRange([tokenBefore.range[1], token.range[0]]);
97 }
98 });
99 }
100
101 /**
102 * Reports that there should be a space after the first token
103 * @param {ASTNode} node The node to report in the event of an error.
104 * @param {Token} token The token to use for the report.
105 * @returns {void}
106 */
107 function reportRequiredBeginningSpace(node, token) {
108 context.report({
109 node,
110 loc: token.loc,
111 messageId: "missingSpaceAfter",
112 data: {
113 tokenValue: token.value
114 },
115 fix(fixer) {
116 return fixer.insertTextAfter(token, " ");
117 }
118 });
119 }
120
121 /**
122 * Reports that there should be a space before the last token
123 * @param {ASTNode} node The node to report in the event of an error.
124 * @param {Token} token The token to use for the report.
125 * @returns {void}
126 */
127 function reportRequiredEndingSpace(node, token) {
128 context.report({
129 node,
130 loc: token.loc,
131 messageId: "missingSpaceBefore",
132 data: {
133 tokenValue: token.value
134 },
135 fix(fixer) {
136 return fixer.insertTextBefore(token, " ");
137 }
138 });
139 }
140
141 /**
142 * Returns a function that checks the spacing of a node on the property name
143 * that was passed in.
144 * @param {string} propertyName The property on the node to check for spacing
145 * @returns {Function} A function that will check spacing on a node
146 */
147 function checkSpacing(propertyName) {
148 return function(node) {
149 if (!node.computed) {
150 return;
151 }
152
153 const property = node[propertyName];
154
155 const before = sourceCode.getTokenBefore(property, astUtils.isOpeningBracketToken),
156 first = sourceCode.getTokenAfter(before, { includeComments: true }),
157 after = sourceCode.getTokenAfter(property, astUtils.isClosingBracketToken),
158 last = sourceCode.getTokenBefore(after, { includeComments: true });
159
160 if (astUtils.isTokenOnSameLine(before, first)) {
161 if (propertyNameMustBeSpaced) {
162 if (!sourceCode.isSpaceBetweenTokens(before, first) && astUtils.isTokenOnSameLine(before, first)) {
163 reportRequiredBeginningSpace(node, before);
164 }
165 } else {
166 if (sourceCode.isSpaceBetweenTokens(before, first)) {
167 reportNoBeginningSpace(node, before, first);
168 }
169 }
170 }
171
172 if (astUtils.isTokenOnSameLine(last, after)) {
173 if (propertyNameMustBeSpaced) {
174 if (!sourceCode.isSpaceBetweenTokens(last, after) && astUtils.isTokenOnSameLine(last, after)) {
175 reportRequiredEndingSpace(node, after);
176 }
177 } else {
178 if (sourceCode.isSpaceBetweenTokens(last, after)) {
179 reportNoEndingSpace(node, after, last);
180 }
181 }
182 }
183 };
184 }
185
186
187 //--------------------------------------------------------------------------
188 // Public
189 //--------------------------------------------------------------------------
190
191 const listeners = {
192 Property: checkSpacing("key"),
193 MemberExpression: checkSpacing("property")
194 };
195
196 if (enforceForClassMembers) {
197 listeners.MethodDefinition =
198 listeners.PropertyDefinition = listeners.Property;
199 }
200
201 return listeners;
202
203 }
204 };