diff options
| author | Aleksey Kladov <aleksey.kladov@gmail.com> | 2020-08-12 18:26:51 +0200 |
|---|---|---|
| committer | Aleksey Kladov <aleksey.kladov@gmail.com> | 2020-08-12 18:30:53 +0200 |
| commit | a1c187eef3ba08076aedb5154929f7eda8d1b424 (patch) | |
| tree | 9d898eb9600b0c36a74e4f95238f679c683fa566 /crates/syntax/src/syntax_node.rs | |
| parent | 3d6889cba72a9d02199f7adaa2ecc69bc30af834 (diff) | |
| download | rust-a1c187eef3ba08076aedb5154929f7eda8d1b424.tar.gz rust-a1c187eef3ba08076aedb5154929f7eda8d1b424.zip | |
Rename ra_syntax -> syntax
Diffstat (limited to 'crates/syntax/src/syntax_node.rs')
| -rw-r--r-- | crates/syntax/src/syntax_node.rs | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/crates/syntax/src/syntax_node.rs b/crates/syntax/src/syntax_node.rs new file mode 100644 index 00000000000..b2abcbfbb36 --- /dev/null +++ b/crates/syntax/src/syntax_node.rs @@ -0,0 +1,77 @@ +//! This module defines Concrete Syntax Tree (CST), used by rust-analyzer. +//! +//! The CST includes comments and whitespace, provides a single node type, +//! `SyntaxNode`, and a basic traversal API (parent, children, siblings). +//! +//! The *real* implementation is in the (language-agnostic) `rowan` crate, this +//! module just wraps its API. + +use rowan::{GreenNodeBuilder, Language}; + +use crate::{Parse, SmolStr, SyntaxError, SyntaxKind, TextSize}; + +pub use rowan::GreenNode; + +pub(crate) use rowan::GreenToken; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub enum RustLanguage {} +impl Language for RustLanguage { + type Kind = SyntaxKind; + + fn kind_from_raw(raw: rowan::SyntaxKind) -> SyntaxKind { + SyntaxKind::from(raw.0) + } + + fn kind_to_raw(kind: SyntaxKind) -> rowan::SyntaxKind { + rowan::SyntaxKind(kind.into()) + } +} + +pub type SyntaxNode = rowan::SyntaxNode<RustLanguage>; +pub type SyntaxToken = rowan::SyntaxToken<RustLanguage>; +pub type SyntaxElement = rowan::SyntaxElement<RustLanguage>; +pub type SyntaxNodeChildren = rowan::SyntaxNodeChildren<RustLanguage>; +pub type SyntaxElementChildren = rowan::SyntaxElementChildren<RustLanguage>; + +pub use rowan::{Direction, NodeOrToken}; + +#[derive(Default)] +pub struct SyntaxTreeBuilder { + errors: Vec<SyntaxError>, + inner: GreenNodeBuilder<'static>, +} + +impl SyntaxTreeBuilder { + pub(crate) fn finish_raw(self) -> (GreenNode, Vec<SyntaxError>) { + let green = self.inner.finish(); + (green, self.errors) + } + + pub fn finish(self) -> Parse<SyntaxNode> { + let (green, errors) = self.finish_raw(); + if cfg!(debug_assertions) { + let node = SyntaxNode::new_root(green.clone()); + crate::validation::validate_block_structure(&node); + } + Parse::new(green, errors) + } + + pub fn token(&mut self, kind: SyntaxKind, text: SmolStr) { + let kind = RustLanguage::kind_to_raw(kind); + self.inner.token(kind, text) + } + + pub fn start_node(&mut self, kind: SyntaxKind) { + let kind = RustLanguage::kind_to_raw(kind); + self.inner.start_node(kind) + } + + pub fn finish_node(&mut self) { + self.inner.finish_node() + } + + pub fn error(&mut self, error: parser::ParseError, text_pos: TextSize) { + self.errors.push(SyntaxError::new_at_offset(*error.0, text_pos)) + } +} |
