diff --git a/crates/oxc_codegen/src/comment.rs b/crates/oxc_codegen/src/comment.rs index 799cd1a0c64d8..d0e2c8bc7aea8 100644 --- a/crates/oxc_codegen/src/comment.rs +++ b/crates/oxc_codegen/src/comment.rs @@ -64,6 +64,22 @@ impl Codegen<'_> { } } + /// Print comments attached to any position in the given range `(start, end)` (exclusive). + /// Returns `true` if any comments were printed. + pub(crate) fn print_comments_in_range(&mut self, start: u32, end: u32) -> bool { + if self.comments.is_empty() { + return false; + } + // Find and remove the first key in the range. + let key = self.comments.keys().find(|&&k| k > start && k < end).copied(); + if let Some(key) = key { + let comments = self.comments.remove(&key).unwrap(); + self.print_comments(&comments); + return true; + } + false + } + pub(crate) fn print_expr_comments(&mut self, start: u32) -> bool { if self.comments.is_empty() { return false; diff --git a/crates/oxc_codegen/src/gen.rs b/crates/oxc_codegen/src/gen.rs index ef7322e8cd1b5..32e7748475795 100644 --- a/crates/oxc_codegen/src/gen.rs +++ b/crates/oxc_codegen/src/gen.rs @@ -2482,9 +2482,16 @@ impl Gen for JSXEmptyExpression { impl Gen for JSXExpression<'_> { fn r#gen(&self, p: &mut Codegen, ctx: Context) { - match self { - Self::EmptyExpression(expr) => expr.print(p, ctx), - _ => p.print_expression(self.to_expression()), + if let Self::EmptyExpression(expr) = self { + expr.print(p, ctx); + } else { + let expr = self.to_expression(); + let start = expr.span().start; + if p.has_comment(start) { + p.print_comments_at(start); + p.print_indent(); + } + p.print_expression(expr); } } } @@ -2515,7 +2522,11 @@ impl Gen for JSXAttributeValue<'_> { impl Gen for JSXSpreadAttribute<'_> { fn r#gen(&self, p: &mut Codegen, _ctx: Context) { - p.print_str("{..."); + p.print_ascii_byte(b'{'); + if p.print_comments_in_range(self.span.start, self.argument.span().start) { + p.print_indent(); + } + p.print_str("..."); self.argument.print_expr(p, Precedence::Comma, Context::empty()); p.print_ascii_byte(b'}'); } diff --git a/crates/oxc_codegen/tests/integration/comments.rs b/crates/oxc_codegen/tests/integration/comments.rs index 4d422504bd67f..145ae33608f0e 100644 --- a/crates/oxc_codegen/tests/integration/comments.rs +++ b/crates/oxc_codegen/tests/integration/comments.rs @@ -20,6 +20,16 @@ fn test_comment_at_top_of_file() { #[test] fn unit() { test_same("
{/* Hello */}
;\n"); + // https://github.com/oxc-project/oxc/issues/17266 + test("console.log(
)", "console.log(
);\n"); + test( + "console.log(
)", + "console.log(
);\n", + ); + test("console.log(
)", "console.log(
);\n"); + test("console.log(
)", "console.log(
);\n"); + test("console.log(
{/*before*/ x}
)", "console.log(
{/*before*/ x}
);\n"); + test("console.log(<>{/*before*/ x})", "console.log(<>{/*before*/ x});\n"); // https://lingui.dev/ref/macro#definemessage test("const message = /*i18n*/{};", "const message = (/*i18n*/ {});\n"); test(