Check for differing attributes in granularity guessing

This commit is contained in:
Lukas Tobias Wirth 2021-05-20 10:25:04 +02:00
parent b4fe479236
commit 2bf720900f
3 changed files with 21 additions and 7 deletions

View File

@ -4,13 +4,13 @@ use std::cmp::Ordering;
use hir::Semantics; use hir::Semantics;
use syntax::{ use syntax::{
algo, algo,
ast::{self, make, AstNode, ModuleItemOwner, PathSegmentKind, VisibilityOwner}, ast::{self, make, AstNode, AttrsOwner, ModuleItemOwner, PathSegmentKind, VisibilityOwner},
ted, AstToken, Direction, NodeOrToken, SyntaxNode, SyntaxToken, ted, AstToken, Direction, NodeOrToken, SyntaxNode, SyntaxToken,
}; };
use crate::{ use crate::{
helpers::merge_imports::{ helpers::merge_imports::{
common_prefix, eq_visibility, try_merge_imports, use_tree_path_cmp, MergeBehavior, common_prefix, eq_attrs, eq_visibility, try_merge_imports, use_tree_path_cmp, MergeBehavior,
}, },
RootDatabase, RootDatabase,
}; };
@ -88,7 +88,7 @@ impl ImportScope {
let use_stmt = |item| match item { let use_stmt = |item| match item {
ast::Item::Use(use_) => { ast::Item::Use(use_) => {
let use_tree = use_.use_tree()?; let use_tree = use_.use_tree()?;
Some((use_tree, use_.visibility())) Some((use_tree, use_.visibility(), use_.attrs()))
} }
_ => None, _ => None,
}; };
@ -98,7 +98,7 @@ impl ImportScope {
} }
.filter_map(use_stmt); .filter_map(use_stmt);
let mut res = ImportGranularityGuess::Unknown; let mut res = ImportGranularityGuess::Unknown;
let (mut prev, mut prev_vis) = match use_stmts.next() { let (mut prev, mut prev_vis, mut prev_attrs) = match use_stmts.next() {
Some(it) => it, Some(it) => it,
None => return res, None => return res,
}; };
@ -113,11 +113,12 @@ impl ImportScope {
} }
} }
let (curr, curr_vis) = match use_stmts.next() { let (curr, curr_vis, curr_attrs) = match use_stmts.next() {
Some(it) => it, Some(it) => it,
None => break res, None => break res,
}; };
if eq_visibility(prev_vis, curr_vis.clone()) { 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((prev_path, curr_path)) = prev.path().zip(curr.path()) {
if let Some(_) = common_prefix(&prev_path, &curr_path) { if let Some(_) = common_prefix(&prev_path, &curr_path) {
if prev.use_tree_list().is_none() && curr.use_tree_list().is_none() { if prev.use_tree_list().is_none() && curr.use_tree_list().is_none() {
@ -133,6 +134,7 @@ impl ImportScope {
} }
prev = curr; prev = curr;
prev_vis = curr_vis; prev_vis = curr_vis;
prev_attrs = curr_attrs;
} }
} }
} }

View File

@ -717,6 +717,18 @@ pub use foo::bar::qux;
); );
} }
#[test]
fn guess_skips_differing_attrs() {
check_guess(
r"
pub use foo::bar::baz;
#[doc(hidden)]
pub use foo::bar::qux;
",
ImportGranularityGuess::Unknown,
);
}
#[test] #[test]
fn guess_grouping_matters() { fn guess_grouping_matters() {
check_guess( check_guess(

View File

@ -299,7 +299,7 @@ pub fn eq_visibility(vis0: Option<ast::Visibility>, vis1: Option<ast::Visibility
} }
} }
fn eq_attrs( pub fn eq_attrs(
attrs0: impl Iterator<Item = ast::Attr>, attrs0: impl Iterator<Item = ast::Attr>,
attrs1: impl Iterator<Item = ast::Attr>, attrs1: impl Iterator<Item = ast::Attr>,
) -> bool { ) -> bool {