mirror of
				https://github.com/rust-lang/rust-analyzer.git
				synced 2025-11-03 13:13:18 +00:00 
			
		
		
		
	switch ra_syntax to new rowan API
This commit is contained in:
		
							parent
							
								
									55272f2023
								
							
						
					
					
						commit
						d91a98ec84
					
				@ -1,19 +1,23 @@
 | 
			
		||||
pub mod visit;
 | 
			
		||||
 | 
			
		||||
use crate::{SyntaxNode, SyntaxNodeRef, TextRange, TextUnit};
 | 
			
		||||
use rowan::TransparentNewType;
 | 
			
		||||
 | 
			
		||||
use crate::{SyntaxNode, TextRange, TextUnit};
 | 
			
		||||
 | 
			
		||||
pub use rowan::LeafAtOffset;
 | 
			
		||||
 | 
			
		||||
pub fn find_leaf_at_offset(node: SyntaxNodeRef, offset: TextUnit) -> LeafAtOffset<SyntaxNodeRef> {
 | 
			
		||||
pub fn find_leaf_at_offset(node: &SyntaxNode, offset: TextUnit) -> LeafAtOffset<&SyntaxNode> {
 | 
			
		||||
    match node.0.leaf_at_offset(offset) {
 | 
			
		||||
        LeafAtOffset::None => LeafAtOffset::None,
 | 
			
		||||
        LeafAtOffset::Single(n) => LeafAtOffset::Single(SyntaxNode(n)),
 | 
			
		||||
        LeafAtOffset::Between(l, r) => LeafAtOffset::Between(SyntaxNode(l), SyntaxNode(r)),
 | 
			
		||||
        LeafAtOffset::Single(n) => LeafAtOffset::Single(SyntaxNode::from_repr(n)),
 | 
			
		||||
        LeafAtOffset::Between(l, r) => {
 | 
			
		||||
            LeafAtOffset::Between(SyntaxNode::from_repr(l), SyntaxNode::from_repr(r))
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn find_covering_node(root: SyntaxNodeRef, range: TextRange) -> SyntaxNodeRef {
 | 
			
		||||
    SyntaxNode(root.0.covering_node(range))
 | 
			
		||||
pub fn find_covering_node(root: &SyntaxNode, range: TextRange) -> &SyntaxNode {
 | 
			
		||||
    SyntaxNode::from_repr(root.0.covering_node(range))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn generate<T>(seed: Option<T>, step: impl Fn(&T) -> Option<T>) -> impl Iterator<Item = T> {
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,4 @@
 | 
			
		||||
use crate::{AstNode, SyntaxNodeRef};
 | 
			
		||||
use crate::{AstNode, SyntaxNode};
 | 
			
		||||
 | 
			
		||||
use std::marker::PhantomData;
 | 
			
		||||
 | 
			
		||||
@ -15,11 +15,11 @@ pub fn visitor_ctx<'a, T, C>(ctx: C) -> impl VisitorCtx<'a, Output = T, Ctx = C>
 | 
			
		||||
 | 
			
		||||
pub trait Visitor<'a>: Sized {
 | 
			
		||||
    type Output;
 | 
			
		||||
    fn accept(self, node: SyntaxNodeRef<'a>) -> Option<Self::Output>;
 | 
			
		||||
    fn accept(self, node: &'a SyntaxNode) -> Option<Self::Output>;
 | 
			
		||||
    fn visit<N, F>(self, f: F) -> Vis<Self, N, F>
 | 
			
		||||
    where
 | 
			
		||||
        N: AstNode<'a>,
 | 
			
		||||
        F: FnOnce(N) -> Self::Output,
 | 
			
		||||
        N: AstNode + 'a,
 | 
			
		||||
        F: FnOnce(&'a N) -> Self::Output,
 | 
			
		||||
    {
 | 
			
		||||
        Vis {
 | 
			
		||||
            inner: self,
 | 
			
		||||
@ -32,11 +32,11 @@ pub trait Visitor<'a>: Sized {
 | 
			
		||||
pub trait VisitorCtx<'a>: Sized {
 | 
			
		||||
    type Output;
 | 
			
		||||
    type Ctx;
 | 
			
		||||
    fn accept(self, node: SyntaxNodeRef<'a>) -> Result<Self::Output, Self::Ctx>;
 | 
			
		||||
    fn accept(self, node: &'a SyntaxNode) -> Result<Self::Output, Self::Ctx>;
 | 
			
		||||
    fn visit<N, F>(self, f: F) -> VisCtx<Self, N, F>
 | 
			
		||||
    where
 | 
			
		||||
        N: AstNode<'a>,
 | 
			
		||||
        F: FnOnce(N, Self::Ctx) -> Self::Output,
 | 
			
		||||
        N: AstNode + 'a,
 | 
			
		||||
        F: FnOnce(&'a N, Self::Ctx) -> Self::Output,
 | 
			
		||||
    {
 | 
			
		||||
        VisCtx {
 | 
			
		||||
            inner: self,
 | 
			
		||||
@ -54,7 +54,7 @@ struct EmptyVisitor<T> {
 | 
			
		||||
impl<'a, T> Visitor<'a> for EmptyVisitor<T> {
 | 
			
		||||
    type Output = T;
 | 
			
		||||
 | 
			
		||||
    fn accept(self, _node: SyntaxNodeRef<'a>) -> Option<T> {
 | 
			
		||||
    fn accept(self, _node: &'a SyntaxNode) -> Option<T> {
 | 
			
		||||
        None
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -69,7 +69,7 @@ impl<'a, T, C> VisitorCtx<'a> for EmptyVisitorCtx<T, C> {
 | 
			
		||||
    type Output = T;
 | 
			
		||||
    type Ctx = C;
 | 
			
		||||
 | 
			
		||||
    fn accept(self, _node: SyntaxNodeRef<'a>) -> Result<T, C> {
 | 
			
		||||
    fn accept(self, _node: &'a SyntaxNode) -> Result<T, C> {
 | 
			
		||||
        Err(self.ctx)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -84,12 +84,12 @@ pub struct Vis<V, N, F> {
 | 
			
		||||
impl<'a, V, N, F> Visitor<'a> for Vis<V, N, F>
 | 
			
		||||
where
 | 
			
		||||
    V: Visitor<'a>,
 | 
			
		||||
    N: AstNode<'a>,
 | 
			
		||||
    F: FnOnce(N) -> <V as Visitor<'a>>::Output,
 | 
			
		||||
    N: AstNode + 'a,
 | 
			
		||||
    F: FnOnce(&'a N) -> <V as Visitor<'a>>::Output,
 | 
			
		||||
{
 | 
			
		||||
    type Output = <V as Visitor<'a>>::Output;
 | 
			
		||||
 | 
			
		||||
    fn accept(self, node: SyntaxNodeRef<'a>) -> Option<Self::Output> {
 | 
			
		||||
    fn accept(self, node: &'a SyntaxNode) -> Option<Self::Output> {
 | 
			
		||||
        let Vis { inner, f, .. } = self;
 | 
			
		||||
        inner.accept(node).or_else(|| N::cast(node).map(f))
 | 
			
		||||
    }
 | 
			
		||||
@ -105,13 +105,13 @@ pub struct VisCtx<V, N, F> {
 | 
			
		||||
impl<'a, V, N, F> VisitorCtx<'a> for VisCtx<V, N, F>
 | 
			
		||||
where
 | 
			
		||||
    V: VisitorCtx<'a>,
 | 
			
		||||
    N: AstNode<'a>,
 | 
			
		||||
    F: FnOnce(N, <V as VisitorCtx<'a>>::Ctx) -> <V as VisitorCtx<'a>>::Output,
 | 
			
		||||
    N: AstNode + 'a,
 | 
			
		||||
    F: FnOnce(&'a N, <V as VisitorCtx<'a>>::Ctx) -> <V as VisitorCtx<'a>>::Output,
 | 
			
		||||
{
 | 
			
		||||
    type Output = <V as VisitorCtx<'a>>::Output;
 | 
			
		||||
    type Ctx = <V as VisitorCtx<'a>>::Ctx;
 | 
			
		||||
 | 
			
		||||
    fn accept(self, node: SyntaxNodeRef<'a>) -> Result<Self::Output, Self::Ctx> {
 | 
			
		||||
    fn accept(self, node: &'a SyntaxNode) -> Result<Self::Output, Self::Ctx> {
 | 
			
		||||
        let VisCtx { inner, f, .. } = self;
 | 
			
		||||
        inner.accept(node).or_else(|ctx| match N::cast(node) {
 | 
			
		||||
            None => Err(ctx),
 | 
			
		||||
 | 
			
		||||
@ -1,119 +1,88 @@
 | 
			
		||||
mod generated;
 | 
			
		||||
 | 
			
		||||
use std::marker::PhantomData;
 | 
			
		||||
use std::string::String as RustString;
 | 
			
		||||
 | 
			
		||||
use itertools::Itertools;
 | 
			
		||||
 | 
			
		||||
pub use self::generated::*;
 | 
			
		||||
use crate::{
 | 
			
		||||
    yellow::{RefRoot, SyntaxNodeChildren},
 | 
			
		||||
    yellow::{SyntaxNode, SyntaxNodeChildren, TreePtr, RaTypes},
 | 
			
		||||
    SmolStr,
 | 
			
		||||
    SyntaxKind::*,
 | 
			
		||||
    SyntaxNodeRef,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/// The main trait to go from untyped `SyntaxNode`  to a typed ast. The
 | 
			
		||||
/// conversion itself has zero runtime cost: ast and syntax nodes have exactly
 | 
			
		||||
/// the same representation: a pointer to the tree root and a pointer to the
 | 
			
		||||
/// node itself.
 | 
			
		||||
pub trait AstNode<'a>: Clone + Copy + 'a {
 | 
			
		||||
    fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self>
 | 
			
		||||
pub trait AstNode: rowan::TransparentNewType<Repr = rowan::SyntaxNode<RaTypes>> {
 | 
			
		||||
    fn cast(syntax: &SyntaxNode) -> Option<&Self>
 | 
			
		||||
    where
 | 
			
		||||
        Self: Sized;
 | 
			
		||||
    fn syntax(self) -> SyntaxNodeRef<'a>;
 | 
			
		||||
    fn syntax(&self) -> &SyntaxNode;
 | 
			
		||||
    fn to_owned(&self) -> TreePtr<Self>;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub trait NameOwner<'a>: AstNode<'a> {
 | 
			
		||||
    fn name(self) -> Option<Name<'a>> {
 | 
			
		||||
pub trait NameOwner: AstNode {
 | 
			
		||||
    fn name(&self) -> Option<&Name> {
 | 
			
		||||
        child_opt(self)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub trait VisibilityOwner<'a>: AstNode<'a> {
 | 
			
		||||
    fn visibility(self) -> Option<Visibility<'a>> {
 | 
			
		||||
pub trait VisibilityOwner: AstNode {
 | 
			
		||||
    fn visibility(&self) -> Option<&Visibility> {
 | 
			
		||||
        child_opt(self)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub trait LoopBodyOwner<'a>: AstNode<'a> {
 | 
			
		||||
    fn loop_body(self) -> Option<Block<'a>> {
 | 
			
		||||
pub trait LoopBodyOwner: AstNode {
 | 
			
		||||
    fn loop_body(&self) -> Option<&Block> {
 | 
			
		||||
        child_opt(self)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub trait ArgListOwner<'a>: AstNode<'a> {
 | 
			
		||||
    fn arg_list(self) -> Option<ArgList<'a>> {
 | 
			
		||||
pub trait ArgListOwner: AstNode {
 | 
			
		||||
    fn arg_list(&self) -> Option<&ArgList> {
 | 
			
		||||
        child_opt(self)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub trait FnDefOwner<'a>: AstNode<'a> {
 | 
			
		||||
    fn functions(self) -> AstChildren<'a, FnDef<'a>> {
 | 
			
		||||
pub trait FnDefOwner: AstNode {
 | 
			
		||||
    fn functions(&self) -> AstChildren<FnDef> {
 | 
			
		||||
        children(self)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ModuleItem
 | 
			
		||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
 | 
			
		||||
pub enum ItemOrMacro<'a> {
 | 
			
		||||
    Item(ModuleItem<'a>),
 | 
			
		||||
    Macro(MacroCall<'a>),
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<'a> AstNode<'a> for ItemOrMacro<'a> {
 | 
			
		||||
    fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
 | 
			
		||||
        let res = if let Some(item) = ModuleItem::cast(syntax) {
 | 
			
		||||
            ItemOrMacro::Item(item)
 | 
			
		||||
        } else if let Some(macro_call) = MacroCall::cast(syntax) {
 | 
			
		||||
            ItemOrMacro::Macro(macro_call)
 | 
			
		||||
        } else {
 | 
			
		||||
            return None;
 | 
			
		||||
        };
 | 
			
		||||
        Some(res)
 | 
			
		||||
    }
 | 
			
		||||
    fn syntax(self) -> SyntaxNodeRef<'a> {
 | 
			
		||||
        match self {
 | 
			
		||||
            ItemOrMacro::Item(it) => it.syntax(),
 | 
			
		||||
            ItemOrMacro::Macro(it) => it.syntax(),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub trait ModuleItemOwner<'a>: AstNode<'a> {
 | 
			
		||||
    fn items(self) -> AstChildren<'a, ModuleItem<'a>> {
 | 
			
		||||
        children(self)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn items_with_macros(self) -> AstChildren<'a, ItemOrMacro<'a>> {
 | 
			
		||||
pub trait ModuleItemOwner: AstNode {
 | 
			
		||||
    fn items(&self) -> AstChildren<ModuleItem> {
 | 
			
		||||
        children(self)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub trait TypeParamsOwner<'a>: AstNode<'a> {
 | 
			
		||||
    fn type_param_list(self) -> Option<TypeParamList<'a>> {
 | 
			
		||||
pub trait TypeParamsOwner: AstNode {
 | 
			
		||||
    fn type_param_list(&self) -> Option<&TypeParamList> {
 | 
			
		||||
        child_opt(self)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn where_clause(self) -> Option<WhereClause<'a>> {
 | 
			
		||||
    fn where_clause(&self) -> Option<&WhereClause> {
 | 
			
		||||
        child_opt(self)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub trait AttrsOwner<'a>: AstNode<'a> {
 | 
			
		||||
    fn attrs(self) -> AstChildren<'a, Attr<'a>> {
 | 
			
		||||
pub trait AttrsOwner: AstNode {
 | 
			
		||||
    fn attrs(&self) -> AstChildren<Attr> {
 | 
			
		||||
        children(self)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub trait DocCommentsOwner<'a>: AstNode<'a> {
 | 
			
		||||
    fn doc_comments(self) -> AstChildren<'a, Comment<'a>> {
 | 
			
		||||
pub trait DocCommentsOwner: AstNode {
 | 
			
		||||
    fn doc_comments(&self) -> AstChildren<Comment> {
 | 
			
		||||
        children(self)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Returns the textual content of a doc comment block as a single string.
 | 
			
		||||
    /// That is, strips leading `///` and joins lines
 | 
			
		||||
    fn doc_comment_text(self) -> RustString {
 | 
			
		||||
    fn doc_comment_text(&self) -> std::string::String {
 | 
			
		||||
        self.doc_comments()
 | 
			
		||||
            .filter(|comment| comment.is_doc_comment())
 | 
			
		||||
            .map(|comment| {
 | 
			
		||||
@ -130,13 +99,13 @@ pub trait DocCommentsOwner<'a>: AstNode<'a> {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<'a> FnDef<'a> {
 | 
			
		||||
impl FnDef {
 | 
			
		||||
    pub fn has_atom_attr(&self, atom: &str) -> bool {
 | 
			
		||||
        self.attrs().filter_map(|x| x.as_atom()).any(|x| x == atom)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<'a> Attr<'a> {
 | 
			
		||||
impl Attr {
 | 
			
		||||
    pub fn as_atom(&self) -> Option<SmolStr> {
 | 
			
		||||
        let tt = self.value()?;
 | 
			
		||||
        let (_bra, attr, _ket) = tt.syntax().children().collect_tuple()?;
 | 
			
		||||
@ -147,7 +116,7 @@ impl<'a> Attr<'a> {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn as_call(&self) -> Option<(SmolStr, TokenTree<'a>)> {
 | 
			
		||||
    pub fn as_call(&self) -> Option<(SmolStr, &TokenTree)> {
 | 
			
		||||
        let tt = self.value()?;
 | 
			
		||||
        let (_bra, attr, args, _ket) = tt.syntax().children().collect_tuple()?;
 | 
			
		||||
        let args = TokenTree::cast(args)?;
 | 
			
		||||
@ -159,37 +128,37 @@ impl<'a> Attr<'a> {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<'a> Lifetime<'a> {
 | 
			
		||||
impl Lifetime {
 | 
			
		||||
    pub fn text(&self) -> SmolStr {
 | 
			
		||||
        self.syntax().leaf_text().unwrap().clone()
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<'a> Char<'a> {
 | 
			
		||||
impl Char {
 | 
			
		||||
    pub fn text(&self) -> &SmolStr {
 | 
			
		||||
        &self.syntax().leaf_text().unwrap()
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<'a> Byte<'a> {
 | 
			
		||||
impl Byte {
 | 
			
		||||
    pub fn text(&self) -> &SmolStr {
 | 
			
		||||
        &self.syntax().leaf_text().unwrap()
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<'a> ByteString<'a> {
 | 
			
		||||
impl ByteString {
 | 
			
		||||
    pub fn text(&self) -> &SmolStr {
 | 
			
		||||
        &self.syntax().leaf_text().unwrap()
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<'a> String<'a> {
 | 
			
		||||
impl String {
 | 
			
		||||
    pub fn text(&self) -> &SmolStr {
 | 
			
		||||
        &self.syntax().leaf_text().unwrap()
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<'a> Comment<'a> {
 | 
			
		||||
impl Comment {
 | 
			
		||||
    pub fn text(&self) -> &SmolStr {
 | 
			
		||||
        self.syntax().leaf_text().unwrap()
 | 
			
		||||
    }
 | 
			
		||||
@ -251,7 +220,7 @@ impl CommentFlavor {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<'a> Whitespace<'a> {
 | 
			
		||||
impl Whitespace {
 | 
			
		||||
    pub fn text(&self) -> &SmolStr {
 | 
			
		||||
        &self.syntax().leaf_text().unwrap()
 | 
			
		||||
    }
 | 
			
		||||
@ -265,36 +234,36 @@ impl<'a> Whitespace<'a> {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<'a> Name<'a> {
 | 
			
		||||
impl Name {
 | 
			
		||||
    pub fn text(&self) -> SmolStr {
 | 
			
		||||
        let ident = self.syntax().first_child().unwrap();
 | 
			
		||||
        ident.leaf_text().unwrap().clone()
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<'a> NameRef<'a> {
 | 
			
		||||
impl NameRef {
 | 
			
		||||
    pub fn text(&self) -> SmolStr {
 | 
			
		||||
        let ident = self.syntax().first_child().unwrap();
 | 
			
		||||
        ident.leaf_text().unwrap().clone()
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<'a> ImplBlock<'a> {
 | 
			
		||||
    pub fn target_type(self) -> Option<TypeRef<'a>> {
 | 
			
		||||
impl ImplBlock {
 | 
			
		||||
    pub fn target_type(&self) -> Option<&TypeRef> {
 | 
			
		||||
        match self.target() {
 | 
			
		||||
            (Some(t), None) | (_, Some(t)) => Some(t),
 | 
			
		||||
            _ => None,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn target_trait(self) -> Option<TypeRef<'a>> {
 | 
			
		||||
    pub fn target_trait(&self) -> Option<&TypeRef> {
 | 
			
		||||
        match self.target() {
 | 
			
		||||
            (Some(t), Some(_)) => Some(t),
 | 
			
		||||
            _ => None,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn target(self) -> (Option<TypeRef<'a>>, Option<TypeRef<'a>>) {
 | 
			
		||||
    fn target(&self) -> (Option<&TypeRef>, Option<&TypeRef>) {
 | 
			
		||||
        let mut types = children(self);
 | 
			
		||||
        let first = types.next();
 | 
			
		||||
        let second = types.next();
 | 
			
		||||
@ -302,8 +271,8 @@ impl<'a> ImplBlock<'a> {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<'a> Module<'a> {
 | 
			
		||||
    pub fn has_semi(self) -> bool {
 | 
			
		||||
impl Module {
 | 
			
		||||
    pub fn has_semi(&self) -> bool {
 | 
			
		||||
        match self.syntax().last_child() {
 | 
			
		||||
            None => false,
 | 
			
		||||
            Some(node) => node.kind() == SEMI,
 | 
			
		||||
@ -311,8 +280,8 @@ impl<'a> Module<'a> {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<'a> LetStmt<'a> {
 | 
			
		||||
    pub fn has_semi(self) -> bool {
 | 
			
		||||
impl LetStmt {
 | 
			
		||||
    pub fn has_semi(&self) -> bool {
 | 
			
		||||
        match self.syntax().last_child() {
 | 
			
		||||
            None => false,
 | 
			
		||||
            Some(node) => node.kind() == SEMI,
 | 
			
		||||
@ -320,35 +289,35 @@ impl<'a> LetStmt<'a> {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<'a> IfExpr<'a> {
 | 
			
		||||
    pub fn then_branch(self) -> Option<Block<'a>> {
 | 
			
		||||
impl IfExpr {
 | 
			
		||||
    pub fn then_branch(&self) -> Option<&Block> {
 | 
			
		||||
        self.blocks().nth(0)
 | 
			
		||||
    }
 | 
			
		||||
    pub fn else_branch(self) -> Option<Block<'a>> {
 | 
			
		||||
    pub fn else_branch(&self) -> Option<&Block> {
 | 
			
		||||
        self.blocks().nth(1)
 | 
			
		||||
    }
 | 
			
		||||
    fn blocks(self) -> AstChildren<'a, Block<'a>> {
 | 
			
		||||
    fn blocks(&self) -> AstChildren<Block> {
 | 
			
		||||
        children(self)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
 | 
			
		||||
pub enum PathSegmentKind<'a> {
 | 
			
		||||
    Name(NameRef<'a>),
 | 
			
		||||
    Name(&'a NameRef),
 | 
			
		||||
    SelfKw,
 | 
			
		||||
    SuperKw,
 | 
			
		||||
    CrateKw,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<'a> PathSegment<'a> {
 | 
			
		||||
    pub fn parent_path(self) -> Path<'a> {
 | 
			
		||||
impl PathSegment {
 | 
			
		||||
    pub fn parent_path(&self) -> &Path {
 | 
			
		||||
        self.syntax()
 | 
			
		||||
            .parent()
 | 
			
		||||
            .and_then(Path::cast)
 | 
			
		||||
            .expect("segments are always nested in paths")
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn kind(self) -> Option<PathSegmentKind<'a>> {
 | 
			
		||||
    pub fn kind(&self) -> Option<PathSegmentKind> {
 | 
			
		||||
        let res = if let Some(name_ref) = self.name_ref() {
 | 
			
		||||
            PathSegmentKind::Name(name_ref)
 | 
			
		||||
        } else {
 | 
			
		||||
@ -363,20 +332,20 @@ impl<'a> PathSegment<'a> {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<'a> Path<'a> {
 | 
			
		||||
    pub fn parent_path(self) -> Option<Path<'a>> {
 | 
			
		||||
impl Path {
 | 
			
		||||
    pub fn parent_path(&self) -> Option<&Path> {
 | 
			
		||||
        self.syntax().parent().and_then(Path::cast)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<'a> UseTree<'a> {
 | 
			
		||||
    pub fn has_star(self) -> bool {
 | 
			
		||||
impl UseTree {
 | 
			
		||||
    pub fn has_star(&self) -> bool {
 | 
			
		||||
        self.syntax().children().any(|it| it.kind() == STAR)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<'a> UseTreeList<'a> {
 | 
			
		||||
    pub fn parent_use_tree(self) -> UseTree<'a> {
 | 
			
		||||
impl UseTreeList {
 | 
			
		||||
    pub fn parent_use_tree(&self) -> &UseTree {
 | 
			
		||||
        self.syntax()
 | 
			
		||||
            .parent()
 | 
			
		||||
            .and_then(UseTree::cast)
 | 
			
		||||
@ -384,22 +353,22 @@ impl<'a> UseTreeList<'a> {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn child_opt<'a, P: AstNode<'a>, C: AstNode<'a>>(parent: P) -> Option<C> {
 | 
			
		||||
fn child_opt<P: AstNode, C: AstNode>(parent: &P) -> Option<&C> {
 | 
			
		||||
    children(parent).next()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn children<'a, P: AstNode<'a>, C: AstNode<'a>>(parent: P) -> AstChildren<'a, C> {
 | 
			
		||||
fn children<P: AstNode, C: AstNode>(parent: &P) -> AstChildren<C> {
 | 
			
		||||
    AstChildren::new(parent.syntax())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Debug)]
 | 
			
		||||
pub struct AstChildren<'a, N> {
 | 
			
		||||
    inner: SyntaxNodeChildren<RefRoot<'a>>,
 | 
			
		||||
    inner: SyntaxNodeChildren<'a>,
 | 
			
		||||
    ph: PhantomData<N>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<'a, N> AstChildren<'a, N> {
 | 
			
		||||
    fn new(parent: SyntaxNodeRef<'a>) -> Self {
 | 
			
		||||
    fn new(parent: &'a SyntaxNode) -> Self {
 | 
			
		||||
        AstChildren {
 | 
			
		||||
            inner: parent.children(),
 | 
			
		||||
            ph: PhantomData,
 | 
			
		||||
@ -407,9 +376,9 @@ impl<'a, N> AstChildren<'a, N> {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<'a, N: AstNode<'a>> Iterator for AstChildren<'a, N> {
 | 
			
		||||
    type Item = N;
 | 
			
		||||
    fn next(&mut self) -> Option<N> {
 | 
			
		||||
impl<'a, N: AstNode + 'a> Iterator for AstChildren<'a, N> {
 | 
			
		||||
    type Item = &'a N;
 | 
			
		||||
    fn next(&mut self) -> Option<&'a N> {
 | 
			
		||||
        loop {
 | 
			
		||||
            if let Some(n) = N::cast(self.inner.next()?) {
 | 
			
		||||
                return Some(n);
 | 
			
		||||
@ -420,13 +389,13 @@ impl<'a, N: AstNode<'a>> Iterator for AstChildren<'a, N> {
 | 
			
		||||
 | 
			
		||||
#[derive(Debug, Clone, PartialEq, Eq)]
 | 
			
		||||
pub enum StructFlavor<'a> {
 | 
			
		||||
    Tuple(PosFieldList<'a>),
 | 
			
		||||
    Named(NamedFieldDefList<'a>),
 | 
			
		||||
    Tuple(&'a PosFieldList),
 | 
			
		||||
    Named(&'a NamedFieldDefList),
 | 
			
		||||
    Unit,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<'a> StructFlavor<'a> {
 | 
			
		||||
    fn from_node<N: AstNode<'a>>(node: N) -> StructFlavor<'a> {
 | 
			
		||||
impl StructFlavor<'_> {
 | 
			
		||||
    fn from_node<N: AstNode>(node: &N) -> StructFlavor {
 | 
			
		||||
        if let Some(nfdl) = child_opt::<_, NamedFieldDefList>(node) {
 | 
			
		||||
            StructFlavor::Named(nfdl)
 | 
			
		||||
        } else if let Some(pfl) = child_opt::<_, PosFieldList>(node) {
 | 
			
		||||
@ -437,31 +406,31 @@ impl<'a> StructFlavor<'a> {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<'a> StructDef<'a> {
 | 
			
		||||
    pub fn flavor(self) -> StructFlavor<'a> {
 | 
			
		||||
impl StructDef {
 | 
			
		||||
    pub fn flavor(&self) -> StructFlavor {
 | 
			
		||||
        StructFlavor::from_node(self)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<'a> EnumVariant<'a> {
 | 
			
		||||
    pub fn flavor(self) -> StructFlavor<'a> {
 | 
			
		||||
impl EnumVariant {
 | 
			
		||||
    pub fn flavor(&self) -> StructFlavor {
 | 
			
		||||
        StructFlavor::from_node(self)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<'a> PointerType<'a> {
 | 
			
		||||
impl PointerType {
 | 
			
		||||
    pub fn is_mut(&self) -> bool {
 | 
			
		||||
        self.syntax().children().any(|n| n.kind() == MUT_KW)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<'a> ReferenceType<'a> {
 | 
			
		||||
impl ReferenceType {
 | 
			
		||||
    pub fn is_mut(&self) -> bool {
 | 
			
		||||
        self.syntax().children().any(|n| n.kind() == MUT_KW)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<'a> RefExpr<'a> {
 | 
			
		||||
impl RefExpr {
 | 
			
		||||
    pub fn is_mut(&self) -> bool {
 | 
			
		||||
        self.syntax().children().any(|n| n.kind() == MUT_KW)
 | 
			
		||||
    }
 | 
			
		||||
@ -477,7 +446,7 @@ pub enum PrefixOp {
 | 
			
		||||
    Neg,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<'a> PrefixExpr<'a> {
 | 
			
		||||
impl PrefixExpr {
 | 
			
		||||
    pub fn op(&self) -> Option<PrefixOp> {
 | 
			
		||||
        match self.syntax().first_child()?.kind() {
 | 
			
		||||
            STAR => Some(PrefixOp::Deref),
 | 
			
		||||
@ -552,7 +521,7 @@ pub enum BinOp {
 | 
			
		||||
    BitXorAssign,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<'a> BinExpr<'a> {
 | 
			
		||||
impl BinExpr {
 | 
			
		||||
    pub fn op(&self) -> Option<BinOp> {
 | 
			
		||||
        self.syntax()
 | 
			
		||||
            .children()
 | 
			
		||||
@ -592,15 +561,15 @@ impl<'a> BinExpr<'a> {
 | 
			
		||||
            .next()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn lhs(self) -> Option<Expr<'a>> {
 | 
			
		||||
    pub fn lhs(&self) -> Option<&Expr> {
 | 
			
		||||
        children(self).nth(0)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn rhs(self) -> Option<Expr<'a>> {
 | 
			
		||||
    pub fn rhs(&self) -> Option<&Expr> {
 | 
			
		||||
        children(self).nth(1)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn sub_exprs(self) -> (Option<Expr<'a>>, Option<Expr<'a>>) {
 | 
			
		||||
    pub fn sub_exprs(&self) -> (Option<&Expr>, Option<&Expr>) {
 | 
			
		||||
        let mut children = children(self);
 | 
			
		||||
        let first = children.next();
 | 
			
		||||
        let second = children.next();
 | 
			
		||||
@ -618,7 +587,7 @@ pub enum SelfParamFlavor {
 | 
			
		||||
    MutRef,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<'a> SelfParam<'a> {
 | 
			
		||||
impl SelfParam {
 | 
			
		||||
    pub fn flavor(&self) -> SelfParamFlavor {
 | 
			
		||||
        let borrowed = self.syntax().children().any(|n| n.kind() == AMP);
 | 
			
		||||
        if borrowed {
 | 
			
		||||
@ -641,7 +610,7 @@ impl<'a> SelfParam<'a> {
 | 
			
		||||
 | 
			
		||||
#[test]
 | 
			
		||||
fn test_doc_comment_of_items() {
 | 
			
		||||
    let file = SourceFileNode::parse(
 | 
			
		||||
    let file = SourceFile::parse(
 | 
			
		||||
        r#"
 | 
			
		||||
        //! doc
 | 
			
		||||
        // non-doc
 | 
			
		||||
 | 
			
		||||
@ -11,89 +11,92 @@ the below applies to the result of this template
 | 
			
		||||
 | 
			
		||||
#![cfg_attr(rustfmt, rustfmt_skip)]
 | 
			
		||||
 | 
			
		||||
use std::hash::{Hash, Hasher};
 | 
			
		||||
use rowan::TransparentNewType;
 | 
			
		||||
 | 
			
		||||
use crate::{
 | 
			
		||||
    ast,
 | 
			
		||||
    SyntaxNode, SyntaxNodeRef, AstNode,
 | 
			
		||||
    yellow::{TreeRoot, RaTypes, OwnedRoot, RefRoot},
 | 
			
		||||
    SyntaxKind::*,
 | 
			
		||||
    SyntaxNode, SyntaxKind::*,
 | 
			
		||||
    yellow::{RaTypes, TreePtr},
 | 
			
		||||
    ast::{self, AstNode},
 | 
			
		||||
};
 | 
			
		||||
{% for node, methods in ast %}
 | 
			
		||||
// {{ node }}
 | 
			
		||||
 | 
			
		||||
{%- if methods.enum %}
 | 
			
		||||
#[derive(Debug, PartialEq, Eq, Hash)]
 | 
			
		||||
#[repr(transparent)]
 | 
			
		||||
pub struct {{ node }} {
 | 
			
		||||
    pub(crate) syntax: SyntaxNode,
 | 
			
		||||
}
 | 
			
		||||
unsafe impl TransparentNewType for {{ node }} {
 | 
			
		||||
    type Repr = rowan::SyntaxNode<RaTypes>;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
 | 
			
		||||
pub enum {{ node }}<'a> {
 | 
			
		||||
pub enum {{ node }}Kind<'a> {
 | 
			
		||||
{%- for kind in methods.enum %}
 | 
			
		||||
    {{ kind }}({{ kind }}<'a>),
 | 
			
		||||
    {{ kind }}(&'a {{ kind }}),
 | 
			
		||||
{%- endfor %}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<'a> AstNode<'a> for {{ node }}<'a> {
 | 
			
		||||
    fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
 | 
			
		||||
impl AstNode for {{ node }} {
 | 
			
		||||
    fn cast(syntax: &SyntaxNode) -> Option<&Self> {
 | 
			
		||||
        match syntax.kind() {
 | 
			
		||||
{%- for kind in methods.enum %}
 | 
			
		||||
            {{ kind | SCREAM }} => Some({{ node }}::{{ kind }}({{ kind }} { syntax })),
 | 
			
		||||
{%- endfor %}
 | 
			
		||||
            {%- for kind in methods.enum %}
 | 
			
		||||
            | {{ kind | SCREAM }}
 | 
			
		||||
            {%- endfor %} => Some({{ node }}::from_repr(syntax.into_repr())),
 | 
			
		||||
            _ => None,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    fn syntax(self) -> SyntaxNodeRef<'a> {
 | 
			
		||||
        match self {
 | 
			
		||||
{%- for kind in methods.enum %}
 | 
			
		||||
            {{ node }}::{{ kind }}(inner) => inner.syntax(),
 | 
			
		||||
{%- endfor %}
 | 
			
		||||
    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 | 
			
		||||
    fn to_owned(&self) -> TreePtr<{{ node }}> { TreePtr::cast(self.syntax.to_owned()) }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl {{ node }} {
 | 
			
		||||
    pub fn kind(&self) -> {{ node }}Kind {
 | 
			
		||||
        match self.syntax.kind() {
 | 
			
		||||
            {%- for kind in methods.enum %}
 | 
			
		||||
            {{ kind | SCREAM }} => {{ node }}Kind::{{ kind }}({{ kind }}::cast(&self.syntax).unwrap()),
 | 
			
		||||
            {%- endfor %}
 | 
			
		||||
            _ => unreachable!(),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
{% else %}
 | 
			
		||||
#[derive(Debug, Clone, Copy,)]
 | 
			
		||||
pub struct {{ node }}Node<R: TreeRoot<RaTypes> = OwnedRoot> {
 | 
			
		||||
    pub(crate) syntax: SyntaxNode<R>,
 | 
			
		||||
#[derive(Debug, PartialEq, Eq, Hash)]
 | 
			
		||||
#[repr(transparent)]
 | 
			
		||||
pub struct {{ node }} {
 | 
			
		||||
    pub(crate) syntax: SyntaxNode,
 | 
			
		||||
}
 | 
			
		||||
pub type {{ node }}<'a> = {{ node }}Node<RefRoot<'a>>;
 | 
			
		||||
 | 
			
		||||
impl<R1: TreeRoot<RaTypes>, R2: TreeRoot<RaTypes>> PartialEq<{{node}}Node<R1>> for {{node}}Node<R2> {
 | 
			
		||||
    fn eq(&self, other: &{{node}}Node<R1>) -> bool { self.syntax == other.syntax }
 | 
			
		||||
}
 | 
			
		||||
impl<R: TreeRoot<RaTypes>> Eq for {{node}}Node<R> {}
 | 
			
		||||
impl<R: TreeRoot<RaTypes>> Hash for {{node}}Node<R> {
 | 
			
		||||
    fn hash<H: Hasher>(&self, state: &mut H) { self.syntax.hash(state) }
 | 
			
		||||
unsafe impl TransparentNewType for {{ node }} {
 | 
			
		||||
    type Repr = rowan::SyntaxNode<RaTypes>;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<'a> AstNode<'a> for {{ node }}<'a> {
 | 
			
		||||
    fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
 | 
			
		||||
impl AstNode for {{ node }} {
 | 
			
		||||
    fn cast(syntax: &SyntaxNode) -> Option<&Self> {
 | 
			
		||||
        match syntax.kind() {
 | 
			
		||||
            {{ node | SCREAM }} => Some({{ node }} { syntax }),
 | 
			
		||||
            {{ node | SCREAM }} => Some({{ node }}::from_repr(syntax.into_repr())),
 | 
			
		||||
            _ => None,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<R: TreeRoot<RaTypes>> {{ node }}Node<R> {
 | 
			
		||||
    pub fn borrowed(&self) -> {{ node }} {
 | 
			
		||||
        {{ node }}Node { syntax: self.syntax.borrowed() }
 | 
			
		||||
    }
 | 
			
		||||
    pub fn owned(&self) -> {{ node }}Node {
 | 
			
		||||
        {{ node }}Node { syntax: self.syntax.owned() }
 | 
			
		||||
    }
 | 
			
		||||
    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 | 
			
		||||
    fn to_owned(&self) -> TreePtr<{{ node }}> { TreePtr::cast(self.syntax.to_owned()) }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
{% endif %}
 | 
			
		||||
{% if methods.traits -%}
 | 
			
		||||
 | 
			
		||||
{%- for t in methods.traits -%}
 | 
			
		||||
impl<'a> ast::{{ t }}<'a> for {{ node }}<'a> {}
 | 
			
		||||
impl ast::{{ t }} for {{ node }} {}
 | 
			
		||||
{% endfor -%}
 | 
			
		||||
 | 
			
		||||
{%- endif -%}
 | 
			
		||||
 | 
			
		||||
impl<'a> {{ node }}<'a> {
 | 
			
		||||
impl {{ node }} {
 | 
			
		||||
{%- if methods.collections -%}
 | 
			
		||||
{%- for m in methods.collections -%}
 | 
			
		||||
{%- set method_name = m.0 -%}
 | 
			
		||||
{%- set ChildName = m.1 %}
 | 
			
		||||
    pub fn {{ method_name }}(self) -> impl Iterator<Item = {{ ChildName }}<'a>> + 'a {
 | 
			
		||||
    pub fn {{ method_name }}(&self) -> impl Iterator<Item = &{{ ChildName }}> {
 | 
			
		||||
        super::children(self)
 | 
			
		||||
    }
 | 
			
		||||
{% endfor -%}
 | 
			
		||||
@ -109,7 +112,7 @@ impl<'a> {{ node }}<'a> {
 | 
			
		||||
{%- set method_name = m.0 -%}
 | 
			
		||||
{%- set ChildName = m.1 %}
 | 
			
		||||
{%- endif %}
 | 
			
		||||
    pub fn {{ method_name }}(self) -> Option<{{ ChildName }}<'a>> {
 | 
			
		||||
    pub fn {{ method_name }}(&self) -> Option<&{{ ChildName }}> {
 | 
			
		||||
        super::child_opt(self)
 | 
			
		||||
    }
 | 
			
		||||
{% endfor -%}
 | 
			
		||||
 | 
			
		||||
@ -42,52 +42,42 @@ pub use crate::{
 | 
			
		||||
    ast::AstNode,
 | 
			
		||||
    lexer::{tokenize, Token},
 | 
			
		||||
    syntax_kinds::SyntaxKind,
 | 
			
		||||
    yellow::{
 | 
			
		||||
        Direction, OwnedRoot, RefRoot, SyntaxError, SyntaxNode, SyntaxNodeRef, TreeRoot, WalkEvent, Location,
 | 
			
		||||
    },
 | 
			
		||||
    yellow::{Direction, SyntaxError, SyntaxNode, WalkEvent, Location, TreePtr},
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
use ra_text_edit::AtomTextEdit;
 | 
			
		||||
use crate::yellow::GreenNode;
 | 
			
		||||
 | 
			
		||||
/// `SourceFileNode` represents a parse tree for a single Rust file.
 | 
			
		||||
pub use crate::ast::{SourceFile, SourceFileNode};
 | 
			
		||||
/// `SourceFile` represents a parse tree for a single Rust file.
 | 
			
		||||
pub use crate::ast::SourceFile;
 | 
			
		||||
 | 
			
		||||
impl SourceFileNode {
 | 
			
		||||
    fn new(green: GreenNode, errors: Vec<SyntaxError>) -> SourceFileNode {
 | 
			
		||||
impl SourceFile {
 | 
			
		||||
    fn new(green: GreenNode, errors: Vec<SyntaxError>) -> TreePtr<SourceFile> {
 | 
			
		||||
        let root = SyntaxNode::new(green, errors);
 | 
			
		||||
        if cfg!(debug_assertions) {
 | 
			
		||||
            utils::validate_block_structure(root.borrowed());
 | 
			
		||||
            utils::validate_block_structure(&root);
 | 
			
		||||
        }
 | 
			
		||||
        assert_eq!(root.kind(), SyntaxKind::SOURCE_FILE);
 | 
			
		||||
        ast::SourceFileNode { syntax: root }
 | 
			
		||||
        TreePtr::cast(root)
 | 
			
		||||
    }
 | 
			
		||||
    pub fn parse(text: &str) -> SourceFileNode {
 | 
			
		||||
    pub fn parse(text: &str) -> TreePtr<SourceFile> {
 | 
			
		||||
        let tokens = tokenize(&text);
 | 
			
		||||
        let (green, errors) =
 | 
			
		||||
            parser_impl::parse_with(yellow::GreenBuilder::new(), text, &tokens, grammar::root);
 | 
			
		||||
        SourceFileNode::new(green, errors)
 | 
			
		||||
        SourceFile::new(green, errors)
 | 
			
		||||
    }
 | 
			
		||||
    pub fn reparse(&self, edit: &AtomTextEdit) -> SourceFileNode {
 | 
			
		||||
    pub fn reparse(&self, edit: &AtomTextEdit) -> TreePtr<SourceFile> {
 | 
			
		||||
        self.incremental_reparse(edit)
 | 
			
		||||
            .unwrap_or_else(|| self.full_reparse(edit))
 | 
			
		||||
    }
 | 
			
		||||
    pub fn incremental_reparse(&self, edit: &AtomTextEdit) -> Option<SourceFileNode> {
 | 
			
		||||
    pub fn incremental_reparse(&self, edit: &AtomTextEdit) -> Option<TreePtr<SourceFile>> {
 | 
			
		||||
        reparsing::incremental_reparse(self.syntax(), edit, self.errors())
 | 
			
		||||
            .map(|(green_node, errors)| SourceFileNode::new(green_node, errors))
 | 
			
		||||
            .map(|(green_node, errors)| SourceFile::new(green_node, errors))
 | 
			
		||||
    }
 | 
			
		||||
    fn full_reparse(&self, edit: &AtomTextEdit) -> SourceFileNode {
 | 
			
		||||
    fn full_reparse(&self, edit: &AtomTextEdit) -> TreePtr<SourceFile> {
 | 
			
		||||
        let text =
 | 
			
		||||
            text_utils::replace_range(self.syntax().text().to_string(), edit.delete, &edit.insert);
 | 
			
		||||
        SourceFileNode::parse(&text)
 | 
			
		||||
    }
 | 
			
		||||
    /// Typed AST representation of the parse tree.
 | 
			
		||||
    pub fn ast(&self) -> ast::SourceFile {
 | 
			
		||||
        self.borrowed()
 | 
			
		||||
    }
 | 
			
		||||
    /// Untyped homogeneous representation of the parse tree.
 | 
			
		||||
    pub fn syntax(&self) -> SyntaxNodeRef {
 | 
			
		||||
        self.syntax.borrowed()
 | 
			
		||||
        SourceFile::parse(&text)
 | 
			
		||||
    }
 | 
			
		||||
    pub fn errors(&self) -> Vec<SyntaxError> {
 | 
			
		||||
        let mut errors = self.syntax.root_data().clone();
 | 
			
		||||
 | 
			
		||||
@ -4,12 +4,12 @@ use crate::lexer::{tokenize, Token};
 | 
			
		||||
use crate::parser_api::Parser;
 | 
			
		||||
use crate::parser_impl;
 | 
			
		||||
use crate::text_utils::replace_range;
 | 
			
		||||
use crate::yellow::{self, GreenNode, SyntaxError, SyntaxNodeRef};
 | 
			
		||||
use crate::yellow::{self, GreenNode, SyntaxError, SyntaxNode};
 | 
			
		||||
use crate::{SyntaxKind::*, TextRange, TextUnit};
 | 
			
		||||
use ra_text_edit::AtomTextEdit;
 | 
			
		||||
 | 
			
		||||
pub(crate) fn incremental_reparse(
 | 
			
		||||
    node: SyntaxNodeRef,
 | 
			
		||||
    node: &SyntaxNode,
 | 
			
		||||
    edit: &AtomTextEdit,
 | 
			
		||||
    errors: Vec<SyntaxError>,
 | 
			
		||||
) -> Option<(GreenNode, Vec<SyntaxError>)> {
 | 
			
		||||
@ -21,9 +21,9 @@ pub(crate) fn incremental_reparse(
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn reparse_leaf<'node>(
 | 
			
		||||
    node: SyntaxNodeRef<'node>,
 | 
			
		||||
    node: &'node SyntaxNode,
 | 
			
		||||
    edit: &AtomTextEdit,
 | 
			
		||||
) -> Option<(SyntaxNodeRef<'node>, GreenNode, Vec<SyntaxError>)> {
 | 
			
		||||
) -> Option<(&'node SyntaxNode, GreenNode, Vec<SyntaxError>)> {
 | 
			
		||||
    let node = algo::find_covering_node(node, edit.delete);
 | 
			
		||||
    match node.kind() {
 | 
			
		||||
        WHITESPACE | COMMENT | IDENT | STRING | RAW_STRING => {
 | 
			
		||||
@ -47,9 +47,9 @@ fn reparse_leaf<'node>(
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn reparse_block<'node>(
 | 
			
		||||
    node: SyntaxNodeRef<'node>,
 | 
			
		||||
    node: &'node SyntaxNode,
 | 
			
		||||
    edit: &AtomTextEdit,
 | 
			
		||||
) -> Option<(SyntaxNodeRef<'node>, GreenNode, Vec<SyntaxError>)> {
 | 
			
		||||
) -> Option<(&'node SyntaxNode, GreenNode, Vec<SyntaxError>)> {
 | 
			
		||||
    let (node, reparser) = find_reparsable_node(node, edit.delete)?;
 | 
			
		||||
    let text = get_text_after_edit(node, &edit);
 | 
			
		||||
    let tokens = tokenize(&text);
 | 
			
		||||
@ -61,7 +61,7 @@ fn reparse_block<'node>(
 | 
			
		||||
    Some((node, green, new_errors))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn get_text_after_edit(node: SyntaxNodeRef, edit: &AtomTextEdit) -> String {
 | 
			
		||||
fn get_text_after_edit(node: &SyntaxNode, edit: &AtomTextEdit) -> String {
 | 
			
		||||
    replace_range(
 | 
			
		||||
        node.text().to_string(),
 | 
			
		||||
        edit.delete - node.range().start(),
 | 
			
		||||
@ -77,17 +77,14 @@ fn is_contextual_kw(text: &str) -> bool {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type ParseFn = fn(&mut Parser);
 | 
			
		||||
fn find_reparsable_node(
 | 
			
		||||
    node: SyntaxNodeRef<'_>,
 | 
			
		||||
    range: TextRange,
 | 
			
		||||
) -> Option<(SyntaxNodeRef<'_>, ParseFn)> {
 | 
			
		||||
fn find_reparsable_node(node: &SyntaxNode, range: TextRange) -> Option<(&SyntaxNode, ParseFn)> {
 | 
			
		||||
    let node = algo::find_covering_node(node, range);
 | 
			
		||||
    return node
 | 
			
		||||
        .ancestors()
 | 
			
		||||
        .filter_map(|node| reparser(node).map(|r| (node, r)))
 | 
			
		||||
        .next();
 | 
			
		||||
 | 
			
		||||
    fn reparser(node: SyntaxNodeRef) -> Option<ParseFn> {
 | 
			
		||||
    fn reparser(node: &SyntaxNode) -> Option<ParseFn> {
 | 
			
		||||
        let res = match node.kind() {
 | 
			
		||||
            BLOCK => grammar::block,
 | 
			
		||||
            NAMED_FIELD_DEF_LIST => grammar::named_field_def_list,
 | 
			
		||||
@ -138,7 +135,7 @@ fn is_balanced(tokens: &[Token]) -> bool {
 | 
			
		||||
fn merge_errors(
 | 
			
		||||
    old_errors: Vec<SyntaxError>,
 | 
			
		||||
    new_errors: Vec<SyntaxError>,
 | 
			
		||||
    old_node: SyntaxNodeRef,
 | 
			
		||||
    old_node: &SyntaxNode,
 | 
			
		||||
    edit: &AtomTextEdit,
 | 
			
		||||
) -> Vec<SyntaxError> {
 | 
			
		||||
    let mut res = Vec::new();
 | 
			
		||||
@ -159,22 +156,22 @@ fn merge_errors(
 | 
			
		||||
mod tests {
 | 
			
		||||
    use test_utils::{extract_range, assert_eq_text};
 | 
			
		||||
 | 
			
		||||
    use crate::{SourceFileNode, text_utils::replace_range, utils::dump_tree };
 | 
			
		||||
    use crate::{SourceFile, AstNode, text_utils::replace_range, utils::dump_tree};
 | 
			
		||||
    use super::*;
 | 
			
		||||
 | 
			
		||||
    fn do_check<F>(before: &str, replace_with: &str, reparser: F)
 | 
			
		||||
    where
 | 
			
		||||
        for<'a> F: Fn(
 | 
			
		||||
            SyntaxNodeRef<'a>,
 | 
			
		||||
            &'a SyntaxNode,
 | 
			
		||||
            &AtomTextEdit,
 | 
			
		||||
        ) -> Option<(SyntaxNodeRef<'a>, GreenNode, Vec<SyntaxError>)>,
 | 
			
		||||
        ) -> Option<(&'a SyntaxNode, GreenNode, Vec<SyntaxError>)>,
 | 
			
		||||
    {
 | 
			
		||||
        let (range, before) = extract_range(before);
 | 
			
		||||
        let after = replace_range(before.clone(), range, replace_with);
 | 
			
		||||
 | 
			
		||||
        let fully_reparsed = SourceFileNode::parse(&after);
 | 
			
		||||
        let fully_reparsed = SourceFile::parse(&after);
 | 
			
		||||
        let incrementally_reparsed = {
 | 
			
		||||
            let f = SourceFileNode::parse(&before);
 | 
			
		||||
            let f = SourceFile::parse(&before);
 | 
			
		||||
            let edit = AtomTextEdit {
 | 
			
		||||
                delete: range,
 | 
			
		||||
                insert: replace_with.to_string(),
 | 
			
		||||
@ -183,7 +180,7 @@ mod tests {
 | 
			
		||||
                reparser(f.syntax(), &edit).expect("cannot incrementally reparse");
 | 
			
		||||
            let green_root = node.replace_with(green);
 | 
			
		||||
            let errors = super::merge_errors(f.errors(), new_errors, node, &edit);
 | 
			
		||||
            SourceFileNode::new(green_root, errors)
 | 
			
		||||
            SourceFile::new(green_root, errors)
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        assert_eq_text!(
 | 
			
		||||
 | 
			
		||||
@ -1,11 +1,11 @@
 | 
			
		||||
use crate::{SourceFileNode, SyntaxKind, SyntaxNodeRef, WalkEvent, AstNode};
 | 
			
		||||
use std::fmt::Write;
 | 
			
		||||
use std::str;
 | 
			
		||||
use std::{str, fmt::Write};
 | 
			
		||||
 | 
			
		||||
use crate::{SourceFile, SyntaxKind, WalkEvent, AstNode, SyntaxNode};
 | 
			
		||||
 | 
			
		||||
/// Parse a file and create a string representation of the resulting parse tree.
 | 
			
		||||
pub fn dump_tree(syntax: SyntaxNodeRef) -> String {
 | 
			
		||||
    let mut errors: Vec<_> = match syntax.ancestors().find_map(SourceFileNode::cast) {
 | 
			
		||||
        Some(file) => file.owned().errors(),
 | 
			
		||||
pub fn dump_tree(syntax: &SyntaxNode) -> String {
 | 
			
		||||
    let mut errors: Vec<_> = match syntax.ancestors().find_map(SourceFile::cast) {
 | 
			
		||||
        Some(file) => file.errors(),
 | 
			
		||||
        None => syntax.root_data().to_vec(),
 | 
			
		||||
    };
 | 
			
		||||
    errors.sort_by_key(|e| e.offset());
 | 
			
		||||
@ -48,14 +48,13 @@ pub fn dump_tree(syntax: SyntaxNodeRef) -> String {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn check_fuzz_invariants(text: &str) {
 | 
			
		||||
    let file = SourceFileNode::parse(text);
 | 
			
		||||
    let file = SourceFile::parse(text);
 | 
			
		||||
    let root = file.syntax();
 | 
			
		||||
    validate_block_structure(root);
 | 
			
		||||
    let _ = file.ast();
 | 
			
		||||
    let _ = file.errors();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub(crate) fn validate_block_structure(root: SyntaxNodeRef) {
 | 
			
		||||
pub(crate) fn validate_block_structure(root: &SyntaxNode) {
 | 
			
		||||
    let mut stack = Vec::new();
 | 
			
		||||
    for node in root.descendants() {
 | 
			
		||||
        match node.kind() {
 | 
			
		||||
 | 
			
		||||
@ -1,16 +1,15 @@
 | 
			
		||||
use crate::{
 | 
			
		||||
    algo::visit::{visitor_ctx, VisitorCtx},
 | 
			
		||||
    ast,
 | 
			
		||||
    SourceFileNode,
 | 
			
		||||
    yellow::SyntaxError,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
mod byte;
 | 
			
		||||
mod byte_string;
 | 
			
		||||
mod char;
 | 
			
		||||
mod string;
 | 
			
		||||
 | 
			
		||||
pub(crate) fn validate(file: &SourceFileNode) -> Vec<SyntaxError> {
 | 
			
		||||
use crate::{
 | 
			
		||||
    SourceFile, yellow::SyntaxError, AstNode,
 | 
			
		||||
    ast,
 | 
			
		||||
    algo::visit::{visitor_ctx, VisitorCtx},
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
pub(crate) fn validate(file: &SourceFile) -> Vec<SyntaxError> {
 | 
			
		||||
    let mut errors = Vec::new();
 | 
			
		||||
    for node in file.syntax().descendants() {
 | 
			
		||||
        let _ = visitor_ctx(&mut errors)
 | 
			
		||||
 | 
			
		||||
@ -11,7 +11,7 @@ use crate::{
 | 
			
		||||
    },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
pub(super) fn validate_byte_node(node: ast::Byte, errors: &mut Vec<SyntaxError>) {
 | 
			
		||||
pub(super) fn validate_byte_node(node: &ast::Byte, errors: &mut Vec<SyntaxError>) {
 | 
			
		||||
    let literal_text = node.text();
 | 
			
		||||
    let literal_range = node.syntax().range();
 | 
			
		||||
    let mut components = string_lexing::parse_byte_literal(literal_text);
 | 
			
		||||
@ -106,11 +106,11 @@ fn validate_byte_code_escape(text: &str, range: TextRange, errors: &mut Vec<Synt
 | 
			
		||||
 | 
			
		||||
#[cfg(test)]
 | 
			
		||||
mod test {
 | 
			
		||||
    use crate::SourceFileNode;
 | 
			
		||||
    use crate::{SourceFile, TreePtr};
 | 
			
		||||
 | 
			
		||||
    fn build_file(literal: &str) -> SourceFileNode {
 | 
			
		||||
    fn build_file(literal: &str) -> TreePtr<SourceFile> {
 | 
			
		||||
        let src = format!("const C: u8 = b'{}';", literal);
 | 
			
		||||
        SourceFileNode::parse(&src)
 | 
			
		||||
        SourceFile::parse(&src)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn assert_valid_byte(literal: &str) {
 | 
			
		||||
 | 
			
		||||
@ -9,7 +9,7 @@ use crate::{
 | 
			
		||||
 | 
			
		||||
use super::byte;
 | 
			
		||||
 | 
			
		||||
pub(crate) fn validate_byte_string_node(node: ast::ByteString, errors: &mut Vec<SyntaxError>) {
 | 
			
		||||
pub(crate) fn validate_byte_string_node(node: &ast::ByteString, errors: &mut Vec<SyntaxError>) {
 | 
			
		||||
    let literal_text = node.text();
 | 
			
		||||
    let literal_range = node.syntax().range();
 | 
			
		||||
    let mut components = string_lexing::parse_byte_string_literal(literal_text);
 | 
			
		||||
@ -43,12 +43,12 @@ pub(crate) fn validate_byte_string_node(node: ast::ByteString, errors: &mut Vec<
 | 
			
		||||
 | 
			
		||||
#[cfg(test)]
 | 
			
		||||
mod test {
 | 
			
		||||
    use crate::SourceFileNode;
 | 
			
		||||
    use crate::{SourceFile, TreePtr};
 | 
			
		||||
 | 
			
		||||
    fn build_file(literal: &str) -> SourceFileNode {
 | 
			
		||||
    fn build_file(literal: &str) -> TreePtr<SourceFile> {
 | 
			
		||||
        let src = format!(r#"const S: &'static [u8] = b"{}";"#, literal);
 | 
			
		||||
        println!("Source: {}", src);
 | 
			
		||||
        SourceFileNode::parse(&src)
 | 
			
		||||
        SourceFile::parse(&src)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn assert_valid_str(literal: &str) {
 | 
			
		||||
 | 
			
		||||
@ -14,7 +14,7 @@ use crate::{
 | 
			
		||||
    },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
pub(super) fn validate_char_node(node: ast::Char, errors: &mut Vec<SyntaxError>) {
 | 
			
		||||
pub(super) fn validate_char_node(node: &ast::Char, errors: &mut Vec<SyntaxError>) {
 | 
			
		||||
    let literal_text = node.text();
 | 
			
		||||
    let literal_range = node.syntax().range();
 | 
			
		||||
    let mut components = string_lexing::parse_char_literal(literal_text);
 | 
			
		||||
@ -175,11 +175,11 @@ fn validate_unicode_escape(text: &str, range: TextRange, errors: &mut Vec<Syntax
 | 
			
		||||
 | 
			
		||||
#[cfg(test)]
 | 
			
		||||
mod test {
 | 
			
		||||
    use crate::SourceFileNode;
 | 
			
		||||
    use crate::{SourceFile, TreePtr};
 | 
			
		||||
 | 
			
		||||
    fn build_file(literal: &str) -> SourceFileNode {
 | 
			
		||||
    fn build_file(literal: &str) -> TreePtr<SourceFile> {
 | 
			
		||||
        let src = format!("const C: char = '{}';", literal);
 | 
			
		||||
        SourceFileNode::parse(&src)
 | 
			
		||||
        SourceFile::parse(&src)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn assert_valid_char(literal: &str) {
 | 
			
		||||
 | 
			
		||||
@ -9,7 +9,7 @@ use crate::{
 | 
			
		||||
 | 
			
		||||
use super::char;
 | 
			
		||||
 | 
			
		||||
pub(crate) fn validate_string_node(node: ast::String, errors: &mut Vec<SyntaxError>) {
 | 
			
		||||
pub(crate) fn validate_string_node(node: &ast::String, errors: &mut Vec<SyntaxError>) {
 | 
			
		||||
    let literal_text = node.text();
 | 
			
		||||
    let literal_range = node.syntax().range();
 | 
			
		||||
    let mut components = string_lexing::parse_string_literal(literal_text);
 | 
			
		||||
@ -38,12 +38,12 @@ pub(crate) fn validate_string_node(node: ast::String, errors: &mut Vec<SyntaxErr
 | 
			
		||||
 | 
			
		||||
#[cfg(test)]
 | 
			
		||||
mod test {
 | 
			
		||||
    use crate::SourceFileNode;
 | 
			
		||||
    use crate::{SourceFile, TreePtr};
 | 
			
		||||
 | 
			
		||||
    fn build_file(literal: &str) -> SourceFileNode {
 | 
			
		||||
    fn build_file(literal: &str) -> TreePtr<SourceFile> {
 | 
			
		||||
        let src = format!(r#"const S: &'static str = "{}";"#, literal);
 | 
			
		||||
        println!("Source: {}", src);
 | 
			
		||||
        SourceFileNode::parse(&src)
 | 
			
		||||
        SourceFile::parse(&src)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn assert_valid_str(literal: &str) {
 | 
			
		||||
 | 
			
		||||
@ -4,15 +4,12 @@ mod syntax_text;
 | 
			
		||||
 | 
			
		||||
use self::syntax_text::SyntaxText;
 | 
			
		||||
use crate::{SmolStr, SyntaxKind, TextRange};
 | 
			
		||||
use rowan::Types;
 | 
			
		||||
use std::{
 | 
			
		||||
    fmt,
 | 
			
		||||
    hash::{Hash, Hasher},
 | 
			
		||||
};
 | 
			
		||||
use rowan::{Types, TransparentNewType};
 | 
			
		||||
use std::fmt;
 | 
			
		||||
 | 
			
		||||
pub(crate) use self::builder::GreenBuilder;
 | 
			
		||||
pub use self::syntax_error::{SyntaxError, SyntaxErrorKind, Location};
 | 
			
		||||
pub use rowan::{TreeRoot, WalkEvent};
 | 
			
		||||
pub use rowan::WalkEvent;
 | 
			
		||||
 | 
			
		||||
#[derive(Debug, Clone, Copy)]
 | 
			
		||||
pub enum RaTypes {}
 | 
			
		||||
@ -21,35 +18,19 @@ impl Types for RaTypes {
 | 
			
		||||
    type RootData = Vec<SyntaxError>;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub type OwnedRoot = ::rowan::OwnedRoot<RaTypes>;
 | 
			
		||||
pub type RefRoot<'a> = ::rowan::RefRoot<'a, RaTypes>;
 | 
			
		||||
 | 
			
		||||
pub type GreenNode = ::rowan::GreenNode<RaTypes>;
 | 
			
		||||
pub type TreePtr<T> = ::rowan::TreePtr<RaTypes, T>;
 | 
			
		||||
 | 
			
		||||
#[derive(Clone, Copy)]
 | 
			
		||||
pub struct SyntaxNode<R: TreeRoot<RaTypes> = OwnedRoot>(pub(crate) ::rowan::SyntaxNode<RaTypes, R>);
 | 
			
		||||
pub type SyntaxNodeRef<'a> = SyntaxNode<RefRoot<'a>>;
 | 
			
		||||
 | 
			
		||||
impl<R1, R2> PartialEq<SyntaxNode<R1>> for SyntaxNode<R2>
 | 
			
		||||
where
 | 
			
		||||
    R1: TreeRoot<RaTypes>,
 | 
			
		||||
    R2: TreeRoot<RaTypes>,
 | 
			
		||||
{
 | 
			
		||||
    fn eq(&self, other: &SyntaxNode<R1>) -> bool {
 | 
			
		||||
        self.0 == other.0
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<R: TreeRoot<RaTypes>> Eq for SyntaxNode<R> {}
 | 
			
		||||
impl<R: TreeRoot<RaTypes>> Hash for SyntaxNode<R> {
 | 
			
		||||
    fn hash<H: Hasher>(&self, state: &mut H) {
 | 
			
		||||
        self.0.hash(state)
 | 
			
		||||
    }
 | 
			
		||||
#[derive(PartialEq, Eq, Hash)]
 | 
			
		||||
#[repr(transparent)]
 | 
			
		||||
pub struct SyntaxNode(pub(crate) ::rowan::SyntaxNode<RaTypes>);
 | 
			
		||||
unsafe impl TransparentNewType for SyntaxNode {
 | 
			
		||||
    type Repr = ::rowan::SyntaxNode<RaTypes>;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl SyntaxNode {
 | 
			
		||||
    pub(crate) fn new(green: GreenNode, errors: Vec<SyntaxError>) -> SyntaxNode {
 | 
			
		||||
        SyntaxNode(::rowan::SyntaxNode::new(green, errors))
 | 
			
		||||
    pub(crate) fn new(green: GreenNode, errors: Vec<SyntaxError>) -> TreePtr<SyntaxNode> {
 | 
			
		||||
        TreePtr::cast(::rowan::SyntaxNode::new(green, errors))
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -59,45 +40,42 @@ pub enum Direction {
 | 
			
		||||
    Prev,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<'a> SyntaxNodeRef<'a> {
 | 
			
		||||
    pub fn leaf_text(self) -> Option<&'a SmolStr> {
 | 
			
		||||
impl SyntaxNode {
 | 
			
		||||
    pub fn leaf_text(&self) -> Option<&SmolStr> {
 | 
			
		||||
        self.0.leaf_text()
 | 
			
		||||
    }
 | 
			
		||||
    pub fn ancestors(self) -> impl Iterator<Item = SyntaxNodeRef<'a>> {
 | 
			
		||||
    pub fn ancestors(&self) -> impl Iterator<Item = &SyntaxNode> {
 | 
			
		||||
        crate::algo::generate(Some(self), |&node| node.parent())
 | 
			
		||||
    }
 | 
			
		||||
    pub fn descendants(self) -> impl Iterator<Item = SyntaxNodeRef<'a>> {
 | 
			
		||||
    pub fn descendants(&self) -> impl Iterator<Item = &SyntaxNode> {
 | 
			
		||||
        self.preorder().filter_map(|event| match event {
 | 
			
		||||
            WalkEvent::Enter(node) => Some(node),
 | 
			
		||||
            WalkEvent::Leave(_) => None,
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
    pub fn siblings(self, direction: Direction) -> impl Iterator<Item = SyntaxNodeRef<'a>> {
 | 
			
		||||
    pub fn siblings(&self, direction: Direction) -> impl Iterator<Item = &SyntaxNode> {
 | 
			
		||||
        crate::algo::generate(Some(self), move |&node| match direction {
 | 
			
		||||
            Direction::Next => node.next_sibling(),
 | 
			
		||||
            Direction::Prev => node.prev_sibling(),
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
    pub fn preorder(self) -> impl Iterator<Item = WalkEvent<SyntaxNodeRef<'a>>> {
 | 
			
		||||
    pub fn preorder(&self) -> impl Iterator<Item = WalkEvent<&SyntaxNode>> {
 | 
			
		||||
        self.0.preorder().map(|event| match event {
 | 
			
		||||
            WalkEvent::Enter(n) => WalkEvent::Enter(SyntaxNode(n)),
 | 
			
		||||
            WalkEvent::Leave(n) => WalkEvent::Leave(SyntaxNode(n)),
 | 
			
		||||
            WalkEvent::Enter(n) => WalkEvent::Enter(SyntaxNode::from_repr(n)),
 | 
			
		||||
            WalkEvent::Leave(n) => WalkEvent::Leave(SyntaxNode::from_repr(n)),
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<R: TreeRoot<RaTypes>> SyntaxNode<R> {
 | 
			
		||||
impl SyntaxNode {
 | 
			
		||||
    pub(crate) fn root_data(&self) -> &Vec<SyntaxError> {
 | 
			
		||||
        self.0.root_data()
 | 
			
		||||
    }
 | 
			
		||||
    pub(crate) fn replace_with(&self, replacement: GreenNode) -> GreenNode {
 | 
			
		||||
        self.0.replace_with(replacement)
 | 
			
		||||
        self.0.replace_self(replacement)
 | 
			
		||||
    }
 | 
			
		||||
    pub fn borrowed<'a>(&'a self) -> SyntaxNode<RefRoot<'a>> {
 | 
			
		||||
        SyntaxNode(self.0.borrowed())
 | 
			
		||||
    }
 | 
			
		||||
    pub fn owned(&self) -> SyntaxNode<OwnedRoot> {
 | 
			
		||||
        SyntaxNode(self.0.owned())
 | 
			
		||||
    pub fn to_owned(&self) -> TreePtr<SyntaxNode> {
 | 
			
		||||
        TreePtr::cast(self.0.to_owned())
 | 
			
		||||
    }
 | 
			
		||||
    pub fn kind(&self) -> SyntaxKind {
 | 
			
		||||
        self.0.kind()
 | 
			
		||||
@ -106,32 +84,32 @@ impl<R: TreeRoot<RaTypes>> SyntaxNode<R> {
 | 
			
		||||
        self.0.range()
 | 
			
		||||
    }
 | 
			
		||||
    pub fn text(&self) -> SyntaxText {
 | 
			
		||||
        SyntaxText::new(self.borrowed())
 | 
			
		||||
        SyntaxText::new(self)
 | 
			
		||||
    }
 | 
			
		||||
    pub fn is_leaf(&self) -> bool {
 | 
			
		||||
        self.0.is_leaf()
 | 
			
		||||
    }
 | 
			
		||||
    pub fn parent(&self) -> Option<SyntaxNode<R>> {
 | 
			
		||||
        self.0.parent().map(SyntaxNode)
 | 
			
		||||
    pub fn parent(&self) -> Option<&SyntaxNode> {
 | 
			
		||||
        self.0.parent().map(SyntaxNode::from_repr)
 | 
			
		||||
    }
 | 
			
		||||
    pub fn first_child(&self) -> Option<SyntaxNode<R>> {
 | 
			
		||||
        self.0.first_child().map(SyntaxNode)
 | 
			
		||||
    pub fn first_child(&self) -> Option<&SyntaxNode> {
 | 
			
		||||
        self.0.first_child().map(SyntaxNode::from_repr)
 | 
			
		||||
    }
 | 
			
		||||
    pub fn last_child(&self) -> Option<SyntaxNode<R>> {
 | 
			
		||||
        self.0.last_child().map(SyntaxNode)
 | 
			
		||||
    pub fn last_child(&self) -> Option<&SyntaxNode> {
 | 
			
		||||
        self.0.last_child().map(SyntaxNode::from_repr)
 | 
			
		||||
    }
 | 
			
		||||
    pub fn next_sibling(&self) -> Option<SyntaxNode<R>> {
 | 
			
		||||
        self.0.next_sibling().map(SyntaxNode)
 | 
			
		||||
    pub fn next_sibling(&self) -> Option<&SyntaxNode> {
 | 
			
		||||
        self.0.next_sibling().map(SyntaxNode::from_repr)
 | 
			
		||||
    }
 | 
			
		||||
    pub fn prev_sibling(&self) -> Option<SyntaxNode<R>> {
 | 
			
		||||
        self.0.prev_sibling().map(SyntaxNode)
 | 
			
		||||
    pub fn prev_sibling(&self) -> Option<&SyntaxNode> {
 | 
			
		||||
        self.0.prev_sibling().map(SyntaxNode::from_repr)
 | 
			
		||||
    }
 | 
			
		||||
    pub fn children(&self) -> SyntaxNodeChildren<R> {
 | 
			
		||||
    pub fn children(&self) -> SyntaxNodeChildren {
 | 
			
		||||
        SyntaxNodeChildren(self.0.children())
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<R: TreeRoot<RaTypes>> fmt::Debug for SyntaxNode<R> {
 | 
			
		||||
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()) {
 | 
			
		||||
@ -142,13 +120,13 @@ impl<R: TreeRoot<RaTypes>> fmt::Debug for SyntaxNode<R> {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Debug)]
 | 
			
		||||
pub struct SyntaxNodeChildren<R: TreeRoot<RaTypes>>(::rowan::SyntaxNodeChildren<RaTypes, R>);
 | 
			
		||||
pub struct SyntaxNodeChildren<'a>(::rowan::SyntaxNodeChildren<'a, RaTypes>);
 | 
			
		||||
 | 
			
		||||
impl<R: TreeRoot<RaTypes>> Iterator for SyntaxNodeChildren<R> {
 | 
			
		||||
    type Item = SyntaxNode<R>;
 | 
			
		||||
impl<'a> Iterator for SyntaxNodeChildren<'a> {
 | 
			
		||||
    type Item = &'a SyntaxNode;
 | 
			
		||||
 | 
			
		||||
    fn next(&mut self) -> Option<SyntaxNode<R>> {
 | 
			
		||||
        self.0.next().map(SyntaxNode)
 | 
			
		||||
    fn next(&mut self) -> Option<&'a SyntaxNode> {
 | 
			
		||||
        self.0.next().map(SyntaxNode::from_repr)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -3,17 +3,17 @@ use std::{fmt, ops};
 | 
			
		||||
use ra_text_edit::text_utils::contains_offset_nonstrict;
 | 
			
		||||
use crate::{
 | 
			
		||||
    text_utils::intersect,
 | 
			
		||||
    SyntaxNodeRef, TextRange, TextUnit,
 | 
			
		||||
    SyntaxNode, TextRange, TextUnit,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#[derive(Clone)]
 | 
			
		||||
pub struct SyntaxText<'a> {
 | 
			
		||||
    node: SyntaxNodeRef<'a>,
 | 
			
		||||
    node: &'a SyntaxNode,
 | 
			
		||||
    range: TextRange,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<'a> SyntaxText<'a> {
 | 
			
		||||
    pub(crate) fn new(node: SyntaxNodeRef<'a>) -> SyntaxText<'a> {
 | 
			
		||||
    pub(crate) fn new(node: &'a SyntaxNode) -> SyntaxText<'a> {
 | 
			
		||||
        SyntaxText {
 | 
			
		||||
            node,
 | 
			
		||||
            range: node.range(),
 | 
			
		||||
 | 
			
		||||
@ -9,8 +9,8 @@ use std::{
 | 
			
		||||
 | 
			
		||||
use test_utils::{project_dir, dir_tests, read_text, collect_tests};
 | 
			
		||||
use ra_syntax::{
 | 
			
		||||
    SourceFile, AstNode,
 | 
			
		||||
    utils::{check_fuzz_invariants, dump_tree},
 | 
			
		||||
    SourceFileNode,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#[test]
 | 
			
		||||
@ -27,7 +27,7 @@ fn parser_tests() {
 | 
			
		||||
        &test_data_dir(),
 | 
			
		||||
        &["parser/inline/ok", "parser/ok"],
 | 
			
		||||
        |text, path| {
 | 
			
		||||
            let file = SourceFileNode::parse(text);
 | 
			
		||||
            let file = SourceFile::parse(text);
 | 
			
		||||
            let errors = file.errors();
 | 
			
		||||
            assert_eq!(
 | 
			
		||||
                &*errors,
 | 
			
		||||
@ -42,7 +42,7 @@ fn parser_tests() {
 | 
			
		||||
        &test_data_dir(),
 | 
			
		||||
        &["parser/err", "parser/inline/err"],
 | 
			
		||||
        |text, path| {
 | 
			
		||||
            let file = SourceFileNode::parse(text);
 | 
			
		||||
            let file = SourceFile::parse(text);
 | 
			
		||||
            let errors = file.errors();
 | 
			
		||||
            assert_ne!(
 | 
			
		||||
                &*errors,
 | 
			
		||||
@ -85,7 +85,7 @@ fn self_hosting_parsing() {
 | 
			
		||||
    {
 | 
			
		||||
        count += 1;
 | 
			
		||||
        let text = read_text(entry.path());
 | 
			
		||||
        let node = SourceFileNode::parse(&text);
 | 
			
		||||
        let node = SourceFile::parse(&text);
 | 
			
		||||
        let errors = node.errors();
 | 
			
		||||
        assert_eq!(
 | 
			
		||||
            &*errors,
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user