Skip to content

Commit 41989cc

Browse files
committed
Indentation of asssignment comments between lhs and rhs
1 parent 949da52 commit 41989cc

File tree

7 files changed

+369
-26
lines changed

7 files changed

+369
-26
lines changed

src/comment.rs

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use crate::rewrite::RewriteContext;
1212
use crate::shape::{Indent, Shape};
1313
use crate::string::{rewrite_string, StringFormat};
1414
use crate::utils::{
15-
count_newlines, first_line_width, last_line_width, trim_left_preserve_layout,
15+
count_newlines, first_line_width, is_single_line, last_line_width, trim_left_preserve_layout,
1616
trimmed_last_line_width, unicode_str_width,
1717
};
1818
use crate::{ErrorKind, FormattingError};
@@ -160,6 +160,18 @@ pub(crate) fn is_last_comment_block(s: &str) -> bool {
160160
s.trim_end().ends_with("*/")
161161
}
162162

163+
/// Returns true if the first line of the passed string starts with a comment
164+
/// that end on that line.
165+
fn is_first_comment_ends_on_first_line(s: &str) -> bool {
166+
if s.starts_with("/*") {
167+
s.lines().next().map_or(false, |l| l.contains("*/"))
168+
} else if s.starts_with("//") {
169+
true
170+
} else {
171+
false
172+
}
173+
}
174+
163175
/// Combine `prev_str` and `next_str` into a single `String`. `span` may contain
164176
/// comments between two strings. If there are such comments, then that will be
165177
/// recovered. If `allow_extend` is true and there is no comment between the two
@@ -225,7 +237,13 @@ pub(crate) fn combine_strs_with_missing_comments(
225237
Cow::from("")
226238
} else {
227239
let one_line_width = last_line_width(prev_str) + first_line_width(&missing_comment) + 1;
228-
if prefer_same_line && one_line_width <= shape.width {
240+
// First comment of a comments block can be in same line if ends in the first line
241+
// (and meets other conditions)
242+
if prefer_same_line
243+
&& one_line_width <= shape.width
244+
&& (is_single_line(&missing_comment)
245+
|| is_first_comment_ends_on_first_line(&missing_comment))
246+
{
229247
Cow::from(" ")
230248
} else {
231249
indent.to_string_with_newline(config)
@@ -240,7 +258,7 @@ pub(crate) fn combine_strs_with_missing_comments(
240258
indent.to_string_with_newline(config)
241259
} else {
242260
one_line_width += missing_comment.len() + first_sep.len() + 1;
243-
allow_one_line &= !missing_comment.starts_with("//") && !missing_comment.contains('\n');
261+
allow_one_line &= !missing_comment.contains('\n');
244262
if prefer_same_line && allow_one_line && one_line_width <= shape.width {
245263
Cow::from(" ")
246264
} else {
@@ -1001,24 +1019,29 @@ fn light_rewrite_comment(
10011019
config: &Config,
10021020
is_doc_comment: bool,
10031021
) -> String {
1004-
let lines: Vec<&str> = orig
1022+
let lines: Vec<String> = orig
10051023
.lines()
10061024
.map(|l| {
10071025
// This is basically just l.trim(), but in the case that a line starts
10081026
// with `*` we want to leave one space before it, so it aligns with the
10091027
// `*` in `/*`.
10101028
let first_non_whitespace = l.find(|c| !char::is_whitespace(c));
1011-
let left_trimmed = if let Some(fnw) = first_non_whitespace {
1012-
if l.as_bytes()[fnw] == b'*' && fnw > 0 {
1013-
&l[fnw - 1..]
1029+
let (blank, left_trimmed) = if let Some(fnw) = first_non_whitespace {
1030+
if l.as_bytes()[fnw] == b'*' {
1031+
// Ensure '*' is preceeded by blank and not by a tab.
1032+
(" ", &l[fnw..])
10141033
} else {
1015-
&l[fnw..]
1034+
("", &l[fnw..])
10161035
}
10171036
} else {
1018-
""
1037+
("", "")
10191038
};
10201039
// Preserve markdown's double-space line break syntax in doc comment.
1021-
trim_end_unless_two_whitespaces(left_trimmed, is_doc_comment)
1040+
format!(
1041+
"{}{}",
1042+
blank,
1043+
trim_end_unless_two_whitespaces(left_trimmed, is_doc_comment),
1044+
)
10221045
})
10231046
.collect();
10241047
lines.join(&format!("\n{}", offset.to_string(config)))

src/expr.rs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ impl Rewrite for ast::Expr {
4242
}
4343
}
4444

45-
#[derive(Copy, Clone, PartialEq)]
45+
#[derive(Copy, Clone, PartialEq, Debug)]
4646
pub(crate) enum ExprType {
4747
Statement,
4848
SubExpression,
@@ -171,11 +171,11 @@ pub(crate) fn format_expr(
171171
ast::ExprKind::Path(ref qself, ref path) => {
172172
rewrite_path(context, PathContext::Expr, qself.as_ref(), path, shape)
173173
}
174-
ast::ExprKind::Assign(ref lhs, ref rhs, _) => {
175-
rewrite_assignment(context, lhs, rhs, None, shape)
174+
ast::ExprKind::Assign(ref lhs, ref rhs, op_span) => {
175+
rewrite_assignment(context, lhs, rhs, op_span, shape)
176176
}
177177
ast::ExprKind::AssignOp(ref op, ref lhs, ref rhs) => {
178-
rewrite_assignment(context, lhs, rhs, Some(op), shape)
178+
rewrite_assignment(context, lhs, rhs, op.span, shape)
179179
}
180180
ast::ExprKind::Continue(ref opt_label) => {
181181
let id_str = match *opt_label {
@@ -1893,24 +1893,24 @@ fn rewrite_assignment(
18931893
context: &RewriteContext<'_>,
18941894
lhs: &ast::Expr,
18951895
rhs: &ast::Expr,
1896-
op: Option<&ast::BinOp>,
1896+
op_span: Span,
18971897
shape: Shape,
18981898
) -> Option<String> {
1899-
let operator_str = match op {
1900-
Some(op) => context.snippet(op.span),
1901-
None => "=",
1902-
};
1903-
19041899
// 1 = space between lhs and operator.
1900+
let operator_str = context.snippet(op_span);
19051901
let lhs_shape = shape.sub_width(operator_str.len() + 1)?;
19061902
let lhs_str = format!("{} {}", lhs.rewrite(context, lhs_shape)?, operator_str);
19071903

1908-
rewrite_assign_rhs(
1904+
let comments_span = mk_sp(op_span.hi(), rhs.span.lo());
1905+
rewrite_assign_rhs_with_comments(
19091906
context,
19101907
lhs_str,
19111908
rhs,
1912-
&RhsAssignKind::Expr(&rhs.kind, rhs.span),
19131909
shape,
1910+
&RhsAssignKind::Expr(&rhs.kind, rhs.span),
1911+
RhsTactics::Default,
1912+
comments_span,
1913+
true,
19141914
)
19151915
}
19161916

src/items.rs

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -113,17 +113,57 @@ impl Rewrite for ast::Local {
113113
result.push_str(&infix);
114114

115115
if let Some((init, _els)) = self.kind.init_else_opt() {
116+
let base_span = if let Some(ref ty) = self.ty {
117+
mk_sp(ty.span.hi(), self.span.hi())
118+
} else {
119+
mk_sp(self.pat.span.hi(), self.span.hi())
120+
};
121+
122+
let offset = context.snippet(base_span).find_uncommented("=")?;
123+
let base_span_lo = base_span.lo();
124+
125+
let assign_lo = base_span_lo + BytePos(offset as u32);
126+
let comment_start_pos = if let Some(ref ty) = self.ty {
127+
ty.span.hi()
128+
} else {
129+
self.pat.span.hi()
130+
};
131+
let comment_before_assign = context.snippet(mk_sp(comment_start_pos, assign_lo)).trim();
132+
133+
let assign_hi = base_span_lo + BytePos((offset + 1) as u32);
134+
let rhs_span_lo = init.span.lo();
135+
let comment_end_pos = if init.attrs.is_empty() {
136+
rhs_span_lo
137+
} else {
138+
let attr_span_lo = init.attrs.first().unwrap().span.lo();
139+
// for the case using block
140+
// ex. let x = { #![my_attr]do_something(); }
141+
if rhs_span_lo < attr_span_lo {
142+
rhs_span_lo
143+
} else {
144+
attr_span_lo
145+
}
146+
};
147+
148+
if !comment_before_assign.is_empty() {
149+
let new_indent_str = &pat_shape
150+
.block_indent(0)
151+
.to_string_with_newline(context.config);
152+
result = format!("{}{}{}", comment_before_assign, new_indent_str, result);
153+
}
154+
116155
// 1 = trailing semicolon;
117156
let nested_shape = shape.sub_width(1)?;
118-
119-
result = rewrite_assign_rhs(
157+
result = rewrite_assign_rhs_with_comments(
120158
context,
121159
result,
122160
init,
123-
&RhsAssignKind::Expr(&init.kind, init.span),
124161
nested_shape,
162+
&RhsAssignKind::Expr(&init.kind, init.span),
163+
RhsTactics::Default,
164+
mk_sp(assign_hi, comment_end_pos),
165+
true,
125166
)?;
126-
// todo else
127167
}
128168

129169
result.push(';');
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
// "=" Assignemnt - Multiline Block comments
2+
fn main () {
3+
let var = /* Block comment line 1
4+
* Block comment line 2
5+
* Block comment line 3 */ first;
6+
var = /* Block comment line 1
7+
* Block comment line 2
8+
* Block comment line 3 */ second;
9+
var = /* Block comment line 1 longggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggg
10+
* Block comment line 2
11+
* Block comment line 3 */ third;
12+
var = /* Block comment line 1
13+
* Block comment line 2 longggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggg
14+
* Block comment line 3 */ forth;
15+
}
16+
17+
// "=" Assignemnt - Multiline Line and Block comments
18+
fn main () {
19+
let var = // Line comment 1
20+
// Line comment 2
21+
// Line comment 3
22+
first;
23+
var = // Line comment
24+
/* Block comment line 1
25+
* Block comment line 2 */ second;
26+
var = /* Block comment single line */
27+
// Line comment
28+
/* Block comment line 1
29+
* Block comment line 2 */ third;
30+
var = /* Block comment line 1 longggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggg
31+
* Block comment line 2 */
32+
// Line comment
33+
forth;
34+
var = // Line comment
35+
/* Block comment line 1 longggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggg
36+
* Block comment line 2 */ fifth;
37+
}
38+
39+
// BinOp Assignemnt - Multiline Block comments
40+
fn main () {
41+
let var = /* Block comment line 1
42+
* Block comment line 2
43+
* Block comment line 3 */ first;
44+
var += /* Block comment line 1
45+
* Block comment line 2
46+
* Block comment line 3 */ second;
47+
var -= /* Block comment line 1 longggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggg
48+
* Block comment line 2
49+
* Block comment line 3 */ third;
50+
var *= /* Block comment line 1
51+
* Block comment line 2 longggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggg
52+
* Block comment line 3 */ forth;
53+
}
54+
55+
// BinOp Assignemnt - Multiline Line and Block comments
56+
fn main () {
57+
let var = // Line comment 1
58+
// Line comment 2
59+
// Line comment 3
60+
first;
61+
var += // Line comment
62+
/* Block comment line 1
63+
* Block comment line 2 */ second;
64+
var -= /* Block comment single line */
65+
// Line comment
66+
/* Block comment line 1
67+
* Block comment line 2 */ third;
68+
var *= /* Block comment line 1 longggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggg
69+
* Block comment line 2 */
70+
// Line comment
71+
forth;
72+
var /= // Line comment
73+
/* Block comment line 1 longggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggg
74+
* Block comment line 2 */ fifth;
75+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// "=" Assignemnt
2+
fn main () {
3+
let var = first;
4+
var = second;
5+
}
6+
fn main () {
7+
let var = /* Block comment */ first;
8+
var = /* Block comment */ second;
9+
}
10+
fn main () {
11+
let var = // Line comment
12+
first;
13+
var = // Line comment
14+
second;
15+
}
16+
fn main () {
17+
let var = /* Block comment longgggggggggggggggggggggggggggggggggggggggggggggggggggggggg */ first;
18+
var = /* Block comment longgggggggggggggggggggggggggggggggggggggggggggggggggggggggggggg */ second;
19+
}
20+
fn main () {
21+
let var = /* Block comment longgggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggg */ first;
22+
var = /* Block comment longgggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggg */ second;
23+
}
24+
25+
// BinOp Assigment
26+
fn main () {
27+
let var = first;
28+
var += second;
29+
}
30+
fn main () {
31+
let var = /* Block comment */ first;
32+
var -= /* Block comment */ second;
33+
}
34+
fn main () {
35+
let var = // Line comment
36+
first;
37+
var *= // Line comment
38+
second;
39+
}
40+
fn main () {
41+
let var = /* Block comment longgggggggggggggggggggggggggggggggggggggggggggggggggggggggg */ first;
42+
var /= /* Block comment longgggggggggggggggggggggggggggggggggggggggggggggggggggggggggggg */ second;
43+
}
44+
fn main () {
45+
let var = /* Block comment longgggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggg */ first;
46+
var /= /* Block comment longgggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggg */ second;
47+
}

0 commit comments

Comments
 (0)