From f078f7adc8ac0ffae07462d736083807c98c0483 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sat, 23 Feb 2019 16:55:01 +0300 Subject: introduce tree builder --- crates/ra_syntax/src/syntax_node.rs | 51 ++++++++++++++++++++++++++++++++++--- 1 file changed, 48 insertions(+), 3 deletions(-) (limited to 'crates/ra_syntax/src/syntax_node.rs') diff --git a/crates/ra_syntax/src/syntax_node.rs b/crates/ra_syntax/src/syntax_node.rs index 4d54ae614..e5b4cdb11 100644 --- a/crates/ra_syntax/src/syntax_node.rs +++ b/crates/ra_syntax/src/syntax_node.rs @@ -11,11 +11,12 @@ use std::{ borrow::Borrow, }; -use rowan::{Types, TransparentNewType}; +use ra_parser::ParseError; +use rowan::{Types, TransparentNewType, GreenNodeBuilder}; use crate::{ - SmolStr, SyntaxKind, TextRange, SyntaxText, SourceFile, AstNode, - syntax_error::SyntaxError, + SmolStr, SyntaxKind, TextUnit, TextRange, SyntaxText, SourceFile, AstNode, + syntax_error::{SyntaxError, SyntaxErrorKind}, }; pub use rowan::WalkEvent; @@ -276,3 +277,47 @@ fn has_short_text(kind: SyntaxKind) -> bool { _ => false, } } + +pub struct SyntaxTreeBuilder { + errors: Vec, + inner: GreenNodeBuilder, +} + +impl Default for SyntaxTreeBuilder { + fn default() -> SyntaxTreeBuilder { + SyntaxTreeBuilder { errors: Vec::new(), inner: GreenNodeBuilder::new() } + } +} + +impl SyntaxTreeBuilder { + pub(crate) fn finish_raw(self) -> (GreenNode, Vec) { + let green = self.inner.finish(); + (green, self.errors) + } + + pub fn finish(self) -> TreeArc { + let (green, errors) = self.finish_raw(); + let node = SyntaxNode::new(green, errors); + if cfg!(debug_assertions) { + crate::validation::validate_block_structure(&node); + } + node + } + + pub fn leaf(&mut self, kind: SyntaxKind, text: SmolStr) { + self.inner.leaf(kind, text) + } + + pub fn start_branch(&mut self, kind: SyntaxKind) { + self.inner.start_internal(kind) + } + + pub fn finish_branch(&mut self) { + self.inner.finish_internal() + } + + pub fn error(&mut self, error: ParseError, text_pos: TextUnit) { + let error = SyntaxError::new(SyntaxErrorKind::ParseError(error), text_pos); + self.errors.push(error) + } +} -- cgit v1.2.3