1use std::num::NonZeroUsize;23use drop_bomb::DropBomb;45use crate::{6 SyntaxKind,7 event::Event,8 parser::{ExpectedSyntax, Parser, SyntaxError},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 145 fn wrap_raw(146 self,147 p: &mut Parser,148 kind: SyntaxKind,149 error: Option<SyntaxError>,150 previous_pos: bool,151 ) -> Self {152 let new_m = p.start();153 match &mut p.events[self.start_event_idx] {154 Event::Start { forward_parent, .. } => {155 *forward_parent = Some(156 NonZeroUsize::new(new_m.start_event_idx - self.start_event_idx).expect("!= 0"),157 );158 }159 _ => unreachable!(),160 }161162 let completed = new_m.complete_raw(p, kind, error);163164 if previous_pos {165 match &mut p.events[self.finish_event_idx] {166 Event::Finish {167 wrapper,168 error: _error,169 } => {170 *wrapper = Some(171 NonZeroUsize::new(completed.finish_event_idx - self.finish_event_idx)172 .expect("!= 0"),173 );174 }175 _ => unreachable!(),176 }177 }178 completed179 }180 pub fn wrap(self, p: &mut Parser, kind: SyntaxKind, previous_pos: bool) -> Self {181 self.wrap_raw(p, kind, None, previous_pos)182 }183 pub fn wrap_error(self, p: &mut Parser, msg: impl AsRef<str>, previous_pos: bool) -> Self {184 self.wrap_raw(185 p,186 SyntaxKind::ERROR_CUSTOM,187 Some(SyntaxError::Custom {188 error: msg.as_ref().to_owned(),189 }),190 previous_pos,191 )192 }193}