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

difftreelog

source

crates/jrsonnet-rowan-parser/src/event.rs3.5 KiBsourcehistory
1use std::mem;23use rowan::{GreenNodeBuilder, Language};45use crate::{6	lex::Lexeme,7	parser::{Parse, SyntaxError},8	JsonnetLanguage, SyntaxKind,9};1011#[derive(Clone, Debug, PartialEq, Eq)]12pub enum Event {13	/// Used for unfinished markers14	Pending,15	/// After marker is completed, Pending event is replaced with Start16	Start {17		kind: SyntaxKind,18		/// If marker is preceded or wrapped - instead of reordering events, we19		/// insert start event in the end of events Vec instead, and store relative offset to this event here20		forward_parent: Option<usize>,21	},22	/// Eat token23	Token {24		kind: SyntaxKind,25	},26	/// Position of finished node27	Finish {28		/// Same as forward_parent of Start, but for wrapping29		wrapper: Option<usize>,30	},31	Error(SyntaxError),32	/// Used for dropped markers and other things33	Noop,34}3536pub(super) struct Sink<'i> {37	pub builder: GreenNodeBuilder<'static>,38	lexemes: &'i [Lexeme<'i>],39	offset: usize,40	events: Vec<Event>,41	pub errors: Vec<SyntaxError>,42}4344impl<'i> Sink<'i> {45	pub(super) fn new(events: Vec<Event>, lexemes: &'i [Lexeme<'i>]) -> Self {46		Self {47			builder: GreenNodeBuilder::new(),48			lexemes,49			offset: 0,50			events,51			errors: vec![],52		}53	}5455	pub(super) fn finish(mut self) -> Parse {56		let mut eat_start_whitespace = false;57		let mut depth = 0;58		for idx in 0..self.events.len() {59			match mem::replace(&mut self.events[idx], Event::Noop) {60				Event::Start {61					kind,62					forward_parent,63				} => {64					if depth != 0 {65						self.skip_whitespace();66					}67					let mut kinds = vec![kind];6869					let mut idx = idx;70					let mut forward_parent = forward_parent;7172					// Walk through the forward parent of the forward parent, and the forward parent73					// of that, and of that, etc. until we reach a StartNode event without a forward74					// parent.75					while let Some(fp) = forward_parent {76						idx += fp;7778						forward_parent = if let Event::Start {79							kind,80							forward_parent,81						} = mem::replace(&mut self.events[idx], Event::Noop)82						{83							kinds.push(kind);84							forward_parent85						} else {86							unreachable!()87						};88					}8990					for kind in kinds.into_iter().rev() {91						self.builder.start_node(JsonnetLanguage::kind_to_raw(kind));92						depth += 1;93						if depth == 1 {94							self.skip_whitespace();95						}96					}9798					eat_start_whitespace = false;99				}100				Event::Token { kind } => {101					if eat_start_whitespace {102						self.skip_whitespace();103					}104					self.token(kind);105					eat_start_whitespace = true;106				}107				Event::Finish { wrapper } => {108					self.builder.finish_node();109					depth -= 1;110					let mut idx = idx;111					let mut wrapper = wrapper;112					while let Some(w) = wrapper {113						idx += w;114						wrapper = if let Event::Finish { wrapper } =115							mem::replace(&mut self.events[idx], Event::Noop)116						{117							self.builder.finish_node();118							depth -= 1;119							wrapper120						} else {121							unreachable!()122						}123					}124					eat_start_whitespace = true;125				}126				Event::Pending => panic!("placeholder should not end in events"),127				Event::Noop => {}128				Event::Error(e) => {129					self.errors.push(e);130				}131			}132		}133134		Parse {135			green_node: self.builder.finish(),136			errors: self.errors,137		}138	}139	fn token(&mut self, kind: SyntaxKind) {140		let lexeme = self.lexemes[self.offset];141		self.builder142			.token(JsonnetLanguage::kind_to_raw(kind), lexeme.text);143		self.offset += 1;144	}145	fn skip_whitespace(&mut self) {146		while let Some(lexeme) = self.lexemes.get(self.offset) {147			if !lexeme.kind.is_trivia() {148				break;149			}150151			self.token(lexeme.kind);152		}153	}154}