diff options
-rw-r--r-- | crates/ra_assists/src/auto_import.rs | 58 |
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 | ||
483 | fn 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 | |||
483 | pub(crate) fn auto_import(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> { | 501 | pub(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 | " | ||
548 | std::fmt<|>::Debug | ||
549 | ", | ||
550 | " | ||
551 | use std::fmt; | ||
552 | |||
553 | fmt<|>::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 | " | ||
761 | use std::fmt<|>; | ||
762 | ", | ||
763 | ); | ||
764 | } | ||
731 | } | 765 | } |