From d1feb00170c3d7095f8c657db10b1249ef517ed5 Mon Sep 17 00:00:00 2001 From: Agustin Zubiaga Date: Wed, 17 May 2023 11:49:06 -0300 Subject: [PATCH] Track spaces between : and <- in record builders --- crates/compiler/can/src/operator.rs | 4 ++-- crates/compiler/fmt/src/annotation.rs | 20 +++++++++++++------ crates/compiler/fmt/src/expr.rs | 17 ++++++++++++---- crates/compiler/fmt/src/spaces.rs | 7 ++++--- crates/compiler/parse/src/ast.rs | 14 ++++++++----- crates/compiler/parse/src/expr.rs | 19 +++++++++++------- crates/compiler/test_syntax/tests/test_fmt.rs | 4 ++-- 7 files changed, 56 insertions(+), 29 deletions(-) diff --git a/crates/compiler/can/src/operator.rs b/crates/compiler/can/src/operator.rs index 65ec1d2d8a..8db8f8ff76 100644 --- a/crates/compiler/can/src/operator.rs +++ b/crates/compiler/can/src/operator.rs @@ -503,7 +503,7 @@ fn record_builder_arg<'a>( RecordBuilderField::Value(label, spaces, expr) => { break AssignedField::RequiredValue(label, spaces, expr) } - RecordBuilderField::ApplyValue(label, spaces, expr) => { + RecordBuilderField::ApplyValue(label, _, _, expr) => { apply_field_names.push(label); apply_exprs.push(expr); @@ -515,7 +515,7 @@ fn record_builder_arg<'a>( }, }); - break AssignedField::RequiredValue(label, spaces, var); + break AssignedField::RequiredValue(label, &[], var); } RecordBuilderField::LabelOnly(label) => break AssignedField::LabelOnly(label), RecordBuilderField::SpaceBefore(sub_field, _) => { diff --git a/crates/compiler/fmt/src/annotation.rs b/crates/compiler/fmt/src/annotation.rs index bbe1468df6..f513286455 100644 --- a/crates/compiler/fmt/src/annotation.rs +++ b/crates/compiler/fmt/src/annotation.rs @@ -513,8 +513,9 @@ fn is_multiline_record_builder_field_help(afield: &RecordBuilderField<'_>) -> bo use self::RecordBuilderField::*; match afield { - Value(_, spaces, ann) | ApplyValue(_, spaces, ann) => { - !spaces.is_empty() || ann.value.is_multiline() + Value(_, spaces, ann) => !spaces.is_empty() || ann.value.is_multiline(), + ApplyValue(_, colon_spaces, arrow_spaces, ann) => { + !colon_spaces.is_empty() || !arrow_spaces.is_empty() || ann.value.is_multiline() } LabelOnly(_) => false, SpaceBefore(_, _) | SpaceAfter(_, _) => true, @@ -549,7 +550,7 @@ fn format_record_builder_field_help( buf.spaces(1); ann.value.format(buf, indent); } - ApplyValue(name, spaces, ann) => { + ApplyValue(name, colon_spaces, arrow_spaces, ann) => { if is_multiline { buf.newline(); buf.indent(indent); @@ -557,12 +558,19 @@ fn format_record_builder_field_help( buf.push_str(name.value); - if !spaces.is_empty() { - fmt_spaces(buf, spaces.iter(), indent); + if !colon_spaces.is_empty() { + fmt_spaces(buf, colon_spaces.iter(), indent); } buf.spaces(separator_spaces); - buf.push_str(": <-"); + buf.push(':'); + buf.spaces(1); + + if !arrow_spaces.is_empty() { + fmt_spaces(buf, arrow_spaces.iter(), indent); + } + + buf.push_str("<-"); buf.spaces(1); ann.value.format(buf, indent); } diff --git a/crates/compiler/fmt/src/expr.rs b/crates/compiler/fmt/src/expr.rs index 91731424a3..ed78c1c218 100644 --- a/crates/compiler/fmt/src/expr.rs +++ b/crates/compiler/fmt/src/expr.rs @@ -1541,19 +1541,28 @@ fn format_record_builder_field_multiline( ann.value.format(buf, indent); buf.push(','); } - ApplyValue(name, spaces, ann) => { + ApplyValue(name, colon_spaces, arrow_spaces, ann) => { buf.newline(); buf.indent(indent); buf.push_str(name.value); - if !spaces.is_empty() { - fmt_spaces(buf, spaces.iter(), indent); + if !colon_spaces.is_empty() { + fmt_spaces(buf, colon_spaces.iter(), indent); buf.indent(indent); } buf.push_str(separator_prefix); - buf.push_str(": <-"); + buf.push(':'); buf.spaces(1); + + if !arrow_spaces.is_empty() { + fmt_spaces(buf, arrow_spaces.iter(), indent); + buf.indent(indent); + } + + buf.push_str("<-"); + buf.spaces(1); + ann.value.format(buf, indent); buf.push(','); } diff --git a/crates/compiler/fmt/src/spaces.rs b/crates/compiler/fmt/src/spaces.rs index eb7c96b927..5408814c09 100644 --- a/crates/compiler/fmt/src/spaces.rs +++ b/crates/compiler/fmt/src/spaces.rs @@ -620,12 +620,13 @@ impl<'a> RemoveSpaces<'a> for RecordBuilderField<'a> { match *self { RecordBuilderField::Value(a, _, c) => RecordBuilderField::Value( a.remove_spaces(arena), - arena.alloc([]), + &[], arena.alloc(c.remove_spaces(arena)), ), - RecordBuilderField::ApplyValue(a, _, c) => RecordBuilderField::ApplyValue( + RecordBuilderField::ApplyValue(a, _, _, c) => RecordBuilderField::ApplyValue( a.remove_spaces(arena), - arena.alloc([]), + &[], + &[], arena.alloc(c.remove_spaces(arena)), ), RecordBuilderField::LabelOnly(a) => { diff --git a/crates/compiler/parse/src/ast.rs b/crates/compiler/parse/src/ast.rs index 3b01744371..c0d35d67c0 100644 --- a/crates/compiler/parse/src/ast.rs +++ b/crates/compiler/parse/src/ast.rs @@ -694,8 +694,13 @@ pub enum RecordBuilderField<'a> { // A field with a value, e.g. `{ name: "blah" }` Value(Loc<&'a str>, &'a [CommentOrNewline<'a>], &'a Loc>), - // A field with a function we can apply to build part of the record, e.g. `{ name <- apply getName }` - ApplyValue(Loc<&'a str>, &'a [CommentOrNewline<'a>], &'a Loc>), + // A field with a function we can apply to build part of the record, e.g. `{ name: <- apply getName }` + ApplyValue( + Loc<&'a str>, + &'a [CommentOrNewline<'a>], + &'a [CommentOrNewline<'a>], + &'a Loc>, + ), // A label with no value, e.g. `{ name }` (this is sugar for { name: name }) LabelOnly(Loc<&'a str>), @@ -1615,9 +1620,8 @@ impl<'a, T: Malformed> Malformed for AssignedField<'a, T> { impl<'a> Malformed for RecordBuilderField<'a> { fn is_malformed(&self) -> bool { match self { - RecordBuilderField::Value(_, _, expr) | RecordBuilderField::ApplyValue(_, _, expr) => { - expr.is_malformed() - } + RecordBuilderField::Value(_, _, expr) + | RecordBuilderField::ApplyValue(_, _, _, expr) => expr.is_malformed(), RecordBuilderField::LabelOnly(_) => false, RecordBuilderField::SpaceBefore(field, _) | RecordBuilderField::SpaceAfter(field, _) => field.is_malformed(), diff --git a/crates/compiler/parse/src/expr.rs b/crates/compiler/parse/src/expr.rs index 3a247c2f30..e77bd8a216 100644 --- a/crates/compiler/parse/src/expr.rs +++ b/crates/compiler/parse/src/expr.rs @@ -2539,7 +2539,12 @@ pub enum RecordField<'a> { LabelOnly(Loc<&'a str>), SpaceBefore(&'a RecordField<'a>, &'a [CommentOrNewline<'a>]), SpaceAfter(&'a RecordField<'a>, &'a [CommentOrNewline<'a>]), - ApplyValue(Loc<&'a str>, &'a [CommentOrNewline<'a>], &'a Loc>), + ApplyValue( + Loc<&'a str>, + &'a [CommentOrNewline<'a>], + &'a [CommentOrNewline<'a>], + &'a Loc>, + ), } #[derive(Debug)] @@ -2554,7 +2559,7 @@ impl<'a> RecordField<'a> { loop { match current { - RecordField::ApplyValue(_, _, _) => break true, + RecordField::ApplyValue(_, _, _, _) => break true, RecordField::SpaceBefore(field, _) | RecordField::SpaceAfter(field, _) => { current = *field; } @@ -2580,7 +2585,7 @@ impl<'a> RecordField<'a> { RecordField::LabelOnly(loc_label) => Ok(LabelOnly(loc_label)), - RecordField::ApplyValue(_, _, _) => Err(FoundApplyValue), + RecordField::ApplyValue(_, _, _, _) => Err(FoundApplyValue), RecordField::SpaceBefore(field, spaces) => { let assigned_field = field.to_assigned_field(arena)?; @@ -2611,8 +2616,8 @@ impl<'a> RecordField<'a> { RecordField::LabelOnly(loc_label) => Ok(LabelOnly(loc_label)), - RecordField::ApplyValue(loc_label, spaces, loc_expr) => { - Ok(ApplyValue(loc_label, spaces, loc_expr)) + RecordField::ApplyValue(loc_label, colon_spaces, arrow_spaces, loc_expr) => { + Ok(ApplyValue(loc_label, colon_spaces, arrow_spaces, loc_expr)) } RecordField::SpaceBefore(field, spaces) => { @@ -2662,8 +2667,8 @@ pub fn record_field<'a>() -> impl Parser<'a, RecordField<'a>, ERecord<'a>> { RequiredValue(loc_label, spaces, arena.alloc(loc_val)) } - Some(Either::First((_, RecordFieldExpr::Apply(_, loc_val)))) => { - ApplyValue(loc_label, spaces, arena.alloc(loc_val)) + Some(Either::First((_, RecordFieldExpr::Apply(arrow_spaces, loc_val)))) => { + ApplyValue(loc_label, spaces, arrow_spaces, arena.alloc(loc_val)) } Some(Either::Second((_, loc_val))) => { diff --git a/crates/compiler/test_syntax/tests/test_fmt.rs b/crates/compiler/test_syntax/tests/test_fmt.rs index 69087839c6..a4414d3e11 100644 --- a/crates/compiler/test_syntax/tests/test_fmt.rs +++ b/crates/compiler/test_syntax/tests/test_fmt.rs @@ -1937,7 +1937,7 @@ mod test_fmt { expr_formats_to( indoc!( r#" - { a: 1, b: <- get "b" |> batch, c: <- get "c" |> batch } + { a: 1, b: <- get "b" |> batch, c:<- get "c" |> batch } "# ), indoc!( @@ -1961,7 +1961,7 @@ mod test_fmt { expr_formats_to( indoc!( r#" - { a: 1, b: <- get "b" |> batch, + { a: 1, b: <- get "b" |> batch, c: <- get "c" |> batch, d } "# ),