block: use separate spans for start/end events
This commit is contained in:
parent
631c9eff42
commit
5e99d98f4f
2 changed files with 373 additions and 346 deletions
638
src/block.rs
638
src/block.rs
File diff suppressed because it is too large
Load diff
81
src/tree.rs
81
src/tree.rs
|
@ -75,7 +75,7 @@ impl<C: Clone, A: Clone> Iterator for Tree<C, A> {
|
||||||
let n = &self.nodes[head.index()];
|
let n = &self.nodes[head.index()];
|
||||||
let kind = match &n.kind {
|
let kind = match &n.kind {
|
||||||
NodeKind::Root => unreachable!(),
|
NodeKind::Root => unreachable!(),
|
||||||
NodeKind::Container(c, child) => {
|
NodeKind::Container(c, child, ..) => {
|
||||||
self.branch.push(head);
|
self.branch.push(head);
|
||||||
self.head = *child;
|
self.head = *child;
|
||||||
EventKind::Enter(c.clone())
|
EventKind::Enter(c.clone())
|
||||||
|
@ -91,10 +91,16 @@ impl<C: Clone, A: Clone> Iterator for Tree<C, A> {
|
||||||
};
|
};
|
||||||
Some(Event { kind, span: n.span })
|
Some(Event { kind, span: n.span })
|
||||||
} else if let Some(block_ni) = self.branch.pop() {
|
} else if let Some(block_ni) = self.branch.pop() {
|
||||||
let InternalNode { next, kind, span } = &self.nodes[block_ni.index()];
|
let InternalNode { next, kind, .. } = &self.nodes[block_ni.index()];
|
||||||
let kind = EventKind::Exit(kind.container().unwrap().clone());
|
if let NodeKind::Container(c, _, span) = kind {
|
||||||
self.head = *next;
|
self.head = *next;
|
||||||
Some(Event { kind, span: *span })
|
Some(Event {
|
||||||
|
kind: EventKind::Exit(c.clone()),
|
||||||
|
span: *span,
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
panic!()
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
@ -122,7 +128,7 @@ impl NodeIndex {
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
enum NodeKind<C, A> {
|
enum NodeKind<C, A> {
|
||||||
Root,
|
Root,
|
||||||
Container(C, Option<NodeIndex>),
|
Container(C, Option<NodeIndex>, Span),
|
||||||
Atom(A),
|
Atom(A),
|
||||||
Inline,
|
Inline,
|
||||||
}
|
}
|
||||||
|
@ -144,7 +150,7 @@ pub struct Builder<C, A> {
|
||||||
|
|
||||||
impl<C, A> NodeKind<C, A> {
|
impl<C, A> NodeKind<C, A> {
|
||||||
fn child(&self) -> Option<NodeIndex> {
|
fn child(&self) -> Option<NodeIndex> {
|
||||||
if let NodeKind::Container(_, child) = self {
|
if let NodeKind::Container(_, child, _) = self {
|
||||||
*child
|
*child
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
@ -152,20 +158,12 @@ impl<C, A> NodeKind<C, A> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn child_mut(&mut self) -> &mut Option<NodeIndex> {
|
fn child_mut(&mut self) -> &mut Option<NodeIndex> {
|
||||||
if let NodeKind::Container(_, child) = self {
|
if let NodeKind::Container(_, child, _) = self {
|
||||||
child
|
child
|
||||||
} else {
|
} else {
|
||||||
panic!()
|
panic!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn container(&self) -> Option<&C> {
|
|
||||||
if let NodeKind::Container(c, _) = self {
|
|
||||||
Some(c)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, C, A> From<&'a mut NodeKind<C, A>> for Element<'a, C, A> {
|
impl<'a, C, A> From<&'a mut NodeKind<C, A>> for Element<'a, C, A> {
|
||||||
|
@ -213,26 +211,36 @@ impl<C, A> Builder<C, A> {
|
||||||
self.depth += 1;
|
self.depth += 1;
|
||||||
self.add_node(InternalNode {
|
self.add_node(InternalNode {
|
||||||
span,
|
span,
|
||||||
kind: NodeKind::Container(c, None),
|
kind: NodeKind::Container(c, None, Span::new(0, 0)),
|
||||||
next: None,
|
next: None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn exit(&mut self) {
|
pub(super) fn exit(&mut self, span: Span) {
|
||||||
self.depth -= 1;
|
self.depth -= 1;
|
||||||
if let Some(head) = self.head.take() {
|
if let Some(head) = self.head.take() {
|
||||||
if matches!(self.nodes[head.index()].kind, NodeKind::Container(..)) {
|
if let NodeKind::Container(_, _, sp) = &mut self.nodes[head.index()].kind {
|
||||||
|
*sp = span;
|
||||||
self.branch.push(head);
|
self.branch.push(head);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let last = self.branch.pop();
|
let last = self.branch.pop();
|
||||||
debug_assert_ne!(last, None);
|
debug_assert_ne!(last, None);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let NodeKind::Container(_, _, sp) =
|
||||||
|
&mut self.nodes[self.branch.last().unwrap().index()].kind
|
||||||
|
{
|
||||||
|
*sp = span;
|
||||||
|
} else {
|
||||||
|
panic!();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Exit and discard all the contents of the current container.
|
/// Exit and discard all the contents of the current container.
|
||||||
pub(super) fn exit_discard(&mut self) {
|
pub(super) fn exit_discard(&mut self) {
|
||||||
self.exit();
|
self.exit(Span::new(0, (1 << 31) - 1));
|
||||||
let exited = self.branch.pop().unwrap();
|
let exited = self.branch.pop().unwrap();
|
||||||
self.nodes.drain(exited.index()..);
|
self.nodes.drain(exited.index()..);
|
||||||
let (prev, has_parent) = self.replace(exited, None);
|
let (prev, has_parent) = self.replace(exited, None);
|
||||||
|
@ -244,14 +252,25 @@ impl<C, A> Builder<C, A> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Swap the node and its children with either its parent or the node before.
|
/// Swap the node and its children with either its parent or the node before.
|
||||||
pub fn swap_prev(&mut self, node: NodeIndex) {
|
pub fn swap_prev(&mut self, node: NodeIndex, span: Span) {
|
||||||
let next = self.nodes[node.index()].next;
|
let next = self.nodes[node.index()].next;
|
||||||
if let Some(n) = next {
|
|
||||||
self.replace(n, None);
|
|
||||||
}
|
|
||||||
let (prev, _) = self.replace(node, next);
|
let (prev, _) = self.replace(node, next);
|
||||||
|
if let Some(n) = next {
|
||||||
|
self.nodes[prev.index()].span = self.nodes[n.index()].span.empty_before();
|
||||||
|
self.replace(n, None);
|
||||||
|
} else {
|
||||||
|
self.nodes[prev.index()].span = self.nodes[self.nodes.len() - 1].span.empty_after();
|
||||||
|
}
|
||||||
self.replace(prev, Some(node));
|
self.replace(prev, Some(node));
|
||||||
self.nodes[node.index()].next = Some(prev);
|
self.nodes[node.index()].next = Some(prev);
|
||||||
|
self.nodes[node.index()].span = span;
|
||||||
|
|
||||||
|
let span = self.nodes[prev.index()].span;
|
||||||
|
if let NodeKind::Container(_, _, sp) = &mut self.nodes[node.index()].kind {
|
||||||
|
*sp = span;
|
||||||
|
} else {
|
||||||
|
panic!()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Remove the specified node and its children.
|
/// Remove the specified node and its children.
|
||||||
|
@ -314,7 +333,7 @@ impl<C, A> Builder<C, A> {
|
||||||
debug_assert_eq!(head.next, None);
|
debug_assert_eq!(head.next, None);
|
||||||
head.next = Some(ni);
|
head.next = Some(ni);
|
||||||
}
|
}
|
||||||
NodeKind::Container(_, child) => {
|
NodeKind::Container(_, child, _) => {
|
||||||
self.branch.push(*head_ni);
|
self.branch.push(*head_ni);
|
||||||
// set child pointer of current container
|
// set child pointer of current container
|
||||||
debug_assert_eq!(*child, None);
|
debug_assert_eq!(*child, None);
|
||||||
|
@ -390,20 +409,20 @@ mod test {
|
||||||
tree.enter(1, Span::new(0, 1));
|
tree.enter(1, Span::new(0, 1));
|
||||||
tree.atom(11, Span::new(0, 1));
|
tree.atom(11, Span::new(0, 1));
|
||||||
tree.atom(12, Span::new(0, 1));
|
tree.atom(12, Span::new(0, 1));
|
||||||
tree.exit();
|
tree.exit(Span::new(0, 0));
|
||||||
tree.enter(2, Span::new(1, 5));
|
tree.enter(2, Span::new(1, 5));
|
||||||
tree.enter(21, Span::new(2, 5));
|
tree.enter(21, Span::new(2, 5));
|
||||||
tree.enter(211, Span::new(3, 4));
|
tree.enter(211, Span::new(3, 4));
|
||||||
tree.atom(2111, Span::new(3, 4));
|
tree.atom(2111, Span::new(3, 4));
|
||||||
tree.exit();
|
tree.exit(Span::new(0, 0));
|
||||||
tree.exit();
|
tree.exit(Span::new(0, 0));
|
||||||
tree.enter(22, Span::new(4, 5));
|
tree.enter(22, Span::new(4, 5));
|
||||||
tree.atom(221, Span::new(4, 5));
|
tree.atom(221, Span::new(4, 5));
|
||||||
tree.exit();
|
tree.exit(Span::new(0, 0));
|
||||||
tree.exit();
|
tree.exit(Span::new(0, 0));
|
||||||
tree.enter(3, Span::new(5, 6));
|
tree.enter(3, Span::new(5, 6));
|
||||||
tree.atom(31, Span::new(5, 6));
|
tree.atom(31, Span::new(5, 6));
|
||||||
tree.exit();
|
tree.exit(Span::new(0, 0));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
format!("{:?}", tree.finish()),
|
format!("{:?}", tree.finish()),
|
||||||
concat!(
|
concat!(
|
||||||
|
|
Loading…
Reference in a new issue