aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_analysis/src/completion/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_analysis/src/completion/mod.rs')
-rw-r--r--crates/ra_analysis/src/completion/mod.rs54
1 files changed, 24 insertions, 30 deletions
diff --git a/crates/ra_analysis/src/completion/mod.rs b/crates/ra_analysis/src/completion/mod.rs
index 2e082705e..e5ba92acd 100644
--- a/crates/ra_analysis/src/completion/mod.rs
+++ b/crates/ra_analysis/src/completion/mod.rs
@@ -2,18 +2,16 @@ mod reference_completion;
2 2
3use ra_editor::find_node_at_offset; 3use ra_editor::find_node_at_offset;
4use ra_syntax::{ 4use ra_syntax::{
5 algo::find_leaf_at_offset,
6 algo::visit::{visitor_ctx, VisitorCtx}, 5 algo::visit::{visitor_ctx, VisitorCtx},
7 ast, 6 ast,
8 AstNode, AtomEdit, 7 AstNode, AtomEdit,
9 SyntaxNodeRef, 8 SyntaxNodeRef,
10}; 9};
10use ra_db::SyntaxDatabase;
11use rustc_hash::{FxHashMap}; 11use rustc_hash::{FxHashMap};
12 12
13use crate::{ 13use crate::{
14 db::{self, SyntaxDatabase}, 14 db,
15 descriptors::{DescriptorDatabase, module::ModuleSource},
16 input::{FilesDatabase},
17 Cancelable, FilePosition 15 Cancelable, FilePosition
18}; 16};
19 17
@@ -31,39 +29,21 @@ pub(crate) fn completions(
31 db: &db::RootDatabase, 29 db: &db::RootDatabase,
32 position: FilePosition, 30 position: FilePosition,
33) -> Cancelable<Option<Vec<CompletionItem>>> { 31) -> Cancelable<Option<Vec<CompletionItem>>> {
34 let original_file = db.file_syntax(position.file_id); 32 let original_file = db.source_file(position.file_id);
35 // Insert a fake ident to get a valid parse tree 33 // Insert a fake ident to get a valid parse tree
36 let file = { 34 let file = {
37 let edit = AtomEdit::insert(position.offset, "intellijRulezz".to_string()); 35 let edit = AtomEdit::insert(position.offset, "intellijRulezz".to_string());
38 original_file.reparse(&edit) 36 original_file.reparse(&edit)
39 }; 37 };
40 38
41 let leaf = match find_leaf_at_offset(original_file.syntax(), position.offset).left_biased() { 39 let module = ctry!(hir::Module::guess_from_position(db, position)?);
42 None => return Ok(None),
43 Some(it) => it,
44 };
45 let source_root_id = db.file_source_root(position.file_id);
46 let module_tree = db.module_tree(source_root_id)?;
47 let module_source = ModuleSource::for_node(position.file_id, leaf);
48 let module_id = match module_tree.any_module_for_source(module_source) {
49 None => return Ok(None),
50 Some(it) => it,
51 };
52 40
53 let mut res = Vec::new(); 41 let mut res = Vec::new();
54 let mut has_completions = false; 42 let mut has_completions = false;
55 // First, let's try to complete a reference to some declaration. 43 // First, let's try to complete a reference to some declaration.
56 if let Some(name_ref) = find_node_at_offset::<ast::NameRef>(file.syntax(), position.offset) { 44 if let Some(name_ref) = find_node_at_offset::<ast::NameRef>(file.syntax(), position.offset) {
57 has_completions = true; 45 has_completions = true;
58 reference_completion::completions( 46 reference_completion::completions(&mut res, db, &module, &file, name_ref)?;
59 &mut res,
60 db,
61 source_root_id,
62 &module_tree,
63 module_id,
64 &file,
65 name_ref,
66 )?;
67 // special case, `trait T { fn foo(i_am_a_name_ref) {} }` 47 // special case, `trait T { fn foo(i_am_a_name_ref) {} }`
68 if is_node::<ast::Param>(name_ref.syntax()) { 48 if is_node::<ast::Param>(name_ref.syntax()) {
69 param_completions(name_ref.syntax(), &mut res); 49 param_completions(name_ref.syntax(), &mut res);
@@ -219,9 +199,9 @@ mod tests {
219 <|> 199 <|>
220 } 200 }
221 ", 201 ",
222 r#"[CompletionItem { label: "Foo", lookup: None, snippet: None }, 202 r#"[CompletionItem { label: "quux", lookup: None, snippet: None },
223 CompletionItem { label: "Baz", lookup: None, snippet: None }, 203 CompletionItem { label: "Foo", lookup: None, snippet: None },
224 CompletionItem { label: "quux", lookup: None, snippet: None }]"#, 204 CompletionItem { label: "Baz", lookup: None, snippet: None }]"#,
225 ); 205 );
226 } 206 }
227 207
@@ -236,6 +216,20 @@ mod tests {
236 } 216 }
237 217
238 #[test] 218 #[test]
219 fn test_completion_self_path() {
220 check_scope_completion(
221 r"
222 use self::m::<|>;
223
224 mod m {
225 struct Bar;
226 }
227 ",
228 r#"[CompletionItem { label: "Bar", lookup: None, snippet: None }]"#,
229 );
230 }
231
232 #[test]
239 fn test_completion_mod_scope_nested() { 233 fn test_completion_mod_scope_nested() {
240 check_scope_completion( 234 check_scope_completion(
241 r" 235 r"
@@ -245,8 +239,8 @@ mod tests {
245 fn quux() { <|> } 239 fn quux() { <|> }
246 } 240 }
247 ", 241 ",
248 r#"[CompletionItem { label: "Bar", lookup: None, snippet: None }, 242 r#"[CompletionItem { label: "quux", lookup: None, snippet: None },
249 CompletionItem { label: "quux", lookup: None, snippet: None }]"#, 243 CompletionItem { label: "Bar", lookup: None, snippet: None }]"#,
250 ); 244 );
251 } 245 }
252 246