mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-27 05:49:08 +00:00
Refactor: introduce NodeInfo and needs_indent
This commit is contained in:
parent
13ec99c16b
commit
d2e1c12b96
4 changed files with 55 additions and 33 deletions
|
@ -1,7 +1,7 @@
|
|||
use crate::{
|
||||
collection::{fmt_collection, Braces},
|
||||
expr::merge_spaces_conservative,
|
||||
node::{parens_around_node, Item, Node, NodeSequenceBuilder, Nodify, Sp},
|
||||
node::{parens_around_node, Item, Node, NodeInfo, NodeSequenceBuilder, Nodify, Sp},
|
||||
pattern::pattern_lift_spaces_after,
|
||||
pattern::snakify_camel_ident,
|
||||
spaces::{fmt_comments_only, fmt_spaces, NewlineAt, INDENT},
|
||||
|
@ -416,18 +416,14 @@ fn fmt_tag_collection<'a>(
|
|||
}
|
||||
|
||||
impl<'a> Nodify<'a> for Tag<'a> {
|
||||
fn to_node<'b>(&'a self, arena: &'b Bump, parens: Parens) -> Spaces<'b, Node<'b>>
|
||||
fn to_node<'b>(&'a self, arena: &'b Bump, parens: Parens) -> NodeInfo<'b>
|
||||
where
|
||||
'a: 'b,
|
||||
{
|
||||
match self {
|
||||
Tag::Apply { name, args } => {
|
||||
if args.is_empty() {
|
||||
Spaces {
|
||||
before: &[],
|
||||
item: Node::Literal(name.value),
|
||||
after: &[],
|
||||
}
|
||||
NodeInfo::item(Node::Literal(name.value))
|
||||
} else {
|
||||
let first = Node::Literal(name.value);
|
||||
let mut new_args: Vec<'b, (Sp<'b>, Node<'b>)> =
|
||||
|
@ -441,7 +437,7 @@ impl<'a> Nodify<'a> for Tag<'a> {
|
|||
new_args.push((Sp::with_space(before), lifted.item));
|
||||
}
|
||||
|
||||
Spaces {
|
||||
NodeInfo {
|
||||
before: &[],
|
||||
item: Node::Sequence {
|
||||
first: arena.alloc(first),
|
||||
|
@ -449,6 +445,7 @@ impl<'a> Nodify<'a> for Tag<'a> {
|
|||
rest: new_args.into_bump_slice(),
|
||||
},
|
||||
after: last_after,
|
||||
needs_indent: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -611,7 +608,7 @@ impl<'a> Formattable for AssignedField<'a, Expr<'a>> {
|
|||
}
|
||||
|
||||
impl<'a> Nodify<'a> for AssignedField<'a, TypeAnnotation<'a>> {
|
||||
fn to_node<'b>(&'a self, arena: &'b Bump, parens: Parens) -> Spaces<'b, Node<'b>>
|
||||
fn to_node<'b>(&'a self, arena: &'b Bump, parens: Parens) -> NodeInfo<'b>
|
||||
where
|
||||
'a: 'b,
|
||||
{
|
||||
|
@ -628,10 +625,11 @@ impl<'a> Nodify<'a> for AssignedField<'a, TypeAnnotation<'a>> {
|
|||
AssignedField::OptionalValue(name, sp, value) => {
|
||||
assigned_field_value_to_node(name.value, arena, sp, &value.value, "?")
|
||||
}
|
||||
AssignedField::LabelOnly(name) => Spaces {
|
||||
AssignedField::LabelOnly(name) => NodeInfo {
|
||||
before: &[],
|
||||
item: Node::Literal(name.value),
|
||||
after: &[],
|
||||
needs_indent: true,
|
||||
},
|
||||
AssignedField::SpaceBefore(inner, sp) => {
|
||||
let mut inner = inner.to_node(arena, parens);
|
||||
|
@ -653,7 +651,7 @@ fn assigned_field_value_to_node<'a, 'b>(
|
|||
sp: &'a [CommentOrNewline<'a>],
|
||||
value: &'a TypeAnnotation<'a>,
|
||||
sep: &'static str,
|
||||
) -> Spaces<'b, Node<'b>>
|
||||
) -> NodeInfo<'b>
|
||||
where
|
||||
'a: 'b,
|
||||
{
|
||||
|
@ -667,10 +665,11 @@ where
|
|||
|
||||
b.push(Sp::with_space(value_lifted.before), value_lifted.item);
|
||||
|
||||
Spaces {
|
||||
NodeInfo {
|
||||
before: &[],
|
||||
item: b.build(),
|
||||
after: value_lifted.after,
|
||||
needs_indent: true,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1206,7 +1205,7 @@ pub fn type_head_lift_spaces_after<'a, 'b: 'a>(
|
|||
}
|
||||
|
||||
impl<'a> Nodify<'a> for TypeAnnotation<'a> {
|
||||
fn to_node<'b>(&'a self, arena: &'b Bump, parens: Parens) -> Spaces<'b, Node<'b>>
|
||||
fn to_node<'b>(&'a self, arena: &'b Bump, parens: Parens) -> NodeInfo<'b>
|
||||
where
|
||||
'a: 'b,
|
||||
{
|
||||
|
@ -1234,7 +1233,7 @@ impl<'a> Nodify<'a> for TypeAnnotation<'a> {
|
|||
});
|
||||
}
|
||||
|
||||
let item = Spaces {
|
||||
let item = NodeInfo {
|
||||
before: &[],
|
||||
item: Node::CommaSequence {
|
||||
allow_blank_lines: false,
|
||||
|
@ -1243,6 +1242,7 @@ impl<'a> Nodify<'a> for TypeAnnotation<'a> {
|
|||
rest: rest.into_bump_slice(),
|
||||
},
|
||||
after: last_after,
|
||||
needs_indent: true,
|
||||
};
|
||||
|
||||
if parens == Parens::InApply && !args.is_empty() {
|
||||
|
@ -1313,7 +1313,7 @@ impl<'a> Nodify<'a> for TypeAnnotation<'a> {
|
|||
node: res_node.item,
|
||||
});
|
||||
|
||||
let item = Spaces {
|
||||
let item = NodeInfo {
|
||||
before: first_node.before,
|
||||
item: Node::CommaSequence {
|
||||
allow_blank_lines: false,
|
||||
|
@ -1322,6 +1322,7 @@ impl<'a> Nodify<'a> for TypeAnnotation<'a> {
|
|||
rest: rest_nodes.into_bump_slice(),
|
||||
},
|
||||
after: res_node.after,
|
||||
needs_indent: true,
|
||||
};
|
||||
|
||||
if parens == Parens::InCollection
|
||||
|
@ -1342,10 +1343,11 @@ impl<'a> Nodify<'a> for TypeAnnotation<'a> {
|
|||
b.push(Sp::with_space(before_as), Node::Literal("as"));
|
||||
b.push(Sp::with_space(right.before), right.item);
|
||||
|
||||
let item = Spaces {
|
||||
let item = NodeInfo {
|
||||
before: left.before,
|
||||
item: b.build(),
|
||||
after: right.after,
|
||||
needs_indent: true,
|
||||
};
|
||||
|
||||
if parens == Parens::InApply || parens == Parens::InAsPattern {
|
||||
|
@ -1355,7 +1357,7 @@ impl<'a> Nodify<'a> for TypeAnnotation<'a> {
|
|||
}
|
||||
}
|
||||
TypeAnnotation::BoundVariable(text) => {
|
||||
let item = Spaces::item(Node::Literal(text));
|
||||
let item = NodeInfo::item(Node::Literal(text));
|
||||
|
||||
if *text == "implements" {
|
||||
parens_around_node(arena, item, false)
|
||||
|
@ -1363,15 +1365,16 @@ impl<'a> Nodify<'a> for TypeAnnotation<'a> {
|
|||
item
|
||||
}
|
||||
}
|
||||
TypeAnnotation::Inferred => Spaces::item(Node::Literal("_")),
|
||||
TypeAnnotation::Wildcard => Spaces::item(Node::Literal("*")),
|
||||
TypeAnnotation::Malformed(text) => Spaces::item(Node::Literal(text)),
|
||||
TypeAnnotation::Inferred => NodeInfo::item(Node::Literal("_")),
|
||||
TypeAnnotation::Wildcard => NodeInfo::item(Node::Literal("*")),
|
||||
TypeAnnotation::Malformed(text) => NodeInfo::item(Node::Literal(text)),
|
||||
_ => {
|
||||
let lifted = ann_lift_spaces(arena, self);
|
||||
Spaces {
|
||||
NodeInfo {
|
||||
before: lifted.before,
|
||||
item: Node::TypeAnnotation(lifted.item),
|
||||
after: lifted.after,
|
||||
needs_indent: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ use crate::expr::{
|
|||
expr_lift_and_lower, expr_lift_spaces, expr_lift_spaces_after, expr_lift_spaces_before,
|
||||
fmt_str_literal, is_str_multiline, sub_expr_requests_parens,
|
||||
};
|
||||
use crate::node::Nodify;
|
||||
use crate::node::{NodeInfo, Nodify};
|
||||
use crate::pattern::pattern_lift_spaces_before;
|
||||
use crate::pattern::{pattern_apply_to_node, pattern_fmt_apply};
|
||||
use crate::spaces::{
|
||||
|
@ -542,7 +542,7 @@ impl<'a> Formattable for TypeHeader<'a> {
|
|||
}
|
||||
|
||||
impl<'a> Nodify<'a> for TypeHeader<'a> {
|
||||
fn to_node<'b>(&'a self, arena: &'b Bump, parens: Parens) -> Spaces<'b, crate::node::Node<'b>>
|
||||
fn to_node<'b>(&'a self, arena: &'b Bump, parens: Parens) -> NodeInfo<'b>
|
||||
where
|
||||
'a: 'b,
|
||||
{
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use bumpalo::{collections::Vec, Bump};
|
||||
use roc_parse::ast::{CommentOrNewline, Pattern, Spaces, TypeAnnotation};
|
||||
use roc_parse::ast::{CommentOrNewline, Pattern, TypeAnnotation};
|
||||
|
||||
use crate::{
|
||||
annotation::{Formattable, Newlines, Parens},
|
||||
|
@ -98,12 +98,12 @@ impl<'a> Node<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn parens_around_node<'a, 'b: 'a>(
|
||||
arena: &'a Bump,
|
||||
item: Spaces<'b, Node<'b>>,
|
||||
pub fn parens_around_node<'b, 'a: 'b>(
|
||||
arena: &'b Bump,
|
||||
item: NodeInfo<'a>,
|
||||
allow_spaces_before: bool,
|
||||
) -> Spaces<'a, Node<'a>> {
|
||||
Spaces {
|
||||
) -> NodeInfo<'b> {
|
||||
NodeInfo {
|
||||
before: if allow_spaces_before {
|
||||
item.before
|
||||
} else {
|
||||
|
@ -123,11 +123,29 @@ pub fn parens_around_node<'a, 'b: 'a>(
|
|||
),
|
||||
// We move the comments/newlines to the outer scope, since they tend to migrate there when re-parsed
|
||||
after: item.after,
|
||||
needs_indent: true, // Maybe want to make parens outdentable?
|
||||
}
|
||||
}
|
||||
|
||||
pub struct NodeInfo<'b> {
|
||||
pub before: &'b [CommentOrNewline<'b>],
|
||||
pub item: Node<'b>,
|
||||
pub after: &'b [CommentOrNewline<'b>],
|
||||
pub needs_indent: bool,
|
||||
}
|
||||
impl<'b> NodeInfo<'b> {
|
||||
pub fn item(text: Node<'b>) -> NodeInfo<'b> {
|
||||
NodeInfo {
|
||||
before: &[],
|
||||
item: text,
|
||||
after: &[],
|
||||
needs_indent: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Nodify<'a> {
|
||||
fn to_node<'b>(&'a self, arena: &'b Bump, parens: Parens) -> Spaces<'b, Node<'b>>
|
||||
fn to_node<'b>(&'a self, arena: &'b Bump, parens: Parens) -> NodeInfo<'b>
|
||||
where
|
||||
'a: 'b;
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ use crate::annotation::{Formattable, Newlines, Parens};
|
|||
use crate::expr::{
|
||||
expr_is_multiline, expr_lift_spaces_after, fmt_str_literal, format_sq_literal, is_str_multiline,
|
||||
};
|
||||
use crate::node::{parens_around_node, Node, NodeSequenceBuilder, Sp};
|
||||
use crate::node::{parens_around_node, Node, NodeInfo, NodeSequenceBuilder, Sp};
|
||||
use crate::spaces::{fmt_comments_only, fmt_spaces, NewlineAt, INDENT};
|
||||
use crate::Buf;
|
||||
use bumpalo::Bump;
|
||||
|
@ -552,7 +552,7 @@ pub fn pattern_apply_to_node<'b, 'a: 'b>(
|
|||
parens: Parens,
|
||||
func: Pattern<'a>,
|
||||
args: &[Loc<Pattern<'a>>],
|
||||
) -> Spaces<'b, Node<'b>> {
|
||||
) -> NodeInfo<'b> {
|
||||
let func_lifted = pattern_lift_spaces(arena, &func);
|
||||
let mut b = NodeSequenceBuilder::new(arena, Node::Pattern(func_lifted.item), args.len(), true);
|
||||
|
||||
|
@ -567,10 +567,11 @@ pub fn pattern_apply_to_node<'b, 'a: 'b>(
|
|||
last_after = arg_lifted.after;
|
||||
}
|
||||
|
||||
let item = Spaces {
|
||||
let item = NodeInfo {
|
||||
before: func_lifted.before,
|
||||
item: b.build(),
|
||||
after: last_after,
|
||||
needs_indent: true,
|
||||
};
|
||||
|
||||
let parens = !args.is_empty() && parens == Parens::InApply;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue