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.rs | 65 |
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; |