git.delta.rocks / jrsonnet / refs/commits / 5382799864e9

difftreelog

source

crates/jrsonnet-rowan-parser/src/event.rs2.2 KiBsourcehistory
1use std::mem;23use rowan::{GreenNode, GreenNodeBuilder, Language};45use crate::{6	lex::{Lang, Lexeme, SyntaxKind},7	parser::{Parse, SyntaxError},8};910#[derive(Clone, Debug, PartialEq, Eq)]11pub enum Event {12	Start {13		kind: SyntaxKind,14		forward_parent: Option<usize>,15	},16	Token,17	Finish,18	Placeholder,19	Error(SyntaxError),20}2122pub(super) struct Sink<'i> {23	pub builder: GreenNodeBuilder<'static>,24	lexemes: &'i [Lexeme<'i>],25	offset: usize,26	events: Vec<Event>,27	pub errors: Vec<SyntaxError>,28}2930impl<'i> Sink<'i> {31	pub(super) fn new(events: Vec<Event>, lexemes: &'i [Lexeme<'i>]) -> Self {32		Self {33			builder: GreenNodeBuilder::new(),34			lexemes,35			offset: 0,36			events,37			errors: vec![],38		}39	}4041	pub(super) fn finish(mut self) -> Parse {42		for idx in 0..self.events.len() {43			match mem::replace(&mut self.events[idx], Event::Placeholder) {44				Event::Start {45					kind,46					forward_parent,47				} => {48					let mut kinds = vec![kind];4950					let mut idx = idx;51					let mut forward_parent = forward_parent;5253					// Walk through the forward parent of the forward parent, and the forward parent54					// of that, and of that, etc. until we reach a StartNode event without a forward55					// parent.56					while let Some(fp) = forward_parent {57						idx += fp;5859						forward_parent = if let Event::Start {60							kind,61							forward_parent,62						} = mem::replace(&mut self.events[idx], Event::Placeholder)63						{64							kinds.push(kind);65							forward_parent66						} else {67							unreachable!()68						};69					}7071					for kind in kinds.into_iter().rev() {72						self.builder.start_node(Lang::kind_to_raw(kind));73					}74				}75				Event::Token => self.token(),76				Event::Finish => {77					self.builder.finish_node();78				}79				Event::Placeholder => {}80				Event::Error(e) => {81					self.errors.push(e);82				}83			}84			self.skip_whitespace();85		}8687		Parse {88			green_node: self.builder.finish(),89			errors: self.errors,90		}91	}92	fn token(&mut self) {93		let lexeme = self.lexemes[self.offset];94		self.builder95			.token(Lang::kind_to_raw(lexeme.kind), lexeme.text);96		self.offset += 1;97	}98	fn skip_whitespace(&mut self) {99		while let Some(lexeme) = self.lexemes.get(self.offset) {100			if !lexeme.kind.is_trivia() {101				break;102			}103104			self.token();105		}106	}107}