Allow to disable import insertion on single path glob imports

This commit is contained in:
Lukas Wirth 2021-06-18 23:11:56 +02:00
parent 84507a0b9c
commit 2ee090faaf
14 changed files with 99 additions and 17 deletions

View file

@ -36,6 +36,7 @@ pub struct InsertUseConfig {
pub enforce_granularity: bool,
pub prefix_kind: PrefixKind,
pub group: bool,
pub skip_glob_imports: bool,
}
#[derive(Debug, Clone)]
@ -153,7 +154,7 @@ enum ImportGranularityGuess {
}
/// Insert an import path into the given file/node. A `merge` value of none indicates that no import merging is allowed to occur.
pub fn insert_use<'a>(scope: &ImportScope, path: ast::Path, cfg: InsertUseConfig) {
pub fn insert_use<'a>(scope: &ImportScope, path: ast::Path, cfg: &InsertUseConfig) {
let _p = profile::span("insert_use");
let mut mb = match cfg.granularity {
ImportGranularity::Crate => Some(MergeBehavior::Crate),
@ -175,7 +176,10 @@ pub fn insert_use<'a>(scope: &ImportScope, path: ast::Path, cfg: InsertUseConfig
make::use_(None, make::use_tree(path.clone(), None, None, false)).clone_for_update();
// merge into existing imports if possible
if let Some(mb) = mb {
for existing_use in scope.as_syntax_node().children().filter_map(ast::Use::cast) {
let filter = |it: &_| !(cfg.skip_glob_imports && ast::Use::is_simple_glob(it));
for existing_use in
scope.as_syntax_node().children().filter_map(ast::Use::cast).filter(filter)
{
if let Some(merged) = try_merge_imports(&existing_use, &use_item, mb) {
ted::replace(existing_use.syntax(), merged.syntax());
return;

View file

@ -3,6 +3,23 @@ use super::*;
use hir::PrefixKind;
use test_utils::assert_eq_text;
#[test]
fn insert_skips_lone_glob_imports() {
check(
"use foo::baz::A",
r"
use foo::bar::*;
",
r"
use foo::bar::*;
use foo::baz::A;
",
ImportGranularity::Crate,
false,
false,
);
}
#[test]
fn insert_not_group() {
cov_mark::check!(insert_no_grouping_last);
@ -534,17 +551,37 @@ fn merge_groups_self() {
#[test]
fn merge_mod_into_glob() {
check_crate(
check_with_config(
"token::TokenKind",
r"use token::TokenKind::*;",
r"use token::TokenKind::{*, self};",
false,
&InsertUseConfig {
granularity: ImportGranularity::Crate,
enforce_granularity: true,
prefix_kind: PrefixKind::Plain,
group: false,
skip_glob_imports: false,
},
)
// FIXME: have it emit `use token::TokenKind::{self, *}`?
}
#[test]
fn merge_self_glob() {
check_crate("self", r"use self::*;", r"use self::{*, self};")
check_with_config(
"self",
r"use self::*;",
r"use self::{*, self};",
false,
&InsertUseConfig {
granularity: ImportGranularity::Crate,
enforce_granularity: true,
prefix_kind: PrefixKind::Plain,
group: false,
skip_glob_imports: false,
},
)
// FIXME: have it emit `use {self, *}`?
}
@ -757,13 +794,12 @@ use foo::bar::qux;
);
}
fn check(
fn check_with_config(
path: &str,
ra_fixture_before: &str,
ra_fixture_after: &str,
granularity: ImportGranularity,
module: bool,
group: bool,
config: &InsertUseConfig,
) {
let mut syntax = ast::SourceFile::parse(ra_fixture_before).tree().syntax().clone();
if module {
@ -777,18 +813,32 @@ fn check(
.find_map(ast::Path::cast)
.unwrap();
insert_use(
&file,
insert_use(&file, path, config);
let result = file.as_syntax_node().to_string();
assert_eq_text!(ra_fixture_after, &result);
}
fn check(
path: &str,
ra_fixture_before: &str,
ra_fixture_after: &str,
granularity: ImportGranularity,
module: bool,
group: bool,
) {
check_with_config(
path,
InsertUseConfig {
ra_fixture_before,
ra_fixture_after,
module,
&InsertUseConfig {
granularity,
enforce_granularity: true,
prefix_kind: PrefixKind::Plain,
group,
skip_glob_imports: true,
},
);
let result = file.as_syntax_node().to_string();
assert_eq_text!(ra_fixture_after, &result);
)
}
fn check_crate(path: &str, ra_fixture_before: &str, ra_fixture_after: &str) {