Skip to content

Commit e67f8c9

Browse files
committed
go
1 parent 96b2c59 commit e67f8c9

File tree

6 files changed

+55
-43
lines changed

6 files changed

+55
-43
lines changed

crates/oxc_formatter/src/formatter/source_text.rs

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -129,13 +129,24 @@ impl<'a> SourceText<'a> {
129129
self.text_for(&span).chars().count()
130130
}
131131

132-
/// Count consecutive line breaks after position
132+
/// Count consecutive line breaks after position, returning `0` if only whitespace follows
133133
pub fn lines_after(&self, end: u32) -> usize {
134-
self.slice_from(end)
135-
.chars()
136-
.filter(|&c| !is_white_space_single_line(c))
137-
.take_while(|&c| is_line_terminator(c))
138-
.count()
134+
let mut count = 0;
135+
for char in self.slice_from(end).chars() {
136+
if is_white_space_single_line(char) {
137+
continue;
138+
}
139+
140+
if is_line_terminator(char) {
141+
count += 1;
142+
continue;
143+
}
144+
145+
return count;
146+
}
147+
148+
// No non-whitespace characters found after position, so return `0` to avoid adding extra new lines
149+
0
139150
}
140151

141152
/// Count line breaks between syntax nodes, considering comments and parentheses
@@ -188,7 +199,7 @@ impl<'a> SourceText<'a> {
188199
count += 1;
189200
}
190201

191-
count
202+
0
192203
}
193204

194205
pub fn is_own_line_comment(&self, comment: &Comment) -> bool {

crates/oxc_formatter/src/utils/conditional.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -144,13 +144,13 @@ fn format_trailing_comments<'a>(
144144
if source_text.contains_newline_between(start, comment.span.start) {
145145
return &comments[..index];
146146
}
147-
// If this comment is a line comment, then it is a end of line comment, so we stop here and return the comments with this comment
148-
else if comment.is_line() {
147+
// If this comment is a line comment or an end of line comment, so we stop here and return the comments with this comment
148+
else if comment.is_line() || source_text.is_end_of_line_comment(comment) {
149149
return &comments[..=index];
150150
}
151151
// Store the index of the comment before the operator, if no line comment or no new line is found, then return all comments before operator
152152
else if source_text.bytes_contain(start, comment.span.start, operator) {
153-
index_before_operator = Some(index + 1);
153+
index_before_operator = Some(index);
154154
}
155155

156156
// Update the start position for the next iteration

crates/oxc_formatter/src/utils/typecast.rs

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -60,24 +60,36 @@ pub fn format_type_cast_comment_node<'a, T>(
6060

6161
write!(f, [FormatLeadingComments::Comments(type_cast_comments)])?;
6262
f.context_mut().comments_mut().mark_as_handled_type_cast_comment();
63-
} else {
64-
let elements = f.elements().iter().rev();
65-
6663
// If the printed cast comment is already handled, return early to avoid infinite recursion.
67-
if !comments.is_already_handled_type_cast_comment()
68-
&& comments.printed_comments().last().is_some_and(|c| {
69-
c.span.end <= span.start
70-
&& source.all_bytes_match(c.span.end, span.start, |c| {
71-
c.is_ascii_whitespace() || c == b'('
72-
})
73-
&& f.comments().is_type_cast_comment(c)
74-
})
64+
} else if !comments.is_already_handled_type_cast_comment()
65+
&& let Some(last_printed_comment) = comments.printed_comments().last()
66+
{
67+
if !last_printed_comment.span.end <= span.start
68+
|| !f.comments().is_type_cast_comment(last_printed_comment)
7569
{
76-
f.context_mut().comments_mut().mark_as_handled_type_cast_comment();
77-
} else {
78-
// No typecast comment
7970
return Ok(false);
8071
}
72+
73+
let mut has_left_paren = false;
74+
// Check whether there is only whitespace or left parenthesis between the comment and the node
75+
for &byte in source.bytes_range(last_printed_comment.span.end, span.start) {
76+
if !byte.is_ascii_whitespace() {
77+
if byte == b'(' {
78+
has_left_paren = true;
79+
} else {
80+
return Ok(false);
81+
}
82+
}
83+
}
84+
85+
if !has_left_paren {
86+
return Ok(false);
87+
}
88+
89+
f.context_mut().comments_mut().mark_as_handled_type_cast_comment();
90+
} else {
91+
// No typecast comment
92+
return Ok(false);
8193
}
8294

8395
// https://github.com/prettier/prettier/blob/7584432401a47a26943dd7a9ca9a8e032ead7285/src/language-js/print/estree.js#L117-L120

crates/oxc_formatter/src/write/call_arguments.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,8 +96,10 @@ impl<'a> Format<'a> for AstNode<'a, ArenaVec<'a, Argument<'a>>> {
9696
);
9797
}
9898

99-
let has_empty_line =
100-
self.iter().any(|arg| f.source_text().get_lines_before(arg.span(), f.comments()) > 1);
99+
let has_empty_line = self
100+
.iter()
101+
.skip(1)
102+
.any(|arg| f.source_text().get_lines_before(arg.span(), f.comments()) > 1);
101103
if has_empty_line
102104
|| (!matches!(self.parent.parent(), AstNodes::Decorator(_))
103105
&& is_function_composition_args(self))

crates/oxc_formatter/src/write/program.rs

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use oxc_syntax::identifier::{ZWNBSP, is_line_terminator};
77

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

3131
write!(
@@ -112,19 +112,8 @@ impl<'a> Format<'a> for AstNode<'a, Vec<'a, Directive<'a>>> {
112112
// }
113113
//```
114114
// so we should keep an extra empty line after JsDirectiveList
115-
let source_text = f.context().source_text();
116-
let mut count = 0;
117-
let mut source_text_chars = source_text.slice_from(last_directive.span.end).chars();
118-
for char in source_text_chars.by_ref() {
119-
if is_line_terminator(char) {
120-
count += 1;
121-
} else if !char.is_whitespace() {
122-
break;
123-
}
124-
}
125115

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

tasks/coverage/snapshots/formatter_babel.snap

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@ commit: 41d96516
22

33
formatter_babel Summary:
44
AST Parsed : 2423/2423 (100.00%)
5-
Positive Passed: 2421/2423 (99.92%)
6-
Mismatch: tasks/coverage/babel/packages/babel-parser/test/fixtures/es2015/class/division/input.js
7-
5+
Positive Passed: 2422/2423 (99.96%)
86
Expect to Parse: tasks/coverage/babel/packages/babel-parser/test/fixtures/es2022/top-level-await-unambiguous/module/input.js
97
`await` is only allowed within async functions and at the top levels of modules

0 commit comments

Comments
 (0)