aboutsummaryrefslogtreecommitdiff
path: root/crates/ide/src/completion
diff options
context:
space:
mode:
authorIgor Aleksanov <[email protected]>2020-10-17 09:17:58 +0100
committerIgor Aleksanov <[email protected]>2020-10-17 09:17:58 +0100
commit99c435939c941fe5216c39bc136769098abbbfea (patch)
treeb4259ce1810c3cd6c2bea62bae499415b764728d /crates/ide/src/completion
parent6f573bd84f4564f11b08db720401ae16a0f42f2f (diff)
Scan all ancestors for the impl trait block check
Diffstat (limited to 'crates/ide/src/completion')
-rw-r--r--crates/ide/src/completion/completion_context.rs12
-rw-r--r--crates/ide/src/completion/patterns.rs19
2 files changed, 17 insertions, 14 deletions
diff --git a/crates/ide/src/completion/completion_context.rs b/crates/ide/src/completion/completion_context.rs
index cff0afae9..d9f90477c 100644
--- a/crates/ide/src/completion/completion_context.rs
+++ b/crates/ide/src/completion/completion_context.rs
@@ -18,8 +18,8 @@ use crate::{
18 patterns::{ 18 patterns::{
19 fn_is_prev, for_is_prev2, has_bind_pat_parent, has_block_expr_parent, 19 fn_is_prev, for_is_prev2, has_bind_pat_parent, has_block_expr_parent,
20 has_field_list_parent, has_impl_as_prev_sibling, has_impl_parent, 20 has_field_list_parent, has_impl_as_prev_sibling, has_impl_parent,
21 has_impl_trait_parent, has_item_list_or_source_file_parent, has_ref_parent, 21 has_item_list_or_source_file_parent, has_ref_parent, has_trait_as_prev_sibling,
22 has_trait_as_prev_sibling, has_trait_parent, if_is_prev, is_in_loop_body, is_match_arm, 22 has_trait_parent, if_is_prev, inside_impl_trait_block, is_in_loop_body, is_match_arm,
23 unsafe_is_prev, 23 unsafe_is_prev,
24 }, 24 },
25 CompletionConfig, 25 CompletionConfig,
@@ -87,7 +87,7 @@ pub(crate) struct CompletionContext<'a> {
87 pub(super) in_loop_body: bool, 87 pub(super) in_loop_body: bool,
88 pub(super) has_trait_parent: bool, 88 pub(super) has_trait_parent: bool,
89 pub(super) has_impl_parent: bool, 89 pub(super) has_impl_parent: bool,
90 pub(super) has_impl_trait_parent: bool, 90 pub(super) inside_impl_trait_block: bool,
91 pub(super) has_field_list_parent: bool, 91 pub(super) has_field_list_parent: bool,
92 pub(super) trait_as_prev_sibling: bool, 92 pub(super) trait_as_prev_sibling: bool,
93 pub(super) impl_as_prev_sibling: bool, 93 pub(super) impl_as_prev_sibling: bool,
@@ -172,7 +172,7 @@ impl<'a> CompletionContext<'a> {
172 block_expr_parent: false, 172 block_expr_parent: false,
173 has_trait_parent: false, 173 has_trait_parent: false,
174 has_impl_parent: false, 174 has_impl_parent: false,
175 has_impl_trait_parent: false, 175 inside_impl_trait_block: false,
176 has_field_list_parent: false, 176 has_field_list_parent: false,
177 trait_as_prev_sibling: false, 177 trait_as_prev_sibling: false,
178 impl_as_prev_sibling: false, 178 impl_as_prev_sibling: false,
@@ -234,7 +234,7 @@ impl<'a> CompletionContext<'a> {
234 /// Exception for this case is `impl Trait for Foo`, where we would like to hint trait method names. 234 /// Exception for this case is `impl Trait for Foo`, where we would like to hint trait method names.
235 /// - `for _ i<|>` -- obviously, it'll be "in" keyword. 235 /// - `for _ i<|>` -- obviously, it'll be "in" keyword.
236 pub(crate) fn no_completion_required(&self) -> bool { 236 pub(crate) fn no_completion_required(&self) -> bool {
237 (self.fn_is_prev && !self.has_impl_trait_parent) || self.for_is_prev2 237 (self.fn_is_prev && !self.inside_impl_trait_block) || self.for_is_prev2
238 } 238 }
239 239
240 /// The range of the identifier that is being completed. 240 /// The range of the identifier that is being completed.
@@ -260,7 +260,7 @@ impl<'a> CompletionContext<'a> {
260 self.in_loop_body = is_in_loop_body(syntax_element.clone()); 260 self.in_loop_body = is_in_loop_body(syntax_element.clone());
261 self.has_trait_parent = has_trait_parent(syntax_element.clone()); 261 self.has_trait_parent = has_trait_parent(syntax_element.clone());
262 self.has_impl_parent = has_impl_parent(syntax_element.clone()); 262 self.has_impl_parent = has_impl_parent(syntax_element.clone());
263 self.has_impl_trait_parent = has_impl_trait_parent(syntax_element.clone()); 263 self.inside_impl_trait_block = inside_impl_trait_block(syntax_element.clone());
264 self.has_field_list_parent = has_field_list_parent(syntax_element.clone()); 264 self.has_field_list_parent = has_field_list_parent(syntax_element.clone());
265 self.impl_as_prev_sibling = has_impl_as_prev_sibling(syntax_element.clone()); 265 self.impl_as_prev_sibling = has_impl_as_prev_sibling(syntax_element.clone());
266 self.trait_as_prev_sibling = has_trait_as_prev_sibling(syntax_element.clone()); 266 self.trait_as_prev_sibling = has_trait_as_prev_sibling(syntax_element.clone());
diff --git a/crates/ide/src/completion/patterns.rs b/crates/ide/src/completion/patterns.rs
index bdce7a6e7..cf6d5947d 100644
--- a/crates/ide/src/completion/patterns.rs
+++ b/crates/ide/src/completion/patterns.rs
@@ -35,19 +35,22 @@ fn test_has_impl_parent() {
35 check_pattern_is_applicable(r"impl A { f<|> }", has_impl_parent); 35 check_pattern_is_applicable(r"impl A { f<|> }", has_impl_parent);
36} 36}
37 37
38pub(crate) fn has_impl_trait_parent(element: SyntaxElement) -> bool { 38pub(crate) fn inside_impl_trait_block(element: SyntaxElement) -> bool {
39 not_same_range_ancestor(element) 39 // Here we search `impl` keyword up through the all ancestors, unlike in `has_impl_parent`,
40 .filter(|it| it.kind() == ASSOC_ITEM_LIST) 40 // where we only check the first parent with different text range.
41 .and_then(|it| it.parent()) 41 element
42 .filter(|it| it.kind() == IMPL) 42 .ancestors()
43 .find(|it| it.kind() == IMPL)
43 .map(|it| ast::Impl::cast(it).unwrap()) 44 .map(|it| ast::Impl::cast(it).unwrap())
44 .map(|it| it.trait_().is_some()) 45 .map(|it| it.trait_().is_some())
45 .unwrap_or(false) 46 .unwrap_or(false)
46} 47}
47#[test] 48#[test]
48fn test_has_impl_trait_parent() { 49fn test_inside_impl_trait_block() {
49 check_pattern_is_applicable(r"impl Foo for Bar { f<|> }", has_impl_trait_parent); 50 check_pattern_is_applicable(r"impl Foo for Bar { f<|> }", inside_impl_trait_block);
50 check_pattern_is_not_applicable(r"impl A { f<|> }", has_impl_trait_parent); 51 check_pattern_is_applicable(r"impl Foo for Bar { fn f<|> }", inside_impl_trait_block);
52 check_pattern_is_not_applicable(r"impl A { f<|> }", inside_impl_trait_block);
53 check_pattern_is_not_applicable(r"impl A { fn f<|> }", inside_impl_trait_block);
51} 54}
52 55
53pub(crate) fn has_field_list_parent(element: SyntaxElement) -> bool { 56pub(crate) fn has_field_list_parent(element: SyntaxElement) -> bool {