mirror of
https://github.com/roc-lang/roc.git
synced 2024-09-22 16:30:04 +03:00
Merge pull request #737 from rtfeldman/format-final-comments-record-type
Format final comments in record annotation
This commit is contained in:
commit
5b675559a9
@ -37,10 +37,6 @@ pub enum Newlines {
|
||||
No,
|
||||
}
|
||||
|
||||
pub fn fmt_annotation<'a>(buf: &mut String<'a>, annotation: &'a TypeAnnotation<'a>, indent: u16) {
|
||||
annotation.format(buf, indent);
|
||||
}
|
||||
|
||||
pub trait Formattable<'a> {
|
||||
fn is_multiline(&self) -> bool;
|
||||
|
||||
@ -85,13 +81,16 @@ where
|
||||
}
|
||||
|
||||
macro_rules! format_sequence {
|
||||
($buf: expr, $indent:expr, $start:expr, $end:expr, $items:expr, $t:ident) => {
|
||||
// is it a multiline type annotation?
|
||||
if $items.iter().any(|item| item.value.is_multiline()) {
|
||||
($buf: expr, $indent:expr, $start:expr, $end:expr, $items:expr, $final_comments:expr, $newline:expr, $t:ident) => {
|
||||
let is_multiline =
|
||||
$items.iter().any(|item| item.value.is_multiline()) || !$final_comments.is_empty();
|
||||
|
||||
if is_multiline {
|
||||
let braces_indent = $indent + INDENT;
|
||||
let item_indent = braces_indent + INDENT;
|
||||
|
||||
newline($buf, braces_indent);
|
||||
if ($newline == Newlines::Yes) {
|
||||
newline($buf, braces_indent);
|
||||
}
|
||||
$buf.push($start);
|
||||
|
||||
for item in $items.iter() {
|
||||
@ -139,10 +138,12 @@ macro_rules! format_sequence {
|
||||
}
|
||||
}
|
||||
}
|
||||
fmt_comments_only($buf, $final_comments.iter(), NewlineAt::Top, item_indent);
|
||||
newline($buf, braces_indent);
|
||||
$buf.push($end);
|
||||
} else {
|
||||
// is_multiline == false
|
||||
// there is no comment to add
|
||||
$buf.push($start);
|
||||
let mut iter = $items.iter().peekable();
|
||||
while let Some(item) = iter.next() {
|
||||
@ -285,9 +286,9 @@ impl<'a> Formattable<'a> for TypeAnnotation<'a> {
|
||||
TagUnion {
|
||||
tags,
|
||||
ext,
|
||||
final_comments: _,
|
||||
final_comments,
|
||||
} => {
|
||||
format_sequence!(buf, indent, '[', ']', tags, Tag);
|
||||
format_sequence!(buf, indent, '[', ']', tags, final_comments, newlines, Tag);
|
||||
|
||||
if let Some(loc_ext_ann) = *ext {
|
||||
loc_ext_ann.value.format(buf, indent);
|
||||
@ -297,9 +298,18 @@ impl<'a> Formattable<'a> for TypeAnnotation<'a> {
|
||||
Record {
|
||||
fields,
|
||||
ext,
|
||||
final_comments: _,
|
||||
final_comments,
|
||||
} => {
|
||||
format_sequence!(buf, indent, '{', '}', fields, AssignedField);
|
||||
format_sequence!(
|
||||
buf,
|
||||
indent,
|
||||
'{',
|
||||
'}',
|
||||
fields,
|
||||
final_comments,
|
||||
newlines,
|
||||
AssignedField
|
||||
);
|
||||
|
||||
if let Some(loc_ext_ann) = *ext {
|
||||
loc_ext_ann.value.format(buf, indent);
|
||||
@ -313,8 +323,18 @@ impl<'a> Formattable<'a> for TypeAnnotation<'a> {
|
||||
rhs.value.format(buf, indent);
|
||||
}
|
||||
|
||||
SpaceBefore(ann, _spaces) | SpaceAfter(ann, _spaces) => {
|
||||
ann.format_with_options(buf, parens, newlines, indent)
|
||||
SpaceBefore(ann, spaces) => {
|
||||
newline(buf, indent + INDENT);
|
||||
fmt_comments_only(buf, spaces.iter(), NewlineAt::Bottom, indent + INDENT);
|
||||
ann.format_with_options(buf, parens, Newlines::No, indent)
|
||||
}
|
||||
SpaceAfter(ann, spaces) => {
|
||||
ann.format_with_options(buf, parens, newlines, indent);
|
||||
fmt_comments_only(buf, spaces.iter(), NewlineAt::Bottom, indent);
|
||||
// seems like this SpaceAfter is not constructible
|
||||
// so this branch hasn't be tested. Please add some test if
|
||||
// this branch is actually reached and remove this dbg_assert.
|
||||
debug_assert!(false);
|
||||
}
|
||||
|
||||
Malformed(raw) => buf.push_str(raw),
|
||||
|
@ -36,8 +36,23 @@ impl<'a> Formattable<'a> for Def<'a> {
|
||||
match self {
|
||||
Annotation(loc_pattern, loc_annotation) => {
|
||||
loc_pattern.format(buf, indent);
|
||||
buf.push_str(" : ");
|
||||
loc_annotation.format(buf, indent);
|
||||
if loc_annotation.is_multiline() {
|
||||
buf.push_str(" :");
|
||||
loc_annotation.format_with_options(
|
||||
buf,
|
||||
Parens::NotNeeded,
|
||||
Newlines::Yes,
|
||||
indent,
|
||||
);
|
||||
} else {
|
||||
buf.push_str(" : ");
|
||||
loc_annotation.format_with_options(
|
||||
buf,
|
||||
Parens::NotNeeded,
|
||||
Newlines::No,
|
||||
indent,
|
||||
);
|
||||
}
|
||||
}
|
||||
Alias { name, vars, ann } => {
|
||||
buf.push_str(name.value);
|
||||
|
@ -770,7 +770,7 @@ mod test_fmt {
|
||||
),
|
||||
indoc!(
|
||||
r#"
|
||||
f :
|
||||
f :
|
||||
{
|
||||
y : Int,
|
||||
x : Int,
|
||||
@ -781,25 +781,125 @@ mod test_fmt {
|
||||
);
|
||||
}
|
||||
|
||||
// // TODO This raises a parse error:
|
||||
// // NotYetImplemented("TODO the : in this declaration seems outdented")
|
||||
// #[test]
|
||||
// fn comments_in_record_annotation() {
|
||||
// expr_formats_to(
|
||||
// indoc!(
|
||||
// r#"
|
||||
// f :
|
||||
// {}
|
||||
#[test]
|
||||
fn trailing_comma_in_record_annotation_same() {
|
||||
expr_formats_same(indoc!(
|
||||
r#"
|
||||
f :
|
||||
{
|
||||
y : Int,
|
||||
x : Int,
|
||||
}
|
||||
|
||||
// f"#
|
||||
// ),
|
||||
// indoc!(
|
||||
// r#"
|
||||
// f : b {}
|
||||
// f"#
|
||||
// ),
|
||||
// );
|
||||
// }
|
||||
f"#
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn multiline_type_definition() {
|
||||
expr_formats_same(indoc!(
|
||||
r#"
|
||||
f :
|
||||
Int
|
||||
|
||||
f"#
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn multiline_empty_record_type_definition() {
|
||||
expr_formats_same(indoc!(
|
||||
r#"
|
||||
f :
|
||||
{}
|
||||
|
||||
f"#
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn type_definition_comment_after_colon() {
|
||||
expr_formats_to(
|
||||
indoc!(
|
||||
r#"
|
||||
f : # comment
|
||||
{}
|
||||
|
||||
f"#
|
||||
),
|
||||
indoc!(
|
||||
r#"
|
||||
f :
|
||||
# comment
|
||||
{}
|
||||
|
||||
f"#
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn final_comment_in_empty_record_type_definition() {
|
||||
expr_formats_to(
|
||||
indoc!(
|
||||
r#"
|
||||
f :
|
||||
{ # comment
|
||||
}
|
||||
|
||||
f"#
|
||||
),
|
||||
indoc!(
|
||||
r#"
|
||||
f :
|
||||
{
|
||||
# comment
|
||||
}
|
||||
|
||||
f"#
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn multiline_inside_empty_record_annotation() {
|
||||
expr_formats_same(indoc!(
|
||||
r#"
|
||||
f :
|
||||
{
|
||||
}
|
||||
|
||||
f"#
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn final_comment_record_annotation() {
|
||||
expr_formats_to(
|
||||
indoc!(
|
||||
r#"
|
||||
f :
|
||||
{
|
||||
x: Int # comment 1
|
||||
,
|
||||
# comment 2
|
||||
}
|
||||
|
||||
f"#
|
||||
),
|
||||
indoc!(
|
||||
r#"
|
||||
f :
|
||||
{
|
||||
x : Int,
|
||||
# comment 1
|
||||
# comment 2
|
||||
}
|
||||
|
||||
f"#
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn def_closure() {
|
||||
|
@ -544,7 +544,7 @@ fn annotation<'a>(
|
||||
ascii_char(b':'),
|
||||
// Spaces after the ':' (at a normal indentation level) and then the type.
|
||||
// The type itself must be indented more than the pattern and ':'
|
||||
space0_before(type_annotation::located(indented_more), indented_more)
|
||||
space0_before(type_annotation::located(indented_more), min_indent)
|
||||
)
|
||||
)
|
||||
}
|
||||
@ -835,7 +835,7 @@ fn parse_def_signature<'a>(
|
||||
// It should be indented more than the original, and it will
|
||||
// end when outdented again.
|
||||
and_then_with_indent_level(
|
||||
type_annotation::located(indented_more),
|
||||
space0_before(type_annotation::located(indented_more), min_indent),
|
||||
// The first annotation may be immediately (spaces_then_comment_or_newline())
|
||||
// followed by a body at the exact same indent_level
|
||||
// leading to an AnnotatedBody in this case
|
||||
|
@ -1775,6 +1775,44 @@ mod test_parse {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn multiline_type_signature_with_comment() {
|
||||
assert_parses_to(
|
||||
"f :# comment\n {}\n\n42",
|
||||
Defs(
|
||||
&[&Located::new(
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
6,
|
||||
Def::Annotation(
|
||||
Located::new(0, 0, 0, 1, Pattern::Identifier("f")),
|
||||
Located::new(
|
||||
1,
|
||||
1,
|
||||
4,
|
||||
6,
|
||||
TypeAnnotation::SpaceBefore(
|
||||
&TypeAnnotation::Record {
|
||||
fields: &[],
|
||||
ext: None,
|
||||
final_comments: &[],
|
||||
},
|
||||
&[LineComment(" comment")],
|
||||
),
|
||||
),
|
||||
),
|
||||
)],
|
||||
&Located::new(
|
||||
3,
|
||||
3,
|
||||
0,
|
||||
2,
|
||||
Expr::SpaceBefore(&Expr::Num("42"), &[Newline, Newline]),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
// #[test]
|
||||
// fn type_signature_function_def() {
|
||||
// use TypeAnnotation;
|
||||
|
Loading…
Reference in New Issue
Block a user