diff --git a/crates/libanalysis/src/lib.rs b/crates/libanalysis/src/lib.rs index b1093fe833..ae96a0d62d 100644 --- a/crates/libanalysis/src/lib.rs +++ b/crates/libanalysis/src/lib.rs @@ -26,7 +26,7 @@ use std::{ }; use libsyntax2::{ - TextUnit, TextRange, SyntaxRoot, + TextUnit, TextRange, RefRoot, ast::{self, AstNode, NameOwner}, SyntaxKind::*, }; @@ -151,7 +151,7 @@ impl World { Ok(vec![]) } - fn index_resolve(&self, name_ref: ast::NameRef<&SyntaxRoot>) -> Vec<(FileId, FileSymbol)> { + fn index_resolve(&self, name_ref: ast::NameRef) -> Vec<(FileId, FileSymbol)> { let name = name_ref.text(); let mut query = Query::new(name.to_string()); query.exact(); @@ -159,7 +159,7 @@ impl World { self.world_symbols(query) } - fn resolve_module(&self, id: FileId, module: ast::Module<&SyntaxRoot>) -> Vec<(FileId, FileSymbol)> { + fn resolve_module(&self, id: FileId, module: ast::Module) -> Vec<(FileId, FileSymbol)> { let name = match module.name() { Some(name) => name.text(), None => return Vec::new(), diff --git a/crates/libeditor/src/code_actions.rs b/crates/libeditor/src/code_actions.rs index 4b2515835a..bb6eb0d618 100644 --- a/crates/libeditor/src/code_actions.rs +++ b/crates/libeditor/src/code_actions.rs @@ -2,8 +2,7 @@ use {TextUnit, File, EditBuilder, Edit}; use libsyntax2::{ ast::{self, AstNode, AttrsOwner}, SyntaxKind::COMMA, - SyntaxNodeRef, - SyntaxRoot, + SyntaxNodeRef, RefRoot, algo::{ Direction, siblings, find_leaf_at_offset, ancestors, @@ -71,7 +70,7 @@ fn non_trivia_sibling(node: SyntaxNodeRef, direction: Direction) -> Option>(syntax: SyntaxNodeRef<'a>, offset: TextUnit) -> Option { +pub fn find_node<'a, N: AstNode>>(syntax: SyntaxNodeRef<'a>, offset: TextUnit) -> Option { let leaves = find_leaf_at_offset(syntax, offset); let leaf = leaves.clone() .find(|leaf| !leaf.kind().is_trivia()) diff --git a/crates/libeditor/src/symbols.rs b/crates/libeditor/src/symbols.rs index ce870430e2..cf5bd2a412 100644 --- a/crates/libeditor/src/symbols.rs +++ b/crates/libeditor/src/symbols.rs @@ -1,6 +1,6 @@ use smol_str::SmolStr; use libsyntax2::{ - SyntaxKind, SyntaxNodeRef, SyntaxRoot, AstNode, + SyntaxKind, SyntaxNodeRef, AstNode, RefRoot, ast::{self, NameOwner}, algo::{ visit::{visitor, Visitor}, @@ -32,7 +32,7 @@ pub fn file_symbols(file: &ast::File) -> Vec { } fn to_symbol(node: SyntaxNodeRef) -> Option { - fn decl<'a, N: NameOwner<&'a SyntaxRoot>>(node: N) -> Option { + fn decl<'a, N: NameOwner>>(node: N) -> Option { let name = node.name()?; Some(FileSymbol { name: name.text(), @@ -80,7 +80,7 @@ pub fn file_structure(file: &ast::File) -> Vec { } fn structure_node(node: SyntaxNodeRef) -> Option { - fn decl<'a, N: NameOwner<&'a SyntaxRoot>>(node: N) -> Option { + fn decl<'a, N: NameOwner>>(node: N) -> Option { let name = node.name()?; Some(StructureNode { parent: None, diff --git a/crates/libsyntax2/src/algo/visit.rs b/crates/libsyntax2/src/algo/visit.rs index dc5afa5a91..55eb72f595 100644 --- a/crates/libsyntax2/src/algo/visit.rs +++ b/crates/libsyntax2/src/algo/visit.rs @@ -1,5 +1,5 @@ use std::marker::PhantomData; -use {SyntaxNodeRef, AstNode, SyntaxRoot}; +use {SyntaxNodeRef, AstNode, RefRoot}; pub fn visitor<'a, T>() -> impl Visitor<'a, Output=T> { @@ -10,7 +10,7 @@ pub trait Visitor<'a>: Sized { type Output; fn accept(self, node: SyntaxNodeRef<'a>) -> Option; fn visit(self, f: F) -> Vis - where N: AstNode<&'a SyntaxRoot>, + where N: AstNode>, F: FnOnce(N) -> Self::Output, { Vis { inner: self, f, ph: PhantomData } @@ -40,7 +40,7 @@ pub struct Vis { impl<'a, V, N, F> Visitor<'a> for Vis where V: Visitor<'a>, - N: AstNode<&'a SyntaxRoot>, + N: AstNode>, F: FnOnce(N) -> >::Output, { type Output = >::Output; diff --git a/crates/libsyntax2/src/ast/generated.rs b/crates/libsyntax2/src/ast/generated.rs index be3f73f7ea..4fc405c8af 100644 --- a/crates/libsyntax2/src/ast/generated.rs +++ b/crates/libsyntax2/src/ast/generated.rs @@ -1,13 +1,12 @@ -use std::sync::Arc; use { ast, - SyntaxNode, SyntaxRoot, TreeRoot, AstNode, + SyntaxNode, OwnedRoot, TreeRoot, AstNode, SyntaxKind::*, }; // ArrayType #[derive(Debug, Clone, Copy)] -pub struct ArrayType> { +pub struct ArrayType { syntax: SyntaxNode, } @@ -25,7 +24,7 @@ impl ArrayType {} // Attr #[derive(Debug, Clone, Copy)] -pub struct Attr> { +pub struct Attr { syntax: SyntaxNode, } @@ -50,7 +49,7 @@ impl Attr { // ConstDef #[derive(Debug, Clone, Copy)] -pub struct ConstDef> { +pub struct ConstDef { syntax: SyntaxNode, } @@ -70,7 +69,7 @@ impl ConstDef {} // DynTraitType #[derive(Debug, Clone, Copy)] -pub struct DynTraitType> { +pub struct DynTraitType { syntax: SyntaxNode, } @@ -88,7 +87,7 @@ impl DynTraitType {} // EnumDef #[derive(Debug, Clone, Copy)] -pub struct EnumDef> { +pub struct EnumDef { syntax: SyntaxNode, } @@ -108,7 +107,7 @@ impl EnumDef {} // File #[derive(Debug, Clone, Copy)] -pub struct File> { +pub struct File { syntax: SyntaxNode, } @@ -132,7 +131,7 @@ impl File { // FnDef #[derive(Debug, Clone, Copy)] -pub struct FnDef> { +pub struct FnDef { syntax: SyntaxNode, } @@ -152,7 +151,7 @@ impl FnDef {} // FnPointerType #[derive(Debug, Clone, Copy)] -pub struct FnPointerType> { +pub struct FnPointerType { syntax: SyntaxNode, } @@ -170,7 +169,7 @@ impl FnPointerType {} // ForType #[derive(Debug, Clone, Copy)] -pub struct ForType> { +pub struct ForType { syntax: SyntaxNode, } @@ -188,7 +187,7 @@ impl ForType {} // ImplItem #[derive(Debug, Clone, Copy)] -pub struct ImplItem> { +pub struct ImplItem { syntax: SyntaxNode, } @@ -206,7 +205,7 @@ impl ImplItem {} // ImplTraitType #[derive(Debug, Clone, Copy)] -pub struct ImplTraitType> { +pub struct ImplTraitType { syntax: SyntaxNode, } @@ -224,7 +223,7 @@ impl ImplTraitType {} // Module #[derive(Debug, Clone, Copy)] -pub struct Module> { +pub struct Module { syntax: SyntaxNode, } @@ -244,7 +243,7 @@ impl Module {} // Name #[derive(Debug, Clone, Copy)] -pub struct Name> { +pub struct Name { syntax: SyntaxNode, } @@ -262,7 +261,7 @@ impl Name {} // NameRef #[derive(Debug, Clone, Copy)] -pub struct NameRef> { +pub struct NameRef { syntax: SyntaxNode, } @@ -280,7 +279,7 @@ impl NameRef {} // NamedField #[derive(Debug, Clone, Copy)] -pub struct NamedField> { +pub struct NamedField { syntax: SyntaxNode, } @@ -300,7 +299,7 @@ impl NamedField {} // NeverType #[derive(Debug, Clone, Copy)] -pub struct NeverType> { +pub struct NeverType { syntax: SyntaxNode, } @@ -318,7 +317,7 @@ impl NeverType {} // NominalDef #[derive(Debug, Clone, Copy)] -pub enum NominalDef> { +pub enum NominalDef { StructDef(StructDef), EnumDef(EnumDef), } @@ -344,7 +343,7 @@ impl NominalDef {} // ParenType #[derive(Debug, Clone, Copy)] -pub struct ParenType> { +pub struct ParenType { syntax: SyntaxNode, } @@ -362,7 +361,7 @@ impl ParenType {} // PathType #[derive(Debug, Clone, Copy)] -pub struct PathType> { +pub struct PathType { syntax: SyntaxNode, } @@ -380,7 +379,7 @@ impl PathType {} // PlaceholderType #[derive(Debug, Clone, Copy)] -pub struct PlaceholderType> { +pub struct PlaceholderType { syntax: SyntaxNode, } @@ -398,7 +397,7 @@ impl PlaceholderType {} // PointerType #[derive(Debug, Clone, Copy)] -pub struct PointerType> { +pub struct PointerType { syntax: SyntaxNode, } @@ -416,7 +415,7 @@ impl PointerType {} // ReferenceType #[derive(Debug, Clone, Copy)] -pub struct ReferenceType> { +pub struct ReferenceType { syntax: SyntaxNode, } @@ -434,7 +433,7 @@ impl ReferenceType {} // SliceType #[derive(Debug, Clone, Copy)] -pub struct SliceType> { +pub struct SliceType { syntax: SyntaxNode, } @@ -452,7 +451,7 @@ impl SliceType {} // StaticDef #[derive(Debug, Clone, Copy)] -pub struct StaticDef> { +pub struct StaticDef { syntax: SyntaxNode, } @@ -472,7 +471,7 @@ impl StaticDef {} // StructDef #[derive(Debug, Clone, Copy)] -pub struct StructDef> { +pub struct StructDef { syntax: SyntaxNode, } @@ -498,7 +497,7 @@ impl StructDef { // TokenTree #[derive(Debug, Clone, Copy)] -pub struct TokenTree> { +pub struct TokenTree { syntax: SyntaxNode, } @@ -516,7 +515,7 @@ impl TokenTree {} // TraitDef #[derive(Debug, Clone, Copy)] -pub struct TraitDef> { +pub struct TraitDef { syntax: SyntaxNode, } @@ -536,7 +535,7 @@ impl TraitDef {} // TupleType #[derive(Debug, Clone, Copy)] -pub struct TupleType> { +pub struct TupleType { syntax: SyntaxNode, } @@ -554,7 +553,7 @@ impl TupleType {} // TypeDef #[derive(Debug, Clone, Copy)] -pub struct TypeDef> { +pub struct TypeDef { syntax: SyntaxNode, } @@ -574,7 +573,7 @@ impl TypeDef {} // TypeRef #[derive(Debug, Clone, Copy)] -pub enum TypeRef> { +pub enum TypeRef { ParenType(ParenType), TupleType(TupleType), NeverType(NeverType), diff --git a/crates/libsyntax2/src/ast/mod.rs b/crates/libsyntax2/src/ast/mod.rs index 9b9200f996..b52230e9cb 100644 --- a/crates/libsyntax2/src/ast/mod.rs +++ b/crates/libsyntax2/src/ast/mod.rs @@ -1,12 +1,10 @@ mod generated; -use std::sync::Arc; - use itertools::Itertools; use smol_str::SmolStr; use { - SyntaxNode, SyntaxNodeRef, SyntaxRoot, TreeRoot, SyntaxError, + SyntaxNode, SyntaxNodeRef, OwnedRoot, TreeRoot, SyntaxError, SyntaxKind::*, }; pub use self::generated::*; @@ -37,7 +35,7 @@ pub trait AttrsOwner: AstNode { } } -impl File> { +impl File { pub fn parse(text: &str) -> Self { File::cast(::parse(text)).unwrap() } @@ -45,7 +43,7 @@ impl File> { impl File { pub fn errors(&self) -> Vec { - self.syntax().root.errors.clone() + self.syntax().root.syntax_root().errors.clone() } } diff --git a/crates/libsyntax2/src/lib.rs b/crates/libsyntax2/src/lib.rs index feef542c4f..0e40fb65fb 100644 --- a/crates/libsyntax2/src/lib.rs +++ b/crates/libsyntax2/src/lib.rs @@ -45,7 +45,7 @@ pub use { lexer::{tokenize, Token}, syntax_kinds::SyntaxKind, text_unit::{TextRange, TextUnit}, - yellow::{SyntaxNode, SyntaxNodeRef, SyntaxRoot, TreeRoot, SyntaxError}, + yellow::{SyntaxNode, SyntaxNodeRef, OwnedRoot, RefRoot, TreeRoot, SyntaxError}, }; diff --git a/crates/libsyntax2/src/utils.rs b/crates/libsyntax2/src/utils.rs index 1fbb872a53..4f60aa2a89 100644 --- a/crates/libsyntax2/src/utils.rs +++ b/crates/libsyntax2/src/utils.rs @@ -1,13 +1,13 @@ use std::fmt::Write; use { algo::walk::{walk, WalkEvent}, - SyntaxNode, + SyntaxNode, TreeRoot, }; /// Parse a file and create a string representation of the resulting parse tree. pub fn dump_tree(syntax: &SyntaxNode) -> String { let syntax = syntax.as_ref(); - let mut errors: Vec<_> = syntax.root.errors.iter().cloned().collect(); + let mut errors: Vec<_> = syntax.root.syntax_root().errors.iter().cloned().collect(); errors.sort_by_key(|e| e.offset); let mut err_pos = 0; let mut level = 0; diff --git a/crates/libsyntax2/src/yellow/mod.rs b/crates/libsyntax2/src/yellow/mod.rs index ff3bb221b2..3c4510fe7f 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; -impl<'a> TreeRoot for &'a SyntaxRoot {} + #[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 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 bb390751a2..ef82ba408f 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, } }