2 use itertools::Itertools;
4 ast::{self, VisibilityOwner},
10 assist_context::{AssistContext, Assists},
14 // Assist: unmerge_use
16 // Extracts single use item from use list.
19 // use std::fmt::{Debug, Display$0};
23 // use std::fmt::{Debug};
24 // use std::fmt::Display;
26 pub(crate) fn unmerge_use(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
27 let tree: ast::UseTree = ctx.find_node_at_offset::<ast::UseTree>()?.clone_for_update();
29 let tree_list = tree.syntax().parent().and_then(ast::UseTreeList::cast)?;
30 if tree_list.use_trees().count() < 2 {
31 cov_mark::hit!(skip_single_use_item);
35 let use_: ast::Use = tree_list.syntax().ancestors().find_map(ast::Use::cast)?;
36 let path = resolve_full_path(&tree)?;
38 let old_parent_range = use_.syntax().parent()?.text_range();
39 let new_parent = use_.syntax().parent()?;
41 let target = tree.syntax().text_range();
43 AssistId("unmerge_use", AssistKind::RefactorRewrite),
47 let new_use = make::use_(
53 tree.star_token().is_some(),
59 ted::insert(Position::after(use_.syntax()), new_use.syntax());
61 builder.replace(old_parent_range, new_parent.to_string());
66 fn resolve_full_path(tree: &ast::UseTree) -> Option<ast::Path> {
70 .take_while(|n| n.kind() != SyntaxKind::USE)
71 .filter_map(ast::UseTree::cast)
72 .filter_map(|t| t.path());
74 let final_path = paths.fold1(|prev, next| make::path_concat(next, prev))?;
75 if final_path.segment().map_or(false, |it| it.self_token().is_some()) {
76 final_path.qualifier()
84 use crate::tests::{check_assist, check_assist_not_applicable};
89 fn skip_single_use_item() {
90 cov_mark::check!(skip_single_use_item);
91 check_assist_not_applicable(
94 use std::fmt::Debug$0;
97 check_assist_not_applicable(
100 use std::fmt::{Debug$0};
103 check_assist_not_applicable(
106 use std::fmt::Debug as Dbg$0;
112 fn skip_single_glob_import() {
113 check_assist_not_applicable(
122 fn unmerge_use_item() {
126 use std::fmt::{Debug, Display$0};
129 use std::fmt::{Debug};
130 use std::fmt::Display;
137 use std::fmt::{Debug, format$0, Display};
140 use std::fmt::{Debug, Display};
141 use std::fmt::format;
147 fn unmerge_glob_import() {
151 use std::fmt::{*$0, Display};
154 use std::fmt::{Display};
161 fn unmerge_renamed_use_item() {
165 use std::fmt::{Debug, Display as Disp$0};
168 use std::fmt::{Debug};
169 use std::fmt::Display as Disp;
175 fn unmerge_indented_use_item() {
180 use std::fmt::{Debug, Display$0 as Disp, format};
185 use std::fmt::{Debug, format};
186 use std::fmt::Display as Disp;
193 fn unmerge_nested_use_item() {
197 use foo::bar::{baz::{qux$0, foobar}, barbaz};
200 use foo::bar::{baz::{foobar}, barbaz};
201 use foo::bar::baz::qux;
207 use foo::bar::{baz$0::{qux, foobar}, barbaz};
210 use foo::bar::{barbaz};
211 use foo::bar::baz::{qux, foobar};
217 fn unmerge_use_item_with_visibility() {
221 pub use std::fmt::{Debug, Display$0};
224 pub use std::fmt::{Debug};
225 pub use std::fmt::Display;
231 fn unmerge_use_item_on_self() {
234 r"use std::process::{Command, self$0};",
235 r"use std::process::{Command};