aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide_api/src/completion/complete_scope.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_ide_api/src/completion/complete_scope.rs')
-rw-r--r--crates/ra_ide_api/src/completion/complete_scope.rs90
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 @@
1use rustc_hash::FxHashSet; 1use crate::completion::{CompletionItem, Completions, CompletionKind, CompletionContext};
2use ra_syntax::ast::AstNode;
3use crate::completion::{CompletionItem, CompletionItemKind, Completions, CompletionKind, CompletionContext};
4 2
5pub(super) fn complete_scope(acc: &mut Completions, ctx: &CompletionContext) { 3pub(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
42fn 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}