mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-27 05:49:08 +00:00
Refactor: Convert TypeAnnotation::Record to to_node
This commit is contained in:
parent
d2e1c12b96
commit
35fa82cbef
3 changed files with 193 additions and 59 deletions
|
@ -1,7 +1,9 @@
|
||||||
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, NodeInfo, NodeSequenceBuilder, Nodify, Sp},
|
node::{
|
||||||
|
parens_around_node, DelimitedItem, 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},
|
||||||
|
@ -54,6 +56,7 @@ pub enum Parens {
|
||||||
InAsPattern,
|
InAsPattern,
|
||||||
InApplyLastArg,
|
InApplyLastArg,
|
||||||
InClosurePattern,
|
InClosurePattern,
|
||||||
|
InTypeExt,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// In an AST node, do we show newlines around it
|
/// In an AST node, do we show newlines around it
|
||||||
|
@ -318,7 +321,7 @@ fn fmt_ty_ann(
|
||||||
TypeAnnotation::Function(..) | TypeAnnotation::As(..) => {
|
TypeAnnotation::Function(..) | TypeAnnotation::As(..) => {
|
||||||
me.item
|
me.item
|
||||||
.to_node(buf.text.bump(), parens)
|
.to_node(buf.text.bump(), parens)
|
||||||
.item
|
.node
|
||||||
.format(buf, indent);
|
.format(buf, indent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -372,7 +375,7 @@ fn fmt_ty_field_collection(
|
||||||
last_after = lifted.after;
|
last_after = lifted.after;
|
||||||
new_items.push(NodeSpaces {
|
new_items.push(NodeSpaces {
|
||||||
before,
|
before,
|
||||||
item: lifted.item,
|
item: lifted.node,
|
||||||
after: &[],
|
after: &[],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -402,7 +405,7 @@ fn fmt_tag_collection<'a>(
|
||||||
last_after = lifted.after;
|
last_after = lifted.after;
|
||||||
new_items.push(NodeSpaces {
|
new_items.push(NodeSpaces {
|
||||||
before,
|
before,
|
||||||
item: lifted.item,
|
item: lifted.node,
|
||||||
after: &[],
|
after: &[],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -434,12 +437,12 @@ impl<'a> Nodify<'a> for Tag<'a> {
|
||||||
let lifted = arg.value.to_node(arena, Parens::InApply);
|
let lifted = arg.value.to_node(arena, Parens::InApply);
|
||||||
let before = merge_spaces_conservative(arena, last_after, lifted.before);
|
let before = merge_spaces_conservative(arena, last_after, lifted.before);
|
||||||
last_after = lifted.after;
|
last_after = lifted.after;
|
||||||
new_args.push((Sp::with_space(before), lifted.item));
|
new_args.push((Sp::with_space(before), lifted.node));
|
||||||
}
|
}
|
||||||
|
|
||||||
NodeInfo {
|
NodeInfo {
|
||||||
before: &[],
|
before: &[],
|
||||||
item: Node::Sequence {
|
node: Node::Sequence {
|
||||||
first: arena.alloc(first),
|
first: arena.alloc(first),
|
||||||
extra_indent_for_rest: true,
|
extra_indent_for_rest: true,
|
||||||
rest: new_args.into_bump_slice(),
|
rest: new_args.into_bump_slice(),
|
||||||
|
@ -509,7 +512,7 @@ fn fmt_ty_collection(
|
||||||
last_after = lifted.after;
|
last_after = lifted.after;
|
||||||
new_items.push(NodeSpaces {
|
new_items.push(NodeSpaces {
|
||||||
before,
|
before,
|
||||||
item: lifted.item,
|
item: lifted.node,
|
||||||
after: &[],
|
after: &[],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -627,7 +630,7 @@ impl<'a> Nodify<'a> for AssignedField<'a, TypeAnnotation<'a>> {
|
||||||
}
|
}
|
||||||
AssignedField::LabelOnly(name) => NodeInfo {
|
AssignedField::LabelOnly(name) => NodeInfo {
|
||||||
before: &[],
|
before: &[],
|
||||||
item: Node::Literal(name.value),
|
node: Node::Literal(name.value),
|
||||||
after: &[],
|
after: &[],
|
||||||
needs_indent: true,
|
needs_indent: true,
|
||||||
},
|
},
|
||||||
|
@ -663,11 +666,11 @@ where
|
||||||
|
|
||||||
let value_lifted = value.to_node(arena, Parens::NotNeeded);
|
let value_lifted = value.to_node(arena, Parens::NotNeeded);
|
||||||
|
|
||||||
b.push(Sp::with_space(value_lifted.before), value_lifted.item);
|
b.push(Sp::with_space(value_lifted.before), value_lifted.node);
|
||||||
|
|
||||||
NodeInfo {
|
NodeInfo {
|
||||||
before: &[],
|
before: &[],
|
||||||
item: b.build(),
|
node: b.build(),
|
||||||
after: value_lifted.after,
|
after: value_lifted.after,
|
||||||
needs_indent: true,
|
needs_indent: true,
|
||||||
}
|
}
|
||||||
|
@ -1226,16 +1229,16 @@ impl<'a> Nodify<'a> for TypeAnnotation<'a> {
|
||||||
last_after = lifted.after;
|
last_after = lifted.after;
|
||||||
rest.push(Item {
|
rest.push(Item {
|
||||||
before,
|
before,
|
||||||
comma: false,
|
comma_before: false,
|
||||||
newline: false,
|
newline: false,
|
||||||
space: true,
|
space: true,
|
||||||
node: lifted.item,
|
node: lifted.node,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
let item = NodeInfo {
|
let item = NodeInfo {
|
||||||
before: &[],
|
before: &[],
|
||||||
item: Node::CommaSequence {
|
node: Node::CommaSequence {
|
||||||
allow_blank_lines: false,
|
allow_blank_lines: false,
|
||||||
indent_rest: true,
|
indent_rest: true,
|
||||||
first: arena.alloc(first),
|
first: arena.alloc(first),
|
||||||
|
@ -1266,25 +1269,24 @@ impl<'a> Nodify<'a> for TypeAnnotation<'a> {
|
||||||
let first_node = first.value.to_node(arena, Parens::InFunctionType);
|
let first_node = first.value.to_node(arena, Parens::InFunctionType);
|
||||||
let mut last_after: &'_ [CommentOrNewline<'_>] = &[];
|
let mut last_after: &'_ [CommentOrNewline<'_>] = &[];
|
||||||
let mut rest_nodes = Vec::with_capacity_in(rest.len() + 2, arena);
|
let mut rest_nodes = Vec::with_capacity_in(rest.len() + 2, arena);
|
||||||
|
let mut multiline = first_node.node.is_multiline() || !first_node.after.is_empty();
|
||||||
let mut multiline = first_node.item.is_multiline() || !first_node.after.is_empty();
|
|
||||||
|
|
||||||
for item in rest {
|
for item in rest {
|
||||||
let node = item.value.to_node(arena, Parens::InFunctionType);
|
let node = item.value.to_node(arena, Parens::InFunctionType);
|
||||||
let before = merge_spaces_conservative(arena, last_after, node.before);
|
let before = merge_spaces_conservative(arena, last_after, node.before);
|
||||||
multiline |= node.item.is_multiline() || !before.is_empty();
|
multiline |= node.node.is_multiline() || !before.is_empty();
|
||||||
last_after = node.after;
|
last_after = node.after;
|
||||||
rest_nodes.push(Item {
|
rest_nodes.push(Item {
|
||||||
before,
|
before,
|
||||||
comma: true,
|
comma_before: true,
|
||||||
newline: false,
|
newline: false,
|
||||||
space: true,
|
space: true,
|
||||||
node: node.item,
|
node: node.node,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
let res_node = res.value.to_node(arena, Parens::InFunctionType);
|
let res_node = res.value.to_node(arena, Parens::InFunctionType);
|
||||||
multiline |= res_node.item.is_multiline()
|
multiline |= res_node.node.is_multiline()
|
||||||
|| !last_after.is_empty()
|
|| !last_after.is_empty()
|
||||||
|| !res_node.before.is_empty();
|
|| !res_node.before.is_empty();
|
||||||
|
|
||||||
|
@ -1296,7 +1298,7 @@ impl<'a> Nodify<'a> for TypeAnnotation<'a> {
|
||||||
|
|
||||||
rest_nodes.push(Item {
|
rest_nodes.push(Item {
|
||||||
before: last_after,
|
before: last_after,
|
||||||
comma: false,
|
comma_before: false,
|
||||||
newline: multiline,
|
newline: multiline,
|
||||||
space: true,
|
space: true,
|
||||||
node: Node::Literal(match purity {
|
node: Node::Literal(match purity {
|
||||||
|
@ -1307,18 +1309,18 @@ impl<'a> Nodify<'a> for TypeAnnotation<'a> {
|
||||||
|
|
||||||
rest_nodes.push(Item {
|
rest_nodes.push(Item {
|
||||||
before: res_node.before,
|
before: res_node.before,
|
||||||
comma: false,
|
comma_before: false,
|
||||||
newline: false,
|
newline: false,
|
||||||
space: true,
|
space: true,
|
||||||
node: res_node.item,
|
node: res_node.node,
|
||||||
});
|
});
|
||||||
|
|
||||||
let item = NodeInfo {
|
let item = NodeInfo {
|
||||||
before: first_node.before,
|
before: first_node.before,
|
||||||
item: Node::CommaSequence {
|
node: Node::CommaSequence {
|
||||||
allow_blank_lines: false,
|
allow_blank_lines: false,
|
||||||
indent_rest: false,
|
indent_rest: false,
|
||||||
first: arena.alloc(first_node.item),
|
first: arena.alloc(first_node.node),
|
||||||
rest: rest_nodes.into_bump_slice(),
|
rest: rest_nodes.into_bump_slice(),
|
||||||
},
|
},
|
||||||
after: res_node.after,
|
after: res_node.after,
|
||||||
|
@ -1339,13 +1341,13 @@ 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, true);
|
let mut b = NodeSequenceBuilder::new(arena, left.node, 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.node);
|
||||||
|
|
||||||
let item = NodeInfo {
|
let item = NodeInfo {
|
||||||
before: left.before,
|
before: left.before,
|
||||||
item: b.build(),
|
node: b.build(),
|
||||||
after: right.after,
|
after: right.after,
|
||||||
needs_indent: true,
|
needs_indent: true,
|
||||||
};
|
};
|
||||||
|
@ -1368,11 +1370,73 @@ impl<'a> Nodify<'a> for TypeAnnotation<'a> {
|
||||||
TypeAnnotation::Inferred => NodeInfo::item(Node::Literal("_")),
|
TypeAnnotation::Inferred => NodeInfo::item(Node::Literal("_")),
|
||||||
TypeAnnotation::Wildcard => NodeInfo::item(Node::Literal("*")),
|
TypeAnnotation::Wildcard => NodeInfo::item(Node::Literal("*")),
|
||||||
TypeAnnotation::Malformed(text) => NodeInfo::item(Node::Literal(text)),
|
TypeAnnotation::Malformed(text) => NodeInfo::item(Node::Literal(text)),
|
||||||
|
TypeAnnotation::Record { fields, ext } => {
|
||||||
|
let mut items = Vec::with_capacity_in(fields.len(), arena);
|
||||||
|
let mut last_after: &[CommentOrNewline<'_>] = &[];
|
||||||
|
let mut multiline = false;
|
||||||
|
for field in fields.iter() {
|
||||||
|
let node = field.value.to_node(arena, Parens::InCollection);
|
||||||
|
dbg!(node);
|
||||||
|
let before = merge_spaces_conservative(arena, last_after, node.before);
|
||||||
|
multiline |= node.node.is_multiline() || !before.is_empty();
|
||||||
|
last_after = node.after;
|
||||||
|
items.push(DelimitedItem {
|
||||||
|
before,
|
||||||
|
newline: false,
|
||||||
|
space: true,
|
||||||
|
node: node.node,
|
||||||
|
comma_after: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if multiline {
|
||||||
|
for item in items.iter_mut() {
|
||||||
|
item.newline = true;
|
||||||
|
}
|
||||||
|
} else if let Some(last) = items.last_mut() {
|
||||||
|
last.comma_after = false;
|
||||||
|
}
|
||||||
|
let delim = Node::DelimitedSequence {
|
||||||
|
braces: Braces::Curly,
|
||||||
|
after: Sp {
|
||||||
|
default_space: !items.is_empty(),
|
||||||
|
force_newline: multiline,
|
||||||
|
comments: merge_spaces_conservative(
|
||||||
|
arena,
|
||||||
|
last_after,
|
||||||
|
fields.final_comments(),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
items: items.into_bump_slice(),
|
||||||
|
indent_items: multiline,
|
||||||
|
};
|
||||||
|
if let Some(ext) = ext {
|
||||||
|
let ext = ext.value.to_node(arena, Parens::InTypeExt);
|
||||||
|
debug_assert_eq!(ext.before, &[]);
|
||||||
|
let item = Node::Sequence {
|
||||||
|
first: arena.alloc(delim),
|
||||||
|
extra_indent_for_rest: false,
|
||||||
|
rest: arena.alloc_slice_copy(&[(Sp::empty(), ext.node)]),
|
||||||
|
};
|
||||||
|
NodeInfo {
|
||||||
|
before: &[],
|
||||||
|
node: item,
|
||||||
|
after: ext.after,
|
||||||
|
needs_indent: false,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
NodeInfo {
|
||||||
|
before: &[],
|
||||||
|
node: delim,
|
||||||
|
after: &[],
|
||||||
|
needs_indent: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
_ => {
|
_ => {
|
||||||
let lifted = ann_lift_spaces(arena, self);
|
let lifted = ann_lift_spaces(arena, self);
|
||||||
NodeInfo {
|
NodeInfo {
|
||||||
before: lifted.before,
|
before: lifted.before,
|
||||||
item: Node::TypeAnnotation(lifted.item),
|
node: Node::TypeAnnotation(lifted.item),
|
||||||
after: lifted.after,
|
after: lifted.after,
|
||||||
needs_indent: true,
|
needs_indent: true,
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,19 +10,22 @@ use crate::{
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug)]
|
#[derive(Copy, Clone, Debug)]
|
||||||
pub struct Sp<'a> {
|
pub struct Sp<'a> {
|
||||||
default_space: bool, // if true and comments is empty, use a space (' ')
|
pub default_space: bool, // if true and comments is empty, use a space (' ')
|
||||||
comments: &'a [CommentOrNewline<'a>],
|
pub force_newline: bool, // if true, force a newline (irrespectively of comments)
|
||||||
|
pub comments: &'a [CommentOrNewline<'a>],
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Sp<'a> {
|
impl<'a> Sp<'a> {
|
||||||
pub fn empty() -> Sp<'a> {
|
pub fn empty() -> Sp<'a> {
|
||||||
Sp {
|
Sp {
|
||||||
|
force_newline: false,
|
||||||
default_space: false,
|
default_space: false,
|
||||||
comments: &[],
|
comments: &[],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn space() -> Sp<'a> {
|
pub fn space() -> Sp<'a> {
|
||||||
Sp {
|
Sp {
|
||||||
|
force_newline: false,
|
||||||
default_space: true,
|
default_space: true,
|
||||||
comments: &[],
|
comments: &[],
|
||||||
}
|
}
|
||||||
|
@ -30,15 +33,37 @@ impl<'a> Sp<'a> {
|
||||||
|
|
||||||
pub fn with_space(sp: &'a [CommentOrNewline<'a>]) -> Self {
|
pub fn with_space(sp: &'a [CommentOrNewline<'a>]) -> Self {
|
||||||
Sp {
|
Sp {
|
||||||
|
force_newline: false,
|
||||||
default_space: true,
|
default_space: true,
|
||||||
comments: sp,
|
comments: sp,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn maybe_with_space(space: bool, sp: &'a [CommentOrNewline<'a>]) -> Sp<'a> {
|
||||||
|
Sp {
|
||||||
|
force_newline: false,
|
||||||
|
default_space: space,
|
||||||
|
comments: sp,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn force_newline(sp: &'a [CommentOrNewline<'a>]) -> Self {
|
||||||
|
Sp {
|
||||||
|
force_newline: true,
|
||||||
|
default_space: false,
|
||||||
|
comments: sp,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_multiline(&self) -> bool {
|
||||||
|
self.force_newline || !self.comments.is_empty()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> From<&'a [CommentOrNewline<'a>]> for Sp<'a> {
|
impl<'a> From<&'a [CommentOrNewline<'a>]> for Sp<'a> {
|
||||||
fn from(comments: &'a [CommentOrNewline<'a>]) -> Self {
|
fn from(comments: &'a [CommentOrNewline<'a>]) -> Self {
|
||||||
Sp {
|
Sp {
|
||||||
|
force_newline: false,
|
||||||
default_space: false,
|
default_space: false,
|
||||||
comments,
|
comments,
|
||||||
}
|
}
|
||||||
|
@ -53,7 +78,12 @@ pub enum Node<'a> {
|
||||||
extra_indent_for_rest: bool,
|
extra_indent_for_rest: bool,
|
||||||
rest: &'a [(Sp<'a>, Node<'a>)],
|
rest: &'a [(Sp<'a>, Node<'a>)],
|
||||||
},
|
},
|
||||||
DelimitedSequence(Braces, &'a [(Sp<'a>, Node<'a>)], Sp<'a>),
|
DelimitedSequence {
|
||||||
|
braces: Braces,
|
||||||
|
indent_items: bool,
|
||||||
|
items: &'a [DelimitedItem<'a>],
|
||||||
|
after: Sp<'a>,
|
||||||
|
},
|
||||||
CommaSequence {
|
CommaSequence {
|
||||||
allow_blank_lines: bool,
|
allow_blank_lines: bool,
|
||||||
indent_rest: bool,
|
indent_rest: bool,
|
||||||
|
@ -67,9 +97,24 @@ pub enum Node<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug)]
|
#[derive(Copy, Clone, Debug)]
|
||||||
pub struct Item<'a> {
|
pub struct DelimitedItem<'a> {
|
||||||
|
pub before: &'a [CommentOrNewline<'a>],
|
||||||
|
pub newline: bool,
|
||||||
|
pub space: bool,
|
||||||
|
pub node: Node<'a>,
|
||||||
|
pub comma_after: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> DelimitedItem<'a> {
|
||||||
|
fn is_multiline(&self) -> bool {
|
||||||
|
self.newline || !self.before.is_empty() || self.node.is_multiline()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug)]
|
||||||
|
pub struct Item<'a> {
|
||||||
|
pub comma_before: bool,
|
||||||
pub before: &'a [CommentOrNewline<'a>],
|
pub before: &'a [CommentOrNewline<'a>],
|
||||||
pub comma: bool,
|
|
||||||
pub newline: bool,
|
pub newline: bool,
|
||||||
pub space: bool,
|
pub space: bool,
|
||||||
pub node: Node<'a>,
|
pub node: Node<'a>,
|
||||||
|
@ -109,27 +154,32 @@ pub fn parens_around_node<'b, 'a: 'b>(
|
||||||
} else {
|
} else {
|
||||||
&[]
|
&[]
|
||||||
},
|
},
|
||||||
item: Node::DelimitedSequence(
|
node: Node::DelimitedSequence {
|
||||||
Braces::Round,
|
braces: Braces::Round,
|
||||||
arena.alloc_slice_copy(&[(
|
indent_items: false,
|
||||||
if allow_spaces_before {
|
items: arena.alloc_slice_copy(&[DelimitedItem {
|
||||||
Sp::empty()
|
before: if allow_spaces_before {
|
||||||
|
&[]
|
||||||
} else {
|
} else {
|
||||||
item.before.into()
|
item.before
|
||||||
|
},
|
||||||
|
node: item.node,
|
||||||
|
newline: false,
|
||||||
|
space: false,
|
||||||
|
comma_after: false,
|
||||||
|
}]),
|
||||||
|
after: Sp::empty(),
|
||||||
},
|
},
|
||||||
item.item,
|
|
||||||
)]),
|
|
||||||
Sp::empty(),
|
|
||||||
),
|
|
||||||
// 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?
|
needs_indent: true, // Maybe want to make parens outdentable?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug)]
|
||||||
pub struct NodeInfo<'b> {
|
pub struct NodeInfo<'b> {
|
||||||
pub before: &'b [CommentOrNewline<'b>],
|
pub before: &'b [CommentOrNewline<'b>],
|
||||||
pub item: Node<'b>,
|
pub node: Node<'b>,
|
||||||
pub after: &'b [CommentOrNewline<'b>],
|
pub after: &'b [CommentOrNewline<'b>],
|
||||||
pub needs_indent: bool,
|
pub needs_indent: bool,
|
||||||
}
|
}
|
||||||
|
@ -137,7 +187,7 @@ impl<'b> NodeInfo<'b> {
|
||||||
pub fn item(text: Node<'b>) -> NodeInfo<'b> {
|
pub fn item(text: Node<'b>) -> NodeInfo<'b> {
|
||||||
NodeInfo {
|
NodeInfo {
|
||||||
before: &[],
|
before: &[],
|
||||||
item: text,
|
node: text,
|
||||||
after: &[],
|
after: &[],
|
||||||
needs_indent: true,
|
needs_indent: true,
|
||||||
}
|
}
|
||||||
|
@ -169,14 +219,14 @@ impl<'a> Formattable for Node<'a> {
|
||||||
first.is_multiline()
|
first.is_multiline()
|
||||||
|| rest
|
|| rest
|
||||||
.iter()
|
.iter()
|
||||||
.any(|(sp, l)| l.is_multiline() || !sp.comments.is_empty())
|
.any(|(sp, l)| l.is_multiline() || sp.is_multiline())
|
||||||
}
|
|
||||||
Node::DelimitedSequence(_braces, lefts, right) => {
|
|
||||||
right.comments.is_empty()
|
|
||||||
&& lefts
|
|
||||||
.iter()
|
|
||||||
.any(|(sp, l)| l.is_multiline() || !sp.comments.is_empty())
|
|
||||||
}
|
}
|
||||||
|
Node::DelimitedSequence {
|
||||||
|
braces: _,
|
||||||
|
indent_items: _,
|
||||||
|
items,
|
||||||
|
after,
|
||||||
|
} => after.is_multiline() || items.iter().any(|item| item.is_multiline()),
|
||||||
Node::CommaSequence {
|
Node::CommaSequence {
|
||||||
allow_blank_lines: _,
|
allow_blank_lines: _,
|
||||||
indent_rest: _,
|
indent_rest: _,
|
||||||
|
@ -191,15 +241,35 @@ impl<'a> Formattable for Node<'a> {
|
||||||
|
|
||||||
fn format_with_options(&self, buf: &mut Buf, parens: Parens, newlines: Newlines, indent: u16) {
|
fn format_with_options(&self, buf: &mut Buf, parens: Parens, newlines: Newlines, indent: u16) {
|
||||||
match self {
|
match self {
|
||||||
Node::DelimitedSequence(braces, lefts, right) => {
|
Node::DelimitedSequence {
|
||||||
|
braces,
|
||||||
|
indent_items,
|
||||||
|
items: lefts,
|
||||||
|
after: right,
|
||||||
|
} => {
|
||||||
buf.indent(indent);
|
buf.indent(indent);
|
||||||
buf.push(braces.start());
|
buf.push(braces.start());
|
||||||
|
|
||||||
for (sp, l) in *lefts {
|
let inner_indent = if *indent_items {
|
||||||
fmt_sp(buf, *sp, indent);
|
indent + INDENT
|
||||||
l.format_with_options(buf, parens, newlines, indent);
|
} else {
|
||||||
|
indent
|
||||||
|
};
|
||||||
|
|
||||||
|
for item in *lefts {
|
||||||
|
fmt_spaces(buf, item.before.iter(), inner_indent);
|
||||||
|
if item.newline {
|
||||||
|
buf.ensure_ends_with_newline();
|
||||||
|
} else if item.space {
|
||||||
|
buf.ensure_ends_with_whitespace();
|
||||||
}
|
}
|
||||||
fmt_sp(buf, *right, indent);
|
item.node
|
||||||
|
.format_with_options(buf, parens, newlines, inner_indent);
|
||||||
|
if item.comma_after {
|
||||||
|
buf.push(',');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fmt_sp(buf, *right, inner_indent);
|
||||||
|
|
||||||
buf.indent(indent);
|
buf.indent(indent);
|
||||||
buf.push(braces.end());
|
buf.push(braces.end());
|
||||||
|
@ -238,7 +308,7 @@ impl<'a> Formattable for Node<'a> {
|
||||||
first.format_with_options(buf, parens, newlines, indent);
|
first.format_with_options(buf, parens, newlines, indent);
|
||||||
|
|
||||||
for item in *rest {
|
for item in *rest {
|
||||||
if item.comma {
|
if item.comma_before {
|
||||||
buf.push(',');
|
buf.push(',');
|
||||||
}
|
}
|
||||||
if *allow_blank_lines {
|
if *allow_blank_lines {
|
||||||
|
|
|
@ -569,7 +569,7 @@ pub fn pattern_apply_to_node<'b, 'a: 'b>(
|
||||||
|
|
||||||
let item = NodeInfo {
|
let item = NodeInfo {
|
||||||
before: func_lifted.before,
|
before: func_lifted.before,
|
||||||
item: b.build(),
|
node: b.build(),
|
||||||
after: last_after,
|
after: last_after,
|
||||||
needs_indent: true,
|
needs_indent: true,
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue