From 70097504f78c4c41368a0b864a94df95fb9c27f7 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 17 Aug 2018 21:10:55 +0300 Subject: hide root --- crates/libsyntax2/src/yellow/mod.rs | 40 +++++++++++++++++++++++++++++----- crates/libsyntax2/src/yellow/syntax.rs | 16 +++++++------- 2 files changed, 43 insertions(+), 13 deletions(-) (limited to 'crates/libsyntax2/src/yellow') diff --git a/crates/libsyntax2/src/yellow/mod.rs b/crates/libsyntax2/src/yellow/mod.rs index ff3bb221b..3c4510fe7 100644 --- a/crates/libsyntax2/src/yellow/mod.rs +++ b/crates/libsyntax2/src/yellow/mod.rs @@ -4,7 +4,6 @@ mod red; mod syntax; use std::{ - ops::Deref, sync::Arc, ptr, }; @@ -15,17 +14,48 @@ pub(crate) use self::{ red::RedNode, }; -pub trait TreeRoot: Deref + Clone + Send + Sync {} - #[derive(Debug)] pub struct SyntaxRoot { red: RedNode, pub(crate) errors: Vec, } -impl TreeRoot for Arc {} +pub trait TreeRoot: Clone + Send + Sync { + fn borrowed(&self) -> RefRoot; + fn owned(&self) -> OwnedRoot; + + #[doc(hidden)] + fn syntax_root(&self) -> &SyntaxRoot; +} +#[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> TreeRoot for &'a SyntaxRoot {} +impl TreeRoot for OwnedRoot { + fn borrowed(&self) -> RefRoot { + RefRoot(&self) + } + fn owned(&self) -> OwnedRoot { + self.clone() + } + + fn syntax_root(&self) -> &SyntaxRoot { + &*self.0 + } +} + +impl<'a> TreeRoot for RefRoot<'a> { + fn borrowed(&self) -> RefRoot { + *self + } + fn owned(&self) -> OwnedRoot { + self.0.clone() + } + fn syntax_root(&self) -> &SyntaxRoot { + self.0.syntax_root() + } +} impl SyntaxRoot { pub(crate) fn new(green: GreenNode, errors: Vec) -> SyntaxRoot { diff --git a/crates/libsyntax2/src/yellow/syntax.rs b/crates/libsyntax2/src/yellow/syntax.rs index bb390751a..ef82ba408 100644 --- a/crates/libsyntax2/src/yellow/syntax.rs +++ b/crates/libsyntax2/src/yellow/syntax.rs @@ -3,14 +3,14 @@ use std::{fmt, sync::Arc}; use smol_str::SmolStr; use { - yellow::{RedNode, TreeRoot, SyntaxRoot, RedPtr}, + yellow::{RedNode, TreeRoot, SyntaxRoot, RedPtr, RefRoot, OwnedRoot}, SyntaxKind::{self, *}, TextRange, TextUnit, }; #[derive(Clone, Copy)] -pub struct SyntaxNode> { +pub struct SyntaxNode { pub(crate) root: R, // Guaranteed to not dangle, because `root` holds a // strong reference to red's ancestor @@ -28,7 +28,7 @@ impl PartialEq> for SyntaxNode { impl Eq for SyntaxNode {} -pub type SyntaxNodeRef<'a> = SyntaxNode<&'a SyntaxRoot>; +pub type SyntaxNodeRef<'a> = SyntaxNode>; #[test] fn syntax_node_ref_is_copy() { @@ -42,18 +42,18 @@ pub struct SyntaxError { pub offset: TextUnit, } -impl SyntaxNode> { +impl SyntaxNode { pub(crate) fn new_owned(root: SyntaxRoot) -> Self { - let root = Arc::new(root); - let red = RedPtr::new(&root.red); + let root = OwnedRoot(Arc::new(root)); + let red = RedPtr::new(&root.syntax_root().red); SyntaxNode { root, red } } } impl SyntaxNode { - pub fn as_ref<'a>(&'a self) -> SyntaxNode<&'a SyntaxRoot> { + pub fn as_ref<'a>(&'a self) -> SyntaxNode> { SyntaxNode { - root: &*self.root, + root: self.root.borrowed(), red: self.red, } } -- cgit v1.2.3