1use drop_bomb::DropBomb;2use rowan::TextRange;34use crate::{event::Event, lex::SyntaxKind, parser::Parser};56pub struct Ranger {7 pub pos: usize,8}9impl Ranger {10 pub fn finish(mut self, p: &Parser) -> FinishedRanger {11 FinishedRanger {12 start_token: self.pos,13 end_token: self.pos.max(p.offset.saturating_sub(1)),14 }15 }16}1718pub struct FinishedRanger {19 pub start_token: usize,20 pub end_token: usize,21}22impl FinishedRanger {23 pub fn had_error_since(&self, p: &Parser) -> bool {24 p.last_error_token >= self.start_token25 }26}2728#[must_use]29pub struct Marker {30 pub start_event_idx: usize,31 pub token: usize,32 bomb: DropBomb,33}34impl Marker {35 pub fn new(pos: usize, token: usize) -> Self {36 Self {37 start_event_idx: pos,38 token,39 bomb: DropBomb::new("marked dropped while not completed"),40 }41 }42 pub fn complete(mut self, p: &mut Parser, kind: SyntaxKind) -> CompletedMarker {43 self.bomb.defuse();44 let event_at_pos = &mut p.events[self.start_event_idx];45 assert_eq!(*event_at_pos, Event::Placeholder);4647 *event_at_pos = Event::Start {48 kind,49 forward_parent: None,50 };5152 p.events.push(Event::Finish);53 p.entered -= 1;54 p.clear_outdated_hints();55 CompletedMarker {56 start_event_idx: self.start_event_idx,57 start_token: self.token,58 end_token: self.token.max(p.offset.saturating_sub(1)),59 }60 }61}62pub struct CompletedMarker {63 start_event_idx: usize,64 pub start_token: usize,65 pub end_token: usize,66}67impl CompletedMarker {68 pub(super) fn precede(self, p: &mut Parser) -> Marker {69 let mut new_m = p.start();70 new_m.token = self.start_token;7172 if let Event::Start {73 ref mut forward_parent,74 ..75 } = p.events[self.start_event_idx]76 {77 *forward_parent = Some(new_m.start_event_idx - self.start_event_idx);78 } else {79 unreachable!();80 }8182 new_m83 }84}8586pub trait AsRange {87 fn as_range(&self, p: &Parser) -> TextRange;88 fn end_token(&self) -> usize;89}9091impl AsRange for CompletedMarker {92 fn as_range(&self, p: &Parser) -> TextRange {93 TextRange::new(94 p.start_of_token(self.start_token),95 p.end_of_token(self.end_token),96 )97 }98 fn end_token(&self) -> usize {99 self.end_token100 }101}102103impl AsRange for FinishedRanger {104 fn as_range(&self, p: &Parser) -> TextRange {105 TextRange::new(106 p.start_of_token(self.start_token),107 p.end_of_token(self.end_token),108 )109 }110111 fn end_token(&self) -> usize {112 self.end_token113 }114}