diff options
Diffstat (limited to 'crates/ra_assists/src/auto_import.rs')
-rw-r--r-- | crates/ra_assists/src/auto_import.rs | 85 |
1 files changed, 67 insertions, 18 deletions
diff --git a/crates/ra_assists/src/auto_import.rs b/crates/ra_assists/src/auto_import.rs index 52c2a0b2b..105c888d5 100644 --- a/crates/ra_assists/src/auto_import.rs +++ b/crates/ra_assists/src/auto_import.rs | |||
@@ -1,4 +1,5 @@ | |||
1 | use hir::db::HirDatabase; | 1 | use hir::db::HirDatabase; |
2 | |||
2 | use ra_syntax::{ | 3 | use ra_syntax::{ |
3 | ast::{ self, NameOwner }, AstNode, SyntaxNode, Direction, TextRange, | 4 | ast::{ self, NameOwner }, AstNode, SyntaxNode, Direction, TextRange, |
4 | SyntaxKind::{ PATH, PATH_SEGMENT, COLONCOLON, COMMA } | 5 | SyntaxKind::{ PATH, PATH_SEGMENT, COLONCOLON, COMMA } |
@@ -267,7 +268,7 @@ fn walk_use_tree_for_best_action<'a>( | |||
267 | false, | 268 | false, |
268 | ) | 269 | ) |
269 | } | 270 | } |
270 | common if left.len() > right.len() => { | 271 | common if common == right.len() && left.len() > right.len() => { |
271 | // e.g: target is std::fmt and we can have | 272 | // e.g: target is std::fmt and we can have |
272 | // 1- use std; | 273 | // 1- use std; |
273 | // 2- use std::{ ... }; | 274 | // 2- use std::{ ... }; |
@@ -294,12 +295,12 @@ fn walk_use_tree_for_best_action<'a>( | |||
294 | } | 295 | } |
295 | } | 296 | } |
296 | } else { | 297 | } else { |
297 | // Case 1, split | 298 | // Case 1, split adding self |
298 | better_action = ImportAction::add_nested_import(prev_len + common, path, None, true) | 299 | better_action = ImportAction::add_nested_import(prev_len + common, path, None, true) |
299 | } | 300 | } |
300 | better_action | 301 | better_action |
301 | } | 302 | } |
302 | common if left.len() < right.len() => { | 303 | common if common == left.len() && left.len() < right.len() => { |
303 | // e.g: target is std::fmt and we can have | 304 | // e.g: target is std::fmt and we can have |
304 | // use std::fmt::Debug; | 305 | // use std::fmt::Debug; |
305 | let segments_to_split = current_path_segments.split_at(prev_len + common).1; | 306 | let segments_to_split = current_path_segments.split_at(prev_len + common).1; |
@@ -310,6 +311,17 @@ fn walk_use_tree_for_best_action<'a>( | |||
310 | true, | 311 | true, |
311 | ) | 312 | ) |
312 | } | 313 | } |
314 | common if common < left.len() && common < right.len() => { | ||
315 | // e.g: target is std::fmt::nested::Debug | ||
316 | // use std::fmt::Display | ||
317 | let segments_to_split = current_path_segments.split_at(prev_len + common).1; | ||
318 | ImportAction::add_nested_import( | ||
319 | prev_len + common, | ||
320 | path, | ||
321 | Some(segments_to_split[0]), | ||
322 | false, | ||
323 | ) | ||
324 | } | ||
313 | _ => unreachable!(), | 325 | _ => unreachable!(), |
314 | }; | 326 | }; |
315 | 327 | ||
@@ -500,8 +512,6 @@ fn apply_auto_import<'a>( | |||
500 | 512 | ||
501 | pub(crate) fn auto_import(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> { | 513 | pub(crate) fn auto_import(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> { |
502 | let node = ctx.covering_node(); | 514 | let node = ctx.covering_node(); |
503 | let current_file = node.ancestors().find_map(ast::SourceFile::cast)?; | ||
504 | |||
505 | let path = node.ancestors().find_map(ast::Path::cast)?; | 515 | let path = node.ancestors().find_map(ast::Path::cast)?; |
506 | // We don't want to mess with use statements | 516 | // We don't want to mess with use statements |
507 | if path.syntax().ancestors().find_map(ast::UseItem::cast).is_some() { | 517 | if path.syntax().ancestors().find_map(ast::UseItem::cast).is_some() { |
@@ -523,6 +533,7 @@ pub(crate) fn auto_import(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist | |||
523 | ); | 533 | ); |
524 | } | 534 | } |
525 | } else { | 535 | } else { |
536 | let current_file = node.ancestors().find_map(ast::SourceFile::cast)?; | ||
526 | ctx.add_action(format!("import {} in the current file", fmt_segments(&segments)), |edit| { | 537 | ctx.add_action(format!("import {} in the current file", fmt_segments(&segments)), |edit| { |
527 | apply_auto_import(current_file.syntax(), path, &segments, edit); | 538 | apply_auto_import(current_file.syntax(), path, &segments, edit); |
528 | }); | 539 | }); |
@@ -537,7 +548,7 @@ mod tests { | |||
537 | use crate::helpers::{ check_assist, check_assist_not_applicable }; | 548 | use crate::helpers::{ check_assist, check_assist_not_applicable }; |
538 | 549 | ||
539 | #[test] | 550 | #[test] |
540 | fn test_auto_import_file_add_use_no_anchor() { | 551 | fn test_auto_import_add_use_no_anchor() { |
541 | check_assist( | 552 | check_assist( |
542 | auto_import, | 553 | auto_import, |
543 | " | 554 | " |
@@ -552,7 +563,7 @@ Debug<|> | |||
552 | } | 563 | } |
553 | 564 | ||
554 | #[test] | 565 | #[test] |
555 | fn test_auto_import_file_add_use_no_anchor_2seg() { | 566 | fn test_auto_import_add_use_no_anchor_2seg() { |
556 | check_assist( | 567 | check_assist( |
557 | auto_import, | 568 | auto_import, |
558 | " | 569 | " |
@@ -567,7 +578,7 @@ fmt<|>::Debug | |||
567 | } | 578 | } |
568 | 579 | ||
569 | #[test] | 580 | #[test] |
570 | fn test_auto_import_file_add_use() { | 581 | fn test_auto_import_add_use() { |
571 | check_assist( | 582 | check_assist( |
572 | auto_import, | 583 | auto_import, |
573 | " | 584 | " |
@@ -587,7 +598,7 @@ impl Debug<|> for Foo { | |||
587 | } | 598 | } |
588 | 599 | ||
589 | #[test] | 600 | #[test] |
590 | fn test_auto_import_file_add_use_other_anchor() { | 601 | fn test_auto_import_file_use_other_anchor() { |
591 | check_assist( | 602 | check_assist( |
592 | auto_import, | 603 | auto_import, |
593 | " | 604 | " |
@@ -604,7 +615,7 @@ impl Debug<|> for Foo { | |||
604 | } | 615 | } |
605 | 616 | ||
606 | #[test] | 617 | #[test] |
607 | fn test_auto_import_file_add_use_other_anchor_indent() { | 618 | fn test_auto_import_add_use_other_anchor_indent() { |
608 | check_assist( | 619 | check_assist( |
609 | auto_import, | 620 | auto_import, |
610 | " | 621 | " |
@@ -621,7 +632,7 @@ impl Debug<|> for Foo { | |||
621 | } | 632 | } |
622 | 633 | ||
623 | #[test] | 634 | #[test] |
624 | fn test_auto_import_file_split_different() { | 635 | fn test_auto_import_split_different() { |
625 | check_assist( | 636 | check_assist( |
626 | auto_import, | 637 | auto_import, |
627 | " | 638 | " |
@@ -640,7 +651,7 @@ impl io<|> for Foo { | |||
640 | } | 651 | } |
641 | 652 | ||
642 | #[test] | 653 | #[test] |
643 | fn test_auto_import_file_split_self_for_use() { | 654 | fn test_auto_import_split_self_for_use() { |
644 | check_assist( | 655 | check_assist( |
645 | auto_import, | 656 | auto_import, |
646 | " | 657 | " |
@@ -659,7 +670,7 @@ impl Debug<|> for Foo { | |||
659 | } | 670 | } |
660 | 671 | ||
661 | #[test] | 672 | #[test] |
662 | fn test_auto_import_file_split_self_for_target() { | 673 | fn test_auto_import_split_self_for_target() { |
663 | check_assist( | 674 | check_assist( |
664 | auto_import, | 675 | auto_import, |
665 | " | 676 | " |
@@ -678,7 +689,7 @@ impl fmt<|> for Foo { | |||
678 | } | 689 | } |
679 | 690 | ||
680 | #[test] | 691 | #[test] |
681 | fn test_auto_import_file_add_to_nested_self_nested() { | 692 | fn test_auto_import_add_to_nested_self_nested() { |
682 | check_assist( | 693 | check_assist( |
683 | auto_import, | 694 | auto_import, |
684 | " | 695 | " |
@@ -697,7 +708,7 @@ impl nested<|> for Foo { | |||
697 | } | 708 | } |
698 | 709 | ||
699 | #[test] | 710 | #[test] |
700 | fn test_auto_import_file_add_to_nested_self_already_included() { | 711 | fn test_auto_import_add_to_nested_self_already_included() { |
701 | check_assist( | 712 | check_assist( |
702 | auto_import, | 713 | auto_import, |
703 | " | 714 | " |
@@ -716,7 +727,7 @@ impl nested<|> for Foo { | |||
716 | } | 727 | } |
717 | 728 | ||
718 | #[test] | 729 | #[test] |
719 | fn test_auto_import_file_add_to_nested_nested() { | 730 | fn test_auto_import_add_to_nested_nested() { |
720 | check_assist( | 731 | check_assist( |
721 | auto_import, | 732 | auto_import, |
722 | " | 733 | " |
@@ -735,7 +746,45 @@ impl Debug<|> for Foo { | |||
735 | } | 746 | } |
736 | 747 | ||
737 | #[test] | 748 | #[test] |
738 | fn test_auto_import_file_alias() { | 749 | fn test_auto_import_split_common_target_longer() { |
750 | check_assist( | ||
751 | auto_import, | ||
752 | " | ||
753 | use std::fmt::Debug; | ||
754 | |||
755 | impl std::fmt::nested::Display<|> for Foo { | ||
756 | } | ||
757 | ", | ||
758 | " | ||
759 | use std::fmt::{ nested::Display, Debug}; | ||
760 | |||
761 | impl Display<|> for Foo { | ||
762 | } | ||
763 | ", | ||
764 | ); | ||
765 | } | ||
766 | |||
767 | #[test] | ||
768 | fn test_auto_import_split_common_use_longer() { | ||
769 | check_assist( | ||
770 | auto_import, | ||
771 | " | ||
772 | use std::fmt::nested::Debug; | ||
773 | |||
774 | impl std::fmt::Display<|> for Foo { | ||
775 | } | ||
776 | ", | ||
777 | " | ||
778 | use std::fmt::{ Display, nested::Debug}; | ||
779 | |||
780 | impl Display<|> for Foo { | ||
781 | } | ||
782 | ", | ||
783 | ); | ||
784 | } | ||
785 | |||
786 | #[test] | ||
787 | fn test_auto_import_alias() { | ||
739 | check_assist( | 788 | check_assist( |
740 | auto_import, | 789 | auto_import, |
741 | " | 790 | " |
@@ -775,7 +824,7 @@ use std::fmt<|>; | |||
775 | } | 824 | } |
776 | 825 | ||
777 | #[test] | 826 | #[test] |
778 | fn test_auto_import_file_add_use_no_anchor_in_mod_mod() { | 827 | fn test_auto_import_add_use_no_anchor_in_mod_mod() { |
779 | check_assist( | 828 | check_assist( |
780 | auto_import, | 829 | auto_import, |
781 | " | 830 | " |