Unnamed repository; edit this file 'description' to name the repository.
Auto merge of #16066 - Young-Flash:auto_remove_brace, r=lnicola
fix: auto remove unnecessary braces after remove unused imports before ![before](https://github.com/rust-lang/rust-analyzer/assets/71162630/8d44f955-f84f-4a92-b13f-5a2dee2ded36) after ![after](https://github.com/rust-lang/rust-analyzer/assets/71162630/1eab23c8-39bd-4711-97c1-d483ce400a18)
bors 2023-12-20
parent 7bdf48c · parent 4cd939a · commit 65ed198
-rw-r--r--crates/ide-assists/src/handlers/remove_unused_imports.rs79
-rw-r--r--crates/syntax/src/ast/edit_in_place.rs1
-rw-r--r--crates/syntax/src/ast/node_ext.rs27
3 files changed, 103 insertions, 4 deletions
diff --git a/crates/ide-assists/src/handlers/remove_unused_imports.rs b/crates/ide-assists/src/handlers/remove_unused_imports.rs
index ee44064e7c..482c36d502 100644
--- a/crates/ide-assists/src/handlers/remove_unused_imports.rs
+++ b/crates/ide-assists/src/handlers/remove_unused_imports.rs
@@ -423,7 +423,7 @@ mod z {
struct X();
struct Y();
mod z {
- use super::{X};
+ use super::X;
fn w() {
let x = X();
@@ -495,7 +495,7 @@ struct X();
mod y {
struct Y();
mod z {
- use crate::{X};
+ use crate::X;
fn f() {
let x = X();
}
@@ -526,7 +526,7 @@ struct X();
mod y {
struct Y();
mod z {
- use crate::{y::Y};
+ use crate::y::Y;
fn f() {
let y = Y();
}
@@ -537,6 +537,79 @@ mod y {
}
#[test]
+ fn remove_unused_auto_remove_brace_nested() {
+ check_assist(
+ remove_unused_imports,
+ r#"
+mod a {
+ pub struct A();
+}
+mod b {
+ struct F();
+ mod c {
+ $0use {{super::{{
+ {d::{{{{{{{S, U}}}}}}}},
+ {{{{e::{H, L, {{{R}}}}}}}},
+ F, super::a::A
+ }}}};$0
+ fn f() {
+ let f = F();
+ let l = L();
+ let a = A();
+ let s = S();
+ let h = H();
+ }
+ }
+
+ mod d {
+ pub struct S();
+ pub struct U();
+ }
+
+ mod e {
+ pub struct H();
+ pub struct L();
+ pub struct R();
+ }
+}
+"#,
+ r#"
+mod a {
+ pub struct A();
+}
+mod b {
+ struct F();
+ mod c {
+ use super::{
+ d::S,
+ e::{H, L},
+ F, super::a::A
+ };
+ fn f() {
+ let f = F();
+ let l = L();
+ let a = A();
+ let s = S();
+ let h = H();
+ }
+ }
+
+ mod d {
+ pub struct S();
+ pub struct U();
+ }
+
+ mod e {
+ pub struct H();
+ pub struct L();
+ pub struct R();
+ }
+}
+"#,
+ );
+ }
+
+ #[test]
fn remove_nested_all_unused() {
check_assist(
remove_unused_imports,
diff --git a/crates/syntax/src/ast/edit_in_place.rs b/crates/syntax/src/ast/edit_in_place.rs
index 37d8212042..916bbbad40 100644
--- a/crates/syntax/src/ast/edit_in_place.rs
+++ b/crates/syntax/src/ast/edit_in_place.rs
@@ -414,6 +414,7 @@ impl ast::UseTree {
u.remove_recursive();
}
}
+ u.remove_unnecessary_braces();
}
}
diff --git a/crates/syntax/src/ast/node_ext.rs b/crates/syntax/src/ast/node_ext.rs
index f81dff8840..cfd919ad6f 100644
--- a/crates/syntax/src/ast/node_ext.rs
+++ b/crates/syntax/src/ast/node_ext.rs
@@ -11,7 +11,7 @@ use rowan::{GreenNodeData, GreenTokenData};
use crate::{
ast::{self, support, AstNode, AstToken, HasAttrs, HasGenericParams, HasName, SyntaxNode},
- NodeOrToken, SmolStr, SyntaxElement, SyntaxToken, TokenText, T,
+ ted, NodeOrToken, SmolStr, SyntaxElement, SyntaxToken, TokenText, T,
};
impl ast::Lifetime {
@@ -323,6 +323,10 @@ impl ast::UseTree {
pub fn is_simple_path(&self) -> bool {
self.use_tree_list().is_none() && self.star_token().is_none()
}
+
+ pub fn parent_use_tree_list(&self) -> Option<ast::UseTreeList> {
+ self.syntax().parent().and_then(ast::UseTreeList::cast)
+ }
}
impl ast::UseTreeList {
@@ -340,6 +344,27 @@ impl ast::UseTreeList {
.find_map(ast::Comment::cast)
.is_some()
}
+
+ /// Remove the unnecessary braces in current `UseTreeList`
+ pub fn remove_unnecessary_braces(mut self) {
+ let remove_brace_in_use_tree_list = |u: &ast::UseTreeList| {
+ let use_tree_count = u.use_trees().count();
+ if use_tree_count == 1 {
+ u.l_curly_token().map(ted::remove);
+ u.r_curly_token().map(ted::remove);
+ }
+ };
+
+ // take `use crate::{{{{A}}}}` for example
+ // the below remove the innermost {}, got `use crate::{{{A}}}`
+ remove_brace_in_use_tree_list(&self);
+
+ // the below remove othe unnecessary {}, got `use crate::A`
+ while let Some(parent_use_tree_list) = self.parent_use_tree().parent_use_tree_list() {
+ remove_brace_in_use_tree_list(&parent_use_tree_list);
+ self = parent_use_tree_list;
+ }
+ }
}
impl ast::Impl {