git.delta.rocks / jrsonnet / refs/heads / master

difftreelog

source

crates/jrsonnet-rowan-parser/src/marker.rs4.6 KiBsourcehistory
1use std::num::NonZeroUsize;23use drop_bomb::DropBomb;45use crate::{6	SyntaxKind,7	event::Event,8	parser::{ExpectedSyntax, Parser, SyntaxError},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 marker144	/// If `previous_pos` is set - the wrapping node would not include everything that happened between wrapped node end and the current position of the parser145	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}