source: imaps-frontend/node_modules/eslint/lib/rules/object-curly-spacing.js

main
Last change on this file was d565449, checked in by stefan toskovski <stefantoska84@…>, 4 weeks ago

Update repo after prototype presentation

  • Property mode set to 100644
File size: 11.6 KB
Line 
1/**
2 * @fileoverview Disallows or enforces spaces inside of object literals.
3 * @author Jamund Ferguson
4 * @deprecated in ESLint v8.53.0
5 */
6"use strict";
7
8const astUtils = require("./utils/ast-utils");
9
10//------------------------------------------------------------------------------
11// Rule Definition
12//------------------------------------------------------------------------------
13
14/** @type {import('../shared/types').Rule} */
15module.exports = {
16 meta: {
17 deprecated: true,
18 replacedBy: [],
19 type: "layout",
20
21 docs: {
22 description: "Enforce consistent spacing inside braces",
23 recommended: false,
24 url: "https://eslint.org/docs/latest/rules/object-curly-spacing"
25 },
26
27 fixable: "whitespace",
28
29 schema: [
30 {
31 enum: ["always", "never"]
32 },
33 {
34 type: "object",
35 properties: {
36 arraysInObjects: {
37 type: "boolean"
38 },
39 objectsInObjects: {
40 type: "boolean"
41 }
42 },
43 additionalProperties: false
44 }
45 ],
46
47 messages: {
48 requireSpaceBefore: "A space is required before '{{token}}'.",
49 requireSpaceAfter: "A space is required after '{{token}}'.",
50 unexpectedSpaceBefore: "There should be no space before '{{token}}'.",
51 unexpectedSpaceAfter: "There should be no space after '{{token}}'."
52 }
53 },
54
55 create(context) {
56 const spaced = context.options[0] === "always",
57 sourceCode = context.sourceCode;
58
59 /**
60 * Determines whether an option is set, relative to the spacing option.
61 * If spaced is "always", then check whether option is set to false.
62 * If spaced is "never", then check whether option is set to true.
63 * @param {Object} option The option to exclude.
64 * @returns {boolean} Whether or not the property is excluded.
65 */
66 function isOptionSet(option) {
67 return context.options[1] ? context.options[1][option] === !spaced : false;
68 }
69
70 const options = {
71 spaced,
72 arraysInObjectsException: isOptionSet("arraysInObjects"),
73 objectsInObjectsException: isOptionSet("objectsInObjects")
74 };
75
76 //--------------------------------------------------------------------------
77 // Helpers
78 //--------------------------------------------------------------------------
79
80 /**
81 * Reports that there shouldn't be a space after the first 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 * @returns {void}
85 */
86 function reportNoBeginningSpace(node, token) {
87 const nextToken = context.sourceCode.getTokenAfter(token, { includeComments: true });
88
89 context.report({
90 node,
91 loc: { start: token.loc.end, end: nextToken.loc.start },
92 messageId: "unexpectedSpaceAfter",
93 data: {
94 token: token.value
95 },
96 fix(fixer) {
97 return fixer.removeRange([token.range[1], nextToken.range[0]]);
98 }
99 });
100 }
101
102 /**
103 * Reports that there shouldn't be a space before the last token
104 * @param {ASTNode} node The node to report in the event of an error.
105 * @param {Token} token The token to use for the report.
106 * @returns {void}
107 */
108 function reportNoEndingSpace(node, token) {
109 const previousToken = context.sourceCode.getTokenBefore(token, { includeComments: true });
110
111 context.report({
112 node,
113 loc: { start: previousToken.loc.end, end: token.loc.start },
114 messageId: "unexpectedSpaceBefore",
115 data: {
116 token: token.value
117 },
118 fix(fixer) {
119 return fixer.removeRange([previousToken.range[1], token.range[0]]);
120 }
121 });
122 }
123
124 /**
125 * Reports that there should be a space after the first token
126 * @param {ASTNode} node The node to report in the event of an error.
127 * @param {Token} token The token to use for the report.
128 * @returns {void}
129 */
130 function reportRequiredBeginningSpace(node, token) {
131 context.report({
132 node,
133 loc: token.loc,
134 messageId: "requireSpaceAfter",
135 data: {
136 token: token.value
137 },
138 fix(fixer) {
139 return fixer.insertTextAfter(token, " ");
140 }
141 });
142 }
143
144 /**
145 * Reports that there should be a space before the last token
146 * @param {ASTNode} node The node to report in the event of an error.
147 * @param {Token} token The token to use for the report.
148 * @returns {void}
149 */
150 function reportRequiredEndingSpace(node, token) {
151 context.report({
152 node,
153 loc: token.loc,
154 messageId: "requireSpaceBefore",
155 data: {
156 token: token.value
157 },
158 fix(fixer) {
159 return fixer.insertTextBefore(token, " ");
160 }
161 });
162 }
163
164 /**
165 * Determines if spacing in curly braces is valid.
166 * @param {ASTNode} node The AST node to check.
167 * @param {Token} first The first token to check (should be the opening brace)
168 * @param {Token} second The second token to check (should be first after the opening brace)
169 * @param {Token} penultimate The penultimate token to check (should be last before closing brace)
170 * @param {Token} last The last token to check (should be closing brace)
171 * @returns {void}
172 */
173 function validateBraceSpacing(node, first, second, penultimate, last) {
174 if (astUtils.isTokenOnSameLine(first, second)) {
175 const firstSpaced = sourceCode.isSpaceBetweenTokens(first, second);
176
177 if (options.spaced && !firstSpaced) {
178 reportRequiredBeginningSpace(node, first);
179 }
180 if (!options.spaced && firstSpaced && second.type !== "Line") {
181 reportNoBeginningSpace(node, first);
182 }
183 }
184
185 if (astUtils.isTokenOnSameLine(penultimate, last)) {
186 const shouldCheckPenultimate = (
187 options.arraysInObjectsException && astUtils.isClosingBracketToken(penultimate) ||
188 options.objectsInObjectsException && astUtils.isClosingBraceToken(penultimate)
189 );
190 const penultimateType = shouldCheckPenultimate && sourceCode.getNodeByRangeIndex(penultimate.range[0]).type;
191
192 const closingCurlyBraceMustBeSpaced = (
193 options.arraysInObjectsException && penultimateType === "ArrayExpression" ||
194 options.objectsInObjectsException && (penultimateType === "ObjectExpression" || penultimateType === "ObjectPattern")
195 ) ? !options.spaced : options.spaced;
196
197 const lastSpaced = sourceCode.isSpaceBetweenTokens(penultimate, last);
198
199 if (closingCurlyBraceMustBeSpaced && !lastSpaced) {
200 reportRequiredEndingSpace(node, last);
201 }
202 if (!closingCurlyBraceMustBeSpaced && lastSpaced) {
203 reportNoEndingSpace(node, last);
204 }
205 }
206 }
207
208 /**
209 * Gets '}' token of an object node.
210 *
211 * Because the last token of object patterns might be a type annotation,
212 * this traverses tokens preceded by the last property, then returns the
213 * first '}' token.
214 * @param {ASTNode} node The node to get. This node is an
215 * ObjectExpression or an ObjectPattern. And this node has one or
216 * more properties.
217 * @returns {Token} '}' token.
218 */
219 function getClosingBraceOfObject(node) {
220 const lastProperty = node.properties[node.properties.length - 1];
221
222 return sourceCode.getTokenAfter(lastProperty, astUtils.isClosingBraceToken);
223 }
224
225 /**
226 * Reports a given object node if spacing in curly braces is invalid.
227 * @param {ASTNode} node An ObjectExpression or ObjectPattern node to check.
228 * @returns {void}
229 */
230 function checkForObject(node) {
231 if (node.properties.length === 0) {
232 return;
233 }
234
235 const first = sourceCode.getFirstToken(node),
236 last = getClosingBraceOfObject(node),
237 second = sourceCode.getTokenAfter(first, { includeComments: true }),
238 penultimate = sourceCode.getTokenBefore(last, { includeComments: true });
239
240 validateBraceSpacing(node, first, second, penultimate, last);
241 }
242
243 /**
244 * Reports a given import node if spacing in curly braces is invalid.
245 * @param {ASTNode} node An ImportDeclaration node to check.
246 * @returns {void}
247 */
248 function checkForImport(node) {
249 if (node.specifiers.length === 0) {
250 return;
251 }
252
253 let firstSpecifier = node.specifiers[0];
254 const lastSpecifier = node.specifiers[node.specifiers.length - 1];
255
256 if (lastSpecifier.type !== "ImportSpecifier") {
257 return;
258 }
259 if (firstSpecifier.type !== "ImportSpecifier") {
260 firstSpecifier = node.specifiers[1];
261 }
262
263 const first = sourceCode.getTokenBefore(firstSpecifier),
264 last = sourceCode.getTokenAfter(lastSpecifier, astUtils.isNotCommaToken),
265 second = sourceCode.getTokenAfter(first, { includeComments: true }),
266 penultimate = sourceCode.getTokenBefore(last, { includeComments: true });
267
268 validateBraceSpacing(node, first, second, penultimate, last);
269 }
270
271 /**
272 * Reports a given export node if spacing in curly braces is invalid.
273 * @param {ASTNode} node An ExportNamedDeclaration node to check.
274 * @returns {void}
275 */
276 function checkForExport(node) {
277 if (node.specifiers.length === 0) {
278 return;
279 }
280
281 const firstSpecifier = node.specifiers[0],
282 lastSpecifier = node.specifiers[node.specifiers.length - 1],
283 first = sourceCode.getTokenBefore(firstSpecifier),
284 last = sourceCode.getTokenAfter(lastSpecifier, astUtils.isNotCommaToken),
285 second = sourceCode.getTokenAfter(first, { includeComments: true }),
286 penultimate = sourceCode.getTokenBefore(last, { includeComments: true });
287
288 validateBraceSpacing(node, first, second, penultimate, last);
289 }
290
291 //--------------------------------------------------------------------------
292 // Public
293 //--------------------------------------------------------------------------
294
295 return {
296
297 // var {x} = y;
298 ObjectPattern: checkForObject,
299
300 // var y = {x: 'y'}
301 ObjectExpression: checkForObject,
302
303 // import {y} from 'x';
304 ImportDeclaration: checkForImport,
305
306 // export {name} from 'yo';
307 ExportNamedDeclaration: checkForExport
308 };
309
310 }
311};
Note: See TracBrowser for help on using the repository browser.