Skip to content

Commit 453222d

Browse files
committed
fix(formatter): missing comment handling for end-of-line comments in member chains (#17659)
close: #17570
1 parent 0805ff2 commit 453222d

3 files changed

Lines changed: 38 additions & 21 deletions

File tree

crates/oxc_formatter/src/formatter/comments.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ impl<'a> Comments<'a> {
182182

183183
/// Returns end-of-line comments that are after the given position (excluding printed ones).
184184
pub fn end_of_line_comments_after(&self, mut pos: u32) -> &'a [Comment] {
185-
let comments = self.unprinted_comments();
185+
let comments = self.comments_after(pos);
186186
for (index, comment) in comments.iter().enumerate() {
187187
if self.source_text.all_bytes_match(pos, comment.span.start, |b| {
188188
matches!(b, b'\t' | b' ' | b'=' | b':')
@@ -248,6 +248,10 @@ impl<'a> Comments<'a> {
248248
self.comments_before_iter(start).any(|comment| comment.followed_by_newline())
249249
}
250250

251+
pub fn has_end_of_line_comment_after(&self, pos: u32) -> bool {
252+
!self.end_of_line_comments_after(pos).is_empty()
253+
}
254+
251255
/// **Critical method**: Advances the printed cursor by one.
252256
///
253257
/// This MUST be called after formatting each comment to maintain system integrity.

crates/oxc_formatter/src/utils/member_chain/mod.rs

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use crate::{
88
JsLabels,
99
ast_nodes::{AstNode, AstNodes},
1010
best_fitting,
11-
formatter::{Buffer, Format, Formatter, prelude::*},
11+
formatter::{Buffer, Comments, Format, Formatter, prelude::*},
1212
utils::{
1313
is_long_curried_call,
1414
member_chain::{
@@ -72,14 +72,10 @@ impl<'a, 'b> MemberChain<'a, 'b> {
7272
return false;
7373
};
7474

75-
let has_comment = first_group.members().first().is_some_and(|member| {
76-
matches!(member, ChainMember::StaticMember(expression)
77-
if f.context().comments().has_comment_in_range(
78-
expression.object().span().end,
79-
expression.property().span.start
80-
)
81-
)
82-
});
75+
let has_comment = first_group
76+
.members()
77+
.first()
78+
.is_some_and(|member| Self::has_comment_in_member(member, f.comments()));
8379

8480
if has_comment {
8581
return false;
@@ -179,15 +175,20 @@ impl<'a, 'b> MemberChain<'a, 'b> {
179175
self.head.members().iter().chain(self.tail.members())
180176
}
181177

178+
/// Check if a member has comments between object and property or end-of-line comments after it
179+
fn has_comment_in_member(member: &ChainMember, comments: &Comments) -> bool {
180+
matches!(
181+
member,
182+
ChainMember::StaticMember(member)
183+
if comments.has_comment_in_range(member.object().span().end, member.property().span.start) || comments.has_end_of_line_comment_after(member.span.end)
184+
)
185+
}
186+
182187
fn has_comment(&self, f: &Formatter<'_, 'a>) -> bool {
183188
let comments = f.comments();
184189

185190
for member in self.members() {
186-
if matches!(
187-
member,
188-
ChainMember::StaticMember(member)
189-
if comments.has_comment_in_range(member.object().span().end, member.property().span.start)
190-
) {
191+
if Self::has_comment_in_member(member, comments) {
191192
return true;
192193
}
193194
}

crates/oxc_formatter/tests/fixtures/ts/member-chains/issue-17570.ts.snap

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,22 +20,34 @@ getParameters /* xxxxxxxxxxxxxxxxxxxxxxxxxxxx */
2020
------------------
2121
{ printWidth: 80 }
2222
------------------
23-
this.getParameters /* xxxxxxxxxxxxxxxxxxxxxxxxxxxx */?.();
23+
this
24+
.getParameters /* xxxxxxxxxxxxxxxxxxxxxxxxxxxx */
25+
?.();
2426

25-
this.getParameters /* xxxxxxxxxxxxxxxxxxxxxxxxxxxx */?.();
27+
this
28+
.getParameters /* xxxxxxxxxxxxxxxxxxxxxxxxxxxx */
29+
?.();
2630

27-
foo.getParameters /* xxxxxxxxxxxxxxxxxxxxxxxxxxxx */?.();
31+
foo
32+
.getParameters /* xxxxxxxxxxxxxxxxxxxxxxxxxxxx */
33+
?.();
2834

2935
getParameters /* xxxxxxxxxxxxxxxxxxxxxxxxxxxx */?.();
3036

3137
-------------------
3238
{ printWidth: 100 }
3339
-------------------
34-
this.getParameters /* xxxxxxxxxxxxxxxxxxxxxxxxxxxx */?.();
40+
this
41+
.getParameters /* xxxxxxxxxxxxxxxxxxxxxxxxxxxx */
42+
?.();
3543

36-
this.getParameters /* xxxxxxxxxxxxxxxxxxxxxxxxxxxx */?.();
44+
this
45+
.getParameters /* xxxxxxxxxxxxxxxxxxxxxxxxxxxx */
46+
?.();
3747

38-
foo.getParameters /* xxxxxxxxxxxxxxxxxxxxxxxxxxxx */?.();
48+
foo
49+
.getParameters /* xxxxxxxxxxxxxxxxxxxxxxxxxxxx */
50+
?.();
3951

4052
getParameters /* xxxxxxxxxxxxxxxxxxxxxxxxxxxx */?.();
4153

0 commit comments

Comments
 (0)