Skip to content

Commit 0e9a503

Browse files
committed
feat(fmt): Handle all possible comments in repeat
1 parent 9029c27 commit 0e9a503

File tree

6 files changed

+116
-45
lines changed

6 files changed

+116
-45
lines changed

src/format.rs

Lines changed: 63 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -429,7 +429,7 @@ fn traverse(
429429
.skip(1)
430430
.take(node.child_count() - 2)
431431
.map(|child| {
432-
let prev_sibling = {
432+
let maybe_prev = {
433433
let tmp = prev_sibling;
434434
prev_sibling = Some(child);
435435
tmp
@@ -448,21 +448,21 @@ fn traverse(
448448
fmt(child)?
449449
};
450450
if is_fmt_skip_comment(&child)
451-
&& prev_sibling
451+
&& maybe_prev
452452
.map(|prev| end_position(prev).row < child.start_position().row)
453453
.unwrap_or(true)
454454
{
455455
fmt_skip = true;
456456
}
457457
if child.kind() == "comment" {
458-
return Ok(match prev_sibling {
458+
return Ok(match maybe_prev {
459459
Some(prev) if same_line(prev, child) => {
460460
format!(" {formatted}")
461461
}
462-
Some(prev_node) => format!(
462+
Some(prev) => format!(
463463
"{}{formatted}",
464464
line_ending.repeat(usize::clamp(
465-
child.start_position().row - end_position(prev_node).row,
465+
child.start_position().row - end_position(prev).row,
466466
1,
467467
2,
468468
))
@@ -473,7 +473,7 @@ fn traverse(
473473
if child.kind() == "comma" {
474474
is_first_arg = false;
475475
return Ok(
476-
if prev_sibling
476+
if maybe_prev
477477
.map(|prev| prev.kind() == "comment")
478478
.unwrap_or(false)
479479
{
@@ -486,7 +486,7 @@ fn traverse(
486486
let result = format!(
487487
"{}{}",
488488
if is_first_arg {
489-
if prev_sibling
489+
if maybe_prev
490490
.map(|prev| prev.kind() == "comment")
491491
.unwrap_or(false)
492492
{
@@ -496,7 +496,7 @@ fn traverse(
496496
}
497497
} else if is_multiline {
498498
line_ending.repeat(usize::clamp(
499-
prev_sibling
499+
maybe_prev
500500
.map(|prev| child.start_position().row - end_position(prev).row)
501501
.unwrap_or(1),
502502
1,
@@ -735,9 +735,9 @@ fn traverse(
735735
let mut out = String::with_capacity(node.end_byte() - node.start_byte());
736736
let mut indent_comments = false;
737737
tree::for_each_child(&mut node.walk(), |child, field_name| {
738-
let prev_node = child.prev_sibling();
738+
let maybe_prev = child.prev_sibling();
739739

740-
let prev_is_comment = prev_node
740+
let prev_is_comment = maybe_prev
741741
.map(|node| node.kind() == "comment")
742742
.unwrap_or(false);
743743
let next_is_comment = child
@@ -763,8 +763,8 @@ fn traverse(
763763
}
764764
}
765765
"comment" => {
766-
if let Some(prev_node) = prev_node
767-
&& same_line(prev_node, child)
766+
if let Some(prev) = maybe_prev
767+
&& same_line(prev, child)
768768
{
769769
out.push(' ');
770770
} else {
@@ -869,9 +869,9 @@ fn traverse(
869869
let mut out = String::with_capacity(node.end_byte() - node.start_byte());
870870
let mut indent_comments = false;
871871
tree::for_each_child(&mut node.walk(), |child, field_name| {
872-
let prev_node = child.prev_sibling();
872+
let maybe_prev = child.prev_sibling();
873873

874-
let prev_is_comment = prev_node
874+
let prev_is_comment = maybe_prev
875875
.map(|node| node.kind() == "comment")
876876
.unwrap_or(false);
877877

@@ -885,8 +885,8 @@ fn traverse(
885885
out.push_str("else")
886886
}
887887
"comment" => {
888-
if let Some(prev_node) = prev_node
889-
&& same_line(prev_node, child)
888+
if let Some(prev) = maybe_prev
889+
&& same_line(prev, child)
890890
{
891891
out.push(' ');
892892
} else {
@@ -1160,15 +1160,49 @@ fn traverse(
11601160
.collect::<Result<String, FormatError>>()?
11611161
}
11621162
"repeat_statement" => {
1163-
let body = field(node, "body")?;
1164-
format!(
1165-
"repeat {}",
1166-
if body.kind() == "braced_expression" {
1167-
fmt_multiline(body, true)?
1168-
} else {
1169-
wrap_with_braces(body)?
1170-
}
1171-
)
1163+
handles_comments = true;
1164+
1165+
let mut out = String::with_capacity(node.end_byte() - node.start_byte());
1166+
tree::for_each_child(&mut node.walk(), |child, field_name| {
1167+
let maybe_prev = child.prev_sibling();
1168+
1169+
let prev_is_comment = maybe_prev
1170+
.map(|node| node.kind() == "comment")
1171+
.unwrap_or(false);
1172+
1173+
match field_name {
1174+
None => match child.kind() {
1175+
"repeat" => out.push_str("repeat"),
1176+
"comment" => {
1177+
if let Some(prev) = maybe_prev
1178+
&& same_line(prev, child)
1179+
{
1180+
out.push(' ');
1181+
} else if !prev_is_comment {
1182+
out.push('\n');
1183+
}
1184+
out.push_str(&fmt(child)?);
1185+
out.push('\n')
1186+
}
1187+
_ => unreachable!(),
1188+
},
1189+
Some(field_name) => {
1190+
if !prev_is_comment {
1191+
out.push(' ');
1192+
}
1193+
match field_name {
1194+
"body" => out.push_str(&if child.kind() == "braced_expression" {
1195+
fmt_multiline(child, true)?
1196+
} else {
1197+
wrap_with_braces(child)?
1198+
}),
1199+
_ => unreachable!(),
1200+
}
1201+
}
1202+
};
1203+
Ok::<_, FormatError>(())
1204+
})?;
1205+
out
11721206
}
11731207
"string" => {
11741208
let maybe_string_content = field_optional(node, "content");
@@ -1236,18 +1270,18 @@ fn traverse(
12361270
let mut out = String::with_capacity(node.end_byte() - node.start_byte());
12371271
let mut indent_comments = false;
12381272
tree::for_each_child(&mut node.walk(), |child, field_name| {
1239-
let prev_node = child.prev_sibling();
1273+
let maybe_prev = child.prev_sibling();
12401274

1241-
let prev_is_comment = prev_node
1275+
let prev_is_comment = maybe_prev
12421276
.map(|node| node.kind() == "comment")
12431277
.unwrap_or(false);
12441278

12451279
match field_name {
12461280
None => match child.kind() {
12471281
"while" => out.push_str("while"),
12481282
"comment" => {
1249-
if let Some(prev_node) = prev_node
1250-
&& same_line(prev_node, child)
1283+
if let Some(prev) = maybe_prev
1284+
&& same_line(prev, child)
12511285
{
12521286
out.push(' ');
12531287
} else {

src/main.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,13 +67,13 @@ enum Command {
6767
Fmt {
6868
/// R files to format
6969
files: Option<Vec<PathBuf>>,
70-
/// Avoid writing any formatted files back; instead, exit with a non-zero status code if any files would have been modified, and zero otherwise
70+
/// Exit with error if files would be modified without making changes
7171
#[clap(long, default_value_t = false)]
7272
check: bool,
73-
/// Avoid writing any formatted files back; instead, exit with a non-zero status code and the difference between the current file and how the formatted file would look like
73+
/// Show diff instead of modifying files; exit with error if changes needed
7474
#[clap(long, default_value_t = false)]
7575
diff: bool,
76-
/// Stop if a comment can't be properly placed (exits with error if a comment would be moved to different location)
76+
/// Stop if a comment can't be properly placed (exits with error if any comment would be moved to different location)
7777
#[clap(long, default_value_t = false)]
7878
stop_on_unhandled_comment: bool,
7979
},
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
source: tests/test_format.rs
3+
expression: "format_str(indoc!\n{\n r#\"\n repeat # repeat\n # 1\n {\n }\n \"#\n}).unwrap()"
4+
---
5+
repeat # repeat
6+
# 1
7+
{}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
---
2+
source: tests/test_format.rs
3+
expression: "format_str(indoc!\n{\n r#\"\n repeat # 1\n body\n repeat # 1\n { body }\n \"#\n}).unwrap()"
4+
---
5+
repeat # 1
6+
{
7+
body
8+
}
9+
repeat # 1
10+
{
11+
body
12+
}

tests/snapshots/test_format__repeat_statement.snap

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
---
2-
source: src/format.rs
3-
expression: "format_str(indoc!\n{\n r#\"\n repeat {\n print(\"Hello, world!\")\n }\n repeat {\n }\n repeat { #foo\n }\n repeat #foo\n { }\n \"#\n})"
2+
source: tests/test_format.rs
3+
expression: "format_str(indoc!\n{\n r#\"\n repeat { body }\n repeat {\n body\n }\n repeat body\n repeat\n body\n \"#\n}).unwrap()"
44
---
55
repeat {
6-
print("Hello, world!")
6+
body
77
}
8-
repeat {}
98
repeat {
10-
# foo
9+
body
10+
}
11+
repeat {
12+
body
13+
}
14+
repeat {
15+
body
1116
}
12-
# foo
13-
repeat {}

tests/test_format.rs

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -559,16 +559,31 @@ fn program() {
559559
#[test]
560560
fn repeat_statement() {
561561
assert_fmt! {r#"
562+
repeat { body }
562563
repeat {
563-
print("Hello, world!")
564-
}
565-
repeat {
564+
body
566565
}
567-
repeat { #foo
566+
repeat body
567+
repeat
568+
body
569+
"#};
570+
571+
// check all possible comment positions
572+
assert_fmt! {r#"
573+
repeat # repeat
574+
# 1
575+
{
568576
}
569-
repeat #foo
570-
{ }
571577
"#};
578+
579+
// comment after condition but no block
580+
assert_fmt! {r#"
581+
repeat # 1
582+
body
583+
repeat # 1
584+
{ body }
585+
"#
586+
};
572587
}
573588

574589
#[test]

0 commit comments

Comments
 (0)