diff --git a/changelog_unreleased/javascript/19263.md b/changelog_unreleased/javascript/19263.md new file mode 100644 index 000000000..9546051de --- /dev/null +++ b/changelog_unreleased/javascript/19263.md @@ -0,0 +1,16 @@ +#### Keep trailing comments inside the parentheses of a sequence or assignment expression (#19263 by @sarathfrancis90) + + +```jsx +// Input +const x = (a, b, c /* comment */); +const y = (a = b /* comment */); + +// Prettier stable +const x = (a, b, c) /* comment */; +const y = (a = b) /* comment */; + +// Prettier main +const x = (a, b, c /* comment */); +const y = (a = b /* comment */); +``` diff --git a/src/language-js/comments/handle-comments.js b/src/language-js/comments/handle-comments.js index c8c82af85..0fe5dc995 100644 --- a/src/language-js/comments/handle-comments.js +++ b/src/language-js/comments/handle-comments.js @@ -112,8 +112,7 @@ function handleEndOfLineComment(context) { handleLastBinaryOperatorOperand, handleTSMappedTypeComments, handleArrowExpressionComments, - handleArrowBodySequenceExpressionTrailingComment, - handleArrowBodyAssignmentExpressionTrailingComment, + handleParenthesizedExpressionTrailingComment, handlePropertySignatureComments, handleBinaryCastExpressionComment, ].some((fn) => fn(context)); @@ -136,8 +135,7 @@ function handleRemainingComment(context) { handleCommentAfterArrowParams, handleFunctionNameComments, handleTSFunctionTrailingComments, - handleArrowBodySequenceExpressionTrailingComment, - handleArrowBodyAssignmentExpressionTrailingComment, + handleParenthesizedExpressionTrailingComment, handleBinaryCastExpressionComment, ].some((fn) => fn(context)); } @@ -1075,43 +1073,41 @@ function handleArrowExpressionComments({ return false; } -function handleArrowBodySequenceExpressionTrailingComment({ +function handleParenthesizedExpressionTrailingComment({ comment, enclosingNode, precedingNode, followingNode, text, }) { - if ( - !followingNode && - enclosingNode?.type === "ArrowFunctionExpression" && - precedingNode?.type === "SequenceExpression" && - enclosingNode.body === precedingNode && - getNextNonSpaceNonCommentCharacter(text, locEnd(comment)) === ")" - ) { - addTrailingComment(precedingNode.expressions.at(-1), comment); - return true; - } - return false; -} + if (!followingNode && enclosingNode) { + const isSequence = precedingNode?.type === "SequenceExpression"; + const isAssignment = precedingNode?.type === "AssignmentExpression"; -function handleArrowBodyAssignmentExpressionTrailingComment({ - comment, - enclosingNode, - precedingNode, - followingNode, - text, -}) { - if ( - !followingNode && - enclosingNode?.type === "ArrowFunctionExpression" && - precedingNode?.type === "AssignmentExpression" && - enclosingNode.body === precedingNode && - getNextNonSpaceNonCommentCharacter(text, locEnd(comment)) === ")" - ) { - addTrailingComment(precedingNode.right, comment); - return true; + if ( + (isSequence || isAssignment) && + ((enclosingNode.type === "ArrowFunctionExpression" && + enclosingNode.body === precedingNode) || + (enclosingNode.type === "VariableDeclarator" && + enclosingNode.init === precedingNode) || + (enclosingNode.type === "ReturnStatement" && + enclosingNode.argument === precedingNode) || + (isSequence && + enclosingNode.type === "ExpressionStatement" && + enclosingNode.expression === precedingNode) || + (isSequence && + enclosingNode.type === "AssignmentExpression" && + enclosingNode.right === precedingNode)) && + getNextNonSpaceNonCommentCharacter(text, locEnd(comment)) === ")" + ) { + addTrailingComment( + isSequence ? precedingNode.expressions.at(-1) : precedingNode.right, + comment, + ); + return true; + } } + return false; } diff --git a/tests/config/format-test/failed-format-tests.js b/tests/config/format-test/failed-format-tests.js index 53bbd584e..a99242a90 100644 --- a/tests/config/format-test/failed-format-tests.js +++ b/tests/config/format-test/failed-format-tests.js @@ -33,6 +33,7 @@ const unstableTests = new Map( "typescript/call/callee-comments.ts", "js/arrows/arrow-chain-with-trailing-comments.js", "typescript/as/comments/18160.ts", + "js/sequence-expression/parenthesized-trailing-comment-unstable.js", ].map((fixture) => { const [file, isUnstable = () => true] = Array.isArray(fixture) ? fixture diff --git a/tests/format/js/sequence-expression/__snapshots__/format.test.js.snap b/tests/format/js/sequence-expression/__snapshots__/format.test.js.snap index 4b8e5396a..2aedc70df 100644 --- a/tests/format/js/sequence-expression/__snapshots__/format.test.js.snap +++ b/tests/format/js/sequence-expression/__snapshots__/format.test.js.snap @@ -127,6 +127,64 @@ console.log( ================================================================================ `; +exports[`parenthesized-trailing-comment.js format 1`] = ` +====================================options===================================== +parsers: ["babel", "flow", "typescript"] + printWidth: 80 (default) | +=====================================input====================================== +const x1 = (a, b, c /* comment */); +const x2 = (a = c /* comment */); + +(a, b, c /* comment */); +// (a = c /* comment */); + +assigned = (a, b, c /* comment */); +// assigned = (a = c /* comment */); + +function f() { + return (a, b, c /* comment */); + return (a = c /* comment */); +} + +=====================================output===================================== +const x1 = (a, b, c /* comment */); +const x2 = (a = c /* comment */); + +(a, b, c /* comment */); +// (a = c /* comment */); + +assigned = (a, b, c /* comment */); +// assigned = (a = c /* comment */); + +function f() { + return (a, b, c /* comment */); + return (a = c /* comment */); +} + +================================================================================ +`; + +exports[`parenthesized-trailing-comment-unstable.js format 1`] = ` +====================================options===================================== +parsers: ["babel", "flow", "typescript"] + printWidth: 80 (default) | +=====================================input====================================== +// TODO: Enable tests in parenthesized-trailing-comment.js when they are stable + +(a = c /* comment */); + +assigned = (a = c /* comment */); + +=====================================output===================================== +// TODO: Enable tests in parenthesized-trailing-comment.js when they are stable + +a = c /* comment */; + +assigned = a = c /* comment */; + +================================================================================ +`; + exports[`return.js format 1`] = ` ====================================options===================================== parsers: ["babel", "flow", "typescript"] diff --git a/tests/format/js/sequence-expression/parenthesized-trailing-comment-unstable.js b/tests/format/js/sequence-expression/parenthesized-trailing-comment-unstable.js new file mode 100644 index 000000000..659db507c --- /dev/null +++ b/tests/format/js/sequence-expression/parenthesized-trailing-comment-unstable.js @@ -0,0 +1,5 @@ +// TODO: Enable tests in parenthesized-trailing-comment.js when they are stable + +(a = c /* comment */); + +assigned = (a = c /* comment */); diff --git a/tests/format/js/sequence-expression/parenthesized-trailing-comment.js b/tests/format/js/sequence-expression/parenthesized-trailing-comment.js new file mode 100644 index 000000000..92ac2f5b4 --- /dev/null +++ b/tests/format/js/sequence-expression/parenthesized-trailing-comment.js @@ -0,0 +1,13 @@ +const x1 = (a, b, c /* comment */); +const x2 = (a = c /* comment */); + +(a, b, c /* comment */); +// (a = c /* comment */); + +assigned = (a, b, c /* comment */); +// assigned = (a = c /* comment */); + +function f() { + return (a, b, c /* comment */); + return (a = c /* comment */); +}