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 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}