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

difftreelog

source

crates/jrsonnet-rowan-parser/src/event.rs3.5 KiBsourcehistory
1use std::mem;23use rowan::{GreenNodeBuilder, Language};45use crate::{6	lex::Lexeme,7	nodes::Trivia,8	parser::{Parse, SyntaxError},9	AstToken, JsonnetLanguage, SyntaxKind,10};1112#[derive(Clone, Debug, PartialEq, Eq)]13pub enum Event {14	/// Used for unfinished markers15	Pending,16	/// After marker is completed, Pending event is replaced with Start17	Start {18		kind: SyntaxKind,19		/// If marker is preceded or wrapped - instead of reordering events, we20		/// insert start event in the end of events Vec instead, and store relative offset to this event here21		forward_parent: Option<usize>,22	},23	/// Eat token24	Token {25		kind: SyntaxKind,26	},27	/// Position of finished node28	Finish {29		/// Same as forward_parent of Start, but for wrapping30		wrapper: Option<usize>,31	},32	Error(SyntaxError),33	/// Used for dropped markers and other things34	Noop,35}3637pub(super) struct Sink<'i> {38	pub builder: GreenNodeBuilder<'static>,39	lexemes: &'i [Lexeme<'i>],40	offset: usize,41	events: Vec<Event>,42	pub errors: Vec<SyntaxError>,43}4445impl<'i> Sink<'i> {46	pub(super) fn new(events: Vec<Event>, lexemes: &'i [Lexeme<'i>]) -> Self {47		Self {48			builder: GreenNodeBuilder::new(),49			lexemes,50			offset: 0,51			events,52			errors: vec![],53		}54	}5556	pub(super) fn finish(mut self) -> Parse {57		let mut eat_start_whitespace = false;58		let mut depth = 0;59		for idx in 0..self.events.len() {60			match mem::replace(&mut self.events[idx], Event::Noop) {61				Event::Start {62					kind,63					forward_parent,64				} => {65					if depth != 0 {66						self.skip_whitespace();67					}68					let mut kinds = vec![kind];6970					let mut idx = idx;71					let mut forward_parent = forward_parent;7273					// Walk through the forward parent of the forward parent, and the forward parent74					// of that, and of that, etc. until we reach a StartNode event without a forward75					// parent.76					while let Some(fp) = forward_parent {77						idx += fp;7879						forward_parent = if let Event::Start {80							kind,81							forward_parent,82						} = mem::replace(&mut self.events[idx], Event::Noop)83						{84							kinds.push(kind);85							forward_parent86						} else {87							unreachable!()88						};89					}9091					for kind in kinds.into_iter().rev() {92						self.builder.start_node(JsonnetLanguage::kind_to_raw(kind));93						depth += 1;94						if depth == 1 {95							self.skip_whitespace();96						}97					}9899					eat_start_whitespace = false;100				}101				Event::Token { kind } => {102					if eat_start_whitespace {103						self.skip_whitespace();104					}105					self.token(kind);106					eat_start_whitespace = true;107				}108				Event::Finish { wrapper } => {109					self.builder.finish_node();110					depth -= 1;111					let mut idx = idx;112					let mut wrapper = wrapper;113					while let Some(w) = wrapper {114						idx += w;115						wrapper = if let Event::Finish { wrapper } =116							mem::replace(&mut self.events[idx], Event::Noop)117						{118							self.builder.finish_node();119							depth -= 1;120							wrapper121						} else {122							unreachable!()123						}124					}125					eat_start_whitespace = true;126				}127				Event::Pending => panic!("placeholder should not end in events"),128				Event::Noop => {}129				Event::Error(e) => {130					self.errors.push(e);131				}132			}133		}134135		Parse {136			green_node: self.builder.finish(),137			errors: self.errors,138		}139	}140	fn token(&mut self, kind: SyntaxKind) {141		let lexeme = self.lexemes[self.offset];142		self.builder143			.token(JsonnetLanguage::kind_to_raw(kind), lexeme.text);144		self.offset += 1;145	}146	fn skip_whitespace(&mut self) {147		while let Some(lexeme) = self.lexemes.get(self.offset) {148			if !Trivia::can_cast(lexeme.kind) {149				break;150			}151152			self.token(lexeme.kind);153		}154	}155}