aboutsummaryrefslogtreecommitdiff
path: root/crates/assists/src/utils/insert_use.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/assists/src/utils/insert_use.rs')
-rw-r--r--crates/assists/src/utils/insert_use.rs31
1 files changed, 18 insertions, 13 deletions
diff --git a/crates/assists/src/utils/insert_use.rs b/crates/assists/src/utils/insert_use.rs
index a76bd5ebf..84a0dffdd 100644
--- a/crates/assists/src/utils/insert_use.rs
+++ b/crates/assists/src/utils/insert_use.rs
@@ -1,12 +1,9 @@
1//! Handle syntactic aspects of inserting a new `use`. 1//! Handle syntactic aspects of inserting a new `use`.
2use std::{ 2use std::{cmp::Ordering, iter::successors};
3 cmp::Ordering,
4 iter::{self, successors},
5};
6 3
7use itertools::{EitherOrBoth, Itertools}; 4use itertools::{EitherOrBoth, Itertools};
8use syntax::{ 5use syntax::{
9 algo, 6 algo::SyntaxRewriter,
10 ast::{ 7 ast::{
11 self, 8 self,
12 edit::{AstNodeEdit, IndentLevel}, 9 edit::{AstNodeEdit, IndentLevel},
@@ -88,20 +85,19 @@ impl ImportScope {
88} 85}
89 86
90/// Insert an import path into the given file/node. A `merge` value of none indicates that no import merging is allowed to occur. 87/// Insert an import path into the given file/node. A `merge` value of none indicates that no import merging is allowed to occur.
91pub(crate) fn insert_use( 88pub(crate) fn insert_use<'a>(
92 scope: &ImportScope, 89 scope: &ImportScope,
93 path: ast::Path, 90 path: ast::Path,
94 merge: Option<MergeBehaviour>, 91 merge: Option<MergeBehaviour>,
95) -> SyntaxNode { 92) -> SyntaxRewriter<'a> {
93 let mut rewriter = SyntaxRewriter::default();
96 let use_item = make::use_(make::use_tree(path.clone(), None, None, false)); 94 let use_item = make::use_(make::use_tree(path.clone(), None, None, false));
97 // merge into existing imports if possible 95 // merge into existing imports if possible
98 if let Some(mb) = merge { 96 if let Some(mb) = merge {
99 for existing_use in scope.as_syntax_node().children().filter_map(ast::Use::cast) { 97 for existing_use in scope.as_syntax_node().children().filter_map(ast::Use::cast) {
100 if let Some(merged) = try_merge_imports(&existing_use, &use_item, mb) { 98 if let Some(merged) = try_merge_imports(&existing_use, &use_item, mb) {
101 let to_delete: SyntaxElement = existing_use.syntax().clone().into(); 99 rewriter.replace(existing_use.syntax(), merged.syntax());
102 let to_delete = to_delete.clone()..=to_delete; 100 return rewriter;
103 let to_insert = iter::once(merged.syntax().clone().into());
104 return algo::replace_children(scope.as_syntax_node(), to_delete, to_insert);
105 } 101 }
106 } 102 }
107 } 103 }
@@ -157,7 +153,15 @@ pub(crate) fn insert_use(
157 buf 153 buf
158 }; 154 };
159 155
160 algo::insert_children(scope.as_syntax_node(), insert_position, to_insert) 156 match insert_position {
157 InsertPosition::First => {
158 rewriter.insert_many_as_first_children(scope.as_syntax_node(), to_insert)
159 }
160 InsertPosition::Last => return rewriter, // actually unreachable
161 InsertPosition::Before(anchor) => rewriter.insert_many_before(&anchor, to_insert),
162 InsertPosition::After(anchor) => rewriter.insert_many_after(&anchor, to_insert),
163 }
164 rewriter
161} 165}
162 166
163fn eq_visibility(vis0: Option<ast::Visibility>, vis1: Option<ast::Visibility>) -> bool { 167fn eq_visibility(vis0: Option<ast::Visibility>, vis1: Option<ast::Visibility>) -> bool {
@@ -1101,7 +1105,8 @@ use foo::bar::baz::Qux;",
1101 .find_map(ast::Path::cast) 1105 .find_map(ast::Path::cast)
1102 .unwrap(); 1106 .unwrap();
1103 1107
1104 let result = insert_use(&file, path, mb).to_string(); 1108 let rewriter = insert_use(&file, path, mb);
1109 let result = rewriter.rewrite(file.as_syntax_node()).to_string();
1105 assert_eq_text!(&result, ra_fixture_after); 1110 assert_eq_text!(&result, ra_fixture_after);
1106 } 1111 }
1107 1112