diff options
Diffstat (limited to 'crates/ra_syntax/src/ast.rs')
-rw-r--r-- | crates/ra_syntax/src/ast.rs | 36 |
1 files changed, 17 insertions, 19 deletions
diff --git a/crates/ra_syntax/src/ast.rs b/crates/ra_syntax/src/ast.rs index 3dcf39f7e..fe00e78d1 100644 --- a/crates/ra_syntax/src/ast.rs +++ b/crates/ra_syntax/src/ast.rs | |||
@@ -9,7 +9,7 @@ mod expr_extensions; | |||
9 | use std::marker::PhantomData; | 9 | use std::marker::PhantomData; |
10 | 10 | ||
11 | use crate::{ | 11 | use crate::{ |
12 | syntax_node::{SyntaxNode, SyntaxNodeChildren, SyntaxToken, TreeArc}, | 12 | syntax_node::{SyntaxNode, SyntaxNodeChildren, SyntaxToken}, |
13 | SmolStr, | 13 | SmolStr, |
14 | }; | 14 | }; |
15 | 15 | ||
@@ -25,51 +25,49 @@ pub use self::{ | |||
25 | /// conversion itself has zero runtime cost: ast and syntax nodes have exactly | 25 | /// conversion itself has zero runtime cost: ast and syntax nodes have exactly |
26 | /// the same representation: a pointer to the tree root and a pointer to the | 26 | /// the same representation: a pointer to the tree root and a pointer to the |
27 | /// node itself. | 27 | /// node itself. |
28 | pub trait AstNode: | 28 | pub trait AstNode { |
29 | rowan::TransparentNewType<Repr = rowan::SyntaxNode> + ToOwned<Owned = TreeArc<Self>> | 29 | fn cast(syntax: SyntaxNode) -> Option<Self> |
30 | { | ||
31 | fn cast(syntax: &SyntaxNode) -> Option<&Self> | ||
32 | where | 30 | where |
33 | Self: Sized; | 31 | Self: Sized; |
34 | fn syntax(&self) -> &SyntaxNode; | 32 | fn syntax(&self) -> &SyntaxNode; |
35 | } | 33 | } |
36 | 34 | ||
37 | /// Like `AstNode`, but wraps tokens rather than interior nodes. | 35 | /// Like `AstNode`, but wraps tokens rather than interior nodes. |
38 | pub trait AstToken<'a> { | 36 | pub trait AstToken { |
39 | fn cast(token: SyntaxToken<'a>) -> Option<Self> | 37 | fn cast(token: SyntaxToken) -> Option<Self> |
40 | where | 38 | where |
41 | Self: Sized; | 39 | Self: Sized; |
42 | fn syntax(&self) -> SyntaxToken<'a>; | 40 | fn syntax(&self) -> &SyntaxToken; |
43 | fn text(&self) -> &'a SmolStr { | 41 | fn text(&self) -> &SmolStr { |
44 | self.syntax().text() | 42 | self.syntax().text() |
45 | } | 43 | } |
46 | } | 44 | } |
47 | 45 | ||
48 | /// An iterator over `SyntaxNode` children of a particular AST type. | 46 | /// An iterator over `SyntaxNode` children of a particular AST type. |
49 | #[derive(Debug)] | 47 | #[derive(Debug)] |
50 | pub struct AstChildren<'a, N> { | 48 | pub struct AstChildren<N> { |
51 | inner: SyntaxNodeChildren<'a>, | 49 | inner: SyntaxNodeChildren, |
52 | ph: PhantomData<N>, | 50 | ph: PhantomData<N>, |
53 | } | 51 | } |
54 | 52 | ||
55 | impl<'a, N> AstChildren<'a, N> { | 53 | impl<N> AstChildren<N> { |
56 | fn new(parent: &'a SyntaxNode) -> Self { | 54 | fn new(parent: &SyntaxNode) -> Self { |
57 | AstChildren { inner: parent.children(), ph: PhantomData } | 55 | AstChildren { inner: parent.children(), ph: PhantomData } |
58 | } | 56 | } |
59 | } | 57 | } |
60 | 58 | ||
61 | impl<'a, N: AstNode + 'a> Iterator for AstChildren<'a, N> { | 59 | impl<N: AstNode> Iterator for AstChildren<N> { |
62 | type Item = &'a N; | 60 | type Item = N; |
63 | fn next(&mut self) -> Option<&'a N> { | 61 | fn next(&mut self) -> Option<N> { |
64 | self.inner.by_ref().find_map(N::cast) | 62 | self.inner.by_ref().find_map(N::cast) |
65 | } | 63 | } |
66 | } | 64 | } |
67 | 65 | ||
68 | fn child_opt<P: AstNode, C: AstNode>(parent: &P) -> Option<&C> { | 66 | fn child_opt<P: AstNode + ?Sized, C: AstNode>(parent: &P) -> Option<C> { |
69 | children(parent).next() | 67 | children(parent).next() |
70 | } | 68 | } |
71 | 69 | ||
72 | fn children<P: AstNode, C: AstNode>(parent: &P) -> AstChildren<C> { | 70 | fn children<P: AstNode + ?Sized, C: AstNode>(parent: &P) -> AstChildren<C> { |
73 | AstChildren::new(parent.syntax()) | 71 | AstChildren::new(parent.syntax()) |
74 | } | 72 | } |
75 | 73 | ||
@@ -123,7 +121,7 @@ fn test_doc_comment_preserves_indents() { | |||
123 | 121 | ||
124 | #[test] | 122 | #[test] |
125 | fn test_where_predicates() { | 123 | fn test_where_predicates() { |
126 | fn assert_bound(text: &str, bound: Option<&TypeBound>) { | 124 | fn assert_bound(text: &str, bound: Option<TypeBound>) { |
127 | assert_eq!(text, bound.unwrap().syntax().text().to_string()); | 125 | assert_eq!(text, bound.unwrap().syntax().text().to_string()); |
128 | } | 126 | } |
129 | 127 | ||