Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/ide-db/src/imports/insert_use.rs')
-rw-r--r--crates/ide-db/src/imports/insert_use.rs65
1 files changed, 34 insertions, 31 deletions
diff --git a/crates/ide-db/src/imports/insert_use.rs b/crates/ide-db/src/imports/insert_use.rs
index 813f38380f..4444ef5d81 100644
--- a/crates/ide-db/src/imports/insert_use.rs
+++ b/crates/ide-db/src/imports/insert_use.rs
@@ -27,9 +27,6 @@ pub use hir::PrefixKind;
/// How imports should be grouped into use statements.
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum ImportGranularity {
- /// Do not change the granularity of any imports and preserve the original structure written
- /// by the developer.
- Preserve,
/// Merge imports from the same crate into a single use statement.
Crate,
/// Merge imports from the same module into a single use statement.
@@ -97,12 +94,11 @@ impl ImportScope {
.map(ImportScopeKind::Module)
.map(|kind| ImportScope { kind, required_cfgs });
} else if let Some(has_attrs) = ast::AnyHasAttrs::cast(syntax) {
- if block.is_none() {
- if let Some(b) = ast::BlockExpr::cast(has_attrs.syntax().clone()) {
- if let Some(b) = sema.original_ast_node(b) {
- block = b.stmt_list();
- }
- }
+ if block.is_none()
+ && let Some(b) = ast::BlockExpr::cast(has_attrs.syntax().clone())
+ && let Some(b) = sema.original_ast_node(b)
+ {
+ block = b.stmt_list();
}
if has_attrs
.attrs()
@@ -175,7 +171,7 @@ fn insert_use_with_alias_option(
ImportGranularity::Crate => Some(MergeBehavior::Crate),
ImportGranularity::Module => Some(MergeBehavior::Module),
ImportGranularity::One => Some(MergeBehavior::One),
- ImportGranularity::Item | ImportGranularity::Preserve => None,
+ ImportGranularity::Item => None,
};
if !cfg.enforce_granularity {
let file_granularity = guess_granularity_from_scope(scope);
@@ -183,9 +179,18 @@ fn insert_use_with_alias_option(
ImportGranularityGuess::Unknown => mb,
ImportGranularityGuess::Item => None,
ImportGranularityGuess::Module => Some(MergeBehavior::Module),
- ImportGranularityGuess::ModuleOrItem => mb.and(Some(MergeBehavior::Module)),
+ // We use the user's setting to infer if this is module or item.
+ ImportGranularityGuess::ModuleOrItem => match mb {
+ Some(MergeBehavior::Module) | None => mb,
+ // There isn't really a way to decide between module or item here, so we just pick one.
+ // FIXME: Maybe it is possible to infer based on semantic analysis?
+ Some(MergeBehavior::One | MergeBehavior::Crate) => Some(MergeBehavior::Module),
+ },
ImportGranularityGuess::Crate => Some(MergeBehavior::Crate),
- ImportGranularityGuess::CrateOrModule => mb.or(Some(MergeBehavior::Crate)),
+ ImportGranularityGuess::CrateOrModule => match mb {
+ Some(MergeBehavior::Crate | MergeBehavior::Module) => mb,
+ Some(MergeBehavior::One) | None => Some(MergeBehavior::Crate),
+ },
ImportGranularityGuess::One => Some(MergeBehavior::One),
};
}
@@ -195,7 +200,7 @@ fn insert_use_with_alias_option(
use_tree = use_tree.clone_for_update();
use_tree.wrap_in_tree_list();
}
- let use_item = make::use_(None, use_tree).clone_for_update();
+ let use_item = make::use_(None, None, use_tree).clone_for_update();
for attr in
scope.required_cfgs.iter().map(|attr| attr.syntax().clone_subtree().clone_for_update())
{
@@ -349,26 +354,24 @@ fn guess_granularity_from_scope(scope: &ImportScope) -> ImportGranularityGuess {
seen_one_style_groups.push((curr_vis.clone(), curr_attrs.clone()));
} else if eq_visibility(prev_vis, curr_vis.clone())
&& eq_attrs(prev_attrs, curr_attrs.clone())
+ && let Some((prev_path, curr_path)) = prev.path().zip(curr.path())
+ && let Some((prev_prefix, _)) = common_prefix(&prev_path, &curr_path)
{
- if let Some((prev_path, curr_path)) = prev.path().zip(curr.path()) {
- if let Some((prev_prefix, _)) = common_prefix(&prev_path, &curr_path) {
- if prev.use_tree_list().is_none() && curr.use_tree_list().is_none() {
- let prefix_c = prev_prefix.qualifiers().count();
- let curr_c = curr_path.qualifiers().count() - prefix_c;
- let prev_c = prev_path.qualifiers().count() - prefix_c;
- if curr_c == 1 && prev_c == 1 {
- // Same prefix, only differing in the last segment and no use tree lists so this has to be of item style.
- break ImportGranularityGuess::Item;
- } else {
- // Same prefix and no use tree list but differs in more than one segment at the end. This might be module style still.
- res = ImportGranularityGuess::ModuleOrItem;
- }
- } else {
- // Same prefix with item tree lists, has to be module style as it
- // can't be crate style since the trees wouldn't share a prefix then.
- break ImportGranularityGuess::Module;
- }
+ if prev.use_tree_list().is_none() && curr.use_tree_list().is_none() {
+ let prefix_c = prev_prefix.qualifiers().count();
+ let curr_c = curr_path.qualifiers().count() - prefix_c;
+ let prev_c = prev_path.qualifiers().count() - prefix_c;
+ if curr_c == 1 && prev_c == 1 {
+ // Same prefix, only differing in the last segment and no use tree lists so this has to be of item style.
+ break ImportGranularityGuess::Item;
+ } else {
+ // Same prefix and no use tree list but differs in more than one segment at the end. This might be module style still.
+ res = ImportGranularityGuess::ModuleOrItem;
}
+ } else {
+ // Same prefix with item tree lists, has to be module style as it
+ // can't be crate style since the trees wouldn't share a prefix then.
+ break ImportGranularityGuess::Module;
}
}
prev = curr;