git.delta.rocks / jrsonnet / refs/commits / ea44e4495023

difftreelog

source

crates/jrsonnet-rowan-parser/src/marker.rs4.3 KiBsourcehistory
1use std::num::NonZeroUsize;23use drop_bomb::DropBomb;45use crate::{6	event::Event,7	parser::{ExpectedSyntax, Parser, SyntaxError},8	SyntaxKind,9};1011// pub struct Ranger {12// 	pub pos: usize,13// }14// impl Ranger {15// 	pub fn finish(self, p: &Parser) -> FinishedRanger {16// 		FinishedRanger {17// 			start_token: self.pos,18// 			end_token: self.pos.max(p.offset.saturating_sub(1)),19// 		}20// 	}21// }2223pub 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		// TODO: is_lexer should return true if enum variant has #[regex]/#[token] over it, or it is defined as lexer error explicitly59		// debug_assert!(60		// 	!kind.is_lexer(),61		// 	"{kind:?} should be only emitted by lexer, not used directly"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	/// Create new node around existing marker, not counting anything that comes after it144	fn wrap_raw(self, p: &mut Parser, kind: SyntaxKind, error: Option<SyntaxError>) -> Self {145		let new_m = p.start();146		match &mut p.events[self.start_event_idx] {147			Event::Start { forward_parent, .. } => {148				*forward_parent = Some(149					NonZeroUsize::new(new_m.start_event_idx - self.start_event_idx).expect("!= 0"),150				);151			}152			_ => unreachable!(),153		}154155		let completed = new_m.complete_raw(p, kind, error);156157		match &mut p.events[self.finish_event_idx] {158			Event::Finish {159				wrapper,160				error: _error,161			} => {162				*wrapper = Some(163					NonZeroUsize::new(completed.finish_event_idx - self.finish_event_idx)164						.expect("!= 0"),165				);166			}167			_ => unreachable!(),168		}169		completed170	}171	pub fn wrap(self, p: &mut Parser, kind: SyntaxKind) -> Self {172		self.wrap_raw(p, kind, None)173	}174	pub fn wrap_error(self, p: &mut Parser, msg: impl AsRef<str>) -> Self {175		self.wrap_raw(176			p,177			SyntaxKind::ERROR_CUSTOM,178			Some(SyntaxError::Custom {179				error: msg.as_ref().to_owned(),180			}),181		)182	}183}