From 4fe5786c0cdab1273685a0668107915b843bcaf6 Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Sat, 20 Feb 2021 13:53:50 +0200 Subject: Consider import prefix config settings during flyimports --- crates/hir/src/code_model.rs | 2 +- crates/ide_completion/src/completions/flyimport.rs | 94 +++++++++++++++++++++- crates/ide_completion/src/lib.rs | 2 +- 3 files changed, 94 insertions(+), 4 deletions(-) diff --git a/crates/hir/src/code_model.rs b/crates/hir/src/code_model.rs index 7d43d4097..021e4ad31 100644 --- a/crates/hir/src/code_model.rs +++ b/crates/hir/src/code_model.rs @@ -2076,7 +2076,7 @@ impl Callable { } /// For IDE only -#[derive(Debug)] +#[derive(Debug, PartialEq, Eq, Hash)] pub enum ScopeDef { ModuleDef(ModuleDef), MacroDef(MacroDef), diff --git a/crates/ide_completion/src/completions/flyimport.rs b/crates/ide_completion/src/completions/flyimport.rs index c9f928483..da8375af9 100644 --- a/crates/ide_completion/src/completions/flyimport.rs +++ b/crates/ide_completion/src/completions/flyimport.rs @@ -53,6 +53,7 @@ use ide_db::helpers::{ import_assets::{ImportAssets, ImportCandidate}, insert_use::ImportScope, }; +use rustc_hash::FxHashSet; use syntax::{AstNode, SyntaxNode, T}; use test_utils::mark; @@ -91,8 +92,10 @@ pub(crate) fn import_on_the_fly(acc: &mut Completions, ctx: &CompletionContext) position_for_import(ctx, Some(import_assets.import_candidate()))?, &ctx.sema, )?; + + let scope_definitions = scope_definitions(ctx); let mut all_mod_paths = import_assets - .search_for_relative_paths(&ctx.sema) + .search_for_imports(&ctx.sema, ctx.config.insert_use.prefix_kind) .into_iter() .map(|(mod_path, item_in_ns)| { let scope_item = match item_in_ns { @@ -102,6 +105,7 @@ pub(crate) fn import_on_the_fly(acc: &mut Completions, ctx: &CompletionContext) }; (mod_path, scope_item) }) + .filter(|(_, proposed_def)| !scope_definitions.contains(proposed_def)) .collect::>(); all_mod_paths.sort_by_cached_key(|(mod_path, _)| { compute_fuzzy_completion_order_key(mod_path, &user_input_lowercased) @@ -125,6 +129,14 @@ pub(crate) fn import_on_the_fly(acc: &mut Completions, ctx: &CompletionContext) Some(()) } +fn scope_definitions(ctx: &CompletionContext) -> FxHashSet { + let mut scope_definitions = FxHashSet::default(); + ctx.scope.process_all_names(&mut |_, scope_def| { + scope_definitions.insert(scope_def); + }); + scope_definitions +} + pub(crate) fn position_for_import<'a>( ctx: &'a CompletionContext, import_candidate: Option<&ImportCandidate>, @@ -192,7 +204,7 @@ mod tests { use crate::{ item::CompletionKind, - test_utils::{check_edit, completion_list}, + test_utils::{check_edit, check_edit_with_config, completion_list, TEST_CONFIG}, }; fn check(ra_fixture: &str, expect: Expect) { @@ -685,4 +697,82 @@ fn main() {} expect![[]], ); } + + #[test] + fn prefix_config_usage() { + let fixture = r#" +mod foo { + pub mod bar { + pub struct Item; + } +} + +use crate::foo::bar; + +fn main() { + Ite$0 +}"#; + let mut config = TEST_CONFIG; + + config.insert_use.prefix_kind = hir::PrefixKind::ByCrate; + check_edit_with_config( + config.clone(), + "Item", + fixture, + r#" +mod foo { + pub mod bar { + pub struct Item; + } +} + +use crate::foo::bar::{self, Item}; + +fn main() { + Item +}"#, + ); + + config.insert_use.prefix_kind = hir::PrefixKind::BySelf; + check_edit_with_config( + config.clone(), + "Item", + fixture, + r#" +mod foo { + pub mod bar { + pub struct Item; + } +} + +use crate::foo::bar; + +use self::foo::bar::Item; + +fn main() { + Item +}"#, + ); + + config.insert_use.prefix_kind = hir::PrefixKind::Plain; + check_edit_with_config( + config, + "Item", + fixture, + r#" +mod foo { + pub mod bar { + pub struct Item; + } +} + +use foo::bar::Item; + +use crate::foo::bar; + +fn main() { + Item +}"#, + ); + } } diff --git a/crates/ide_completion/src/lib.rs b/crates/ide_completion/src/lib.rs index db8bfbbc3..76f31de9e 100644 --- a/crates/ide_completion/src/lib.rs +++ b/crates/ide_completion/src/lib.rs @@ -151,7 +151,7 @@ pub fn resolve_completion_edits( let import_path = imports_locator::find_exact_imports(&ctx.sema, current_crate, imported_name) .filter_map(|candidate| { let item: hir::ItemInNs = candidate.either(Into::into, Into::into); - current_module.find_use_path(db, item) + current_module.find_use_path_prefixed(db, item, config.insert_use.prefix_kind) }) .find(|mod_path| mod_path.to_string() == full_import_path)?; -- cgit v1.2.3