diff options
Diffstat (limited to 'crates/ide_db/src')
-rw-r--r-- | crates/ide_db/src/helpers/insert_use.rs | 8 | ||||
-rw-r--r-- | crates/ide_db/src/helpers/insert_use/tests.rs | 72 |
2 files changed, 67 insertions, 13 deletions
diff --git a/crates/ide_db/src/helpers/insert_use.rs b/crates/ide_db/src/helpers/insert_use.rs index 10bbafe77..4da058cb2 100644 --- a/crates/ide_db/src/helpers/insert_use.rs +++ b/crates/ide_db/src/helpers/insert_use.rs | |||
@@ -36,6 +36,7 @@ pub struct InsertUseConfig { | |||
36 | pub enforce_granularity: bool, | 36 | pub enforce_granularity: bool, |
37 | pub prefix_kind: PrefixKind, | 37 | pub prefix_kind: PrefixKind, |
38 | pub group: bool, | 38 | pub group: bool, |
39 | pub skip_glob_imports: bool, | ||
39 | } | 40 | } |
40 | 41 | ||
41 | #[derive(Debug, Clone)] | 42 | #[derive(Debug, Clone)] |
@@ -153,7 +154,7 @@ enum ImportGranularityGuess { | |||
153 | } | 154 | } |
154 | 155 | ||
155 | /// Insert an import path into the given file/node. A `merge` value of none indicates that no import merging is allowed to occur. | 156 | /// Insert an import path into the given file/node. A `merge` value of none indicates that no import merging is allowed to occur. |
156 | pub fn insert_use<'a>(scope: &ImportScope, path: ast::Path, cfg: InsertUseConfig) { | 157 | pub fn insert_use<'a>(scope: &ImportScope, path: ast::Path, cfg: &InsertUseConfig) { |
157 | let _p = profile::span("insert_use"); | 158 | let _p = profile::span("insert_use"); |
158 | let mut mb = match cfg.granularity { | 159 | let mut mb = match cfg.granularity { |
159 | ImportGranularity::Crate => Some(MergeBehavior::Crate), | 160 | ImportGranularity::Crate => Some(MergeBehavior::Crate), |
@@ -175,7 +176,10 @@ pub fn insert_use<'a>(scope: &ImportScope, path: ast::Path, cfg: InsertUseConfig | |||
175 | make::use_(None, make::use_tree(path.clone(), None, None, false)).clone_for_update(); | 176 | make::use_(None, make::use_tree(path.clone(), None, None, false)).clone_for_update(); |
176 | // merge into existing imports if possible | 177 | // merge into existing imports if possible |
177 | if let Some(mb) = mb { | 178 | if let Some(mb) = mb { |
178 | for existing_use in scope.as_syntax_node().children().filter_map(ast::Use::cast) { | 179 | let filter = |it: &_| !(cfg.skip_glob_imports && ast::Use::is_simple_glob(it)); |
180 | for existing_use in | ||
181 | scope.as_syntax_node().children().filter_map(ast::Use::cast).filter(filter) | ||
182 | { | ||
179 | if let Some(merged) = try_merge_imports(&existing_use, &use_item, mb) { | 183 | if let Some(merged) = try_merge_imports(&existing_use, &use_item, mb) { |
180 | ted::replace(existing_use.syntax(), merged.syntax()); | 184 | ted::replace(existing_use.syntax(), merged.syntax()); |
181 | return; | 185 | return; |
diff --git a/crates/ide_db/src/helpers/insert_use/tests.rs b/crates/ide_db/src/helpers/insert_use/tests.rs index 5a88ec742..263edcdc9 100644 --- a/crates/ide_db/src/helpers/insert_use/tests.rs +++ b/crates/ide_db/src/helpers/insert_use/tests.rs | |||
@@ -4,6 +4,23 @@ use hir::PrefixKind; | |||
4 | use test_utils::assert_eq_text; | 4 | use test_utils::assert_eq_text; |
5 | 5 | ||
6 | #[test] | 6 | #[test] |
7 | fn insert_skips_lone_glob_imports() { | ||
8 | check( | ||
9 | "use foo::baz::A", | ||
10 | r" | ||
11 | use foo::bar::*; | ||
12 | ", | ||
13 | r" | ||
14 | use foo::bar::*; | ||
15 | use foo::baz::A; | ||
16 | ", | ||
17 | ImportGranularity::Crate, | ||
18 | false, | ||
19 | false, | ||
20 | ); | ||
21 | } | ||
22 | |||
23 | #[test] | ||
7 | fn insert_not_group() { | 24 | fn insert_not_group() { |
8 | cov_mark::check!(insert_no_grouping_last); | 25 | cov_mark::check!(insert_no_grouping_last); |
9 | check( | 26 | check( |
@@ -534,17 +551,37 @@ fn merge_groups_self() { | |||
534 | 551 | ||
535 | #[test] | 552 | #[test] |
536 | fn merge_mod_into_glob() { | 553 | fn merge_mod_into_glob() { |
537 | check_crate( | 554 | check_with_config( |
538 | "token::TokenKind", | 555 | "token::TokenKind", |
539 | r"use token::TokenKind::*;", | 556 | r"use token::TokenKind::*;", |
540 | r"use token::TokenKind::{*, self};", | 557 | r"use token::TokenKind::{*, self};", |
558 | false, | ||
559 | &InsertUseConfig { | ||
560 | granularity: ImportGranularity::Crate, | ||
561 | enforce_granularity: true, | ||
562 | prefix_kind: PrefixKind::Plain, | ||
563 | group: false, | ||
564 | skip_glob_imports: false, | ||
565 | }, | ||
541 | ) | 566 | ) |
542 | // FIXME: have it emit `use token::TokenKind::{self, *}`? | 567 | // FIXME: have it emit `use token::TokenKind::{self, *}`? |
543 | } | 568 | } |
544 | 569 | ||
545 | #[test] | 570 | #[test] |
546 | fn merge_self_glob() { | 571 | fn merge_self_glob() { |
547 | check_crate("self", r"use self::*;", r"use self::{*, self};") | 572 | check_with_config( |
573 | "self", | ||
574 | r"use self::*;", | ||
575 | r"use self::{*, self};", | ||
576 | false, | ||
577 | &InsertUseConfig { | ||
578 | granularity: ImportGranularity::Crate, | ||
579 | enforce_granularity: true, | ||
580 | prefix_kind: PrefixKind::Plain, | ||
581 | group: false, | ||
582 | skip_glob_imports: false, | ||
583 | }, | ||
584 | ) | ||
548 | // FIXME: have it emit `use {self, *}`? | 585 | // FIXME: have it emit `use {self, *}`? |
549 | } | 586 | } |
550 | 587 | ||
@@ -757,13 +794,12 @@ use foo::bar::qux; | |||
757 | ); | 794 | ); |
758 | } | 795 | } |
759 | 796 | ||
760 | fn check( | 797 | fn check_with_config( |
761 | path: &str, | 798 | path: &str, |
762 | ra_fixture_before: &str, | 799 | ra_fixture_before: &str, |
763 | ra_fixture_after: &str, | 800 | ra_fixture_after: &str, |
764 | granularity: ImportGranularity, | ||
765 | module: bool, | 801 | module: bool, |
766 | group: bool, | 802 | config: &InsertUseConfig, |
767 | ) { | 803 | ) { |
768 | let mut syntax = ast::SourceFile::parse(ra_fixture_before).tree().syntax().clone(); | 804 | let mut syntax = ast::SourceFile::parse(ra_fixture_before).tree().syntax().clone(); |
769 | if module { | 805 | if module { |
@@ -777,18 +813,32 @@ fn check( | |||
777 | .find_map(ast::Path::cast) | 813 | .find_map(ast::Path::cast) |
778 | .unwrap(); | 814 | .unwrap(); |
779 | 815 | ||
780 | insert_use( | 816 | insert_use(&file, path, config); |
781 | &file, | 817 | let result = file.as_syntax_node().to_string(); |
818 | assert_eq_text!(ra_fixture_after, &result); | ||
819 | } | ||
820 | |||
821 | fn check( | ||
822 | path: &str, | ||
823 | ra_fixture_before: &str, | ||
824 | ra_fixture_after: &str, | ||
825 | granularity: ImportGranularity, | ||
826 | module: bool, | ||
827 | group: bool, | ||
828 | ) { | ||
829 | check_with_config( | ||
782 | path, | 830 | path, |
783 | InsertUseConfig { | 831 | ra_fixture_before, |
832 | ra_fixture_after, | ||
833 | module, | ||
834 | &InsertUseConfig { | ||
784 | granularity, | 835 | granularity, |
785 | enforce_granularity: true, | 836 | enforce_granularity: true, |
786 | prefix_kind: PrefixKind::Plain, | 837 | prefix_kind: PrefixKind::Plain, |
787 | group, | 838 | group, |
839 | skip_glob_imports: true, | ||
788 | }, | 840 | }, |
789 | ); | 841 | ) |
790 | let result = file.as_syntax_node().to_string(); | ||
791 | assert_eq_text!(ra_fixture_after, &result); | ||
792 | } | 842 | } |
793 | 843 | ||
794 | fn check_crate(path: &str, ra_fixture_before: &str, ra_fixture_after: &str) { | 844 | fn check_crate(path: &str, ra_fixture_before: &str, ra_fixture_after: &str) { |