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

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	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		// TODO: is_lexer should return true if enum variant has #[regex]/#[token] over it, or it is defined as lexer error explicitly58		// debug_assert!(59		// 	!kind.is_lexer(),60		// 	"{kind:?} should be only emitted by lexer, not used directly"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	/// Create new node around existing marker, not counting anything that comes after it143	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}