aboutsummaryrefslogtreecommitdiff
path: root/crates/ide_completion/src/patterns.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ide_completion/src/patterns.rs')
-rw-r--r--crates/ide_completion/src/patterns.rs58
1 files changed, 23 insertions, 35 deletions
diff --git a/crates/ide_completion/src/patterns.rs b/crates/ide_completion/src/patterns.rs
index 3d8a83ed8..04f2c532b 100644
--- a/crates/ide_completion/src/patterns.rs
+++ b/crates/ide_completion/src/patterns.rs
@@ -4,7 +4,7 @@ use syntax::{
4 algo::non_trivia_sibling, 4 algo::non_trivia_sibling,
5 ast::{self, LoopBodyOwner}, 5 ast::{self, LoopBodyOwner},
6 match_ast, AstNode, Direction, NodeOrToken, SyntaxElement, 6 match_ast, AstNode, Direction, NodeOrToken, SyntaxElement,
7 SyntaxKind::*, 7 SyntaxKind::{self, *},
8 SyntaxNode, SyntaxToken, T, 8 SyntaxNode, SyntaxToken, T,
9}; 9};
10 10
@@ -73,6 +73,7 @@ fn test_has_block_expr_parent() {
73pub(crate) fn has_bind_pat_parent(element: SyntaxElement) -> bool { 73pub(crate) fn has_bind_pat_parent(element: SyntaxElement) -> bool {
74 element.ancestors().any(|it| it.kind() == IDENT_PAT) 74 element.ancestors().any(|it| it.kind() == IDENT_PAT)
75} 75}
76
76#[test] 77#[test]
77fn test_has_bind_pat_parent() { 78fn test_has_bind_pat_parent() {
78 check_pattern_is_applicable(r"fn my_fn(m$0) {}", has_bind_pat_parent); 79 check_pattern_is_applicable(r"fn my_fn(m$0) {}", has_bind_pat_parent);
@@ -91,11 +92,10 @@ fn test_has_ref_parent() {
91} 92}
92 93
93pub(crate) fn has_item_list_or_source_file_parent(element: SyntaxElement) -> bool { 94pub(crate) fn has_item_list_or_source_file_parent(element: SyntaxElement) -> bool {
94 let ancestor = not_same_range_ancestor(element); 95 match not_same_range_ancestor(element) {
95 if !ancestor.is_some() { 96 Some(it) => it.kind() == SOURCE_FILE || it.kind() == ITEM_LIST,
96 return true; 97 None => true,
97 } 98 }
98 ancestor.filter(|it| it.kind() == SOURCE_FILE || it.kind() == ITEM_LIST).is_some()
99} 99}
100#[test] 100#[test]
101fn test_has_item_list_or_source_file_parent() { 101fn test_has_item_list_or_source_file_parent() {
@@ -134,42 +134,30 @@ fn test_for_is_prev2() {
134 check_pattern_is_applicable(r"for i i$0", for_is_prev2); 134 check_pattern_is_applicable(r"for i i$0", for_is_prev2);
135} 135}
136 136
137pub(crate) fn has_trait_as_prev_sibling(element: SyntaxElement) -> bool { 137pub(crate) fn has_prev_sibling(element: SyntaxElement, kind: SyntaxKind) -> bool {
138 previous_sibling_or_ancestor_sibling(element).filter(|it| it.kind() == TRAIT).is_some() 138 previous_sibling_or_ancestor_sibling(element).filter(|it| it.kind() == kind).is_some()
139}
140#[test]
141fn test_has_trait_as_prev_sibling() {
142 check_pattern_is_applicable(r"trait A w$0 {}", has_trait_as_prev_sibling);
143}
144
145pub(crate) fn has_impl_as_prev_sibling(element: SyntaxElement) -> bool {
146 previous_sibling_or_ancestor_sibling(element).filter(|it| it.kind() == IMPL).is_some()
147} 139}
148#[test] 140#[test]
149fn test_has_impl_as_prev_sibling() { 141fn test_has_impl_as_prev_sibling() {
150 check_pattern_is_applicable(r"impl A w$0 {}", has_impl_as_prev_sibling); 142 check_pattern_is_applicable(r"impl A w$0 {}", |it| has_prev_sibling(it, IMPL));
151} 143}
152 144
153pub(crate) fn is_in_loop_body(element: SyntaxElement) -> bool { 145pub(crate) fn is_in_loop_body(element: SyntaxElement) -> bool {
154 for node in element.ancestors() { 146 element
155 if node.kind() == FN || node.kind() == CLOSURE_EXPR { 147 .ancestors()
156 break; 148 .take_while(|it| it.kind() != FN && it.kind() != CLOSURE_EXPR)
157 } 149 .find_map(|it| {
158 let loop_body = match_ast! { 150 let loop_body = match_ast! {
159 match node { 151 match it {
160 ast::ForExpr(it) => it.loop_body(), 152 ast::ForExpr(it) => it.loop_body(),
161 ast::WhileExpr(it) => it.loop_body(), 153 ast::WhileExpr(it) => it.loop_body(),
162 ast::LoopExpr(it) => it.loop_body(), 154 ast::LoopExpr(it) => it.loop_body(),
163 _ => None, 155 _ => None,
164 } 156 }
165 }; 157 };
166 if let Some(body) = loop_body { 158 loop_body.filter(|it| it.syntax().text_range().contains_range(element.text_range()))
167 if body.syntax().text_range().contains_range(element.text_range()) { 159 })
168 return true; 160 .is_some()
169 }
170 }
171 }
172 false
173} 161}
174 162
175fn not_same_range_ancestor(element: SyntaxElement) -> Option<SyntaxNode> { 163fn not_same_range_ancestor(element: SyntaxElement) -> Option<SyntaxNode> {