1use std::num::NonZeroUsize;23use drop_bomb::DropBomb;45use crate::{6 event::Event,7 parser::{ExpectedSyntax, Parser, SyntaxError},8 SyntaxKind,9};1011121314151617181920212223pub struct FinishedRanger {24 pub start_token: usize,25 #[allow(dead_code)]26 pub end_token: usize,27}28impl FinishedRanger {29 #[allow(dead_code)]30 pub fn had_error_since(&self, p: &Parser) -> bool {31 p.last_error_token >= self.start_token32 }33}3435#[must_use]36pub struct Marker {37 pub start_event_idx: usize,38 bomb: DropBomb,39}40impl Marker {41 pub fn new(pos: usize) -> Self {42 Self {43 start_event_idx: pos,44 bomb: DropBomb::new("marked dropped while not completed"),45 }46 }47 fn complete_raw(48 mut self,49 p: &mut Parser,50 kind: SyntaxKind,51 error: Option<SyntaxError>,52 ) -> CompletedMarker {53 self.bomb.defuse();54 assert!(55 !kind.is_enum(),56 "{kind:?} is a enum kind, you should use variant kinds instead"57 );58 59 60 61 62 63 let event_at_pos = &mut p.events[self.start_event_idx];64 assert!(matches!(event_at_pos, Event::Pending));6566 *event_at_pos = Event::Start {67 kind,68 forward_parent: None,69 };7071 let finish_event_idx = p.events.len();72 p.events.push(Event::Finish {73 wrapper: None,74 error: error.map(Box::new),75 });76 p.entered -= 1;77 p.clear_outdated_hints();78 CompletedMarker {79 start_event_idx: self.start_event_idx,80 finish_event_idx,81 }82 }83 pub fn complete(self, p: &mut Parser, kind: SyntaxKind) -> CompletedMarker {84 self.complete_raw(p, kind, None)85 }86 pub fn complete_error(self, p: &mut Parser, msg: impl AsRef<str>) -> CompletedMarker {87 self.complete_raw(88 p,89 SyntaxKind::ERROR_CUSTOM,90 Some(SyntaxError::Custom {91 error: msg.as_ref().to_owned(),92 }),93 )94 }95 pub fn complete_missing(self, p: &mut Parser, expected: ExpectedSyntax) -> CompletedMarker {96 self.complete_raw(97 p,98 SyntaxKind::ERROR_MISSING_TOKEN,99 Some(SyntaxError::Missing { expected }),100 )101 }102 pub fn complete_unexpected(103 self,104 p: &mut Parser,105 expected: ExpectedSyntax,106 found: SyntaxKind,107 ) -> CompletedMarker {108 self.complete_raw(109 p,110 SyntaxKind::ERROR_UNEXPECTED_TOKEN,111 Some(SyntaxError::Unexpected { expected, found }),112 )113 }114115 pub fn forget(mut self, p: &mut Parser) {116 self.bomb.defuse();117 let event_at_pos = &mut p.events[self.start_event_idx];118 assert!(matches!(event_at_pos, Event::Pending));119120 *event_at_pos = Event::Noop;121 p.entered -= 1;122 p.clear_outdated_hints();123 }124}125pub struct CompletedMarker {126 start_event_idx: usize,127 finish_event_idx: usize,128}129impl CompletedMarker {130 pub(super) fn precede(self, p: &mut Parser) -> Marker {131 let new_m = p.start();132 match &mut p.events[self.start_event_idx] {133 Event::Start { forward_parent, .. } => {134 *forward_parent = Some(135 NonZeroUsize::new(new_m.start_event_idx - self.start_event_idx).expect("!= 0"),136 );137 }138 _ => unreachable!(),139 }140141 new_m142 }143 144 fn wrap_raw(145 self,146 p: &mut Parser,147 kind: SyntaxKind,148 error: Option<SyntaxError>,149 ) -> CompletedMarker {150 let new_m = p.start();151 match &mut p.events[self.start_event_idx] {152 Event::Start { forward_parent, .. } => {153 *forward_parent = Some(154 NonZeroUsize::new(new_m.start_event_idx - self.start_event_idx).expect("!= 0"),155 );156 }157 _ => unreachable!(),158 }159160 let completed = new_m.complete_raw(p, kind, error);161162 match &mut p.events[self.finish_event_idx] {163 Event::Finish {164 wrapper,165 error: _error,166 } => {167 *wrapper = Some(168 NonZeroUsize::new(completed.finish_event_idx - self.finish_event_idx)169 .expect("!= 0"),170 );171 }172 _ => unreachable!(),173 }174 completed175 }176 pub fn wrap(self, p: &mut Parser, kind: SyntaxKind) -> CompletedMarker {177 self.wrap_raw(p, kind, None)178 }179 pub fn wrap_error(self, p: &mut Parser, msg: impl AsRef<str>) -> CompletedMarker {180 self.wrap_raw(181 p,182 SyntaxKind::ERROR_CUSTOM,183 Some(SyntaxError::Custom {184 error: msg.as_ref().to_owned(),185 }),186 )187 }188}