2 * @fileoverview Disallows or enforces spaces inside of array brackets.
3 * @author Jamund Ferguson
7 const astUtils
= require("./utils/ast-utils");
9 //------------------------------------------------------------------------------
11 //------------------------------------------------------------------------------
13 /** @type {import('../shared/types').Rule} */
19 description
: "Enforce consistent spacing inside array brackets",
21 url
: "https://eslint.org/docs/rules/array-bracket-spacing"
24 fixable
: "whitespace",
28 enum: ["always", "never"]
43 additionalProperties
: false
48 unexpectedSpaceAfter
: "There should be no space after '{{tokenValue}}'.",
49 unexpectedSpaceBefore
: "There should be no space before '{{tokenValue}}'.",
50 missingSpaceAfter
: "A space is required after '{{tokenValue}}'.",
51 missingSpaceBefore
: "A space is required before '{{tokenValue}}'."
55 const spaced
= context
.options
[0] === "always",
56 sourceCode
= context
.getSourceCode();
59 * Determines whether an option is set, relative to the spacing option.
60 * If spaced is "always", then check whether option is set to false.
61 * If spaced is "never", then check whether option is set to true.
62 * @param {Object} option The option to exclude.
63 * @returns {boolean} Whether or not the property is excluded.
65 function isOptionSet(option
) {
66 return context
.options
[1] ? context
.options
[1][option
] === !spaced
: false;
71 singleElementException
: isOptionSet("singleValue"),
72 objectsInArraysException
: isOptionSet("objectsInArrays"),
73 arraysInArraysException
: isOptionSet("arraysInArrays")
76 //--------------------------------------------------------------------------
78 //--------------------------------------------------------------------------
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.
86 function reportNoBeginningSpace(node
, token
) {
87 const nextToken
= sourceCode
.getTokenAfter(token
);
91 loc
: { start
: token
.loc
.end
, end
: nextToken
.loc
.start
},
92 messageId
: "unexpectedSpaceAfter",
94 tokenValue
: token
.value
97 return fixer
.removeRange([token
.range
[1], nextToken
.range
[0]]);
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.
108 function reportNoEndingSpace(node
, token
) {
109 const previousToken
= sourceCode
.getTokenBefore(token
);
113 loc
: { start
: previousToken
.loc
.end
, end
: token
.loc
.start
},
114 messageId
: "unexpectedSpaceBefore",
116 tokenValue
: token
.value
119 return fixer
.removeRange([previousToken
.range
[1], token
.range
[0]]);
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.
130 function reportRequiredBeginningSpace(node
, token
) {
134 messageId
: "missingSpaceAfter",
136 tokenValue
: token
.value
139 return fixer
.insertTextAfter(token
, " ");
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.
150 function reportRequiredEndingSpace(node
, token
) {
154 messageId
: "missingSpaceBefore",
156 tokenValue
: token
.value
159 return fixer
.insertTextBefore(token
, " ");
165 * Determines if a node is an object type
166 * @param {ASTNode} node The node to check.
167 * @returns {boolean} Whether or not the node is an object type.
169 function isObjectType(node
) {
170 return node
&& (node
.type
=== "ObjectExpression" || node
.type
=== "ObjectPattern");
174 * Determines if a node is an array type
175 * @param {ASTNode} node The node to check.
176 * @returns {boolean} Whether or not the node is an array type.
178 function isArrayType(node
) {
179 return node
&& (node
.type
=== "ArrayExpression" || node
.type
=== "ArrayPattern");
183 * Validates the spacing around array brackets
184 * @param {ASTNode} node The node we're checking for spacing
187 function validateArraySpacing(node
) {
188 if (options
.spaced
&& node
.elements
.length
=== 0) {
192 const first
= sourceCode
.getFirstToken(node
),
193 second
= sourceCode
.getFirstToken(node
, 1),
194 last
= node
.typeAnnotation
195 ? sourceCode
.getTokenBefore(node
.typeAnnotation
)
196 : sourceCode
.getLastToken(node
),
197 penultimate
= sourceCode
.getTokenBefore(last
),
198 firstElement
= node
.elements
[0],
199 lastElement
= node
.elements
[node
.elements
.length
- 1];
201 const openingBracketMustBeSpaced
=
202 options
.objectsInArraysException
&& isObjectType(firstElement
) ||
203 options
.arraysInArraysException
&& isArrayType(firstElement
) ||
204 options
.singleElementException
&& node
.elements
.length
=== 1
205 ? !options
.spaced
: options
.spaced
;
207 const closingBracketMustBeSpaced
=
208 options
.objectsInArraysException
&& isObjectType(lastElement
) ||
209 options
.arraysInArraysException
&& isArrayType(lastElement
) ||
210 options
.singleElementException
&& node
.elements
.length
=== 1
211 ? !options
.spaced
: options
.spaced
;
213 if (astUtils
.isTokenOnSameLine(first
, second
)) {
214 if (openingBracketMustBeSpaced
&& !sourceCode
.isSpaceBetweenTokens(first
, second
)) {
215 reportRequiredBeginningSpace(node
, first
);
217 if (!openingBracketMustBeSpaced
&& sourceCode
.isSpaceBetweenTokens(first
, second
)) {
218 reportNoBeginningSpace(node
, first
);
222 if (first
!== penultimate
&& astUtils
.isTokenOnSameLine(penultimate
, last
)) {
223 if (closingBracketMustBeSpaced
&& !sourceCode
.isSpaceBetweenTokens(penultimate
, last
)) {
224 reportRequiredEndingSpace(node
, last
);
226 if (!closingBracketMustBeSpaced
&& sourceCode
.isSpaceBetweenTokens(penultimate
, last
)) {
227 reportNoEndingSpace(node
, last
);
232 //--------------------------------------------------------------------------
234 //--------------------------------------------------------------------------
237 ArrayPattern
: validateArraySpacing
,
238 ArrayExpression
: validateArraySpacing