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 15 Pending,16 17 Start {18 kind: SyntaxKind,19 20 21 forward_parent: Option<usize>,22 },23 24 Token {25 kind: SyntaxKind,26 },27 28 VirtualToken {29 kind: SyntaxKind,30 },31 32 Finish {33 34 wrapper: Option<usize>,35 },36 Error(SyntaxError),37 38 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 78 79 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 self.builder.finish_node();121 depth -= 1;122 let mut idx = idx;123 let mut wrapper = wrapper;124 while let Some(w) = wrapper {125 idx += w;126 wrapper = if let Event::Finish { wrapper } =127 mem::replace(&mut self.events[idx], Event::Noop)128 {129 self.builder.finish_node();130 depth -= 1;131 wrapper132 } else {133 unreachable!()134 }135 }136 eat_start_whitespace = true;137 }138 Event::Pending => panic!("pending event should not appear in finished events"),139 Event::Noop => {}140 Event::Error(e) => {141 self.errors.push(e);142 }143 }144 }145146 Parse {147 green_node: self.builder.finish(),148 errors: self.errors,149 }150 }151 fn virtual_token(&mut self, kind: SyntaxKind) {152 self.builder.token(JsonnetLanguage::kind_to_raw(kind), "")153 }154 fn token(&mut self, kind: SyntaxKind) {155 let lexeme = self.lexemes[self.offset];156 self.builder157 .token(JsonnetLanguage::kind_to_raw(kind), lexeme.text);158 self.offset += 1;159 }160 fn skip_whitespace(&mut self) {161 while let Some(lexeme) = self.lexemes.get(self.offset) {162 if !Trivia::can_cast(lexeme.kind) {163 break;164 }165166 self.token(lexeme.kind);167 }168 }169}