Show case-insensitive exact matches instead of fuzzy flyimport for short paths

This commit is contained in:
Lukas Wirth 2021-12-09 19:18:11 +01:00
parent c469f8abcb
commit 143a30aa51
6 changed files with 55 additions and 33 deletions

View file

@ -65,7 +65,7 @@ pub(crate) fn replace_derive_with_manual_impl(
let found_traits = items_locator::items_with_name( let found_traits = items_locator::items_with_name(
&ctx.sema, &ctx.sema,
current_crate, current_crate,
NameToImport::Exact(trait_path.segments().last()?.to_string()), NameToImport::exact_case_sensitive(trait_path.segments().last()?.to_string()),
items_locator::AssocItemSearch::Exclude, items_locator::AssocItemSearch::Exclude,
Some(items_locator::DEFAULT_QUERY_SEARCH_LIMIT.inner()), Some(items_locator::DEFAULT_QUERY_SEARCH_LIMIT.inner()),
) )

View file

@ -227,22 +227,18 @@ fn import_assets(ctx: &CompletionContext, fuzzy_name: String) -> Option<ImportAs
) )
} else { } else {
let fuzzy_name_length = fuzzy_name.len(); let fuzzy_name_length = fuzzy_name.len();
let assets_for_path = ImportAssets::for_fuzzy_path( let mut assets_for_path = ImportAssets::for_fuzzy_path(
current_module, current_module,
ctx.path_qual().cloned(), ctx.path_qual().cloned(),
fuzzy_name, fuzzy_name,
&ctx.sema, &ctx.sema,
ctx.token.parent()?, ctx.token.parent()?,
)?; )?;
if fuzzy_name_length < 3 {
if matches!(assets_for_path.import_candidate(), ImportCandidate::Path(_)) cov_mark::hit!(flyimport_exact_on_short_path);
&& fuzzy_name_length < 2 assets_for_path.path_fuzzy_name_to_exact(false);
{
cov_mark::hit!(ignore_short_input_for_path);
None
} else {
Some(assets_for_path)
} }
Some(assets_for_path)
} }
} }

View file

