Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 19 additions & 8 deletions crates/oxc_formatter/src/formatter/source_text.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,13 +129,24 @@ impl<'a> SourceText<'a> {
self.text_for(&span).chars().count()
}

/// Count consecutive line breaks after position
/// Count consecutive line breaks after position, returning `0` if only whitespace follows
pub fn lines_after(&self, end: u32) -> usize {
self.slice_from(end)
.chars()
.filter(|&c| !is_white_space_single_line(c))
.take_while(|&c| is_line_terminator(c))
.count()
let mut count = 0;
for char in self.slice_from(end).chars() {
if is_white_space_single_line(char) {
continue;
}

if is_line_terminator(char) {
count += 1;
continue;
}

return count;
}

// No non-whitespace characters found after position, so return `0` to avoid adding extra new lines
0
}

/// Count line breaks between syntax nodes, considering comments and parentheses
Expand All @@ -146,7 +157,7 @@ impl<'a> SourceText<'a> {

// Should skip the leading comments of the node.
if let Some(comment) = comments.first()
&& comment.span.end < start
&& comment.span.end <= start
{
start = comment.span.start;
}
Expand Down Expand Up @@ -188,7 +199,7 @@ impl<'a> SourceText<'a> {
count += 1;
}

count
0
}

pub fn is_own_line_comment(&self, comment: &Comment) -> bool {
Expand Down
17 changes: 3 additions & 14 deletions crates/oxc_formatter/src/write/program.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use oxc_syntax::identifier::{ZWNBSP, is_line_terminator};

use crate::{
Buffer, Format, FormatResult, FormatTrailingCommas, TrailingSeparator, format_args,
formatter::{prelude::*, separated::FormatSeparatedIter, trivia::FormatTrailingComments},
formatter::{prelude::*, trivia::FormatTrailingComments},
generated::ast_nodes::{AstNode, AstNodes},
utils::{
call_expression::is_test_call_expression,
Expand All @@ -25,7 +25,7 @@ impl<'a> FormatWrite<'a> for AstNode<'a, Program<'a>> {
fn write(&self, f: &mut Formatter<'_, 'a>) -> FormatResult<()> {
let format_trailing_comments = format_once(|f| {
let comments = f.context().comments().comments_before(self.span.end);
FormatTrailingComments::Comments(comments).fmt(f)
write!(f, FormatTrailingComments::Comments(comments))
});

write!(
Expand Down Expand Up @@ -112,19 +112,8 @@ impl<'a> Format<'a> for AstNode<'a, Vec<'a, Directive<'a>>> {
// }
//```
// so we should keep an extra empty line after JsDirectiveList
let source_text = f.context().source_text();
let mut count = 0;
let mut source_text_chars = source_text.slice_from(last_directive.span.end).chars();
for char in source_text_chars.by_ref() {
if is_line_terminator(char) {
count += 1;
} else if !char.is_whitespace() {
break;
}
}

// Need an extra empty line if it has the following line and still has non-characters after whitespace.
let need_extra_empty_line = source_text_chars.next().is_some() && count > 1;
let need_extra_empty_line = f.source_text().lines_after(last_directive.span.end) > 1;
write!(f, if need_extra_empty_line { empty_line() } else { hard_line_break() })
}
}
Expand Down
Loading