aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_syntax/src/ast.rs
diff options
context:
space:
mode:
authorBenjamin Coenen <[email protected]>2020-04-11 21:54:22 +0100
committerBenjamin Coenen <[email protected]>2020-04-11 22:45:09 +0100
commit93bfc2d05d36a47dc05a1799210327473d702dbc (patch)
treedee25e78b24b5d1b23d73ae1009bddbd060927cf /crates/ra_syntax/src/ast.rs
parentd42346fed61f706d68fe888631a41ea5f2752d7f (diff)
parentfd06fe7b13045185ab4e630b0044aa9d8bbcdf8a (diff)
Improve autocompletion by looking on the type and name
Signed-off-by: Benjamin Coenen <[email protected]>
Diffstat (limited to 'crates/ra_syntax/src/ast.rs')
-rw-r--r--crates/ra_syntax/src/ast.rs44
1 files changed, 18 insertions, 26 deletions
diff --git a/crates/ra_syntax/src/ast.rs b/crates/ra_syntax/src/ast.rs
index a42eec91a..99c6b7219 100644
--- a/crates/ra_syntax/src/ast.rs
+++ b/crates/ra_syntax/src/ast.rs
@@ -42,11 +42,6 @@ pub trait AstNode {
42 fn syntax(&self) -> &SyntaxNode; 42 fn syntax(&self) -> &SyntaxNode;
43} 43}
44 44
45#[test]
46fn assert_ast_is_object_safe() {
47 fn _f(_: &dyn AstNode, _: &dyn NameOwner) {}
48}
49
50/// Like `AstNode`, but wraps tokens rather than interior nodes. 45/// Like `AstNode`, but wraps tokens rather than interior nodes.
51pub trait AstToken { 46pub trait AstToken {
52 fn can_cast(token: SyntaxKind) -> bool 47 fn can_cast(token: SyntaxKind) -> bool
@@ -64,22 +59,6 @@ pub trait AstToken {
64 } 59 }
65} 60}
66 61
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
83/// An iterator over `SyntaxNode` children of a particular AST type. 62/// An iterator over `SyntaxNode` children of a particular AST type.
84#[derive(Debug, Clone)] 63#[derive(Debug, Clone)]
85pub struct AstChildren<N> { 64pub struct AstChildren<N> {
@@ -100,12 +79,25 @@ impl<N: AstNode> Iterator for AstChildren<N> {
100 } 79 }
101} 80}
102 81
103fn child_opt<P: AstNode + ?Sized, C: AstNode>(parent: &P) -> Option<C> { 82mod support {
104 children(parent).next() 83 use super::{AstChildren, AstNode, SyntaxKind, SyntaxNode, SyntaxToken};
84
85 pub(super) fn child<N: AstNode>(parent: &SyntaxNode) -> Option<N> {
86 parent.children().find_map(N::cast)
87 }
88
89 pub(super) fn children<N: AstNode>(parent: &SyntaxNode) -> AstChildren<N> {
90 AstChildren::new(parent)
91 }
92
93 pub(super) fn token(parent: &SyntaxNode, kind: SyntaxKind) -> Option<SyntaxToken> {
94 parent.children_with_tokens().filter_map(|it| it.into_token()).find(|it| it.kind() == kind)
95 }
105} 96}
106 97
107fn children<P: AstNode + ?Sized, C: AstNode>(parent: &P) -> AstChildren<C> { 98#[test]
108 AstChildren::new(parent.syntax()) 99fn assert_ast_is_object_safe() {
100 fn _f(_: &dyn AstNode, _: &dyn NameOwner) {}
109} 101}
110 102
111#[test] 103#[test]
@@ -287,7 +279,7 @@ where
287 let pred = predicates.next().unwrap(); 279 let pred = predicates.next().unwrap();
288 let mut bounds = pred.type_bound_list().unwrap().bounds(); 280 let mut bounds = pred.type_bound_list().unwrap().bounds();
289 281
290 assert_eq!("'a", pred.lifetime().unwrap().text()); 282 assert_eq!("'a", pred.lifetime_token().unwrap().text());
291 283
292 assert_bound("'b", bounds.next()); 284 assert_bound("'b", bounds.next());
293 assert_bound("'c", bounds.next()); 285 assert_bound("'c", bounds.next());