Skip to content

Commit fe35c29

Browse files
committed
fix(formatter): preserve block comment positions in argument/parameter lists
closes #792 Signed-off-by: azjezz <[email protected]>
1 parent a922309 commit fe35c29

File tree

5 files changed

+71
-5
lines changed

5 files changed

+71
-5
lines changed

crates/formatter/src/internal/comment/format.rs

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -166,13 +166,18 @@ impl<'arena> FormatterState<'_, 'arena> {
166166
let comment = Comment::from_trivia(self.file, trivia);
167167

168168
if range.end_offset() < comment.start && self.is_insignificant(range.end_offset(), comment.start) {
169+
let gap = &self.source_text[(range.end_offset() as usize)..(comment.start as usize)];
170+
if comment.is_block && gap.contains(',') {
171+
break;
172+
}
173+
169174
// Check if comment is in an ignore region - if so, preserve as-is
170175
if self.get_ignore_region_for(comment.start).is_some() {
171176
self.print_preserved_trailing_comment(&mut parts, comment);
172177
previous_comment = Some(comment);
173178
} else {
174-
let previous = self.print_trailing_comment(&mut parts, comment, previous_comment);
175-
previous_comment = Some(previous);
179+
previous_comment =
180+
Some(self.print_trailing_comment(&mut parts, comment, previous_comment, range.end_offset()));
176181
}
177182
self.next_comment_index += 1;
178183
} else {
@@ -229,6 +234,7 @@ impl<'arena> FormatterState<'_, 'arena> {
229234
parts: &mut Vec<'arena, Document<'arena>>,
230235
comment: Comment,
231236
previous: Option<Comment>,
237+
token_end_offset: u32,
232238
) -> Comment {
233239
let printed = self.print_comment(comment);
234240

@@ -251,7 +257,21 @@ impl<'arena> FormatterState<'_, 'arena> {
251257
return comment.with_line_suffix(true);
252258
}
253259

254-
if comment.is_inline_comment() || previous.is_some_and(|c| c.has_line_suffix) {
260+
if !comment.is_block || previous.is_some_and(|c| c.has_line_suffix) {
261+
parts.push(Document::LineSuffix(vec![in self.arena; Document::Space(Space::soft()), printed]));
262+
263+
return comment.with_line_suffix(true);
264+
}
265+
266+
let followed_by_semicolon = self
267+
.skip_spaces(Some(comment.end), false)
268+
.map(|idx| self.source_text.as_bytes().get(idx as usize))
269+
.is_some_and(|c| c == Some(&b';'));
270+
271+
let has_semicolon_in_gap =
272+
self.source_text[(token_end_offset as usize)..(comment.start as usize)].bytes().any(|c| c == b';');
273+
274+
if followed_by_semicolon || has_semicolon_in_gap {
255275
parts.push(Document::LineSuffix(vec![in self.arena; Document::Space(Space::soft()), printed]));
256276

257277
return comment.with_line_suffix(true);
@@ -489,8 +509,8 @@ impl<'arena> FormatterState<'_, 'arena> {
489509
after.end_offset() == comment.start || self.is_insignificant(after.end_offset(), comment.start);
490510

491511
if is_between && gap_is_ok {
492-
let previous = self.print_trailing_comment(&mut parts, comment, previous_comment);
493-
previous_comment = Some(previous);
512+
previous_comment =
513+
Some(self.print_trailing_comment(&mut parts, comment, previous_comment, after.end_offset()));
494514
self.next_comment_index += 1;
495515
} else {
496516
break;
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
3+
// Block comments trailing arguments should stay with their arguments
4+
foo(4 /* length */, 8 /* height */);
5+
6+
// Multiple inline block comments
7+
bar($a /* comment a */, $b /* comment b */, $c /* comment c */);
8+
9+
// Mixed: inline and trailing semicolon
10+
baz($x /* inline */); /* trailing */
11+
12+
// Comment only followed by comma, not semicolon
13+
qux(1 /* one */, 2 /* two */, 3 /* three */);
14+
15+
class Example
16+
{
17+
private function addFooooos($foooooIds, /*string*/ $precision)
18+
{
19+
}
20+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
3+
// Block comments trailing arguments should stay with their arguments
4+
foo(4 /* length */, 8 /* height */);
5+
6+
// Multiple inline block comments
7+
bar(
8+
$a /* comment a */,
9+
$b /* comment b */,
10+
$c /* comment c */
11+
);
12+
13+
// Mixed: inline and trailing semicolon
14+
baz($x /* inline */) /* trailing */;
15+
16+
// Comment only followed by comma, not semicolon
17+
qux(1 /* one */, 2 /* two */, 3 /* three */);
18+
19+
class Example
20+
{
21+
private function addFooooos($foooooIds, /*string*/ $precision)
22+
{
23+
}
24+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
FormatSettings::default()

crates/formatter/tests/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,7 @@ test_case!(issue_683);
304304
test_case!(issue_727);
305305
test_case!(issue_738);
306306
test_case!(issue_788);
307+
test_case!(inline_block_comments_in_arguments);
307308

308309
#[test]
309310
fn test_all_test_cases_are_ran() {

0 commit comments

Comments
 (0)