diff options
Diffstat (limited to 'crates/ide_assists/src/handlers/replace_qualified_name_with_use.rs')
-rw-r--r-- | crates/ide_assists/src/handlers/replace_qualified_name_with_use.rs | 34 |
1 files changed, 13 insertions, 21 deletions
diff --git a/crates/ide_assists/src/handlers/replace_qualified_name_with_use.rs b/crates/ide_assists/src/handlers/replace_qualified_name_with_use.rs index 36d2e0331..99ba79860 100644 --- a/crates/ide_assists/src/handlers/replace_qualified_name_with_use.rs +++ b/crates/ide_assists/src/handlers/replace_qualified_name_with_use.rs | |||
@@ -1,5 +1,5 @@ | |||
1 | use ide_db::helpers::insert_use::{insert_use, ImportScope}; | 1 | use ide_db::helpers::insert_use::{insert_use, ImportScope}; |
2 | use syntax::{algo::SyntaxRewriter, ast, match_ast, AstNode, SyntaxNode}; | 2 | use syntax::{ast, match_ast, ted, AstNode, SyntaxNode}; |
3 | 3 | ||
4 | use crate::{AssistContext, AssistId, AssistKind, Assists}; | 4 | use crate::{AssistContext, AssistId, AssistKind, Assists}; |
5 | 5 | ||
@@ -31,7 +31,7 @@ pub(crate) fn replace_qualified_name_with_use( | |||
31 | } | 31 | } |
32 | 32 | ||
33 | let target = path.syntax().text_range(); | 33 | let target = path.syntax().text_range(); |
34 | let scope = ImportScope::find_insert_use_container(path.syntax(), &ctx.sema)?; | 34 | let scope = ImportScope::find_insert_use_container_with_macros(path.syntax(), &ctx.sema)?; |
35 | let syntax = scope.as_syntax_node(); | 35 | let syntax = scope.as_syntax_node(); |
36 | acc.add( | 36 | acc.add( |
37 | AssistId("replace_qualified_name_with_use", AssistKind::RefactorRewrite), | 37 | AssistId("replace_qualified_name_with_use", AssistKind::RefactorRewrite), |
@@ -40,18 +40,17 @@ pub(crate) fn replace_qualified_name_with_use( | |||
40 | |builder| { | 40 | |builder| { |
41 | // Now that we've brought the name into scope, re-qualify all paths that could be | 41 | // Now that we've brought the name into scope, re-qualify all paths that could be |
42 | // affected (that is, all paths inside the node we added the `use` to). | 42 | // affected (that is, all paths inside the node we added the `use` to). |
43 | let mut rewriter = SyntaxRewriter::default(); | 43 | let syntax = builder.make_mut(syntax.clone()); |
44 | shorten_paths(&mut rewriter, syntax.clone(), &path); | ||
45 | if let Some(ref import_scope) = ImportScope::from(syntax.clone()) { | 44 | if let Some(ref import_scope) = ImportScope::from(syntax.clone()) { |
46 | rewriter += insert_use(import_scope, path, ctx.config.insert_use); | 45 | shorten_paths(&syntax, &path.clone_for_update()); |
47 | builder.rewrite(rewriter); | 46 | insert_use(import_scope, path, ctx.config.insert_use); |
48 | } | 47 | } |
49 | }, | 48 | }, |
50 | ) | 49 | ) |
51 | } | 50 | } |
52 | 51 | ||
53 | /// Adds replacements to `re` that shorten `path` in all descendants of `node`. | 52 | /// Adds replacements to `re` that shorten `path` in all descendants of `node`. |
54 | fn shorten_paths(rewriter: &mut SyntaxRewriter<'static>, node: SyntaxNode, path: &ast::Path) { | 53 | fn shorten_paths(node: &SyntaxNode, path: &ast::Path) { |
55 | for child in node.children() { | 54 | for child in node.children() { |
56 | match_ast! { | 55 | match_ast! { |
57 | match child { | 56 | match child { |
@@ -60,34 +59,26 @@ fn shorten_paths(rewriter: &mut SyntaxRewriter<'static>, node: SyntaxNode, path: | |||
60 | ast::Use(_it) => continue, | 59 | ast::Use(_it) => continue, |
61 | // Don't descend into submodules, they don't have the same `use` items in scope. | 60 | // Don't descend into submodules, they don't have the same `use` items in scope. |
62 | ast::Module(_it) => continue, | 61 | ast::Module(_it) => continue, |
63 | 62 | ast::Path(p) => if maybe_replace_path(p.clone(), path.clone()).is_none() { | |
64 | ast::Path(p) => { | 63 | shorten_paths(p.syntax(), path); |
65 | match maybe_replace_path(rewriter, p.clone(), path.clone()) { | ||
66 | Some(()) => {}, | ||
67 | None => shorten_paths(rewriter, p.syntax().clone(), path), | ||
68 | } | ||
69 | }, | 64 | }, |
70 | _ => shorten_paths(rewriter, child, path), | 65 | _ => shorten_paths(&child, path), |
71 | } | 66 | } |
72 | } | 67 | } |
73 | } | 68 | } |
74 | } | 69 | } |
75 | 70 | ||
76 | fn maybe_replace_path( | 71 | fn maybe_replace_path(path: ast::Path, target: ast::Path) -> Option<()> { |
77 | rewriter: &mut SyntaxRewriter<'static>, | ||
78 | path: ast::Path, | ||
79 | target: ast::Path, | ||
80 | ) -> Option<()> { | ||
81 | if !path_eq(path.clone(), target) { | 72 | if !path_eq(path.clone(), target) { |
82 | return None; | 73 | return None; |
83 | } | 74 | } |
84 | 75 | ||
85 | // Shorten `path`, leaving only its last segment. | 76 | // Shorten `path`, leaving only its last segment. |
86 | if let Some(parent) = path.qualifier() { | 77 | if let Some(parent) = path.qualifier() { |
87 | rewriter.delete(parent.syntax()); | 78 | ted::remove(parent.syntax()); |
88 | } | 79 | } |
89 | if let Some(double_colon) = path.coloncolon_token() { | 80 | if let Some(double_colon) = path.coloncolon_token() { |
90 | rewriter.delete(&double_colon); | 81 | ted::remove(&double_colon); |
91 | } | 82 | } |
92 | 83 | ||
93 | Some(()) | 84 | Some(()) |
@@ -150,6 +141,7 @@ Debug | |||
150 | ", | 141 | ", |
151 | ); | 142 | ); |
152 | } | 143 | } |
144 | |||
153 | #[test] | 145 | #[test] |
154 | fn test_replace_add_use_no_anchor_with_item_below() { | 146 | fn test_replace_add_use_no_anchor_with_item_below() { |
155 | check_assist( | 147 | check_assist( |