fix(formatter): use position-based comment checks for concise arrays (#28169)

Closes #28104.

`can_concisely_print_array_list` shared one cursor-based comments iterator across elements.
Checking an element consumed the comments of later ones, so a comment inside a later signed number was missed and the array fill-printed on the second pass.

- Check each element with the position-based `has_any_comment_in_range`, and the trailing line comment check with `all_comments_in_range` over the array
  - Layout decisions use the position-based queries, see `crates/oxc_formatter/AGENTS.md`
- `js/arrays/numbers-negative-comment-after-minus.js` is now idempotent
This commit is contained in:
leaysgur committed 2026-10-26 08:29:49 +00:00
1 parent 068a8ea8c0
commit 9d37ff614d
4 files changed
+76 -22

No files matched your search

@@ -117,8 +117,6 @@ pub fn can_concisely_print_array_list(
let comments = f.comments();
let mut comments_iter = comments.comments_before_iter(array_expression_span.end);
for item in list {
match item {
ArrayExpressionElement::NumericLiteral(_) => {}
@@ -128,7 +126,8 @@ pub fn can_concisely_print_array_list(
if !signed
|| !matches!(argument, Expression::NumericLiteral(_))
|| has_comment_inside_unary(&mut comments_iter, unary_expr.span)
// `-(/* comment */ 1)`
|| comments.has_any_comment_in_range(unary_expr.span.start, unary_expr.span.end)
{
return false;
}
@@ -149,23 +148,6 @@ pub fn can_concisely_print_array_list(
// ```
!comments
.comments_before_iter(array_expression_span.end)
.all_comments_in_range(array_expression_span.start, array_expression_span.end)
.any(|comment| comment.is_line() && !comment.preceded_by_newline())
}
// ```js
// - (/* comment */ 1)
// ^^^^^^^^^^^^ // This is a unary expression with a comment inside
// ```
fn has_comment_inside_unary<'a>(
comments_iter: &mut impl Iterator<Item = &'a Comment>,
unary_expr_span: Span,
) -> bool {
// `comments_iter` is avoid repeatedly iterating over the same comments from the start
for comment in comments_iter.by_ref() {
if comment.span.start > unary_expr_span.start {
return unary_expr_span.contains_inclusive(comment.span);
}
}
false
}
@@ -0,0 +1,10 @@
// A comment inside any signed number, not only the first one, prints one element per line.
x = [
-1,
-(
// comment
2
),
-3,
];
y = [-1, -2, -(/* comment */ 3), -4, -5, -6, -7, -8, -9, -10, -11, -12, -13, -14, -15, -16, -17];
@@ -0,0 +1,63 @@
---
source: crates/oxc_formatter/tests/fixtures/mod.rs
---
==================== Input ====================
// A comment inside any signed number, not only the first one, prints one element per line.
x = [
-1,
-(
// comment
2
),
-3,
];
y = [-1, -2, -(/* comment */ 3), -4, -5, -6, -7, -8, -9, -10, -11, -12, -13, -14, -15, -16, -17];
==================== Output ====================
------------------
{ printWidth: 80 }
------------------
// A comment inside any signed number, not only the first one, prints one element per line.
x = [
-1,
-(
// comment
2
),
-3,
];
y = [
-1,
-2,
-(/* comment */ 3),
-4,
-5,
-6,
-7,
-8,
-9,
-10,
-11,
-12,
-13,
-14,
-15,
-16,
-17,
];
-------------------
{ printWidth: 100 }
-------------------
// A comment inside any signed number, not only the first one, prints one element per line.
x = [
-1,
-(
// comment
2
),
-3,
];
y = [-1, -2, -(/* comment */ 3), -4, -5, -6, -7, -8, -9, -10, -11, -12, -13, -14, -15, -16, -17];
===================== End =====================
@@ -87,7 +87,6 @@ js compatibility: 1033/1123 (91.99%), 23 files skipped
# Not idempotent
- js/arrays/numbers-negative-comment-after-minus.js
- js/comments/return-statement.js
- js/comments/first-argument/first-argument.js
- js/for/continue-and-break-comment-without-blocks.js