diff options
Diffstat (limited to 'crates/ra_ide_api/src/completion')
5 files changed, 76 insertions, 56 deletions
diff --git a/crates/ra_ide_api/src/completion/complete_macro_in_item_position.rs b/crates/ra_ide_api/src/completion/complete_macro_in_item_position.rs index 6fcef4a72..0cbe4abf7 100644 --- a/crates/ra_ide_api/src/completion/complete_macro_in_item_position.rs +++ b/crates/ra_ide_api/src/completion/complete_macro_in_item_position.rs | |||
@@ -3,11 +3,11 @@ use crate::completion::{CompletionContext, Completions}; | |||
3 | pub(super) fn complete_macro_in_item_position(acc: &mut Completions, ctx: &CompletionContext) { | 3 | pub(super) fn complete_macro_in_item_position(acc: &mut Completions, ctx: &CompletionContext) { |
4 | // Show only macros in top level. | 4 | // Show only macros in top level. |
5 | if ctx.is_new_item { | 5 | if ctx.is_new_item { |
6 | for (name, res) in ctx.analyzer.all_names(ctx.db) { | 6 | ctx.analyzer.process_all_names(ctx.db, &mut |name, res| { |
7 | if res.get_macros().is_some() { | 7 | if let hir::ScopeDef::MacroDef(mac) = res { |
8 | acc.add_resolution(ctx, name.to_string(), &res.only_macros()); | 8 | acc.add_macro(ctx, Some(name.to_string()), mac); |
9 | } | 9 | } |
10 | } | 10 | }) |
11 | } | 11 | } |
12 | } | 12 | } |
13 | 13 | ||
diff --git a/crates/ra_ide_api/src/completion/complete_path.rs b/crates/ra_ide_api/src/completion/complete_path.rs index 4d3414f33..5ee2864dc 100644 --- a/crates/ra_ide_api/src/completion/complete_path.rs +++ b/crates/ra_ide_api/src/completion/complete_path.rs | |||
@@ -1,4 +1,4 @@ | |||
1 | use hir::{Adt, Either, Resolution}; | 1 | use hir::{Adt, Either, PathResolution}; |
2 | use ra_syntax::AstNode; | 2 | use ra_syntax::AstNode; |
3 | use test_utils::tested_by; | 3 | use test_utils::tested_by; |
4 | 4 | ||
@@ -9,15 +9,15 @@ pub(super) fn complete_path(acc: &mut Completions, ctx: &CompletionContext) { | |||
9 | Some(path) => path.clone(), | 9 | Some(path) => path.clone(), |
10 | _ => return, | 10 | _ => return, |
11 | }; | 11 | }; |
12 | let def = match ctx.analyzer.resolve_hir_path(ctx.db, &path).take_types() { | 12 | let def = match dbg!(ctx.analyzer.resolve_hir_path(ctx.db, &path)) { |
13 | Some(Resolution::Def(def)) => def, | 13 | Some(PathResolution::Def(def)) => def, |
14 | _ => return, | 14 | _ => return, |
15 | }; | 15 | }; |
16 | match def { | 16 | match def { |
17 | hir::ModuleDef::Module(module) => { | 17 | hir::ModuleDef::Module(module) => { |
18 | let module_scope = module.scope(ctx.db); | 18 | let module_scope = module.scope(ctx.db); |
19 | for (name, res) in module_scope.entries() { | 19 | for (name, res) in module_scope.entries() { |
20 | if let Some(hir::ModuleDef::BuiltinType(..)) = res.def.as_ref().take_types() { | 20 | if let Some(hir::ModuleDef::BuiltinType(..)) = res.def.take_types() { |
21 | if ctx.use_item_syntax.is_some() { | 21 | if ctx.use_item_syntax.is_some() { |
22 | tested_by!(dont_complete_primitive_in_use); | 22 | tested_by!(dont_complete_primitive_in_use); |
23 | continue; | 23 | continue; |
@@ -34,7 +34,7 @@ pub(super) fn complete_path(acc: &mut Completions, ctx: &CompletionContext) { | |||
34 | } | 34 | } |
35 | } | 35 | } |
36 | } | 36 | } |
37 | acc.add_resolution(ctx, name.to_string(), &res.def.map(hir::Resolution::Def)); | 37 | acc.add_resolution(ctx, name.to_string(), &res.def.into()); |
38 | } | 38 | } |
39 | } | 39 | } |
40 | hir::ModuleDef::Adt(_) | hir::ModuleDef::TypeAlias(_) => { | 40 | hir::ModuleDef::Adt(_) | hir::ModuleDef::TypeAlias(_) => { |
diff --git a/crates/ra_ide_api/src/completion/complete_pattern.rs b/crates/ra_ide_api/src/completion/complete_pattern.rs index fb7f9feb8..c17b5b7ee 100644 --- a/crates/ra_ide_api/src/completion/complete_pattern.rs +++ b/crates/ra_ide_api/src/completion/complete_pattern.rs | |||
@@ -7,22 +7,20 @@ pub(super) fn complete_pattern(acc: &mut Completions, ctx: &CompletionContext) { | |||
7 | } | 7 | } |
8 | // FIXME: ideally, we should look at the type we are matching against and | 8 | // FIXME: ideally, we should look at the type we are matching against and |
9 | // suggest variants + auto-imports | 9 | // suggest variants + auto-imports |
10 | let names = ctx.analyzer.all_names(ctx.db); | 10 | ctx.analyzer.process_all_names(ctx.db, &mut |name, res| { |
11 | for (name, res) in names.into_iter() { | 11 | let def = match &res { |
12 | let r = res.as_ref(); | 12 | hir::ScopeDef::ModuleDef(def) => def, |
13 | let def = match r.take_types().or_else(|| r.take_values()) { | 13 | _ => return, |
14 | Some(hir::Resolution::Def(def)) => def, | ||
15 | _ => continue, | ||
16 | }; | 14 | }; |
17 | match def { | 15 | match def { |
18 | hir::ModuleDef::Adt(hir::Adt::Enum(..)) | 16 | hir::ModuleDef::Adt(hir::Adt::Enum(..)) |
19 | | hir::ModuleDef::EnumVariant(..) | 17 | | hir::ModuleDef::EnumVariant(..) |
20 | | hir::ModuleDef::Const(..) | 18 | | hir::ModuleDef::Const(..) |
21 | | hir::ModuleDef::Module(..) => (), | 19 | | hir::ModuleDef::Module(..) => (), |
22 | _ => continue, | 20 | _ => return, |
23 | } | 21 | } |
24 | acc.add_resolution(ctx, name.to_string(), &res) | 22 | acc.add_resolution(ctx, name.to_string(), &res) |
25 | } | 23 | }); |
26 | } | 24 | } |
27 | 25 | ||
28 | #[cfg(test)] | 26 | #[cfg(test)] |
diff --git a/crates/ra_ide_api/src/completion/complete_scope.rs b/crates/ra_ide_api/src/completion/complete_scope.rs index 2ea22876f..c1f48b026 100644 --- a/crates/ra_ide_api/src/completion/complete_scope.rs +++ b/crates/ra_ide_api/src/completion/complete_scope.rs | |||
@@ -10,8 +10,9 @@ pub(super) fn complete_scope(acc: &mut Completions, ctx: &CompletionContext) { | |||
10 | return; | 10 | return; |
11 | } | 11 | } |
12 | 12 | ||
13 | let names = ctx.analyzer.all_names(ctx.db); | 13 | ctx.analyzer.process_all_names(ctx.db, &mut |name, res| { |
14 | names.into_iter().for_each(|(name, res)| acc.add_resolution(ctx, name.to_string(), &res)); | 14 | acc.add_resolution(ctx, name.to_string(), &res) |
15 | }); | ||
15 | 16 | ||
16 | // auto-import | 17 | // auto-import |
17 | // We fetch ident from the original file, because we need to pre-filter auto-imports | 18 | // We fetch ident from the original file, because we need to pre-filter auto-imports |
diff --git a/crates/ra_ide_api/src/completion/presentation.rs b/crates/ra_ide_api/src/completion/presentation.rs index 95bbd34b7..31b887492 100644 --- a/crates/ra_ide_api/src/completion/presentation.rs +++ b/crates/ra_ide_api/src/completion/presentation.rs | |||
@@ -1,5 +1,5 @@ | |||
1 | //! This modules takes care of rendering various defenitions as completion items. | 1 | //! This modules takes care of rendering various definitions as completion items. |
2 | use hir::{Docs, HasSource, HirDisplay, PerNs, Resolution, Ty, TypeWalk}; | 2 | use hir::{Docs, HasSource, HirDisplay, ScopeDef, Ty, TypeWalk}; |
3 | use join_to_string::join; | 3 | use join_to_string::join; |
4 | use ra_syntax::ast::NameOwner; | 4 | use ra_syntax::ast::NameOwner; |
5 | use test_utils::tested_by; | 5 | use test_utils::tested_by; |
@@ -39,61 +39,77 @@ impl Completions { | |||
39 | &mut self, | 39 | &mut self, |
40 | ctx: &CompletionContext, | 40 | ctx: &CompletionContext, |
41 | local_name: String, | 41 | local_name: String, |
42 | resolution: &PerNs<Resolution>, | 42 | resolution: &ScopeDef, |
43 | ) { | 43 | ) { |
44 | use hir::ModuleDef::*; | 44 | use hir::ModuleDef::*; |
45 | 45 | ||
46 | if let Some(macro_) = resolution.get_macros() { | 46 | // if let Some(macro_) = resolution.get_macros() { |
47 | self.add_macro(ctx, Some(local_name.clone()), macro_); | 47 | // self.add_macro(ctx, Some(local_name.clone()), macro_); |
48 | } | 48 | // } |
49 | 49 | ||
50 | let def = resolution.as_ref().take_types().or_else(|| resolution.as_ref().take_values()); | 50 | // let def = resolution.as_ref().take_types().or_else(|| resolution.as_ref().take_values()); |
51 | let def = match def { | 51 | // let def = match def { |
52 | // Only insert once if it is just a macro name | 52 | // // Only insert once if it is just a macro name |
53 | None if resolution.get_macros().is_some() => return, | 53 | // None if resolution.get_macros().is_some() => return, |
54 | None => { | 54 | // None => { |
55 | self.add(CompletionItem::new( | 55 | // self.add(CompletionItem::new( |
56 | CompletionKind::Reference, | 56 | // CompletionKind::Reference, |
57 | ctx.source_range(), | 57 | // ctx.source_range(), |
58 | local_name, | 58 | // local_name, |
59 | )); | 59 | // )); |
60 | return; | 60 | // return; |
61 | } | 61 | // } |
62 | Some(it) => it, | 62 | // Some(it) => it, |
63 | }; | 63 | // }; |
64 | let mut completion_kind = CompletionKind::Reference; | 64 | let mut completion_kind = CompletionKind::Reference; |
65 | let (kind, docs) = match def { | 65 | let (kind, docs) = match resolution { |
66 | Resolution::Def(Module(it)) => (CompletionItemKind::Module, it.docs(ctx.db)), | 66 | ScopeDef::ModuleDef(Module(it)) => (CompletionItemKind::Module, it.docs(ctx.db)), |
67 | Resolution::Def(Function(func)) => { | 67 | ScopeDef::ModuleDef(Function(func)) => { |
68 | return self.add_function_with_name(ctx, Some(local_name), *func); | 68 | return self.add_function_with_name(ctx, Some(local_name), *func); |
69 | } | 69 | } |
70 | Resolution::Def(Adt(hir::Adt::Struct(it))) => { | 70 | ScopeDef::ModuleDef(Adt(hir::Adt::Struct(it))) => { |
71 | (CompletionItemKind::Struct, it.docs(ctx.db)) | 71 | (CompletionItemKind::Struct, it.docs(ctx.db)) |
72 | } | 72 | } |
73 | Resolution::Def(Adt(hir::Adt::Union(it))) => { | 73 | ScopeDef::ModuleDef(Adt(hir::Adt::Union(it))) => { |
74 | (CompletionItemKind::Struct, it.docs(ctx.db)) | 74 | (CompletionItemKind::Struct, it.docs(ctx.db)) |
75 | } | 75 | } |
76 | Resolution::Def(Adt(hir::Adt::Enum(it))) => (CompletionItemKind::Enum, it.docs(ctx.db)), | 76 | ScopeDef::ModuleDef(Adt(hir::Adt::Enum(it))) => { |
77 | Resolution::Def(EnumVariant(it)) => (CompletionItemKind::EnumVariant, it.docs(ctx.db)), | 77 | (CompletionItemKind::Enum, it.docs(ctx.db)) |
78 | Resolution::Def(Const(it)) => (CompletionItemKind::Const, it.docs(ctx.db)), | 78 | } |
79 | Resolution::Def(Static(it)) => (CompletionItemKind::Static, it.docs(ctx.db)), | 79 | ScopeDef::ModuleDef(EnumVariant(it)) => { |
80 | Resolution::Def(Trait(it)) => (CompletionItemKind::Trait, it.docs(ctx.db)), | 80 | (CompletionItemKind::EnumVariant, it.docs(ctx.db)) |
81 | Resolution::Def(TypeAlias(it)) => (CompletionItemKind::TypeAlias, it.docs(ctx.db)), | 81 | } |
82 | Resolution::Def(BuiltinType(..)) => { | 82 | ScopeDef::ModuleDef(Const(it)) => (CompletionItemKind::Const, it.docs(ctx.db)), |
83 | ScopeDef::ModuleDef(Static(it)) => (CompletionItemKind::Static, it.docs(ctx.db)), | ||
84 | ScopeDef::ModuleDef(Trait(it)) => (CompletionItemKind::Trait, it.docs(ctx.db)), | ||
85 | ScopeDef::ModuleDef(TypeAlias(it)) => (CompletionItemKind::TypeAlias, it.docs(ctx.db)), | ||
86 | ScopeDef::ModuleDef(BuiltinType(..)) => { | ||
83 | completion_kind = CompletionKind::BuiltinType; | 87 | completion_kind = CompletionKind::BuiltinType; |
84 | (CompletionItemKind::BuiltinType, None) | 88 | (CompletionItemKind::BuiltinType, None) |
85 | } | 89 | } |
86 | Resolution::GenericParam(..) => (CompletionItemKind::TypeParam, None), | 90 | ScopeDef::GenericParam(..) => (CompletionItemKind::TypeParam, None), |
87 | Resolution::LocalBinding(..) => (CompletionItemKind::Binding, None), | 91 | ScopeDef::LocalBinding(..) => (CompletionItemKind::Binding, None), |
88 | Resolution::SelfType(..) => ( | 92 | ScopeDef::SelfType(..) => ( |
89 | CompletionItemKind::TypeParam, // (does this need its own kind?) | 93 | CompletionItemKind::TypeParam, // (does this need its own kind?) |
90 | None, | 94 | None, |
91 | ), | 95 | ), |
96 | ScopeDef::MacroDef(mac) => { | ||
97 | self.add_macro(ctx, Some(local_name.clone()), *mac); | ||
98 | return; | ||
99 | } | ||
100 | ScopeDef::Unknown => { | ||
101 | self.add(CompletionItem::new( | ||
102 | CompletionKind::Reference, | ||
103 | ctx.source_range(), | ||
104 | local_name, | ||
105 | )); | ||
106 | return; | ||
107 | } | ||
92 | }; | 108 | }; |
93 | 109 | ||
94 | let mut completion_item = | 110 | let mut completion_item = |
95 | CompletionItem::new(completion_kind, ctx.source_range(), local_name); | 111 | CompletionItem::new(completion_kind, ctx.source_range(), local_name); |
96 | if let Resolution::LocalBinding(pat_id) = def { | 112 | if let ScopeDef::LocalBinding(pat_id) = resolution { |
97 | let ty = ctx | 113 | let ty = ctx |
98 | .analyzer | 114 | .analyzer |
99 | .type_of_pat_by_id(ctx.db, pat_id.clone()) | 115 | .type_of_pat_by_id(ctx.db, pat_id.clone()) |
@@ -108,7 +124,12 @@ impl Completions { | |||
108 | self.add_function_with_name(ctx, None, func) | 124 | self.add_function_with_name(ctx, None, func) |
109 | } | 125 | } |
110 | 126 | ||
111 | fn add_macro(&mut self, ctx: &CompletionContext, name: Option<String>, macro_: hir::MacroDef) { | 127 | pub(crate) fn add_macro( |
128 | &mut self, | ||
129 | ctx: &CompletionContext, | ||
130 | name: Option<String>, | ||
131 | macro_: hir::MacroDef, | ||
132 | ) { | ||
112 | let ast_node = macro_.source(ctx.db).ast; | 133 | let ast_node = macro_.source(ctx.db).ast; |
113 | if let Some(name) = name { | 134 | if let Some(name) = name { |
114 | let detail = macro_label(&ast_node); | 135 | let detail = macro_label(&ast_node); |