Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: remove multiple trailing lines in comments #6163

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Also remove trailing bare lines in comments
Block comments with bare lines are handled differently than those
without bare lines (unless `normalize_comments` is configured). If
`normalize_comments` is false but `wrap_comments` is true, trailing
blank lines should be removed from block comments, including those with
bare lines.

Signed-off-by: Ross Williams <[email protected]>
  • Loading branch information
overhacked committed Jul 31, 2024
commit f66d7d8ab0ee702f6fcc010a3ce78cda048bd22b
53 changes: 50 additions & 3 deletions src/comment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ use crate::rewrite::RewriteContext;
use crate::shape::{Indent, Shape};
use crate::string::{rewrite_string, StringFormat};
use crate::utils::{
count_newlines, first_line_width, last_line_width, trim_left_preserve_layout,
trimmed_last_line_width, unicode_str_width,
count_newlines, first_line_width, is_horizontal_space, last_line_width,
trim_left_preserve_layout, trimmed_last_line_width, unicode_str_width,
};
use crate::{ErrorKind, FormattingError};

Expand Down Expand Up @@ -346,7 +346,14 @@ fn identify_comment(
let (first_group, rest) = orig.split_at(first_group_ending);
let rewritten_first_group =
if !config.normalize_comments() && has_bare_lines && style.is_block_comment() {
trim_left_preserve_layout(first_group, shape.indent, config)?
let reindented = trim_left_preserve_layout(first_group, shape.indent, config)?;

// If wrap_comments is enabled, then remove any trailing blank lines
if config.wrap_comments() {
strip_comment_trailing_lines(reindented, style)
} else {
reindented
}
} else if !config.normalize_comments()
&& !config.wrap_comments()
&& !(
Expand Down Expand Up @@ -1053,6 +1060,46 @@ fn trim_end_unless_two_whitespaces(s: &str, is_doc_comment: bool) -> &str {
}
}

/// Removes blank lines at the end of block comments
fn strip_comment_trailing_lines(comment: String, style: CommentStyle<'_>) -> String {
debug_assert!(
style.is_block_comment(),
"strip_suffix(style.closer()) ensures this function is a no-op on non-block comments"
);

// If final line is a normal closing line, look for trailing blank lines
if let Some(without_closer) = comment
.strip_suffix(style.closer())
.map(|s| s.trim_end_matches(is_horizontal_space))
.and_then(|s| s.strip_suffix('\n'))
{
let mut trimmed = without_closer.trim_end();
let closer_line = &comment[without_closer.len()..];
let line_start = style.line_start().trim_end();
// Start trimming trailing blank lines
loop {
// Remove any asterisk-prefixed or bare block comment lines
let t = trimmed.trim_end_matches(line_start).trim_end();
if t.len() == trimmed.len() {
// If no trimming occurred
break;
} else {
// ... otherwise, keep trying to trim
trimmed = t;
}
}

if without_closer.len() == trimmed.len() {
// No blank lines were removed
comment
} else {
trimmed.to_string() + closer_line
}
} else {
// Final line either didn't have a closer or had non-whitespace along with the closer
comment
}
}
/// Trims whitespace and aligns to indent, but otherwise does not change comments.
fn light_rewrite_comment(
orig: &str,
Expand Down
4 changes: 4 additions & 0 deletions src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -675,6 +675,10 @@ pub(crate) fn is_empty_line(s: &str) -> bool {
s.is_empty() || s.chars().all(char::is_whitespace)
}

pub(crate) fn is_horizontal_space(c: char) -> bool {
c == ' ' || c == '\t'
}

fn get_prefix_space_width(config: &Config, s: &str) -> usize {
let mut width = 0;
for c in s.chars() {
Expand Down
7 changes: 7 additions & 0 deletions tests/source/comment_trailing_lines.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,10 @@ pub mod bar {}
*
*/
pub mod block {}

/**
Outer Block doc comment with multiple trailing lines


*/
pub mod outer_block_doc_comment {}
5 changes: 5 additions & 0 deletions tests/target/comment_trailing_lines.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,8 @@ pub mod bar {}
* Block comment with multiple trailing lines
*/
pub mod block {}

/**
Outer Block doc comment with multiple trailing lines
*/
pub mod outer_block_doc_comment {}
Loading