diff options
Diffstat (limited to 'crates/ra_ide_api/src/completion/complete_scope.rs')
-rw-r--r-- | crates/ra_ide_api/src/completion/complete_scope.rs | 90 |
1 files changed, 35 insertions, 55 deletions
diff --git a/crates/ra_ide_api/src/completion/complete_scope.rs b/crates/ra_ide_api/src/completion/complete_scope.rs index f837bb1db..44514ab2b 100644 --- a/crates/ra_ide_api/src/completion/complete_scope.rs +++ b/crates/ra_ide_api/src/completion/complete_scope.rs | |||
@@ -1,63 +1,20 @@ | |||
1 | use rustc_hash::FxHashSet; | 1 | use crate::completion::{CompletionItem, Completions, CompletionKind, CompletionContext}; |
2 | use ra_syntax::ast::AstNode; | ||
3 | use crate::completion::{CompletionItem, CompletionItemKind, Completions, CompletionKind, CompletionContext}; | ||
4 | 2 | ||
5 | pub(super) fn complete_scope(acc: &mut Completions, ctx: &CompletionContext) { | 3 | pub(super) fn complete_scope(acc: &mut Completions, ctx: &CompletionContext) { |
6 | if !ctx.is_trivial_path { | 4 | if !ctx.is_trivial_path { |
7 | return; | 5 | return; |
8 | } | 6 | } |
9 | let module = match &ctx.module { | 7 | let names = ctx.resolver.all_names(); |
10 | Some(it) => it, | ||
11 | None => return, | ||
12 | }; | ||
13 | if let Some(function) = &ctx.function { | ||
14 | let scopes = function.scopes(ctx.db); | ||
15 | complete_fn(acc, &scopes, ctx); | ||
16 | } | ||
17 | |||
18 | let module_scope = module.scope(ctx.db); | ||
19 | module_scope | ||
20 | .entries() | ||
21 | .filter(|(_name, res)| { | ||
22 | // For cases like `use self::foo<|>` don't suggest foo itself. | ||
23 | match res.import { | ||
24 | None => true, | ||
25 | Some(import) => { | ||
26 | let source = module.import_source(ctx.db, import); | ||
27 | !source.syntax().range().is_subrange(&ctx.leaf.range()) | ||
28 | } | ||
29 | } | ||
30 | }) | ||
31 | .for_each(|(name, res)| { | ||
32 | CompletionItem::new( | ||
33 | CompletionKind::Reference, | ||
34 | ctx.source_range(), | ||
35 | name.to_string(), | ||
36 | ) | ||
37 | .from_resolution(ctx, res) | ||
38 | .add_to(acc) | ||
39 | }); | ||
40 | } | ||
41 | 8 | ||
42 | fn complete_fn( | 9 | names.into_iter().for_each(|(name, res)| { |
43 | acc: &mut Completions, | 10 | CompletionItem::new( |
44 | scopes: &hir::ScopesWithSyntaxMapping, | 11 | CompletionKind::Reference, |
45 | ctx: &CompletionContext, | 12 | ctx.source_range(), |
46 | ) { | 13 | name.to_string(), |
47 | let mut shadowed = FxHashSet::default(); | 14 | ) |
48 | scopes | 15 | .from_resolution(ctx, &res) |
49 | .scope_chain_for_offset(ctx.offset) | 16 | .add_to(acc) |
50 | .flat_map(|scope| scopes.scopes.entries(scope).iter()) | 17 | }); |
51 | .filter(|entry| shadowed.insert(entry.name())) | ||
52 | .for_each(|entry| { | ||
53 | CompletionItem::new( | ||
54 | CompletionKind::Reference, | ||
55 | ctx.source_range(), | ||
56 | entry.name().to_string(), | ||
57 | ) | ||
58 | .kind(CompletionItemKind::Binding) | ||
59 | .add_to(acc) | ||
60 | }); | ||
61 | } | 18 | } |
62 | 19 | ||
63 | #[cfg(test)] | 20 | #[cfg(test)] |
@@ -116,6 +73,30 @@ mod tests { | |||
116 | } | 73 | } |
117 | 74 | ||
118 | #[test] | 75 | #[test] |
76 | fn completes_generic_params() { | ||
77 | check_reference_completion( | ||
78 | "generic_params", | ||
79 | r" | ||
80 | fn quux<T>() { | ||
81 | <|> | ||
82 | } | ||
83 | ", | ||
84 | ); | ||
85 | } | ||
86 | |||
87 | #[test] | ||
88 | fn completes_generic_params_in_struct() { | ||
89 | check_reference_completion( | ||
90 | "generic_params_in_struct", | ||
91 | r" | ||
92 | struct X<T> { | ||
93 | x: <|> | ||
94 | } | ||
95 | ", | ||
96 | ); | ||
97 | } | ||
98 | |||
99 | #[test] | ||
119 | fn completes_module_items() { | 100 | fn completes_module_items() { |
120 | check_reference_completion( | 101 | check_reference_completion( |
121 | "module_items", | 102 | "module_items", |
@@ -174,5 +155,4 @@ mod tests { | |||
174 | fn completes_self_in_methods() { | 155 | fn completes_self_in_methods() { |
175 | check_reference_completion("self_in_methods", r"impl S { fn foo(&self) { <|> } }") | 156 | check_reference_completion("self_in_methods", r"impl S { fn foo(&self) { <|> } }") |
176 | } | 157 | } |
177 | |||
178 | } | 158 | } |