fix(formatter): wrap comment-only JSX expression container in a group (#27666)

Fixes #27496
This commit is contained in:
leaysgur committed 2026-10-14 01:45:31 +00:00
1 parent a0a987cbbd
commit a07a0fbb8f
3 files changed
+115 -25

No files matched your search

+18 -25
View File
@@ -154,31 +154,24 @@ impl<'a> FormatWrite<'a> for AstNode<'a, JSXExpressionContainer<'a>> {
let comments = f.context().comments().comments_before(self.span.end);
let has_line_comment = comments.iter().any(Comment::is_line);
write!(f, ["{"]);
if has_line_comment {
write!(
f,
[
FormatDanglingComments::Comments {
comments,
indent: DanglingIndentMode::Block
},
format_dangling_comments(self.span).with_block_indent(),
hard_line_break()
]
);
} else {
write!(
f,
[FormatDanglingComments::Comments {
comments,
indent: DanglingIndentMode::None
},]
);
}
write!(f, ["}"]);
let format_comments = format_with(|f| {
let indent = if has_line_comment {
DanglingIndentMode::Block
} else {
DanglingIndentMode::None
};
write!(f, [FormatDanglingComments::Comments { comments, indent }]);
if has_line_comment {
write!(
f,
[
format_dangling_comments(self.span).with_block_indent(),
hard_line_break()
]
);
}
});
write!(f, [group(&format_args!("{", format_comments, "}"))]);
} else {
let is_conditional_or_binary = matches!(
self.expression,
@@ -0,0 +1,19 @@
// A comment-only expression container is a group like Prettier's;
// measuring the over-long comment resets the re-measure pending from the flat hard line after `text`,
// so `<a>` stays flat and only its `{" "}` separator breaks.
export const X = () => (
<p>
text
{/* this comment is deliberately longer than the print width so that it cannot fit on one line at all */}
aaa bbb ccc ddd eee fff ggg hhh iii jjj kkk lll <a onClick={() => doSomething()}>link text</a> more
</p>
);
// A short comment fits, the hard line after it prints flat and `<a>` is re-measured with its separator.
export const Y = () => (
<p>
text
{/* short */}
aaa bbb ccc ddd eee fff ggg hhh iii jjj kkk lll <a onClick={() => doSomething()}>link text</a> more
</p>
);
@@ -0,0 +1,78 @@
---
source: crates/oxc_formatter/tests/fixtures/mod.rs
---
==================== Input ====================
// A comment-only expression container is a group like Prettier's;
// measuring the over-long comment resets the re-measure pending from the flat hard line after `text`,
// so `<a>` stays flat and only its `{" "}` separator breaks.
export const X = () => (
<p>
text
{/* this comment is deliberately longer than the print width so that it cannot fit on one line at all */}
aaa bbb ccc ddd eee fff ggg hhh iii jjj kkk lll <a onClick={() => doSomething()}>link text</a> more
</p>
);
// A short comment fits, the hard line after it prints flat and `<a>` is re-measured with its separator.
export const Y = () => (
<p>
text
{/* short */}
aaa bbb ccc ddd eee fff ggg hhh iii jjj kkk lll <a onClick={() => doSomething()}>link text</a> more
</p>
);
==================== Output ====================
------------------
{ printWidth: 80 }
------------------
// A comment-only expression container is a group like Prettier's;
// measuring the over-long comment resets the re-measure pending from the flat hard line after `text`,
// so `<a>` stays flat and only its `{" "}` separator breaks.
export const X = () => (
<p>
text
{/* this comment is deliberately longer than the print width so that it cannot fit on one line at all */}
aaa bbb ccc ddd eee fff ggg hhh iii jjj kkk lll{" "}
<a onClick={() => doSomething()}>link text</a> more
</p>
);
// A short comment fits, the hard line after it prints flat and `<a>` is re-measured with its separator.
export const Y = () => (
<p>
text
{/* short */}
aaa bbb ccc ddd eee fff ggg hhh iii jjj kkk lll{" "}
<a onClick={() => doSomething()}>link text</a> more
</p>
);
-------------------
{ printWidth: 100 }
-------------------
// A comment-only expression container is a group like Prettier's;
// measuring the over-long comment resets the re-measure pending from the flat hard line after `text`,
// so `<a>` stays flat and only its `{" "}` separator breaks.
export const X = () => (
<p>
text
{/* this comment is deliberately longer than the print width so that it cannot fit on one line at all */}
aaa bbb ccc ddd eee fff ggg hhh iii jjj kkk lll <a onClick={() => doSomething()}>link text</a>{" "}
more
</p>
);
// A short comment fits, the hard line after it prints flat and `<a>` is re-measured with its separator.
export const Y = () => (
<p>
text
{/* short */}
aaa bbb ccc ddd eee fff ggg hhh iii jjj kkk lll <a onClick={() => doSomething()}>
link text
</a>{" "}
more
</p>
);
===================== End =====================