Skip to content

Commit b790942

Browse files
authored
Merge pull request #1604 from topecongiro/comment-group
Format comments with different opening in different manner
2 parents 9b79cb5 + bcebe9e commit b790942

10 files changed

+237
-27
lines changed

src/comment.rs

Lines changed: 156 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,122 @@ fn is_custom_comment(comment: &str) -> bool {
3232
}
3333
}
3434

35+
#[derive(PartialEq, Eq)]
36+
pub enum CommentStyle {
37+
DoubleSlash,
38+
TripleSlash,
39+
Doc,
40+
SingleBullet,
41+
DoubleBullet,
42+
Exclamation,
43+
Custom,
44+
}
45+
46+
impl CommentStyle {
47+
pub fn opener<'a>(&self, orig: &'a str) -> &'a str {
48+
match *self {
49+
CommentStyle::DoubleSlash => "// ",
50+
CommentStyle::TripleSlash => "/// ",
51+
CommentStyle::Doc => "//! ",
52+
CommentStyle::SingleBullet => "/* ",
53+
CommentStyle::DoubleBullet => "/** ",
54+
CommentStyle::Exclamation => "/*! ",
55+
CommentStyle::Custom => {
56+
if orig.chars().nth(3) == Some(' ') {
57+
&orig[0..4]
58+
} else {
59+
&orig[0..3]
60+
}
61+
}
62+
}
63+
}
64+
65+
pub fn closer<'a>(&self) -> &'a str {
66+
match *self {
67+
CommentStyle::DoubleSlash |
68+
CommentStyle::TripleSlash |
69+
CommentStyle::Custom |
70+
CommentStyle::Doc => "",
71+
CommentStyle::DoubleBullet => " **/",
72+
CommentStyle::SingleBullet |
73+
CommentStyle::Exclamation => " */",
74+
}
75+
}
76+
77+
pub fn line_start<'a>(&self, orig: &'a str) -> &'a str {
78+
match *self {
79+
CommentStyle::DoubleSlash => "// ",
80+
CommentStyle::TripleSlash => "/// ",
81+
CommentStyle::Doc => "//! ",
82+
CommentStyle::SingleBullet |
83+
CommentStyle::Exclamation => " * ",
84+
CommentStyle::DoubleBullet => " ** ",
85+
CommentStyle::Custom => {
86+
if orig.chars().nth(3) == Some(' ') {
87+
&orig[0..4]
88+
} else {
89+
&orig[0..3]
90+
}
91+
}
92+
}
93+
}
94+
95+
pub fn to_str_tuplet<'a>(&self, orig: &'a str) -> (&'a str, &'a str, &'a str) {
96+
(self.opener(orig), self.closer(), self.line_start(orig))
97+
}
98+
99+
pub fn line_with_same_comment_style<'a>(&self,
100+
line: &str,
101+
orig: &'a str,
102+
normalize_comments: bool)
103+
-> bool {
104+
match *self {
105+
CommentStyle::DoubleSlash |
106+
CommentStyle::TripleSlash |
107+
CommentStyle::Custom |
108+
CommentStyle::Doc => {
109+
line.trim_left()
110+
.starts_with(self.line_start(orig).trim_left()) ||
111+
comment_style(line, normalize_comments) == *self
112+
}
113+
CommentStyle::DoubleBullet |
114+
CommentStyle::SingleBullet |
115+
CommentStyle::Exclamation => {
116+
line.trim_left().starts_with(self.closer().trim_left()) ||
117+
line.trim_left()
118+
.starts_with(self.line_start(orig).trim_left()) ||
119+
comment_style(line, normalize_comments) == *self
120+
}
121+
}
122+
}
123+
}
124+
125+
fn comment_style(orig: &str, normalize_comments: bool) -> CommentStyle {
126+
if !normalize_comments {
127+
if orig.starts_with("/**") && !orig.starts_with("/**/") {
128+
CommentStyle::DoubleBullet
129+
} else if orig.starts_with("/*!") {
130+
CommentStyle::Exclamation
131+
} else if orig.starts_with("/*") {
132+
CommentStyle::SingleBullet
133+
} else if orig.starts_with("///") {
134+
CommentStyle::TripleSlash
135+
} else if orig.starts_with("//!") {
136+
CommentStyle::Doc
137+
} else {
138+
CommentStyle::DoubleSlash
139+
}
140+
} else if orig.starts_with("///") || (orig.starts_with("/**") && !orig.starts_with("/**/")) {
141+
CommentStyle::TripleSlash
142+
} else if orig.starts_with("//!") || orig.starts_with("/*!") {
143+
CommentStyle::Doc
144+
} else if is_custom_comment(orig) {
145+
CommentStyle::Custom
146+
} else {
147+
CommentStyle::DoubleSlash
148+
}
149+
}
150+
35151
pub fn rewrite_comment(orig: &str,
36152
block_style: bool,
37153
shape: Shape,
@@ -47,39 +163,52 @@ pub fn rewrite_comment(orig: &str,
47163
if num_bare_lines > 0 && !config.normalize_comments() {
48164
return Some(orig.to_owned());
49165
}
50-
51166
if !config.normalize_comments() && !config.wrap_comments() {
52167
return light_rewrite_comment(orig, shape.indent, config);
53168
}
54169

170+
identify_comment(orig, block_style, shape, config)
171+
}
172+
173+
fn identify_comment(orig: &str,
174+
block_style: bool,
175+
shape: Shape,
176+
config: &Config)
177+
-> Option<String> {
178+
let style = comment_style(orig, false);
179+
let first_group = orig.lines()
180+
.take_while(|l| style.line_with_same_comment_style(l, orig, false))
181+
.collect::<Vec<_>>()
182+
.join("\n");
183+
let rest = orig.lines()
184+
.skip(first_group.lines().count())
185+
.collect::<Vec<_>>()
186+
.join("\n");
187+
188+
let first_group_str = try_opt!(rewrite_comment_inner(&first_group, block_style, shape, config));
189+
if rest.is_empty() {
190+
Some(first_group_str)
191+
} else {
192+
identify_comment(&rest, block_style, shape, config).map(|rest_str| {
193+
format!("{}\n{}{}",
194+
first_group_str,
195+
shape
196+
.indent
197+
.to_string(config),
198+
rest_str)
199+
})
200+
}
201+
}
202+
203+
fn rewrite_comment_inner(orig: &str,
204+
block_style: bool,
205+
shape: Shape,
206+
config: &Config)
207+
-> Option<String> {
55208
let (opener, closer, line_start) = if block_style {
56-
("/* ", " */", " * ")
57-
} else if !config.normalize_comments() {
58-
if orig.starts_with("/**") && !orig.starts_with("/**/") {
59-
("/** ", " **/", " ** ")
60-
} else if orig.starts_with("/*!") {
61-
("/*! ", " */", " * ")
62-
} else if orig.starts_with("/*") {
63-
("/* ", " */", " * ")
64-
} else if orig.starts_with("///") {
65-
("/// ", "", "/// ")
66-
} else if orig.starts_with("//!") {
67-
("//! ", "", "//! ")
68-
} else {
69-
("// ", "", "// ")
70-
}
71-
} else if orig.starts_with("///") || (orig.starts_with("/**") && !orig.starts_with("/**/")) {
72-
("/// ", "", "/// ")
73-
} else if orig.starts_with("//!") || orig.starts_with("/*!") {
74-
("//! ", "", "//! ")
75-
} else if is_custom_comment(orig) {
76-
if orig.chars().nth(3) == Some(' ') {
77-
(&orig[0..4], "", &orig[0..4])
78-
} else {
79-
(&orig[0..3], "", &orig[0..3])
80-
}
209+
CommentStyle::SingleBullet.to_str_tuplet("")
81210
} else {
82-
("// ", "", "// ")
211+
comment_style(orig, config.normalize_comments()).to_str_tuplet(orig)
83212
};
84213

85214
let max_chars = shape

tests/source/closure.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,3 +131,15 @@ impl Foo {
131131
})
132132
}
133133
}
134+
135+
fn issue1329() {
136+
aaaaaaaaaaaaaaaa.map(|x| {
137+
x += 1;
138+
x
139+
})
140+
.filter
141+
}
142+
143+
fn issue325() {
144+
let f = || unsafe { xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx };
145+
}

