fix: binop associativity formatting

it seems we can fix this by changing which side
gets subtracted by 1 depending on the op associativity.
BinOp::Or & BinOp::And are right associative while the
other bin ops are left associative.

closes #893

Co-authored-by: Kasey White <kwhitemsg@gmail.com>
This commit is contained in:
rvcas 2024-03-21 20:12:49 -04:00
parent 0f9dbfd874
commit a09069b828
No known key found for this signature in database
GPG Key ID: C09B64E263F7D68C
5 changed files with 58 additions and 6 deletions

View File

@ -1219,11 +1219,27 @@ impl<'comments> Formatter<'comments> {
let left = self.expr(left, false); let left = self.expr(left, false);
let right = self.expr(right, false); let right = self.expr(right, false);
self.operator_side(left, precedence, left_precedence) self.operator_side(
.append(" ") left,
.append(name) precedence,
.append(" ") if matches!(name, BinOp::Or | BinOp::And) {
.append(self.operator_side(right, precedence, right_precedence.saturating_sub(1))) left_precedence.saturating_sub(1)
} else {
left_precedence
},
)
.append(" ")
.append(name)
.append(" ")
.append(self.operator_side(
right,
precedence,
if matches!(name, BinOp::Or | BinOp::And) {
right_precedence
} else {
right_precedence.saturating_sub(1)
},
))
} }
pub fn operator_side<'a>(&mut self, doc: Document<'a>, op: u8, side: u8) -> Document<'a> { pub fn operator_side<'a>(&mut self, doc: Document<'a>, op: u8, side: u8) -> Document<'a> {

View File

@ -755,3 +755,25 @@ fn fuzzer_annotations() {
"# "#
); );
} }
#[test]
fn preserve_associativity_parens_in_binop() {
assert_format!(
r#"
pub fn bar() {
( a || b ) || c
}
"#
);
}
#[test]
fn superfluous_parens_in_binop() {
assert_format!(
r#"
pub fn bar() {
a && ( b && c )
}
"#
);
}

View File

@ -11,5 +11,5 @@ fn bar() {
} }
fn baz() { fn baz() {
a || ( b && c || d ) a || b && c || d
} }

View File

@ -0,0 +1,7 @@
---
source: crates/aiken-lang/src/tests/format.rs
description: "Code:\n\npub fn bar() {\n ( a || b ) || c\n}\n"
---
pub fn bar() {
( a || b ) || c
}

View File

@ -0,0 +1,7 @@
---
source: crates/aiken-lang/src/tests/format.rs
description: "Code:\n\npub fn bar() {\n a && ( b && c )\n}\n"
---
pub fn bar() {
a && b && c
}