aboutsummaryrefslogtreecommitdiff
path: root/crates/assists/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/assists/src')
-rw-r--r--crates/assists/src/handlers/auto_import.rs19
-rw-r--r--crates/assists/src/handlers/extract_struct_from_enum_variant.rs20
-rw-r--r--crates/assists/src/handlers/replace_qualified_name_with_use.rs65
-rw-r--r--crates/assists/src/utils/insert_use.rs18
4 files changed, 68 insertions, 54 deletions
diff --git a/crates/assists/src/handlers/auto_import.rs b/crates/assists/src/handlers/auto_import.rs
index c4770f336..f3b4c5708 100644
--- a/crates/assists/src/handlers/auto_import.rs
+++ b/crates/assists/src/handlers/auto_import.rs
@@ -13,8 +13,11 @@ use syntax::{
13}; 13};
14 14
15use crate::{ 15use crate::{
16 utils::insert_use_statement, AssistContext, AssistId, AssistKind, Assists, GroupLabel, 16 utils::{insert_use, MergeBehaviour},
17 AssistContext, AssistId, AssistKind, Assists, GroupLabel,
17}; 18};
19use ast::make;
20use insert_use::find_insert_use_container;
18 21
19// Assist: auto_import 22// Assist: auto_import
20// 23//
@@ -44,6 +47,8 @@ pub(crate) fn auto_import(acc: &mut Assists, ctx: &AssistContext) -> Option<()>
44 47
45 let range = ctx.sema.original_range(&auto_import_assets.syntax_under_caret).range; 48 let range = ctx.sema.original_range(&auto_import_assets.syntax_under_caret).range;
46 let group = auto_import_assets.get_import_group_message(); 49 let group = auto_import_assets.get_import_group_message();
50 let container = find_insert_use_container(&auto_import_assets.syntax_under_caret, ctx)?;
51 let syntax = container.either(|l| l.syntax().clone(), |r| r.syntax().clone());
47 for import in proposed_imports { 52 for import in proposed_imports {
48 acc.add_group( 53 acc.add_group(
49 &group, 54 &group,
@@ -51,12 +56,12 @@ pub(crate) fn auto_import(acc: &mut Assists, ctx: &AssistContext) -> Option<()>
51 format!("Import `{}`", &import), 56 format!("Import `{}`", &import),
52 range, 57 range,
53 |builder| { 58 |builder| {
54 insert_use_statement( 59 let new_syntax = insert_use(
55 &auto_import_assets.syntax_under_caret, 60 &syntax,
56 &import.to_string(), 61 make::path_from_text(&import.to_string()),
57 ctx, 62 Some(MergeBehaviour::Full),
58 builder.text_edit_builder(),
59 ); 63 );
64 builder.replace(syntax.text_range(), new_syntax.to_string())
60 }, 65 },
61 ); 66 );
62 } 67 }
@@ -358,7 +363,7 @@ mod tests {
358 } 363 }
359 ", 364 ",
360 r" 365 r"
361 use PubMod::{PubStruct2, PubStruct1}; 366 use PubMod::{PubStruct1, PubStruct2};
362 367
363 struct Test { 368 struct Test {
364 test: PubStruct2<u8>, 369 test: PubStruct2<u8>,
diff --git a/crates/assists/src/handlers/extract_struct_from_enum_variant.rs b/crates/assists/src/handlers/extract_struct_from_enum_variant.rs
index 8ac20210a..d9c50f25f 100644
--- a/crates/assists/src/handlers/extract_struct_from_enum_variant.rs
+++ b/crates/assists/src/handlers/extract_struct_from_enum_variant.rs
@@ -10,9 +10,12 @@ use syntax::{
10}; 10};
11 11
12use crate::{ 12use crate::{
13 assist_context::AssistBuilder, utils::insert_use_statement, AssistContext, AssistId, 13 assist_context::AssistBuilder,
14 AssistKind, Assists, 14 utils::{insert_use, MergeBehaviour},
15 AssistContext, AssistId, AssistKind, Assists,
15}; 16};
17use ast::make;
18use insert_use::find_insert_use_container;
16 19
17// Assist: extract_struct_from_enum_variant 20// Assist: extract_struct_from_enum_variant
18// 21//
@@ -107,12 +110,15 @@ fn insert_import(
107 if let Some(mut mod_path) = mod_path { 110 if let Some(mut mod_path) = mod_path {
108 mod_path.segments.pop(); 111 mod_path.segments.pop();
109 mod_path.segments.push(variant_hir_name.clone()); 112 mod_path.segments.push(variant_hir_name.clone());
110 insert_use_statement( 113 let container = find_insert_use_container(path.syntax(), ctx)?;
111 path.syntax(), 114 let syntax = container.either(|l| l.syntax().clone(), |r| r.syntax().clone());
112 &mod_path.to_string(), 115
113 ctx, 116 let new_syntax = insert_use(
114 builder.text_edit_builder(), 117 &syntax,
118 make::path_from_text(&mod_path.to_string()),
119 Some(MergeBehaviour::Full),
115 ); 120 );
121 builder.replace(syntax.text_range(), new_syntax.to_string())
116 } 122 }
117 Some(()) 123 Some(())
118} 124}
diff --git a/crates/assists/src/handlers/replace_qualified_name_with_use.rs b/crates/assists/src/handlers/replace_qualified_name_with_use.rs
index 470e5f8ff..56e85125d 100644
--- a/crates/assists/src/handlers/replace_qualified_name_with_use.rs
+++ b/crates/assists/src/handlers/replace_qualified_name_with_use.rs
@@ -2,9 +2,10 @@ use syntax::{algo::SyntaxRewriter, ast, match_ast, AstNode, SyntaxNode, TextRang
2use test_utils::mark; 2use test_utils::mark;
3 3
4use crate::{ 4use crate::{
5 utils::{find_insert_use_container, insert_use_statement}, 5 utils::{find_insert_use_container, insert_use, MergeBehaviour},
6 AssistContext, AssistId, AssistKind, Assists, 6 AssistContext, AssistId, AssistKind, Assists,
7}; 7};
8use ast::make;
8 9
9// Assist: replace_qualified_name_with_use 10// Assist: replace_qualified_name_with_use
10// 11//
@@ -32,7 +33,7 @@ pub(crate) fn replace_qualified_name_with_use(
32 mark::hit!(dont_import_trivial_paths); 33 mark::hit!(dont_import_trivial_paths);
33 return None; 34 return None;
34 } 35 }
35 let path_to_import = path.to_string().clone(); 36 let path_to_import = path.to_string();
36 let path_to_import = match path.segment()?.generic_arg_list() { 37 let path_to_import = match path.segment()?.generic_arg_list() {
37 Some(generic_args) => { 38 Some(generic_args) => {
38 let generic_args_start = 39 let generic_args_start =
@@ -43,28 +44,24 @@ pub(crate) fn replace_qualified_name_with_use(
43 }; 44 };
44 45
45 let target = path.syntax().text_range(); 46 let target = path.syntax().text_range();
47 let container = find_insert_use_container(path.syntax(), ctx)?;
48 let syntax = container.either(|l| l.syntax().clone(), |r| r.syntax().clone());
46 acc.add( 49 acc.add(
47 AssistId("replace_qualified_name_with_use", AssistKind::RefactorRewrite), 50 AssistId("replace_qualified_name_with_use", AssistKind::RefactorRewrite),
48 "Replace qualified path with use", 51 "Replace qualified path with use",
49 target, 52 target,
50 |builder| { 53 |builder| {
51 let container = match find_insert_use_container(path.syntax(), ctx) {
52 Some(c) => c,
53 None => return,
54 };
55 insert_use_statement(
56 path.syntax(),
57 &path_to_import.to_string(),
58 ctx,
59 builder.text_edit_builder(),
60 );
61
62 // Now that we've brought the name into scope, re-qualify all paths that could be 54 // Now that we've brought the name into scope, re-qualify all paths that could be
63 // affected (that is, all paths inside the node we added the `use` to). 55 // affected (that is, all paths inside the node we added the `use` to).
64 let mut rewriter = SyntaxRewriter::default(); 56 let mut rewriter = SyntaxRewriter::default();
65 let syntax = container.either(|l| l.syntax().clone(), |r| r.syntax().clone()); 57 shorten_paths(&mut rewriter, syntax.clone(), path);
66 shorten_paths(&mut rewriter, syntax, path); 58 let rewritten_syntax = rewriter.rewrite(&syntax);
67 builder.rewrite(rewriter); 59 let new_syntax = insert_use(
60 &rewritten_syntax,
61 make::path_from_text(path_to_import),
62 Some(MergeBehaviour::Full),
63 );
64 builder.replace(syntax.text_range(), new_syntax.to_string())
68 }, 65 },
69 ) 66 )
70} 67}
@@ -220,9 +217,10 @@ impl std::fmt::Debug<|> for Foo {
220} 217}
221 ", 218 ",
222 r" 219 r"
223use stdx;
224use std::fmt::Debug; 220use std::fmt::Debug;
225 221
222use stdx;
223
226impl Debug for Foo { 224impl Debug for Foo {
227} 225}
228 ", 226 ",
@@ -274,7 +272,7 @@ impl std::io<|> for Foo {
274} 272}
275 ", 273 ",
276 r" 274 r"
277use std::{io, fmt}; 275use std::{fmt, io};
278 276
279impl io for Foo { 277impl io for Foo {
280} 278}
@@ -293,7 +291,7 @@ impl std::fmt::Debug<|> for Foo {
293} 291}
294 ", 292 ",
295 r" 293 r"
296use std::fmt::{self, Debug, }; 294use std::fmt::{self, Debug};
297 295
298impl Debug for Foo { 296impl Debug for Foo {
299} 297}
@@ -312,7 +310,7 @@ impl std::fmt<|> for Foo {
312} 310}
313 ", 311 ",
314 r" 312 r"
315use std::fmt::{self, Debug}; 313use std::fmt::{Debug, self};
316 314
317impl fmt for Foo { 315impl fmt for Foo {
318} 316}
@@ -330,8 +328,9 @@ use std::fmt::{Debug, nested::{Display}};
330impl std::fmt::nested<|> for Foo { 328impl std::fmt::nested<|> for Foo {
331} 329}
332", 330",
331 // FIXME(veykril): should be nested::{self, Display} here
333 r" 332 r"
334use std::fmt::{Debug, nested::{Display, self}}; 333use std::fmt::{Debug, nested::{Display}, nested};
335 334
336impl nested for Foo { 335impl nested for Foo {
337} 336}
@@ -349,8 +348,9 @@ use std::fmt::{Debug, nested::{self, Display}};
349impl std::fmt::nested<|> for Foo { 348impl std::fmt::nested<|> for Foo {
350} 349}
351", 350",
351 // FIXME(veykril): self is being pulled out for some reason now
352 r" 352 r"
353use std::fmt::{Debug, nested::{self, Display}}; 353use std::fmt::{Debug, nested::{Display}, nested};
354 354
355impl nested for Foo { 355impl nested for Foo {
356} 356}
@@ -369,7 +369,7 @@ impl std::fmt::nested::Debug<|> for Foo {
369} 369}
370", 370",
371 r" 371 r"
372use std::fmt::{Debug, nested::{Display, Debug}}; 372use std::fmt::{Debug, nested::{Display}, nested::Debug};
373 373
374impl Debug for Foo { 374impl Debug for Foo {
375} 375}
@@ -388,7 +388,7 @@ impl std::fmt::nested::Display<|> for Foo {
388} 388}
389", 389",
390 r" 390 r"
391use std::fmt::{nested::Display, Debug}; 391use std::fmt::{Debug, nested::Display};
392 392
393impl Display for Foo { 393impl Display for Foo {
394} 394}
@@ -407,7 +407,7 @@ impl std::fmt::Display<|> for Foo {
407} 407}
408", 408",
409 r" 409 r"
410use std::fmt::{Display, nested::Debug}; 410use std::fmt::{nested::Debug, Display};
411 411
412impl Display for Foo { 412impl Display for Foo {
413} 413}
@@ -427,11 +427,12 @@ use crate::{
427 427
428fn foo() { crate::ty::lower<|>::trait_env() } 428fn foo() { crate::ty::lower<|>::trait_env() }
429", 429",
430 // FIXME(veykril): formatting broke here
430 r" 431 r"
431use crate::{ 432use crate::{
432 ty::{Substs, Ty, lower}, 433 ty::{Substs, Ty},
433 AssocItem, 434 AssocItem,
434}; 435ty::lower};
435 436
436fn foo() { lower::trait_env() } 437fn foo() { lower::trait_env() }
437", 438",
@@ -451,6 +452,8 @@ impl foo::Debug<|> for Foo {
451 r" 452 r"
452use std::fmt as foo; 453use std::fmt as foo;
453 454
455use foo::Debug;
456
454impl Debug for Foo { 457impl Debug for Foo {
455} 458}
456", 459",
@@ -627,7 +630,7 @@ fn main() {
627} 630}
628 ", 631 ",
629 r" 632 r"
630use std::fmt::{self, Display}; 633use std::fmt::{Display, self};
631 634
632fn main() { 635fn main() {
633 fmt; 636 fmt;
@@ -647,9 +650,8 @@ impl std::io<|> for Foo {
647} 650}
648 ", 651 ",
649 r" 652 r"
650use std::io;
651
652pub use std::fmt; 653pub use std::fmt;
654use std::io;
653 655
654impl io for Foo { 656impl io for Foo {
655} 657}
@@ -668,9 +670,8 @@ impl std::io<|> for Foo {
668} 670}
669 ", 671 ",
670 r" 672 r"
671use std::io;
672
673pub(crate) use std::fmt; 673pub(crate) use std::fmt;
674use std::io;
674 675
675impl io for Foo { 676impl io for Foo {
676} 677}
diff --git a/crates/assists/src/utils/insert_use.rs b/crates/assists/src/utils/insert_use.rs
index 030a5a935..f2acda6f3 100644
--- a/crates/assists/src/utils/insert_use.rs
+++ b/crates/assists/src/utils/insert_use.rs
@@ -18,9 +18,10 @@ pub(crate) fn find_insert_use_container(
18) -> Option<Either<ast::ItemList, ast::SourceFile>> { 18) -> Option<Either<ast::ItemList, ast::SourceFile>> {
19 ctx.sema.ancestors_with_macros(position.clone()).find_map(|n| { 19 ctx.sema.ancestors_with_macros(position.clone()).find_map(|n| {
20 if let Some(module) = ast::Module::cast(n.clone()) { 20 if let Some(module) = ast::Module::cast(n.clone()) {
21 return module.item_list().map(Either::Left); 21 module.item_list().map(Either::Left)
22 } else {
23 Some(Either::Right(ast::SourceFile::cast(n)?))
22 } 24 }
23 Some(Either::Right(ast::SourceFile::cast(n)?))
24 }) 25 })
25} 26}
26 27
@@ -92,6 +93,7 @@ fn use_tree_list_is_nested(tl: &ast::UseTreeList) -> bool {
92 }) 93 })
93} 94}
94 95
96// FIXME: currently this merely prepends the new tree into old, ideally it would insert the items in a sorted fashion
95pub fn try_merge_trees( 97pub fn try_merge_trees(
96 old: &ast::UseTree, 98 old: &ast::UseTree,
97 new: &ast::UseTree, 99 new: &ast::UseTree,
@@ -486,7 +488,7 @@ use std::io;",
486 check_full( 488 check_full(
487 "std::foo::bar::Baz", 489 "std::foo::bar::Baz",
488 r"use std::foo::bar::Qux;", 490 r"use std::foo::bar::Qux;",
489 r"use std::foo::bar::{Baz, Qux};", 491 r"use std::foo::bar::{Qux, Baz};",
490 ) 492 )
491 } 493 }
492 494
@@ -495,7 +497,7 @@ use std::io;",
495 check_last( 497 check_last(
496 "std::foo::bar::Baz", 498 "std::foo::bar::Baz",
497 r"use std::foo::bar::Qux;", 499 r"use std::foo::bar::Qux;",
498 r"use std::foo::bar::{Baz, Qux};", 500 r"use std::foo::bar::{Qux, Baz};",
499 ) 501 )
500 } 502 }
501 503
@@ -504,7 +506,7 @@ use std::io;",
504 check_full( 506 check_full(
505 "std::foo::bar::Baz", 507 "std::foo::bar::Baz",
506 r"use std::foo::bar::{Qux, Quux};", 508 r"use std::foo::bar::{Qux, Quux};",
507 r"use std::foo::bar::{Baz, Quux, Qux};", 509 r"use std::foo::bar::{Qux, Quux, Baz};",
508 ) 510 )
509 } 511 }
510 512
@@ -513,7 +515,7 @@ use std::io;",
513 check_last( 515 check_last(
514 "std::foo::bar::Baz", 516 "std::foo::bar::Baz",
515 r"use std::foo::bar::{Qux, Quux};", 517 r"use std::foo::bar::{Qux, Quux};",
516 r"use std::foo::bar::{Baz, Quux, Qux};", 518 r"use std::foo::bar::{Qux, Quux, Baz};",
517 ) 519 )
518 } 520 }
519 521
@@ -522,7 +524,7 @@ use std::io;",
522 check_full( 524 check_full(
523 "std::foo::bar::Baz", 525 "std::foo::bar::Baz",
524 r"use std::foo::bar::{Qux, quux::{Fez, Fizz}};", 526 r"use std::foo::bar::{Qux, quux::{Fez, Fizz}};",
525 r"use std::foo::bar::{Baz, quux::{Fez, Fizz}, Qux};", 527 r"use std::foo::bar::{Qux, quux::{Fez, Fizz}, Baz};",
526 ) 528 )
527 } 529 }
528 530
@@ -532,7 +534,7 @@ use std::io;",
532 "std::foo::bar::Baz", 534 "std::foo::bar::Baz",
533 r"use std::foo::bar::{Qux, quux::{Fez, Fizz}};", 535 r"use std::foo::bar::{Qux, quux::{Fez, Fizz}};",
534 r"use std::foo::bar::Baz; 536 r"use std::foo::bar::Baz;
535use std::foo::bar::{quux::{Fez, Fizz}, Qux};", 537use std::foo::bar::{Qux, quux::{Fez, Fizz}};",
536 ) 538 )
537 } 539 }
538 540