tests/source/issue-1278.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// rustfmt-fn_args_layout = "block"
2+
3+
#![feature(pub_restricted)]
4+
5+
mod inner_mode {
6+
pub(super) fn func_name(abc: i32) -> i32 {
7+
abc
8+
}
9+
}

tests/source/macros.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,9 @@ fn main() {
8383
let json = json!({
8484
"foo": "bar",
8585
});
86+
87+
// #1092
88+
chain!(input, a:take!(max_size), || []);
8689
}
8790

8891
impl X {

tests/target/closure.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,3 +150,17 @@ impl Foo {
150150
})
151151
}
152152
}
153+
154+
fn issue1329() {
155+
aaaaaaaaaaaaaaaa
156+
.map(|x| {
157+
x += 1;
158+
x
159+
})
160+
.filter
161+
}
162+
163+
fn issue325() {
164+
let f =
165+
|| unsafe { xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx };
166+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// rustfmt-fn_call_style: Block
2+
// rustfmt-max_width: 80
3+
// rustfmt-tab_spaces: 2
4+
5+
// #1427
6+
fn main() {
7+
exceptaions::config(move || {
8+
(
9+
NmiConfig {},
10+
HardFaultConfig {},
11+
SysTickConfig { gpio_sbsrr },
12+
)
13+
});
14+
}

tests/target/issue-1214.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/*!
2+
# Example
3+
4+
```
5+
// Here goes some example
6+
```
7+
*/
8+
struct Item;

tests/target/issue-1278.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// rustfmt-fn_args_layout = "block"
2+
3+
#![feature(pub_restricted)]
4+
5+
mod inner_mode {
6+
pub(super) fn func_name(abc: i32) -> i32 {
7+
abc
8+
}
9+
}

tests/target/issue-691.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// rustfmt-normalize_comments: true
2+
3+
//! `std` or `core` and simply link to this library. In case the target
4+
//! platform has no hardware
5+
//! support for some operation, software implementations provided by this
6+
//! library will be used automagically.
7+
// TODO: provide instructions to override default libm link and how to link to
8+
// this library.
9+
fn foo() {}

tests/target/macros.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,9 @@ fn main() {
8888
let json = json!({
8989
"foo": "bar",
9090
});
91+
92+
// #1092
93+
chain!(input, a:take!(max_size), || []);
9194
}
9295

9396
impl X {

0 commit comments

Comments
 (0)