Move apply to NodeInfo

This commit is contained in:
Joshua Warner 2024-12-25 09:03:21 -05:00
parent 99efcee275
commit 72da294d55
No known key found for this signature in database
GPG key ID: 89AD497003F93FDD
2 changed files with 67 additions and 54 deletions

View file

@ -980,60 +980,11 @@ impl<'a> Nodify<'a> for TypeAnnotation<'a> {
Node::Literal(arena.alloc_str(&format!("{}.{}", module, func)))
};
let mut last_after: &[CommentOrNewline<'_>] = &[];
let mut rest = Vec::with_capacity_in(args.len(), arena);
let mut multiline = false;
let mut indent_rest = true;
for (i, arg) in args.iter().enumerate() {
let is_last = i == args.len() - 1;
dbg!(arg, arg.value.to_node(arena));
let node = arg.value.to_node(arena).add_parens(arena, Parens::InApply);
let before = merge_spaces_conservative(arena, last_after, node.before);
if is_last
&& !multiline
&& node.node.is_multiline()
&& !node.needs_indent
&& before.is_empty()
{
// We can outdent the last argument, e.g.:
// foo {
// a:b,
// }
// In this case, the argument does its own indentation.
indent_rest = false;
}
multiline |= node.node.is_multiline() || !before.is_empty();
last_after = node.after;
rest.push(Item {
before,
comma_before: false,
newline: false,
space: true,
node: node.node,
});
}
NodeInfo {
before: &[],
node: Node::CommaSequence {
allow_blank_lines: false,
allow_newlines: true,
indent_rest,
first: arena.alloc(first),
rest: rest.into_bump_slice(),
},
after: last_after,
needs_indent: true,
prec: if args.is_empty() {
Prec::Term
} else {
Prec::Apply
},
}
NodeInfo::apply(
arena,
NodeInfo::item(first),
args.iter().map(|arg| arg.value.to_node(arena)),
)
}
TypeAnnotation::SpaceBefore(expr, spaces) => {
let mut inner = expr.to_node(arena);

View file

@ -4,6 +4,7 @@ use roc_parse::ast::{CommentOrNewline, Pattern, TypeAnnotation};
use crate::{
annotation::{Formattable, Newlines, Parens},
collection::Braces,
expr::merge_spaces_conservative,
spaces::{fmt_comments_only, fmt_spaces, fmt_spaces_no_blank_lines, NewlineAt, INDENT},
Buf,
};
@ -214,6 +215,67 @@ impl<'b> NodeInfo<'b> {
}
}
pub fn apply(
arena: &'b Bump,
first: NodeInfo<'b>,
args: impl Iterator<Item = NodeInfo<'b>>,
) -> NodeInfo<'b> {
let mut last_after = first.after;
let mut rest = Vec::with_capacity_in(args.size_hint().0, arena);
let mut multiline = false;
let mut indent_rest = true;
let mut it = args.peekable();
while let Some(arg) = it.next() {
let is_last = it.peek().is_none();
let arg = arg.add_parens(arena, Parens::InApply);
let before = merge_spaces_conservative(arena, last_after, arg.before);
if is_last
&& !multiline
&& arg.node.is_multiline()
&& !arg.needs_indent
&& before.is_empty()
{
// We can outdent the last argument, e.g.:
// foo {
// a:b,
// }
// In this case, the argument does its own indentation.
indent_rest = false;
}
multiline |= arg.node.is_multiline() || !before.is_empty();
last_after = arg.after;
rest.push(Item {
before,
comma_before: false,
newline: false,
space: true,
node: arg.node,
});
}
NodeInfo {
before: first.before,
prec: if rest.is_empty() {
Prec::Term
} else {
Prec::Apply
},
node: Node::CommaSequence {
allow_blank_lines: false,
allow_newlines: true,
indent_rest,
first: arena.alloc(first.node),
rest: rest.into_bump_slice(),
},
after: last_after,
needs_indent: true,
}
}
pub fn add_parens<'a>(&self, arena: &'a Bump, parens: Parens) -> NodeInfo<'a>
where
'b: 'a,