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

difftreelog

source

crates/jrsonnet-rowan-parser/src/marker.rs2.8 KiBsourcehistory
1use drop_bomb::DropBomb;2use rowan::TextRange;34use crate::{event::Event, parser::Parser, SyntaxKind};56pub struct Ranger {7	pub pos: usize,8}9impl Ranger {10	pub fn finish(self, p: &Parser) -> FinishedRanger {11		FinishedRanger {12			start_token: self.pos,13			end_token: self.pos.max(p.offset.saturating_sub(1)),14		}15	}16}1718pub struct FinishedRanger {19	pub start_token: usize,20	pub end_token: usize,21}22impl FinishedRanger {23	#[allow(dead_code)]24	pub fn had_error_since(&self, p: &Parser) -> bool {25		p.last_error_token >= self.start_token26	}27}2829#[must_use]30pub struct Marker {31	pub start_event_idx: usize,32	bomb: DropBomb,33}34impl Marker {35	pub fn new(pos: usize) -> Self {36		Self {37			start_event_idx: pos,38			bomb: DropBomb::new("marked dropped while not completed"),39		}40	}41	pub fn complete(mut self, p: &mut Parser, kind: SyntaxKind) -> CompletedMarker {42		self.bomb.defuse();43		assert!(44			!kind.is_enum(),45			"{kind:?} is a enum kind, you should use variant kinds instead"46		);47		// TODO: is_lexer should return true if enum variant has #[regex]/#[token] over it, or it is defined as lexer error explicitly48		// debug_assert!(49		// 	!kind.is_lexer(),50		// 	"{kind:?} should be only emitted by lexer, not used directly"51		// );52		let event_at_pos = &mut p.events[self.start_event_idx];53		assert_eq!(*event_at_pos, Event::Pending);5455		*event_at_pos = Event::Start {56			kind,57			forward_parent: None,58		};5960		let finish_event_idx = p.events.len();61		p.events.push(Event::Finish { wrapper: None });62		p.entered -= 1;63		p.clear_outdated_hints();64		CompletedMarker {65			start_event_idx: self.start_event_idx,66			finish_event_idx,67		}68	}69	pub fn forget(mut self, p: &mut Parser) {70		self.bomb.defuse();71		let event_at_pos = &mut p.events[self.start_event_idx];72		assert_eq!(*event_at_pos, Event::Pending);7374		*event_at_pos = Event::Noop;75		p.entered -= 1;76		p.clear_outdated_hints();77	}78}79pub struct CompletedMarker {80	start_event_idx: usize,81	finish_event_idx: usize,82}83impl CompletedMarker {84	pub(super) fn precede(self, p: &mut Parser) -> Marker {85		let new_m = p.start();86		match &mut p.events[self.start_event_idx] {87			Event::Start { forward_parent, .. } => {88				*forward_parent = Some(new_m.start_event_idx - self.start_event_idx);89			}90			_ => unreachable!(),91		}9293		new_m94	}95	/// Create new node around existing marker, not counting anything that comes after it96	pub fn wrap(self, p: &mut Parser, kind: SyntaxKind) -> CompletedMarker {97		let new_m = p.start();98		match &mut p.events[self.start_event_idx] {99			Event::Start { forward_parent, .. } => {100				*forward_parent = Some(new_m.start_event_idx - self.start_event_idx);101			}102			_ => unreachable!(),103		}104105		let completed = new_m.complete(p, kind);106107		match &mut p.events[self.finish_event_idx] {108			Event::Finish { wrapper } => {109				*wrapper = Some(completed.finish_event_idx - self.finish_event_idx);110			}111			_ => unreachable!(),112		}113		completed114	}115}