From 4cf179c089aeed381cd67bcd265e76a27f11facd Mon Sep 17 00:00:00 2001 From: pcpthm Date: Tue, 19 Mar 2019 18:44:23 +0900 Subject: Replace `contract_child` to a less ad-hoc API --- crates/ra_parser/src/grammar/expressions.rs | 20 +++++----- crates/ra_parser/src/parser.rs | 57 ++++++++++++++--------------- 2 files changed, 37 insertions(+), 40 deletions(-) (limited to 'crates/ra_parser/src') diff --git a/crates/ra_parser/src/grammar/expressions.rs b/crates/ra_parser/src/grammar/expressions.rs index c8ce07179..73e1acd5a 100644 --- a/crates/ra_parser/src/grammar/expressions.rs +++ b/crates/ra_parser/src/grammar/expressions.rs @@ -82,16 +82,15 @@ pub(crate) fn expr_block_contents(p: &mut Parser) { }; let (cm, blocklike) = expr_stmt(p); + let kind = cm.as_ref().map(|cm| cm.kind()).unwrap_or(ERROR); - if let Some(cm) = &cm { - if has_attrs && !is_expr_stmt_attr_allowed(cm.kind()) { - // test_err attr_on_expr_not_allowed - // fn foo() { - // #[A] 1 + 2; - // #[B] if true {}; - // } - p.error(format!("attributes are not allowed on {:?}", cm.kind())); - } + if has_attrs && !is_expr_stmt_attr_allowed(kind) { + // test_err attr_on_expr_not_allowed + // fn foo() { + // #[A] 1 + 2; + // #[B] if true {}; + // } + p.error(format!("attributes are not allowed on {:?}", kind)); } if p.at(R_CURLY) { @@ -101,7 +100,8 @@ pub(crate) fn expr_block_contents(p: &mut Parser) { // #[B] &() // } if let Some(cm) = cm { - m.contract_child(p, cm); + cm.undo_completion(p).abandon(p); + m.complete(p, kind); } else { m.abandon(p); } diff --git a/crates/ra_parser/src/parser.rs b/crates/ra_parser/src/parser.rs index fa036bdbf..3c326452b 100644 --- a/crates/ra_parser/src/parser.rs +++ b/crates/ra_parser/src/parser.rs @@ -212,8 +212,9 @@ impl Marker { } _ => unreachable!(), } + let finish_pos = p.events.len() as u32; p.push_event(Event::Finish); - CompletedMarker::new(self.pos, kind) + CompletedMarker::new(self.pos, finish_pos, kind) } /// Abandons the syntax tree node. All its children @@ -228,36 +229,17 @@ impl Marker { } } } - - /// Contract a node `cm` and complete as `cm`'s `kind`. - /// `cm` must be a child of `m` to work correctly. - /// ```text - /// m--A m--A - /// +--cm--B -> +--B - /// +--C C - /// - /// [m: TOMBSTONE, A, cm: Start(k), B, Finish, C] - /// [m: Start(k), A, cm: TOMBSTONE, B, Finish, C] - /// ``` - pub(crate) fn contract_child(mut self, p: &mut Parser, cm: CompletedMarker) -> CompletedMarker { - self.bomb.defuse(); - match p.events[self.pos as usize] { - Event::Start { kind: ref mut slot, .. } => *slot = cm.kind(), - _ => unreachable!(), - }; - match p.events[cm.0 as usize] { - Event::Start { kind: ref mut slot, .. } => *slot = TOMBSTONE, - _ => unreachable!(), - }; - CompletedMarker::new(self.pos, cm.kind()) - } } -pub(crate) struct CompletedMarker(u32, SyntaxKind); +pub(crate) struct CompletedMarker { + start_pos: u32, + finish_pos: u32, + kind: SyntaxKind, +} impl CompletedMarker { - fn new(pos: u32, kind: SyntaxKind) -> Self { - CompletedMarker(pos, kind) + fn new(start_pos: u32, finish_pos: u32, kind: SyntaxKind) -> Self { + CompletedMarker { start_pos, finish_pos, kind } } /// This method allows to create a new node which starts @@ -274,17 +256,32 @@ impl CompletedMarker { /// distance to `NEWSTART` into forward_parent(=2 in this case); pub(crate) fn precede(self, p: &mut Parser) -> Marker { let new_pos = p.start(); - let idx = self.0 as usize; + let idx = self.start_pos as usize; match p.events[idx] { Event::Start { ref mut forward_parent, .. } => { - *forward_parent = Some(new_pos.pos - self.0); + *forward_parent = Some(new_pos.pos - self.start_pos); } _ => unreachable!(), } new_pos } + /// Undo this completion and turns into a `Marker` + pub(crate) fn undo_completion(self, p: &mut Parser) -> Marker { + let start_idx = self.start_pos as usize; + let finish_idx = self.finish_pos as usize; + match p.events[start_idx] { + Event::Start { ref mut kind, forward_parent: None } => *kind = TOMBSTONE, + _ => unreachable!(), + } + match p.events[finish_idx] { + ref mut slot @ Event::Finish => *slot = Event::tombstone(), + _ => unreachable!(), + } + Marker::new(self.start_pos) + } + pub(crate) fn kind(&self) -> SyntaxKind { - self.1 + self.kind } } -- cgit v1.2.3