Skip to content

Commit e4f111b

Browse files
authored
Fix: arrow-body-style crash with object pattern (fixes #14633) (#14635)
1 parent ec28b5a commit e4f111b

2 files changed

Lines changed: 29 additions & 11 deletions

File tree

lib/rules/arrow-body-style.js

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -87,17 +87,17 @@ module.exports = {
8787
}
8888

8989
/**
90-
* Gets the closing parenthesis which is the pair of the given opening parenthesis.
91-
* @param {Token} token The opening parenthesis token to get.
90+
* Gets the closing parenthesis by the given node.
91+
* @param {ASTNode} node first node after an opening parenthesis.
9292
* @returns {Token} The found closing parenthesis token.
9393
*/
94-
function findClosingParen(token) {
95-
let node = sourceCode.getNodeByRangeIndex(token.range[0]);
94+
function findClosingParen(node) {
95+
let nodeToCheck = node;
9696

97-
while (!astUtils.isParenthesised(sourceCode, node)) {
98-
node = node.parent;
97+
while (!astUtils.isParenthesised(sourceCode, nodeToCheck)) {
98+
nodeToCheck = nodeToCheck.parent;
9999
}
100-
return sourceCode.getTokenAfter(node);
100+
return sourceCode.getTokenAfter(nodeToCheck);
101101
}
102102

103103
/**
@@ -226,12 +226,22 @@ module.exports = {
226226
const arrowToken = sourceCode.getTokenBefore(arrowBody, astUtils.isArrowToken);
227227
const [firstTokenAfterArrow, secondTokenAfterArrow] = sourceCode.getTokensAfter(arrowToken, { count: 2 });
228228
const lastToken = sourceCode.getLastToken(node);
229-
const isParenthesisedObjectLiteral =
229+
230+
let parenthesisedObjectLiteral = null;
231+
232+
if (
230233
astUtils.isOpeningParenToken(firstTokenAfterArrow) &&
231-
astUtils.isOpeningBraceToken(secondTokenAfterArrow);
234+
astUtils.isOpeningBraceToken(secondTokenAfterArrow)
235+
) {
236+
const braceNode = sourceCode.getNodeByRangeIndex(secondTokenAfterArrow.range[0]);
237+
238+
if (braceNode.type === "ObjectExpression") {
239+
parenthesisedObjectLiteral = braceNode;
240+
}
241+
}
232242

233243
// If the value is object literal, remove parentheses which were forced by syntax.
234-
if (isParenthesisedObjectLiteral) {
244+
if (parenthesisedObjectLiteral) {
235245
const openingParenToken = firstTokenAfterArrow;
236246
const openingBraceToken = secondTokenAfterArrow;
237247

@@ -247,7 +257,7 @@ module.exports = {
247257
}
248258

249259
// Closing paren for the object doesn't have to be lastToken, e.g.: () => ({}).foo()
250-
fixes.push(fixer.remove(findClosingParen(openingBraceToken)));
260+
fixes.push(fixer.remove(findClosingParen(parenthesisedObjectLiteral)));
251261
fixes.push(fixer.insertTextAfter(lastToken, "}"));
252262

253263
} else {

tests/lib/rules/arrow-body-style.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -810,6 +810,14 @@ ruleTester.run("arrow-body-style", rule, {
810810
`,
811811
options: ["always"],
812812
errors: [{ messageId: "expectedBlock" }]
813+
},
814+
815+
// https://github.com/eslint/eslint/issues/14633
816+
{
817+
code: "const createMarker = (color) => ({ latitude, longitude }, index) => {};",
818+
output: "const createMarker = (color) => {return ({ latitude, longitude }, index) => {}};",
819+
options: ["always"],
820+
errors: [{ messageId: "expectedBlock" }]
813821
}
814822
]
815823
});

0 commit comments

Comments
 (0)