From 7dc331faefe3f84daffa13ce7c0847fcf23fb279 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sat, 25 Sep 2021 19:11:45 +0300 Subject: [PATCH] fix: correct extend_to logic in parser Previously we swapped to events in the buffer, but that might be wrong if there aer `forward_parent` links pointing to the swapped-out node. Let's do the same via parent links instead, keeping the nodes in place --- crates/parser/src/event.rs | 10 ++++------ crates/parser/src/parser.rs | 10 +++++++--- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/crates/parser/src/event.rs b/crates/parser/src/event.rs index 9036688921..41b0328027 100644 --- a/crates/parser/src/event.rs +++ b/crates/parser/src/event.rs @@ -93,8 +93,6 @@ pub(super) fn process(sink: &mut dyn TreeSink, mut events: Vec) { for i in 0..events.len() { match mem::replace(&mut events[i], Event::tombstone()) { - Event::Start { kind: TOMBSTONE, .. } => (), - Event::Start { kind, forward_parent } => { // For events[A, B, C], B is A's forward_parent, C is B's forward_parent, // in the normal control flow, the parent-child relation: `A -> B -> C`, @@ -109,9 +107,7 @@ pub(super) fn process(sink: &mut dyn TreeSink, mut events: Vec) { // append `A`'s forward_parent `B` fp = match mem::replace(&mut events[idx], Event::tombstone()) { Event::Start { kind, forward_parent } => { - if kind != TOMBSTONE { - forward_parents.push(kind); - } + forward_parents.push(kind); forward_parent } _ => unreachable!(), @@ -120,7 +116,9 @@ pub(super) fn process(sink: &mut dyn TreeSink, mut events: Vec) { } for kind in forward_parents.drain(..).rev() { - sink.start_node(kind); + if kind != TOMBSTONE { + sink.start_node(kind); + } } } Event::Finish => sink.finish_node(), diff --git a/crates/parser/src/parser.rs b/crates/parser/src/parser.rs index f6b8308c57..ff2af130be 100644 --- a/crates/parser/src/parser.rs +++ b/crates/parser/src/parser.rs @@ -340,10 +340,14 @@ impl CompletedMarker { /// Extends this completed marker *to the left* up to `m`. pub(crate) fn extend_to(self, p: &mut Parser, mut m: Marker) { - assert!(m.pos <= self.pos); m.bomb.defuse(); - - p.events.swap(self.pos as usize, m.pos as usize); + let idx = m.pos as usize; + match &mut p.events[idx] { + Event::Start { forward_parent, .. } => { + *forward_parent = Some(self.pos - m.pos); + } + _ => unreachable!(), + } } pub(crate) fn kind(&self) -> SyntaxKind {