aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_syntax/src/ast.rs
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2019-07-18 17:23:05 +0100
committerAleksey Kladov <[email protected]>2019-07-19 11:16:24 +0100
commitd402974aa0af6de290245a9d2a69a5d56c4fa610 (patch)
treedf4a0e38e548f9f74592e00a2c5a7d37bab3c4c2 /crates/ra_syntax/src/ast.rs
parent58d4983ba5745975446d60f2886d96f8d2adf0f2 (diff)
migrate ra_syntax to the new rowan API
Diffstat (limited to 'crates/ra_syntax/src/ast.rs')
-rw-r--r--crates/ra_syntax/src/ast.rs36
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;
9use std::marker::PhantomData; 9use std::marker::PhantomData;
10 10
11use crate::{ 11use 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.
28pub trait AstNode: 28pub 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.
38pub trait AstToken<'a> { 36pub 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)]
50pub struct AstChildren<'a, N> { 48pub struct AstChildren<N> {
51 inner: SyntaxNodeChildren<'a>, 49 inner: SyntaxNodeChildren,
52 ph: PhantomData<N>, 50 ph: PhantomData<N>,
53} 51}
54 52
55impl<'a, N> AstChildren<'a, N> { 53impl<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
61impl<'a, N: AstNode + 'a> Iterator for AstChildren<'a, N> { 59impl<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
68fn child_opt<P: AstNode, C: AstNode>(parent: &P) -> Option<&C> { 66fn child_opt<P: AstNode + ?Sized, C: AstNode>(parent: &P) -> Option<C> {
69 children(parent).next() 67 children(parent).next()
70} 68}
71 69
72fn children<P: AstNode, C: AstNode>(parent: &P) -> AstChildren<C> { 70fn 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]
125fn test_where_predicates() { 123fn 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