mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-28 06:14:46 +00:00
cleanup
This commit is contained in:
parent
d6bdb45c82
commit
ba38d4ec14
4 changed files with 76 additions and 244 deletions
|
@ -3,7 +3,7 @@ use bumpalo::collections::String;
|
||||||
use roc_parse::ast::{AssignedField, Expr, Tag, TypeAnnotation};
|
use roc_parse::ast::{AssignedField, Expr, Tag, TypeAnnotation};
|
||||||
use roc_region::all::Located;
|
use roc_region::all::Located;
|
||||||
|
|
||||||
#[derive(PartialEq, Eq)]
|
#[derive(PartialEq, Eq, Clone, Copy)]
|
||||||
pub enum Parens {
|
pub enum Parens {
|
||||||
NotNeeded,
|
NotNeeded,
|
||||||
InFunctionType,
|
InFunctionType,
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
use crate::annotation::{fmt_annotation, Formattable, Newlines, Parens};
|
use crate::annotation::{Formattable, Newlines, Parens};
|
||||||
use crate::expr::fmt_expr;
|
|
||||||
use crate::pattern::fmt_pattern;
|
use crate::pattern::fmt_pattern;
|
||||||
use crate::spaces::{fmt_spaces, is_comment, newline, INDENT};
|
use crate::spaces::{fmt_spaces, is_comment, newline, INDENT};
|
||||||
use bumpalo::collections::String;
|
use bumpalo::collections::String;
|
||||||
|
@ -88,21 +87,24 @@ pub fn fmt_body<'a>(
|
||||||
body: &'a Expr<'a>,
|
body: &'a Expr<'a>,
|
||||||
indent: u16,
|
indent: u16,
|
||||||
) {
|
) {
|
||||||
fmt_pattern(buf, pattern, indent, Parens::InApply);
|
pattern.format_with_options(buf, Parens::InApply, Newlines::No, indent);
|
||||||
buf.push_str(" =");
|
buf.push_str(" =");
|
||||||
if body.is_multiline() {
|
if body.is_multiline() {
|
||||||
match body {
|
match body {
|
||||||
|
Expr::SpaceBefore(_, _) => {
|
||||||
|
body.format_with_options(buf, Parens::NotNeeded, Newlines::Yes, indent + INDENT);
|
||||||
|
}
|
||||||
Expr::Record { .. } | Expr::List(_) => {
|
Expr::Record { .. } | Expr::List(_) => {
|
||||||
newline(buf, indent + INDENT);
|
newline(buf, indent + INDENT);
|
||||||
fmt_expr(buf, body, indent + INDENT, false, true);
|
body.format_with_options(buf, Parens::NotNeeded, Newlines::Yes, indent + INDENT);
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
buf.push(' ');
|
buf.push(' ');
|
||||||
fmt_expr(buf, body, indent, false, true);
|
body.format_with_options(buf, Parens::NotNeeded, Newlines::Yes, indent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
buf.push(' ');
|
buf.push(' ');
|
||||||
fmt_expr(buf, body, indent, false, true);
|
body.format_with_options(buf, Parens::NotNeeded, Newlines::Yes, indent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,9 +74,7 @@ impl<'a> Formattable<'a> for Expr<'a> {
|
||||||
.any(|loc_pattern| loc_pattern.is_multiline())
|
.any(|loc_pattern| loc_pattern.is_multiline())
|
||||||
}
|
}
|
||||||
|
|
||||||
Record { fields, .. } => fields
|
Record { fields, .. } => fields.iter().any(|loc_field| loc_field.is_multiline()),
|
||||||
.iter()
|
|
||||||
.any(|loc_field| is_multiline_field(&loc_field.value)),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,10 +97,10 @@ impl<'a> Formattable<'a> for Expr<'a> {
|
||||||
} else {
|
} else {
|
||||||
fmt_comments_only(buf, spaces.iter(), indent);
|
fmt_comments_only(buf, spaces.iter(), indent);
|
||||||
}
|
}
|
||||||
fmt_expr(buf, sub_expr, indent, apply_needs_parens, format_newlines);
|
sub_expr.format_with_options(buf, parens, newlines, indent);
|
||||||
}
|
}
|
||||||
SpaceAfter(sub_expr, spaces) => {
|
SpaceAfter(sub_expr, spaces) => {
|
||||||
fmt_expr(buf, sub_expr, indent, apply_needs_parens, format_newlines);
|
sub_expr.format_with_options(buf, parens, newlines, indent);
|
||||||
if format_newlines {
|
if format_newlines {
|
||||||
fmt_spaces(buf, spaces.iter(), indent);
|
fmt_spaces(buf, spaces.iter(), indent);
|
||||||
} else {
|
} else {
|
||||||
|
@ -111,7 +109,7 @@ impl<'a> Formattable<'a> for Expr<'a> {
|
||||||
}
|
}
|
||||||
ParensAround(sub_expr) => {
|
ParensAround(sub_expr) => {
|
||||||
buf.push('(');
|
buf.push('(');
|
||||||
fmt_expr(buf, sub_expr, indent, false, true);
|
sub_expr.format_with_options(buf, Parens::NotNeeded, Newlines::Yes, indent);
|
||||||
buf.push(')');
|
buf.push(')');
|
||||||
}
|
}
|
||||||
Str(string) => {
|
Str(string) => {
|
||||||
|
@ -132,23 +130,21 @@ impl<'a> Formattable<'a> for Expr<'a> {
|
||||||
buf.push('(');
|
buf.push('(');
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt_expr(buf, &loc_expr.value, indent, true, true);
|
loc_expr.format_with_options(buf, Parens::InApply, Newlines::Yes, indent);
|
||||||
|
|
||||||
let multiline_args = loc_args
|
let multiline_args = loc_args.iter().any(|loc_arg| loc_arg.is_multiline());
|
||||||
.iter()
|
|
||||||
.any(|loc_arg| is_multiline_expr(&loc_arg.value));
|
|
||||||
|
|
||||||
if multiline_args {
|
if multiline_args {
|
||||||
let arg_indent = indent + INDENT;
|
let arg_indent = indent + INDENT;
|
||||||
|
|
||||||
for loc_arg in loc_args {
|
for loc_arg in loc_args {
|
||||||
newline(buf, arg_indent);
|
newline(buf, arg_indent);
|
||||||
fmt_expr(buf, &loc_arg.value, arg_indent, true, false);
|
loc_arg.format_with_options(buf, Parens::InApply, Newlines::No, arg_indent);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for loc_arg in loc_args {
|
for loc_arg in loc_args {
|
||||||
buf.push(' ');
|
buf.push(' ');
|
||||||
fmt_expr(buf, &loc_arg.value, indent, true, true);
|
loc_arg.format_with_options(buf, Parens::InApply, Newlines::Yes, indent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -185,7 +181,7 @@ impl<'a> Formattable<'a> for Expr<'a> {
|
||||||
buf.push_str(string);
|
buf.push_str(string);
|
||||||
}
|
}
|
||||||
Record { fields, update } => {
|
Record { fields, update } => {
|
||||||
fmt_record(buf, *update, fields, indent, parens);
|
fmt_record(buf, *update, fields, indent);
|
||||||
}
|
}
|
||||||
Closure(loc_patterns, loc_ret) => {
|
Closure(loc_patterns, loc_ret) => {
|
||||||
fmt_closure(buf, loc_patterns, loc_ret, indent);
|
fmt_closure(buf, loc_patterns, loc_ret, indent);
|
||||||
|
@ -234,7 +230,7 @@ impl<'a> Formattable<'a> for Expr<'a> {
|
||||||
|
|
||||||
// Even if there were no defs, which theoretically should never happen,
|
// Even if there were no defs, which theoretically should never happen,
|
||||||
// still print the return value.
|
// still print the return value.
|
||||||
fmt_expr(buf, &ret.value, indent, false, true);
|
ret.format_with_options(buf, Parens::NotNeeded, Newlines::Yes, indent);
|
||||||
}
|
}
|
||||||
If(loc_condition, loc_then, loc_else) => {
|
If(loc_condition, loc_then, loc_else) => {
|
||||||
fmt_if(buf, loc_condition, loc_then, loc_else, indent);
|
fmt_if(buf, loc_condition, loc_then, loc_else, indent);
|
||||||
|
@ -249,7 +245,7 @@ impl<'a> Formattable<'a> for Expr<'a> {
|
||||||
bin_op,
|
bin_op,
|
||||||
loc_right_side,
|
loc_right_side,
|
||||||
false,
|
false,
|
||||||
apply_needs_parens,
|
parens,
|
||||||
indent,
|
indent,
|
||||||
),
|
),
|
||||||
UnaryOp(sub_expr, unary_op) => {
|
UnaryOp(sub_expr, unary_op) => {
|
||||||
|
@ -262,29 +258,17 @@ impl<'a> Formattable<'a> for Expr<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt_expr(
|
sub_expr.format_with_options(buf, parens, newlines, indent);
|
||||||
buf,
|
|
||||||
&sub_expr.value,
|
|
||||||
indent,
|
|
||||||
apply_needs_parens,
|
|
||||||
format_newlines,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
Nested(nested_expr) => {
|
Nested(nested_expr) => {
|
||||||
fmt_expr(
|
nested_expr.format_with_options(buf, parens, newlines, indent);
|
||||||
buf,
|
|
||||||
nested_expr,
|
|
||||||
indent,
|
|
||||||
apply_needs_parens,
|
|
||||||
format_newlines,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
AccessorFunction(key) => {
|
AccessorFunction(key) => {
|
||||||
buf.push('.');
|
buf.push('.');
|
||||||
buf.push_str(key);
|
buf.push_str(key);
|
||||||
}
|
}
|
||||||
Access(expr, key) => {
|
Access(expr, key) => {
|
||||||
fmt_expr(buf, expr, indent, apply_needs_parens, true);
|
expr.format_with_options(buf, parens, Newlines::Yes, indent);
|
||||||
buf.push('.');
|
buf.push('.');
|
||||||
buf.push_str(key);
|
buf.push_str(key);
|
||||||
}
|
}
|
||||||
|
@ -295,41 +279,19 @@ impl<'a> Formattable<'a> for Expr<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fmt_expr<'a>(
|
|
||||||
buf: &mut String<'a>,
|
|
||||||
expr: &'a Expr<'a>,
|
|
||||||
indent: u16,
|
|
||||||
apply_needs_parens: bool,
|
|
||||||
format_newlines: bool,
|
|
||||||
) {
|
|
||||||
let parens = if apply_needs_parens {
|
|
||||||
Parens::InApply
|
|
||||||
} else {
|
|
||||||
Parens::NotNeeded
|
|
||||||
};
|
|
||||||
|
|
||||||
let newlines = if format_newlines {
|
|
||||||
Newlines::Yes
|
|
||||||
} else {
|
|
||||||
Newlines::No
|
|
||||||
};
|
|
||||||
|
|
||||||
expr.format_with_options(buf, parens, newlines, indent)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn fmt_bin_op<'a>(
|
fn fmt_bin_op<'a>(
|
||||||
buf: &mut String<'a>,
|
buf: &mut String<'a>,
|
||||||
loc_left_side: &'a Located<Expr<'a>>,
|
loc_left_side: &'a Located<Expr<'a>>,
|
||||||
loc_bin_op: &'a Located<BinOp>,
|
loc_bin_op: &'a Located<BinOp>,
|
||||||
loc_right_side: &'a Located<Expr<'a>>,
|
loc_right_side: &'a Located<Expr<'a>>,
|
||||||
part_of_multi_line_bin_ops: bool,
|
part_of_multi_line_bin_ops: bool,
|
||||||
apply_needs_parens: bool,
|
apply_needs_parens: Parens,
|
||||||
indent: u16,
|
indent: u16,
|
||||||
) {
|
) {
|
||||||
fmt_expr(buf, &loc_left_side.value, indent, apply_needs_parens, false);
|
loc_left_side.format_with_options(buf, apply_needs_parens, Newlines::No, indent);
|
||||||
|
|
||||||
let is_multiline = is_multiline_expr(&loc_right_side.value)
|
let is_multiline = (&loc_right_side.value).is_multiline()
|
||||||
|| is_multiline_expr(&loc_left_side.value)
|
|| (&loc_left_side.value).is_multiline()
|
||||||
|| part_of_multi_line_bin_ops;
|
|| part_of_multi_line_bin_ops;
|
||||||
|
|
||||||
if is_multiline {
|
if is_multiline {
|
||||||
|
@ -374,7 +336,7 @@ fn fmt_bin_op<'a>(
|
||||||
}
|
}
|
||||||
|
|
||||||
_ => {
|
_ => {
|
||||||
fmt_expr(buf, &loc_right_side.value, indent, apply_needs_parens, true);
|
loc_right_side.format_with_options(buf, apply_needs_parens, Newlines::Yes, indent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -384,7 +346,7 @@ pub fn fmt_list<'a>(buf: &mut String<'a>, loc_items: &[&Located<Expr<'a>>], inde
|
||||||
|
|
||||||
let mut iter = loc_items.iter().peekable();
|
let mut iter = loc_items.iter().peekable();
|
||||||
|
|
||||||
let is_multiline = loc_items.iter().any(|item| is_multiline_expr(&item.value));
|
let is_multiline = loc_items.iter().any(|item| (&item.value).is_multiline());
|
||||||
|
|
||||||
let item_indent = if is_multiline {
|
let item_indent = if is_multiline {
|
||||||
indent + INDENT
|
indent + INDENT
|
||||||
|
@ -401,7 +363,7 @@ pub fn fmt_list<'a>(buf: &mut String<'a>, loc_items: &[&Located<Expr<'a>>], inde
|
||||||
|
|
||||||
match &expr_below {
|
match &expr_below {
|
||||||
Expr::SpaceAfter(expr_above, spaces_below_expr) => {
|
Expr::SpaceAfter(expr_above, spaces_below_expr) => {
|
||||||
fmt_expr(buf, expr_above, item_indent, false, false);
|
expr_above.format(buf, item_indent);
|
||||||
|
|
||||||
if iter.peek().is_some() {
|
if iter.peek().is_some() {
|
||||||
buf.push(',');
|
buf.push(',');
|
||||||
|
@ -410,7 +372,7 @@ pub fn fmt_list<'a>(buf: &mut String<'a>, loc_items: &[&Located<Expr<'a>>], inde
|
||||||
fmt_condition_spaces(buf, spaces_below_expr.iter(), item_indent);
|
fmt_condition_spaces(buf, spaces_below_expr.iter(), item_indent);
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
fmt_expr(buf, expr_below, item_indent, false, false);
|
expr_below.format(buf, item_indent);
|
||||||
if iter.peek().is_some() {
|
if iter.peek().is_some() {
|
||||||
buf.push(',');
|
buf.push(',');
|
||||||
}
|
}
|
||||||
|
@ -421,7 +383,7 @@ pub fn fmt_list<'a>(buf: &mut String<'a>, loc_items: &[&Located<Expr<'a>>], inde
|
||||||
Expr::SpaceAfter(sub_expr, spaces) => {
|
Expr::SpaceAfter(sub_expr, spaces) => {
|
||||||
newline(buf, item_indent);
|
newline(buf, item_indent);
|
||||||
|
|
||||||
fmt_expr(buf, sub_expr, item_indent, false, false);
|
sub_expr.format(buf, item_indent);
|
||||||
|
|
||||||
if iter.peek().is_some() {
|
if iter.peek().is_some() {
|
||||||
buf.push(',');
|
buf.push(',');
|
||||||
|
@ -457,50 +419,6 @@ pub fn fmt_list<'a>(buf: &mut String<'a>, loc_items: &[&Located<Expr<'a>>], inde
|
||||||
buf.push(']');
|
buf.push(']');
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fmt_field<'a>(
|
|
||||||
buf: &mut String<'a>,
|
|
||||||
assigned_field: &'a AssignedField<'a, Expr<'a>>,
|
|
||||||
is_multiline: bool,
|
|
||||||
indent: u16,
|
|
||||||
apply_needs_parens: bool,
|
|
||||||
) {
|
|
||||||
use self::AssignedField::*;
|
|
||||||
|
|
||||||
match assigned_field {
|
|
||||||
LabeledValue(name, spaces, value) => {
|
|
||||||
if is_multiline {
|
|
||||||
newline(buf, indent);
|
|
||||||
}
|
|
||||||
|
|
||||||
buf.push_str(name.value);
|
|
||||||
|
|
||||||
if !spaces.is_empty() {
|
|
||||||
fmt_spaces(buf, spaces.iter(), indent);
|
|
||||||
}
|
|
||||||
|
|
||||||
buf.push(':');
|
|
||||||
buf.push(' ');
|
|
||||||
fmt_expr(buf, &value.value, indent, apply_needs_parens, true);
|
|
||||||
}
|
|
||||||
LabelOnly(name) => {
|
|
||||||
if is_multiline {
|
|
||||||
newline(buf, indent);
|
|
||||||
}
|
|
||||||
|
|
||||||
buf.push_str(name.value);
|
|
||||||
}
|
|
||||||
AssignedField::SpaceBefore(sub_expr, spaces) => {
|
|
||||||
fmt_comments_only(buf, spaces.iter(), indent);
|
|
||||||
fmt_field(buf, sub_expr, is_multiline, indent, apply_needs_parens);
|
|
||||||
}
|
|
||||||
AssignedField::SpaceAfter(sub_expr, spaces) => {
|
|
||||||
fmt_field(buf, sub_expr, is_multiline, indent, apply_needs_parens);
|
|
||||||
fmt_comments_only(buf, spaces.iter(), indent);
|
|
||||||
}
|
|
||||||
Malformed(string) => buf.push_str(string),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn empty_line_before_expr<'a>(expr: &'a Expr<'a>) -> bool {
|
pub fn empty_line_before_expr<'a>(expr: &'a Expr<'a>) -> bool {
|
||||||
use roc_parse::ast::Expr::*;
|
use roc_parse::ast::Expr::*;
|
||||||
|
|
||||||
|
@ -530,105 +448,13 @@ pub fn empty_line_before_expr<'a>(expr: &'a Expr<'a>) -> bool {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_multiline_pattern<'a>(pattern: &'a Pattern<'a>) -> bool {
|
|
||||||
pattern.is_multiline()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn is_multiline_expr<'a>(expr: &'a Expr<'a>) -> bool {
|
|
||||||
use roc_parse::ast::Expr::*;
|
|
||||||
// TODO cache these answers using a Map<Pointer, bool>, so
|
|
||||||
// we don't have to traverse subexpressions repeatedly
|
|
||||||
|
|
||||||
match expr {
|
|
||||||
// Return whether these spaces contain any Newlines
|
|
||||||
SpaceBefore(_, spaces) | SpaceAfter(_, spaces) => {
|
|
||||||
debug_assert!(!spaces.is_empty());
|
|
||||||
|
|
||||||
// "spaces" always contain either a newline or comment, and comments have newlines
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
// These expressions never have newlines
|
|
||||||
Float(_)
|
|
||||||
| Num(_)
|
|
||||||
| NonBase10Int { .. }
|
|
||||||
| Str(_)
|
|
||||||
| Access(_, _)
|
|
||||||
| AccessorFunction(_)
|
|
||||||
| Var { .. }
|
|
||||||
| MalformedIdent(_)
|
|
||||||
| MalformedClosure
|
|
||||||
| GlobalTag(_)
|
|
||||||
| PrivateTag(_) => false,
|
|
||||||
|
|
||||||
// These expressions always have newlines
|
|
||||||
Defs(_, _) | When(_, _) => true,
|
|
||||||
|
|
||||||
List(elems) => elems
|
|
||||||
.iter()
|
|
||||||
.any(|loc_expr| is_multiline_expr(&loc_expr.value)),
|
|
||||||
|
|
||||||
BlockStr(lines) => lines.len() > 1,
|
|
||||||
Apply(loc_expr, args, _) => {
|
|
||||||
is_multiline_expr(&loc_expr.value)
|
|
||||||
|| args.iter().any(|loc_arg| is_multiline_expr(&loc_arg.value))
|
|
||||||
}
|
|
||||||
|
|
||||||
If(loc_cond, loc_if_true, loc_if_false) => {
|
|
||||||
is_multiline_expr(&loc_cond.value)
|
|
||||||
|| is_multiline_expr(&loc_if_true.value)
|
|
||||||
|| is_multiline_expr(&loc_if_false.value)
|
|
||||||
}
|
|
||||||
|
|
||||||
BinOp((loc_left, _, loc_right)) => {
|
|
||||||
let next_is_multiline_bin_op: bool = match &loc_right.value {
|
|
||||||
Expr::BinOp((_, _, nested_loc_right)) => is_multiline_expr(&nested_loc_right.value),
|
|
||||||
_ => false,
|
|
||||||
};
|
|
||||||
|
|
||||||
is_multiline_expr(&loc_left.value)
|
|
||||||
|| is_multiline_expr(&loc_right.value)
|
|
||||||
|| next_is_multiline_bin_op
|
|
||||||
}
|
|
||||||
|
|
||||||
UnaryOp(loc_subexpr, _) | PrecedenceConflict(_, _, _, loc_subexpr) => {
|
|
||||||
is_multiline_expr(&loc_subexpr.value)
|
|
||||||
}
|
|
||||||
|
|
||||||
ParensAround(subexpr) | Nested(subexpr) => is_multiline_expr(&subexpr),
|
|
||||||
|
|
||||||
Closure(loc_patterns, loc_body) => {
|
|
||||||
// check the body first because it's more likely to be multiline
|
|
||||||
is_multiline_expr(&loc_body.value)
|
|
||||||
|| loc_patterns
|
|
||||||
.iter()
|
|
||||||
.any(|loc_pattern| is_multiline_pattern(&loc_pattern.value))
|
|
||||||
}
|
|
||||||
|
|
||||||
Record { fields, .. } => fields
|
|
||||||
.iter()
|
|
||||||
.any(|loc_field| is_multiline_field(&loc_field.value)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn is_multiline_field<'a, Val>(field: &'a AssignedField<'a, Val>) -> bool {
|
|
||||||
use self::AssignedField::*;
|
|
||||||
|
|
||||||
match field {
|
|
||||||
LabeledValue(_, spaces, _) => !spaces.is_empty(),
|
|
||||||
LabelOnly(_) => false,
|
|
||||||
AssignedField::SpaceBefore(_, _) | AssignedField::SpaceAfter(_, _) => true,
|
|
||||||
Malformed(text) => text.chars().any(|c| c == '\n'),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn fmt_when<'a>(
|
fn fmt_when<'a>(
|
||||||
buf: &mut String<'a>,
|
buf: &mut String<'a>,
|
||||||
loc_condition: &'a Located<Expr<'a>>,
|
loc_condition: &'a Located<Expr<'a>>,
|
||||||
branches: &[&'a WhenBranch<'a>],
|
branches: &[&'a WhenBranch<'a>],
|
||||||
indent: u16,
|
indent: u16,
|
||||||
) {
|
) {
|
||||||
let is_multiline_condition = is_multiline_expr(&loc_condition.value);
|
let is_multiline_condition = loc_condition.is_multiline();
|
||||||
buf.push_str(
|
buf.push_str(
|
||||||
"\
|
"\
|
||||||
when",
|
when",
|
||||||
|
@ -642,24 +468,24 @@ fn fmt_when<'a>(
|
||||||
newline(buf, condition_indent);
|
newline(buf, condition_indent);
|
||||||
match &expr_below {
|
match &expr_below {
|
||||||
Expr::SpaceAfter(expr_above, spaces_below_expr) => {
|
Expr::SpaceAfter(expr_above, spaces_below_expr) => {
|
||||||
fmt_expr(buf, &expr_above, condition_indent, false, false);
|
expr_above.format(buf, condition_indent);
|
||||||
fmt_condition_spaces(buf, spaces_below_expr.iter(), condition_indent);
|
fmt_condition_spaces(buf, spaces_below_expr.iter(), condition_indent);
|
||||||
newline(buf, indent);
|
newline(buf, indent);
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
fmt_expr(buf, &expr_below, condition_indent, false, false);
|
expr_below.format(buf, condition_indent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
newline(buf, condition_indent);
|
newline(buf, condition_indent);
|
||||||
fmt_expr(buf, &loc_condition.value, condition_indent, false, false);
|
loc_condition.format(buf, condition_indent);
|
||||||
newline(buf, indent);
|
newline(buf, indent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
buf.push(' ');
|
buf.push(' ');
|
||||||
fmt_expr(buf, &loc_condition.value, indent, false, true);
|
loc_condition.format(buf, indent);
|
||||||
buf.push(' ');
|
buf.push(' ');
|
||||||
}
|
}
|
||||||
buf.push_str("is\n");
|
buf.push_str("is\n");
|
||||||
|
@ -694,7 +520,7 @@ fn fmt_when<'a>(
|
||||||
|
|
||||||
if let Some(guard_expr) = &branch.guard {
|
if let Some(guard_expr) = &branch.guard {
|
||||||
buf.push_str(" if ");
|
buf.push_str(" if ");
|
||||||
fmt_expr(buf, &guard_expr.value, indent + INDENT, false, true);
|
guard_expr.format_with_options(buf, Parens::NotNeeded, Newlines::Yes, indent + INDENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
buf.push_str(" ->\n");
|
buf.push_str(" ->\n");
|
||||||
|
@ -703,10 +529,20 @@ fn fmt_when<'a>(
|
||||||
match expr.value {
|
match expr.value {
|
||||||
Expr::SpaceBefore(nested, spaces) => {
|
Expr::SpaceBefore(nested, spaces) => {
|
||||||
fmt_comments_only(buf, spaces.iter(), indent + (INDENT * 2));
|
fmt_comments_only(buf, spaces.iter(), indent + (INDENT * 2));
|
||||||
fmt_expr(buf, &nested, indent + (INDENT * 2), false, true);
|
nested.format_with_options(
|
||||||
|
buf,
|
||||||
|
Parens::NotNeeded,
|
||||||
|
Newlines::Yes,
|
||||||
|
indent + 2 * INDENT,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
fmt_expr(buf, &expr.value, indent + (INDENT * 2), false, true);
|
expr.format_with_options(
|
||||||
|
buf,
|
||||||
|
Parens::NotNeeded,
|
||||||
|
Newlines::Yes,
|
||||||
|
indent + 2 * INDENT,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -724,9 +560,9 @@ fn fmt_if<'a>(
|
||||||
loc_else: &'a Located<Expr<'a>>,
|
loc_else: &'a Located<Expr<'a>>,
|
||||||
indent: u16,
|
indent: u16,
|
||||||
) {
|
) {
|
||||||
let is_multiline_then = is_multiline_expr(&loc_then.value);
|
let is_multiline_then = (&loc_then.value).is_multiline();
|
||||||
let is_multiline_else = is_multiline_expr(&loc_else.value);
|
let is_multiline_else = (&loc_else.value).is_multiline();
|
||||||
let is_multiline_condition = is_multiline_expr(&loc_condition.value);
|
let is_multiline_condition = (&loc_condition.value).is_multiline();
|
||||||
let is_multiline = is_multiline_then || is_multiline_else || is_multiline_condition;
|
let is_multiline = is_multiline_then || is_multiline_else || is_multiline_condition;
|
||||||
|
|
||||||
let return_indent = if is_multiline {
|
let return_indent = if is_multiline {
|
||||||
|
@ -745,33 +581,33 @@ fn fmt_if<'a>(
|
||||||
|
|
||||||
match &expr_below {
|
match &expr_below {
|
||||||
Expr::SpaceAfter(expr_above, spaces_below_expr) => {
|
Expr::SpaceAfter(expr_above, spaces_below_expr) => {
|
||||||
fmt_expr(buf, &expr_above, return_indent, false, false);
|
expr_above.format(buf, return_indent);
|
||||||
fmt_condition_spaces(buf, spaces_below_expr.iter(), return_indent);
|
fmt_condition_spaces(buf, spaces_below_expr.iter(), return_indent);
|
||||||
newline(buf, indent);
|
newline(buf, indent);
|
||||||
}
|
}
|
||||||
|
|
||||||
_ => {
|
_ => {
|
||||||
fmt_expr(buf, &expr_below, return_indent, false, false);
|
expr_below.format(buf, return_indent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Expr::SpaceAfter(expr_above, spaces_below_expr) => {
|
Expr::SpaceAfter(expr_above, spaces_below_expr) => {
|
||||||
newline(buf, return_indent);
|
newline(buf, return_indent);
|
||||||
fmt_expr(buf, &expr_above, return_indent, false, false);
|
expr_above.format(buf, return_indent);
|
||||||
fmt_condition_spaces(buf, spaces_below_expr.iter(), return_indent);
|
fmt_condition_spaces(buf, spaces_below_expr.iter(), return_indent);
|
||||||
newline(buf, indent);
|
newline(buf, indent);
|
||||||
}
|
}
|
||||||
|
|
||||||
_ => {
|
_ => {
|
||||||
newline(buf, return_indent);
|
newline(buf, return_indent);
|
||||||
fmt_expr(buf, &loc_condition.value, return_indent, false, false);
|
loc_condition.format(buf, return_indent);
|
||||||
newline(buf, indent);
|
newline(buf, indent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
buf.push(' ');
|
buf.push(' ');
|
||||||
fmt_expr(buf, &loc_condition.value, indent, false, true);
|
loc_condition.format_with_options(buf, Parens::NotNeeded, Newlines::Yes, indent);
|
||||||
buf.push(' ');
|
buf.push(' ');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -794,24 +630,24 @@ fn fmt_if<'a>(
|
||||||
|
|
||||||
match &expr_below {
|
match &expr_below {
|
||||||
Expr::SpaceAfter(expr_above, spaces_above) => {
|
Expr::SpaceAfter(expr_above, spaces_above) => {
|
||||||
fmt_expr(buf, &expr_above, return_indent, false, false);
|
expr_above.format(buf, return_indent);
|
||||||
|
|
||||||
fmt_condition_spaces(buf, spaces_above.iter(), return_indent);
|
fmt_condition_spaces(buf, spaces_above.iter(), return_indent);
|
||||||
newline(buf, indent);
|
newline(buf, indent);
|
||||||
}
|
}
|
||||||
|
|
||||||
_ => {
|
_ => {
|
||||||
fmt_expr(buf, &expr_below, return_indent, false, false);
|
expr_below.format(buf, return_indent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
fmt_expr(buf, &loc_condition.value, return_indent, false, false);
|
loc_condition.format(buf, return_indent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
buf.push_str(" ");
|
buf.push_str(" ");
|
||||||
fmt_expr(buf, &loc_then.value, return_indent, false, false);
|
loc_then.format(buf, return_indent);
|
||||||
}
|
}
|
||||||
|
|
||||||
if is_multiline {
|
if is_multiline {
|
||||||
|
@ -821,7 +657,7 @@ fn fmt_if<'a>(
|
||||||
buf.push_str(" else ");
|
buf.push_str(" else ");
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt_expr(buf, &loc_else.value, return_indent, false, false);
|
loc_else.format(buf, return_indent);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fmt_closure<'a>(
|
pub fn fmt_closure<'a>(
|
||||||
|
@ -836,7 +672,7 @@ pub fn fmt_closure<'a>(
|
||||||
|
|
||||||
let arguments_are_multiline = loc_patterns
|
let arguments_are_multiline = loc_patterns
|
||||||
.iter()
|
.iter()
|
||||||
.any(|loc_pattern| is_multiline_pattern(&loc_pattern.value));
|
.any(|loc_pattern| loc_pattern.is_multiline());
|
||||||
|
|
||||||
// If the arguments are multiline, go down a line and indent.
|
// If the arguments are multiline, go down a line and indent.
|
||||||
let indent = if arguments_are_multiline {
|
let indent = if arguments_are_multiline {
|
||||||
|
@ -848,7 +684,7 @@ pub fn fmt_closure<'a>(
|
||||||
let mut it = loc_patterns.iter().peekable();
|
let mut it = loc_patterns.iter().peekable();
|
||||||
|
|
||||||
while let Some(loc_pattern) = it.next() {
|
while let Some(loc_pattern) = it.next() {
|
||||||
fmt_pattern(buf, &loc_pattern.value, indent, Parens::NotNeeded);
|
loc_pattern.format(buf, indent);
|
||||||
|
|
||||||
if it.peek().is_some() {
|
if it.peek().is_some() {
|
||||||
if arguments_are_multiline {
|
if arguments_are_multiline {
|
||||||
|
@ -868,7 +704,7 @@ pub fn fmt_closure<'a>(
|
||||||
|
|
||||||
buf.push_str("->");
|
buf.push_str("->");
|
||||||
|
|
||||||
let is_multiline = is_multiline_expr(&loc_ret.value);
|
let is_multiline = (&loc_ret.value).is_multiline();
|
||||||
|
|
||||||
// If the body is multiline, go down a line and indent.
|
// If the body is multiline, go down a line and indent.
|
||||||
let body_indent = if is_multiline {
|
let body_indent = if is_multiline {
|
||||||
|
@ -891,7 +727,7 @@ pub fn fmt_closure<'a>(
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
fmt_expr(buf, &loc_ret.value, body_indent, false, true);
|
loc_ret.format_with_options(buf, Parens::NotNeeded, Newlines::Yes, body_indent);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fmt_record<'a>(
|
pub fn fmt_record<'a>(
|
||||||
|
@ -899,7 +735,6 @@ pub fn fmt_record<'a>(
|
||||||
update: Option<&'a Located<Expr<'a>>>,
|
update: Option<&'a Located<Expr<'a>>>,
|
||||||
loc_fields: &[Located<AssignedField<'a, Expr<'a>>>],
|
loc_fields: &[Located<AssignedField<'a, Expr<'a>>>],
|
||||||
indent: u16,
|
indent: u16,
|
||||||
apply_needs_parens: Parens,
|
|
||||||
) {
|
) {
|
||||||
buf.push('{');
|
buf.push('{');
|
||||||
|
|
||||||
|
@ -916,9 +751,7 @@ pub fn fmt_record<'a>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let is_multiline = loc_fields
|
let is_multiline = loc_fields.iter().any(|loc_field| loc_field.is_multiline());
|
||||||
.iter()
|
|
||||||
.any(|loc_field| is_multiline_field(&loc_field.value));
|
|
||||||
|
|
||||||
let mut iter = loc_fields.iter().peekable();
|
let mut iter = loc_fields.iter().peekable();
|
||||||
let field_indent = if is_multiline {
|
let field_indent = if is_multiline {
|
||||||
|
|
|
@ -11,8 +11,8 @@ extern crate roc_parse;
|
||||||
mod test_fmt {
|
mod test_fmt {
|
||||||
use bumpalo::collections::String;
|
use bumpalo::collections::String;
|
||||||
use bumpalo::Bump;
|
use bumpalo::Bump;
|
||||||
|
use roc_fmt::annotation::{Formattable, Newlines, Parens};
|
||||||
use roc_fmt::def::fmt_def;
|
use roc_fmt::def::fmt_def;
|
||||||
use roc_fmt::expr::fmt_expr;
|
|
||||||
use roc_fmt::module::fmt_module;
|
use roc_fmt::module::fmt_module;
|
||||||
use roc_parse::ast::{Attempting, Expr};
|
use roc_parse::ast::{Attempting, Expr};
|
||||||
use roc_parse::blankspace::space0_before;
|
use roc_parse::blankspace::space0_before;
|
||||||
|
@ -38,7 +38,7 @@ mod test_fmt {
|
||||||
Ok(actual) => {
|
Ok(actual) => {
|
||||||
let mut buf = String::new_in(&arena);
|
let mut buf = String::new_in(&arena);
|
||||||
|
|
||||||
fmt_expr(&mut buf, &actual, 0, false, true);
|
actual.format_with_options(&mut buf, Parens::NotNeeded, Newlines::Yes, 0);
|
||||||
|
|
||||||
assert_eq!(buf, expected)
|
assert_eq!(buf, expected)
|
||||||
}
|
}
|
||||||
|
@ -2187,18 +2187,15 @@ mod test_fmt {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn applied_tags() {
|
fn body_starts_with_spaces_multiline() {
|
||||||
expr_formats_same(indoc!(
|
expr_formats_same(indoc!(
|
||||||
r#"
|
r#"
|
||||||
x = Foo 1 2
|
|
||||||
|
|
||||||
# well, that's wrong
|
|
||||||
y =
|
y =
|
||||||
Foo
|
Foo
|
||||||
1
|
1
|
||||||
2
|
2
|
||||||
|
|
||||||
{ x, y }
|
y
|
||||||
"#
|
"#
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue