From 31aad2528f53349e9a0601c756d3c9f86ca9154c Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Tue, 8 Jun 2021 22:14:30 +0200 Subject: [PATCH] Fix edge case for ImportGranularity guessing --- crates/ide_db/src/helpers/insert_use.rs | 18 +++++++++++------- crates/ide_db/src/helpers/insert_use/tests.rs | 15 +++++++++++++++ crates/syntax/src/ast/node_ext.rs | 5 ++++- 3 files changed, 30 insertions(+), 8 deletions(-) diff --git a/crates/ide_db/src/helpers/insert_use.rs b/crates/ide_db/src/helpers/insert_use.rs index aa61c5bcb46..10bbafe7765 100644 --- a/crates/ide_db/src/helpers/insert_use.rs +++ b/crates/ide_db/src/helpers/insert_use.rs @@ -120,15 +120,19 @@ fn guess_granularity_from_scope(&self) -> ImportGranularityGuess { if eq_visibility(prev_vis, curr_vis.clone()) && eq_attrs(prev_attrs, curr_attrs.clone()) { if let Some((prev_path, curr_path)) = prev.path().zip(curr.path()) { - if let Some(_) = common_prefix(&prev_path, &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() { - // Same prefix but no use tree lists so this has to be of item style. - break ImportGranularityGuess::Item; // this overwrites CrateOrModule, technically the file doesn't adhere to anything here. - } 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; + 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 but no use tree lists so this has to be of item style. + break ImportGranularityGuess::Item; // this overwrites CrateOrModule, technically the file doesn't adhere to anything here. + } } + // 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; } } } diff --git a/crates/ide_db/src/helpers/insert_use/tests.rs b/crates/ide_db/src/helpers/insert_use/tests.rs index 78a2a87b385..70b11bf81f2 100644 --- a/crates/ide_db/src/helpers/insert_use/tests.rs +++ b/crates/ide_db/src/helpers/insert_use/tests.rs @@ -660,6 +660,13 @@ fn guess_item() { r" use foo::bar::baz; use foo::bar::qux; +", + ImportGranularityGuess::Item, + ); + check_guess( + r" +use foo::bar::Bar; +use foo::baz; ", ImportGranularityGuess::Item, ); @@ -679,6 +686,14 @@ fn guess_module() { r" use foo::bar::baz; use foo::{baz::{qux, quux}, bar}; +", + ImportGranularityGuess::Module, + ); + check_guess( + r" +use foo::bar::Bar; +use foo::baz::Baz; +use foo::{Foo, Qux}; ", ImportGranularityGuess::Module, ); diff --git a/crates/syntax/src/ast/node_ext.rs b/crates/syntax/src/ast/node_ext.rs index 884fe0739db..a60bc5ad95d 100644 --- a/crates/syntax/src/ast/node_ext.rs +++ b/crates/syntax/src/ast/node_ext.rs @@ -259,11 +259,14 @@ pub fn first_segment(&self) -> Option { } pub fn segments(&self) -> impl Iterator + Clone { - // cant make use of SyntaxNode::siblings, because the returned Iterator is not clone successors(self.first_segment(), |p| { p.parent_path().parent_path().and_then(|p| p.segment()) }) } + + pub fn qualifiers(&self) -> impl Iterator + Clone { + successors(self.qualifier(), |p| p.qualifier()) + } } impl ast::UseTree { pub fn is_simple_path(&self) -> bool {