Binops with parentheses keep their parentheses

This commit is contained in:
Chadtech 2021-10-16 18:01:13 -04:00
parent 56c36c51d7
commit 5e2decf89a
2 changed files with 68 additions and 4 deletions

View file

@ -133,7 +133,7 @@ impl<'a> Formattable<'a> for Expr<'a> {
} }
} }
ParensAround(sub_expr) => { ParensAround(sub_expr) => {
if parens == Parens::NotNeeded { if parens == Parens::NotNeeded && !sub_expr_requests_parens(&sub_expr) {
sub_expr.format_with_options(buf, Parens::NotNeeded, Newlines::Yes, indent); sub_expr.format_with_options(buf, Parens::NotNeeded, Newlines::Yes, indent);
} else { } else {
buf.push('('); buf.push('(');
@ -319,7 +319,7 @@ impl<'a> Formattable<'a> for Expr<'a> {
buf.push_str(key); buf.push_str(key);
} }
Access(expr, key) => { Access(expr, key) => {
expr.format_with_options(buf, parens, Newlines::Yes, indent); expr.format_with_options(buf, Parens::InApply, Newlines::Yes, indent);
buf.push('.'); buf.push('.');
buf.push_str(key); buf.push_str(key);
} }
@ -398,6 +398,8 @@ fn fmt_bin_ops<'a>(
|| lefts.iter().any(|(expr, _)| expr.value.is_multiline()); || lefts.iter().any(|(expr, _)| expr.value.is_multiline());
for (loc_left_side, loc_bin_op) in lefts { for (loc_left_side, loc_bin_op) in lefts {
let bin_op = loc_bin_op.value;
loc_left_side.format_with_options(buf, apply_needs_parens, Newlines::No, indent); loc_left_side.format_with_options(buf, apply_needs_parens, Newlines::No, indent);
if is_multiline { if is_multiline {
@ -406,7 +408,7 @@ fn fmt_bin_ops<'a>(
buf.push(' '); buf.push(' ');
} }
push_op(buf, loc_bin_op.value); push_op(buf, bin_op);
buf.push(' '); buf.push(' ');
} }
@ -1050,3 +1052,32 @@ fn format_field_multiline<'a, T>(
} }
} }
} }
fn sub_expr_requests_parens(expr: &Expr<'_>) -> bool {
match expr {
Expr::BinOps(left_side, _) => {
left_side
.iter()
.any(|(_, loc_bin_op)| match loc_bin_op.value {
BinOp::Caret
| BinOp::Star
| BinOp::Slash
| BinOp::DoubleSlash
| BinOp::Percent
| BinOp::DoublePercent
| BinOp::Plus
| BinOp::Minus
| BinOp::Equals
| BinOp::NotEquals
| BinOp::LessThan
| BinOp::GreaterThan
| BinOp::LessThanOrEq
| BinOp::GreaterThanOrEq
| BinOp::And
| BinOp::Or => true,
BinOp::Pizza | BinOp::Assignment | BinOp::HasType | BinOp::Backpassing => false,
})
}
_ => false,
}
}

View file

@ -2249,7 +2249,7 @@ mod test_fmt {
} }
#[test] #[test]
fn precedence_conflict_exponents() { fn binop_parens() {
expr_formats_same(indoc!( expr_formats_same(indoc!(
r#" r#"
if 4 == (6 ^ 6 ^ 7 ^ 8) then if 4 == (6 ^ 6 ^ 7 ^ 8) then
@ -2258,6 +2258,39 @@ mod test_fmt {
"Naturally" "Naturally"
"# "#
)); ));
expr_formats_same(indoc!(
r#"
if 5 == 1 ^ 1 ^ 1 ^ 1 then
"Not buying it"
else
"True"
"#
));
expr_formats_to(
indoc!(
r#"
if (1 == 1)
&& (2 == 1) && (3 == 2) then
"true"
else
"false"
"#
),
indoc!(
r#"
if
(1 == 1)
&& (2 == 1)
&& (3 == 2)
then
"true"
else
"false"
"#
),
);
} }
#[test] #[test]