refactor parse AST to allow multiple if branches

This commit is contained in:
Folkert 2021-02-23 14:31:48 +01:00
parent c208f500d9
commit 4eea0aff7a
6 changed files with 145 additions and 109 deletions

View file

@ -58,8 +58,11 @@ impl<'a> Formattable<'a> for Expr<'a> {
loc_expr.is_multiline() || args.iter().any(|loc_arg| loc_arg.is_multiline())
}
If(loc_cond, loc_if_true, loc_if_false) => {
loc_cond.is_multiline() || loc_if_true.is_multiline() || loc_if_false.is_multiline()
If(branches, final_else) => {
final_else.is_multiline()
|| branches
.iter()
.any(|(c, t)| c.is_multiline() || t.is_multiline())
}
BinOp((loc_left, _, loc_right)) => {
@ -257,8 +260,8 @@ impl<'a> Formattable<'a> for Expr<'a> {
// still print the return value.
ret.format_with_options(buf, Parens::NotNeeded, Newlines::Yes, indent);
}
If(loc_condition, loc_then, loc_else) => {
fmt_if(buf, loc_condition, loc_then, loc_else, indent);
If(branches, final_else) => {
fmt_if(buf, branches, final_else, self.is_multiline(), indent);
}
When(loc_condition, branches) => fmt_when(buf, loc_condition, branches, indent),
List {
@ -629,15 +632,15 @@ fn fmt_when<'a>(
fn fmt_if<'a>(
buf: &mut String<'a>,
loc_condition: &'a Located<Expr<'a>>,
loc_then: &'a Located<Expr<'a>>,
loc_else: &'a Located<Expr<'a>>,
branches: &'a [(Located<Expr<'a>>, Located<Expr<'a>>)],
final_else: &'a Located<Expr<'a>>,
is_multiline: bool,
indent: u16,
) {
let is_multiline_then = loc_then.is_multiline();
let is_multiline_else = loc_else.is_multiline();
let is_multiline_condition = loc_condition.is_multiline();
let is_multiline = is_multiline_then || is_multiline_else || is_multiline_condition;
// let is_multiline_then = loc_then.is_multiline();
// let is_multiline_else = final_else.is_multiline();
// let is_multiline_condition = loc_condition.is_multiline();
// let is_multiline = is_multiline_then || is_multiline_else || is_multiline_condition;
let return_indent = if is_multiline {
indent + INDENT
@ -645,80 +648,89 @@ fn fmt_if<'a>(
indent
};
buf.push_str("if");
for (loc_condition, loc_then) in branches.iter() {
let is_multiline_condition = loc_condition.is_multiline();
if is_multiline_condition {
match &loc_condition.value {
Expr::SpaceBefore(expr_below, spaces_above_expr) => {
fmt_comments_only(buf, spaces_above_expr.iter(), NewlineAt::Top, return_indent);
newline(buf, return_indent);
buf.push_str("if");
match &expr_below {
Expr::SpaceAfter(expr_above, spaces_below_expr) => {
expr_above.format(buf, return_indent);
fmt_comments_only(
buf,
spaces_below_expr.iter(),
NewlineAt::Top,
return_indent,
);
newline(buf, indent);
}
if is_multiline_condition {
match &loc_condition.value {
Expr::SpaceBefore(expr_below, spaces_above_expr) => {
fmt_comments_only(buf, spaces_above_expr.iter(), NewlineAt::Top, return_indent);
newline(buf, return_indent);
_ => {
expr_below.format(buf, return_indent);
match &expr_below {
Expr::SpaceAfter(expr_above, spaces_below_expr) => {
expr_above.format(buf, return_indent);
fmt_comments_only(
buf,
spaces_below_expr.iter(),
NewlineAt::Top,
return_indent,
);
newline(buf, indent);
}
_ => {
expr_below.format(buf, return_indent);
}
}
}
}
Expr::SpaceAfter(expr_above, spaces_below_expr) => {
newline(buf, return_indent);
expr_above.format(buf, return_indent);
fmt_comments_only(buf, spaces_below_expr.iter(), NewlineAt::Top, return_indent);
newline(buf, indent);
}
Expr::SpaceAfter(expr_above, spaces_below_expr) => {
newline(buf, return_indent);
expr_above.format(buf, return_indent);
fmt_comments_only(buf, spaces_below_expr.iter(), NewlineAt::Top, return_indent);
newline(buf, indent);
}
_ => {
newline(buf, return_indent);
loc_condition.format(buf, return_indent);
newline(buf, indent);
}
}
} else {
buf.push(' ');
loc_condition.format_with_options(buf, Parens::NotNeeded, Newlines::Yes, indent);
buf.push(' ');
}
buf.push_str("then");
if is_multiline {
match &loc_then.value {
Expr::SpaceBefore(expr_below, spaces_below) => {
// we want exactly one newline, user-inserted extra newlines are ignored.
newline(buf, return_indent);
fmt_comments_only(buf, spaces_below.iter(), NewlineAt::Bottom, return_indent);
match &expr_below {
Expr::SpaceAfter(expr_above, spaces_above) => {
expr_above.format(buf, return_indent);
fmt_comments_only(buf, spaces_above.iter(), NewlineAt::Top, return_indent);
newline(buf, indent);
}
_ => {
expr_below.format(buf, return_indent);
}
_ => {
newline(buf, return_indent);
loc_condition.format(buf, return_indent);
newline(buf, indent);
}
}
_ => {
loc_condition.format(buf, return_indent);
}
} else {
buf.push(' ');
loc_condition.format_with_options(buf, Parens::NotNeeded, Newlines::Yes, indent);
buf.push(' ');
}
buf.push_str("then");
if is_multiline {
match &loc_then.value {
Expr::SpaceBefore(expr_below, spaces_below) => {
// we want exactly one newline, user-inserted extra newlines are ignored.
newline(buf, return_indent);
fmt_comments_only(buf, spaces_below.iter(), NewlineAt::Bottom, return_indent);
match &expr_below {
Expr::SpaceAfter(expr_above, spaces_above) => {
expr_above.format(buf, return_indent);
fmt_comments_only(
buf,
spaces_above.iter(),
NewlineAt::Top,
return_indent,
);
newline(buf, indent);
}
_ => {
expr_below.format(buf, return_indent);
}
}
}
_ => {
loc_condition.format(buf, return_indent);
}
}
} else {
buf.push_str(" ");
loc_then.format(buf, return_indent);
}
} else {
buf.push_str(" ");
loc_then.format(buf, return_indent);
}
if is_multiline {
@ -728,7 +740,7 @@ fn fmt_if<'a>(
buf.push_str(" else ");
}
loc_else.format(buf, return_indent);
final_else.format(buf, return_indent);
}
pub fn fmt_closure<'a>(