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 | |
parent | d834306e7cf85fe0b07e4979d2ff39bf4ef1f6be (diff) |
rewrite merge use trees assist to use muatable syntax trees
changelog internal
Diffstat (limited to 'crates/ide_assists/src/handlers')
-rw-r--r-- | crates/ide_assists/src/handlers/merge_imports.rs | 49 | ||||
-rw-r--r-- | crates/ide_assists/src/handlers/unmerge_use.rs | 30 |
2 files changed, 42 insertions, 37 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 | } |
diff --git a/crates/ide_assists/src/handlers/unmerge_use.rs b/crates/ide_assists/src/handlers/unmerge_use.rs index 616af7c2e..8d271e056 100644 --- a/crates/ide_assists/src/handlers/unmerge_use.rs +++ b/crates/ide_assists/src/handlers/unmerge_use.rs | |||
@@ -1,6 +1,6 @@ | |||
1 | use syntax::{ | 1 | use syntax::{ |
2 | algo::SyntaxRewriter, | 2 | ast::{self, VisibilityOwner}, |
3 | ast::{self, edit::AstNodeEdit, VisibilityOwner}, | 3 | ted::{self, Position}, |
4 | AstNode, SyntaxKind, | 4 | AstNode, SyntaxKind, |
5 | }; | 5 | }; |
6 | 6 | ||
@@ -22,7 +22,7 @@ use crate::{ | |||
22 | // use std::fmt::Display; | 22 | // use std::fmt::Display; |
23 | // ``` | 23 | // ``` |
24 | pub(crate) fn unmerge_use(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { | 24 | pub(crate) fn unmerge_use(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { |
25 | let tree: ast::UseTree = ctx.find_node_at_offset()?; | 25 | let tree: ast::UseTree = ctx.find_node_at_offset::<ast::UseTree>()?.clone_for_update(); |
26 | 26 | ||
27 | let tree_list = tree.syntax().parent().and_then(ast::UseTreeList::cast)?; | 27 | let tree_list = tree.syntax().parent().and_then(ast::UseTreeList::cast)?; |
28 | if tree_list.use_trees().count() < 2 { | 28 | if tree_list.use_trees().count() < 2 { |
@@ -33,6 +33,9 @@ pub(crate) fn unmerge_use(acc: &mut Assists, ctx: &AssistContext) -> Option<()> | |||
33 | let use_: ast::Use = tree_list.syntax().ancestors().find_map(ast::Use::cast)?; | 33 | let use_: ast::Use = tree_list.syntax().ancestors().find_map(ast::Use::cast)?; |
34 | let path = resolve_full_path(&tree)?; | 34 | let path = resolve_full_path(&tree)?; |
35 | 35 | ||
36 | let old_parent_range = use_.syntax().parent()?.text_range(); | ||
37 | let new_parent = use_.syntax().parent()?; | ||
38 | |||
36 | let target = tree.syntax().text_range(); | 39 | let target = tree.syntax().text_range(); |
37 | acc.add( | 40 | acc.add( |
38 | AssistId("unmerge_use", AssistKind::RefactorRewrite), | 41 | AssistId("unmerge_use", AssistKind::RefactorRewrite), |
@@ -47,20 +50,13 @@ pub(crate) fn unmerge_use(acc: &mut Assists, ctx: &AssistContext) -> Option<()> | |||
47 | tree.rename(), | 50 | tree.rename(), |
48 | tree.star_token().is_some(), | 51 | tree.star_token().is_some(), |
49 | ), | 52 | ), |
50 | ); | 53 | ) |
51 | 54 | .clone_for_update(); | |
52 | let mut rewriter = SyntaxRewriter::default(); | 55 | |
53 | rewriter += tree.remove(); | 56 | tree.remove(); |
54 | rewriter.insert_after(use_.syntax(), &ast::make::tokens::single_newline()); | 57 | ted::insert(Position::after(use_.syntax()), new_use.syntax()); |
55 | if let ident_level @ 1..=usize::MAX = use_.indent_level().0 as usize { | 58 | |
56 | rewriter.insert_after( | 59 | builder.replace(old_parent_range, new_parent.to_string()); |
57 | use_.syntax(), | ||
58 | &ast::make::tokens::whitespace(&" ".repeat(4 * ident_level)), | ||
59 | ); | ||
60 | } | ||
61 | rewriter.insert_after(use_.syntax(), new_use.syntax()); | ||
62 | |||
63 | builder.rewrite(rewriter); | ||
64 | }, | 60 | }, |
65 | ) | 61 | ) |
66 | } | 62 | } |