diff options
Diffstat (limited to 'crates')
-rw-r--r-- | crates/hir_def/src/find_path.rs | 587 | ||||
-rw-r--r-- | crates/ide/src/move_item.rs | 100 | ||||
-rw-r--r-- | crates/rust-analyzer/src/handlers.rs | 9 | ||||
-rw-r--r-- | crates/rust-analyzer/src/lsp_ext.rs | 2 | ||||
-rw-r--r-- | crates/rust-analyzer/src/to_proto.rs | 12 |
5 files changed, 402 insertions, 308 deletions
diff --git a/crates/hir_def/src/find_path.rs b/crates/hir_def/src/find_path.rs index 109d3552f..317ca86ec 100644 --- a/crates/hir_def/src/find_path.rs +++ b/crates/hir_def/src/find_path.rs | |||
@@ -425,106 +425,145 @@ mod tests { | |||
425 | 425 | ||
426 | #[test] | 426 | #[test] |
427 | fn same_module() { | 427 | fn same_module() { |
428 | let code = r#" | 428 | check_found_path( |
429 | //- /main.rs | 429 | r#" |
430 | struct S; | 430 | //- /main.rs |
431 | $0 | 431 | struct S; |
432 | "#; | 432 | $0 |
433 | check_found_path(code, "S", "S", "crate::S", "self::S"); | 433 | "#, |
434 | "S", | ||
435 | "S", | ||
436 | "crate::S", | ||
437 | "self::S", | ||
438 | ); | ||
434 | } | 439 | } |
435 | 440 | ||
436 | #[test] | 441 | #[test] |
437 | fn enum_variant() { | 442 | fn enum_variant() { |
438 | let code = r#" | 443 | check_found_path( |
439 | //- /main.rs | 444 | r#" |
440 | enum E { A } | 445 | //- /main.rs |
441 | $0 | 446 | enum E { A } |
442 | "#; | 447 | $0 |
443 | check_found_path(code, "E::A", "E::A", "E::A", "E::A"); | 448 | "#, |
449 | "E::A", | ||
450 | "E::A", | ||
451 | "E::A", | ||
452 | "E::A", | ||
453 | ); | ||
444 | } | 454 | } |
445 | 455 | ||
446 | #[test] | 456 | #[test] |
447 | fn sub_module() { | 457 | fn sub_module() { |
448 | let code = r#" | 458 | check_found_path( |
449 | //- /main.rs | 459 | r#" |
450 | mod foo { | 460 | //- /main.rs |
451 | pub struct S; | 461 | mod foo { |
452 | } | 462 | pub struct S; |
453 | $0 | 463 | } |
454 | "#; | 464 | $0 |
455 | check_found_path(code, "foo::S", "foo::S", "crate::foo::S", "self::foo::S"); | 465 | "#, |
466 | "foo::S", | ||
467 | "foo::S", | ||
468 | "crate::foo::S", | ||
469 | "self::foo::S", | ||
470 | ); | ||
456 | } | 471 | } |
457 | 472 | ||
458 | #[test] | 473 | #[test] |
459 | fn super_module() { | 474 | fn super_module() { |
460 | let code = r#" | 475 | check_found_path( |
461 | //- /main.rs | 476 | r#" |
462 | mod foo; | 477 | //- /main.rs |
463 | //- /foo.rs | 478 | mod foo; |
464 | mod bar; | 479 | //- /foo.rs |
465 | struct S; | 480 | mod bar; |
466 | //- /foo/bar.rs | 481 | struct S; |
467 | $0 | 482 | //- /foo/bar.rs |
468 | "#; | 483 | $0 |
469 | check_found_path(code, "super::S", "super::S", "crate::foo::S", "super::S"); | 484 | "#, |
485 | "super::S", | ||
486 | "super::S", | ||
487 | "crate::foo::S", | ||
488 | "super::S", | ||
489 | ); | ||
470 | } | 490 | } |
471 | 491 | ||
472 | #[test] | 492 | #[test] |
473 | fn self_module() { | 493 | fn self_module() { |
474 | let code = r#" | 494 | check_found_path( |
475 | //- /main.rs | 495 | r#" |
476 | mod foo; | 496 | //- /main.rs |
477 | //- /foo.rs | 497 | mod foo; |
478 | $0 | 498 | //- /foo.rs |
479 | "#; | 499 | $0 |
480 | check_found_path(code, "self", "self", "crate::foo", "self"); | 500 | "#, |
501 | "self", | ||
502 | "self", | ||
503 | "crate::foo", | ||
504 | "self", | ||
505 | ); | ||
481 | } | 506 | } |
482 | 507 | ||
483 | #[test] | 508 | #[test] |
484 | fn crate_root() { | 509 | fn crate_root() { |
485 | let code = r#" | 510 | check_found_path( |
486 | //- /main.rs | 511 | r#" |
487 | mod foo; | 512 | //- /main.rs |
488 | //- /foo.rs | 513 | mod foo; |
489 | $0 | 514 | //- /foo.rs |
490 | "#; | 515 | $0 |
491 | check_found_path(code, "crate", "crate", "crate", "crate"); | 516 | "#, |
517 | "crate", | ||
518 | "crate", | ||
519 | "crate", | ||
520 | "crate", | ||
521 | ); | ||
492 | } | 522 | } |
493 | 523 | ||
494 | #[test] | 524 | #[test] |
495 | fn same_crate() { | 525 | fn same_crate() { |
496 | let code = r#" | 526 | check_found_path( |
497 | //- /main.rs | 527 | r#" |
498 | mod foo; | 528 | //- /main.rs |
499 | struct S; | 529 | mod foo; |
500 | //- /foo.rs | 530 | struct S; |
501 | $0 | 531 | //- /foo.rs |
502 | "#; | 532 | $0 |
503 | check_found_path(code, "crate::S", "crate::S", "crate::S", "crate::S"); | 533 | "#, |
534 | "crate::S", | ||
535 | "crate::S", | ||
536 | "crate::S", | ||
537 | "crate::S", | ||
538 | ); | ||
504 | } | 539 | } |
505 | 540 | ||
506 | #[test] | 541 | #[test] |
507 | fn different_crate() { | 542 | fn different_crate() { |
508 | let code = r#" | 543 | check_found_path( |
509 | //- /main.rs crate:main deps:std | 544 | r#" |
510 | $0 | 545 | //- /main.rs crate:main deps:std |
511 | //- /std.rs crate:std | 546 | $0 |
512 | pub struct S; | 547 | //- /std.rs crate:std |
513 | "#; | 548 | pub struct S; |
514 | check_found_path(code, "std::S", "std::S", "std::S", "std::S"); | 549 | "#, |
550 | "std::S", | ||
551 | "std::S", | ||
552 | "std::S", | ||
553 | "std::S", | ||
554 | ); | ||
515 | } | 555 | } |
516 | 556 | ||
517 | #[test] | 557 | #[test] |
518 | fn different_crate_renamed() { | 558 | fn different_crate_renamed() { |
519 | let code = r#" | ||
520 | //- /main.rs crate:main deps:std | ||
521 | extern crate std as std_renamed; | ||
522 | $0 | ||
523 | //- /std.rs crate:std | ||
524 | pub struct S; | ||
525 | "#; | ||
526 | check_found_path( | 559 | check_found_path( |
527 | code, | 560 | r#" |
561 | //- /main.rs crate:main deps:std | ||
562 | extern crate std as std_renamed; | ||
563 | $0 | ||
564 | //- /std.rs crate:std | ||
565 | pub struct S; | ||
566 | "#, | ||
528 | "std_renamed::S", | 567 | "std_renamed::S", |
529 | "std_renamed::S", | 568 | "std_renamed::S", |
530 | "std_renamed::S", | 569 | "std_renamed::S", |
@@ -537,41 +576,38 @@ mod tests { | |||
537 | cov_mark::check!(partially_imported); | 576 | cov_mark::check!(partially_imported); |
538 | // Tests that short paths are used even for external items, when parts of the path are | 577 | // Tests that short paths are used even for external items, when parts of the path are |
539 | // already in scope. | 578 | // already in scope. |
540 | let code = r#" | 579 | check_found_path( |
541 | //- /main.rs crate:main deps:syntax | 580 | r#" |
581 | //- /main.rs crate:main deps:syntax | ||
542 | 582 | ||
543 | use syntax::ast; | 583 | use syntax::ast; |
544 | $0 | 584 | $0 |
545 | 585 | ||
546 | //- /lib.rs crate:syntax | 586 | //- /lib.rs crate:syntax |
547 | pub mod ast { | 587 | pub mod ast { |
548 | pub enum ModuleItem { | 588 | pub enum ModuleItem { |
549 | A, B, C, | 589 | A, B, C, |
550 | } | 590 | } |
551 | } | 591 | } |
552 | "#; | 592 | "#, |
553 | check_found_path( | ||
554 | code, | ||
555 | "ast::ModuleItem", | 593 | "ast::ModuleItem", |
556 | "syntax::ast::ModuleItem", | 594 | "syntax::ast::ModuleItem", |
557 | "syntax::ast::ModuleItem", | 595 | "syntax::ast::ModuleItem", |
558 | "syntax::ast::ModuleItem", | 596 | "syntax::ast::ModuleItem", |
559 | ); | 597 | ); |
560 | 598 | ||
561 | let code = r#" | ||
562 | //- /main.rs crate:main deps:syntax | ||
563 | |||
564 | $0 | ||
565 | |||
566 | //- /lib.rs crate:syntax | ||
567 | pub mod ast { | ||
568 | pub enum ModuleItem { | ||
569 | A, B, C, | ||
570 | } | ||
571 | } | ||
572 | "#; | ||
573 | check_found_path( | 599 | check_found_path( |
574 | code, | 600 | r#" |
601 | //- /main.rs crate:main deps:syntax | ||
602 | $0 | ||
603 | |||
604 | //- /lib.rs crate:syntax | ||
605 | pub mod ast { | ||
606 | pub enum ModuleItem { | ||
607 | A, B, C, | ||
608 | } | ||
609 | } | ||
610 | "#, | ||
575 | "syntax::ast::ModuleItem", | 611 | "syntax::ast::ModuleItem", |
576 | "syntax::ast::ModuleItem", | 612 | "syntax::ast::ModuleItem", |
577 | "syntax::ast::ModuleItem", | 613 | "syntax::ast::ModuleItem", |
@@ -581,68 +617,88 @@ mod tests { | |||
581 | 617 | ||
582 | #[test] | 618 | #[test] |
583 | fn same_crate_reexport() { | 619 | fn same_crate_reexport() { |
584 | let code = r#" | 620 | check_found_path( |
585 | //- /main.rs | 621 | r#" |
586 | mod bar { | 622 | //- /main.rs |
587 | mod foo { pub(super) struct S; } | 623 | mod bar { |
588 | pub(crate) use foo::*; | 624 | mod foo { pub(super) struct S; } |
589 | } | 625 | pub(crate) use foo::*; |
590 | $0 | 626 | } |
591 | "#; | 627 | $0 |
592 | check_found_path(code, "bar::S", "bar::S", "crate::bar::S", "self::bar::S"); | 628 | "#, |
629 | "bar::S", | ||
630 | "bar::S", | ||
631 | "crate::bar::S", | ||
632 | "self::bar::S", | ||
633 | ); | ||
593 | } | 634 | } |
594 | 635 | ||
595 | #[test] | 636 | #[test] |
596 | fn same_crate_reexport_rename() { | 637 | fn same_crate_reexport_rename() { |
597 | let code = r#" | 638 | check_found_path( |
598 | //- /main.rs | 639 | r#" |
599 | mod bar { | 640 | //- /main.rs |
600 | mod foo { pub(super) struct S; } | 641 | mod bar { |
601 | pub(crate) use foo::S as U; | 642 | mod foo { pub(super) struct S; } |
602 | } | 643 | pub(crate) use foo::S as U; |
603 | $0 | 644 | } |
604 | "#; | 645 | $0 |
605 | check_found_path(code, "bar::U", "bar::U", "crate::bar::U", "self::bar::U"); | 646 | "#, |
647 | "bar::U", | ||
648 | "bar::U", | ||
649 | "crate::bar::U", | ||
650 | "self::bar::U", | ||
651 | ); | ||
606 | } | 652 | } |
607 | 653 | ||
608 | #[test] | 654 | #[test] |
609 | fn different_crate_reexport() { | 655 | fn different_crate_reexport() { |
610 | let code = r#" | 656 | check_found_path( |
611 | //- /main.rs crate:main deps:std | 657 | r#" |
612 | $0 | 658 | //- /main.rs crate:main deps:std |
613 | //- /std.rs crate:std deps:core | 659 | $0 |
614 | pub use core::S; | 660 | //- /std.rs crate:std deps:core |
615 | //- /core.rs crate:core | 661 | pub use core::S; |
616 | pub struct S; | 662 | //- /core.rs crate:core |
617 | "#; | 663 | pub struct S; |
618 | check_found_path(code, "std::S", "std::S", "std::S", "std::S"); | 664 | "#, |
665 | "std::S", | ||
666 | "std::S", | ||
667 | "std::S", | ||
668 | "std::S", | ||
669 | ); | ||
619 | } | 670 | } |
620 | 671 | ||
621 | #[test] | 672 | #[test] |
622 | fn prelude() { | 673 | fn prelude() { |
623 | let code = r#" | 674 | check_found_path( |
624 | //- /main.rs crate:main deps:std | 675 | r#" |
625 | $0 | 676 | //- /main.rs crate:main deps:std |
626 | //- /std.rs crate:std | 677 | $0 |
627 | pub mod prelude { pub struct S; } | 678 | //- /std.rs crate:std |
628 | #[prelude_import] | 679 | pub mod prelude { pub struct S; } |
629 | pub use prelude::*; | 680 | #[prelude_import] |
630 | "#; | 681 | pub use prelude::*; |
631 | check_found_path(code, "S", "S", "S", "S"); | 682 | "#, |
683 | "S", | ||
684 | "S", | ||
685 | "S", | ||
686 | "S", | ||
687 | ); | ||
632 | } | 688 | } |
633 | 689 | ||
634 | #[test] | 690 | #[test] |
635 | fn enum_variant_from_prelude() { | 691 | fn enum_variant_from_prelude() { |
636 | let code = r#" | 692 | let code = r#" |
637 | //- /main.rs crate:main deps:std | 693 | //- /main.rs crate:main deps:std |
638 | $0 | 694 | $0 |
639 | //- /std.rs crate:std | 695 | //- /std.rs crate:std |
640 | pub mod prelude { | 696 | pub mod prelude { |
641 | pub enum Option<T> { Some(T), None } | 697 | pub enum Option<T> { Some(T), None } |
642 | pub use Option::*; | 698 | pub use Option::*; |
643 | } | 699 | } |
644 | #[prelude_import] | 700 | #[prelude_import] |
645 | pub use prelude::*; | 701 | pub use prelude::*; |
646 | "#; | 702 | "#; |
647 | check_found_path(code, "None", "None", "None", "None"); | 703 | check_found_path(code, "None", "None", "None", "None"); |
648 | check_found_path(code, "Some", "Some", "Some", "Some"); | 704 | check_found_path(code, "Some", "Some", "Some", "Some"); |
@@ -650,71 +706,85 @@ mod tests { | |||
650 | 706 | ||
651 | #[test] | 707 | #[test] |
652 | fn shortest_path() { | 708 | fn shortest_path() { |
653 | let code = r#" | 709 | check_found_path( |
654 | //- /main.rs | 710 | r#" |
655 | pub mod foo; | 711 | //- /main.rs |
656 | pub mod baz; | 712 | pub mod foo; |
657 | struct S; | 713 | pub mod baz; |
658 | $0 | 714 | struct S; |
659 | //- /foo.rs | 715 | $0 |
660 | pub mod bar { pub struct S; } | 716 | //- /foo.rs |
661 | //- /baz.rs | 717 | pub mod bar { pub struct S; } |
662 | pub use crate::foo::bar::S; | 718 | //- /baz.rs |
663 | "#; | 719 | pub use crate::foo::bar::S; |
664 | check_found_path(code, "baz::S", "baz::S", "crate::baz::S", "self::baz::S"); | 720 | "#, |
721 | "baz::S", | ||
722 | "baz::S", | ||
723 | "crate::baz::S", | ||
724 | "self::baz::S", | ||
725 | ); | ||
665 | } | 726 | } |
666 | 727 | ||
667 | #[test] | 728 | #[test] |
668 | fn discount_private_imports() { | 729 | fn discount_private_imports() { |
669 | let code = r#" | 730 | check_found_path( |
670 | //- /main.rs | 731 | r#" |
671 | mod foo; | 732 | //- /main.rs |
672 | pub mod bar { pub struct S; } | 733 | mod foo; |
673 | use bar::S; | 734 | pub mod bar { pub struct S; } |
674 | //- /foo.rs | 735 | use bar::S; |
675 | $0 | 736 | //- /foo.rs |
676 | "#; | 737 | $0 |
677 | // crate::S would be shorter, but using private imports seems wrong | 738 | "#, |
678 | check_found_path(code, "crate::bar::S", "crate::bar::S", "crate::bar::S", "crate::bar::S"); | 739 | // crate::S would be shorter, but using private imports seems wrong |
740 | "crate::bar::S", | ||
741 | "crate::bar::S", | ||
742 | "crate::bar::S", | ||
743 | "crate::bar::S", | ||
744 | ); | ||
679 | } | 745 | } |
680 | 746 | ||
681 | #[test] | 747 | #[test] |
682 | fn import_cycle() { | 748 | fn import_cycle() { |
683 | let code = r#" | 749 | check_found_path( |
684 | //- /main.rs | 750 | r#" |
685 | pub mod foo; | 751 | //- /main.rs |
686 | pub mod bar; | 752 | pub mod foo; |
687 | pub mod baz; | 753 | pub mod bar; |
688 | //- /bar.rs | 754 | pub mod baz; |
689 | $0 | 755 | //- /bar.rs |
690 | //- /foo.rs | 756 | $0 |
691 | pub use super::baz; | 757 | //- /foo.rs |
692 | pub struct S; | 758 | pub use super::baz; |
693 | //- /baz.rs | 759 | pub struct S; |
694 | pub use super::foo; | 760 | //- /baz.rs |
695 | "#; | 761 | pub use super::foo; |
696 | check_found_path(code, "crate::foo::S", "crate::foo::S", "crate::foo::S", "crate::foo::S"); | 762 | "#, |
763 | "crate::foo::S", | ||
764 | "crate::foo::S", | ||
765 | "crate::foo::S", | ||
766 | "crate::foo::S", | ||
767 | ); | ||
697 | } | 768 | } |
698 | 769 | ||
699 | #[test] | 770 | #[test] |
700 | fn prefer_std_paths_over_alloc() { | 771 | fn prefer_std_paths_over_alloc() { |
701 | cov_mark::check!(prefer_std_paths); | 772 | cov_mark::check!(prefer_std_paths); |
702 | let code = r#" | 773 | check_found_path( |
703 | //- /main.rs crate:main deps:alloc,std | 774 | r#" |
704 | $0 | 775 | //- /main.rs crate:main deps:alloc,std |
776 | $0 | ||
705 | 777 | ||
706 | //- /std.rs crate:std deps:alloc | 778 | //- /std.rs crate:std deps:alloc |
707 | pub mod sync { | 779 | pub mod sync { |
708 | pub use alloc::sync::Arc; | 780 | pub use alloc::sync::Arc; |
709 | } | 781 | } |
710 | 782 | ||
711 | //- /zzz.rs crate:alloc | 783 | //- /zzz.rs crate:alloc |
712 | pub mod sync { | 784 | pub mod sync { |
713 | pub struct Arc; | 785 | pub struct Arc; |
714 | } | 786 | } |
715 | "#; | 787 | "#, |
716 | check_found_path( | ||
717 | code, | ||
718 | "std::sync::Arc", | 788 | "std::sync::Arc", |
719 | "std::sync::Arc", | 789 | "std::sync::Arc", |
720 | "std::sync::Arc", | 790 | "std::sync::Arc", |
@@ -725,26 +795,25 @@ mod tests { | |||
725 | #[test] | 795 | #[test] |
726 | fn prefer_core_paths_over_std() { | 796 | fn prefer_core_paths_over_std() { |
727 | cov_mark::check!(prefer_no_std_paths); | 797 | cov_mark::check!(prefer_no_std_paths); |
728 | let code = r#" | 798 | check_found_path( |
729 | //- /main.rs crate:main deps:core,std | 799 | r#" |
730 | #![no_std] | 800 | //- /main.rs crate:main deps:core,std |
801 | #![no_std] | ||
731 | 802 | ||
732 | $0 | 803 | $0 |
733 | 804 | ||
734 | //- /std.rs crate:std deps:core | 805 | //- /std.rs crate:std deps:core |
735 | 806 | ||
736 | pub mod fmt { | 807 | pub mod fmt { |
737 | pub use core::fmt::Error; | 808 | pub use core::fmt::Error; |
738 | } | 809 | } |
739 | 810 | ||
740 | //- /zzz.rs crate:core | 811 | //- /zzz.rs crate:core |
741 | 812 | ||
742 | pub mod fmt { | 813 | pub mod fmt { |
743 | pub struct Error; | 814 | pub struct Error; |
744 | } | 815 | } |
745 | "#; | 816 | "#, |
746 | check_found_path( | ||
747 | code, | ||
748 | "core::fmt::Error", | 817 | "core::fmt::Error", |
749 | "core::fmt::Error", | 818 | "core::fmt::Error", |
750 | "core::fmt::Error", | 819 | "core::fmt::Error", |
@@ -754,26 +823,25 @@ mod tests { | |||
754 | 823 | ||
755 | #[test] | 824 | #[test] |
756 | fn prefer_alloc_paths_over_std() { | 825 | fn prefer_alloc_paths_over_std() { |
757 | let code = r#" | 826 | check_found_path( |
758 | //- /main.rs crate:main deps:alloc,std | 827 | r#" |
759 | #![no_std] | 828 | //- /main.rs crate:main deps:alloc,std |
829 | #![no_std] | ||
760 | 830 | ||
761 | $0 | 831 | $0 |
762 | 832 | ||
763 | //- /std.rs crate:std deps:alloc | 833 | //- /std.rs crate:std deps:alloc |
764 | 834 | ||
765 | pub mod sync { | 835 | pub mod sync { |
766 | pub use alloc::sync::Arc; | 836 | pub use alloc::sync::Arc; |
767 | } | 837 | } |
768 | 838 | ||
769 | //- /zzz.rs crate:alloc | 839 | //- /zzz.rs crate:alloc |
770 | 840 | ||
771 | pub mod sync { | 841 | pub mod sync { |
772 | pub struct Arc; | 842 | pub struct Arc; |
773 | } | 843 | } |
774 | "#; | 844 | "#, |
775 | check_found_path( | ||
776 | code, | ||
777 | "alloc::sync::Arc", | 845 | "alloc::sync::Arc", |
778 | "alloc::sync::Arc", | 846 | "alloc::sync::Arc", |
779 | "alloc::sync::Arc", | 847 | "alloc::sync::Arc", |
@@ -783,20 +851,19 @@ mod tests { | |||
783 | 851 | ||
784 | #[test] | 852 | #[test] |
785 | fn prefer_shorter_paths_if_not_alloc() { | 853 | fn prefer_shorter_paths_if_not_alloc() { |
786 | let code = r#" | 854 | check_found_path( |
787 | //- /main.rs crate:main deps:megaalloc,std | 855 | r#" |
788 | $0 | 856 | //- /main.rs crate:main deps:megaalloc,std |
857 | $0 | ||
789 | 858 | ||
790 | //- /std.rs crate:std deps:megaalloc | 859 | //- /std.rs crate:std deps:megaalloc |
791 | pub mod sync { | 860 | pub mod sync { |
792 | pub use megaalloc::sync::Arc; | 861 | pub use megaalloc::sync::Arc; |
793 | } | 862 | } |
794 | 863 | ||
795 | //- /zzz.rs crate:megaalloc | 864 | //- /zzz.rs crate:megaalloc |
796 | pub struct Arc; | 865 | pub struct Arc; |
797 | "#; | 866 | "#, |
798 | check_found_path( | ||
799 | code, | ||
800 | "megaalloc::Arc", | 867 | "megaalloc::Arc", |
801 | "megaalloc::Arc", | 868 | "megaalloc::Arc", |
802 | "megaalloc::Arc", | 869 | "megaalloc::Arc", |
@@ -807,12 +874,12 @@ mod tests { | |||
807 | #[test] | 874 | #[test] |
808 | fn builtins_are_in_scope() { | 875 | fn builtins_are_in_scope() { |
809 | let code = r#" | 876 | let code = r#" |
810 | //- /main.rs | 877 | //- /main.rs |
811 | $0 | 878 | $0 |
812 | 879 | ||
813 | pub mod primitive { | 880 | pub mod primitive { |
814 | pub use u8; | 881 | pub use u8; |
815 | } | 882 | } |
816 | "#; | 883 | "#; |
817 | check_found_path(code, "u8", "u8", "u8", "u8"); | 884 | check_found_path(code, "u8", "u8", "u8", "u8"); |
818 | check_found_path(code, "u16", "u16", "u16", "u16"); | 885 | check_found_path(code, "u16", "u16", "u16", "u16"); |
@@ -822,10 +889,10 @@ mod tests { | |||
822 | fn inner_items() { | 889 | fn inner_items() { |
823 | check_found_path( | 890 | check_found_path( |
824 | r#" | 891 | r#" |
825 | fn main() { | 892 | fn main() { |
826 | struct Inner {} | 893 | struct Inner {} |
827 | $0 | 894 | $0 |
828 | } | 895 | } |
829 | "#, | 896 | "#, |
830 | "Inner", | 897 | "Inner", |
831 | "Inner", | 898 | "Inner", |
@@ -838,12 +905,12 @@ mod tests { | |||
838 | fn inner_items_from_outer_scope() { | 905 | fn inner_items_from_outer_scope() { |
839 | check_found_path( | 906 | check_found_path( |
840 | r#" | 907 | r#" |
841 | fn main() { | 908 | fn main() { |
842 | struct Struct {} | 909 | struct Struct {} |
843 | { | 910 | { |
844 | $0 | 911 | $0 |
845 | } | 912 | } |
846 | } | 913 | } |
847 | "#, | 914 | "#, |
848 | "Struct", | 915 | "Struct", |
849 | "Struct", | 916 | "Struct", |
@@ -857,14 +924,14 @@ mod tests { | |||
857 | cov_mark::check!(prefixed_in_block_expression); | 924 | cov_mark::check!(prefixed_in_block_expression); |
858 | check_found_path( | 925 | check_found_path( |
859 | r#" | 926 | r#" |
860 | fn main() { | 927 | fn main() { |
861 | mod module { | 928 | mod module { |
862 | struct Struct {} | 929 | struct Struct {} |
863 | } | 930 | } |
864 | { | 931 | { |
865 | $0 | 932 | $0 |
866 | } | 933 | } |
867 | } | 934 | } |
868 | "#, | 935 | "#, |
869 | "module::Struct", | 936 | "module::Struct", |
870 | "module::Struct", | 937 | "module::Struct", |
@@ -877,14 +944,14 @@ mod tests { | |||
877 | fn outer_items_with_inner_items_present() { | 944 | fn outer_items_with_inner_items_present() { |
878 | check_found_path( | 945 | check_found_path( |
879 | r#" | 946 | r#" |
880 | mod module { | 947 | mod module { |
881 | pub struct CompleteMe; | 948 | pub struct CompleteMe; |
882 | } | 949 | } |
883 | 950 | ||
884 | fn main() { | 951 | fn main() { |
885 | fn inner() {} | 952 | fn inner() {} |
886 | $0 | 953 | $0 |
887 | } | 954 | } |
888 | "#, | 955 | "#, |
889 | "module::CompleteMe", | 956 | "module::CompleteMe", |
890 | "module::CompleteMe", | 957 | "module::CompleteMe", |
diff --git a/crates/ide/src/move_item.rs b/crates/ide/src/move_item.rs index 8d37f4f92..246f10a0a 100644 --- a/crates/ide/src/move_item.rs +++ b/crates/ide/src/move_item.rs | |||
@@ -1,4 +1,4 @@ | |||
1 | use std::iter::once; | 1 | use std::{iter::once, mem}; |
2 | 2 | ||
3 | use hir::Semantics; | 3 | use hir::Semantics; |
4 | use ide_db::{base_db::FileRange, RootDatabase}; | 4 | use ide_db::{base_db::FileRange, RootDatabase}; |
@@ -102,7 +102,7 @@ fn move_in_direction( | |||
102 | ast::GenericArgList(it) => swap_sibling_in_list(node, it.generic_args(), range, direction), | 102 | ast::GenericArgList(it) => swap_sibling_in_list(node, it.generic_args(), range, direction), |
103 | ast::VariantList(it) => swap_sibling_in_list(node, it.variants(), range, direction), | 103 | ast::VariantList(it) => swap_sibling_in_list(node, it.variants(), range, direction), |
104 | ast::TypeBoundList(it) => swap_sibling_in_list(node, it.bounds(), range, direction), | 104 | ast::TypeBoundList(it) => swap_sibling_in_list(node, it.bounds(), range, direction), |
105 | _ => Some(replace_nodes(node, &match direction { | 105 | _ => Some(replace_nodes(range, node, &match direction { |
106 | Direction::Up => node.prev_sibling(), | 106 | Direction::Up => node.prev_sibling(), |
107 | Direction::Down => node.next_sibling(), | 107 | Direction::Down => node.next_sibling(), |
108 | }?)) | 108 | }?)) |
@@ -125,7 +125,7 @@ fn swap_sibling_in_list<A: AstNode + Clone, I: Iterator<Item = A>>( | |||
125 | .next(); | 125 | .next(); |
126 | 126 | ||
127 | if let Some((l, r)) = list_lookup { | 127 | if let Some((l, r)) = list_lookup { |
128 | Some(replace_nodes(l.syntax(), r.syntax())) | 128 | Some(replace_nodes(range, l.syntax(), r.syntax())) |
129 | } else { | 129 | } else { |
130 | // Cursor is beyond any movable list item (for example, on curly brace in enum). | 130 | // Cursor is beyond any movable list item (for example, on curly brace in enum). |
131 | // It's not necessary, that parent of list is movable (arg list's parent is not, for example), | 131 | // It's not necessary, that parent of list is movable (arg list's parent is not, for example), |
@@ -134,11 +134,38 @@ fn swap_sibling_in_list<A: AstNode + Clone, I: Iterator<Item = A>>( | |||
134 | } | 134 | } |
135 | } | 135 | } |
136 | 136 | ||
137 | fn replace_nodes(first: &SyntaxNode, second: &SyntaxNode) -> TextEdit { | 137 | fn replace_nodes<'a>( |
138 | range: TextRange, | ||
139 | mut first: &'a SyntaxNode, | ||
140 | mut second: &'a SyntaxNode, | ||
141 | ) -> TextEdit { | ||
142 | let cursor_offset = if range.is_empty() { | ||
143 | // FIXME: `applySnippetTextEdits` does not support non-empty selection ranges | ||
144 | if first.text_range().contains_range(range) { | ||
145 | Some(range.start() - first.text_range().start()) | ||
146 | } else if second.text_range().contains_range(range) { | ||
147 | mem::swap(&mut first, &mut second); | ||
148 | Some(range.start() - first.text_range().start()) | ||
149 | } else { | ||
150 | None | ||
151 | } | ||
152 | } else { | ||
153 | None | ||
154 | }; | ||
155 | |||
156 | let first_with_cursor = match cursor_offset { | ||
157 | Some(offset) => { | ||
158 | let mut item_text = first.text().to_string(); | ||
159 | item_text.insert_str(offset.into(), "$0"); | ||
160 | item_text | ||
161 | } | ||
162 | None => first.text().to_string(), | ||
163 | }; | ||
164 | |||
138 | let mut edit = TextEditBuilder::default(); | 165 | let mut edit = TextEditBuilder::default(); |
139 | 166 | ||
140 | algo::diff(first, second).into_text_edit(&mut edit); | 167 | algo::diff(first, second).into_text_edit(&mut edit); |
141 | algo::diff(second, first).into_text_edit(&mut edit); | 168 | edit.replace(second.text_range(), first_with_cursor); |
142 | 169 | ||
143 | edit.finish() | 170 | edit.finish() |
144 | } | 171 | } |
@@ -188,7 +215,7 @@ fn main() { | |||
188 | expect![[r#" | 215 | expect![[r#" |
189 | fn main() { | 216 | fn main() { |
190 | match true { | 217 | match true { |
191 | false => { | 218 | false =>$0 { |
192 | println!("Test"); | 219 | println!("Test"); |
193 | }, | 220 | }, |
194 | true => { | 221 | true => { |
@@ -222,7 +249,7 @@ fn main() { | |||
222 | false => { | 249 | false => { |
223 | println!("Test"); | 250 | println!("Test"); |
224 | }, | 251 | }, |
225 | true => { | 252 | true =>$0 { |
226 | println!("Hello, world"); | 253 | println!("Hello, world"); |
227 | } | 254 | } |
228 | }; | 255 | }; |
@@ -274,7 +301,7 @@ fn main() { | |||
274 | "#, | 301 | "#, |
275 | expect![[r#" | 302 | expect![[r#" |
276 | fn main() { | 303 | fn main() { |
277 | let test2 = 456; | 304 | let test2$0 = 456; |
278 | let test = 123; | 305 | let test = 123; |
279 | } | 306 | } |
280 | "#]], | 307 | "#]], |
@@ -293,7 +320,7 @@ fn main() { | |||
293 | "#, | 320 | "#, |
294 | expect![[r#" | 321 | expect![[r#" |
295 | fn main() { | 322 | fn main() { |
296 | println!("All I want to say is..."); | 323 | println!("All I want to say is...");$0 |
297 | println!("Hello, world"); | 324 | println!("Hello, world"); |
298 | } | 325 | } |
299 | "#]], | 326 | "#]], |
@@ -313,7 +340,7 @@ fn main() { | |||
313 | fn main() { | 340 | fn main() { |
314 | if true { | 341 | if true { |
315 | println!("Test"); | 342 | println!("Test"); |
316 | } | 343 | }$0 |
317 | 344 | ||
318 | println!("Hello, world"); | 345 | println!("Hello, world"); |
319 | } | 346 | } |
@@ -334,7 +361,7 @@ fn main() { | |||
334 | fn main() { | 361 | fn main() { |
335 | for i in 0..10 { | 362 | for i in 0..10 { |
336 | println!("Test"); | 363 | println!("Test"); |
337 | } | 364 | }$0 |
338 | 365 | ||
339 | println!("Hello, world"); | 366 | println!("Hello, world"); |
340 | } | 367 | } |
@@ -355,7 +382,7 @@ fn main() { | |||
355 | fn main() { | 382 | fn main() { |
356 | loop { | 383 | loop { |
357 | println!("Test"); | 384 | println!("Test"); |
358 | } | 385 | }$0 |
359 | 386 | ||
360 | println!("Hello, world"); | 387 | println!("Hello, world"); |
361 | } | 388 | } |
@@ -376,7 +403,7 @@ fn main() { | |||
376 | fn main() { | 403 | fn main() { |
377 | while true { | 404 | while true { |
378 | println!("Test"); | 405 | println!("Test"); |
379 | } | 406 | }$0 |
380 | 407 | ||
381 | println!("Hello, world"); | 408 | println!("Hello, world"); |
382 | } | 409 | } |
@@ -393,7 +420,7 @@ fn main() { | |||
393 | "#, | 420 | "#, |
394 | expect![[r#" | 421 | expect![[r#" |
395 | fn main() { | 422 | fn main() { |
396 | return 123; | 423 | return 123;$0 |
397 | 424 | ||
398 | println!("Hello, world"); | 425 | println!("Hello, world"); |
399 | } | 426 | } |
@@ -430,7 +457,7 @@ fn main() {} | |||
430 | fn foo() {}$0$0 | 457 | fn foo() {}$0$0 |
431 | "#, | 458 | "#, |
432 | expect![[r#" | 459 | expect![[r#" |
433 | fn foo() {} | 460 | fn foo() {}$0 |
434 | 461 | ||
435 | fn main() {} | 462 | fn main() {} |
436 | "#]], | 463 | "#]], |
@@ -451,7 +478,7 @@ impl Wow for Yay $0$0{} | |||
451 | expect![[r#" | 478 | expect![[r#" |
452 | struct Yay; | 479 | struct Yay; |
453 | 480 | ||
454 | impl Wow for Yay {} | 481 | impl Wow for Yay $0{} |
455 | 482 | ||
456 | trait Wow {} | 483 | trait Wow {} |
457 | "#]], | 484 | "#]], |
@@ -467,7 +494,7 @@ use std::vec::Vec; | |||
467 | use std::collections::HashMap$0$0; | 494 | use std::collections::HashMap$0$0; |
468 | "#, | 495 | "#, |
469 | expect![[r#" | 496 | expect![[r#" |
470 | use std::collections::HashMap; | 497 | use std::collections::HashMap$0; |
471 | use std::vec::Vec; | 498 | use std::vec::Vec; |
472 | "#]], | 499 | "#]], |
473 | Direction::Up, | 500 | Direction::Up, |
@@ -502,7 +529,7 @@ fn main() { | |||
502 | } | 529 | } |
503 | 530 | ||
504 | #[test] | 531 | #[test] |
505 | fn test_moves_param_up() { | 532 | fn test_moves_param() { |
506 | check( | 533 | check( |
507 | r#" | 534 | r#" |
508 | fn test(one: i32, two$0$0: u32) {} | 535 | fn test(one: i32, two$0$0: u32) {} |
@@ -512,7 +539,7 @@ fn main() { | |||
512 | } | 539 | } |
513 | "#, | 540 | "#, |
514 | expect![[r#" | 541 | expect![[r#" |
515 | fn test(two: u32, one: i32) {} | 542 | fn test(two$0: u32, one: i32) {} |
516 | 543 | ||
517 | fn main() { | 544 | fn main() { |
518 | test(123, 456); | 545 | test(123, 456); |
@@ -520,6 +547,15 @@ fn main() { | |||
520 | "#]], | 547 | "#]], |
521 | Direction::Up, | 548 | Direction::Up, |
522 | ); | 549 | ); |
550 | check( | ||
551 | r#" | ||
552 | fn f($0$0arg: u8, arg2: u16) {} | ||
553 | "#, | ||
554 | expect![[r#" | ||
555 | fn f(arg2: u16, $0arg: u8) {} | ||
556 | "#]], | ||
557 | Direction::Down, | ||
558 | ); | ||
523 | } | 559 | } |
524 | 560 | ||
525 | #[test] | 561 | #[test] |
@@ -536,7 +572,7 @@ fn main() { | |||
536 | fn test(one: i32, two: u32) {} | 572 | fn test(one: i32, two: u32) {} |
537 | 573 | ||
538 | fn main() { | 574 | fn main() { |
539 | test(456, 123); | 575 | test(456$0, 123); |
540 | } | 576 | } |
541 | "#]], | 577 | "#]], |
542 | Direction::Up, | 578 | Direction::Up, |
@@ -557,7 +593,7 @@ fn main() { | |||
557 | fn test(one: i32, two: u32) {} | 593 | fn test(one: i32, two: u32) {} |
558 | 594 | ||
559 | fn main() { | 595 | fn main() { |
560 | test(456, 123); | 596 | test(456, 123$0); |
561 | } | 597 | } |
562 | "#]], | 598 | "#]], |
563 | Direction::Down, | 599 | Direction::Down, |
@@ -594,7 +630,7 @@ struct Test<A, B$0$0>(A, B); | |||
594 | fn main() {} | 630 | fn main() {} |
595 | "#, | 631 | "#, |
596 | expect![[r#" | 632 | expect![[r#" |
597 | struct Test<B, A>(A, B); | 633 | struct Test<B$0, A>(A, B); |
598 | 634 | ||
599 | fn main() {} | 635 | fn main() {} |
600 | "#]], | 636 | "#]], |
@@ -616,7 +652,7 @@ fn main() { | |||
616 | struct Test<A, B>(A, B); | 652 | struct Test<A, B>(A, B); |
617 | 653 | ||
618 | fn main() { | 654 | fn main() { |
619 | let t = Test::<&str, i32>(123, "yay"); | 655 | let t = Test::<&str$0, i32>(123, "yay"); |
620 | } | 656 | } |
621 | "#]], | 657 | "#]], |
622 | Direction::Up, | 658 | Direction::Up, |
@@ -636,7 +672,7 @@ fn main() {} | |||
636 | "#, | 672 | "#, |
637 | expect![[r#" | 673 | expect![[r#" |
638 | enum Hello { | 674 | enum Hello { |
639 | Two, | 675 | Two$0, |
640 | One | 676 | One |
641 | } | 677 | } |
642 | 678 | ||
@@ -663,7 +699,7 @@ trait One {} | |||
663 | 699 | ||
664 | trait Two {} | 700 | trait Two {} |
665 | 701 | ||
666 | fn test<T: Two + One>(t: T) {} | 702 | fn test<T: Two$0 + One>(t: T) {} |
667 | 703 | ||
668 | fn main() {} | 704 | fn main() {} |
669 | "#]], | 705 | "#]], |
@@ -709,7 +745,7 @@ trait Yay { | |||
709 | impl Yay for Test { | 745 | impl Yay for Test { |
710 | type One = i32; | 746 | type One = i32; |
711 | 747 | ||
712 | fn inner() { | 748 | fn inner() {$0 |
713 | println!("Mmmm"); | 749 | println!("Mmmm"); |
714 | } | 750 | } |
715 | 751 | ||
@@ -736,7 +772,7 @@ fn test() { | |||
736 | "#, | 772 | "#, |
737 | expect![[r#" | 773 | expect![[r#" |
738 | fn test() { | 774 | fn test() { |
739 | mod hi { | 775 | mod hi {$0 |
740 | fn inner() {} | 776 | fn inner() {} |
741 | } | 777 | } |
742 | 778 | ||
@@ -764,7 +800,7 @@ fn main() {} | |||
764 | expect![[r#" | 800 | expect![[r#" |
765 | fn main() {} | 801 | fn main() {} |
766 | 802 | ||
767 | #[derive(Debug)] | 803 | $0#[derive(Debug)] |
768 | enum FooBar { | 804 | enum FooBar { |
769 | Foo, | 805 | Foo, |
770 | Bar, | 806 | Bar, |
@@ -784,7 +820,7 @@ fn main() {} | |||
784 | expect![[r#" | 820 | expect![[r#" |
785 | fn main() {} | 821 | fn main() {} |
786 | 822 | ||
787 | enum FooBar { | 823 | $0enum FooBar { |
788 | Foo, | 824 | Foo, |
789 | Bar, | 825 | Bar, |
790 | } | 826 | } |
@@ -804,7 +840,7 @@ fn main() {} | |||
804 | expect![[r#" | 840 | expect![[r#" |
805 | struct Test; | 841 | struct Test; |
806 | 842 | ||
807 | impl SomeTrait for Test {} | 843 | $0impl SomeTrait for Test {} |
808 | 844 | ||
809 | trait SomeTrait {} | 845 | trait SomeTrait {} |
810 | 846 | ||
@@ -831,7 +867,7 @@ fn main() {} | |||
831 | enum FooBar { | 867 | enum FooBar { |
832 | Foo, | 868 | Foo, |
833 | Bar, | 869 | Bar, |
834 | } | 870 | }$0 |
835 | "#]], | 871 | "#]], |
836 | Direction::Down, | 872 | Direction::Down, |
837 | ); | 873 | ); |
@@ -848,7 +884,7 @@ fn main() {} | |||
848 | expect![[r#" | 884 | expect![[r#" |
849 | struct Test; | 885 | struct Test; |
850 | 886 | ||
851 | impl SomeTrait for Test {} | 887 | impl SomeTrait for Test {}$0 |
852 | 888 | ||
853 | trait SomeTrait {} | 889 | trait SomeTrait {} |
854 | 890 | ||
diff --git a/crates/rust-analyzer/src/handlers.rs b/crates/rust-analyzer/src/handlers.rs index 4f0c9d23c..1f59402e5 100644 --- a/crates/rust-analyzer/src/handlers.rs +++ b/crates/rust-analyzer/src/handlers.rs | |||
@@ -1410,7 +1410,7 @@ pub(crate) fn handle_open_cargo_toml( | |||
1410 | pub(crate) fn handle_move_item( | 1410 | pub(crate) fn handle_move_item( |
1411 | snap: GlobalStateSnapshot, | 1411 | snap: GlobalStateSnapshot, |
1412 | params: lsp_ext::MoveItemParams, | 1412 | params: lsp_ext::MoveItemParams, |
1413 | ) -> Result<Option<lsp_types::TextDocumentEdit>> { | 1413 | ) -> Result<Vec<lsp_ext::SnippetTextEdit>> { |
1414 | let _p = profile::span("handle_move_item"); | 1414 | let _p = profile::span("handle_move_item"); |
1415 | let file_id = from_proto::file_id(&snap, ¶ms.text_document.uri)?; | 1415 | let file_id = from_proto::file_id(&snap, ¶ms.text_document.uri)?; |
1416 | let range = from_proto::file_range(&snap, params.text_document, params.range)?; | 1416 | let range = from_proto::file_range(&snap, params.text_document, params.range)?; |
@@ -1421,8 +1421,11 @@ pub(crate) fn handle_move_item( | |||
1421 | }; | 1421 | }; |
1422 | 1422 | ||
1423 | match snap.analysis.move_item(range, direction)? { | 1423 | match snap.analysis.move_item(range, direction)? { |
1424 | Some(text_edit) => Ok(Some(to_proto::text_document_edit(&snap, file_id, text_edit)?)), | 1424 | Some(text_edit) => { |
1425 | None => Ok(None), | 1425 | let line_index = snap.file_line_index(file_id)?; |
1426 | Ok(to_proto::snippet_text_edit_vec(&line_index, true, text_edit)) | ||
1427 | } | ||
1428 | None => Ok(vec![]), | ||
1426 | } | 1429 | } |
1427 | } | 1430 | } |
1428 | 1431 | ||
diff --git a/crates/rust-analyzer/src/lsp_ext.rs b/crates/rust-analyzer/src/lsp_ext.rs index 81a6f22f1..d648cda32 100644 --- a/crates/rust-analyzer/src/lsp_ext.rs +++ b/crates/rust-analyzer/src/lsp_ext.rs | |||
@@ -407,7 +407,7 @@ pub enum MoveItem {} | |||
407 | 407 | ||
408 | impl Request for MoveItem { | 408 | impl Request for MoveItem { |
409 | type Params = MoveItemParams; | 409 | type Params = MoveItemParams; |
410 | type Result = Option<lsp_types::TextDocumentEdit>; | 410 | type Result = Vec<SnippetTextEdit>; |
411 | const METHOD: &'static str = "experimental/moveItem"; | 411 | const METHOD: &'static str = "experimental/moveItem"; |
412 | } | 412 | } |
413 | 413 | ||
diff --git a/crates/rust-analyzer/src/to_proto.rs b/crates/rust-analyzer/src/to_proto.rs index 8d7cb9b74..1a1f65f3b 100644 --- a/crates/rust-analyzer/src/to_proto.rs +++ b/crates/rust-analyzer/src/to_proto.rs | |||
@@ -688,18 +688,6 @@ pub(crate) fn goto_definition_response( | |||
688 | } | 688 | } |
689 | } | 689 | } |
690 | 690 | ||
691 | pub(crate) fn text_document_edit( | ||
692 | snap: &GlobalStateSnapshot, | ||
693 | file_id: FileId, | ||
694 | edit: TextEdit, | ||
695 | ) -> Result<lsp_types::TextDocumentEdit> { | ||
696 | let text_document = optional_versioned_text_document_identifier(snap, file_id); | ||
697 | let line_index = snap.file_line_index(file_id)?; | ||
698 | let edits = | ||
699 | edit.into_iter().map(|it| lsp_types::OneOf::Left(text_edit(&line_index, it))).collect(); | ||
700 | Ok(lsp_types::TextDocumentEdit { text_document, edits }) | ||
701 | } | ||
702 | |||
703 | pub(crate) fn snippet_text_document_edit( | 691 | pub(crate) fn snippet_text_document_edit( |
704 | snap: &GlobalStateSnapshot, | 692 | snap: &GlobalStateSnapshot, |
705 | is_snippet: bool, | 693 | is_snippet: bool, |