From 9096a639cfa36e04c2ddd346831978c681ad958d Mon Sep 17 00:00:00 2001 From: Dunqing <29533304+Dunqing@users.noreply.github.com> Date: Fri, 28 Nov 2025 02:49:47 +0000 Subject: [PATCH] fix(formatter): correct printing of trailing comments after the semicolon for class properties (#16225) * close: #16130 --- crates/oxc_formatter/src/write/class.rs | 20 ++++++-- .../js/semicolons/class-properties.js | 5 ++ .../js/semicolons/class-properties.js.snap | 48 +++++++++++++++++++ 3 files changed, 70 insertions(+), 3 deletions(-) create mode 100644 crates/oxc_formatter/tests/fixtures/js/semicolons/class-properties.js create mode 100644 crates/oxc_formatter/tests/fixtures/js/semicolons/class-properties.js.snap diff --git a/crates/oxc_formatter/src/write/class.rs b/crates/oxc_formatter/src/write/class.rs index 863b63ba9adb5..e164414b115da 100644 --- a/crates/oxc_formatter/src/write/class.rs +++ b/crates/oxc_formatter/src/write/class.rs @@ -567,8 +567,6 @@ impl<'a, 'b> FormatClassElementWithSemicolon<'a, 'b> { impl<'a> Format<'a> for FormatClassElementWithSemicolon<'a, '_> { fn fmt(&self, f: &mut Formatter<'_, 'a>) { - write!(f, [self.element]); - let needs_semi = matches!( self.element.as_ref(), ClassElement::PropertyDefinition(_) | ClassElement::AccessorProperty(_) @@ -580,7 +578,23 @@ impl<'a> Format<'a> for FormatClassElementWithSemicolon<'a, '_> { Semicolons::AsNeeded => self.needs_semicolon(), }; - write!(f, needs_semi.then_some(";")); + if needs_semi { + write!(f, [FormatNodeWithoutTrailingComments(self.element), ";"]); + // Print trailing comments after the semicolon + match self.element.as_ast_nodes() { + AstNodes::PropertyDefinition(prop) => { + prop.format_trailing_comments(f); + } + AstNodes::AccessorProperty(prop) => { + prop.format_trailing_comments(f); + } + _ => { + unreachable!("Only `PropertyDefinition` and `AccessorProperty` can reach here"); + } + } + } else { + write!(f, self.element); + } } } diff --git a/crates/oxc_formatter/tests/fixtures/js/semicolons/class-properties.js b/crates/oxc_formatter/tests/fixtures/js/semicolons/class-properties.js new file mode 100644 index 0000000000000..77512f3601b0d --- /dev/null +++ b/crates/oxc_formatter/tests/fixtures/js/semicolons/class-properties.js @@ -0,0 +1,5 @@ +class X { + prop1 = "test"; /* comment */ + accessor prop2 = 1; /* comment */ + static prop3; /* comment */ +} diff --git a/crates/oxc_formatter/tests/fixtures/js/semicolons/class-properties.js.snap b/crates/oxc_formatter/tests/fixtures/js/semicolons/class-properties.js.snap new file mode 100644 index 0000000000000..37ee139c891e4 --- /dev/null +++ b/crates/oxc_formatter/tests/fixtures/js/semicolons/class-properties.js.snap @@ -0,0 +1,48 @@ +--- +source: crates/oxc_formatter/tests/fixtures/mod.rs +--- +==================== Input ==================== +class X { + prop1 = "test"; /* comment */ + accessor prop2 = 1; /* comment */ + static prop3; /* comment */ +} + +==================== Output ==================== +------------------------------ +{ printWidth: 80, semi: true } +------------------------------ +class X { + prop1 = "test"; /* comment */ + accessor prop2 = 1; /* comment */ + static prop3; /* comment */ +} + +------------------------------- +{ printWidth: 100, semi: true } +------------------------------- +class X { + prop1 = "test"; /* comment */ + accessor prop2 = 1; /* comment */ + static prop3; /* comment */ +} + +------------------------------- +{ printWidth: 80, semi: false } +------------------------------- +class X { + prop1 = "test" /* comment */ + accessor prop2 = 1 /* comment */ + static prop3 /* comment */ +} + +-------------------------------- +{ printWidth: 100, semi: false } +-------------------------------- +class X { + prop1 = "test" /* comment */ + accessor prop2 = 1 /* comment */ + static prop3 /* comment */ +} + +===================== End =====================