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

difftreelog

source

crates/jrsonnet-rowan-parser/src/event.rs4.0 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	/// Push token, but do not eat anything,28	VirtualToken {29		kind: SyntaxKind,30	},31	/// Position of finished node32	Finish {33		/// Same as forward_parent of Start, but for wrapping34		wrapper: Option<usize>,35	},36	Error(SyntaxError),37	/// Used for dropped markers and other things38	Noop,39}4041pub(super) struct Sink<'i> {42	pub builder: GreenNodeBuilder<'static>,43	lexemes: &'i [Lexeme<'i>],44	offset: usize,45	events: Vec<Event>,46	pub errors: Vec<SyntaxError>,47}4849impl<'i> Sink<'i> {50	pub(super) fn new(events: Vec<Event>, lexemes: &'i [Lexeme<'i>]) -> Self {51		Self {52			builder: GreenNodeBuilder::new(),53			lexemes,54			offset: 0,55			events,56			errors: vec![],57		}58	}5960	pub(super) fn finish(mut self) -> Parse {61		let mut eat_start_whitespace = false;62		let mut depth = 0;63		for idx in 0..self.events.len() {64			match mem::replace(&mut self.events[idx], Event::Noop) {65				Event::Start {66					kind,67					forward_parent,68				} => {69					if depth != 0 {70						self.skip_whitespace();71					}72					let mut kinds = vec![kind];7374					let mut idx = idx;75					let mut forward_parent = forward_parent;7677					// Walk through the forward parent of the forward parent, and the forward parent78					// of that, and of that, etc. until we reach a StartNode event without a forward79					// parent.80					while let Some(fp) = forward_parent {81						idx += fp;8283						forward_parent = if let Event::Start {84							kind,85							forward_parent,86						} = mem::replace(&mut self.events[idx], Event::Noop)87						{88							kinds.push(kind);89							forward_parent90						} else {91							unreachable!()92						};93					}9495					for kind in kinds.into_iter().rev() {96						self.builder.start_node(JsonnetLanguage::kind_to_raw(kind));97						depth += 1;98						if depth == 1 {99							self.skip_whitespace();100						}101					}102103					eat_start_whitespace = false;104				}105				Event::Token { kind } => {106					if eat_start_whitespace {107						self.skip_whitespace();108					}109					self.token(kind);110					eat_start_whitespace = true;111				}112				Event::VirtualToken { kind } => {113					if eat_start_whitespace {114						self.skip_whitespace();115					}116					self.virtual_token(kind);117					eat_start_whitespace = false;118				}119				Event::Finish { wrapper } => {120					if depth == 1 {121						self.skip_whitespace();122					}123					self.builder.finish_node();124					depth -= 1;125					let mut idx = idx;126					let mut wrapper = wrapper;127					while let Some(w) = wrapper {128						idx += w;129						wrapper = if let Event::Finish { wrapper } =130							mem::replace(&mut self.events[idx], Event::Noop)131						{132							if depth == 1 {133								self.skip_whitespace();134							}135							self.builder.finish_node();136							depth -= 1;137							wrapper138						} else {139							unreachable!()140						}141					}142					eat_start_whitespace = true;143				}144				Event::Pending => panic!("pending event should not appear in finished events"),145				Event::Noop => {}146				Event::Error(e) => {147					self.errors.push(e);148				}149			}150		}151152		Parse {153			green_node: self.builder.finish(),154			errors: self.errors,155		}156	}157	fn virtual_token(&mut self, kind: SyntaxKind) {158		self.builder.token(JsonnetLanguage::kind_to_raw(kind), "")159	}160	fn token(&mut self, kind: SyntaxKind) {161		let lexeme = self.lexemes[self.offset];162		self.builder163			.token(JsonnetLanguage::kind_to_raw(kind), lexeme.text);164		self.offset += 1;165	}166	fn skip_whitespace(&mut self) {167		while let Some(lexeme) = self.lexemes.get(self.offset) {168			if !Trivia::can_cast(lexeme.kind) {169				break;170			}171172			self.token(lexeme.kind);173		}174	}175}