mirror of
https://github.com/oxc-project/oxc.git
synced 2026-11-04 10:29:58 +00:00
fix(formatter): keep trailing double spaces on JSDoc lines (#26861)
Prettier keeps a trailing double space on the middle lines of a `/**` comment (prettier/prettier#18594, in the pinned 3.9.6): it is a Markdown hard line break that doc tooling renders (prettier/prettier#6793). We printed every aligned line through `trim()`, so the spaces were dropped: ```tsx /** * JSDoc with new line using double space * It's on another line */ ``` Match Prettier's `printIndentableBlockComment`: in a `/**` comment (not `/***`), a middle line whose source ends with two or more spaces keeps exactly two after its trimmed content. A bare `*` line, a single trailing space, the opening line, and non-JSDoc block comments are trimmed as before. The check is textual rather than `comment.is_jsdoc()` because the parser also tags `/***` as JSDoc and Prettier's test is textual. The printer never trims text at a line end, so writing the two spaces before the next hard line break is enough. Fixture `js/comments/jsdoc-trailing-double-space.js` mirrors Prettier's `tests/format/js/comments/trailing-spaces` cases plus a plain `/*` block; its output is byte-identical to Prettier 3.9.8. One line added to `js/crlf/block-comment.js` pins the CRLF output. `cargo test -p oxc_formatter`, clippy and fmt are clean; I did not run the `tasks/coverage` idempotency suites locally. Written with help from an AI assistant (Claude); reviewed and tested by me. Closes #26854 --------- Co-authored-by: leaysgur <6259812+leaysgur@users.noreply.github.com>
This commit is contained in:
1 parent
5186328763
commit
cd45f71d0d
5 files changed
+214
-1
No files matched your search
@@ -564,9 +564,17 @@ impl<'a> Format<'a, JsFormatContext<'a>> for FormatCommentText<'_> {
|
||||
let first_line = lines.next().unwrap();
|
||||
write!(f, [text(first_line.trim_end())]);
|
||||
|
||||
// Not `comment.is_jsdoc()`, which also accepts `/***`
|
||||
let is_jsdoc = content.starts_with("/**") && !content.starts_with("/***");
|
||||
|
||||
// Indent the remaining lines by one space so that all `*` are aligned.
|
||||
for line in lines {
|
||||
write!(f, [hard_line_break(), " ", text(line.trim())]);
|
||||
let trimmed = line.trim();
|
||||
write!(f, [hard_line_break(), " ", text(trimmed)]);
|
||||
// Keep a Markdown hard line break in JSDoc, as 2 trailing spaces
|
||||
if is_jsdoc && trimmed != "*" && line.ends_with(" ") {
|
||||
write!(f, [" "]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Normalize line endings `\r\n` to `\n`
|
||||
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
// Prettier keeps a trailing double space on JSDoc lines (prettier/prettier#18594).
|
||||
/**
|
||||
* Two spaces stay.
|
||||
* It's on another line
|
||||
*/
|
||||
function two() {}
|
||||
|
||||
/**
|
||||
* Three spaces collapse to two.
|
||||
* next
|
||||
*/
|
||||
function three() {}
|
||||
|
||||
/**
|
||||
* One space goes.
|
||||
* next
|
||||
*/
|
||||
function one() {}
|
||||
|
||||
/**
|
||||
*
|
||||
* A bare star line drops its spaces.
|
||||
*/
|
||||
function bare() {}
|
||||
|
||||
/**
|
||||
* Spaces on the opening line go, spaces here stay.
|
||||
*/
|
||||
function opening() {}
|
||||
|
||||
function nested() {
|
||||
/**
|
||||
* Misaligned and indented, spaces stay.
|
||||
*/
|
||||
return 1;
|
||||
}
|
||||
|
||||
/***
|
||||
* Not JSDoc, spaces go.
|
||||
*/
|
||||
function notJsdoc() {}
|
||||
|
||||
/*
|
||||
* Plain block comment, spaces go.
|
||||
*/
|
||||
function plain() {}
|
||||
+153
@@ -0,0 +1,153 @@
|
||||
---
|
||||
source: crates/oxc_formatter/tests/fixtures/mod.rs
|
||||
---
|
||||
==================== Input ====================
|
||||
// Prettier keeps a trailing double space on JSDoc lines (prettier/prettier#18594).
|
||||
/**
|
||||
* Two spaces stay.
|
||||
* It's on another line
|
||||
*/
|
||||
function two() {}
|
||||
|
||||
/**
|
||||
* Three spaces collapse to two.
|
||||
* next
|
||||
*/
|
||||
function three() {}
|
||||
|
||||
/**
|
||||
* One space goes.
|
||||
* next
|
||||
*/
|
||||
function one() {}
|
||||
|
||||
/**
|
||||
*
|
||||
* A bare star line drops its spaces.
|
||||
*/
|
||||
function bare() {}
|
||||
|
||||
/**
|
||||
* Spaces on the opening line go, spaces here stay.
|
||||
*/
|
||||
function opening() {}
|
||||
|
||||
function nested() {
|
||||
/**
|
||||
* Misaligned and indented, spaces stay.
|
||||
*/
|
||||
return 1;
|
||||
}
|
||||
|
||||
/***
|
||||
* Not JSDoc, spaces go.
|
||||
*/
|
||||
function notJsdoc() {}
|
||||
|
||||
/*
|
||||
* Plain block comment, spaces go.
|
||||
*/
|
||||
function plain() {}
|
||||
|
||||
==================== Output ====================
|
||||
------------------
|
||||
{ printWidth: 80 }
|
||||
------------------
|
||||
// Prettier keeps a trailing double space on JSDoc lines (prettier/prettier#18594).
|
||||
/**
|
||||
* Two spaces stay.
|
||||
* It's on another line
|
||||
*/
|
||||
function two() {}
|
||||
|
||||
/**
|
||||
* Three spaces collapse to two.
|
||||
* next
|
||||
*/
|
||||
function three() {}
|
||||
|
||||
/**
|
||||
* One space goes.
|
||||
* next
|
||||
*/
|
||||
function one() {}
|
||||
|
||||
/**
|
||||
*
|
||||
* A bare star line drops its spaces.
|
||||
*/
|
||||
function bare() {}
|
||||
|
||||
/**
|
||||
* Spaces on the opening line go, spaces here stay.
|
||||
*/
|
||||
function opening() {}
|
||||
|
||||
function nested() {
|
||||
/**
|
||||
* Misaligned and indented, spaces stay.
|
||||
*/
|
||||
return 1;
|
||||
}
|
||||
|
||||
/***
|
||||
* Not JSDoc, spaces go.
|
||||
*/
|
||||
function notJsdoc() {}
|
||||
|
||||
/*
|
||||
* Plain block comment, spaces go.
|
||||
*/
|
||||
function plain() {}
|
||||
|
||||
-------------------
|
||||
{ printWidth: 100 }
|
||||
-------------------
|
||||
// Prettier keeps a trailing double space on JSDoc lines (prettier/prettier#18594).
|
||||
/**
|
||||
* Two spaces stay.
|
||||
* It's on another line
|
||||
*/
|
||||
function two() {}
|
||||
|
||||
/**
|
||||
* Three spaces collapse to two.
|
||||
* next
|
||||
*/
|
||||
function three() {}
|
||||
|
||||
/**
|
||||
* One space goes.
|
||||
* next
|
||||
*/
|
||||
function one() {}
|
||||
|
||||
/**
|
||||
*
|
||||
* A bare star line drops its spaces.
|
||||
*/
|
||||
function bare() {}
|
||||
|
||||
/**
|
||||
* Spaces on the opening line go, spaces here stay.
|
||||
*/
|
||||
function opening() {}
|
||||
|
||||
function nested() {
|
||||
/**
|
||||
* Misaligned and indented, spaces stay.
|
||||
*/
|
||||
return 1;
|
||||
}
|
||||
|
||||
/***
|
||||
* Not JSDoc, spaces go.
|
||||
*/
|
||||
function notJsdoc() {}
|
||||
|
||||
/*
|
||||
* Plain block comment, spaces go.
|
||||
*/
|
||||
function plain() {}
|
||||
|
||||
===================== End =====================
|
||||
@@ -6,6 +6,7 @@ block
|
||||
|
||||
/**
|
||||
* js doc
|
||||
* hard break kept
|
||||
* @type {string}
|
||||
* @description This is a description.
|
||||
*/
|
||||
|
||||
@@ -10,6 +10,7 @@ block
|
||||
|
||||
/**
|
||||
* js doc
|
||||
* hard break kept
|
||||
* @type {string}
|
||||
* @description This is a description.
|
||||
*/
|
||||
@@ -28,6 +29,7 @@ block
|
||||
|
||||
/**
|
||||
* js doc
|
||||
* hard break kept
|
||||
* @type {string}
|
||||
* @description This is a description.
|
||||
*/
|
||||
@@ -45,6 +47,7 @@ block
|
||||
|
||||
/**
|
||||
* js doc
|
||||
* hard break kept
|
||||
* @type {string}
|
||||
* @description This is a description.
|
||||
*/
|
||||
@@ -62,6 +65,7 @@ block
|
||||
|
||||
/**
|
||||
* js doc
|
||||
* hard break kept
|
||||
* @type {string}
|
||||
* @description This is a description.
|
||||
*/
|
||||
@@ -79,6 +83,7 @@ block
|
||||
|
||||
/**
|
||||
* js doc
|
||||
* hard break kept
|
||||
* @type {string}
|
||||
* @description This is a description.
|
||||
*/
|
||||
|
||||
Reference in new issue
Block a user