diff options
Diffstat (limited to 'crates/ra_ide/src/completion/complete_qualified_path.rs')
-rw-r--r-- | crates/ra_ide/src/completion/complete_qualified_path.rs | 63 |
1 files changed, 55 insertions, 8 deletions
diff --git a/crates/ra_ide/src/completion/complete_qualified_path.rs b/crates/ra_ide/src/completion/complete_qualified_path.rs index aa56a5cd8..02ac0166b 100644 --- a/crates/ra_ide/src/completion/complete_qualified_path.rs +++ b/crates/ra_ide/src/completion/complete_qualified_path.rs | |||
@@ -2,20 +2,25 @@ | |||
2 | 2 | ||
3 | use hir::{Adt, HasVisibility, PathResolution, ScopeDef}; | 3 | use hir::{Adt, HasVisibility, PathResolution, ScopeDef}; |
4 | use ra_syntax::AstNode; | 4 | use ra_syntax::AstNode; |
5 | use test_utils::tested_by; | 5 | use rustc_hash::FxHashSet; |
6 | use test_utils::mark; | ||
6 | 7 | ||
7 | use crate::completion::{CompletionContext, Completions}; | 8 | use crate::completion::{CompletionContext, Completions}; |
8 | use rustc_hash::FxHashSet; | ||
9 | 9 | ||
10 | pub(super) fn complete_qualified_path(acc: &mut Completions, ctx: &CompletionContext) { | 10 | pub(super) fn complete_qualified_path(acc: &mut Completions, ctx: &CompletionContext) { |
11 | let path = match &ctx.path_prefix { | 11 | let path = match &ctx.path_prefix { |
12 | Some(path) => path.clone(), | 12 | Some(path) => path.clone(), |
13 | _ => return, | 13 | None => return, |
14 | }; | 14 | }; |
15 | |||
16 | if ctx.attribute_under_caret.is_some() { | ||
17 | return; | ||
18 | } | ||
19 | |||
15 | let scope = ctx.scope(); | 20 | let scope = ctx.scope(); |
16 | let context_module = scope.module(); | 21 | let context_module = scope.module(); |
17 | 22 | ||
18 | let res = match scope.resolve_hir_path(&path) { | 23 | let res = match scope.resolve_hir_path_qualifier(&path) { |
19 | Some(res) => res, | 24 | Some(res) => res, |
20 | None => return, | 25 | None => return, |
21 | }; | 26 | }; |
@@ -35,7 +40,7 @@ pub(super) fn complete_qualified_path(acc: &mut Completions, ctx: &CompletionCon | |||
35 | if let Some(name_ref) = ctx.name_ref_syntax.as_ref() { | 40 | if let Some(name_ref) = ctx.name_ref_syntax.as_ref() { |
36 | if name_ref.syntax().text() == name.to_string().as_str() { | 41 | if name_ref.syntax().text() == name.to_string().as_str() { |
37 | // for `use self::foo<|>`, don't suggest `foo` as a completion | 42 | // for `use self::foo<|>`, don't suggest `foo` as a completion |
38 | tested_by!(dont_complete_current_use); | 43 | mark::hit!(dont_complete_current_use); |
39 | continue; | 44 | continue; |
40 | } | 45 | } |
41 | } | 46 | } |
@@ -79,7 +84,7 @@ pub(super) fn complete_qualified_path(acc: &mut Completions, ctx: &CompletionCon | |||
79 | }); | 84 | }); |
80 | 85 | ||
81 | // Iterate assoc types separately | 86 | // Iterate assoc types separately |
82 | ty.iterate_impl_items(ctx.db, krate, |item| { | 87 | ty.iterate_assoc_items(ctx.db, krate, |item| { |
83 | if context_module.map_or(false, |m| !item.is_visible_from(ctx.db, m)) { | 88 | if context_module.map_or(false, |m| !item.is_visible_from(ctx.db, m)) { |
84 | return None; | 89 | return None; |
85 | } | 90 | } |
@@ -142,7 +147,7 @@ pub(super) fn complete_qualified_path(acc: &mut Completions, ctx: &CompletionCon | |||
142 | 147 | ||
143 | #[cfg(test)] | 148 | #[cfg(test)] |
144 | mod tests { | 149 | mod tests { |
145 | use test_utils::covers; | 150 | use test_utils::mark; |
146 | 151 | ||
147 | use crate::completion::{test_utils::do_completion, CompletionItem, CompletionKind}; | 152 | use crate::completion::{test_utils::do_completion, CompletionItem, CompletionKind}; |
148 | use insta::assert_debug_snapshot; | 153 | use insta::assert_debug_snapshot; |
@@ -153,7 +158,7 @@ mod tests { | |||
153 | 158 | ||
154 | #[test] | 159 | #[test] |
155 | fn dont_complete_current_use() { | 160 | fn dont_complete_current_use() { |
156 | covers!(dont_complete_current_use); | 161 | mark::check!(dont_complete_current_use); |
157 | let completions = do_completion(r"use self::foo<|>;", CompletionKind::Reference); | 162 | let completions = do_completion(r"use self::foo<|>;", CompletionKind::Reference); |
158 | assert!(completions.is_empty()); | 163 | assert!(completions.is_empty()); |
159 | } | 164 | } |
@@ -221,6 +226,34 @@ mod tests { | |||
221 | } | 226 | } |
222 | 227 | ||
223 | #[test] | 228 | #[test] |
229 | fn completes_mod_with_same_name_as_function() { | ||
230 | assert_debug_snapshot!( | ||
231 | do_reference_completion( | ||
232 | r" | ||
233 | use self::my::<|>; | ||
234 | |||
235 | mod my { | ||
236 | pub struct Bar; | ||
237 | } | ||
238 | |||
239 | fn my() {} | ||
240 | " | ||
241 | ), | ||
242 | @r###" | ||
243 | [ | ||
244 | CompletionItem { | ||
245 | label: "Bar", | ||
246 | source_range: 31..31, | ||
247 | delete: 31..31, | ||
248 | insert: "Bar", | ||
249 | kind: Struct, | ||
250 | }, | ||
251 | ] | ||
252 | "### | ||
253 | ); | ||
254 | } | ||
255 | |||
256 | #[test] | ||
224 | fn path_visibility() { | 257 | fn path_visibility() { |
225 | assert_debug_snapshot!( | 258 | assert_debug_snapshot!( |
226 | do_reference_completion( | 259 | do_reference_completion( |
@@ -1325,4 +1358,18 @@ mod tests { | |||
1325 | "### | 1358 | "### |
1326 | ); | 1359 | ); |
1327 | } | 1360 | } |
1361 | |||
1362 | #[test] | ||
1363 | fn dont_complete_attr() { | ||
1364 | assert_debug_snapshot!( | ||
1365 | do_reference_completion( | ||
1366 | r" | ||
1367 | mod foo { pub struct Foo; } | ||
1368 | #[foo::<|>] | ||
1369 | fn f() {} | ||
1370 | " | ||
1371 | ), | ||
1372 | @r###"[]"### | ||
1373 | ) | ||
1374 | } | ||
1328 | } | 1375 | } |