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

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(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}