Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 47a0f78

Browse files
author
Ruben Schmidmeister
committed
Fix normalisation of multi-line doc attributes
1 parent 7fc181d commit 47a0f78

File tree

2 files changed

+98
-5
lines changed

2 files changed

+98
-5
lines changed

src/attr.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
use syntax::ast;
44
use syntax::source_map::{BytePos, Span, DUMMY_SP};
55

6+
use self::doc_comment::DocCommentFormatter;
67
use crate::comment::{contains_comment, rewrite_doc_comment, CommentStyle};
78
use crate::config::lists::*;
89
use crate::config::IndentStyle;
@@ -14,6 +15,8 @@ use crate::shape::Shape;
1415
use crate::types::{rewrite_path, PathContext};
1516
use crate::utils::{count_newlines, mk_sp};
1617

18+
mod doc_comment;
19+
1720
/// Returns attributes on the given statement.
1821
pub(crate) fn get_attrs_from_stmt(stmt: &ast::Stmt) -> &[ast::Attribute] {
1922
match stmt.node {
@@ -331,11 +334,9 @@ impl Rewrite for ast::Attribute {
331334
ast::AttrStyle::Outer => CommentStyle::TripleSlash,
332335
};
333336

334-
// Remove possible whitespace from the `CommentStyle::opener()` so that
335-
// the literal itself has control over the comment's leading spaces.
336-
let opener = comment_style.opener().trim_end();
337-
338-
let doc_comment = format!("{}{}", opener, literal);
337+
let doc_comment_formatter =
338+
DocCommentFormatter::new(literal, comment_style);
339+
let doc_comment = format!("{}", doc_comment_formatter);
339340
return rewrite_doc_comment(
340341
&doc_comment,
341342
shape.comment(context.config),

src/attr/doc_comment.rs

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
use crate::comment::CommentStyle;
2+
use std::fmt::{self, Display};
3+
use syntax_pos::symbol::Symbol;
4+
5+
pub(super) struct DocCommentFormatter<'a> {
6+
literal: &'a Symbol,
7+
style: CommentStyle<'a>,
8+
}
9+
10+
impl<'a> DocCommentFormatter<'a> {
11+
pub(super) fn new(literal: &'a Symbol, style: CommentStyle<'a>) -> Self {
12+
Self { literal, style }
13+
}
14+
}
15+
16+
impl Display for DocCommentFormatter<'_> {
17+
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
18+
let opener = self.style.opener().trim_end();
19+
20+
let literal_as_str = self.literal.as_str().get();
21+
let line_count = literal_as_str.lines().count();
22+
let last_line_index = line_count - 1;
23+
let lines = literal_as_str.lines().enumerate();
24+
25+
for (index, line) in lines {
26+
if index == last_line_index {
27+
write!(formatter, "{}{}", opener, line)?;
28+
} else {
29+
writeln!(formatter, "{}{}", opener, line)?;
30+
}
31+
}
32+
33+
Ok(())
34+
}
35+
}
36+
37+
#[cfg(test)]
38+
mod tests {
39+
use super::*;
40+
use syntax_pos::{Globals, GLOBALS};
41+
42+
#[test]
43+
fn literal_controls_leading_spaces() {
44+
test_doc_comment_is_formatted_correctly(
45+
" Lorem ipsum",
46+
"/// Lorem ipsum",
47+
CommentStyle::TripleSlash,
48+
);
49+
}
50+
51+
#[test]
52+
fn single_line_doc_comment_is_formatted_correctly() {
53+
test_doc_comment_is_formatted_correctly(
54+
"Lorem ipsum",
55+
"///Lorem ipsum",
56+
CommentStyle::TripleSlash,
57+
);
58+
}
59+
60+
#[test]
61+
fn multi_line_doc_comment_is_formatted_correctly() {
62+
test_doc_comment_is_formatted_correctly(
63+
"Lorem ipsum\nDolor sit amet",
64+
"///Lorem ipsum\n///Dolor sit amet",
65+
CommentStyle::TripleSlash,
66+
);
67+
}
68+
69+
#[test]
70+
fn whitespace_within_lines_is_preserved() {
71+
test_doc_comment_is_formatted_correctly(
72+
" Lorem ipsum \n Dolor sit amet ",
73+
"/// Lorem ipsum \n/// Dolor sit amet ",
74+
CommentStyle::TripleSlash,
75+
);
76+
}
77+
78+
fn test_doc_comment_is_formatted_correctly(
79+
literal: &str,
80+
expected_comment: &str,
81+
style: CommentStyle<'_>,
82+
) {
83+
GLOBALS.set(&Globals::new(), || {
84+
let literal = Symbol::gensym(literal);
85+
86+
assert_eq!(
87+
expected_comment,
88+
format!("{}", DocCommentFormatter::new(&literal, style))
89+
);
90+
});
91+
}
92+
}

0 commit comments

Comments
 (0)