Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix comments inside JSX attributes #14082

Merged
merged 5 commits into from Dec 30, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
17 changes: 17 additions & 0 deletions changelog_unreleased/javascript/14082.md
@@ -0,0 +1,17 @@
#### Fix formatting for comments inside JSX attribute (#14082 with by @fisker)

<!-- prettier-ignore -->
```jsx
// Input
function MyFunctionComponent() {
<button label=/*old*/"new">button</button>
}

// Prettier stable
Error: Comment "old" was not printed. Please report this error!

// Prettier main
function MyFunctionComponent() {
<button label=/*old*/ "new">button</button>;
}
```
9 changes: 7 additions & 2 deletions src/language-js/print/jsx.js
Expand Up @@ -3,6 +3,7 @@
const {
printComments,
printDanglingComments,
printCommentsSeparately,
} = require("../../main/comments.js");
const {
builders: {
Expand Down Expand Up @@ -490,7 +491,11 @@ function printJsxAttribute(path, options, print) {
options.jsxSingleQuote ? "'" : '"'
);
final = final.replace(regex, escaped);
res = [quote, final, quote];
const { leading, trailing } = path.call(
() => printCommentsSeparately(path, options),
"value"
);
res = [leading, quote, final, quote, trailing];
} else {
res = print("value");
}
Expand Down Expand Up @@ -766,7 +771,7 @@ function printJsx(path, options, print) {
return printJsxEmptyExpression(path, options /*, print*/);
case "JSXText":
/* istanbul ignore next */
throw new Error("JSXTest should be handled by JSXElement");
throw new Error("JSXText should be handled by JSXElement");
default:
/* istanbul ignore next */
throw new Error(`Unknown JSX node type: ${JSON.stringify(node.type)}.`);
Expand Down
1 change: 1 addition & 0 deletions tests/config/format-test.js
Expand Up @@ -42,6 +42,7 @@ const unstableTests = new Map(
"js/for/continue-and-break-comment-without-blocks.js",
"typescript/satisfies-operators/comments-unstable.ts",
["js/identifier/parentheses/let.js", (options) => options.semi === false],
"jsx/comments/in-attributes.js",
].map((fixture) => {
const [file, isUnstable = () => true] = Array.isArray(fixture)
? fixture
Expand Down
56 changes: 56 additions & 0 deletions tests/format/jsx/comments/__snapshots__/jsfmt.spec.js.snap
Expand Up @@ -27,6 +27,62 @@ const render = (items) => (
================================================================================
`;

exports[`in-attributes.js - {"bracketSameLine":true} format 1`] = `
====================================options=====================================
bracketSameLine: true
parsers: ["flow", "babel", "typescript"]
printWidth: 80
| printWidth
=====================================input======================================
<div
attr=/* comment */"foo"
></div>;

<div
attr=
/* comment */
"foo"
></div>;

<div
attr= /* comment */
"foo"
></div>;

<div
attr=
/* comment */ "foo"
></div>;

<div
attr=
// comment
"foo"
></div>;

<div
attr= // comment
"foo"
></div>;

=====================================output=====================================
<div attr=/* comment */ "foo"></div>;

<div attr=/* comment */
"foo"></div>;

<div attr /* comment */="foo"></div>;

<div attr=/* comment */ "foo"></div>;

<div attr=// comment
"foo"></div>;

<div attr="foo"></div>; // comment

================================================================================
`;

exports[`in-end-tag.js - {"bracketSameLine":true} [typescript] format 1`] = `
"Identifier expected. (2:6)
1 | /* =========== before slash =========== */
Expand Down
30 changes: 30 additions & 0 deletions tests/format/jsx/comments/in-attributes.js
@@ -0,0 +1,30 @@
<div
attr=/* comment */"foo"
></div>;

<div
attr=
/* comment */
"foo"
></div>;

<div
attr= /* comment */
"foo"
></div>;

<div
attr=
/* comment */ "foo"
></div>;

<div
attr=
// comment
"foo"
></div>;

<div
attr= // comment
"foo"
></div>;