Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/syntax/src/parsing/text_tree_sink.rs')
-rw-r--r--crates/syntax/src/parsing/text_tree_sink.rs44
1 files changed, 32 insertions, 12 deletions
diff --git a/crates/syntax/src/parsing/text_tree_sink.rs b/crates/syntax/src/parsing/text_tree_sink.rs
index c9e7feb965..c435791746 100644
--- a/crates/syntax/src/parsing/text_tree_sink.rs
+++ b/crates/syntax/src/parsing/text_tree_sink.rs
@@ -2,7 +2,7 @@
use std::mem;
-use parser::{LexedStr, ParseError, TreeSink};
+use parser::{LexedStr, TreeTraversal};
use crate::{
ast,
@@ -12,6 +12,36 @@ use crate::{
SyntaxTreeBuilder, TextRange,
};
+pub(crate) fn build_tree(
+ lexed: LexedStr<'_>,
+ tree_traversal: TreeTraversal,
+ synthetic_root: bool,
+) -> (GreenNode, Vec<SyntaxError>, bool) {
+ let mut builder = TextTreeSink::new(lexed);
+
+ if synthetic_root {
+ builder.start_node(SyntaxKind::SOURCE_FILE);
+ }
+
+ for event in tree_traversal.iter() {
+ match event {
+ parser::TraversalStep::Token { kind, n_raw_tokens } => {
+ builder.token(kind, n_raw_tokens)
+ }
+ parser::TraversalStep::EnterNode { kind } => builder.start_node(kind),
+ parser::TraversalStep::LeaveNode => builder.finish_node(),
+ parser::TraversalStep::Error { msg } => {
+ let text_pos = builder.lexed.text_start(builder.pos).try_into().unwrap();
+ builder.inner.error(msg.to_string(), text_pos);
+ }
+ }
+ }
+ if synthetic_root {
+ builder.finish_node()
+ }
+ builder.finish_eof()
+}
+
/// Bridges the parser with our specific syntax tree representation.
///
/// `TextTreeSink` also handles attachment of trivia (whitespace) to nodes.
@@ -28,7 +58,7 @@ enum State {
PendingFinish,
}
-impl<'a> TreeSink for TextTreeSink<'a> {
+impl<'a> TextTreeSink<'a> {
fn token(&mut self, kind: SyntaxKind, n_tokens: u8) {
match mem::replace(&mut self.state, State::Normal) {
State::PendingStart => unreachable!(),
@@ -70,11 +100,6 @@ impl<'a> TreeSink for TextTreeSink<'a> {
State::Normal => (),
}
}
-
- fn error(&mut self, error: ParseError) {
- let text_pos = self.lexed.text_start(self.pos).try_into().unwrap();
- self.inner.error(error, text_pos);
- }
}
impl<'a> TextTreeSink<'a> {
@@ -106,11 +131,6 @@ impl<'a> TextTreeSink<'a> {
(node, errors, is_eof)
}
- pub(super) fn finish(self) -> (GreenNode, Vec<SyntaxError>) {
- let (node, errors, _eof) = self.finish_eof();
- (node, errors)
- }
-
fn eat_trivias(&mut self) {
while self.pos < self.lexed.len() {
let kind = self.lexed.kind(self.pos);