mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-03 00:24:34 +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::{
|
use crate::{
|
||||||
collection::{fmt_collection, Braces},
|
collection::{fmt_collection, Braces},
|
||||||
expr::merge_spaces_conservative,
|
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::pattern_lift_spaces_after,
|
||||||
pattern::snakify_camel_ident,
|
pattern::snakify_camel_ident,
|
||||||
spaces::{fmt_comments_only, fmt_spaces, NewlineAt, INDENT},
|
spaces::{fmt_comments_only, fmt_spaces, NewlineAt, INDENT},
|
||||||
|
@ -416,18 +416,14 @@ fn fmt_tag_collection<'a>(
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Nodify<'a> for Tag<'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
|
where
|
||||||
'a: 'b,
|
'a: 'b,
|
||||||
{
|
{
|
||||||
match self {
|
match self {
|
||||||
Tag::Apply { name, args } => {
|
Tag::Apply { name, args } => {
|
||||||
if args.is_empty() {
|
if args.is_empty() {
|
||||||
Spaces {
|
NodeInfo::item(Node::Literal(name.value))
|
||||||
before: &[],
|
|
||||||
item: Node::Literal(name.value),
|
|
||||||
after: &[],
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
let first = Node::Literal(name.value);
|
let first = Node::Literal(name.value);
|
||||||
let mut new_args: Vec<'b, (Sp<'b>, Node<'b>)> =
|
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));
|
new_args.push((Sp::with_space(before), lifted.item));
|
||||||
}
|
}
|
||||||
|
|
||||||
Spaces {
|
NodeInfo {
|
||||||
before: &[],
|
before: &[],
|
||||||
item: Node::Sequence {
|
item: Node::Sequence {
|
||||||
first: arena.alloc(first),
|
first: arena.alloc(first),
|
||||||
|
@ -449,6 +445,7 @@ impl<'a> Nodify<'a> for Tag<'a> {
|
||||||
rest: new_args.into_bump_slice(),
|
rest: new_args.into_bump_slice(),
|
||||||
},
|
},
|
||||||
after: last_after,
|
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>> {
|
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
|
where
|
||||||
'a: 'b,
|
'a: 'b,
|
||||||
{
|
{
|
||||||
|
@ -628,10 +625,11 @@ impl<'a> Nodify<'a> for AssignedField<'a, TypeAnnotation<'a>> {
|
||||||
AssignedField::OptionalValue(name, sp, value) => {
|
AssignedField::OptionalValue(name, sp, value) => {
|
||||||
assigned_field_value_to_node(name.value, arena, sp, &value.value, "?")
|
assigned_field_value_to_node(name.value, arena, sp, &value.value, "?")
|
||||||
}
|
}
|
||||||
AssignedField::LabelOnly(name) => Spaces {
|
AssignedField::LabelOnly(name) => NodeInfo {
|
||||||
before: &[],
|
before: &[],
|
||||||
item: Node::Literal(name.value),
|
item: Node::Literal(name.value),
|
||||||
after: &[],
|
after: &[],
|
||||||
|
needs_indent: true,
|
||||||
},
|
},
|
||||||
AssignedField::SpaceBefore(inner, sp) => {
|
AssignedField::SpaceBefore(inner, sp) => {
|
||||||
let mut inner = inner.to_node(arena, parens);
|
let mut inner = inner.to_node(arena, parens);
|
||||||
|
@ -653,7 +651,7 @@ fn assigned_field_value_to_node<'a, 'b>(
|
||||||
sp: &'a [CommentOrNewline<'a>],
|
sp: &'a [CommentOrNewline<'a>],
|
||||||
value: &'a TypeAnnotation<'a>,
|
value: &'a TypeAnnotation<'a>,
|
||||||
sep: &'static str,
|
sep: &'static str,
|
||||||
) -> Spaces<'b, Node<'b>>
|
) -> NodeInfo<'b>
|
||||||
where
|
where
|
||||||
'a: 'b,
|
'a: 'b,
|
||||||
{
|
{
|
||||||
|
@ -667,10 +665,11 @@ where
|
||||||
|
|
||||||
b.push(Sp::with_space(value_lifted.before), value_lifted.item);
|
b.push(Sp::with_space(value_lifted.before), value_lifted.item);
|
||||||
|
|
||||||
Spaces {
|
NodeInfo {
|
||||||
before: &[],
|
before: &[],
|
||||||
item: b.build(),
|
item: b.build(),
|
||||||
after: value_lifted.after,
|
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> {
|
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
|
where
|
||||||
'a: 'b,
|
'a: 'b,
|
||||||
{
|
{
|
||||||
|
@ -1234,7 +1233,7 @@ impl<'a> Nodify<'a> for TypeAnnotation<'a> {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
let item = Spaces {
|
let item = NodeInfo {
|
||||||
before: &[],
|
before: &[],
|
||||||
item: Node::CommaSequence {
|
item: Node::CommaSequence {
|
||||||
allow_blank_lines: false,
|
allow_blank_lines: false,
|
||||||
|
@ -1243,6 +1242,7 @@ impl<'a> Nodify<'a> for TypeAnnotation<'a> {
|
||||||
rest: rest.into_bump_slice(),
|
rest: rest.into_bump_slice(),
|
||||||
},
|
},
|
||||||
after: last_after,
|
after: last_after,
|
||||||
|
needs_indent: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
if parens == Parens::InApply && !args.is_empty() {
|
if parens == Parens::InApply && !args.is_empty() {
|
||||||
|
@ -1313,7 +1313,7 @@ impl<'a> Nodify<'a> for TypeAnnotation<'a> {
|
||||||
node: res_node.item,
|
node: res_node.item,
|
||||||
});
|
});
|
||||||
|
|
||||||
let item = Spaces {
|
let item = NodeInfo {
|
||||||
before: first_node.before,
|
before: first_node.before,
|
||||||
item: Node::CommaSequence {
|
item: Node::CommaSequence {
|
||||||
allow_blank_lines: false,
|
allow_blank_lines: false,
|
||||||
|
@ -1322,6 +1322,7 @@ impl<'a> Nodify<'a> for TypeAnnotation<'a> {
|
||||||
rest: rest_nodes.into_bump_slice(),
|
rest: rest_nodes.into_bump_slice(),
|
||||||
},
|
},
|
||||||
after: res_node.after,
|
after: res_node.after,
|
||||||
|
needs_indent: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
if parens == Parens::InCollection
|
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(before_as), Node::Literal("as"));
|
||||||
b.push(Sp::with_space(right.before), right.item);
|
b.push(Sp::with_space(right.before), right.item);
|
||||||
|
|
||||||
let item = Spaces {
|
let item = NodeInfo {
|
||||||
before: left.before,
|
before: left.before,
|
||||||
item: b.build(),
|
item: b.build(),
|
||||||
after: right.after,
|
after: right.after,
|
||||||
|
needs_indent: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
if parens == Parens::InApply || parens == Parens::InAsPattern {
|
if parens == Parens::InApply || parens == Parens::InAsPattern {
|
||||||
|
@ -1355,7 +1357,7 @@ impl<'a> Nodify<'a> for TypeAnnotation<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TypeAnnotation::BoundVariable(text) => {
|
TypeAnnotation::BoundVariable(text) => {
|
||||||
let item = Spaces::item(Node::Literal(text));
|
let item = NodeInfo::item(Node::Literal(text));
|
||||||
|
|
||||||
if *text == "implements" {
|
if *text == "implements" {
|
||||||
parens_around_node(arena, item, false)
|
parens_around_node(arena, item, false)
|
||||||
|
@ -1363,15 +1365,16 @@ impl<'a> Nodify<'a> for TypeAnnotation<'a> {
|
||||||
item
|
item
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TypeAnnotation::Inferred => Spaces::item(Node::Literal("_")),
|
TypeAnnotation::Inferred => NodeInfo::item(Node::Literal("_")),
|
||||||
TypeAnnotation::Wildcard => Spaces::item(Node::Literal("*")),
|
TypeAnnotation::Wildcard => NodeInfo::item(Node::Literal("*")),
|
||||||
TypeAnnotation::Malformed(text) => Spaces::item(Node::Literal(text)),
|
TypeAnnotation::Malformed(text) => NodeInfo::item(Node::Literal(text)),
|
||||||
_ => {
|
_ => {
|
||||||
let lifted = ann_lift_spaces(arena, self);
|
let lifted = ann_lift_spaces(arena, self);
|
||||||
Spaces {
|
NodeInfo {
|
||||||
before: lifted.before,
|
before: lifted.before,
|
||||||
item: Node::TypeAnnotation(lifted.item),
|
item: Node::TypeAnnotation(lifted.item),
|
||||||
after: lifted.after,
|
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,
|
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,
|
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_lift_spaces_before;
|
||||||
use crate::pattern::{pattern_apply_to_node, pattern_fmt_apply};
|
use crate::pattern::{pattern_apply_to_node, pattern_fmt_apply};
|
||||||
use crate::spaces::{
|
use crate::spaces::{
|
||||||
|
@ -542,7 +542,7 @@ impl<'a> Formattable for TypeHeader<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Nodify<'a> 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
|
where
|
||||||
'a: 'b,
|
'a: 'b,
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use bumpalo::{collections::Vec, Bump};
|
use bumpalo::{collections::Vec, Bump};
|
||||||
use roc_parse::ast::{CommentOrNewline, Pattern, Spaces, TypeAnnotation};
|
use roc_parse::ast::{CommentOrNewline, Pattern, TypeAnnotation};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
annotation::{Formattable, Newlines, Parens},
|
annotation::{Formattable, Newlines, Parens},
|
||||||
|
@ -98,12 +98,12 @@ impl<'a> Node<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parens_around_node<'a, 'b: 'a>(
|
pub fn parens_around_node<'b, 'a: 'b>(
|
||||||
arena: &'a Bump,
|
arena: &'b Bump,
|
||||||
item: Spaces<'b, Node<'b>>,
|
item: NodeInfo<'a>,
|
||||||
allow_spaces_before: bool,
|
allow_spaces_before: bool,
|
||||||
) -> Spaces<'a, Node<'a>> {
|
) -> NodeInfo<'b> {
|
||||||
Spaces {
|
NodeInfo {
|
||||||
before: if allow_spaces_before {
|
before: if allow_spaces_before {
|
||||||
item.before
|
item.before
|
||||||
} else {
|
} 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
|
// We move the comments/newlines to the outer scope, since they tend to migrate there when re-parsed
|
||||||
after: item.after,
|
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> {
|
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
|
where
|
||||||
'a: 'b;
|
'a: 'b;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@ use crate::annotation::{Formattable, Newlines, Parens};
|
||||||
use crate::expr::{
|
use crate::expr::{
|
||||||
expr_is_multiline, expr_lift_spaces_after, fmt_str_literal, format_sq_literal, is_str_multiline,
|
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::spaces::{fmt_comments_only, fmt_spaces, NewlineAt, INDENT};
|
||||||
use crate::Buf;
|
use crate::Buf;
|
||||||
use bumpalo::Bump;
|
use bumpalo::Bump;
|
||||||
|
@ -552,7 +552,7 @@ pub fn pattern_apply_to_node<'b, 'a: 'b>(
|
||||||
parens: Parens,
|
parens: Parens,
|
||||||
func: Pattern<'a>,
|
func: Pattern<'a>,
|
||||||
args: &[Loc<Pattern<'a>>],
|
args: &[Loc<Pattern<'a>>],
|
||||||
) -> Spaces<'b, Node<'b>> {
|
) -> NodeInfo<'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(), true);
|
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;
|
last_after = arg_lifted.after;
|
||||||
}
|
}
|
||||||
|
|
||||||
let item = Spaces {
|
let item = NodeInfo {
|
||||||
before: func_lifted.before,
|
before: func_lifted.before,
|
||||||
item: b.build(),
|
item: b.build(),
|
||||||
after: last_after,
|
after: last_after,
|
||||||
|
needs_indent: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
let parens = !args.is_empty() && parens == Parens::InApply;
|
let parens = !args.is_empty() && parens == Parens::InApply;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue