Auto merge of #16372 - davidsemakula:import-granularity-one, r=Veykril

feat: Add "One" import granularity

Adds a new import granularity option "One" that merges all imports into a single use statement as long as they have the same visibility and attributes.

This is similar to [rustfmt's `imports_granularity = "One"`](https://rust-lang.github.io/rustfmt/?version=v1.6.0&search=import#imports_granularity).

Fixes: #11361
This commit is contained in:
bors 2024-01-18 15:40:12 +00:00
commit 3f4c6dac3d
10 changed files with 473 additions and 85 deletions

View file

@ -1,6 +1,6 @@
//! Structural editing for ast.
use std::iter::{empty, successors};
use std::iter::{empty, once, successors};
use parser::{SyntaxKind, T};
@ -530,6 +530,25 @@ impl ast::UseTree {
Some(())
}
}
/// Wraps the use tree in use tree list with no top level path (if it isn't already).
///
/// # Examples
///
/// `foo::bar` -> `{foo::bar}`
///
/// `{foo::bar}` -> `{foo::bar}`
pub fn wrap_in_tree_list(&self) {
if self.path().is_none() {
return;
}
let subtree = self.clone_subtree().clone_for_update();
ted::remove_all_iter(self.syntax().children_with_tokens());
ted::append_child(
self.syntax(),
make::use_tree_list(once(subtree)).clone_for_update().syntax(),
);
}
}
impl ast::UseTreeList {

View file

@ -327,6 +327,14 @@ impl ast::UseTree {
pub fn parent_use_tree_list(&self) -> Option<ast::UseTreeList> {
self.syntax().parent().and_then(ast::UseTreeList::cast)
}
pub fn top_use_tree(&self) -> ast::UseTree {
let mut this = self.clone();
while let Some(use_tree_list) = this.parent_use_tree_list() {
this = use_tree_list.parent_use_tree();
}
this
}
}
impl ast::UseTreeList {