From a261a1836ba02a1c091c5165795dc165ca399a87 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 2 Oct 2018 17:07:12 +0300 Subject: Move to rowan for syntax tree impl --- crates/ra_syntax/src/yellow/mod.rs | 174 +++++++++++++++++++++++-------------- 1 file changed, 108 insertions(+), 66 deletions(-) (limited to 'crates/ra_syntax/src/yellow/mod.rs') diff --git a/crates/ra_syntax/src/yellow/mod.rs b/crates/ra_syntax/src/yellow/mod.rs index 0596e702f..c621b1d6a 100644 --- a/crates/ra_syntax/src/yellow/mod.rs +++ b/crates/ra_syntax/src/yellow/mod.rs @@ -1,100 +1,142 @@ mod builder; -mod green; -mod red; -mod syntax; mod syntax_text; use std::{ - sync::Arc, - ptr, -}; -pub use self::syntax::{SyntaxNode, SyntaxNodeRef, SyntaxError, SyntaxNodeChildren}; -pub(crate) use self::{ - builder::GreenBuilder, - green::GreenNode, - red::RedNode, - syntax_text::SyntaxText, + fmt, + hash::{Hash, Hasher}, }; +use rowan::Types; +use {SyntaxKind, TextUnit, TextRange, SmolStr}; +use self::syntax_text::SyntaxText; -#[derive(Debug)] -pub struct SyntaxRoot { - red: RedNode, - pub(crate) errors: Vec, +pub use rowan::{TreeRoot}; +pub(crate) use self::builder::GreenBuilder; + +#[derive(Debug, Clone, Copy)] +pub enum RaTypes {} +impl Types for RaTypes { + type Kind = SyntaxKind; + type RootData = Vec; } -pub trait TreeRoot: Clone + Send + Sync { - fn borrowed(&self) -> RefRoot; - fn owned(&self) -> OwnedRoot; +pub type OwnedRoot = ::rowan::OwnedRoot; +pub type RefRoot<'a> = ::rowan::RefRoot<'a, RaTypes>; + +pub type GreenNode = ::rowan::GreenNode; - #[doc(hidden)] - fn syntax_root(&self) -> &SyntaxRoot; +#[derive(Debug, Clone, PartialEq, Eq, Hash, Ord, PartialOrd)] +pub struct SyntaxError { + pub msg: String, + pub offset: TextUnit, } -#[derive(Clone, Debug)] -pub struct OwnedRoot(Arc); -#[derive(Clone, Copy, Debug)] -pub struct RefRoot<'a>(&'a OwnedRoot); // TODO: shared_from_this instead of double indirection -impl<'a> RefRoot<'a> { - fn syntax_root(&self) -> &'a SyntaxRoot { - self.0.syntax_root() +#[derive(Clone, Copy)] +pub struct SyntaxNode = OwnedRoot>( + ::rowan::SyntaxNode, +); +pub type SyntaxNodeRef<'a> = SyntaxNode>; + +impl PartialEq> for SyntaxNode +where + R1: TreeRoot, + R2: TreeRoot, +{ + fn eq(&self, other: &SyntaxNode) -> bool { + self.0 == other.0 } } -impl TreeRoot for OwnedRoot { - fn borrowed(&self) -> RefRoot { - RefRoot(&self) - } - fn owned(&self) -> OwnedRoot { - self.clone() +impl> Eq for SyntaxNode {} +impl> Hash for SyntaxNode { + fn hash(&self, state: &mut H) { + self.0.hash(state) } +} - fn syntax_root(&self) -> &SyntaxRoot { - &*self.0 +impl SyntaxNode { + pub(crate) fn new(green: GreenNode, errors: Vec) -> SyntaxNode { + SyntaxNode(::rowan::SyntaxNode::new(green, errors)) + } +} +impl<'a> SyntaxNode> { + pub fn leaf_text(self) -> Option<&'a SmolStr> { + self.0.leaf_text() } } -impl<'a> TreeRoot for RefRoot<'a> { - fn borrowed(&self) -> RefRoot { - *self +impl> SyntaxNode { + pub(crate) fn root_data(&self) -> &Vec { + self.0.root_data() + } + pub(crate) fn replace_with(&self, replacement: GreenNode) -> GreenNode { + self.0.replace_with(replacement) + } + pub fn borrowed<'a>(&'a self) -> SyntaxNode> { + SyntaxNode(self.0.borrowed()) + } + pub fn owned(&self) -> SyntaxNode { + SyntaxNode(self.0.owned()) + } + pub fn kind(&self) -> SyntaxKind { + self.0.kind() } - fn owned(&self) -> OwnedRoot { - self.0.clone() + pub fn range(&self) -> TextRange { + self.0.range() } - fn syntax_root(&self) -> &SyntaxRoot { - self.0.syntax_root() + pub fn text(&self) -> SyntaxText { + SyntaxText::new(self.borrowed()) + } + pub fn is_leaf(&self) -> bool { + self.0.is_leaf() + } + pub fn parent(&self) -> Option> { + self.0.parent().map(SyntaxNode) + } + pub fn first_child(&self) -> Option> { + self.0.first_child().map(SyntaxNode) + } + pub fn last_child(&self) -> Option> { + self.0.last_child().map(SyntaxNode) + } + pub fn next_sibling(&self) -> Option> { + self.0.next_sibling().map(SyntaxNode) + } + pub fn prev_sibling(&self) -> Option> { + self.0.prev_sibling().map(SyntaxNode) + } + pub fn children(&self) -> SyntaxNodeChildren { + SyntaxNodeChildren(self.0.children()) } } -impl SyntaxRoot { - pub(crate) fn new(green: GreenNode, errors: Vec) -> SyntaxRoot { - SyntaxRoot { - red: RedNode::new_root(green), - errors, +impl> fmt::Debug for SyntaxNode { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + write!(fmt, "{:?}@{:?}", self.kind(), self.range())?; + if has_short_text(self.kind()) { + write!(fmt, " \"{}\"", self.text())?; } + Ok(()) } } -#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] -pub(crate) struct RedPtr(ptr::NonNull); - -unsafe impl Send for RedPtr {} - -unsafe impl Sync for RedPtr {} +#[derive(Debug)] +pub struct SyntaxNodeChildren>( + ::rowan::SyntaxNodeChildren +); -impl RedPtr { - fn new(red: &RedNode) -> RedPtr { - RedPtr(red.into()) - } +impl> Iterator for SyntaxNodeChildren { + type Item = SyntaxNode; - unsafe fn get<'a>(self, _root: &'a SyntaxRoot) -> &'a RedNode { - &*self.0.as_ptr() + fn next(&mut self) -> Option> { + self.0.next().map(SyntaxNode) } } -#[test] -fn assert_send_sync() { - fn f() {} - f::(); - f::(); - f::(); + +fn has_short_text(kind: SyntaxKind) -> bool { + use SyntaxKind::*; + match kind { + IDENT | LIFETIME | INT_NUMBER | FLOAT_NUMBER => true, + _ => false, + } } -- cgit v1.2.3