Always use to_node for TypeAnnotation::As

This commit is contained in:
Joshua Warner 2024-12-19 11:13:57 -05:00
parent 5b93e834f1
commit dbbd097708
No known key found for this signature in database
GPG key ID: 89AD497003F93FDD
7 changed files with 197 additions and 43 deletions

View file

@ -1,6 +1,6 @@
use crate::{ use crate::{
collection::{fmt_collection, Braces}, collection::{fmt_collection, Braces},
expr::{format_spaces, merge_spaces_conservative}, expr::merge_spaces_conservative,
node::{parens_around_node, Node, NodeSequenceBuilder, Nodify, Sp}, node::{parens_around_node, Node, NodeSequenceBuilder, Nodify, Sp},
pattern::pattern_lift_spaces_after, pattern::pattern_lift_spaces_after,
pattern::snakify_camel_ident, pattern::snakify_camel_ident,
@ -370,36 +370,40 @@ fn fmt_ty_ann(
fmt_ext(ext, buf, indent); fmt_ext(ext, buf, indent);
} }
TypeAnnotation::As(lhs, spaces, TypeHeader { name, vars }) => { TypeAnnotation::As(..) => {
let write_parens = parens == Parens::InAsPattern || parens == Parens::InApply; me.item
.to_node(buf.text.bump(), parens)
.item
.format(buf, indent);
// let write_parens = parens == Parens::InAsPattern || parens == Parens::InApply;
buf.indent(indent); // buf.indent(indent);
if write_parens { // if write_parens {
buf.push('(') // buf.push('(')
} // }
let lhs_indent = buf.cur_line_indent(); // let lhs_indent = buf.cur_line_indent();
lhs.value // lhs.value
.format_with_options(buf, Parens::InAsPattern, Newlines::No, indent); // .format_with_options(buf, Parens::InAsPattern, Newlines::No, indent);
buf.spaces(1); // buf.spaces(1);
format_spaces(buf, spaces, newlines, indent); // format_spaces(buf, spaces, newlines, indent);
buf.indent(lhs_indent + INDENT); // buf.indent(lhs_indent + INDENT);
buf.push_str("as"); // buf.push_str("as");
buf.spaces(1); // buf.spaces(1);
buf.push_str(name.value); // buf.push_str(name.value);
for var in *vars { // for var in *vars {
buf.spaces(1); // buf.spaces(1);
var.value.format_with_options( // var.value.format_with_options(
buf, // buf,
Parens::NotNeeded, // Parens::NotNeeded,
Newlines::No, // Newlines::No,
lhs_indent + INDENT, // lhs_indent + INDENT,
); // );
} // }
if write_parens { // if write_parens {
buf.push(')') // buf.push(')')
} // }
} }
TypeAnnotation::Where(annot, implements_clauses) => { TypeAnnotation::Where(annot, implements_clauses) => {
@ -523,7 +527,11 @@ impl<'a> Nodify<'a> for Tag<'a> {
Spaces { Spaces {
before: &[], before: &[],
item: Node::Sequence(arena.alloc(first), new_args.into_bump_slice()), item: Node::Sequence {
first: arena.alloc(first),
extra_indent_for_rest: true,
rest: new_args.into_bump_slice(),
},
after: last_after, after: last_after,
} }
} }
@ -735,7 +743,7 @@ where
{ {
let first = Node::Literal(name); let first = Node::Literal(name);
let mut b = NodeSequenceBuilder::new(arena, first, 2); let mut b = NodeSequenceBuilder::new(arena, first, 2, false);
b.push(Sp::with_space(sp), Node::Literal(sep)); b.push(Sp::with_space(sp), Node::Literal(sep));
@ -1386,7 +1394,7 @@ impl<'a> Nodify<'a> for TypeAnnotation<'a> {
let left = left.value.to_node(arena, Parens::InAsPattern); let left = left.value.to_node(arena, Parens::InAsPattern);
let right = right.to_node(arena, Parens::InAsPattern); let right = right.to_node(arena, Parens::InAsPattern);
let before_as = merge_spaces(arena, left.after, sp); let before_as = merge_spaces(arena, left.after, sp);
let mut b = NodeSequenceBuilder::new(arena, left.item, 2); let mut b = NodeSequenceBuilder::new(arena, left.item, 2, true);
b.push(Sp::with_space(before_as), Node::Literal("as")); b.push(Sp::with_space(before_as), Node::Literal("as"));
b.push(Sp::with_space(right.before), right.item); b.push(Sp::with_space(right.before), right.item);

View file

@ -4,7 +4,7 @@ use roc_parse::ast::{CommentOrNewline, Pattern, Spaces, TypeAnnotation};
use crate::{ use crate::{
annotation::{Formattable, Newlines, Parens}, annotation::{Formattable, Newlines, Parens},
collection::Braces, collection::Braces,
spaces::fmt_spaces, spaces::{fmt_spaces, INDENT},
Buf, Buf,
}; };
@ -48,7 +48,11 @@ impl<'a> From<&'a [CommentOrNewline<'a>]> for Sp<'a> {
#[derive(Copy, Clone, Debug)] #[derive(Copy, Clone, Debug)]
pub enum Node<'a> { pub enum Node<'a> {
Literal(&'a str), Literal(&'a str),
Sequence(&'a Node<'a>, &'a [(Sp<'a>, Node<'a>)]), Sequence {
first: &'a Node<'a>,
extra_indent_for_rest: bool,
rest: &'a [(Sp<'a>, Node<'a>)],
},
DelimitedSequence(Braces, &'a [(Sp<'a>, Node<'a>)], Sp<'a>), DelimitedSequence(Braces, &'a [(Sp<'a>, Node<'a>)], Sp<'a>),
// Temporary! TODO: translate these into proper Node elements // Temporary! TODO: translate these into proper Node elements
@ -107,7 +111,11 @@ impl<'a> Formattable for Node<'a> {
.iter() .iter()
.any(|(sp, l)| l.is_multiline() || !sp.comments.is_empty()) .any(|(sp, l)| l.is_multiline() || !sp.comments.is_empty())
} }
Node::Sequence(first, rest) => { Node::Sequence {
first,
extra_indent_for_rest: _,
rest,
} => {
first.is_multiline() first.is_multiline()
|| rest || rest
.iter() .iter()
@ -134,12 +142,23 @@ impl<'a> Formattable for Node<'a> {
buf.indent(indent); buf.indent(indent);
buf.push(braces.end()); buf.push(braces.end());
} }
Node::Sequence(first, rest) => { Node::Sequence {
first,
extra_indent_for_rest,
rest,
} => {
buf.indent(indent);
let cur_indent = buf.cur_line_indent();
first.format_with_options(buf, parens, newlines, indent); first.format_with_options(buf, parens, newlines, indent);
let next_indent = if *extra_indent_for_rest {
cur_indent + INDENT
} else {
indent
};
for (sp, l) in *rest { for (sp, l) in *rest {
fmt_sp(buf, *sp, indent); fmt_sp(buf, *sp, next_indent);
l.format_with_options(buf, parens, newlines, indent); l.format_with_options(buf, parens, newlines, next_indent);
} }
} }
Node::Literal(text) => { Node::Literal(text) => {
@ -158,13 +177,20 @@ impl<'a> Formattable for Node<'a> {
pub struct NodeSequenceBuilder<'a> { pub struct NodeSequenceBuilder<'a> {
first: Node<'a>, first: Node<'a>,
extra_indent_for_rest: bool,
rest: Vec<'a, (Sp<'a>, Node<'a>)>, rest: Vec<'a, (Sp<'a>, Node<'a>)>,
} }
impl<'a> NodeSequenceBuilder<'a> { impl<'a> NodeSequenceBuilder<'a> {
pub fn new(arena: &'a Bump, first: Node<'a>, capacity: usize) -> Self { pub fn new(
arena: &'a Bump,
first: Node<'a>,
capacity: usize,
extra_indent_for_rest: bool,
) -> Self {
Self { Self {
first, first,
extra_indent_for_rest,
rest: Vec::with_capacity_in(capacity, arena), rest: Vec::with_capacity_in(capacity, arena),
} }
} }
@ -174,9 +200,10 @@ impl<'a> NodeSequenceBuilder<'a> {
} }
pub fn build(self) -> Node<'a> { pub fn build(self) -> Node<'a> {
Node::Sequence( Node::Sequence {
self.rest.bump().alloc(self.first), first: self.rest.bump().alloc(self.first),
self.rest.into_bump_slice(), extra_indent_for_rest: self.extra_indent_for_rest,
) rest: self.rest.into_bump_slice(),
}
} }
} }

View file

@ -554,7 +554,7 @@ pub fn pattern_apply_to_node<'b, 'a: 'b>(
args: &[Loc<Pattern<'a>>], args: &[Loc<Pattern<'a>>],
) -> Spaces<'b, Node<'b>> { ) -> Spaces<'b, Node<'b>> {
let func_lifted = pattern_lift_spaces(arena, &func); let func_lifted = pattern_lift_spaces(arena, &func);
let mut b = NodeSequenceBuilder::new(arena, Node::Pattern(func_lifted.item), args.len()); let mut b = NodeSequenceBuilder::new(arena, Node::Pattern(func_lifted.item), args.len(), true);
let mut last_after = func_lifted.after; let mut last_after = func_lifted.after;

View file

@ -0,0 +1,3 @@
mainForHost : [StdoutWrite Str ({} -> Op), StderrWrite Str ({} -> Op), Done] as Op
mainForHost = main
42

View file

@ -0,0 +1,112 @@
@0-104 SpaceAfter(
Defs(
Defs {
tags: [
EitherIndex(2147483648),
],
regions: [
@0-101,
],
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: [
AnnotatedBody {
ann_pattern: @0-11 Identifier {
ident: "mainForHost",
},
ann_type: @14-0 As(
@14-76 TagUnion {
ext: None,
tags: [
@15-41 Apply {
name: @15-26 "StdoutWrite",
args: [
@27-30 Apply(
"",
"Str",
[],
),
@32-40 Function(
[
@32-34 Record {
fields: [],
ext: None,
},
],
Pure,
@38-40 Apply(
"",
"Op",
[],
),
),
],
},
@43-69 Apply {
name: @43-54 "StderrWrite",
args: [
@55-58 Apply(
"",
"Str",
[],
),
@60-68 Function(
[
@60-62 Record {
fields: [],
ext: None,
},
],
Pure,
@66-68 Apply(
"",
"Op",
[],
),
),
],
},
@71-75 Apply {
name: @71-75 "Done",
args: [],
},
],
},
[],
TypeHeader {
name: @80-82 "Op",
vars: [],
},
),
lines_between: [
Newline,
],
body_pattern: @83-94 Identifier {
ident: "mainForHost",
},
body_expr: @97-101 Var {
module_name: "",
ident: "main",
},
},
],
},
@102-104 SpaceBefore(
Num(
"42",
),
[
Newline,
],
),
),
[
Newline,
],
)

View file

@ -0,0 +1,3 @@
mainForHost : [StdoutWrite Str ({} -> Op), StderrWrite Str ({} -> Op), Done] as Op
mainForHost = main
42

View file

@ -693,6 +693,7 @@ mod test_snapshots {
pass/tag_destructure_bang_no_space.expr, pass/tag_destructure_bang_no_space.expr,
pass/tag_pattern.expr, pass/tag_pattern.expr,
pass/tag_union_ann_with_as.expr, pass/tag_union_ann_with_as.expr,
pass/tag_union_functions_as.expr,
pass/ten_times_eleven.expr, pass/ten_times_eleven.expr,
pass/three_arg_closure.expr, pass/three_arg_closure.expr,
pass/triple_paren_pat_ann.expr, pass/triple_paren_pat_ann.expr,