mirror of
https://github.com/roc-lang/roc.git
synced 2025-11-03 06:02:54 +00:00
Fix parenthesized spaces in tag unions
This commit is contained in:
parent
02e07f95e7
commit
3acc6940b4
5 changed files with 209 additions and 30 deletions
|
|
@ -343,7 +343,7 @@ fn fmt_ty_ann(
|
||||||
}
|
}
|
||||||
|
|
||||||
TypeAnnotation::TagUnion { tags, ext } => {
|
TypeAnnotation::TagUnion { tags, ext } => {
|
||||||
fmt_collection(buf, indent, Braces::Square, *tags, newlines);
|
fmt_tag_collection(buf, indent, *tags, newlines);
|
||||||
fmt_ext(ext, buf, indent);
|
fmt_ext(ext, buf, indent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -403,6 +403,78 @@ fn fmt_ty_ann(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn fmt_tag_collection<'a>(
|
||||||
|
buf: &mut Buf<'_>,
|
||||||
|
indent: u16,
|
||||||
|
tags: Collection<'a, Loc<Tag<'a>>>,
|
||||||
|
newlines: Newlines,
|
||||||
|
) {
|
||||||
|
let arena = buf.text.bump();
|
||||||
|
let mut new_items: Vec<'_, NodeSpaces<'_, Node<'_>>> = Vec::with_capacity_in(tags.len(), arena);
|
||||||
|
|
||||||
|
let mut last_after: &[CommentOrNewline<'_>] = &[];
|
||||||
|
|
||||||
|
for item in tags.items.iter() {
|
||||||
|
let lifted = tag_lift_to_node(arena, item.value);
|
||||||
|
let before = merge_spaces_conservative(arena, last_after, lifted.before);
|
||||||
|
last_after = lifted.after;
|
||||||
|
new_items.push(NodeSpaces {
|
||||||
|
before,
|
||||||
|
item: lifted.item,
|
||||||
|
after: &[],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let final_comments = merge_spaces_conservative(arena, last_after, tags.final_comments());
|
||||||
|
|
||||||
|
let new_items =
|
||||||
|
Collection::with_items_and_comments(arena, new_items.into_bump_slice(), final_comments);
|
||||||
|
|
||||||
|
fmt_collection(buf, indent, Braces::Square, new_items, newlines);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn tag_lift_to_node<'a, 'b: 'a>(arena: &'a Bump, value: Tag<'b>) -> Spaces<'a, Node<'a>> {
|
||||||
|
match value {
|
||||||
|
Tag::Apply { name, args } => {
|
||||||
|
if args.is_empty() {
|
||||||
|
Spaces {
|
||||||
|
before: &[],
|
||||||
|
item: Node::Literal(name.value),
|
||||||
|
after: &[],
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let first = Node::Literal(name.value);
|
||||||
|
let mut new_args: Vec<'a, (Sp<'a>, Node<'a>)> =
|
||||||
|
Vec::with_capacity_in(args.len(), arena);
|
||||||
|
let mut last_after: &[CommentOrNewline<'_>] = &[];
|
||||||
|
|
||||||
|
for arg in args.iter() {
|
||||||
|
let lifted = ann_lift_to_node(Parens::InApply, arena, &arg.value);
|
||||||
|
let before = merge_spaces_conservative(arena, last_after, lifted.before);
|
||||||
|
last_after = lifted.after;
|
||||||
|
new_args.push((before, lifted.item));
|
||||||
|
}
|
||||||
|
|
||||||
|
Spaces {
|
||||||
|
before: &[],
|
||||||
|
item: Node::Sequence(arena.alloc(first), new_args.into_bump_slice()),
|
||||||
|
after: last_after,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Tag::SpaceBefore(inner, sp) => {
|
||||||
|
let mut inner = tag_lift_to_node(arena, *inner);
|
||||||
|
inner.before = merge_spaces_conservative(arena, sp, inner.before);
|
||||||
|
inner
|
||||||
|
}
|
||||||
|
Tag::SpaceAfter(inner, sp) => {
|
||||||
|
let mut inner = tag_lift_to_node(arena, *inner);
|
||||||
|
inner.after = merge_spaces_conservative(arena, inner.after, sp);
|
||||||
|
inner
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn lower<'a, 'b: 'a>(
|
fn lower<'a, 'b: 'a>(
|
||||||
arena: &'b Bump,
|
arena: &'b Bump,
|
||||||
lifted: Spaces<'b, TypeAnnotation<'b>>,
|
lifted: Spaces<'b, TypeAnnotation<'b>>,
|
||||||
|
|
@ -1070,6 +1142,8 @@ type Sp<'a> = &'a [CommentOrNewline<'a>];
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug)]
|
#[derive(Copy, Clone, Debug)]
|
||||||
enum Node<'a> {
|
enum Node<'a> {
|
||||||
|
Literal(&'a str),
|
||||||
|
Sequence(&'a Node<'a>, &'a [(Sp<'a>, Node<'a>)]),
|
||||||
DelimitedSequence(Braces, &'a [(Sp<'a>, Node<'a>)], Sp<'a>),
|
DelimitedSequence(Braces, &'a [(Sp<'a>, Node<'a>)], Sp<'a>),
|
||||||
TypeAnnotation(TypeAnnotation<'a>),
|
TypeAnnotation(TypeAnnotation<'a>),
|
||||||
}
|
}
|
||||||
|
|
@ -1078,17 +1152,19 @@ impl<'a> Formattable for Node<'a> {
|
||||||
fn is_multiline(&self) -> bool {
|
fn is_multiline(&self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
Node::DelimitedSequence(_braces, lefts, right) => {
|
Node::DelimitedSequence(_braces, lefts, right) => {
|
||||||
if !right.is_empty() {
|
right.is_empty()
|
||||||
return true;
|
&& lefts
|
||||||
}
|
.iter()
|
||||||
for (sp, l) in *lefts {
|
.any(|(sp, l)| l.is_multiline() || !sp.is_empty())
|
||||||
if l.is_multiline() || !sp.is_empty() {
|
}
|
||||||
return true;
|
Node::Sequence(first, rest) => {
|
||||||
}
|
first.is_multiline()
|
||||||
}
|
|| rest
|
||||||
false
|
.iter()
|
||||||
|
.any(|(sp, l)| l.is_multiline() || !sp.is_empty())
|
||||||
}
|
}
|
||||||
Node::TypeAnnotation(type_annotation) => type_annotation.is_multiline(),
|
Node::TypeAnnotation(type_annotation) => type_annotation.is_multiline(),
|
||||||
|
Node::Literal(_) => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1113,9 +1189,26 @@ impl<'a> Formattable for Node<'a> {
|
||||||
buf.indent(indent);
|
buf.indent(indent);
|
||||||
buf.push(braces.end());
|
buf.push(braces.end());
|
||||||
}
|
}
|
||||||
|
Node::Sequence(first, rest) => {
|
||||||
|
first.format_with_options(buf, parens, newlines, indent);
|
||||||
|
|
||||||
|
for (sp, l) in *rest {
|
||||||
|
if !sp.is_empty() {
|
||||||
|
fmt_spaces(buf, sp.iter(), indent);
|
||||||
|
} else {
|
||||||
|
buf.spaces(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
l.format_with_options(buf, parens, newlines, indent);
|
||||||
|
}
|
||||||
|
}
|
||||||
Node::TypeAnnotation(type_annotation) => {
|
Node::TypeAnnotation(type_annotation) => {
|
||||||
type_annotation.format_with_options(buf, parens, newlines, indent);
|
type_annotation.format_with_options(buf, parens, newlines, indent);
|
||||||
}
|
}
|
||||||
|
Node::Literal(text) => {
|
||||||
|
buf.indent(indent);
|
||||||
|
buf.push_str(text);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1158,14 +1251,27 @@ fn ann_lift_to_node<'a, 'b: 'a>(
|
||||||
&[]
|
&[]
|
||||||
};
|
};
|
||||||
|
|
||||||
Spaces {
|
let item = Node::TypeAnnotation(TypeAnnotation::Apply(
|
||||||
before: &[],
|
module,
|
||||||
item: Node::TypeAnnotation(TypeAnnotation::Apply(
|
func,
|
||||||
module,
|
new_args.into_bump_slice(),
|
||||||
func,
|
));
|
||||||
new_args.into_bump_slice(),
|
|
||||||
)),
|
if parens == Parens::InApply {
|
||||||
after,
|
parens_around_node(
|
||||||
|
arena,
|
||||||
|
Spaces {
|
||||||
|
before: &[],
|
||||||
|
item,
|
||||||
|
after,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
Spaces {
|
||||||
|
before: &[],
|
||||||
|
item,
|
||||||
|
after,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TypeAnnotation::SpaceBefore(expr, spaces) => {
|
TypeAnnotation::SpaceBefore(expr, spaces) => {
|
||||||
|
|
@ -1198,18 +1304,8 @@ fn ann_lift_to_node<'a, 'b: 'a>(
|
||||||
item: Node::TypeAnnotation(new_ann),
|
item: Node::TypeAnnotation(new_ann),
|
||||||
after: new_res.after,
|
after: new_res.after,
|
||||||
};
|
};
|
||||||
if parens == Parens::InCollection {
|
if parens == Parens::InCollection || parens == Parens::InApply {
|
||||||
let node = Node::DelimitedSequence(
|
parens_around_node(arena, inner)
|
||||||
Braces::Round,
|
|
||||||
arena.alloc_slice_copy(&[(inner.before, inner.item)]),
|
|
||||||
inner.after,
|
|
||||||
);
|
|
||||||
|
|
||||||
Spaces {
|
|
||||||
before: &[],
|
|
||||||
item: node,
|
|
||||||
after: &[],
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
inner
|
inner
|
||||||
}
|
}
|
||||||
|
|
@ -1225,6 +1321,21 @@ fn ann_lift_to_node<'a, 'b: 'a>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn parens_around_node<'a, 'b: 'a>(
|
||||||
|
arena: &'a Bump,
|
||||||
|
item: Spaces<'b, Node<'b>>,
|
||||||
|
) -> Spaces<'a, Node<'a>> {
|
||||||
|
Spaces {
|
||||||
|
before: &[],
|
||||||
|
item: Node::DelimitedSequence(
|
||||||
|
Braces::Round,
|
||||||
|
arena.alloc_slice_copy(&[(item.before, item.item)]),
|
||||||
|
item.after,
|
||||||
|
),
|
||||||
|
after: &[],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||||
pub struct NodeSpaces<'a, T> {
|
pub struct NodeSpaces<'a, T> {
|
||||||
pub before: &'a [CommentOrNewline<'a>],
|
pub before: &'a [CommentOrNewline<'a>],
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
g : [
|
||||||
|
T T, #
|
||||||
|
]
|
||||||
|
D
|
||||||
|
|
@ -0,0 +1,60 @@
|
||||||
|
@0-12 SpaceAfter(
|
||||||
|
Defs(
|
||||||
|
Defs {
|
||||||
|
tags: [
|
||||||
|
EitherIndex(2147483648),
|
||||||
|
],
|
||||||
|
regions: [
|
||||||
|
@0-10,
|
||||||
|
],
|
||||||
|
space_before: [
|
||||||
|
Slice<roc_parse::ast::CommentOrNewline> { start: 0, length: 0 },
|
||||||
|
],
|
||||||
|
space_after: [
|
||||||
|
Slice<roc_parse::ast::CommentOrNewline> { start: 0, length: 0 },
|
||||||
|
],
|
||||||
|
spaces: [],
|
||||||
|
type_defs: [],
|
||||||
|
value_defs: [
|
||||||
|
Annotation(
|
||||||
|
@0-1 Identifier {
|
||||||
|
ident: "g",
|
||||||
|
},
|
||||||
|
@2-10 TagUnion {
|
||||||
|
ext: None,
|
||||||
|
tags: [
|
||||||
|
@3-9 Apply {
|
||||||
|
name: @3-4 "T",
|
||||||
|
args: [
|
||||||
|
@5-6 SpaceAfter(
|
||||||
|
Apply(
|
||||||
|
"",
|
||||||
|
"T",
|
||||||
|
[],
|
||||||
|
),
|
||||||
|
[
|
||||||
|
LineComment(
|
||||||
|
"",
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
@11-12 SpaceBefore(
|
||||||
|
Tag(
|
||||||
|
"D",
|
||||||
|
),
|
||||||
|
[
|
||||||
|
Newline,
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
[
|
||||||
|
Newline,
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
g:[T(T#
|
||||||
|
)]
|
||||||
|
D
|
||||||
|
|
@ -298,6 +298,7 @@ mod test_snapshots {
|
||||||
pass/annotated_tuple_destructure.expr,
|
pass/annotated_tuple_destructure.expr,
|
||||||
pass/annotation_apply_newlines.expr,
|
pass/annotation_apply_newlines.expr,
|
||||||
pass/annotation_comment_before_colon.expr,
|
pass/annotation_comment_before_colon.expr,
|
||||||
|
pass/annotation_tag_parens_comment.expr,
|
||||||
pass/annotation_tuple_comment.expr,
|
pass/annotation_tuple_comment.expr,
|
||||||
pass/annotation_tuple_newline.expr,
|
pass/annotation_tuple_newline.expr,
|
||||||
pass/annotation_tuple_parens_newlines.expr,
|
pass/annotation_tuple_parens_newlines.expr,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue