From d3c90ded2b9a4f75e101fa3abc60cd3aebc439c9 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 17 Aug 2018 22:00:13 +0300 Subject: Borrowed AST --- crates/libsyntax2/src/algo/visit.rs | 6 +- crates/libsyntax2/src/ast/generated.rs | 436 ++++++++++++++-------------- crates/libsyntax2/src/ast/generated.rs.tera | 31 +- crates/libsyntax2/src/ast/mod.rs | 61 ++-- crates/libsyntax2/src/lib.rs | 2 +- crates/libsyntax2/src/utils.rs | 5 +- crates/libsyntax2/src/yellow/syntax.rs | 16 +- crates/libsyntax2/tests/test/main.rs | 2 +- 8 files changed, 284 insertions(+), 275 deletions(-) (limited to 'crates/libsyntax2') diff --git a/crates/libsyntax2/src/algo/visit.rs b/crates/libsyntax2/src/algo/visit.rs index 55eb72f59..a36c8f45e 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, RefRoot}; +use {SyntaxNodeRef, AstNode}; 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>, + where N: AstNode<'a>, 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>, + N: AstNode<'a>, F: FnOnce(N) -> >::Output, { type Output = >::Output; diff --git a/crates/libsyntax2/src/ast/generated.rs b/crates/libsyntax2/src/ast/generated.rs index 4fc405c8a..e8a87eba5 100644 --- a/crates/libsyntax2/src/ast/generated.rs +++ b/crates/libsyntax2/src/ast/generated.rs @@ -1,45 +1,45 @@ use { ast, - SyntaxNode, OwnedRoot, TreeRoot, AstNode, + SyntaxNodeRef, AstNode, SyntaxKind::*, }; // ArrayType #[derive(Debug, Clone, Copy)] -pub struct ArrayType { - syntax: SyntaxNode, +pub struct ArrayType<'a> { + syntax: SyntaxNodeRef<'a>, } -impl AstNode for ArrayType { - fn cast(syntax: SyntaxNode) -> Option { +impl<'a> AstNode<'a> for ArrayType<'a> { + fn cast(syntax: SyntaxNodeRef<'a>) -> Option { match syntax.kind() { ARRAY_TYPE => Some(ArrayType { syntax }), _ => None, } } - fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } } -impl ArrayType {} +impl<'a> ArrayType<'a> {} // Attr #[derive(Debug, Clone, Copy)] -pub struct Attr { - syntax: SyntaxNode, +pub struct Attr<'a> { + syntax: SyntaxNodeRef<'a>, } -impl AstNode for Attr { - fn cast(syntax: SyntaxNode) -> Option { +impl<'a> AstNode<'a> for Attr<'a> { + fn cast(syntax: SyntaxNodeRef<'a>) -> Option { match syntax.kind() { ATTR => Some(Attr { syntax }), _ => None, } } - fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } } -impl Attr { - pub fn value(&self) -> Option> { +impl<'a> Attr<'a> { + pub fn value(self) -> Option> { self.syntax() .children() .filter_map(TokenTree::cast) @@ -49,80 +49,80 @@ impl Attr { // ConstDef #[derive(Debug, Clone, Copy)] -pub struct ConstDef { - syntax: SyntaxNode, +pub struct ConstDef<'a> { + syntax: SyntaxNodeRef<'a>, } -impl AstNode for ConstDef { - fn cast(syntax: SyntaxNode) -> Option { +impl<'a> AstNode<'a> for ConstDef<'a> { + fn cast(syntax: SyntaxNodeRef<'a>) -> Option { match syntax.kind() { CONST_DEF => Some(ConstDef { syntax }), _ => None, } } - fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } } -impl ast::NameOwner for ConstDef {} -impl ast::AttrsOwner for ConstDef {} -impl ConstDef {} +impl<'a> ast::NameOwner<'a> for ConstDef<'a> {} +impl<'a> ast::AttrsOwner<'a> for ConstDef<'a> {} +impl<'a> ConstDef<'a> {} // DynTraitType #[derive(Debug, Clone, Copy)] -pub struct DynTraitType { - syntax: SyntaxNode, +pub struct DynTraitType<'a> { + syntax: SyntaxNodeRef<'a>, } -impl AstNode for DynTraitType { - fn cast(syntax: SyntaxNode) -> Option { +impl<'a> AstNode<'a> for DynTraitType<'a> { + fn cast(syntax: SyntaxNodeRef<'a>) -> Option { match syntax.kind() { DYN_TRAIT_TYPE => Some(DynTraitType { syntax }), _ => None, } } - fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } } -impl DynTraitType {} +impl<'a> DynTraitType<'a> {} // EnumDef #[derive(Debug, Clone, Copy)] -pub struct EnumDef { - syntax: SyntaxNode, +pub struct EnumDef<'a> { + syntax: SyntaxNodeRef<'a>, } -impl AstNode for EnumDef { - fn cast(syntax: SyntaxNode) -> Option { +impl<'a> AstNode<'a> for EnumDef<'a> { + fn cast(syntax: SyntaxNodeRef<'a>) -> Option { match syntax.kind() { ENUM_DEF => Some(EnumDef { syntax }), _ => None, } } - fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } } -impl ast::NameOwner for EnumDef {} -impl ast::AttrsOwner for EnumDef {} -impl EnumDef {} +impl<'a> ast::NameOwner<'a> for EnumDef<'a> {} +impl<'a> ast::AttrsOwner<'a> for EnumDef<'a> {} +impl<'a> EnumDef<'a> {} // File #[derive(Debug, Clone, Copy)] -pub struct File { - syntax: SyntaxNode, +pub struct File<'a> { + syntax: SyntaxNodeRef<'a>, } -impl AstNode for File { - fn cast(syntax: SyntaxNode) -> Option { +impl<'a> AstNode<'a> for File<'a> { + fn cast(syntax: SyntaxNodeRef<'a>) -> Option { match syntax.kind() { FILE => Some(File { syntax }), _ => None, } } - fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } } -impl File { - pub fn functions<'a>(&'a self) -> impl Iterator> + 'a { +impl<'a> File<'a> { + pub fn functions(self) -> impl Iterator> + 'a { self.syntax() .children() .filter_map(FnDef::cast) @@ -131,206 +131,206 @@ impl File { // FnDef #[derive(Debug, Clone, Copy)] -pub struct FnDef { - syntax: SyntaxNode, +pub struct FnDef<'a> { + syntax: SyntaxNodeRef<'a>, } -impl AstNode for FnDef { - fn cast(syntax: SyntaxNode) -> Option { +impl<'a> AstNode<'a> for FnDef<'a> { + fn cast(syntax: SyntaxNodeRef<'a>) -> Option { match syntax.kind() { FN_DEF => Some(FnDef { syntax }), _ => None, } } - fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } } -impl ast::NameOwner for FnDef {} -impl ast::AttrsOwner for FnDef {} -impl FnDef {} +impl<'a> ast::NameOwner<'a> for FnDef<'a> {} +impl<'a> ast::AttrsOwner<'a> for FnDef<'a> {} +impl<'a> FnDef<'a> {} // FnPointerType #[derive(Debug, Clone, Copy)] -pub struct FnPointerType { - syntax: SyntaxNode, +pub struct FnPointerType<'a> { + syntax: SyntaxNodeRef<'a>, } -impl AstNode for FnPointerType { - fn cast(syntax: SyntaxNode) -> Option { +impl<'a> AstNode<'a> for FnPointerType<'a> { + fn cast(syntax: SyntaxNodeRef<'a>) -> Option { match syntax.kind() { FN_POINTER_TYPE => Some(FnPointerType { syntax }), _ => None, } } - fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } } -impl FnPointerType {} +impl<'a> FnPointerType<'a> {} // ForType #[derive(Debug, Clone, Copy)] -pub struct ForType { - syntax: SyntaxNode, +pub struct ForType<'a> { + syntax: SyntaxNodeRef<'a>, } -impl AstNode for ForType { - fn cast(syntax: SyntaxNode) -> Option { +impl<'a> AstNode<'a> for ForType<'a> { + fn cast(syntax: SyntaxNodeRef<'a>) -> Option { match syntax.kind() { FOR_TYPE => Some(ForType { syntax }), _ => None, } } - fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } } -impl ForType {} +impl<'a> ForType<'a> {} // ImplItem #[derive(Debug, Clone, Copy)] -pub struct ImplItem { - syntax: SyntaxNode, +pub struct ImplItem<'a> { + syntax: SyntaxNodeRef<'a>, } -impl AstNode for ImplItem { - fn cast(syntax: SyntaxNode) -> Option { +impl<'a> AstNode<'a> for ImplItem<'a> { + fn cast(syntax: SyntaxNodeRef<'a>) -> Option { match syntax.kind() { IMPL_ITEM => Some(ImplItem { syntax }), _ => None, } } - fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } } -impl ImplItem {} +impl<'a> ImplItem<'a> {} // ImplTraitType #[derive(Debug, Clone, Copy)] -pub struct ImplTraitType { - syntax: SyntaxNode, +pub struct ImplTraitType<'a> { + syntax: SyntaxNodeRef<'a>, } -impl AstNode for ImplTraitType { - fn cast(syntax: SyntaxNode) -> Option { +impl<'a> AstNode<'a> for ImplTraitType<'a> { + fn cast(syntax: SyntaxNodeRef<'a>) -> Option { match syntax.kind() { IMPL_TRAIT_TYPE => Some(ImplTraitType { syntax }), _ => None, } } - fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } } -impl ImplTraitType {} +impl<'a> ImplTraitType<'a> {} // Module #[derive(Debug, Clone, Copy)] -pub struct Module { - syntax: SyntaxNode, +pub struct Module<'a> { + syntax: SyntaxNodeRef<'a>, } -impl AstNode for Module { - fn cast(syntax: SyntaxNode) -> Option { +impl<'a> AstNode<'a> for Module<'a> { + fn cast(syntax: SyntaxNodeRef<'a>) -> Option { match syntax.kind() { MODULE => Some(Module { syntax }), _ => None, } } - fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } } -impl ast::NameOwner for Module {} -impl ast::AttrsOwner for Module {} -impl Module {} +impl<'a> ast::NameOwner<'a> for Module<'a> {} +impl<'a> ast::AttrsOwner<'a> for Module<'a> {} +impl<'a> Module<'a> {} // Name #[derive(Debug, Clone, Copy)] -pub struct Name { - syntax: SyntaxNode, +pub struct Name<'a> { + syntax: SyntaxNodeRef<'a>, } -impl AstNode for Name { - fn cast(syntax: SyntaxNode) -> Option { +impl<'a> AstNode<'a> for Name<'a> { + fn cast(syntax: SyntaxNodeRef<'a>) -> Option { match syntax.kind() { NAME => Some(Name { syntax }), _ => None, } } - fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } } -impl Name {} +impl<'a> Name<'a> {} // NameRef #[derive(Debug, Clone, Copy)] -pub struct NameRef { - syntax: SyntaxNode, +pub struct NameRef<'a> { + syntax: SyntaxNodeRef<'a>, } -impl AstNode for NameRef { - fn cast(syntax: SyntaxNode) -> Option { +impl<'a> AstNode<'a> for NameRef<'a> { + fn cast(syntax: SyntaxNodeRef<'a>) -> Option { match syntax.kind() { NAME_REF => Some(NameRef { syntax }), _ => None, } } - fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } } -impl NameRef {} +impl<'a> NameRef<'a> {} // NamedField #[derive(Debug, Clone, Copy)] -pub struct NamedField { - syntax: SyntaxNode, +pub struct NamedField<'a> { + syntax: SyntaxNodeRef<'a>, } -impl AstNode for NamedField { - fn cast(syntax: SyntaxNode) -> Option { +impl<'a> AstNode<'a> for NamedField<'a> { + fn cast(syntax: SyntaxNodeRef<'a>) -> Option { match syntax.kind() { NAMED_FIELD => Some(NamedField { syntax }), _ => None, } } - fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } } -impl ast::NameOwner for NamedField {} -impl ast::AttrsOwner for NamedField {} -impl NamedField {} +impl<'a> ast::NameOwner<'a> for NamedField<'a> {} +impl<'a> ast::AttrsOwner<'a> for NamedField<'a> {} +impl<'a> NamedField<'a> {} // NeverType #[derive(Debug, Clone, Copy)] -pub struct NeverType { - syntax: SyntaxNode, +pub struct NeverType<'a> { + syntax: SyntaxNodeRef<'a>, } -impl AstNode for NeverType { - fn cast(syntax: SyntaxNode) -> Option { +impl<'a> AstNode<'a> for NeverType<'a> { + fn cast(syntax: SyntaxNodeRef<'a>) -> Option { match syntax.kind() { NEVER_TYPE => Some(NeverType { syntax }), _ => None, } } - fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } } -impl NeverType {} +impl<'a> NeverType<'a> {} // NominalDef #[derive(Debug, Clone, Copy)] -pub enum NominalDef { - StructDef(StructDef), - EnumDef(EnumDef), +pub enum NominalDef<'a> { + StructDef(StructDef<'a>), + EnumDef(EnumDef<'a>), } -impl AstNode for NominalDef { - fn cast(syntax: SyntaxNode) -> Option { +impl<'a> AstNode<'a> for NominalDef<'a> { + fn cast(syntax: SyntaxNodeRef<'a>) -> Option { match syntax.kind() { STRUCT_DEF => Some(NominalDef::StructDef(StructDef { syntax })), ENUM_DEF => Some(NominalDef::EnumDef(EnumDef { syntax })), _ => None, } } - fn syntax(&self) -> &SyntaxNode { + fn syntax(self) -> SyntaxNodeRef<'a> { match self { NominalDef::StructDef(inner) => inner.syntax(), NominalDef::EnumDef(inner) => inner.syntax(), @@ -338,157 +338,157 @@ impl AstNode for NominalDef { } } -impl ast::AttrsOwner for NominalDef {} -impl NominalDef {} +impl<'a> ast::AttrsOwner<'a> for NominalDef<'a> {} +impl<'a> NominalDef<'a> {} // ParenType #[derive(Debug, Clone, Copy)] -pub struct ParenType { - syntax: SyntaxNode, +pub struct ParenType<'a> { + syntax: SyntaxNodeRef<'a>, } -impl AstNode for ParenType { - fn cast(syntax: SyntaxNode) -> Option { +impl<'a> AstNode<'a> for ParenType<'a> { + fn cast(syntax: SyntaxNodeRef<'a>) -> Option { match syntax.kind() { PAREN_TYPE => Some(ParenType { syntax }), _ => None, } } - fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } } -impl ParenType {} +impl<'a> ParenType<'a> {} // PathType #[derive(Debug, Clone, Copy)] -pub struct PathType { - syntax: SyntaxNode, +pub struct PathType<'a> { + syntax: SyntaxNodeRef<'a>, } -impl AstNode for PathType { - fn cast(syntax: SyntaxNode) -> Option { +impl<'a> AstNode<'a> for PathType<'a> { + fn cast(syntax: SyntaxNodeRef<'a>) -> Option { match syntax.kind() { PATH_TYPE => Some(PathType { syntax }), _ => None, } } - fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } } -impl PathType {} +impl<'a> PathType<'a> {} // PlaceholderType #[derive(Debug, Clone, Copy)] -pub struct PlaceholderType { - syntax: SyntaxNode, +pub struct PlaceholderType<'a> { + syntax: SyntaxNodeRef<'a>, } -impl AstNode for PlaceholderType { - fn cast(syntax: SyntaxNode) -> Option { +impl<'a> AstNode<'a> for PlaceholderType<'a> { + fn cast(syntax: SyntaxNodeRef<'a>) -> Option { match syntax.kind() { PLACEHOLDER_TYPE => Some(PlaceholderType { syntax }), _ => None, } } - fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } } -impl PlaceholderType {} +impl<'a> PlaceholderType<'a> {} // PointerType #[derive(Debug, Clone, Copy)] -pub struct PointerType { - syntax: SyntaxNode, +pub struct PointerType<'a> { + syntax: SyntaxNodeRef<'a>, } -impl AstNode for PointerType { - fn cast(syntax: SyntaxNode) -> Option { +impl<'a> AstNode<'a> for PointerType<'a> { + fn cast(syntax: SyntaxNodeRef<'a>) -> Option { match syntax.kind() { POINTER_TYPE => Some(PointerType { syntax }), _ => None, } } - fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } } -impl PointerType {} +impl<'a> PointerType<'a> {} // ReferenceType #[derive(Debug, Clone, Copy)] -pub struct ReferenceType { - syntax: SyntaxNode, +pub struct ReferenceType<'a> { + syntax: SyntaxNodeRef<'a>, } -impl AstNode for ReferenceType { - fn cast(syntax: SyntaxNode) -> Option { +impl<'a> AstNode<'a> for ReferenceType<'a> { + fn cast(syntax: SyntaxNodeRef<'a>) -> Option { match syntax.kind() { REFERENCE_TYPE => Some(ReferenceType { syntax }), _ => None, } } - fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } } -impl ReferenceType {} +impl<'a> ReferenceType<'a> {} // SliceType #[derive(Debug, Clone, Copy)] -pub struct SliceType { - syntax: SyntaxNode, +pub struct SliceType<'a> { + syntax: SyntaxNodeRef<'a>, } -impl AstNode for SliceType { - fn cast(syntax: SyntaxNode) -> Option { +impl<'a> AstNode<'a> for SliceType<'a> { + fn cast(syntax: SyntaxNodeRef<'a>) -> Option { match syntax.kind() { SLICE_TYPE => Some(SliceType { syntax }), _ => None, } } - fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } } -impl SliceType {} +impl<'a> SliceType<'a> {} // StaticDef #[derive(Debug, Clone, Copy)] -pub struct StaticDef { - syntax: SyntaxNode, +pub struct StaticDef<'a> { + syntax: SyntaxNodeRef<'a>, } -impl AstNode for StaticDef { - fn cast(syntax: SyntaxNode) -> Option { +impl<'a> AstNode<'a> for StaticDef<'a> { + fn cast(syntax: SyntaxNodeRef<'a>) -> Option { match syntax.kind() { STATIC_DEF => Some(StaticDef { syntax }), _ => None, } } - fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } } -impl ast::NameOwner for StaticDef {} -impl ast::AttrsOwner for StaticDef {} -impl StaticDef {} +impl<'a> ast::NameOwner<'a> for StaticDef<'a> {} +impl<'a> ast::AttrsOwner<'a> for StaticDef<'a> {} +impl<'a> StaticDef<'a> {} // StructDef #[derive(Debug, Clone, Copy)] -pub struct StructDef { - syntax: SyntaxNode, +pub struct StructDef<'a> { + syntax: SyntaxNodeRef<'a>, } -impl AstNode for StructDef { - fn cast(syntax: SyntaxNode) -> Option { +impl<'a> AstNode<'a> for StructDef<'a> { + fn cast(syntax: SyntaxNodeRef<'a>) -> Option { match syntax.kind() { STRUCT_DEF => Some(StructDef { syntax }), _ => None, } } - fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } } -impl ast::NameOwner for StructDef {} -impl ast::AttrsOwner for StructDef {} -impl StructDef { - pub fn fields<'a>(&'a self) -> impl Iterator> + 'a { +impl<'a> ast::NameOwner<'a> for StructDef<'a> {} +impl<'a> ast::AttrsOwner<'a> for StructDef<'a> {} +impl<'a> StructDef<'a> { + pub fn fields(self) -> impl Iterator> + 'a { self.syntax() .children() .filter_map(NamedField::cast) @@ -497,100 +497,100 @@ impl StructDef { // TokenTree #[derive(Debug, Clone, Copy)] -pub struct TokenTree { - syntax: SyntaxNode, +pub struct TokenTree<'a> { + syntax: SyntaxNodeRef<'a>, } -impl AstNode for TokenTree { - fn cast(syntax: SyntaxNode) -> Option { +impl<'a> AstNode<'a> for TokenTree<'a> { + fn cast(syntax: SyntaxNodeRef<'a>) -> Option { match syntax.kind() { TOKEN_TREE => Some(TokenTree { syntax }), _ => None, } } - fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } } -impl TokenTree {} +impl<'a> TokenTree<'a> {} // TraitDef #[derive(Debug, Clone, Copy)] -pub struct TraitDef { - syntax: SyntaxNode, +pub struct TraitDef<'a> { + syntax: SyntaxNodeRef<'a>, } -impl AstNode for TraitDef { - fn cast(syntax: SyntaxNode) -> Option { +impl<'a> AstNode<'a> for TraitDef<'a> { + fn cast(syntax: SyntaxNodeRef<'a>) -> Option { match syntax.kind() { TRAIT_DEF => Some(TraitDef { syntax }), _ => None, } } - fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } } -impl ast::NameOwner for TraitDef {} -impl ast::AttrsOwner for TraitDef {} -impl TraitDef {} +impl<'a> ast::NameOwner<'a> for TraitDef<'a> {} +impl<'a> ast::AttrsOwner<'a> for TraitDef<'a> {} +impl<'a> TraitDef<'a> {} // TupleType #[derive(Debug, Clone, Copy)] -pub struct TupleType { - syntax: SyntaxNode, +pub struct TupleType<'a> { + syntax: SyntaxNodeRef<'a>, } -impl AstNode for TupleType { - fn cast(syntax: SyntaxNode) -> Option { +impl<'a> AstNode<'a> for TupleType<'a> { + fn cast(syntax: SyntaxNodeRef<'a>) -> Option { match syntax.kind() { TUPLE_TYPE => Some(TupleType { syntax }), _ => None, } } - fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } } -impl TupleType {} +impl<'a> TupleType<'a> {} // TypeDef #[derive(Debug, Clone, Copy)] -pub struct TypeDef { - syntax: SyntaxNode, +pub struct TypeDef<'a> { + syntax: SyntaxNodeRef<'a>, } -impl AstNode for TypeDef { - fn cast(syntax: SyntaxNode) -> Option { +impl<'a> AstNode<'a> for TypeDef<'a> { + fn cast(syntax: SyntaxNodeRef<'a>) -> Option { match syntax.kind() { TYPE_DEF => Some(TypeDef { syntax }), _ => None, } } - fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } } -impl ast::NameOwner for TypeDef {} -impl ast::AttrsOwner for TypeDef {} -impl TypeDef {} +impl<'a> ast::NameOwner<'a> for TypeDef<'a> {} +impl<'a> ast::AttrsOwner<'a> for TypeDef<'a> {} +impl<'a> TypeDef<'a> {} // TypeRef #[derive(Debug, Clone, Copy)] -pub enum TypeRef { - ParenType(ParenType), - TupleType(TupleType), - NeverType(NeverType), - PathType(PathType), - PointerType(PointerType), - ArrayType(ArrayType), - SliceType(SliceType), - ReferenceType(ReferenceType), - PlaceholderType(PlaceholderType), - FnPointerType(FnPointerType), - ForType(ForType), - ImplTraitType(ImplTraitType), - DynTraitType(DynTraitType), -} - -impl AstNode for TypeRef { - fn cast(syntax: SyntaxNode) -> Option { +pub enum TypeRef<'a> { + ParenType(ParenType<'a>), + TupleType(TupleType<'a>), + NeverType(NeverType<'a>), + PathType(PathType<'a>), + PointerType(PointerType<'a>), + ArrayType(ArrayType<'a>), + SliceType(SliceType<'a>), + ReferenceType(ReferenceType<'a>), + PlaceholderType(PlaceholderType<'a>), + FnPointerType(FnPointerType<'a>), + ForType(ForType<'a>), + ImplTraitType(ImplTraitType<'a>), + DynTraitType(DynTraitType<'a>), +} + +impl<'a> AstNode<'a> for TypeRef<'a> { + fn cast(syntax: SyntaxNodeRef<'a>) -> Option { match syntax.kind() { PAREN_TYPE => Some(TypeRef::ParenType(ParenType { syntax })), TUPLE_TYPE => Some(TypeRef::TupleType(TupleType { syntax })), @@ -608,7 +608,7 @@ impl AstNode for TypeRef { _ => None, } } - fn syntax(&self) -> &SyntaxNode { + fn syntax(self) -> SyntaxNodeRef<'a> { match self { TypeRef::ParenType(inner) => inner.syntax(), TypeRef::TupleType(inner) => inner.syntax(), @@ -627,5 +627,5 @@ impl AstNode for TypeRef { } } -impl TypeRef {} +impl<'a> TypeRef<'a> {} diff --git a/crates/libsyntax2/src/ast/generated.rs.tera b/crates/libsyntax2/src/ast/generated.rs.tera index f83da0326..0572cceaa 100644 --- a/crates/libsyntax2/src/ast/generated.rs.tera +++ b/crates/libsyntax2/src/ast/generated.rs.tera @@ -1,21 +1,20 @@ -use std::sync::Arc; use { ast, - SyntaxNode, SyntaxRoot, TreeRoot, AstNode, + SyntaxNodeRef, AstNode, SyntaxKind::*, }; {% for node, methods in ast %} // {{ node }} {%- if methods.enum %} #[derive(Debug, Clone, Copy)] -pub enum {{ node }}> { +pub enum {{ node }}<'a> { {%- for kind in methods.enum %} - {{ kind }}({{ kind }}), + {{ kind }}({{ kind }}<'a>), {%- endfor %} } -impl AstNode for {{ node }} { - fn cast(syntax: SyntaxNode) -> Option { +impl<'a> AstNode<'a> for {{ node }}<'a> { + fn cast(syntax: SyntaxNodeRef<'a>) -> Option { match syntax.kind() { {%- for kind in methods.enum %} {{ kind | SCREAM }} => Some({{ node }}::{{ kind }}({{ kind }} { syntax })), @@ -23,7 +22,7 @@ impl AstNode for {{ node }} { _ => None, } } - fn syntax(&self) -> &SyntaxNode { + fn syntax(self) -> SyntaxNodeRef<'a> { match self { {%- for kind in methods.enum %} {{ node }}::{{ kind }}(inner) => inner.syntax(), @@ -33,32 +32,32 @@ impl AstNode for {{ node }} { } {% else %} #[derive(Debug, Clone, Copy)] -pub struct {{ node }}> { - syntax: SyntaxNode, +pub struct {{ node }}<'a> { + syntax: SyntaxNodeRef<'a>, } -impl AstNode for {{ node }} { - fn cast(syntax: SyntaxNode) -> Option { +impl<'a> AstNode<'a> for {{ node }}<'a> { + fn cast(syntax: SyntaxNodeRef<'a>) -> Option { match syntax.kind() { {{ node | SCREAM }} => Some({{ node }} { syntax }), _ => None, } } - fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } } {% endif %} {% if methods.traits -%} {%- for t in methods.traits -%} -impl ast::{{ t }} for {{ node }} {} +impl<'a> ast::{{ t }}<'a> for {{ node }}<'a> {} {% endfor -%} {%- endif -%} -impl {{ node }} { +impl<'a> {{ node }}<'a> { {%- if methods.collections -%} {%- for m in methods.collections -%} {%- set method_name = m.0 -%} {%- set ChildName = m.1 %} - pub fn {{ method_name }}<'a>(&'a self) -> impl Iterator> + 'a { + pub fn {{ method_name }}(self) -> impl Iterator> + 'a { self.syntax() .children() .filter_map({{ ChildName }}::cast) @@ -70,7 +69,7 @@ impl {{ node }} { {%- for m in methods.options -%} {%- set method_name = m.0 -%} {%- set ChildName = m.1 %} - pub fn {{ method_name }}(&self) -> Option<{{ ChildName }}> { + pub fn {{ method_name }}(self) -> Option<{{ ChildName }}<'a>> { self.syntax() .children() .filter_map({{ ChildName }}::cast) diff --git a/crates/libsyntax2/src/ast/mod.rs b/crates/libsyntax2/src/ast/mod.rs index b52230e9c..46509b5ec 100644 --- a/crates/libsyntax2/src/ast/mod.rs +++ b/crates/libsyntax2/src/ast/mod.rs @@ -4,22 +4,19 @@ use itertools::Itertools; use smol_str::SmolStr; use { - SyntaxNode, SyntaxNodeRef, OwnedRoot, TreeRoot, SyntaxError, + SyntaxNode, SyntaxNodeRef, TreeRoot, SyntaxError, SyntaxKind::*, }; pub use self::generated::*; -pub trait AstNode { - fn cast(syntax: SyntaxNode) -> Option +pub trait AstNode<'a>: Clone + Copy { + fn cast(syntax: SyntaxNodeRef<'a>) -> Option where Self: Sized; - fn syntax(&self) -> &SyntaxNode; - fn syntax_ref<'a>(&'a self) -> SyntaxNodeRef<'a> where R: 'a { - self.syntax().as_ref() - } + fn syntax(self) -> SyntaxNodeRef<'a>; } -pub trait NameOwner: AstNode { - fn name(&self) -> Option> { +pub trait NameOwner<'a>: AstNode<'a> { + fn name(self) -> Option> { self.syntax() .children() .filter_map(Name::cast) @@ -27,27 +24,37 @@ pub trait NameOwner: AstNode { } } -pub trait AttrsOwner: AstNode { - fn attrs<'a>(&'a self) -> Box> + 'a> where R: 'a { +pub trait AttrsOwner<'a>: AstNode<'a> { + fn attrs(&self) -> Box> + 'a> { let it = self.syntax().children() .filter_map(Attr::cast); Box::new(it) } } -impl File { - pub fn parse(text: &str) -> Self { - File::cast(::parse(text)).unwrap() - } +#[derive(Clone, Debug)] +pub struct ParsedFile { + root: SyntaxNode } -impl File { +impl ParsedFile { + pub fn parse(text: &str) -> Self { + let root = ::parse(text); + ParsedFile { root } + } + pub fn ast(&self) -> File { + File::cast(self.syntax()).unwrap() + } + pub fn syntax(&self) -> SyntaxNodeRef { + self.root.as_ref() + } pub fn errors(&self) -> Vec { self.syntax().root.syntax_root().errors.clone() } + } -impl FnDef { +impl<'a> FnDef<'a> { pub fn has_atom_attr(&self, atom: &str) -> bool { self.attrs() .filter_map(|x| x.as_atom()) @@ -55,7 +62,7 @@ impl FnDef { } } -impl Attr { +impl<'a> Attr<'a> { pub fn as_atom(&self) -> Option { let tt = self.value()?; let (_bra, attr, _ket) = tt.syntax().children().collect_tuple()?; @@ -66,7 +73,7 @@ impl Attr { } } - pub fn as_call(&self) -> Option<(SmolStr, TokenTree)> { + pub fn as_call(&self) -> Option<(SmolStr, TokenTree<'a>)> { let tt = self.value()?; let (_bra, attr, args, _ket) = tt.syntax().children().collect_tuple()?; let args = TokenTree::cast(args)?; @@ -78,7 +85,7 @@ impl Attr { } } -impl Name { +impl<'a> Name<'a> { pub fn text(&self) -> SmolStr { let ident = self.syntax().first_child() .unwrap(); @@ -86,7 +93,7 @@ impl Name { } } -impl NameRef { +impl<'a> NameRef<'a> { pub fn text(&self) -> SmolStr { let ident = self.syntax().first_child() .unwrap(); @@ -94,22 +101,22 @@ impl NameRef { } } -impl ImplItem { - pub fn target_type(&self) -> Option> { +impl<'a> ImplItem<'a> { + pub fn target_type(&self) -> Option> { match self.target() { (Some(t), None) | (_, Some(t)) => Some(t), _ => None, } } - pub fn target_trait(&self) -> Option> { + pub fn target_trait(&self) -> Option> { match self.target() { (Some(t), Some(_)) => Some(t), _ => None, } } - fn target(&self) -> (Option>, Option>) { + fn target(&self) -> (Option>, Option>) { let mut types = self.syntax().children().filter_map(TypeRef::cast); let first = types.next(); let second = types.next(); @@ -117,9 +124,9 @@ impl ImplItem { } } -impl Module { +impl<'a> Module<'a> { pub fn has_semi(&self) -> bool { - match self.syntax_ref().last_child() { + match self.syntax().last_child() { None => false, Some(node) => node.kind() == SEMI, } diff --git a/crates/libsyntax2/src/lib.rs b/crates/libsyntax2/src/lib.rs index 0e40fb65f..e837a8d2d 100644 --- a/crates/libsyntax2/src/lib.rs +++ b/crates/libsyntax2/src/lib.rs @@ -41,7 +41,7 @@ mod yellow; pub mod utils; pub use { - ast::{AstNode, File}, + ast::{AstNode, ParsedFile}, lexer::{tokenize, Token}, syntax_kinds::SyntaxKind, text_unit::{TextRange, TextUnit}, diff --git a/crates/libsyntax2/src/utils.rs b/crates/libsyntax2/src/utils.rs index 4f60aa2a8..fbe48dd71 100644 --- a/crates/libsyntax2/src/utils.rs +++ b/crates/libsyntax2/src/utils.rs @@ -1,12 +1,11 @@ use std::fmt::Write; use { algo::walk::{walk, WalkEvent}, - SyntaxNode, TreeRoot, + SyntaxNodeRef, 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(); +pub fn dump_tree(syntax: SyntaxNodeRef) -> String { let mut errors: Vec<_> = syntax.root.syntax_root().errors.iter().cloned().collect(); errors.sort_by_key(|e| e.offset); let mut err_pos = 0; diff --git a/crates/libsyntax2/src/yellow/syntax.rs b/crates/libsyntax2/src/yellow/syntax.rs index ef82ba408..87e4a159d 100644 --- a/crates/libsyntax2/src/yellow/syntax.rs +++ b/crates/libsyntax2/src/yellow/syntax.rs @@ -71,12 +71,16 @@ impl SyntaxNode { self.red().green().text() } - pub fn children<'a>(&'a self) -> impl Iterator> + 'a { - let red = self.red(); - let n_children = red.n_children(); - (0..n_children).map(move |i| SyntaxNode { - root: self.root.clone(), - red: red.get_child(i).unwrap(), + pub fn children(&self) -> impl Iterator> { + let red = self.red; + let n_children = self.red().n_children(); + let root = self.root.clone(); + (0..n_children).map(move |i| { + let red = unsafe { red.get(&root) }; + SyntaxNode { + root: root.clone(), + red: red.get_child(i).unwrap(), + } }) } diff --git a/crates/libsyntax2/tests/test/main.rs b/crates/libsyntax2/tests/test/main.rs index 802dba0e9..d35935c64 100644 --- a/crates/libsyntax2/tests/test/main.rs +++ b/crates/libsyntax2/tests/test/main.rs @@ -21,7 +21,7 @@ fn lexer_tests() { fn parser_tests() { dir_tests(&["parser/inline", "parser/ok", "parser/err"], |text| { let file = libsyntax2::parse(text); - libsyntax2::utils::dump_tree(&file) + libsyntax2::utils::dump_tree(file.as_ref()) }) } -- cgit v1.2.3