diff options
Diffstat (limited to 'crates/ra_ide/src/completion/patterns.rs')
-rw-r--r-- | crates/ra_ide/src/completion/patterns.rs | 61 |
1 files changed, 47 insertions, 14 deletions
diff --git a/crates/ra_ide/src/completion/patterns.rs b/crates/ra_ide/src/completion/patterns.rs index bc39689ab..bc37196d5 100644 --- a/crates/ra_ide/src/completion/patterns.rs +++ b/crates/ra_ide/src/completion/patterns.rs | |||
@@ -6,16 +6,42 @@ use ra_syntax::{ | |||
6 | SyntaxNode, SyntaxToken, | 6 | SyntaxNode, SyntaxToken, |
7 | }; | 7 | }; |
8 | 8 | ||
9 | pub(crate) fn inside_trait(element: SyntaxElement) -> bool { | 9 | pub(crate) fn has_trait_parent(element: SyntaxElement) -> bool { |
10 | element.ancestors().find(|it| it.kind() == TRAIT_DEF).is_some() | 10 | not_same_range_ancestor(element) |
11 | .filter(|it| it.kind() == ITEM_LIST) | ||
12 | .and_then(|it| it.parent()) | ||
13 | .filter(|it| it.kind() == TRAIT_DEF) | ||
14 | .is_some() | ||
15 | } | ||
16 | |||
17 | pub(crate) fn has_impl_parent(element: SyntaxElement) -> bool { | ||
18 | not_same_range_ancestor(element) | ||
19 | .filter(|it| it.kind() == ITEM_LIST) | ||
20 | .and_then(|it| it.parent()) | ||
21 | .filter(|it| it.kind() == IMPL_DEF) | ||
22 | .is_some() | ||
23 | } | ||
24 | |||
25 | pub(crate) fn has_block_expr_parent(element: SyntaxElement) -> bool { | ||
26 | not_same_range_ancestor(element).filter(|it| it.kind() == BLOCK_EXPR).is_some() | ||
11 | } | 27 | } |
12 | 28 | ||
13 | pub(crate) fn has_bind_pat_parent(element: SyntaxElement) -> bool { | 29 | pub(crate) fn has_bind_pat_parent(element: SyntaxElement) -> bool { |
14 | element.ancestors().find(|it| it.kind() == BIND_PAT).is_some() | 30 | element.ancestors().find(|it| it.kind() == BIND_PAT).is_some() |
15 | } | 31 | } |
16 | 32 | ||
17 | pub(crate) fn has_ref_pat_parent(element: SyntaxElement) -> bool { | 33 | pub(crate) fn has_ref_parent(element: SyntaxElement) -> bool { |
18 | element.ancestors().find(|it| it.kind() == REF_PAT).is_some() | 34 | not_same_range_ancestor(element) |
35 | .filter(|it| it.kind() == REF_PAT || it.kind() == REF_EXPR) | ||
36 | .is_some() | ||
37 | } | ||
38 | |||
39 | pub(crate) fn is_match_arm(element: SyntaxElement) -> bool { | ||
40 | not_same_range_ancestor(element.clone()).filter(|it| it.kind() == MATCH_ARM).is_some() | ||
41 | && previous_sibling_or_ancestor_sibling(element) | ||
42 | .and_then(|it| it.into_token()) | ||
43 | .filter(|it| it.kind() == FAT_ARROW) | ||
44 | .is_some() | ||
19 | } | 45 | } |
20 | 46 | ||
21 | pub(crate) fn unsafe_is_prev(element: SyntaxElement) -> bool { | 47 | pub(crate) fn unsafe_is_prev(element: SyntaxElement) -> bool { |
@@ -34,10 +60,6 @@ pub(crate) fn if_is_prev(element: SyntaxElement) -> bool { | |||
34 | .is_some() | 60 | .is_some() |
35 | } | 61 | } |
36 | 62 | ||
37 | pub(crate) fn has_block_expr_parent(element: SyntaxElement) -> bool { | ||
38 | not_same_range_ancestor(element).filter(|it| it.kind() == BLOCK_EXPR).is_some() | ||
39 | } | ||
40 | |||
41 | pub(crate) fn has_trait_as_prev_sibling(element: SyntaxElement) -> bool { | 63 | pub(crate) fn has_trait_as_prev_sibling(element: SyntaxElement) -> bool { |
42 | previous_sibling_or_ancestor_sibling(element).filter(|it| it.kind() == TRAIT_DEF).is_some() | 64 | previous_sibling_or_ancestor_sibling(element).filter(|it| it.kind() == TRAIT_DEF).is_some() |
43 | } | 65 | } |
@@ -114,8 +136,9 @@ fn previous_sibling_or_ancestor_sibling(element: SyntaxElement) -> Option<Syntax | |||
114 | #[cfg(test)] | 136 | #[cfg(test)] |
115 | mod tests { | 137 | mod tests { |
116 | use super::{ | 138 | use super::{ |
117 | has_bind_pat_parent, has_block_expr_parent, has_impl_as_prev_sibling, has_ref_pat_parent, | 139 | has_bind_pat_parent, has_block_expr_parent, has_impl_as_prev_sibling, has_impl_parent, |
118 | has_trait_as_prev_sibling, if_is_prev, inside_trait, unsafe_is_prev, | 140 | has_ref_parent, has_trait_as_prev_sibling, has_trait_parent, if_is_prev, is_match_arm, |
141 | unsafe_is_prev, | ||
119 | }; | 142 | }; |
120 | use crate::completion::test_utils::check_pattern_is_applicable; | 143 | use crate::completion::test_utils::check_pattern_is_applicable; |
121 | 144 | ||
@@ -130,8 +153,13 @@ mod tests { | |||
130 | } | 153 | } |
131 | 154 | ||
132 | #[test] | 155 | #[test] |
133 | fn test_inside_trait() { | 156 | fn test_has_trait_parent() { |
134 | check_pattern_is_applicable(r"trait A { fn<|> }", inside_trait); | 157 | check_pattern_is_applicable(r"trait A { f<|> }", has_trait_parent); |
158 | } | ||
159 | |||
160 | #[test] | ||
161 | fn test_has_impl_parent() { | ||
162 | check_pattern_is_applicable(r"impl A { f<|> }", has_impl_parent); | ||
135 | } | 163 | } |
136 | 164 | ||
137 | #[test] | 165 | #[test] |
@@ -151,12 +179,12 @@ mod tests { | |||
151 | 179 | ||
152 | #[test] | 180 | #[test] |
153 | fn test_has_ref_pat_parent_in_func_parameters() { | 181 | fn test_has_ref_pat_parent_in_func_parameters() { |
154 | check_pattern_is_applicable(r"fn my_fn(&<|>) {}", has_ref_pat_parent); | 182 | check_pattern_is_applicable(r"fn my_fn(&m<|>) {}", has_ref_parent); |
155 | } | 183 | } |
156 | 184 | ||
157 | #[test] | 185 | #[test] |
158 | fn test_has_ref_pat_parent_in_let_statement() { | 186 | fn test_has_ref_pat_parent_in_let_statement() { |
159 | check_pattern_is_applicable(r"fn my_fn() { let &<|> }", has_ref_pat_parent); | 187 | check_pattern_is_applicable(r"fn my() { let &m<|> }", has_ref_parent); |
160 | } | 188 | } |
161 | 189 | ||
162 | #[test] | 190 | #[test] |
@@ -168,4 +196,9 @@ mod tests { | |||
168 | fn test_has_bind_pat_parent_in_let_statement() { | 196 | fn test_has_bind_pat_parent_in_let_statement() { |
169 | check_pattern_is_applicable(r"fn my_fn() { let m<|> }", has_bind_pat_parent); | 197 | check_pattern_is_applicable(r"fn my_fn() { let m<|> }", has_bind_pat_parent); |
170 | } | 198 | } |
199 | |||
200 | #[test] | ||
201 | fn test_is_match_arm() { | ||
202 | check_pattern_is_applicable(r"fn my_fn() { match () { () => m<|> } }", is_match_arm); | ||
203 | } | ||
171 | } | 204 | } |