diff --git a/changelog_unreleased/javascript/18615-2.md b/changelog_unreleased/javascript/18615-2.md new file mode 100644 index 000000000..e79990344 --- /dev/null +++ b/changelog_unreleased/javascript/18615-2.md @@ -0,0 +1,53 @@ +#### Improve comment handling around empty call argument list (#18615 by @fisker) + + +```jsx +// Input +call +// line comment +(); +call(// line comment +); +call( + // line comment +); + +call +/* block comment */ +(); +call(/* block comment */ +); +call( + /* block comment */ +); + +// Prettier stable +call(); +// line comment +call(); // line comment +call(); +// line comment + +call(); +/* block comment */ +call /* block comment */(); +call(); +/* block comment */ + +// Prettier main +call +// line comment +(); +call( + // line comment +); +call( + // line comment +); + +call +/* block comment */ +(); +call(/* block comment */); +call(/* block comment */); +``` diff --git a/changelog_unreleased/javascript/18615-3.md b/changelog_unreleased/javascript/18615-3.md new file mode 100644 index 000000000..33379c67b --- /dev/null +++ b/changelog_unreleased/javascript/18615-3.md @@ -0,0 +1,21 @@ +#### Fix unstable comment in call expression (#18615 by @fisker) + + +```jsx +// Input +foo = + call( + /* call argument */); + +// Prettier stable (First format) +foo = + call(); + /* call argument */ + +// Prettier stable (Second format) +foo = call(); +/* call argument */ + +// Prettier main +foo = call(/* call argument */); +``` diff --git a/changelog_unreleased/javascript/18615.md b/changelog_unreleased/javascript/18615.md new file mode 100644 index 000000000..b650a00d6 --- /dev/null +++ b/changelog_unreleased/javascript/18615.md @@ -0,0 +1,29 @@ +#### Allow empty call expression argument list with long comments to break (#18615 by @fisker) + + +```jsx +// Input +call(/* a long long long long long long long long long long long long comment */); +array = [/* a long long long long long long long long long long long long comment */]; +object = {/* a long long long long long long long long long long long long comment */}; + +// Prettier stable +call(/* a long long long long long long long long long long long long comment */); +array = [ + /* a long long long long long long long long long long long long comment */ +]; +object = { + /* a long long long long long long long long long long long long comment */ +}; + +// Prettier main +call( + /* a long long long long long long long long long long long long comment */ +); +array = [ + /* a long long long long long long long long long long long long comment */ +]; +object = { + /* a long long long long long long long long long long long long comment */ +}; +``` diff --git a/src/language-js/comments/handle-comments.js b/src/language-js/comments/handle-comments.js index bbbe73736..a7cd47a44 100644 --- a/src/language-js/comments/handle-comments.js +++ b/src/language-js/comments/handle-comments.js @@ -82,6 +82,7 @@ function handleOwnLineComment(context) { handleCommentsInDestructuringPattern, handleTSMappedTypeComments, handleBinaryCastExpressionComment, + handleCommentInEmptyParens, ].some((fn) => fn(context)); } @@ -112,6 +113,7 @@ function handleEndOfLineComment(context) { handleCommentAfterArrowExpression, handlePropertySignatureComments, handleBinaryCastExpressionComment, + handleCommentInEmptyParens, ].some((fn) => fn(context)); } @@ -635,10 +637,14 @@ function handleCommentInEmptyParens({ comment, enclosingNode, options }) { return false; } + // This condition should be removed, but excluded for function parameters in #18615 to make PRs smaller + const isRemainingComment = comment.placement === "remaining"; + // Only add dangling comments to fix the case when no params are present, // i.e. a function without any argument. if ( - ((isRealFunctionLikeNode(enclosingNode) && + ((isRemainingComment && + isRealFunctionLikeNode(enclosingNode) && getFunctionParameters(enclosingNode).length === 0) || (isCallLikeExpression(enclosingNode) && getCallArguments(enclosingNode).length === 0)) && @@ -649,6 +655,7 @@ function handleCommentInEmptyParens({ comment, enclosingNode, options }) { } if ( + isRemainingComment && (enclosingNode.type === "MethodDefinition" || enclosingNode.type === "TSAbstractMethodDefinition") && getFunctionParameters(enclosingNode.value).length === 0 && diff --git a/src/language-js/print/call-arguments.js b/src/language-js/print/call-arguments.js index c076fc87c..01bce68b5 100644 --- a/src/language-js/print/call-arguments.js +++ b/src/language-js/print/call-arguments.js @@ -49,8 +49,23 @@ function printCallArguments(path, options, print) { const { node } = path; const args = getCallArguments(node); + if (args.length === 0) { - return ["(", printDanglingComments(path, options), ")"]; + return group([ + "(", + hasComment(node, CommentCheckFlags.Dangling) + ? [ + indent([softline, printDanglingComments(path, options)]), + hasComment( + node, + CommentCheckFlags.Dangling | CommentCheckFlags.Line, + ) + ? hardline + : softline, + ] + : [], + ")", + ]); } const lastArgIndex = args.length - 1; diff --git a/src/language-js/print/call-expression.js b/src/language-js/print/call-expression.js index d199510e5..5dd726f0c 100644 --- a/src/language-js/print/call-expression.js +++ b/src/language-js/print/call-expression.js @@ -1,4 +1,4 @@ -import { group, join } from "../../document/index.js"; +import { group, join, lineSuffixBoundary } from "../../document/index.js"; import needsParentheses from "../parentheses/needs-parentheses.js"; import { getCallArguments, @@ -93,6 +93,7 @@ function printCallExpression(path, options, print) { printCallee(path, print), optional, typeArgumentsDoc, + lineSuffixBoundary, printCallArguments(path, options, print), ]; diff --git a/tests/config/run-format-test.js b/tests/config/run-format-test.js index 780c39142..921b00d63 100644 --- a/tests/config/run-format-test.js +++ b/tests/config/run-format-test.js @@ -27,7 +27,6 @@ const unstableTests = new Map( "js/comments/return-statement.js", "js/comments/tagged-template-literal.js", "js/for/9812-unstable.js", - "js/comments/in-list/dangling-comment-in-list.js", [ "js/multiparser-markdown/codeblock.js", (options) => options.proseWrap === "always", diff --git a/tests/format/js/call/no-argument/__snapshots__/format.test.js.snap b/tests/format/js/call/no-argument/__snapshots__/format.test.js.snap index 881f34e8a..1df42afa4 100644 --- a/tests/format/js/call/no-argument/__snapshots__/format.test.js.snap +++ b/tests/format/js/call/no-argument/__snapshots__/format.test.js.snap @@ -1,5 +1,112 @@ // Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing +exports[`no-arguments.js format 1`] = ` +====================================options===================================== +parsers: ["babel", "flow", "typescript"] +printWidth: 80 + | printWidth +=====================================input====================================== +call// 101 +() +call +// 102 +() +call(// 103 + ) +call + (// 104 + ) +call( + // 105 + ) +call// 106 +?.( + ) +call// 107 +?.( + ) +call?.// 108 +( + ) + +call/* 201 */ +() +call +/* 202 */ +() +call/* 203 */() +call(/* 204 */ + ) +call( + /* 205 */ + ) +call/* 206 */?. +() +call/* 207 */ +?. +() +call +/* 208 */?. +() + +call/* 209 */ +?. +() +call?./* 210 */ +() +call +?./* 211 */ +() +call +?. +/* 212 */ +() + +=====================================output===================================== +call // 101 +(); +call +// 102 +(); +call( + // 103 +); +call( + // 104 +); +call( + // 105 +); +call?. // 106 +(); +call?. // 107 +(); +call?. // 108 +(); + +call /* 201 */(); +call +/* 202 */ +(); +call /* 203 */(); +call(/* 204 */); +call(/* 205 */); +call /* 206 */?.(); +call /* 207 */?.(); +call?. +/* 208 */ +(); + +call /* 209 */?.(); +call /* 210 */?.(); +call /* 211 */?.(); +call?. +/* 212 */ +(); + +================================================================================ +`; + exports[`special-cases.js format 1`] = ` ====================================options===================================== parsers: ["babel", "flow", "typescript"] diff --git a/tests/format/js/call/no-argument/no-arguments.js b/tests/format/js/call/no-argument/no-arguments.js new file mode 100644 index 000000000..8d428999d --- /dev/null +++ b/tests/format/js/call/no-argument/no-arguments.js @@ -0,0 +1,55 @@ +call// 101 +() +call +// 102 +() +call(// 103 + ) +call + (// 104 + ) +call( + // 105 + ) +call// 106 +?.( + ) +call// 107 +?.( + ) +call?.// 108 +( + ) + +call/* 201 */ +() +call +/* 202 */ +() +call/* 203 */() +call(/* 204 */ + ) +call( + /* 205 */ + ) +call/* 206 */?. +() +call/* 207 */ +?. +() +call +/* 208 */?. +() + +call/* 209 */ +?. +() +call?./* 210 */ +() +call +?./* 211 */ +() +call +?. +/* 212 */ +() diff --git a/tests/format/js/comments/in-list/__snapshots__/format.test.js.snap b/tests/format/js/comments/in-list/__snapshots__/format.test.js.snap index 4a973e97c..3f1a1cc7c 100644 --- a/tests/format/js/comments/in-list/__snapshots__/format.test.js.snap +++ b/tests/format/js/comments/in-list/__snapshots__/format.test.js.snap @@ -12,13 +12,13 @@ call = call(/* call argument */) fn = function(/* function parameter */) {} newFoo = new Foo(/* new argument */) -// TODO[@fisker]: fix the following array = [ /* array */] object = { /* object */} call = call( /* call argument */) +// TODO[@fisker]: fix this fn = function( /* function parameter */) {} newFoo = new Foo @@ -27,6 +27,7 @@ newFoo = new Foo array = [/* array long long long long long long long long long long long long long long */] object = {/* object long long long long long long long long long long long long long long */} call = call(/* call argument long long long long long long long long long long long long long long */) +// TODO[@fisker]: fix this fn = function (/* function long parameter long long long long long long long long long long long long long */) {} newFoo = new Foo(/* new argument long long long long long long long long long long long long long long */) @@ -37,12 +38,10 @@ call = call(/* call argument */); fn = function (/* function parameter */) {}; newFoo = new Foo(/* new argument */); -// TODO[@fisker]: fix the following array = [/* array */]; object = {/* object */}; -call = - call(); - /* call argument */ +call = call(/* call argument */); +// TODO[@fisker]: fix this fn = function () /* function parameter */ {}; newFoo = new Foo(/* new argument */); @@ -53,11 +52,15 @@ object = { /* object long long long long long long long long long long long long long long */ }; call = - call(/* call argument long long long long long long long long long long long long long long */); + call( + /* call argument long long long long long long long long long long long long long long */ + ); +// TODO[@fisker]: fix this fn = function (/* function long parameter long long long long long long long long long long long long long */) {}; -newFoo = - new Foo(/* new argument long long long long long long long long long long long long long long */); +newFoo = new Foo( + /* new argument long long long long long long long long long long long long long long */ +); ================================================================================ `; diff --git a/tests/format/js/comments/in-list/dangling-comment-in-list.js b/tests/format/js/comments/in-list/dangling-comment-in-list.js index 46c665cf1..32f33773a 100644 --- a/tests/format/js/comments/in-list/dangling-comment-in-list.js +++ b/tests/format/js/comments/in-list/dangling-comment-in-list.js @@ -4,13 +4,13 @@ call = call(/* call argument */) fn = function(/* function parameter */) {} newFoo = new Foo(/* new argument */) -// TODO[@fisker]: fix the following array = [ /* array */] object = { /* object */} call = call( /* call argument */) +// TODO[@fisker]: fix this fn = function( /* function parameter */) {} newFoo = new Foo @@ -19,5 +19,6 @@ newFoo = new Foo array = [/* array long long long long long long long long long long long long long long */] object = {/* object long long long long long long long long long long long long long long */} call = call(/* call argument long long long long long long long long long long long long long long */) +// TODO[@fisker]: fix this fn = function (/* function long parameter long long long long long long long long long long long long long */) {} newFoo = new Foo(/* new argument long long long long long long long long long long long long long long */) diff --git a/tests/format/typescript/comments/__snapshots__/format.test.js.snap b/tests/format/typescript/comments/__snapshots__/format.test.js.snap index b755fabe0..f08ae0fc8 100644 --- a/tests/format/typescript/comments/__snapshots__/format.test.js.snap +++ b/tests/format/typescript/comments/__snapshots__/format.test.js.snap @@ -1364,7 +1364,8 @@ interface Foo { =====================================output===================================== functionName(); -functionName(); // comment +functionName // comment +(); interface Foo { < A, // comment