diff options
Diffstat (limited to 'crates/assists/src')
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 | ||
15 | use crate::{ | 15 | use crate::{ |
16 | utils::insert_use_statement, AssistContext, AssistId, AssistKind, Assists, GroupLabel, | 16 | utils::{insert_use, MergeBehaviour}, |
17 | AssistContext, AssistId, AssistKind, Assists, GroupLabel, | ||
17 | }; | 18 | }; |
19 | use ast::make; | ||
20 | use 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 | ||
12 | use crate::{ | 12 | use 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 | }; |
17 | use ast::make; | ||
18 | use 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 | |||
2 | use test_utils::mark; | 2 | use test_utils::mark; |
3 | 3 | ||
4 | use crate::{ | 4 | use 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 | }; |
8 | use 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" |
223 | use stdx; | ||
224 | use std::fmt::Debug; | 220 | use std::fmt::Debug; |
225 | 221 | ||
222 | use stdx; | ||
223 | |||
226 | impl Debug for Foo { | 224 | impl Debug for Foo { |
227 | } | 225 | } |
228 | ", | 226 | ", |
@@ -274,7 +272,7 @@ impl std::io<|> for Foo { | |||
274 | } | 272 | } |
275 | ", | 273 | ", |
276 | r" | 274 | r" |
277 | use std::{io, fmt}; | 275 | use std::{fmt, io}; |
278 | 276 | ||
279 | impl io for Foo { | 277 | impl io for Foo { |
280 | } | 278 | } |
@@ -293,7 +291,7 @@ impl std::fmt::Debug<|> for Foo { | |||
293 | } | 291 | } |
294 | ", | 292 | ", |
295 | r" | 293 | r" |
296 | use std::fmt::{self, Debug, }; | 294 | use std::fmt::{self, Debug}; |
297 | 295 | ||
298 | impl Debug for Foo { | 296 | impl Debug for Foo { |
299 | } | 297 | } |
@@ -312,7 +310,7 @@ impl std::fmt<|> for Foo { | |||
312 | } | 310 | } |
313 | ", | 311 | ", |
314 | r" | 312 | r" |
315 | use std::fmt::{self, Debug}; | 313 | use std::fmt::{Debug, self}; |
316 | 314 | ||
317 | impl fmt for Foo { | 315 | impl fmt for Foo { |
318 | } | 316 | } |
@@ -330,8 +328,9 @@ use std::fmt::{Debug, nested::{Display}}; | |||
330 | impl std::fmt::nested<|> for Foo { | 328 | impl std::fmt::nested<|> for Foo { |
331 | } | 329 | } |
332 | ", | 330 | ", |
331 | // FIXME(veykril): should be nested::{self, Display} here | ||
333 | r" | 332 | r" |
334 | use std::fmt::{Debug, nested::{Display, self}}; | 333 | use std::fmt::{Debug, nested::{Display}, nested}; |
335 | 334 | ||
336 | impl nested for Foo { | 335 | impl nested for Foo { |
337 | } | 336 | } |
@@ -349,8 +348,9 @@ use std::fmt::{Debug, nested::{self, Display}}; | |||
349 | impl std::fmt::nested<|> for Foo { | 348 | impl 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" |
353 | use std::fmt::{Debug, nested::{self, Display}}; | 353 | use std::fmt::{Debug, nested::{Display}, nested}; |
354 | 354 | ||
355 | impl nested for Foo { | 355 | impl nested for Foo { |
356 | } | 356 | } |
@@ -369,7 +369,7 @@ impl std::fmt::nested::Debug<|> for Foo { | |||
369 | } | 369 | } |
370 | ", | 370 | ", |
371 | r" | 371 | r" |
372 | use std::fmt::{Debug, nested::{Display, Debug}}; | 372 | use std::fmt::{Debug, nested::{Display}, nested::Debug}; |
373 | 373 | ||
374 | impl Debug for Foo { | 374 | impl Debug for Foo { |
375 | } | 375 | } |
@@ -388,7 +388,7 @@ impl std::fmt::nested::Display<|> for Foo { | |||
388 | } | 388 | } |
389 | ", | 389 | ", |
390 | r" | 390 | r" |
391 | use std::fmt::{nested::Display, Debug}; | 391 | use std::fmt::{Debug, nested::Display}; |
392 | 392 | ||
393 | impl Display for Foo { | 393 | impl Display for Foo { |
394 | } | 394 | } |
@@ -407,7 +407,7 @@ impl std::fmt::Display<|> for Foo { | |||
407 | } | 407 | } |
408 | ", | 408 | ", |
409 | r" | 409 | r" |
410 | use std::fmt::{Display, nested::Debug}; | 410 | use std::fmt::{nested::Debug, Display}; |
411 | 411 | ||
412 | impl Display for Foo { | 412 | impl Display for Foo { |
413 | } | 413 | } |
@@ -427,11 +427,12 @@ use crate::{ | |||
427 | 427 | ||
428 | fn foo() { crate::ty::lower<|>::trait_env() } | 428 | fn foo() { crate::ty::lower<|>::trait_env() } |
429 | ", | 429 | ", |
430 | // FIXME(veykril): formatting broke here | ||
430 | r" | 431 | r" |
431 | use crate::{ | 432 | use crate::{ |
432 | ty::{Substs, Ty, lower}, | 433 | ty::{Substs, Ty}, |
433 | AssocItem, | 434 | AssocItem, |
434 | }; | 435 | ty::lower}; |
435 | 436 | ||
436 | fn foo() { lower::trait_env() } | 437 | fn foo() { lower::trait_env() } |
437 | ", | 438 | ", |
@@ -451,6 +452,8 @@ impl foo::Debug<|> for Foo { | |||
451 | r" | 452 | r" |
452 | use std::fmt as foo; | 453 | use std::fmt as foo; |
453 | 454 | ||
455 | use foo::Debug; | ||
456 | |||
454 | impl Debug for Foo { | 457 | impl Debug for Foo { |
455 | } | 458 | } |
456 | ", | 459 | ", |
@@ -627,7 +630,7 @@ fn main() { | |||
627 | } | 630 | } |
628 | ", | 631 | ", |
629 | r" | 632 | r" |
630 | use std::fmt::{self, Display}; | 633 | use std::fmt::{Display, self}; |
631 | 634 | ||
632 | fn main() { | 635 | fn main() { |
633 | fmt; | 636 | fmt; |
@@ -647,9 +650,8 @@ impl std::io<|> for Foo { | |||
647 | } | 650 | } |
648 | ", | 651 | ", |
649 | r" | 652 | r" |
650 | use std::io; | ||
651 | |||
652 | pub use std::fmt; | 653 | pub use std::fmt; |
654 | use std::io; | ||
653 | 655 | ||
654 | impl io for Foo { | 656 | impl io for Foo { |
655 | } | 657 | } |
@@ -668,9 +670,8 @@ impl std::io<|> for Foo { | |||
668 | } | 670 | } |
669 | ", | 671 | ", |
670 | r" | 672 | r" |
671 | use std::io; | ||
672 | |||
673 | pub(crate) use std::fmt; | 673 | pub(crate) use std::fmt; |
674 | use std::io; | ||
674 | 675 | ||
675 | impl io for Foo { | 676 | impl 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 | ||
95 | pub fn try_merge_trees( | 97 | pub 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; |
535 | use std::foo::bar::{quux::{Fez, Fizz}, Qux};", | 537 | use std::foo::bar::{Qux, quux::{Fez, Fizz}};", |
536 | ) | 538 | ) |
537 | } | 539 | } |
538 | 540 | ||