From 0ba2d693ba8bfa4b29ebc363cf534e95b43bf3a8 Mon Sep 17 00:00:00 2001 From: SUZUKI Sosuke Date: Fri, 24 Nov 2023 00:56:14 +0900 Subject: [PATCH] Fix unstable and ugly formatting for comments in destructuring patterns (#15708) --- changelog_unreleased/typescript/15708.md | 31 +++++ src/language-js/comments/handle-comments.js | 39 ++++++ tests/format/typescript/comments/15707.ts | 55 ++++++++ .../comments/__snapshots__/jsfmt.spec.js.snap | 122 ++++++++++++++++++ 4 files changed, 247 insertions(+) create mode 100644 changelog_unreleased/typescript/15708.md create mode 100644 tests/format/typescript/comments/15707.ts diff --git a/changelog_unreleased/typescript/15708.md b/changelog_unreleased/typescript/15708.md new file mode 100644 index 000000000..1565fc229 --- /dev/null +++ b/changelog_unreleased/typescript/15708.md @@ -0,0 +1,31 @@ +#### Fix unstable and ugly formatting for comments in destructuring patterns (#15708 by @sosukesuzuki) + + +```tsx +// Input +const { + foo, + // bar + // baz +}: Foo = expr; + +// Prettier stable +const { + foo1, +} // bar +// baz +: Foo = expr; + +// Prettier stable second output +const { + foo1, // bar +} // baz +: Foo = expr; + +// Prettier main +const { + foo1, + // bar + // baz +}: Foo = expr; +``` diff --git a/src/language-js/comments/handle-comments.js b/src/language-js/comments/handle-comments.js index 0712fbe2e..40b677997 100644 --- a/src/language-js/comments/handle-comments.js +++ b/src/language-js/comments/handle-comments.js @@ -62,6 +62,7 @@ function handleOwnLineComment(context) { handleLabeledStatementComments, handleBreakAndContinueStatementComments, handleNestedConditionalExpressionComments, + handleCommentsInDestructuringPattern, ].some((fn) => fn(context)); } @@ -976,6 +977,44 @@ function handleLastUnionElementInExpression({ return false; } +/** + * const [ + * foo, + * // bar + * // baz + * ]: Foo = foo(); + * + * const { + * foo, + * // bar + * // baz + * }: Foo = foo(); + * + */ +function handleCommentsInDestructuringPattern({ + comment, + enclosingNode, + precedingNode, + followingNode, +}) { + if ( + (enclosingNode?.type === "ObjectPattern" || + enclosingNode?.type === "ArrayPattern") && + followingNode?.type === "TSTypeAnnotation" + ) { + if (precedingNode) { + addTrailingComment(precedingNode, comment); + } else { + // const { + // // bar + // // baz + // }: Foo = expr; + addDanglingComment(enclosingNode, comment); + } + return true; + } +} + /** * @param {Node} node * @returns {boolean} diff --git a/tests/format/typescript/comments/15707.ts b/tests/format/typescript/comments/15707.ts new file mode 100644 index 000000000..98f7001f1 --- /dev/null +++ b/tests/format/typescript/comments/15707.ts @@ -0,0 +1,55 @@ +const { + foo, + // bar + // baz +}: Foo = expr; + +const { + foo1, + // bar + foo2, + // baz +}: Foo = expr; + +const [ + foo, + // bar + // baz +]: Foo = expr; + +const [ + foo1, + // bar + foo2, + // baz +]: Foo = expr; + +function method({ + foo, + // bar = "bar", + // bazz = "bazz", +}: Foo) {} + +function method({ + foo1, + // bar = "bar", + foo2 + // bazz = "bazz", +}: Foo) {} + +function method([ + foo, + // bar = "bar", + foo2 + // bazz = "bazz", +]: Foo) {} + +const { + // bar + // baz +}: Foo = expr; + +const [ + // bar + // baz +]: Foo = expr; diff --git a/tests/format/typescript/comments/__snapshots__/jsfmt.spec.js.snap b/tests/format/typescript/comments/__snapshots__/jsfmt.spec.js.snap index 5970bf034..1c8718267 100644 --- a/tests/format/typescript/comments/__snapshots__/jsfmt.spec.js.snap +++ b/tests/format/typescript/comments/__snapshots__/jsfmt.spec.js.snap @@ -1,5 +1,127 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`15707.ts format 1`] = ` +====================================options===================================== +parsers: ["typescript"] +printWidth: 80 + | printWidth +=====================================input====================================== +const { + foo, + // bar + // baz +}: Foo = expr; + +const { + foo1, + // bar + foo2, + // baz +}: Foo = expr; + +const [ + foo, + // bar + // baz +]: Foo = expr; + +const [ + foo1, + // bar + foo2, + // baz +]: Foo = expr; + +function method({ + foo, + // bar = "bar", + // bazz = "bazz", +}: Foo) {} + +function method({ + foo1, + // bar = "bar", + foo2 + // bazz = "bazz", +}: Foo) {} + +function method([ + foo, + // bar = "bar", + foo2 + // bazz = "bazz", +]: Foo) {} + +const { + // bar + // baz +}: Foo = expr; + +const [ + // bar + // baz +]: Foo = expr; + +=====================================output===================================== +const { + foo, + // bar + // baz +}: Foo = expr; + +const { + foo1, + // bar + foo2, + // baz +}: Foo = expr; + +const [ + foo, + // bar + // baz +]: Foo = expr; + +const [ + foo1, + // bar + foo2, + // baz +]: Foo = expr; + +function method({ + foo, + // bar = "bar", + // bazz = "bazz", +}: Foo) {} + +function method({ + foo1, + // bar = "bar", + foo2, + // bazz = "bazz", +}: Foo) {} + +function method([ + foo, + // bar = "bar", + foo2, + // bazz = "bazz", +]: Foo) {} + +const { + // bar + // baz +}: Foo = expr; + +const [ + // bar + // baz +]: Foo = expr; + +================================================================================ +`; + exports[`abstract_class.ts format 1`] = ` ====================================options===================================== parsers: ["typescript"]