aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_assists
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_assists')
-rw-r--r--crates/ra_assists/src/add_derive.rs19
-rw-r--r--crates/ra_assists/src/add_impl.rs17
-rw-r--r--crates/ra_assists/src/change_visibility.rs13
-rw-r--r--crates/ra_assists/src/fill_match_arms.rs18
-rw-r--r--crates/ra_assists/src/flip_comma.rs8
-rw-r--r--crates/ra_assists/src/introduce_variable.rs35
-rw-r--r--crates/ra_assists/src/lib.rs66
-rw-r--r--crates/ra_assists/src/remove_dbg.rs18
-rw-r--r--crates/ra_assists/src/replace_if_let_with_match.rs25
-rw-r--r--crates/ra_assists/src/split_import.rs7
10 files changed, 210 insertions, 16 deletions
diff --git a/crates/ra_assists/src/add_derive.rs b/crates/ra_assists/src/add_derive.rs
index de33b356c..ea9707631 100644
--- a/crates/ra_assists/src/add_derive.rs
+++ b/crates/ra_assists/src/add_derive.rs
@@ -39,7 +39,7 @@ fn derive_insertion_offset(nominal: &ast::NominalDef) -> Option<TextUnit> {
39#[cfg(test)] 39#[cfg(test)]
40mod tests { 40mod tests {
41 use super::*; 41 use super::*;
42 use crate::helpers::check_assist; 42 use crate::helpers::{check_assist, check_assist_target};
43 43
44 #[test] 44 #[test]
45 fn add_derive_new() { 45 fn add_derive_new() {
@@ -81,4 +81,21 @@ struct Foo { a: i32, }
81 ", 81 ",
82 ); 82 );
83 } 83 }
84
85 #[test]
86 fn add_derive_target() {
87 check_assist_target(
88 add_derive,
89 "
90struct SomeThingIrrelevant;
91/// `Foo` is a pretty important struct.
92/// It does stuff.
93struct Foo { a: i32<|>, }
94struct EvenMoreIrrelevant;
95 ",
96 "/// `Foo` is a pretty important struct.
97/// It does stuff.
98struct Foo { a: i32, }",
99 );
100 }
84} 101}
diff --git a/crates/ra_assists/src/add_impl.rs b/crates/ra_assists/src/add_impl.rs
index f2360bc89..32fc074a6 100644
--- a/crates/ra_assists/src/add_impl.rs
+++ b/crates/ra_assists/src/add_impl.rs
@@ -11,6 +11,7 @@ pub(crate) fn add_impl(ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> {
11 let nominal = ctx.node_at_offset::<ast::NominalDef>()?; 11 let nominal = ctx.node_at_offset::<ast::NominalDef>()?;
12 let name = nominal.name()?; 12 let name = nominal.name()?;
13 ctx.build("add impl", |edit| { 13 ctx.build("add impl", |edit| {
14 edit.target(nominal.syntax().range());
14 let type_params = nominal.type_param_list(); 15 let type_params = nominal.type_param_list();
15 let start_offset = nominal.syntax().range().end(); 16 let start_offset = nominal.syntax().range().end();
16 let mut buf = String::new(); 17 let mut buf = String::new();
@@ -37,7 +38,7 @@ pub(crate) fn add_impl(ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> {
37#[cfg(test)] 38#[cfg(test)]
38mod tests { 39mod tests {
39 use super::*; 40 use super::*;
40 use crate::helpers::check_assist; 41 use crate::helpers::{check_assist, check_assist_target};
41 42
42 #[test] 43 #[test]
43 fn test_add_impl() { 44 fn test_add_impl() {
@@ -54,4 +55,18 @@ mod tests {
54 ); 55 );
55 } 56 }
56 57
58 #[test]
59 fn add_impl_target() {
60 check_assist_target(
61 add_impl,
62 "
63struct SomeThingIrrelevant;
64/// Has a lifetime parameter
65struct Foo<'a, T: Foo<'a>> {<|>}
66struct EvenMoreIrrelevant;
67",
68 "/// Has a lifetime parameter
69struct Foo<'a, T: Foo<'a>> {}",
70 );
71 }
57} 72}
diff --git a/crates/ra_assists/src/change_visibility.rs b/crates/ra_assists/src/change_visibility.rs
index 73dd8319f..6d9a4eec2 100644
--- a/crates/ra_assists/src/change_visibility.rs
+++ b/crates/ra_assists/src/change_visibility.rs
@@ -31,14 +31,14 @@ fn add_vis(ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> {
31 if parent.children().any(|child| child.kind() == VISIBILITY) { 31 if parent.children().any(|child| child.kind() == VISIBILITY) {
32 return None; 32 return None;
33 } 33 }
34 (vis_offset(parent), parent.range()) 34 (vis_offset(parent), keyword.range())
35 } else { 35 } else {
36 let ident = ctx.leaf_at_offset().find(|leaf| leaf.kind() == IDENT)?; 36 let ident = ctx.leaf_at_offset().find(|leaf| leaf.kind() == IDENT)?;
37 let field = ident.ancestors().find_map(ast::NamedFieldDef::cast)?; 37 let field = ident.ancestors().find_map(ast::NamedFieldDef::cast)?;
38 if field.name()?.syntax().range() != ident.range() && field.visibility().is_some() { 38 if field.name()?.syntax().range() != ident.range() && field.visibility().is_some() {
39 return None; 39 return None;
40 } 40 }
41 (vis_offset(field.syntax()), field.syntax().range()) 41 (vis_offset(field.syntax()), ident.range())
42 }; 42 };
43 43
44 ctx.build("make pub(crate)", |edit| { 44 ctx.build("make pub(crate)", |edit| {
@@ -80,7 +80,7 @@ fn change_vis(ctx: AssistCtx<impl HirDatabase>, vis: &ast::Visibility) -> Option
80#[cfg(test)] 80#[cfg(test)]
81mod tests { 81mod tests {
82 use super::*; 82 use super::*;
83 use crate::helpers::check_assist; 83 use crate::helpers::{check_assist, check_assist_target};
84 84
85 #[test] 85 #[test]
86 fn change_visibility_adds_pub_crate_to_items() { 86 fn change_visibility_adds_pub_crate_to_items() {
@@ -138,4 +138,11 @@ mod tests {
138 ", 138 ",
139 ) 139 )
140 } 140 }
141
142 #[test]
143 fn change_visibility_target() {
144 check_assist_target(change_visibility, "<|>fn foo() {}", "fn");
145 check_assist_target(change_visibility, "pub(crate)<|> fn foo() {}", "pub(crate)");
146 check_assist_target(change_visibility, "struct S { <|>field: u32 }", "field");
147 }
141} 148}
diff --git a/crates/ra_assists/src/fill_match_arms.rs b/crates/ra_assists/src/fill_match_arms.rs
index 741f75e2a..69b535a27 100644
--- a/crates/ra_assists/src/fill_match_arms.rs
+++ b/crates/ra_assists/src/fill_match_arms.rs
@@ -65,6 +65,7 @@ pub(crate) fn fill_match_arms(ctx: AssistCtx<impl HirDatabase>) -> Option<Assist
65 buf.push_str(" => (),\n"); 65 buf.push_str(" => (),\n");
66 } 66 }
67 buf.push_str("}"); 67 buf.push_str("}");
68 edit.target(match_expr.syntax().range());
68 edit.set_cursor(expr.syntax().range().start()); 69 edit.set_cursor(expr.syntax().range().start());
69 edit.replace_node_and_indent(match_expr.syntax(), buf); 70 edit.replace_node_and_indent(match_expr.syntax(), buf);
70 }) 71 })
@@ -72,7 +73,7 @@ pub(crate) fn fill_match_arms(ctx: AssistCtx<impl HirDatabase>) -> Option<Assist
72 73
73#[cfg(test)] 74#[cfg(test)]
74mod tests { 75mod tests {
75 use crate::helpers::check_assist; 76 use crate::helpers::{check_assist, check_assist_target};
76 77
77 use super::fill_match_arms; 78 use super::fill_match_arms;
78 79
@@ -139,4 +140,19 @@ mod tests {
139 "#, 140 "#,
140 ); 141 );
141 } 142 }
143
144 #[test]
145 fn fill_match_arms_target() {
146 check_assist_target(
147 fill_match_arms,
148 r#"
149 enum E { X, Y}
150
151 fn main() {
152 match E::X<|> {}
153 }
154 "#,
155 "match E::X {}",
156 );
157 }
142} 158}
diff --git a/crates/ra_assists/src/flip_comma.rs b/crates/ra_assists/src/flip_comma.rs
index a49820c29..33da58f17 100644
--- a/crates/ra_assists/src/flip_comma.rs
+++ b/crates/ra_assists/src/flip_comma.rs
@@ -11,6 +11,7 @@ pub(crate) fn flip_comma(ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> {
11 let prev = non_trivia_sibling(comma, Direction::Prev)?; 11 let prev = non_trivia_sibling(comma, Direction::Prev)?;
12 let next = non_trivia_sibling(comma, Direction::Next)?; 12 let next = non_trivia_sibling(comma, Direction::Next)?;
13 ctx.build("flip comma", |edit| { 13 ctx.build("flip comma", |edit| {
14 edit.target(comma.range());
14 edit.replace(prev.range(), next.text()); 15 edit.replace(prev.range(), next.text());
15 edit.replace(next.range(), prev.text()); 16 edit.replace(next.range(), prev.text());
16 }) 17 })
@@ -20,7 +21,7 @@ pub(crate) fn flip_comma(ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> {
20mod tests { 21mod tests {
21 use super::*; 22 use super::*;
22 23
23 use crate::helpers::check_assist; 24 use crate::helpers::{check_assist, check_assist_target};
24 25
25 #[test] 26 #[test]
26 fn flip_comma_works_for_function_parameters() { 27 fn flip_comma_works_for_function_parameters() {
@@ -30,4 +31,9 @@ mod tests {
30 "fn foo(y: Result<(), ()>,<|> x: i32) {}", 31 "fn foo(y: Result<(), ()>,<|> x: i32) {}",
31 ) 32 )
32 } 33 }
34
35 #[test]
36 fn flip_comma_target() {
37 check_assist_target(flip_comma, "fn foo(x: i32,<|> y: Result<(), ()>) {}", ",")
38 }
33} 39}
diff --git a/crates/ra_assists/src/introduce_variable.rs b/crates/ra_assists/src/introduce_variable.rs
index 4f7c9f3c2..934d1d6b3 100644
--- a/crates/ra_assists/src/introduce_variable.rs
+++ b/crates/ra_assists/src/introduce_variable.rs
@@ -45,6 +45,7 @@ pub(crate) fn introduce_variable(ctx: AssistCtx<impl HirDatabase>) -> Option<Ass
45 } else { 45 } else {
46 buf.push_str(";"); 46 buf.push_str(";");
47 indent.text().push_to(&mut buf); 47 indent.text().push_to(&mut buf);
48 edit.target(expr.syntax().range());
48 edit.replace(expr.syntax().range(), "var_name".to_string()); 49 edit.replace(expr.syntax().range(), "var_name".to_string());
49 edit.insert(anchor_stmt.range().start(), buf); 50 edit.insert(anchor_stmt.range().start(), buf);
50 if wrap_in_block { 51 if wrap_in_block {
@@ -58,7 +59,7 @@ pub(crate) fn introduce_variable(ctx: AssistCtx<impl HirDatabase>) -> Option<Ass
58fn valid_covering_node(node: &SyntaxNode) -> bool { 59fn valid_covering_node(node: &SyntaxNode) -> bool {
59 node.kind() != COMMENT 60 node.kind() != COMMENT
60} 61}
61/// Check wether the node is a valid expression which can be extracted to a variable. 62/// Check whether the node is a valid expression which can be extracted to a variable.
62/// In general that's true for any expression, but in some cases that would produce invalid code. 63/// In general that's true for any expression, but in some cases that would produce invalid code.
63fn valid_target_expr(node: &SyntaxNode) -> Option<&ast::Expr> { 64fn valid_target_expr(node: &SyntaxNode) -> Option<&ast::Expr> {
64 match node.kind() { 65 match node.kind() {
@@ -74,7 +75,7 @@ fn valid_target_expr(node: &SyntaxNode) -> Option<&ast::Expr> {
74/// and a boolean indicating whether we have to wrap it within a { } block 75/// and a boolean indicating whether we have to wrap it within a { } block
75/// to produce correct code. 76/// to produce correct code.
76/// It can be a statement, the last in a block expression or a wanna be block 77/// It can be a statement, the last in a block expression or a wanna be block
77/// expression like a lamba or match arm. 78/// expression like a lambda or match arm.
78fn anchor_stmt(expr: &ast::Expr) -> Option<(&SyntaxNode, bool)> { 79fn anchor_stmt(expr: &ast::Expr) -> Option<(&SyntaxNode, bool)> {
79 expr.syntax().ancestors().find_map(|node| { 80 expr.syntax().ancestors().find_map(|node| {
80 if ast::Stmt::cast(node).is_some() { 81 if ast::Stmt::cast(node).is_some() {
@@ -100,7 +101,7 @@ fn anchor_stmt(expr: &ast::Expr) -> Option<(&SyntaxNode, bool)> {
100#[cfg(test)] 101#[cfg(test)]
101mod tests { 102mod tests {
102 use super::*; 103 use super::*;
103 use crate::helpers::{check_assist, check_assist_not_applicable, check_assist_range}; 104 use crate::helpers::{check_assist, check_assist_not_applicable, check_assist_range, check_assist_target, check_assist_range_target};
104 105
105 #[test] 106 #[test]
106 fn test_introduce_var_simple() { 107 fn test_introduce_var_simple() {
@@ -425,4 +426,32 @@ fn main() {
425", 426",
426 ); 427 );
427 } 428 }
429
430 // FIXME: This is not quite correct, but good enough(tm) for the sorting heuristic
431 #[test]
432 fn introduce_var_target() {
433 check_assist_target(
434 introduce_variable,
435 "
436fn foo() -> u32 {
437 r<|>eturn 2 + 2;
438}
439",
440 "2 + 2",
441 );
442
443 check_assist_range_target(
444 introduce_variable,
445 "
446fn main() {
447 let x = true;
448 let tuple = match x {
449 true => (<|>2 + 2<|>, true)
450 _ => (0, false)
451 };
452}
453",
454 "2 + 2",
455 );
456 }
428} 457}
diff --git a/crates/ra_assists/src/lib.rs b/crates/ra_assists/src/lib.rs
index fc4e95303..2590faca9 100644
--- a/crates/ra_assists/src/lib.rs
+++ b/crates/ra_assists/src/lib.rs
@@ -65,7 +65,7 @@ where
65 Assist::Unresolved(..) => unreachable!(), 65 Assist::Unresolved(..) => unreachable!(),
66 }) 66 })
67 .collect::<Vec<(AssistLabel, AssistAction)>>(); 67 .collect::<Vec<(AssistLabel, AssistAction)>>();
68 a.sort_unstable_by(|a, b| match a { 68 a.sort_by(|a, b| match a {
69 // Some(y) < Some(x) < None for y < x 69 // Some(y) < Some(x) < None for y < x
70 (_, AssistAction { target: Some(a), .. }) => match b { 70 (_, AssistAction { target: Some(a), .. }) => match b {
71 (_, AssistAction { target: Some(b), .. }) => a.len().cmp(&b.len()), 71 (_, AssistAction { target: Some(b), .. }) => a.len().cmp(&b.len()),
@@ -163,6 +163,45 @@ mod helpers {
163 assert_eq_text!(after, &actual); 163 assert_eq_text!(after, &actual);
164 } 164 }
165 165
166 pub(crate) fn check_assist_target(
167 assist: fn(AssistCtx<MockDatabase>) -> Option<Assist>,
168 before: &str,
169 target: &str,
170 ) {
171 let (before_cursor_pos, before) = extract_offset(before);
172 let (db, _source_root, file_id) = MockDatabase::with_single_file(&before);
173 let frange =
174 FileRange { file_id, range: TextRange::offset_len(before_cursor_pos, 0.into()) };
175 let assist =
176 AssistCtx::with_ctx(&db, frange, true, assist).expect("code action is not applicable");
177 let action = match assist {
178 Assist::Unresolved(_) => unreachable!(),
179 Assist::Resolved(_, it) => it,
180 };
181
182 let range = action.target.expect("expected target on action");
183 assert_eq_text!(&before[range.start().to_usize()..range.end().to_usize()], target);
184 }
185
186 pub(crate) fn check_assist_range_target(
187 assist: fn(AssistCtx<MockDatabase>) -> Option<Assist>,
188 before: &str,
189 target: &str,
190 ) {
191 let (range, before) = extract_range(before);
192 let (db, _source_root, file_id) = MockDatabase::with_single_file(&before);
193 let frange = FileRange { file_id, range };
194 let assist =
195 AssistCtx::with_ctx(&db, frange, true, assist).expect("code action is not applicable");
196 let action = match assist {
197 Assist::Unresolved(_) => unreachable!(),
198 Assist::Resolved(_, it) => it,
199 };
200
201 let range = action.target.expect("expected target on action");
202 assert_eq_text!(&before[range.start().to_usize()..range.end().to_usize()], target);
203 }
204
166 pub(crate) fn check_assist_not_applicable( 205 pub(crate) fn check_assist_not_applicable(
167 assist: fn(AssistCtx<MockDatabase>) -> Option<Assist>, 206 assist: fn(AssistCtx<MockDatabase>) -> Option<Assist>,
168 before: &str, 207 before: &str,
@@ -181,10 +220,10 @@ mod tests {
181 use hir::mock::MockDatabase; 220 use hir::mock::MockDatabase;
182 use ra_syntax::TextRange; 221 use ra_syntax::TextRange;
183 use ra_db::FileRange; 222 use ra_db::FileRange;
184 use test_utils::extract_offset; 223 use test_utils::{extract_offset, extract_range};
185 224
186 #[test] 225 #[test]
187 fn assist_order() { 226 fn assist_order_field_struct() {
188 let before = "struct Foo { <|>bar: u32 }"; 227 let before = "struct Foo { <|>bar: u32 }";
189 let (before_cursor_pos, before) = extract_offset(before); 228 let (before_cursor_pos, before) = extract_offset(before);
190 let (db, _source_root, file_id) = MockDatabase::with_single_file(&before); 229 let (db, _source_root, file_id) = MockDatabase::with_single_file(&before);
@@ -197,4 +236,25 @@ mod tests {
197 assert_eq!(assists.next().expect("expected assist").0.label, "add `#[derive]`"); 236 assert_eq!(assists.next().expect("expected assist").0.label, "add `#[derive]`");
198 } 237 }
199 238
239 #[test]
240 fn assist_order_if_expr() {
241 let before = "
242 pub fn test_some_range(a: int) -> bool {
243 if let 2..6 = 5<|> {
244 true
245 } else {
246 false
247 }
248 }";
249 let (before_cursor_pos, before) = extract_offset(before);
250 let (db, _source_root, file_id) = MockDatabase::with_single_file(&before);
251 let frange =
252 FileRange { file_id, range: TextRange::offset_len(before_cursor_pos, 0.into()) };
253 let assists = super::assists(&db, frange);
254 let mut assists = assists.iter();
255
256 assert_eq!(assists.next().expect("expected assist").0.label, "introduce variable");
257 assert_eq!(assists.next().expect("expected assist").0.label, "replace with match");
258 }
259
200} 260}
diff --git a/crates/ra_assists/src/remove_dbg.rs b/crates/ra_assists/src/remove_dbg.rs
index 40f97a849..e9d0a635b 100644
--- a/crates/ra_assists/src/remove_dbg.rs
+++ b/crates/ra_assists/src/remove_dbg.rs
@@ -47,6 +47,7 @@ pub(crate) fn remove_dbg(ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> {
47 }; 47 };
48 48
49 ctx.build("remove dbg!()", |edit| { 49 ctx.build("remove dbg!()", |edit| {
50 edit.target(macro_call.syntax().range());
50 edit.replace(macro_range, macro_content); 51 edit.replace(macro_range, macro_content);
51 edit.set_cursor(cursor_pos); 52 edit.set_cursor(cursor_pos);
52 }) 53 })
@@ -78,7 +79,7 @@ fn is_valid_macrocall(macro_call: &ast::MacroCall, macro_name: &str) -> Option<b
78#[cfg(test)] 79#[cfg(test)]
79mod tests { 80mod tests {
80 use super::*; 81 use super::*;
81 use crate::helpers::{check_assist, check_assist_not_applicable}; 82 use crate::helpers::{check_assist, check_assist_not_applicable, check_assist_target};
82 83
83 #[test] 84 #[test]
84 fn test_remove_dbg() { 85 fn test_remove_dbg() {
@@ -120,4 +121,19 @@ fn foo(n: usize) {
120 check_assist_not_applicable(remove_dbg, "<|>dbg(5, 6, 7)"); 121 check_assist_not_applicable(remove_dbg, "<|>dbg(5, 6, 7)");
121 check_assist_not_applicable(remove_dbg, "<|>dbg!(5, 6, 7"); 122 check_assist_not_applicable(remove_dbg, "<|>dbg!(5, 6, 7");
122 } 123 }
124
125 #[test]
126 fn remove_dbg_target() {
127 check_assist_target(
128 remove_dbg,
129 "
130fn foo(n: usize) {
131 if let Some(_) = dbg!(n.<|>checked_sub(4)) {
132 // ...
133 }
134}
135",
136 "dbg!(n.checked_sub(4))",
137 );
138 }
123} 139}
diff --git a/crates/ra_assists/src/replace_if_let_with_match.rs b/crates/ra_assists/src/replace_if_let_with_match.rs
index 683f0d119..a22ec5584 100644
--- a/crates/ra_assists/src/replace_if_let_with_match.rs
+++ b/crates/ra_assists/src/replace_if_let_with_match.rs
@@ -17,6 +17,7 @@ pub(crate) fn replace_if_let_with_match(ctx: AssistCtx<impl HirDatabase>) -> Opt
17 17
18 ctx.build("replace with match", |edit| { 18 ctx.build("replace with match", |edit| {
19 let match_expr = build_match_expr(expr, pat, then_block, else_block); 19 let match_expr = build_match_expr(expr, pat, then_block, else_block);
20 edit.target(if_expr.syntax().range());
20 edit.replace_node_and_indent(if_expr.syntax(), match_expr); 21 edit.replace_node_and_indent(if_expr.syntax(), match_expr);
21 edit.set_cursor(if_expr.syntax().range().start()) 22 edit.set_cursor(if_expr.syntax().range().start())
22 }) 23 })
@@ -46,7 +47,7 @@ fn format_arm(block: &ast::Block) -> String {
46#[cfg(test)] 47#[cfg(test)]
47mod tests { 48mod tests {
48 use super::*; 49 use super::*;
49 use crate::helpers::check_assist; 50 use crate::helpers::{check_assist, check_assist_target};
50 51
51 #[test] 52 #[test]
52 fn test_replace_if_let_with_match_unwraps_simple_expressions() { 53 fn test_replace_if_let_with_match_unwraps_simple_expressions() {
@@ -73,4 +74,26 @@ impl VariantData {
73} ", 74} ",
74 ) 75 )
75 } 76 }
77
78 #[test]
79 fn replace_if_let_with_match_target() {
80 check_assist_target(
81 replace_if_let_with_match,
82 "
83impl VariantData {
84 pub fn is_struct(&self) -> bool {
85 if <|>let VariantData::Struct(..) = *self {
86 true
87 } else {
88 false
89 }
90 }
91} ",
92 "if let VariantData::Struct(..) = *self {
93 true
94 } else {
95 false
96 }",
97 );
98 }
76} 99}
diff --git a/crates/ra_assists/src/split_import.rs b/crates/ra_assists/src/split_import.rs
index 287c05830..051bc6fec 100644
--- a/crates/ra_assists/src/split_import.rs
+++ b/crates/ra_assists/src/split_import.rs
@@ -34,7 +34,7 @@ pub(crate) fn split_import(ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> {
34#[cfg(test)] 34#[cfg(test)]
35mod tests { 35mod tests {
36 use super::*; 36 use super::*;
37 use crate::helpers::check_assist; 37 use crate::helpers::{check_assist, check_assist_target};
38 38
39 #[test] 39 #[test]
40 fn test_split_import() { 40 fn test_split_import() {
@@ -53,4 +53,9 @@ mod tests {
53 "use algo::{<|>visitor::{Visitor, visit}}", 53 "use algo::{<|>visitor::{Visitor, visit}}",
54 ) 54 )
55 } 55 }
56
57 #[test]
58 fn split_import_target() {
59 check_assist_target(split_import, "use algo::<|>visitor::{Visitor, visit}", "::");
60 }
56} 61}