aboutsummaryrefslogtreecommitdiff
path: root/crates/ide_completion/src
diff options
context:
space:
mode:
authorKirill Bulatov <[email protected]>2021-02-24 23:06:31 +0000
committerKirill Bulatov <[email protected]>2021-03-08 21:59:18 +0000
commit582cee2cdf5355b681f14bbb33bd5c431c284d87 (patch)
tree47d25e9c057759b1aa334abf3f584f1d0317d941 /crates/ide_completion/src
parent309421c117fc20e58b9f30fb28a01a89f50b0086 (diff)
Return more data about located imports
Diffstat (limited to 'crates/ide_completion/src')
-rw-r--r--crates/ide_completion/src/completions/flyimport.rs23
-rw-r--r--crates/ide_completion/src/item.rs28
-rw-r--r--crates/ide_completion/src/lib.rs20
-rw-r--r--crates/ide_completion/src/render.rs2
4 files changed, 37 insertions, 36 deletions
diff --git a/crates/ide_completion/src/completions/flyimport.rs b/crates/ide_completion/src/completions/flyimport.rs
index 64b60bbdd..8ff76688e 100644
--- a/crates/ide_completion/src/completions/flyimport.rs
+++ b/crates/ide_completion/src/completions/flyimport.rs
@@ -96,21 +96,21 @@ pub(crate) fn import_on_the_fly(acc: &mut Completions, ctx: &CompletionContext)
96 let mut all_mod_paths = import_assets 96 let mut all_mod_paths = import_assets
97 .search_for_imports(&ctx.sema, ctx.config.insert_use.prefix_kind) 97 .search_for_imports(&ctx.sema, ctx.config.insert_use.prefix_kind)
98 .into_iter() 98 .into_iter()
99 .map(|(mod_path, item_in_ns)| { 99 .map(|import| {
100 let scope_item = match item_in_ns { 100 let proposed_def = match import.item_to_import() {
101 hir::ItemInNs::Types(id) => ScopeDef::ModuleDef(id.into()), 101 hir::ItemInNs::Types(id) => ScopeDef::ModuleDef(id.into()),
102 hir::ItemInNs::Values(id) => ScopeDef::ModuleDef(id.into()), 102 hir::ItemInNs::Values(id) => ScopeDef::ModuleDef(id.into()),
103 hir::ItemInNs::Macros(id) => ScopeDef::MacroDef(id.into()), 103 hir::ItemInNs::Macros(id) => ScopeDef::MacroDef(id.into()),
104 }; 104 };
105 (mod_path, scope_item) 105 (import, proposed_def)
106 }) 106 })
107 .filter(|(_, proposed_def)| !scope_definitions.contains(proposed_def)) 107 .filter(|(_, proposed_def)| !scope_definitions.contains(proposed_def))
108 .collect::<Vec<_>>(); 108 .collect::<Vec<_>>();
109 all_mod_paths.sort_by_cached_key(|(mod_path, _)| { 109 all_mod_paths.sort_by_cached_key(|(import, _)| {
110 compute_fuzzy_completion_order_key(mod_path, &user_input_lowercased) 110 compute_fuzzy_completion_order_key(import.display_path(), &user_input_lowercased)
111 }); 111 });
112 112
113 acc.add_all(all_mod_paths.into_iter().filter_map(|(import_path, definition)| { 113 acc.add_all(all_mod_paths.into_iter().filter_map(|(import, definition)| {
114 let import_for_trait_assoc_item = match definition { 114 let import_for_trait_assoc_item = match definition {
115 ScopeDef::ModuleDef(module_def) => module_def 115 ScopeDef::ModuleDef(module_def) => module_def
116 .as_assoc_item(ctx.db) 116 .as_assoc_item(ctx.db)
@@ -118,11 +118,8 @@ pub(crate) fn import_on_the_fly(acc: &mut Completions, ctx: &CompletionContext)
118 .is_some(), 118 .is_some(),
119 _ => false, 119 _ => false,
120 }; 120 };
121 let import_edit = ImportEdit { 121 let import_edit =
122 import_path, 122 ImportEdit { import, import_scope: import_scope.clone(), import_for_trait_assoc_item };
123 import_scope: import_scope.clone(),
124 import_for_trait_assoc_item,
125 };
126 render_resolution_with_import(RenderContext::new(ctx), import_edit, &definition) 123 render_resolution_with_import(RenderContext::new(ctx), import_edit, &definition)
127 })); 124 }));
128 Some(()) 125 Some(())
@@ -186,11 +183,11 @@ fn compute_fuzzy_completion_order_key(
186 user_input_lowercased: &str, 183 user_input_lowercased: &str,
187) -> usize { 184) -> usize {
188 cov_mark::hit!(certain_fuzzy_order_test); 185 cov_mark::hit!(certain_fuzzy_order_test);
189 let proposed_import_name = match proposed_mod_path.segments().last() { 186 let import_name = match proposed_mod_path.segments().last() {
190 Some(name) => name.to_string().to_lowercase(), 187 Some(name) => name.to_string().to_lowercase(),
191 None => return usize::MAX, 188 None => return usize::MAX,
192 }; 189 };
193 match proposed_import_name.match_indices(user_input_lowercased).next() { 190 match import_name.match_indices(user_input_lowercased).next() {
194 Some((first_matching_index, _)) => first_matching_index, 191 Some((first_matching_index, _)) => first_matching_index,
195 None => usize::MAX, 192 None => usize::MAX,
196 } 193 }
diff --git a/crates/ide_completion/src/item.rs b/crates/ide_completion/src/item.rs
index 9b2435c4b..0390fe226 100644
--- a/crates/ide_completion/src/item.rs
+++ b/crates/ide_completion/src/item.rs
@@ -2,9 +2,10 @@
2 2
3use std::fmt; 3use std::fmt;
4 4
5use hir::{Documentation, ModPath, Mutability}; 5use hir::{Documentation, Mutability};
6use ide_db::{ 6use ide_db::{
7 helpers::{ 7 helpers::{
8 import_assets::LocatedImport,
8 insert_use::{self, ImportScope, InsertUseConfig}, 9 insert_use::{self, ImportScope, InsertUseConfig},
9 mod_path_to_ast, SnippetCap, 10 mod_path_to_ast, SnippetCap,
10 }, 11 },
@@ -272,7 +273,7 @@ impl CompletionItem {
272/// An extra import to add after the completion is applied. 273/// An extra import to add after the completion is applied.
273#[derive(Debug, Clone)] 274#[derive(Debug, Clone)]
274pub struct ImportEdit { 275pub struct ImportEdit {
275 pub import_path: ModPath, 276 pub import: LocatedImport,
276 pub import_scope: ImportScope, 277 pub import_scope: ImportScope,
277 pub import_for_trait_assoc_item: bool, 278 pub import_for_trait_assoc_item: bool,
278} 279}
@@ -283,8 +284,11 @@ impl ImportEdit {
283 pub fn to_text_edit(&self, cfg: InsertUseConfig) -> Option<TextEdit> { 284 pub fn to_text_edit(&self, cfg: InsertUseConfig) -> Option<TextEdit> {
284 let _p = profile::span("ImportEdit::to_text_edit"); 285 let _p = profile::span("ImportEdit::to_text_edit");
285 286
286 let rewriter = 287 let rewriter = insert_use::insert_use(
287 insert_use::insert_use(&self.import_scope, mod_path_to_ast(&self.import_path), cfg); 288 &self.import_scope,
289 mod_path_to_ast(self.import.import_path()),
290 cfg,
291 );
288 let old_ast = rewriter.rewrite_root()?; 292 let old_ast = rewriter.rewrite_root()?;
289 let mut import_insert = TextEdit::builder(); 293 let mut import_insert = TextEdit::builder();
290 algo::diff(&old_ast, &rewriter.rewrite(&old_ast)).into_text_edit(&mut import_insert); 294 algo::diff(&old_ast, &rewriter.rewrite(&old_ast)).into_text_edit(&mut import_insert);
@@ -323,19 +327,13 @@ impl Builder {
323 let mut insert_text = self.insert_text; 327 let mut insert_text = self.insert_text;
324 328
325 if let Some(import_to_add) = self.import_to_add.as_ref() { 329 if let Some(import_to_add) = self.import_to_add.as_ref() {
330 lookup = lookup.or_else(|| Some(label.clone()));
331 insert_text = insert_text.or_else(|| Some(label.clone()));
332 let display_path = import_to_add.import.display_path();
326 if import_to_add.import_for_trait_assoc_item { 333 if import_to_add.import_for_trait_assoc_item {
327 lookup = lookup.or_else(|| Some(label.clone())); 334 label = format!("{} ({})", label, display_path);
328 insert_text = insert_text.or_else(|| Some(label.clone()));
329 label = format!("{} ({})", label, import_to_add.import_path);
330 } else { 335 } else {
331 let mut import_path_without_last_segment = import_to_add.import_path.to_owned(); 336 label = display_path.to_string();
332 let _ = import_path_without_last_segment.pop_segment();
333
334 if !import_path_without_last_segment.segments().is_empty() {
335 lookup = lookup.or_else(|| Some(label.clone()));
336 insert_text = insert_text.or_else(|| Some(label.clone()));
337 label = format!("{}::{}", import_path_without_last_segment, label);
338 }
339 } 337 }
340 } 338 }
341 339
diff --git a/crates/ide_completion/src/lib.rs b/crates/ide_completion/src/lib.rs
index b0b809791..ca2e5e706 100644
--- a/crates/ide_completion/src/lib.rs
+++ b/crates/ide_completion/src/lib.rs
@@ -13,7 +13,9 @@ mod completions;
13 13
14use completions::flyimport::position_for_import; 14use completions::flyimport::position_for_import;
15use ide_db::{ 15use ide_db::{
16 base_db::FilePosition, helpers::insert_use::ImportScope, imports_locator, RootDatabase, 16 base_db::FilePosition,
17 helpers::{import_assets::LocatedImport, insert_use::ImportScope},
18 imports_locator, RootDatabase,
17}; 19};
18use text_edit::TextEdit; 20use text_edit::TextEdit;
19 21
@@ -148,12 +150,16 @@ pub fn resolve_completion_edits(
148 let current_module = ctx.sema.scope(position_for_import).module()?; 150 let current_module = ctx.sema.scope(position_for_import).module()?;
149 let current_crate = current_module.krate(); 151 let current_crate = current_module.krate();
150 152
151 let import_path = imports_locator::find_exact_imports(&ctx.sema, current_crate, imported_name) 153 let (import_path, item_to_import) =
152 .filter_map(|candidate| { 154 imports_locator::find_exact_imports(&ctx.sema, current_crate, imported_name)
153 let item: hir::ItemInNs = candidate.either(Into::into, Into::into); 155 .filter_map(|candidate| {
154 current_module.find_use_path_prefixed(db, item, config.insert_use.prefix_kind) 156 let item: hir::ItemInNs = candidate.either(Into::into, Into::into);
155 }) 157 current_module
156 .find(|mod_path| mod_path.to_string() == full_import_path)?; 158 .find_use_path_prefixed(db, item, config.insert_use.prefix_kind)
159 .zip(Some(item))
160 })
161 .find(|(mod_path, _)| mod_path.to_string() == full_import_path)?;
162 let import = LocatedImport::new(import_path, item_to_import, None);
157 163
158 ImportEdit { import_path, import_scope, import_for_trait_assoc_item } 164 ImportEdit { import_path, import_scope, import_for_trait_assoc_item }
159 .to_text_edit(config.insert_use) 165 .to_text_edit(config.insert_use)
diff --git a/crates/ide_completion/src/render.rs b/crates/ide_completion/src/render.rs
index dcfac23c5..df26e7642 100644
--- a/crates/ide_completion/src/render.rs
+++ b/crates/ide_completion/src/render.rs
@@ -56,7 +56,7 @@ pub(crate) fn render_resolution_with_import<'a>(
56 ScopeDef::ModuleDef(ModuleDef::Function(f)) => f.name(ctx.completion.db).to_string(), 56 ScopeDef::ModuleDef(ModuleDef::Function(f)) => f.name(ctx.completion.db).to_string(),
57 ScopeDef::ModuleDef(ModuleDef::Const(c)) => c.name(ctx.completion.db)?.to_string(), 57 ScopeDef::ModuleDef(ModuleDef::Const(c)) => c.name(ctx.completion.db)?.to_string(),
58 ScopeDef::ModuleDef(ModuleDef::TypeAlias(t)) => t.name(ctx.completion.db).to_string(), 58 ScopeDef::ModuleDef(ModuleDef::TypeAlias(t)) => t.name(ctx.completion.db).to_string(),
59 _ => import_edit.import_path.segments().last()?.to_string(), 59 _ => import_edit.import.display_path().segments().last()?.to_string(),
60 }; 60 };
61 Render::new(ctx).render_resolution(local_name, Some(import_edit), resolution).map(|mut item| { 61 Render::new(ctx).render_resolution(local_name, Some(import_edit), resolution).map(|mut item| {
62 item.completion_kind = CompletionKind::Magic; 62 item.completion_kind = CompletionKind::Magic;