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