Skip to content

Commit 24a5d3b

Browse files
Fix the completion labels and tests
1 parent 33c83e7 commit 24a5d3b

File tree

4 files changed

+116
-65
lines changed

4 files changed

+116
-65
lines changed

crates/ide_completion/src/completions/flyimport.rs

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ pub(crate) fn import_on_the_fly(acc: &mut Completions, ctx: &CompletionContext)
144144
.filter_map(|import| {
145145
render_resolution_with_import(
146146
RenderContext::new(ctx),
147-
ImportEdit { import, import_scope: import_scope.clone() },
147+
ImportEdit { import, scope: import_scope.clone() },
148148
)
149149
}),
150150
);
@@ -690,8 +690,8 @@ fn main() {
690690
}
691691
"#,
692692
expect![[r#"
693-
fn weird_function() (dep::test_mod::TestTrait) -> () DEPRECATED
694693
ct SPECIAL_CONST (dep::test_mod::TestTrait) DEPRECATED
694+
fn weird_function() (dep::test_mod::TestTrait) -> () DEPRECATED
695695
"#]],
696696
);
697697
}
@@ -807,7 +807,12 @@ fn main() {
807807
bar::baz::Ite$0
808808
}"#;
809809

810-
check(fixture, expect![["st Item (foo::bar::baz::Item)"]]);
810+
check(
811+
fixture,
812+
expect![[r#"
813+
st foo::bar::baz::Item
814+
"#]],
815+
);
811816

812817
check_edit(
813818
"Item",
@@ -825,8 +830,7 @@ fn main() {
825830
826831
fn main() {
827832
bar::baz::Item
828-
}
829-
"#,
833+
}"#,
830834
);
831835
}
832836

@@ -845,7 +849,12 @@ fn main() {
845849
Item::TEST_A$0
846850
}"#;
847851

848-
check(fixture, expect![["ct TEST_ASSOC (foo::bar::baz::Item)"]]);
852+
check(
853+
fixture,
854+
expect![[r#"
855+
ct TEST_ASSOC (foo::Item)
856+
"#]],
857+
);
849858

850859
check_edit(
851860
"TEST_ASSOC",
@@ -863,8 +872,7 @@ mod foo {
863872
864873
fn main() {
865874
Item::TEST_ASSOC
866-
}
867-
"#,
875+
}"#,
868876
);
869877
}
870878

@@ -885,7 +893,12 @@ fn main() {
885893
bar::Item::TEST_A$0
886894
}"#;
887895

888-
check(fixture, expect![["ct TEST_ASSOC (foo::bar::baz::Item)"]]);
896+
check(
897+
fixture,
898+
expect![[r#"
899+
ct TEST_ASSOC (foo::bar::Item)
900+
"#]],
901+
);
889902

890903
check_edit(
891904
"TEST_ASSOC",
@@ -905,8 +918,7 @@ mod foo {
905918
906919
fn main() {
907920
bar::Item::TEST_ASSOC
908-
}
909-
"#,
921+
}"#,
910922
);
911923
}
912924
}

crates/ide_completion/src/item.rs

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use ide_db::{
1111
},
1212
SymbolKind,
1313
};
14-
use stdx::{impl_from, never};
14+
use stdx::{format_to, impl_from, never};
1515
use syntax::{algo, TextRange};
1616
use text_edit::TextEdit;
1717

@@ -274,7 +274,7 @@ impl CompletionItem {
274274
#[derive(Debug, Clone)]
275275
pub struct ImportEdit {
276276
pub import: LocatedImport,
277-
pub import_scope: ImportScope,
277+
pub scope: ImportScope,
278278
}
279279

280280
impl ImportEdit {
@@ -284,7 +284,7 @@ impl ImportEdit {
284284
let _p = profile::span("ImportEdit::to_text_edit");
285285

286286
let rewriter = insert_use::insert_use(
287-
&self.import_scope,
287+
&self.scope,
288288
mod_path_to_ast(&self.import.import_path),
289289
cfg,
290290
);
@@ -302,7 +302,6 @@ impl ImportEdit {
302302
pub(crate) struct Builder {
303303
source_range: TextRange,
304304
completion_kind: CompletionKind,
305-
// TODO kb also add a db here, to resolve the completion label?
306305
import_to_add: Option<ImportEdit>,
307306
label: String,
308307
insert_text: Option<String>,
@@ -322,22 +321,24 @@ impl Builder {
322321
pub(crate) fn build(self) -> CompletionItem {
323322
let _p = profile::span("item::Builder::build");
324323

325-
let label = self.label;
326-
let lookup = self.lookup;
327-
let insert_text = self.insert_text;
328-
329-
if let Some(_import_to_add) = self.import_to_add.as_ref() {
330-
todo!("todo kb")
331-
// let import = &import_to_add.import;
332-
// let item_to_import = import.item_to_import();
333-
// lookup = lookup.or_else(|| Some(label.clone()));
334-
// insert_text = insert_text.or_else(|| Some(label.clone()));
335-
// let display_path = import_to_add.import.display_path();
336-
// if import_to_add.import {
337-
// label = format!("{} ({})", label, display_path);
338-
// } else {
339-
// label = display_path.to_string();
340-
// }
324+
let mut label = self.label;
325+
let mut lookup = self.lookup;
326+
let mut insert_text = self.insert_text;
327+
328+
if let Some(original_path) = self
329+
.import_to_add
330+
.as_ref()
331+
.and_then(|import_edit| import_edit.import.original_path.as_ref())
332+
{
333+
lookup = lookup.or_else(|| Some(label.clone()));
334+
insert_text = insert_text.or_else(|| Some(label.clone()));
335+
336+
let original_path_label = original_path.to_string();
337+
if original_path_label.ends_with(&label) {
338+
label = original_path_label;
339+
} else {
340+
format_to!(label, " ({})", original_path)
341+
}
341342
}
342343

343344
let text_edit = match self.text_edit {

crates/ide_completion/src/lib.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ pub fn resolve_completion_edits(
144144
) -> Option<Vec<TextEdit>> {
145145
let ctx = CompletionContext::new(db, position, config)?;
146146
let position_for_import = position_for_import(&ctx, None)?;
147-
let import_scope = ImportScope::find_insert_use_container(position_for_import, &ctx.sema)?;
147+
let scope = ImportScope::find_insert_use_container(position_for_import, &ctx.sema)?;
148148

149149
let current_module = ctx.sema.scope(position_for_import).module()?;
150150
let current_crate = current_module.krate();
@@ -158,9 +158,10 @@ pub fn resolve_completion_edits(
158158
.zip(Some(candidate))
159159
})
160160
.find(|(mod_path, _)| mod_path.to_string() == full_import_path)?;
161-
let import = LocatedImport::new(import_path, item_to_import, item_to_import);
161+
let import =
162+
LocatedImport::new(import_path.clone(), item_to_import, item_to_import, Some(import_path));
162163

163-
ImportEdit { import, import_scope }.to_text_edit(config.insert_use).map(|edit| vec![edit])
164+
ImportEdit { import, scope }.to_text_edit(config.insert_use).map(|edit| vec![edit])
164165
}
165166

166167
#[cfg(test)]

crates/ide_db/src/helpers/import_assets.rs

Lines changed: 68 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -132,11 +132,17 @@ pub struct LocatedImport {
132132
pub import_path: ModPath,
133133
pub item_to_import: ItemInNs,
134134
pub original_item: ItemInNs,
135+
pub original_path: Option<ModPath>,
135136
}
136137

137138
impl LocatedImport {
138-
pub fn new(import_path: ModPath, item_to_import: ItemInNs, original_item: ItemInNs) -> Self {
139-
Self { import_path, item_to_import, original_item }
139+
pub fn new(
140+
import_path: ModPath,
141+
item_to_import: ItemInNs,
142+
original_item: ItemInNs,
143+
original_path: Option<ModPath>,
144+
) -> Self {
145+
Self { import_path, item_to_import, original_item, original_path }
140146
}
141147

142148
pub fn original_item_name(&self, db: &RootDatabase) -> Option<Name> {
@@ -238,7 +244,9 @@ impl<'a> ImportAssets<'a> {
238244
let _p = profile::span("import_assets::applicable_defs");
239245
let current_crate = self.module_with_candidate.krate();
240246

241-
let mod_path = |item| get_mod_path(db, item, &self.module_with_candidate, prefixed);
247+
let mod_path = |item| {
248+
get_mod_path(db, item_for_path_search(db, item)?, &self.module_with_candidate, prefixed)
249+
};
242250

243251
match &self.import_candidate {
244252
ImportCandidate::Path(path_candidate) => {
@@ -276,7 +284,9 @@ fn path_applicable_imports(
276284
Qualifier::Absent => {
277285
return items_with_candidate_name
278286
.into_iter()
279-
.filter_map(|item| Some(LocatedImport::new(mod_path(item)?, item, item)))
287+
.filter_map(|item| {
288+
Some(LocatedImport::new(mod_path(item)?, item, item, mod_path(item)))
289+
})
280290
.collect();
281291
}
282292
Qualifier::FirstSegmentUnresolved(first_segment, qualifier) => {
@@ -300,46 +310,69 @@ fn import_for_item(
300310
original_item: ItemInNs,
301311
) -> Option<LocatedImport> {
302312
let _p = profile::span("import_assets::import_for_item");
303-
let (item_candidate, trait_to_import) = match original_item.as_module_def_id() {
304-
Some(module_def_id) => {
305-
match ModuleDef::from(module_def_id).as_assoc_item(db).map(|assoc| assoc.container(db))
306-
{
307-
Some(AssocItemContainer::Trait(trait_)) => {
308-
let trait_item = ItemInNs::from(ModuleDef::from(trait_));
309-
(trait_item, Some(trait_item))
310-
}
311-
Some(AssocItemContainer::Impl(impl_)) => {
312-
(ItemInNs::from(ModuleDef::from(impl_.target_ty(db).as_adt()?)), None)
313-
}
314-
None => (original_item, None),
315-
}
316-
}
317-
None => (original_item, None),
318-
};
319-
let import_path_candidate = mod_path(item_candidate)?;
320313

314+
let original_item_candidate = item_for_path_search(db, original_item)?;
315+
let import_path_candidate = mod_path(original_item_candidate)?;
321316
let import_path_string = import_path_candidate.to_string();
317+
322318
if !import_path_string.contains(unresolved_first_segment)
323319
|| !import_path_string.contains(unresolved_qualifier)
324320
{
325321
return None;
326322
}
327323

328-
let segment_import = find_import_for_segment(db, item_candidate, &unresolved_first_segment)?;
329-
Some(match (segment_import == item_candidate, trait_to_import) {
324+
let segment_import =
325+
find_import_for_segment(db, original_item_candidate, &unresolved_first_segment)?;
326+
let trait_item_to_import = original_item
327+
.as_module_def_id()
328+
.and_then(|module_def_id| {
329+
ModuleDef::from(module_def_id).as_assoc_item(db)?.containing_trait(db)
330+
})
331+
.map(|trait_| ItemInNs::from(ModuleDef::from(trait_)));
332+
Some(match (segment_import == original_item_candidate, trait_item_to_import) {
330333
(true, Some(_)) => {
331334
// FIXME we should be able to import both the trait and the segment,
332335
// but it's unclear what to do with overlapping edits (merge imports?)
333336
// especially in case of lazy completion edit resolutions.
334337
return None;
335338
}
336-
(false, Some(trait_to_import)) => {
337-
LocatedImport::new(mod_path(trait_to_import)?, trait_to_import, original_item)
338-
}
339-
(true, None) => LocatedImport::new(import_path_candidate, item_candidate, original_item),
340-
(false, None) => {
341-
LocatedImport::new(mod_path(segment_import)?, segment_import, original_item)
339+
(false, Some(trait_to_import)) => LocatedImport::new(
340+
mod_path(trait_to_import)?,
341+
trait_to_import,
342+
original_item,
343+
mod_path(original_item),
344+
),
345+
(true, None) => LocatedImport::new(
346+
import_path_candidate,
347+
original_item_candidate,
348+
original_item,
349+
mod_path(original_item),
350+
),
351+
(false, None) => LocatedImport::new(
352+
mod_path(segment_import)?,
353+
segment_import,
354+
original_item,
355+
mod_path(original_item),
356+
),
357+
})
358+
}
359+
360+
fn item_for_path_search(db: &RootDatabase, item: ItemInNs) -> Option<ItemInNs> {
361+
Some(match item {
362+
ItemInNs::Types(module_def_id) | ItemInNs::Values(module_def_id) => {
363+
let module_def = ModuleDef::from(module_def_id);
364+
365+
match module_def.as_assoc_item(db) {
366+
Some(assoc_item) => match assoc_item.container(db) {
367+
AssocItemContainer::Trait(trait_) => ItemInNs::from(ModuleDef::from(trait_)),
368+
AssocItemContainer::Impl(impl_) => {
369+
ItemInNs::from(ModuleDef::from(impl_.target_ty(db).as_adt()?))
370+
}
371+
},
372+
None => item,
373+
}
342374
}
375+
ItemInNs::Macros(_) => item,
343376
})
344377
}
345378

@@ -420,10 +453,12 @@ fn trait_applicable_items(
420453
}
421454

422455
let item = ItemInNs::from(ModuleDef::from(assoc.containing_trait(db)?));
456+
let original_item = assoc_to_item(assoc);
423457
located_imports.insert(LocatedImport::new(
424458
mod_path(item)?,
425459
item,
426-
assoc_to_item(assoc),
460+
original_item,
461+
mod_path(original_item),
427462
));
428463
}
429464
None::<()>
@@ -439,10 +474,12 @@ fn trait_applicable_items(
439474
let assoc = function.as_assoc_item(db)?;
440475
if required_assoc_items.contains(&assoc) {
441476
let item = ItemInNs::from(ModuleDef::from(assoc.containing_trait(db)?));
477+
let original_item = assoc_to_item(assoc);
442478
located_imports.insert(LocatedImport::new(
443479
mod_path(item)?,
444480
item,
445-
assoc_to_item(assoc),
481+
original_item,
482+
mod_path(original_item),
446483
));
447484
}
448485
None::<()>

0 commit comments

Comments
 (0)