@ -195,7 +195,7 @@ pub fn resolve_completion_edits(
let items_with_name = items_locator::items_with_name( let items_with_name = items_locator::items_with_name(
&ctx.sema, &ctx.sema,
current_crate, current_crate,
NameToImport::Exact(imported_name), NameToImport::exact_case_sensitive(imported_name),
items_locator::AssocItemSearch::Include, items_locator::AssocItemSearch::Include,
Some(items_locator::DEFAULT_QUERY_SEARCH_LIMIT.inner()), Some(items_locator::DEFAULT_QUERY_SEARCH_LIMIT.inner()),
); );

View file

@ -96,25 +96,29 @@ fn main() {
#[test] #[test]
fn short_paths_are_ignored() { fn short_paths_are_ignored() {
cov_mark::check!(ignore_short_input_for_path); cov_mark::check!(flyimport_exact_on_short_path);
check( check(
r#" r#"
//- /lib.rs crate:dep //- /lib.rs crate:dep
pub struct FirstStruct; pub struct Bar;
pub struct Rcar;
pub struct Rc;
pub mod some_module { pub mod some_module {
pub struct SecondStruct; pub struct Bar;
pub struct ThirdStruct; pub struct Rcar;
pub struct Rc;
} }
//- /main.rs crate:main deps:dep //- /main.rs crate:main deps:dep
use dep::{FirstStruct, some_module::SecondStruct};
fn main() { fn main() {
t$0 rc$0
} }
"#, "#,
expect![[r#""#]], expect![[r#"
st Rc (use dep::Rc)
st Rc (use dep::some_module::Rc)
"#]],
); );
} }
@ -772,7 +776,7 @@ mod foo {
} }
fn main() { fn main() {
TE$0 TES$0
}"#, }"#,
expect![[r#" expect![[r#"
ct TEST_CONST (use foo::TEST_CONST) ct TEST_CONST (use foo::TEST_CONST)
@ -789,7 +793,7 @@ mod foo {
} }
fn main() { fn main() {
te$0 tes$0
}"#, }"#,
expect![[r#" expect![[r#"
ct TEST_CONST (use foo::TEST_CONST) ct TEST_CONST (use foo::TEST_CONST)
@ -846,7 +850,7 @@ struct Foo {
some_field: i32, some_field: i32,
} }
fn main() { fn main() {
let _ = Foo { some_field: so$0 }; let _ = Foo { some_field: som$0 };
} }
"#, "#,
expect![[r#" expect![[r#"

View file

@ -68,17 +68,23 @@ pub struct FirstSegmentUnresolved {
/// A name that will be used during item lookups. /// A name that will be used during item lookups.
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub enum NameToImport { pub enum NameToImport {
/// Requires items with names that exactly match the given string, case-sensitive. /// Requires items with names that exactly match the given string, bool indicatse case-sensitivity.
Exact(String), Exact(String, bool),
/// Requires items with names that case-insensitively contain all letters from the string, /// Requires items with names that case-insensitively contain all letters from the string,
/// in the same order, but not necessary adjacent. /// in the same order, but not necessary adjacent.
Fuzzy(String), Fuzzy(String),
} }
impl NameToImport {
pub fn exact_case_sensitive(s: String) -> NameToImport {
NameToImport::Exact(s, true)
}
}
impl NameToImport { impl NameToImport {
pub fn text(&self) -> &str { pub fn text(&self) -> &str {
match self { match self {
NameToImport::Exact(text) => text.as_str(), NameToImport::Exact(text, _) => text.as_str(),
NameToImport::Fuzzy(text) => text.as_str(), NameToImport::Fuzzy(text) => text.as_str(),
} }
} }
@ -140,7 +146,7 @@ impl ImportAssets {
if let Some(_) = path.qualifier() { if let Some(_) = path.qualifier() {
return None; return None;
} }
let name = NameToImport::Exact(path.segment()?.name_ref()?.to_string()); let name = NameToImport::exact_case_sensitive(path.segment()?.name_ref()?.to_string());
let candidate_node = attr.syntax().clone(); let candidate_node = attr.syntax().clone();
Some(Self { Some(Self {
import_candidate: ImportCandidate::Path(PathImportCandidate { qualifier: None, name }), import_candidate: ImportCandidate::Path(PathImportCandidate { qualifier: None, name }),
@ -230,6 +236,18 @@ impl ImportAssets {
self.search_for(sema, None) self.search_for(sema, None)
} }
pub fn path_fuzzy_name_to_exact(&mut self, case_sensitive: bool) {
if let ImportCandidate::Path(PathImportCandidate { name: to_import, .. }) =
&mut self.import_candidate
{
let name = match to_import {
NameToImport::Fuzzy(name) => std::mem::take(name),
_ => return,
};
*to_import = NameToImport::Exact(name, case_sensitive);
}
}
fn search_for( fn search_for(
&self, &self,
sema: &Semantics<RootDatabase>, sema: &Semantics<RootDatabase>,
@ -561,7 +579,9 @@ impl ImportCandidate {
Some(_) => None, Some(_) => None,
None => Some(Self::TraitMethod(TraitImportCandidate { None => Some(Self::TraitMethod(TraitImportCandidate {
receiver_ty: sema.type_of_expr(&method_call.receiver()?)?.adjusted(), receiver_ty: sema.type_of_expr(&method_call.receiver()?)?.adjusted(),
assoc_item_name: NameToImport::Exact(method_call.name_ref()?.to_string()), assoc_item_name: NameToImport::exact_case_sensitive(
method_call.name_ref()?.to_string(),
),
})), })),
} }
} }
@ -573,7 +593,7 @@ impl ImportCandidate {
path_import_candidate( path_import_candidate(
sema, sema,
path.qualifier(), path.qualifier(),
NameToImport::Exact(path.segment()?.name_ref()?.to_string()), NameToImport::exact_case_sensitive(path.segment()?.name_ref()?.to_string()),
) )
} }
@ -587,7 +607,7 @@ impl ImportCandidate {
} }
Some(ImportCandidate::Path(PathImportCandidate { Some(ImportCandidate::Path(PathImportCandidate {
qualifier: None, qualifier: None,
name: NameToImport::Exact(name.to_string()), name: NameToImport::exact_case_sensitive(name.to_string()),
})) }))
} }

View file

@ -50,16 +50,18 @@ pub fn items_with_name<'a>(
}); });
let (mut local_query, mut external_query) = match name { let (mut local_query, mut external_query) = match name {
NameToImport::Exact(exact_name) => { NameToImport::Exact(exact_name, case_sensitive) => {
let mut local_query = symbol_index::Query::new(exact_name.clone()); let mut local_query = symbol_index::Query::new(exact_name.clone());
local_query.exact(); local_query.exact();
let external_query = import_map::Query::new(exact_name) let external_query = import_map::Query::new(exact_name)
.name_only() .name_only()
.search_mode(import_map::SearchMode::Equals) .search_mode(import_map::SearchMode::Equals);
.case_sensitive();
(local_query, external_query) (
local_query,
if case_sensitive { external_query.case_sensitive() } else { external_query },
)
} }
NameToImport::Fuzzy(fuzzy_search_string) => { NameToImport::Fuzzy(fuzzy_search_string) => {
let mut local_query = symbol_index::Query::new(fuzzy_search_string.clone()); let mut local_query = symbol_index::Query::new(fuzzy_search_string.clone());