aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKirill Bulatov <[email protected]>2021-03-04 22:11:07 +0000
committerKirill Bulatov <[email protected]>2021-03-08 21:59:20 +0000
commit84c575a21201cdbeb391ff2cfae2fbbccaa76f8a (patch)
tree53db325890176bacca7e17ddd4ac148ac4252f51
parent6ca6f101c1b3a795ff6578bae6e01cb4b818e14c (diff)
Restrict fuzzy qualifiers for now
-rw-r--r--crates/hir_def/src/import_map.rs23
-rw-r--r--crates/ide_completion/src/completions/flyimport.rs7
-rw-r--r--crates/ide_db/src/helpers/import_assets.rs43
3 files changed, 26 insertions, 47 deletions
diff --git a/crates/hir_def/src/import_map.rs b/crates/hir_def/src/import_map.rs
index 07ee7bdfd..369bc3350 100644
--- a/crates/hir_def/src/import_map.rs
+++ b/crates/hir_def/src/import_map.rs
@@ -1094,27 +1094,4 @@ mod tests {
1094 expect![[r#""#]], 1094 expect![[r#""#]],
1095 ); 1095 );
1096 } 1096 }
1097
1098 #[test]
1099 fn search_with_path() {
1100 check_search(
1101 r#"
1102//- /main.rs crate:main deps:dep
1103//- /dep.rs crate:dep
1104pub mod foo {
1105 pub mod bar {
1106 pub mod baz {
1107 pub trait Display {
1108 fn fmt();
1109 }
1110 }
1111 }
1112}"#,
1113 "main",
1114 Query::new("baz::fmt".to_string()).search_mode(SearchMode::Fuzzy),
1115 expect![[r#"
1116 dep::foo::bar::baz::Display::fmt (a)
1117 "#]],
1118 );
1119 }
1120} 1097}
diff --git a/crates/ide_completion/src/completions/flyimport.rs b/crates/ide_completion/src/completions/flyimport.rs
index efb91fe0e..8a11cba41 100644
--- a/crates/ide_completion/src/completions/flyimport.rs
+++ b/crates/ide_completion/src/completions/flyimport.rs
@@ -21,8 +21,9 @@
21//! ``` 21//! ```
22//! 22//!
23//! Also completes associated items, that require trait imports. 23//! Also completes associated items, that require trait imports.
24//! If any unresolved and/or partially-qualified path predeces the input, it will be taken into account: only the items with import string 24//! If any unresolved and/or partially-qualified path predeces the input, it will be taken into account.
25//! containing this whole path will be considered and the corresponding path import will be added: 25//! Currently, only the imports with their import path ending with the whole qialifier will be proposed
26//! (no fuzzy matching for qualifier).
26//! 27//!
27//! ``` 28//! ```
28//! mod foo { 29//! mod foo {
@@ -187,7 +188,6 @@ fn import_assets<'a>(ctx: &'a CompletionContext, fuzzy_name: String) -> Option<I
187 ctx.scope.clone(), 188 ctx.scope.clone(),
188 )?; 189 )?;
189 190
190 // TODO kb bad: with the path prefix, the "min 3 symbols" limit applies. Fix in a separate PR on the symbol_index level
191 if matches!(assets_for_path.import_candidate(), ImportCandidate::Path(_)) 191 if matches!(assets_for_path.import_candidate(), ImportCandidate::Path(_))
192 && fuzzy_name_length < 2 192 && fuzzy_name_length < 2
193 { 193 {
@@ -937,7 +937,6 @@ mod foo {
937} 937}
938 938
939fn main() { 939fn main() {
940 let zz = "sdsd";
941 bar::Ass$0 940 bar::Ass$0
942}"#, 941}"#,
943 expect![[]], 942 expect![[]],
diff --git a/crates/ide_db/src/helpers/import_assets.rs b/crates/ide_db/src/helpers/import_assets.rs
index b78d1969d..9bdc93877 100644
--- a/crates/ide_db/src/helpers/import_assets.rs
+++ b/crates/ide_db/src/helpers/import_assets.rs
@@ -314,19 +314,21 @@ fn import_for_item(
314 let import_path_candidate = mod_path(original_item_candidate)?; 314 let import_path_candidate = mod_path(original_item_candidate)?;
315 let import_path_string = import_path_candidate.to_string(); 315 let import_path_string = import_path_candidate.to_string();
316 316
317 let expected_import_end = if item_as_assoc(db, original_item).is_some() {
318 unresolved_qualifier.to_string()
319 } else {
320 format!("{}::{}", unresolved_qualifier, item_name(db, original_item)?)
321 };
317 if !import_path_string.contains(unresolved_first_segment) 322 if !import_path_string.contains(unresolved_first_segment)
318 || !import_path_string.contains(unresolved_qualifier) 323 || !import_path_string.ends_with(&expected_import_end)
319 { 324 {
320 return None; 325 return None;
321 } 326 }
322 327
323 let segment_import = 328 let segment_import =
324 find_import_for_segment(db, original_item_candidate, &unresolved_first_segment)?; 329 find_import_for_segment(db, original_item_candidate, &unresolved_first_segment)?;
325 let trait_item_to_import = original_item 330 let trait_item_to_import = item_as_assoc(db, original_item)
326 .as_module_def_id() 331 .and_then(|assoc| assoc.containing_trait(db))
327 .and_then(|module_def_id| {
328 ModuleDef::from(module_def_id).as_assoc_item(db)?.containing_trait(db)
329 })
330 .map(|trait_| ItemInNs::from(ModuleDef::from(trait_))); 332 .map(|trait_| ItemInNs::from(ModuleDef::from(trait_)));
331 Some(match (segment_import == original_item_candidate, trait_item_to_import) { 333 Some(match (segment_import == original_item_candidate, trait_item_to_import) {
332 (true, Some(_)) => { 334 (true, Some(_)) => {
@@ -358,19 +360,15 @@ fn import_for_item(
358 360
359fn item_for_path_search(db: &RootDatabase, item: ItemInNs) -> Option<ItemInNs> { 361fn item_for_path_search(db: &RootDatabase, item: ItemInNs) -> Option<ItemInNs> {
360 Some(match item { 362 Some(match item {
361 ItemInNs::Types(module_def_id) | ItemInNs::Values(module_def_id) => { 363 ItemInNs::Types(_) | ItemInNs::Values(_) => match item_as_assoc(db, item) {
362 let module_def = ModuleDef::from(module_def_id); 364 Some(assoc_item) => match assoc_item.container(db) {
363 365 AssocItemContainer::Trait(trait_) => ItemInNs::from(ModuleDef::from(trait_)),
364 match module_def.as_assoc_item(db) { 366 AssocItemContainer::Impl(impl_) => {
365 Some(assoc_item) => match assoc_item.container(db) { 367 ItemInNs::from(ModuleDef::from(impl_.target_ty(db).as_adt()?))
366 AssocItemContainer::Trait(trait_) => ItemInNs::from(ModuleDef::from(trait_)), 368 }
367 AssocItemContainer::Impl(impl_) => { 369 },
368 ItemInNs::from(ModuleDef::from(impl_.target_ty(db).as_adt()?)) 370 None => item,
369 } 371 },
370 },
371 None => item,
372 }
373 }
374 ItemInNs::Macros(_) => item, 372 ItemInNs::Macros(_) => item,
375 }) 373 })
376} 374}
@@ -427,7 +425,7 @@ fn trait_applicable_items(
427 425
428 let trait_candidates = items_with_candidate_name 426 let trait_candidates = items_with_candidate_name
429 .into_iter() 427 .into_iter()
430 .filter_map(|input| ModuleDef::from(input.as_module_def_id()?).as_assoc_item(db)) 428 .filter_map(|input| item_as_assoc(db, input))
431 .filter_map(|assoc| { 429 .filter_map(|assoc| {
432 let assoc_item_trait = assoc.containing_trait(db)?; 430 let assoc_item_trait = assoc.containing_trait(db)?;
433 required_assoc_items.insert(assoc); 431 required_assoc_items.insert(assoc);
@@ -583,3 +581,8 @@ fn path_import_candidate(
583 None => ImportCandidate::Path(PathImportCandidate { qualifier: Qualifier::Absent, name }), 581 None => ImportCandidate::Path(PathImportCandidate { qualifier: Qualifier::Absent, name }),
584 }) 582 })
585} 583}
584
585fn item_as_assoc(db: &RootDatabase, item: ItemInNs) -> Option<AssocItem> {
586 item.as_module_def_id()
587 .and_then(|module_def_id| ModuleDef::from(module_def_id).as_assoc_item(db))
588}