aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_syntax/src/ast.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_syntax/src/ast.rs')
-rw-r--r--crates/ra_syntax/src/ast.rs28
1 files changed, 25 insertions, 3 deletions
diff --git a/crates/ra_syntax/src/ast.rs b/crates/ra_syntax/src/ast.rs
index 26fafb469..15a8279f3 100644
--- a/crates/ra_syntax/src/ast.rs
+++ b/crates/ra_syntax/src/ast.rs
@@ -21,7 +21,7 @@ pub use self::{
21 AttrKind, FieldKind, PathSegmentKind, SelfParamKind, SlicePatComponents, StructKind, 21 AttrKind, FieldKind, PathSegmentKind, SelfParamKind, SlicePatComponents, StructKind,
22 TypeBoundKind, VisibilityKind, 22 TypeBoundKind, VisibilityKind,
23 }, 23 },
24 generated::*, 24 generated::{nodes::*, tokens::*},
25 tokens::*, 25 tokens::*,
26 traits::*, 26 traits::*,
27}; 27};
@@ -30,7 +30,7 @@ pub use self::{
30/// conversion itself has zero runtime cost: ast and syntax nodes have exactly 30/// conversion itself has zero runtime cost: ast and syntax nodes have exactly
31/// the same representation: a pointer to the tree root and a pointer to the 31/// the same representation: a pointer to the tree root and a pointer to the
32/// node itself. 32/// node itself.
33pub trait AstNode: std::fmt::Display { 33pub trait AstNode {
34 fn can_cast(kind: SyntaxKind) -> bool 34 fn can_cast(kind: SyntaxKind) -> bool
35 where 35 where
36 Self: Sized; 36 Self: Sized;
@@ -49,15 +49,37 @@ fn assert_ast_is_object_safe() {
49 49
50/// Like `AstNode`, but wraps tokens rather than interior nodes. 50/// Like `AstNode`, but wraps tokens rather than interior nodes.
51pub trait AstToken { 51pub trait AstToken {
52 fn cast(token: SyntaxToken) -> Option<Self> 52 fn can_cast(token: SyntaxKind) -> bool
53 where 53 where
54 Self: Sized; 54 Self: Sized;
55
56 fn cast(syntax: SyntaxToken) -> Option<Self>
57 where
58 Self: Sized;
59
55 fn syntax(&self) -> &SyntaxToken; 60 fn syntax(&self) -> &SyntaxToken;
61
56 fn text(&self) -> &SmolStr { 62 fn text(&self) -> &SmolStr {
57 self.syntax().text() 63 self.syntax().text()
58 } 64 }
59} 65}
60 66
67mod support {
68 use super::{AstChildren, AstNode, AstToken, SyntaxNode};
69
70 pub(super) fn child<N: AstNode>(parent: &SyntaxNode) -> Option<N> {
71 parent.children().find_map(N::cast)
72 }
73
74 pub(super) fn children<N: AstNode>(parent: &SyntaxNode) -> AstChildren<N> {
75 AstChildren::new(parent)
76 }
77
78 pub(super) fn token<T: AstToken>(parent: &SyntaxNode) -> Option<T> {
79 parent.children_with_tokens().filter_map(|it| it.into_token()).find_map(T::cast)
80 }
81}
82
61/// An iterator over `SyntaxNode` children of a particular AST type. 83/// An iterator over `SyntaxNode` children of a particular AST type.
62#[derive(Debug, Clone)] 84#[derive(Debug, Clone)]
63pub struct AstChildren<N> { 85pub struct AstChildren<N> {