diff options
author | Aleksey Kladov <[email protected]> | 2021-03-18 09:57:55 +0000 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2021-03-22 17:47:46 +0000 |
commit | 9cbf09ec4f24aa30af1d9855a909a6cfc67188f7 (patch) | |
tree | 20057e98e523440ebc3120e1e3c104b306a97baf /crates/ide_assists/src/handlers/merge_imports.rs | |
parent | d834306e7cf85fe0b07e4979d2ff39bf4ef1f6be (diff) |
rewrite merge use trees assist to use muatable syntax trees
changelog internal
Diffstat (limited to 'crates/ide_assists/src/handlers/merge_imports.rs')
-rw-r--r-- | crates/ide_assists/src/handlers/merge_imports.rs | 49 |
1 files changed, 29 insertions, 20 deletions
diff --git a/crates/ide_assists/src/handlers/merge_imports.rs b/crates/ide_assists/src/handlers/merge_imports.rs index 7bd7e1e36..cfc472a32 100644 --- a/crates/ide_assists/src/handlers/merge_imports.rs +++ b/crates/ide_assists/src/handlers/merge_imports.rs | |||
@@ -1,8 +1,5 @@ | |||
1 | use ide_db::helpers::insert_use::{try_merge_imports, try_merge_trees, MergeBehavior}; | 1 | use ide_db::helpers::insert_use::{try_merge_imports, try_merge_trees, MergeBehavior}; |
2 | use syntax::{ | 2 | use syntax::{algo::neighbor, ast, ted, AstNode}; |
3 | algo::{neighbor, SyntaxRewriter}, | ||
4 | ast, AstNode, | ||
5 | }; | ||
6 | 3 | ||
7 | use crate::{ | 4 | use crate::{ |
8 | assist_context::{AssistContext, Assists}, | 5 | assist_context::{AssistContext, Assists}, |
@@ -24,33 +21,29 @@ use crate::{ | |||
24 | // ``` | 21 | // ``` |
25 | pub(crate) fn merge_imports(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { | 22 | pub(crate) fn merge_imports(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { |
26 | let tree: ast::UseTree = ctx.find_node_at_offset()?; | 23 | let tree: ast::UseTree = ctx.find_node_at_offset()?; |
27 | let mut rewriter = SyntaxRewriter::default(); | 24 | let original_parent = tree.syntax().ancestors().last()?; |
25 | |||
26 | let tree = tree.clone_for_update(); | ||
27 | let new_parent = tree.syntax().ancestors().last()?; | ||
28 | |||
28 | let mut offset = ctx.offset(); | 29 | let mut offset = ctx.offset(); |
29 | 30 | ||
31 | let mut imports = None; | ||
32 | let mut uses = None; | ||
30 | if let Some(use_item) = tree.syntax().parent().and_then(ast::Use::cast) { | 33 | if let Some(use_item) = tree.syntax().parent().and_then(ast::Use::cast) { |
31 | let (merged, to_delete) = | 34 | let (merged, to_remove) = |
32 | next_prev().filter_map(|dir| neighbor(&use_item, dir)).find_map(|use_item2| { | 35 | next_prev().filter_map(|dir| neighbor(&use_item, dir)).find_map(|use_item2| { |
33 | try_merge_imports(&use_item, &use_item2, MergeBehavior::Full).zip(Some(use_item2)) | 36 | try_merge_imports(&use_item, &use_item2, MergeBehavior::Full).zip(Some(use_item2)) |
34 | })?; | 37 | })?; |
35 | 38 | ||
36 | rewriter.replace_ast(&use_item, &merged); | 39 | imports = Some((use_item, merged, to_remove)); |
37 | rewriter += to_delete.remove(); | ||
38 | |||
39 | if to_delete.syntax().text_range().end() < offset { | ||
40 | offset -= to_delete.syntax().text_range().len(); | ||
41 | } | ||
42 | } else { | 40 | } else { |
43 | let (merged, to_delete) = | 41 | let (merged, to_remove) = |
44 | next_prev().filter_map(|dir| neighbor(&tree, dir)).find_map(|use_tree| { | 42 | next_prev().filter_map(|dir| neighbor(&tree, dir)).find_map(|use_tree| { |
45 | try_merge_trees(&tree, &use_tree, MergeBehavior::Full).zip(Some(use_tree)) | 43 | try_merge_trees(&tree, &use_tree, MergeBehavior::Full).zip(Some(use_tree)) |
46 | })?; | 44 | })?; |
47 | 45 | ||
48 | rewriter.replace_ast(&tree, &merged); | 46 | uses = Some((tree.clone(), merged, to_remove)) |
49 | rewriter += to_delete.remove(); | ||
50 | |||
51 | if to_delete.syntax().text_range().end() < offset { | ||
52 | offset -= to_delete.syntax().text_range().len(); | ||
53 | } | ||
54 | }; | 47 | }; |
55 | 48 | ||
56 | let target = tree.syntax().text_range(); | 49 | let target = tree.syntax().text_range(); |
@@ -59,7 +52,23 @@ pub(crate) fn merge_imports(acc: &mut Assists, ctx: &AssistContext) -> Option<() | |||
59 | "Merge imports", | 52 | "Merge imports", |
60 | target, | 53 | target, |
61 | |builder| { | 54 | |builder| { |
62 | builder.rewrite(rewriter); | 55 | if let Some((to_replace, replacement, to_remove)) = imports { |
56 | if to_remove.syntax().text_range().end() < offset { | ||
57 | offset -= to_remove.syntax().text_range().len(); | ||
58 | } | ||
59 | ted::replace(to_replace.syntax().clone(), replacement.syntax().clone()); | ||
60 | to_remove.remove(); | ||
61 | } | ||
62 | |||
63 | if let Some((to_replace, replacement, to_remove)) = uses { | ||
64 | if to_remove.syntax().text_range().end() < offset { | ||
65 | offset -= to_remove.syntax().text_range().len(); | ||
66 | } | ||
67 | ted::replace(to_replace.syntax().clone(), replacement.syntax().clone()); | ||
68 | to_remove.remove() | ||
69 | } | ||
70 | |||
71 | builder.replace(original_parent.text_range(), new_parent.to_string()) | ||
63 | }, | 72 | }, |
64 | ) | 73 | ) |
65 | } | 74 | } |