mirror of
https://github.com/aphrody-labs/oxc.git
synced 2026-10-15 06:39:17 +00:00
fix(formatter/jsdoc): more alignment with original plugin (#27039)
- Handle non-leading JSDoc and also legal - Keep trailing 2 spaces (for hard break) - Remove useless spaces when they can hug
This commit is contained in:
1 parent
50be18e6ef
commit
8fbddb123e
8 files changed
+79
-19
No files matched your search
@@ -12,6 +12,10 @@ use super::super::markers::{ListMarker, list_marker};
|
||||
/// Author opt-outs (`\- ` escape, blank line before an intended list) are pinned in
|
||||
/// `descriptions/043-list-interrupting-continuation`.
|
||||
pub(super) fn needs_mdast_parsing(text: &str) -> bool {
|
||||
// Hard line break by 2 trailing spaces
|
||||
if text.contains(" \n") {
|
||||
return true;
|
||||
}
|
||||
let bytes = text.as_bytes();
|
||||
let len = bytes.len();
|
||||
let mut i = 0;
|
||||
|
||||
@@ -473,10 +473,13 @@ impl JsdocFormatter<'_, '_> {
|
||||
}
|
||||
|
||||
// Split description into first line and rest (avoids collecting all lines)
|
||||
let (first_text_line, rest_of_desc) = match desc_raw.split_once('\n') {
|
||||
Some((first, rest)) => (first.trim(), Some(rest)),
|
||||
None => (desc_raw.trim(), None),
|
||||
let (first_line, rest_of_desc) = match desc_raw.split_once('\n') {
|
||||
Some((first, rest)) => (first, Some(rest)),
|
||||
None => (desc_raw, None),
|
||||
};
|
||||
let first_text_line = first_line.trim();
|
||||
// Keep a Markdown hard line break, which `trim()` drops
|
||||
let first_hard_break = rest_of_desc.is_some() && first_line.ends_with(" ");
|
||||
|
||||
// If the description starts with a code fence, output the tag line alone
|
||||
// and treat the entire description as structural content with a blank line separator
|
||||
@@ -626,6 +629,9 @@ impl JsdocFormatter<'_, '_> {
|
||||
let mut s = if has_remaining {
|
||||
let mut s = String::with_capacity(first_text.len() + 1 + remaining_desc.len());
|
||||
s.push_str(&first_text);
|
||||
if first_hard_break {
|
||||
s.push_str(" ");
|
||||
}
|
||||
s.push('\n');
|
||||
s.push_str(&remaining_desc);
|
||||
s
|
||||
@@ -1130,8 +1136,11 @@ impl JsdocFormatter<'_, '_> {
|
||||
}
|
||||
|
||||
let fits_on_one_line = prefix_len + str_width(&desc_text) <= self.wrap_width;
|
||||
if fits_on_one_line || skip_wrapping {
|
||||
// Fits on one line, or tag skips description formatting (no wrapping).
|
||||
// Other descriptions go through wrapping, which collapses line breaks and spaces
|
||||
let is_plain_one_liner =
|
||||
fits_on_one_line && !desc_text.contains('\n') && !desc_text.contains(" ");
|
||||
if is_plain_one_liner || skip_wrapping {
|
||||
// Fits on one line as is, or tag skips description formatting (no wrapping).
|
||||
// Tags in TAGS_PEV_FORMATE_DESCRIPTION (e.g. @see) and unknown tags
|
||||
// keep their description on one line regardless of length.
|
||||
// When desc has embedded newlines (e.g. @module Name\n\nMore text),
|
||||
|
||||
@@ -521,8 +521,7 @@ impl<'a> Format<'a, JsFormatContext<'a>> for FormatCommentText<'_> {
|
||||
}
|
||||
|
||||
// JSDoc formatting: if enabled, try to format JSDoc comments
|
||||
let formatted_jsdoc = if comment.is_jsdoc()
|
||||
&& !comment.is_legal()
|
||||
let formatted_jsdoc = if is_jsdoc_comment(comment)
|
||||
&& let Some(jsdoc_options) = &f.options().jsdoc
|
||||
{
|
||||
let source: &str = &f.source_text();
|
||||
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
/**
|
||||
* JSDoc with new line using double space
|
||||
* It is on another line
|
||||
*
|
||||
* @param a first
|
||||
* Continued
|
||||
*/
|
||||
function f(a) {}
|
||||
|
||||
/***
|
||||
* triple
|
||||
* Next
|
||||
*/
|
||||
function g() {}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
/**
|
||||
* JSDoc with new line using double space\
|
||||
* It is on another line
|
||||
*
|
||||
* @param a First\
|
||||
* Continued
|
||||
*/
|
||||
function f(a) {}
|
||||
|
||||
/**
|
||||
* Triple\
|
||||
* Next
|
||||
*/
|
||||
function g() {}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
/** @license MIT
|
||||
* some text */
|
||||
const a = 1;
|
||||
|
||||
/** @author MIT
|
||||
* some text */
|
||||
const b = 1;
|
||||
|
||||
const c = 1; /** trailing doc
|
||||
* next */
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
/** @license MIT some text */
|
||||
const a = 1;
|
||||
|
||||
/** @author MIT Some text */
|
||||
const b = 1;
|
||||
|
||||
const c = 1; /** Trailing doc next */
|
||||
@@ -105,20 +105,23 @@ impl<'a> JSDocCommentPart<'a> {
|
||||
result.push('\n');
|
||||
}
|
||||
let trimmed = line.trim();
|
||||
if let Some(rest) = trimmed.strip_prefix('*') {
|
||||
// Strip `*` as a comment continuation prefix UNLESS it looks like
|
||||
// markdown emphasis (`*word*`). Emphasis has `*` followed by an
|
||||
// alphanumeric char; continuation prefixes have `*` followed by
|
||||
// space, backtick, punctuation, or nothing.
|
||||
let is_emphasis = rest.starts_with(|c: char| c.is_alphanumeric() || c == '_');
|
||||
if !is_emphasis {
|
||||
// Strip at most one leading space after `*` (the conventional ` * ` prefix)
|
||||
// to preserve any additional indentation (e.g. for indented code blocks)
|
||||
result.push_str(rest.strip_prefix(' ').unwrap_or(rest));
|
||||
continue;
|
||||
let content = match trimmed.strip_prefix('*') {
|
||||
// Strip `*` as a comment continuation prefix
|
||||
// UNLESS it looks like markdown emphasis (`*word*`).
|
||||
// Emphasis has `*` followed by an alphanumeric char;
|
||||
// continuation prefixes have `*` followed by space, backtick, punctuation, or nothing.
|
||||
// Strip at most one leading space after `*` (the conventional ` * ` prefix)
|
||||
// to preserve any additional indentation (e.g. for indented code blocks)
|
||||
Some(rest) if !rest.starts_with(|c: char| c.is_alphanumeric() || c == '_') => {
|
||||
rest.strip_prefix(' ').unwrap_or(rest)
|
||||
}
|
||||
_ => trimmed,
|
||||
};
|
||||
result.push_str(content);
|
||||
// Keep a Markdown hard line break, as 2 trailing spaces
|
||||
if line.ends_with(" ") && !content.is_empty() {
|
||||
result.push_str(" ");
|
||||
}
|
||||
result.push_str(trimmed);
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user