mirror of
https://github.com/oxc-project/oxc.git
synced 2026-11-04 10:29:58 +00:00
fix(codegen): print comments in JSX expression containers and spread attributes (#19701)
## Summary Closes #17266 - Print leading comments attached to expressions inside `JSXExpressionContainer` (e.g. `{/*before*/ x}`, `{/*before*/ "y"}`, `{/*before*/ true}`) - Print comments between `{` and `...` in `JSXSpreadAttribute` (e.g. `{/*before*/ ...x}`) - Add `print_comments_in_range` helper for finding comments attached to positions not directly represented in the AST (needed for the `...` token in spread attributes) 🤖 Generated with [Claude Code](https://claude.com/claude-code)
This commit is contained in:
3 files changed
+41
-4
No files matched your search
@@ -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;
|
||||
|
||||
@@ -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'}');
|
||||
}
|
||||
|
||||
@@ -20,6 +20,16 @@ fn test_comment_at_top_of_file() {
|
||||
#[test]
|
||||
fn unit() {
|
||||
test_same("<div>{/* Hello */}</div>;\n");
|
||||
// https://github.com/oxc-project/oxc/issues/17266
|
||||
test("console.log(<div x={/*before*/ x} />)", "console.log(<div x={/*before*/ x} />);\n");
|
||||
test(
|
||||
"console.log(<div x={/*before*/ \"y\"} />)",
|
||||
"console.log(<div x={/*before*/ \"y\"} />);\n",
|
||||
);
|
||||
test("console.log(<div x={/*before*/ true} />)", "console.log(<div x={/*before*/ true} />);\n");
|
||||
test("console.log(<div {/*before*/ ...x} />)", "console.log(<div {/*before*/ ...x} />);\n");
|
||||
test("console.log(<div>{/*before*/ x}</div>)", "console.log(<div>{/*before*/ x}</div>);\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(
|
||||
|
||||
Reference in new issue
Block a user