1use std::{mem, num::NonZeroUsize};23use rowan::{GreenNodeBuilder, Language, TextRange, TextSize};45use crate::{6 lex::Lexeme,7 nodes::Trivia,8 parser::{LocatedSyntaxError, Parse, SyntaxError},9 AstToken, JsonnetLanguage, SyntaxKind,10};1112#[derive(Clone, Debug)]13pub enum Event {14 15 Pending,16 17 Start {18 kind: SyntaxKind,19 20 21 forward_parent: Option<NonZeroUsize>,22 },23 24 Token { kind: SyntaxKind },25 26 27 28 Finish {29 30 wrapper: Option<NonZeroUsize>,31 error: Option<Box<SyntaxError>>,32 },33 34 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<LocatedSyntaxError>,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 fn text_offset(&self) -> TextSize {57 if self.offset == 0 {58 return 0.into();59 };60 if let Some(lex) = self.lexemes.get(self.offset) {61 lex.range.start()62 } else if let Some(lex) = self.lexemes.get(self.offset - 1) {63 lex.range.end()64 } else {65 panic!("hard oob")66 }67 }6869 pub(super) fn finish(mut self) -> Parse {70 let mut eat_start_whitespace = false;71 let mut depth = 0;72 let mut error_starts_at = Vec::new();73 for idx in 0..self.events.len() {74 match mem::replace(&mut self.events[idx], Event::Noop) {75 Event::Start {76 kind,77 forward_parent,78 } => {79 if depth != 0 {80 self.skip_whitespace();81 }82 let mut kinds = vec![kind];8384 let mut idx = idx;85 let mut forward_parent = forward_parent;8687 88 89 90 while let Some(fp) = forward_parent {91 idx += fp.get();9293 forward_parent = if let Event::Start {94 kind,95 forward_parent,96 } = mem::replace(&mut self.events[idx], Event::Noop)97 {98 kinds.push(kind);99 forward_parent100 } else {101 unreachable!()102 };103 }104105 for kind in kinds.into_iter().rev() {106 self.builder.start_node(JsonnetLanguage::kind_to_raw(kind));107 depth += 1;108 if depth == 1 {109 self.skip_whitespace();110 }111 error_starts_at.push(self.text_offset());112 }113114 eat_start_whitespace = false;115 }116 Event::Token { kind } => {117 if eat_start_whitespace {118 self.skip_whitespace();119 }120 self.token(kind);121 eat_start_whitespace = true;122 }123 124 125 126 127 128 129 130 Event::Finish { wrapper, error } => {131 if depth == 1 {132 self.skip_whitespace();133 }134 let range = (135 error_starts_at.pop().expect("starts == finishes"),136 self.text_offset(),137 );138 if let Some(error) = error {139 self.errors.push(LocatedSyntaxError {140 error: *error,141 range: TextRange::new(range.0, range.1),142 })143 }144 self.builder.finish_node();145 depth -= 1;146 let mut idx = idx;147 let mut wrapper = wrapper;148 while let Some(w) = wrapper {149 idx += w.get();150 wrapper = if let Event::Finish { wrapper, error } =151 mem::replace(&mut self.events[idx], Event::Noop)152 {153 let range = (154 error_starts_at.pop().expect("starts == finishes"),155 self.text_offset(),156 );157 if let Some(error) = error {158 self.errors.push(LocatedSyntaxError {159 error: *error,160 range: TextRange::new(range.0, range.1),161 })162 }163164 if depth == 1 {165 self.skip_whitespace();166 }167 self.builder.finish_node();168 depth -= 1;169 wrapper170 } else {171 unreachable!()172 }173 }174 eat_start_whitespace = true;175 }176 Event::Pending => panic!("pending event should not appear in finished events"),177 Event::Noop => {}178 }179 }180181 Parse {182 green_node: self.builder.finish(),183 errors: self.errors,184 }185 }186 187 188 189 fn token(&mut self, kind: SyntaxKind) {190 let lexeme = self.lexemes[self.offset];191 self.builder192 .token(JsonnetLanguage::kind_to_raw(kind), lexeme.text);193 self.offset += 1;194 }195 fn skip_whitespace(&mut self) {196 while let Some(lexeme) = self.lexemes.get(self.offset) {197 if !Trivia::can_cast(lexeme.kind) {198 break;199 }200201 self.token(lexeme.kind);202 }203 }204}