Skip to content

Commit ee40364

Browse files
authored
feat: convert no-array-constructor suggestions to autofixes (#19621)
* feat: convert no-array-constructor suggestions to autofixes * refactor * refactor * refactor * refactor * refactor * fix tests * revert format change * revert format change * sorry * refactor
1 parent fbb8be9 commit ee40364

2 files changed

Lines changed: 469 additions & 82 deletions

File tree

lib/rules/no-array-constructor.js

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ module.exports = {
3434
url: "https://eslint.org/docs/latest/rules/no-array-constructor",
3535
},
3636

37+
fixable: "code",
38+
3739
hasSuggestions: true,
3840

3941
schema: [],
@@ -49,6 +51,30 @@ module.exports = {
4951
create(context) {
5052
const sourceCode = context.sourceCode;
5153

54+
/**
55+
* Checks if there are comments in Array constructor expressions.
56+
* @param {ASTNode} node A CallExpression or NewExpression node.
57+
* @returns {boolean} True if there are comments, false otherwise.
58+
*/
59+
function hasCommentsInArrayConstructor(node) {
60+
const firstToken = sourceCode.getFirstToken(node);
61+
const lastToken = sourceCode.getLastToken(node);
62+
63+
let lastRelevantToken = sourceCode.getLastToken(node.callee);
64+
65+
while (
66+
lastRelevantToken !== lastToken &&
67+
!isOpeningParenToken(lastRelevantToken)
68+
) {
69+
lastRelevantToken = sourceCode.getTokenAfter(lastRelevantToken);
70+
}
71+
72+
return sourceCode.commentsExistBetween(
73+
firstToken,
74+
lastRelevantToken,
75+
);
76+
}
77+
5278
/**
5379
* Gets the text between the calling parentheses of a CallExpression or NewExpression.
5480
* @param {ASTNode} node A CallExpression or NewExpression node.
@@ -107,6 +133,17 @@ module.exports = {
107133
let fixText;
108134
let messageId;
109135

136+
const nonSpreadCount = node.arguments.reduce(
137+
(count, arg) =>
138+
arg.type !== "SpreadElement" ? count + 1 : count,
139+
0,
140+
);
141+
142+
const shouldSuggest =
143+
node.optional ||
144+
(node.arguments.length > 0 && nonSpreadCount < 2) ||
145+
hasCommentsInArrayConstructor(node);
146+
110147
/*
111148
* Check if the suggested change should include a preceding semicolon or not.
112149
* Due to JavaScript's ASI rules, a missing semicolon may be inserted automatically
@@ -127,10 +164,23 @@ module.exports = {
127164
context.report({
128165
node,
129166
messageId: "preferLiteral",
167+
fix(fixer) {
168+
if (shouldSuggest) {
169+
return null;
170+
}
171+
172+
return fixer.replaceText(node, fixText);
173+
},
130174
suggest: [
131175
{
132176
messageId,
133-
fix: fixer => fixer.replaceText(node, fixText),
177+
fix(fixer) {
178+
if (shouldSuggest) {
179+
return fixer.replaceText(node, fixText);
180+
}
181+
182+
return null;
183+
},
134184
},
135185
],
136186
});

0 commit comments

Comments
 (0)