aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/ra_assists/src/auto_import.rs58
1 files changed, 46 insertions, 12 deletions
diff --git a/crates/ra_assists/src/auto_import.rs b/crates/ra_assists/src/auto_import.rs
index b251c9369..3255a1008 100644
--- a/crates/ra_assists/src/auto_import.rs
+++ b/crates/ra_assists/src/auto_import.rs
@@ -345,9 +345,9 @@ fn best_action_for_target<'b, 'a: 'b>(
345 match best_action { 345 match best_action {
346 Some(action) => return action, 346 Some(action) => return action,
347 None => { 347 None => {
348 // We have no action we no use item was found in container so we find 348 // We have no action and no UseItem was found in container so we find
349 // another item and we use it as anchor. 349 // another item and we use it as anchor.
350 // If there are not items, we choose the target path itself as anchor. 350 // If there are no items, we choose the target path itself as anchor.
351 let anchor = container 351 let anchor = container
352 .children() 352 .children()
353 .find_map(ast::ModuleItem::cast) 353 .find_map(ast::ModuleItem::cast)
@@ -480,6 +480,24 @@ fn make_assist_add_nested_import(
480 } 480 }
481} 481}
482 482
483fn apply_auto_import<'a>(
484 container: &SyntaxNode,
485 path: &ast::Path,
486 target: &[&'a ast::PathSegment],
487 edit: &mut AssistBuilder,
488) {
489 let action = best_action_for_target(container, path, target);
490 make_assist(&action, target, edit);
491 if let (Some(first), Some(last)) = (target.first(), target.last()) {
492 // Here we are assuming the assist will provide a correct use statement
493 // so we can delete the path qualifier
494 edit.delete(TextRange::from_to(
495 first.syntax().range().start(),
496 last.syntax().range().start(),
497 ));
498 }
499}
500
483pub(crate) fn auto_import(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> { 501pub(crate) fn auto_import(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> {
484 let node = ctx.covering_node(); 502 let node = ctx.covering_node();
485 let current_file = node.ancestors().find_map(ast::SourceFile::cast)?; 503 let current_file = node.ancestors().find_map(ast::SourceFile::cast)?;
@@ -496,16 +514,7 @@ pub(crate) fn auto_import(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist
496 } 514 }
497 515
498 ctx.add_action(format!("import {} in the current file", fmt_segments(&segments)), |edit| { 516 ctx.add_action(format!("import {} in the current file", fmt_segments(&segments)), |edit| {
499 let action = best_action_for_target(current_file.syntax(), path, &segments); 517 apply_auto_import(current_file.syntax(), path, &segments, edit);
500 make_assist(&action, segments.as_slice(), edit);
501 if let Some(last_segment) = path.segment() {
502 // Here we are assuming the assist will provide a correct use statement
503 // so we can delete the path qualifier
504 edit.delete(TextRange::from_to(
505 path.syntax().range().start(),
506 last_segment.syntax().range().start(),
507 ));
508 }
509 }); 518 });
510 519
511 ctx.build() 520 ctx.build()
@@ -532,6 +541,21 @@ Debug<|>
532 } 541 }
533 542
534 #[test] 543 #[test]
544 fn test_auto_import_file_add_use_no_anchor_2seg() {
545 check_assist(
546 auto_import,
547 "
548std::fmt<|>::Debug
549 ",
550 "
551use std::fmt;
552
553fmt<|>::Debug
554 ",
555 );
556 }
557
558 #[test]
535 fn test_auto_import_file_add_use() { 559 fn test_auto_import_file_add_use() {
536 check_assist( 560 check_assist(
537 auto_import, 561 auto_import,
@@ -728,4 +752,14 @@ impl foo<|> for Foo {
728", 752",
729 ); 753 );
730 } 754 }
755
756 #[test]
757 fn test_auto_import_not_applicable_in_use() {
758 check_assist_not_applicable(
759 auto_import,
760 "
761use std::fmt<|>;
762",
763 );
764 }
731} 765}