mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-23 23:34:48 +00:00
Allow to disable import insertion on single path glob imports
This commit is contained in:
parent
84507a0b9c
commit
2ee090faaf
@ -104,7 +104,7 @@ pub(crate) fn auto_import(acc: &mut Assists, ctx: &AssistContext) -> Option<()>
|
||||
ImportScope::File(it) => ImportScope::File(builder.make_mut(it)),
|
||||
ImportScope::Module(it) => ImportScope::Module(builder.make_mut(it)),
|
||||
};
|
||||
insert_use(&scope, mod_path_to_ast(&import.import_path), ctx.config.insert_use);
|
||||
insert_use(&scope, mod_path_to_ast(&import.import_path), &ctx.config.insert_use);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
@ -235,7 +235,7 @@ fn apply_references(
|
||||
import: Option<(ImportScope, hir::ModPath)>,
|
||||
) {
|
||||
if let Some((scope, path)) = import {
|
||||
insert_use(&scope, mod_path_to_ast(&path), insert_use_cfg);
|
||||
insert_use(&scope, mod_path_to_ast(&path), &insert_use_cfg);
|
||||
}
|
||||
// deep clone to prevent cycle
|
||||
let path = make::path_from_segments(iter::once(segment.clone_subtree()), false);
|
||||
|
@ -43,7 +43,7 @@ pub(crate) fn replace_qualified_name_with_use(
|
||||
let syntax = builder.make_syntax_mut(syntax.clone());
|
||||
if let Some(ref import_scope) = ImportScope::from(syntax.clone()) {
|
||||
shorten_paths(&syntax, &path.clone_for_update());
|
||||
insert_use(import_scope, path, ctx.config.insert_use);
|
||||
insert_use(import_scope, path, &ctx.config.insert_use);
|
||||
}
|
||||
},
|
||||
)
|
||||
|
@ -28,6 +28,7 @@ pub(crate) const TEST_CONFIG: AssistConfig = AssistConfig {
|
||||
prefix_kind: hir::PrefixKind::Plain,
|
||||
enforce_granularity: true,
|
||||
group: true,
|
||||
skip_glob_imports: true,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -378,7 +378,7 @@ impl ImportEdit {
|
||||
let _p = profile::span("ImportEdit::to_text_edit");
|
||||
|
||||
let new_ast = self.scope.clone_for_update();
|
||||
insert_use::insert_use(&new_ast, mod_path_to_ast(&self.import.import_path), cfg);
|
||||
insert_use::insert_use(&new_ast, mod_path_to_ast(&self.import.import_path), &cfg);
|
||||
let mut import_insert = TextEdit::builder();
|
||||
algo::diff(self.scope.as_syntax_node(), new_ast.as_syntax_node())
|
||||
.into_text_edit(&mut import_insert);
|
||||
|
@ -36,6 +36,7 @@ pub(crate) const TEST_CONFIG: CompletionConfig = CompletionConfig {
|
||||
prefix_kind: PrefixKind::Plain,
|
||||
enforce_granularity: true,
|
||||
group: true,
|
||||
skip_glob_imports: true,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
@ -44,6 +44,9 @@ config_data! {
|
||||
assist_importPrefix: ImportPrefixDef = "\"plain\"",
|
||||
/// Group inserted imports by the [following order](https://rust-analyzer.github.io/manual.html#auto-import). Groups are separated by newlines.
|
||||
assist_importGroup: bool = "true",
|
||||
/// Whether to allow import insertion to merge new imports into single path glob imports like `use std::fmt::*;`.
|
||||
assist_allowMergingIntoGlobImports: bool = "true",
|
||||
|
||||
/// Show function name and docs in parameter hints.
|
||||
callInfo_full: bool = "true",
|
||||
|
||||
@ -672,6 +675,7 @@ impl Config {
|
||||
ImportPrefixDef::BySelf => PrefixKind::BySelf,
|
||||
},
|
||||
group: self.data.assist_importGroup,
|
||||
skip_glob_imports: !self.data.assist_allowMergingIntoGlobImports,
|
||||
}
|
||||
}
|
||||
pub fn completion(&self) -> CompletionConfig {
|
||||
|
@ -143,6 +143,7 @@ fn integrated_completion_benchmark() {
|
||||
prefix_kind: hir::PrefixKind::ByCrate,
|
||||
enforce_granularity: true,
|
||||
group: true,
|
||||
skip_glob_imports: true,
|
||||
},
|
||||
};
|
||||
let position =
|
||||
@ -178,6 +179,7 @@ fn integrated_completion_benchmark() {
|
||||
prefix_kind: hir::PrefixKind::ByCrate,
|
||||
enforce_granularity: true,
|
||||
group: true,
|
||||
skip_glob_imports: true,
|
||||
},
|
||||
};
|
||||
let position =
|
||||
|
@ -1187,6 +1187,7 @@ mod tests {
|
||||
prefix_kind: PrefixKind::Plain,
|
||||
enforce_granularity: true,
|
||||
group: true,
|
||||
skip_glob_imports: true,
|
||||
},
|
||||
},
|
||||
ide_db::base_db::FilePosition { file_id, offset },
|
||||
|
@ -281,6 +281,15 @@ impl ast::Path {
|
||||
successors(self.qualifier(), |p| p.qualifier())
|
||||
}
|
||||
}
|
||||
|
||||
impl ast::Use {
|
||||
pub fn is_simple_glob(&self) -> bool {
|
||||
self.use_tree()
|
||||
.map(|use_tree| use_tree.use_tree_list().is_none() && use_tree.star_token().is_some())
|
||||
.unwrap_or(false)
|
||||
}
|
||||
}
|
||||
|
||||
impl ast::UseTree {
|
||||
pub fn is_simple_path(&self) -> bool {
|
||||
self.use_tree_list().is_none() && self.star_token().is_none()
|
||||
|
@ -18,6 +18,11 @@ The path structure for newly inserted paths to use.
|
||||
--
|
||||
Group inserted imports by the [following order](https://rust-analyzer.github.io/manual.html#auto-import). Groups are separated by newlines.
|
||||
--
|
||||
[[rust-analyzer.assist.allowMergingIntoGlobImports]]rust-analyzer.assist.allowMergingIntoGlobImports (default: `true`)::
|
||||
+
|
||||
--
|
||||
Whether to allow import insertion to merge new imports into single path glob imports like `use std::fmt::*;`.
|
||||
--
|
||||
[[rust-analyzer.callInfo.full]]rust-analyzer.callInfo.full (default: `true`)::
|
||||
+
|
||||
--
|
||||
|
@ -432,6 +432,11 @@
|
||||
"default": true,
|
||||
"type": "boolean"
|
||||
},
|
||||
"rust-analyzer.assist.allowMergingIntoGlobImports": {
|
||||
"markdownDescription": "Whether to allow import insertion to merge new imports into single path glob imports like `use std::fmt::*;`.",
|
||||
"default": true,
|
||||
"type": "boolean"
|
||||
},
|
||||
"rust-analyzer.callInfo.full": {
|
||||
"markdownDescription": "Show function name and docs in parameter hints.",
|
||||
"default": true,
|
||||
|
Loading…
Reference in New Issue
Block a user