Skip to content

Commit 7bc86f4

Browse files
committed
refactor(formatter): simplify foramtting import and export (#14576)
Benefits from the changes of #14110, we don't need to print all remaining comments before `}` in import and export
1 parent 29c3cf2 commit 7bc86f4

File tree

4 files changed

+40
-83
lines changed

4 files changed

+40
-83
lines changed

crates/oxc_formatter/src/generated/format.rs

Lines changed: 20 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -2496,39 +2496,33 @@ impl<'a> Format<'a> for AstNode<'a, ImportDeclarationSpecifier<'a>> {
24962496
impl<'a> Format<'a> for AstNode<'a, ImportSpecifier<'a>> {
24972497
fn fmt(&self, f: &mut Formatter<'_, 'a>) -> FormatResult<()> {
24982498
let is_suppressed = f.comments().is_suppressed(self.span().start);
2499-
if is_suppressed {
2500-
self.format_leading_comments(f)?;
2501-
FormatSuppressedNode(self.span()).fmt(f)?;
2502-
self.format_trailing_comments(f)
2503-
} else {
2504-
self.write(f)
2505-
}
2499+
self.format_leading_comments(f)?;
2500+
let result =
2501+
if is_suppressed { FormatSuppressedNode(self.span()).fmt(f) } else { self.write(f) };
2502+
self.format_trailing_comments(f)?;
2503+
result
25062504
}
25072505
}
25082506

25092507
impl<'a> Format<'a> for AstNode<'a, ImportDefaultSpecifier<'a>> {
25102508
fn fmt(&self, f: &mut Formatter<'_, 'a>) -> FormatResult<()> {
25112509
let is_suppressed = f.comments().is_suppressed(self.span().start);
2512-
if is_suppressed {
2513-
self.format_leading_comments(f)?;
2514-
FormatSuppressedNode(self.span()).fmt(f)?;
2515-
self.format_trailing_comments(f)
2516-
} else {
2517-
self.write(f)
2518-
}
2510+
self.format_leading_comments(f)?;
2511+
let result =
2512+
if is_suppressed { FormatSuppressedNode(self.span()).fmt(f) } else { self.write(f) };
2513+
self.format_trailing_comments(f)?;
2514+
result
25192515
}
25202516
}
25212517

25222518
impl<'a> Format<'a> for AstNode<'a, ImportNamespaceSpecifier<'a>> {
25232519
fn fmt(&self, f: &mut Formatter<'_, 'a>) -> FormatResult<()> {
25242520
let is_suppressed = f.comments().is_suppressed(self.span().start);
2525-
if is_suppressed {
2526-
self.format_leading_comments(f)?;
2527-
FormatSuppressedNode(self.span()).fmt(f)?;
2528-
self.format_trailing_comments(f)
2529-
} else {
2530-
self.write(f)
2531-
}
2521+
self.format_leading_comments(f)?;
2522+
let result =
2523+
if is_suppressed { FormatSuppressedNode(self.span()).fmt(f) } else { self.write(f) };
2524+
self.format_trailing_comments(f)?;
2525+
result
25322526
}
25332527
}
25342528

@@ -2620,13 +2614,11 @@ impl<'a> Format<'a> for AstNode<'a, ExportAllDeclaration<'a>> {
26202614
impl<'a> Format<'a> for AstNode<'a, ExportSpecifier<'a>> {
26212615
fn fmt(&self, f: &mut Formatter<'_, 'a>) -> FormatResult<()> {
26222616
let is_suppressed = f.comments().is_suppressed(self.span().start);
2623-
if is_suppressed {
2624-
self.format_leading_comments(f)?;
2625-
FormatSuppressedNode(self.span()).fmt(f)?;
2626-
self.format_trailing_comments(f)
2627-
} else {
2628-
self.write(f)
2629-
}
2617+
self.format_leading_comments(f)?;
2618+
let result =
2619+
if is_suppressed { FormatSuppressedNode(self.span()).fmt(f) } else { self.write(f) };
2620+
self.format_trailing_comments(f)?;
2621+
result
26302622
}
26312623
}
26322624

crates/oxc_formatter/src/write/export_declarations.rs

Lines changed: 8 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ impl<'a> FormatWrite<'a> for AstNode<'a, ExportNamedDeclaration<'a>> {
146146
[
147147
export_kind,
148148
"{",
149-
group(&soft_block_indent_with_maybe_space(&specifiers, needs_space))
149+
group(&soft_block_indent_with_maybe_space(specifiers, needs_space))
150150
]
151151
)?;
152152
}
@@ -177,15 +177,12 @@ impl<'a> Format<'a> for AstNode<'a, Vec<'a, ExportSpecifier<'a>>> {
177177
.map(|specifier| {
178178
format_once(move |f| {
179179
// Should add empty line before the specifier if there are comments before it.
180-
let comments =
181-
f.context().comments().comments_before(specifier.span().start);
182-
if !comments.is_empty() {
183-
if f.source_text().get_lines_before(comments[0].span, f.comments())
180+
let specifier_span = specifier.span();
181+
if f.context().comments().has_comment_before(specifier_span.start)
182+
&& f.source_text().get_lines_before(specifier_span, f.comments())
184183
> 1
185-
{
186-
write!(f, [empty_line()])?;
187-
}
188-
write!(f, [FormatLeadingComments::Comments(comments)])?;
184+
{
185+
write!(f, [empty_line()])?;
189186
}
190187

191188
write!(f, specifier)
@@ -209,18 +206,9 @@ impl<'a> FormatWrite<'a> for AstNode<'a, ExportSpecifier<'a>> {
209206

210207
write!(f, [self.export_kind()]);
211208
if self.local.span() == self.exported.span() {
212-
write!(f, self.exported())?;
209+
write!(f, self.exported())
213210
} else {
214-
write!(f, [self.local(), space(), "as", space(), self.exported()])?;
215-
}
216-
217-
if f.source_text().next_non_whitespace_byte_is(self.span.end, b'}') {
218-
// `export { a as b /* comment */ } from 'mod'
219-
// ^^^^^^^^^^^^ get comments that before `}` to print
220-
let comments = f.context().comments().comments_before_character(self.span.end, b'}');
221-
write!(f, [FormatTrailingComments::Comments(comments)])
222-
} else {
223-
self.format_trailing_comments(f)
211+
write!(f, [self.local(), space(), "as", space(), self.exported()])
224212
}
225213
}
226214
}

crates/oxc_formatter/src/write/import_declaration.rs

Lines changed: 12 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ impl<'a> Format<'a> for AstNode<'a, Vec<'a, ImportDeclarationSpecifier<'a>>> {
9191
} else if self.len() == 1
9292
&& let Some(ImportDeclarationSpecifier::ImportSpecifier(specifier)) =
9393
specifiers_iter.peek().map(AsRef::as_ref)
94-
&& !f.comments().has_comment_before(specifier.local.span.start)
94+
&& f.comments().comments_before_character(self.parent.span().start, b'}').is_empty()
9595
{
9696
write!(
9797
f,
@@ -117,20 +117,16 @@ impl<'a> Format<'a> for AstNode<'a, Vec<'a, ImportDeclarationSpecifier<'a>>> {
117117
.map(|specifier| {
118118
format_once(move |f| {
119119
// Should add empty line before the specifier if there are comments before it.
120-
let comments = f
121-
.context()
120+
let specifier_span = specifier.span();
121+
if f.context()
122122
.comments()
123-
.comments_before(specifier.span().start);
124-
if !comments.is_empty() {
125-
if f.source_text()
126-
.get_lines_before(comments[0].span, f.comments())
123+
.has_comment_before(specifier_span.start)
124+
&& f.source_text()
125+
.get_lines_before(specifier_span, f.comments())
127126
> 1
128-
{
129-
write!(f, [empty_line()])?;
130-
}
131-
write!(f, [FormatLeadingComments::Comments(comments)])?;
127+
{
128+
write!(f, [empty_line()])?;
132129
}
133-
134130
write!(f, specifier)
135131
})
136132
});
@@ -159,37 +155,22 @@ impl<'a> FormatWrite<'a> for AstNode<'a, ImportSpecifier<'a>> {
159155
}
160156
write!(f, [self.import_kind()])?;
161157
if self.local.span == self.imported.span() {
162-
write!(f, [self.local()])?;
163-
} else {
164-
write!(f, [self.imported(), space(), "as", space(), self.local()])?;
165-
}
166-
167-
if f.source_text().next_non_whitespace_byte_is(self.span.end, b'}') {
168-
let comments = f.context().comments().comments_before_character(self.span.end, b'}');
169-
write!(f, [FormatTrailingComments::Comments(comments)])
158+
write!(f, [self.local()])
170159
} else {
171-
self.format_trailing_comments(f)
160+
write!(f, [self.imported(), space(), "as", space(), self.local()])
172161
}
173162
}
174163
}
175164

176165
impl<'a> FormatWrite<'a> for AstNode<'a, ImportDefaultSpecifier<'a>> {
177166
fn write(&self, f: &mut Formatter<'_, 'a>) -> FormatResult<()> {
178-
self.local().fmt(f)
167+
write!(f, [self.local()])
179168
}
180169
}
181170

182171
impl<'a> FormatWrite<'a> for AstNode<'a, ImportNamespaceSpecifier<'a>> {
183172
fn write(&self, f: &mut Formatter<'_, 'a>) -> FormatResult<()> {
184-
write!(f, ["*", space(), "as", space()])?;
185-
let local = self.local();
186-
local.format_leading_comments(f)?;
187-
local.write(f)?;
188-
// `import * as all /* comment */ from 'mod'`
189-
// ^^^^^^^^^^^^ get comments that before `from` keyword to print
190-
// `f` is the first character of `from`
191-
let comments = f.context().comments().comments_before_character(local.span().start, b'f');
192-
write!(f, [space(), FormatTrailingComments::Comments(comments)])
173+
write!(f, ["*", space(), "as", space(), self.local()])
193174
}
194175
}
195176

tasks/ast_tools/src/generators/formatter/format.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,6 @@ const AST_NODE_WITHOUT_PRINTING_COMMENTS_LIST: &[&str] = &[
3131
"JSXFragment",
3232
//
3333
"TemplateElement",
34-
"ImportSpecifier",
35-
"ImportDefaultSpecifier",
36-
"ImportNamespaceSpecifier",
37-
"ExportSpecifier",
3834
];
3935

4036
const AST_NODE_NEEDS_PARENTHESES: &[&str] = &[

0 commit comments

Comments
 (0)