aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_assists/src
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2020-07-03 18:32:44 +0100
committerGitHub <[email protected]>2020-07-03 18:32:44 +0100
commita095cdb87912e0174341121542af2d4a01d7d8cd (patch)
tree3e2e02e862af35b6e0e6f859eb22c1b32938d958 /crates/ra_assists/src
parenta434ecef51bc8cf20b626267ef90c2887aa5116a (diff)
parentd09f6923009943cee1b24571c2905c3c0bfb49c7 (diff)
Merge #5213
5213: Add AssistKind::Generate r=matklad a=matklad bors r+ 🤖 Co-authored-by: Aleksey Kladov <[email protected]>
Diffstat (limited to 'crates/ra_assists/src')
-rw-r--r--crates/ra_assists/src/handlers/generate_derive.rs (renamed from crates/ra_assists/src/handlers/add_derive.rs)61
-rw-r--r--crates/ra_assists/src/handlers/generate_from_impl_for_enum.rs (renamed from crates/ra_assists/src/handlers/add_from_impl_for_enum.rs)20
-rw-r--r--crates/ra_assists/src/handlers/generate_function.rs (renamed from crates/ra_assists/src/handlers/add_function.rs)85
-rw-r--r--crates/ra_assists/src/handlers/generate_impl.rs (renamed from crates/ra_assists/src/handlers/add_impl.rs)20
-rw-r--r--crates/ra_assists/src/handlers/generate_new.rs (renamed from crates/ra_assists/src/handlers/add_new.rs)42
-rw-r--r--crates/ra_assists/src/lib.rs21
-rw-r--r--crates/ra_assists/src/tests/generated.rs218
7 files changed, 241 insertions, 226 deletions
diff --git a/crates/ra_assists/src/handlers/add_derive.rs b/crates/ra_assists/src/handlers/generate_derive.rs
index e2b94e7f8..6ccf39900 100644
--- a/crates/ra_assists/src/handlers/add_derive.rs
+++ b/crates/ra_assists/src/handlers/generate_derive.rs
@@ -6,7 +6,7 @@ use ra_syntax::{
6 6
7use crate::{AssistContext, AssistId, AssistKind, Assists}; 7use crate::{AssistContext, AssistId, AssistKind, Assists};
8 8
9// Assist: add_derive 9// Assist: generate_derive
10// 10//
11// Adds a new `#[derive()]` clause to a struct or enum. 11// Adds a new `#[derive()]` clause to a struct or enum.
12// 12//
@@ -24,32 +24,37 @@ use crate::{AssistContext, AssistId, AssistKind, Assists};
24// y: u32, 24// y: u32,
25// } 25// }
26// ``` 26// ```
27pub(crate) fn add_derive(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { 27pub(crate) fn generate_derive(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
28 let cap = ctx.config.snippet_cap?; 28 let cap = ctx.config.snippet_cap?;
29 let nominal = ctx.find_node_at_offset::<ast::NominalDef>()?; 29 let nominal = ctx.find_node_at_offset::<ast::NominalDef>()?;
30 let node_start = derive_insertion_offset(&nominal)?; 30 let node_start = derive_insertion_offset(&nominal)?;
31 let target = nominal.syntax().text_range(); 31 let target = nominal.syntax().text_range();
32 acc.add(AssistId("add_derive", AssistKind::None), "Add `#[derive]`", target, |builder| { 32 acc.add(
33 let derive_attr = nominal 33 AssistId("generate_derive", AssistKind::Generate),
34 .attrs() 34 "Add `#[derive]`",
35 .filter_map(|x| x.as_simple_call()) 35 target,
36 .filter(|(name, _arg)| name == "derive") 36 |builder| {
37 .map(|(_name, arg)| arg) 37 let derive_attr = nominal
38 .next(); 38 .attrs()
39 match derive_attr { 39 .filter_map(|x| x.as_simple_call())
40 None => { 40 .filter(|(name, _arg)| name == "derive")
41 builder.insert_snippet(cap, node_start, "#[derive($0)]\n"); 41 .map(|(_name, arg)| arg)
42 } 42 .next();
43 Some(tt) => { 43 match derive_attr {
44 // Just move the cursor. 44 None => {
45 builder.insert_snippet( 45 builder.insert_snippet(cap, node_start, "#[derive($0)]\n");
46 cap, 46 }
47 tt.syntax().text_range().end() - TextSize::of(')'), 47 Some(tt) => {
48 "$0", 48 // Just move the cursor.
49 ) 49 builder.insert_snippet(
50 } 50 cap,
51 }; 51 tt.syntax().text_range().end() - TextSize::of(')'),
52 }) 52 "$0",
53 )
54 }
55 };
56 },
57 )
53} 58}
54 59
55// Insert `derive` after doc comments. 60// Insert `derive` after doc comments.
@@ -70,12 +75,12 @@ mod tests {
70 #[test] 75 #[test]
71 fn add_derive_new() { 76 fn add_derive_new() {
72 check_assist( 77 check_assist(
73 add_derive, 78 generate_derive,
74 "struct Foo { a: i32, <|>}", 79 "struct Foo { a: i32, <|>}",
75 "#[derive($0)]\nstruct Foo { a: i32, }", 80 "#[derive($0)]\nstruct Foo { a: i32, }",
76 ); 81 );
77 check_assist( 82 check_assist(
78 add_derive, 83 generate_derive,
79 "struct Foo { <|> a: i32, }", 84 "struct Foo { <|> a: i32, }",
80 "#[derive($0)]\nstruct Foo { a: i32, }", 85 "#[derive($0)]\nstruct Foo { a: i32, }",
81 ); 86 );
@@ -84,7 +89,7 @@ mod tests {
84 #[test] 89 #[test]
85 fn add_derive_existing() { 90 fn add_derive_existing() {
86 check_assist( 91 check_assist(
87 add_derive, 92 generate_derive,
88 "#[derive(Clone)]\nstruct Foo { a: i32<|>, }", 93 "#[derive(Clone)]\nstruct Foo { a: i32<|>, }",
89 "#[derive(Clone$0)]\nstruct Foo { a: i32, }", 94 "#[derive(Clone$0)]\nstruct Foo { a: i32, }",
90 ); 95 );
@@ -93,7 +98,7 @@ mod tests {
93 #[test] 98 #[test]
94 fn add_derive_new_with_doc_comment() { 99 fn add_derive_new_with_doc_comment() {
95 check_assist( 100 check_assist(
96 add_derive, 101 generate_derive,
97 " 102 "
98/// `Foo` is a pretty important struct. 103/// `Foo` is a pretty important struct.
99/// It does stuff. 104/// It does stuff.
@@ -111,7 +116,7 @@ struct Foo { a: i32, }
111 #[test] 116 #[test]
112 fn add_derive_target() { 117 fn add_derive_target() {
113 check_assist_target( 118 check_assist_target(
114 add_derive, 119 generate_derive,
115 " 120 "
116struct SomeThingIrrelevant; 121struct SomeThingIrrelevant;
117/// `Foo` is a pretty important struct. 122/// `Foo` is a pretty important struct.
diff --git a/crates/ra_assists/src/handlers/add_from_impl_for_enum.rs b/crates/ra_assists/src/handlers/generate_from_impl_for_enum.rs
index a324670ed..a347e3c2e 100644
--- a/crates/ra_assists/src/handlers/add_from_impl_for_enum.rs
+++ b/crates/ra_assists/src/handlers/generate_from_impl_for_enum.rs
@@ -4,7 +4,7 @@ use test_utils::mark;
4 4
5use crate::{utils::FamousDefs, AssistContext, AssistId, AssistKind, Assists}; 5use crate::{utils::FamousDefs, AssistContext, AssistId, AssistKind, Assists};
6 6
7// Assist: add_from_impl_for_enum 7// Assist: generate_from_impl_for_enum
8// 8//
9// Adds a From impl for an enum variant with one tuple field. 9// Adds a From impl for an enum variant with one tuple field.
10// 10//
@@ -21,7 +21,7 @@ use crate::{utils::FamousDefs, AssistContext, AssistId, AssistKind, Assists};
21// } 21// }
22// } 22// }
23// ``` 23// ```
24pub(crate) fn add_from_impl_for_enum(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { 24pub(crate) fn generate_from_impl_for_enum(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
25 let variant = ctx.find_node_at_offset::<ast::EnumVariant>()?; 25 let variant = ctx.find_node_at_offset::<ast::EnumVariant>()?;
26 let variant_name = variant.name()?; 26 let variant_name = variant.name()?;
27 let enum_name = variant.parent_enum().name()?; 27 let enum_name = variant.parent_enum().name()?;
@@ -45,8 +45,8 @@ pub(crate) fn add_from_impl_for_enum(acc: &mut Assists, ctx: &AssistContext) ->
45 45
46 let target = variant.syntax().text_range(); 46 let target = variant.syntax().text_range();
47 acc.add( 47 acc.add(
48 AssistId("add_from_impl_for_enum", AssistKind::Refactor), 48 AssistId("generate_from_impl_for_enum", AssistKind::Generate),
49 "Add From impl for this enum variant", 49 "Generate `From` impl for this enum variant",
50 target, 50 target,
51 |edit| { 51 |edit| {
52 let start_offset = variant.parent_enum().syntax().text_range().end(); 52 let start_offset = variant.parent_enum().syntax().text_range().end();
@@ -97,9 +97,9 @@ mod tests {
97 use super::*; 97 use super::*;
98 98
99 #[test] 99 #[test]
100 fn test_add_from_impl_for_enum() { 100 fn test_generate_from_impl_for_enum() {
101 check_assist( 101 check_assist(
102 add_from_impl_for_enum, 102 generate_from_impl_for_enum,
103 "enum A { <|>One(u32) }", 103 "enum A { <|>One(u32) }",
104 r#"enum A { One(u32) } 104 r#"enum A { One(u32) }
105 105
@@ -112,9 +112,9 @@ impl From<u32> for A {
112 } 112 }
113 113
114 #[test] 114 #[test]
115 fn test_add_from_impl_for_enum_complicated_path() { 115 fn test_generate_from_impl_for_enum_complicated_path() {
116 check_assist( 116 check_assist(
117 add_from_impl_for_enum, 117 generate_from_impl_for_enum,
118 r#"enum A { <|>One(foo::bar::baz::Boo) }"#, 118 r#"enum A { <|>One(foo::bar::baz::Boo) }"#,
119 r#"enum A { One(foo::bar::baz::Boo) } 119 r#"enum A { One(foo::bar::baz::Boo) }
120 120
@@ -129,7 +129,7 @@ impl From<foo::bar::baz::Boo> for A {
129 fn check_not_applicable(ra_fixture: &str) { 129 fn check_not_applicable(ra_fixture: &str) {
130 let fixture = 130 let fixture =
131 format!("//- /main.rs crate:main deps:core\n{}\n{}", ra_fixture, FamousDefs::FIXTURE); 131 format!("//- /main.rs crate:main deps:core\n{}\n{}", ra_fixture, FamousDefs::FIXTURE);
132 check_assist_not_applicable(add_from_impl_for_enum, &fixture) 132 check_assist_not_applicable(generate_from_impl_for_enum, &fixture)
133 } 133 }
134 134
135 #[test] 135 #[test]
@@ -166,7 +166,7 @@ impl From<u32> for A {
166 #[test] 166 #[test]
167 fn test_add_from_impl_different_variant_impl_exists() { 167 fn test_add_from_impl_different_variant_impl_exists() {
168 check_assist( 168 check_assist(
169 add_from_impl_for_enum, 169 generate_from_impl_for_enum,
170 r#"enum A { <|>One(u32), Two(String), } 170 r#"enum A { <|>One(u32), Two(String), }
171 171
172impl From<String> for A { 172impl From<String> for A {
diff --git a/crates/ra_assists/src/handlers/add_function.rs b/crates/ra_assists/src/handlers/generate_function.rs
index 7150eb53a..b721b96bb 100644
--- a/crates/ra_assists/src/handlers/add_function.rs
+++ b/crates/ra_assists/src/handlers/generate_function.rs
@@ -16,7 +16,7 @@ use crate::{
16 AssistContext, AssistId, AssistKind, Assists, 16 AssistContext, AssistId, AssistKind, Assists,
17}; 17};
18 18
19// Assist: add_function 19// Assist: generate_function
20// 20//
21// Adds a stub function with a signature matching the function under the cursor. 21// Adds a stub function with a signature matching the function under the cursor.
22// 22//
@@ -41,7 +41,7 @@ use crate::{
41// } 41// }
42// 42//
43// ``` 43// ```
44pub(crate) fn add_function(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { 44pub(crate) fn generate_function(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
45 let path_expr: ast::PathExpr = ctx.find_node_at_offset()?; 45 let path_expr: ast::PathExpr = ctx.find_node_at_offset()?;
46 let call = path_expr.syntax().parent().and_then(ast::CallExpr::cast)?; 46 let call = path_expr.syntax().parent().and_then(ast::CallExpr::cast)?;
47 let path = path_expr.path()?; 47 let path = path_expr.path()?;
@@ -62,15 +62,20 @@ pub(crate) fn add_function(acc: &mut Assists, ctx: &AssistContext) -> Option<()>
62 let function_builder = FunctionBuilder::from_call(&ctx, &call, &path, target_module)?; 62 let function_builder = FunctionBuilder::from_call(&ctx, &call, &path, target_module)?;
63 63
64 let target = call.syntax().text_range(); 64 let target = call.syntax().text_range();
65 acc.add(AssistId("add_function", AssistKind::None), "Add function", target, |builder| { 65 acc.add(
66 let function_template = function_builder.render(); 66 AssistId("generate_function", AssistKind::Generate),
67 builder.edit_file(function_template.file); 67 format!("Generate `{}` function", function_builder.fn_name),
68 let new_fn = function_template.to_string(ctx.config.snippet_cap); 68 target,
69 match ctx.config.snippet_cap { 69 |builder| {
70 Some(cap) => builder.insert_snippet(cap, function_template.insert_offset, new_fn), 70 let function_template = function_builder.render();
71 None => builder.insert(function_template.insert_offset, new_fn), 71 builder.edit_file(function_template.file);
72 } 72 let new_fn = function_template.to_string(ctx.config.snippet_cap);
73 }) 73 match ctx.config.snippet_cap {
74 Some(cap) => builder.insert_snippet(cap, function_template.insert_offset, new_fn),
75 None => builder.insert(function_template.insert_offset, new_fn),
76 }
77 },
78 )
74} 79}
75 80
76struct FunctionTemplate { 81struct FunctionTemplate {
@@ -333,7 +338,7 @@ mod tests {
333 #[test] 338 #[test]
334 fn add_function_with_no_args() { 339 fn add_function_with_no_args() {
335 check_assist( 340 check_assist(
336 add_function, 341 generate_function,
337 r" 342 r"
338fn foo() { 343fn foo() {
339 bar<|>(); 344 bar<|>();
@@ -356,7 +361,7 @@ fn bar() {
356 // This ensures that the function is correctly generated 361 // This ensures that the function is correctly generated
357 // in the next outer mod or file 362 // in the next outer mod or file
358 check_assist( 363 check_assist(
359 add_function, 364 generate_function,
360 r" 365 r"
361impl Foo { 366impl Foo {
362 fn foo() { 367 fn foo() {
@@ -382,7 +387,7 @@ fn bar() {
382 fn add_function_directly_after_current_block() { 387 fn add_function_directly_after_current_block() {
383 // The new fn should not be created at the end of the file or module 388 // The new fn should not be created at the end of the file or module
384 check_assist( 389 check_assist(
385 add_function, 390 generate_function,
386 r" 391 r"
387fn foo1() { 392fn foo1() {
388 bar<|>(); 393 bar<|>();
@@ -407,7 +412,7 @@ fn foo2() {}
407 #[test] 412 #[test]
408 fn add_function_with_no_args_in_same_module() { 413 fn add_function_with_no_args_in_same_module() {
409 check_assist( 414 check_assist(
410 add_function, 415 generate_function,
411 r" 416 r"
412mod baz { 417mod baz {
413 fn foo() { 418 fn foo() {
@@ -432,7 +437,7 @@ mod baz {
432 #[test] 437 #[test]
433 fn add_function_with_function_call_arg() { 438 fn add_function_with_function_call_arg() {
434 check_assist( 439 check_assist(
435 add_function, 440 generate_function,
436 r" 441 r"
437struct Baz; 442struct Baz;
438fn baz() -> Baz { todo!() } 443fn baz() -> Baz { todo!() }
@@ -457,7 +462,7 @@ fn bar(baz: Baz) {
457 #[test] 462 #[test]
458 fn add_function_with_method_call_arg() { 463 fn add_function_with_method_call_arg() {
459 check_assist( 464 check_assist(
460 add_function, 465 generate_function,
461 r" 466 r"
462struct Baz; 467struct Baz;
463impl Baz { 468impl Baz {
@@ -490,7 +495,7 @@ fn bar(baz: Baz) {
490 #[test] 495 #[test]
491 fn add_function_with_string_literal_arg() { 496 fn add_function_with_string_literal_arg() {
492 check_assist( 497 check_assist(
493 add_function, 498 generate_function,
494 r#" 499 r#"
495fn foo() { 500fn foo() {
496 <|>bar("bar") 501 <|>bar("bar")
@@ -511,7 +516,7 @@ fn bar(arg: &str) {
511 #[test] 516 #[test]
512 fn add_function_with_char_literal_arg() { 517 fn add_function_with_char_literal_arg() {
513 check_assist( 518 check_assist(
514 add_function, 519 generate_function,
515 r#" 520 r#"
516fn foo() { 521fn foo() {
517 <|>bar('x') 522 <|>bar('x')
@@ -532,7 +537,7 @@ fn bar(arg: char) {
532 #[test] 537 #[test]
533 fn add_function_with_int_literal_arg() { 538 fn add_function_with_int_literal_arg() {
534 check_assist( 539 check_assist(
535 add_function, 540 generate_function,
536 r" 541 r"
537fn foo() { 542fn foo() {
538 <|>bar(42) 543 <|>bar(42)
@@ -553,7 +558,7 @@ fn bar(arg: i32) {
553 #[test] 558 #[test]
554 fn add_function_with_cast_int_literal_arg() { 559 fn add_function_with_cast_int_literal_arg() {
555 check_assist( 560 check_assist(
556 add_function, 561 generate_function,
557 r" 562 r"
558fn foo() { 563fn foo() {
559 <|>bar(42 as u8) 564 <|>bar(42 as u8)
@@ -576,7 +581,7 @@ fn bar(arg: u8) {
576 // Ensures that the name of the cast type isn't used 581 // Ensures that the name of the cast type isn't used
577 // in the generated function signature. 582 // in the generated function signature.
578 check_assist( 583 check_assist(
579 add_function, 584 generate_function,
580 r" 585 r"
581fn foo() { 586fn foo() {
582 let x = 42; 587 let x = 42;
@@ -599,7 +604,7 @@ fn bar(x: u8) {
599 #[test] 604 #[test]
600 fn add_function_with_variable_arg() { 605 fn add_function_with_variable_arg() {
601 check_assist( 606 check_assist(
602 add_function, 607 generate_function,
603 r" 608 r"
604fn foo() { 609fn foo() {
605 let worble = (); 610 let worble = ();
@@ -622,7 +627,7 @@ fn bar(worble: ()) {
622 #[test] 627 #[test]
623 fn add_function_with_impl_trait_arg() { 628 fn add_function_with_impl_trait_arg() {
624 check_assist( 629 check_assist(
625 add_function, 630 generate_function,
626 r" 631 r"
627trait Foo {} 632trait Foo {}
628fn foo() -> impl Foo { 633fn foo() -> impl Foo {
@@ -651,7 +656,7 @@ fn bar(foo: impl Foo) {
651 #[test] 656 #[test]
652 fn borrowed_arg() { 657 fn borrowed_arg() {
653 check_assist( 658 check_assist(
654 add_function, 659 generate_function,
655 r" 660 r"
656struct Baz; 661struct Baz;
657fn baz() -> Baz { todo!() } 662fn baz() -> Baz { todo!() }
@@ -678,7 +683,7 @@ fn bar(baz: &Baz) {
678 #[test] 683 #[test]
679 fn add_function_with_qualified_path_arg() { 684 fn add_function_with_qualified_path_arg() {
680 check_assist( 685 check_assist(
681 add_function, 686 generate_function,
682 r" 687 r"
683mod Baz { 688mod Baz {
684 pub struct Bof; 689 pub struct Bof;
@@ -709,7 +714,7 @@ fn bar(baz: Baz::Bof) {
709 // FIXME fix printing the generics of a `Ty` to make this test pass 714 // FIXME fix printing the generics of a `Ty` to make this test pass
710 fn add_function_with_generic_arg() { 715 fn add_function_with_generic_arg() {
711 check_assist( 716 check_assist(
712 add_function, 717 generate_function,
713 r" 718 r"
714fn foo<T>(t: T) { 719fn foo<T>(t: T) {
715 <|>bar(t) 720 <|>bar(t)
@@ -732,7 +737,7 @@ fn bar<T>(t: T) {
732 // FIXME Fix function type printing to make this test pass 737 // FIXME Fix function type printing to make this test pass
733 fn add_function_with_fn_arg() { 738 fn add_function_with_fn_arg() {
734 check_assist( 739 check_assist(
735 add_function, 740 generate_function,
736 r" 741 r"
737struct Baz; 742struct Baz;
738impl Baz { 743impl Baz {
@@ -763,7 +768,7 @@ fn bar(arg: fn() -> Baz) {
763 // FIXME Fix closure type printing to make this test pass 768 // FIXME Fix closure type printing to make this test pass
764 fn add_function_with_closure_arg() { 769 fn add_function_with_closure_arg() {
765 check_assist( 770 check_assist(
766 add_function, 771 generate_function,
767 r" 772 r"
768fn foo() { 773fn foo() {
769 let closure = |x: i64| x - 1; 774 let closure = |x: i64| x - 1;
@@ -786,7 +791,7 @@ fn bar(closure: impl Fn(i64) -> i64) {
786 #[test] 791 #[test]
787 fn unresolveable_types_default_to_unit() { 792 fn unresolveable_types_default_to_unit() {
788 check_assist( 793 check_assist(
789 add_function, 794 generate_function,
790 r" 795 r"
791fn foo() { 796fn foo() {
792 <|>bar(baz) 797 <|>bar(baz)
@@ -807,7 +812,7 @@ fn bar(baz: ()) {
807 #[test] 812 #[test]
808 fn arg_names_dont_overlap() { 813 fn arg_names_dont_overlap() {
809 check_assist( 814 check_assist(
810 add_function, 815 generate_function,
811 r" 816 r"
812struct Baz; 817struct Baz;
813fn baz() -> Baz { Baz } 818fn baz() -> Baz { Baz }
@@ -832,7 +837,7 @@ fn bar(baz_1: Baz, baz_2: Baz) {
832 #[test] 837 #[test]
833 fn arg_name_counters_start_at_1_per_name() { 838 fn arg_name_counters_start_at_1_per_name() {
834 check_assist( 839 check_assist(
835 add_function, 840 generate_function,
836 r#" 841 r#"
837struct Baz; 842struct Baz;
838fn baz() -> Baz { Baz } 843fn baz() -> Baz { Baz }
@@ -857,7 +862,7 @@ fn bar(baz_1: Baz, baz_2: Baz, arg_1: &str, arg_2: &str) {
857 #[test] 862 #[test]
858 fn add_function_in_module() { 863 fn add_function_in_module() {
859 check_assist( 864 check_assist(
860 add_function, 865 generate_function,
861 r" 866 r"
862mod bar {} 867mod bar {}
863 868
@@ -885,7 +890,7 @@ fn foo() {
885 // See https://github.com/rust-analyzer/rust-analyzer/issues/1165 890 // See https://github.com/rust-analyzer/rust-analyzer/issues/1165
886 fn qualified_path_uses_correct_scope() { 891 fn qualified_path_uses_correct_scope() {
887 check_assist( 892 check_assist(
888 add_function, 893 generate_function,
889 " 894 "
890mod foo { 895mod foo {
891 pub struct Foo; 896 pub struct Foo;
@@ -916,7 +921,7 @@ fn baz(foo: foo::Foo) {
916 #[test] 921 #[test]
917 fn add_function_in_module_containing_other_items() { 922 fn add_function_in_module_containing_other_items() {
918 check_assist( 923 check_assist(
919 add_function, 924 generate_function,
920 r" 925 r"
921mod bar { 926mod bar {
922 fn something_else() {} 927 fn something_else() {}
@@ -945,7 +950,7 @@ fn foo() {
945 #[test] 950 #[test]
946 fn add_function_in_nested_module() { 951 fn add_function_in_nested_module() {
947 check_assist( 952 check_assist(
948 add_function, 953 generate_function,
949 r" 954 r"
950mod bar { 955mod bar {
951 mod baz {} 956 mod baz {}
@@ -974,7 +979,7 @@ fn foo() {
974 #[test] 979 #[test]
975 fn add_function_in_another_file() { 980 fn add_function_in_another_file() {
976 check_assist( 981 check_assist(
977 add_function, 982 generate_function,
978 r" 983 r"
979//- /main.rs 984//- /main.rs
980mod foo; 985mod foo;
@@ -996,7 +1001,7 @@ pub(crate) fn bar() {
996 #[test] 1001 #[test]
997 fn add_function_not_applicable_if_function_already_exists() { 1002 fn add_function_not_applicable_if_function_already_exists() {
998 check_assist_not_applicable( 1003 check_assist_not_applicable(
999 add_function, 1004 generate_function,
1000 r" 1005 r"
1001fn foo() { 1006fn foo() {
1002 bar<|>(); 1007 bar<|>();
@@ -1013,7 +1018,7 @@ fn bar() {}
1013 // bar is resolved, but baz isn't. 1018 // bar is resolved, but baz isn't.
1014 // The assist is only active if the cursor is on an unresolved path, 1019 // The assist is only active if the cursor is on an unresolved path,
1015 // but the assist should only be offered if the path is a function call. 1020 // but the assist should only be offered if the path is a function call.
1016 add_function, 1021 generate_function,
1017 r" 1022 r"
1018fn foo() { 1023fn foo() {
1019 bar(b<|>az); 1024 bar(b<|>az);
@@ -1028,7 +1033,7 @@ fn bar(baz: ()) {}
1028 #[ignore] 1033 #[ignore]
1029 fn create_method_with_no_args() { 1034 fn create_method_with_no_args() {
1030 check_assist( 1035 check_assist(
1031 add_function, 1036 generate_function,
1032 r" 1037 r"
1033struct Foo; 1038struct Foo;
1034impl Foo { 1039impl Foo {
diff --git a/crates/ra_assists/src/handlers/add_impl.rs b/crates/ra_assists/src/handlers/generate_impl.rs
index 2f603ef9c..cbbac1d7f 100644
--- a/crates/ra_assists/src/handlers/add_impl.rs
+++ b/crates/ra_assists/src/handlers/generate_impl.rs
@@ -3,7 +3,7 @@ use stdx::{format_to, SepBy};
3 3
4use crate::{AssistContext, AssistId, AssistKind, Assists}; 4use crate::{AssistContext, AssistId, AssistKind, Assists};
5 5
6// Assist: add_impl 6// Assist: generate_impl
7// 7//
8// Adds a new inherent impl for a type. 8// Adds a new inherent impl for a type.
9// 9//
@@ -22,13 +22,13 @@ use crate::{AssistContext, AssistId, AssistKind, Assists};
22// $0 22// $0
23// } 23// }
24// ``` 24// ```
25pub(crate) fn add_impl(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { 25pub(crate) fn generate_impl(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
26 let nominal = ctx.find_node_at_offset::<ast::NominalDef>()?; 26 let nominal = ctx.find_node_at_offset::<ast::NominalDef>()?;
27 let name = nominal.name()?; 27 let name = nominal.name()?;
28 let target = nominal.syntax().text_range(); 28 let target = nominal.syntax().text_range();
29 acc.add( 29 acc.add(
30 AssistId("add_impl", AssistKind::Refactor), 30 AssistId("generate_impl", AssistKind::Generate),
31 format!("Implement {}", name.text().as_str()), 31 format!("Generate impl for `{}`", name),
32 target, 32 target,
33 |edit| { 33 |edit| {
34 let type_params = nominal.type_param_list(); 34 let type_params = nominal.type_param_list();
@@ -75,14 +75,18 @@ mod tests {
75 75
76 #[test] 76 #[test]
77 fn test_add_impl() { 77 fn test_add_impl() {
78 check_assist(add_impl, "struct Foo {<|>}\n", "struct Foo {}\n\nimpl Foo {\n $0\n}\n");
79 check_assist( 78 check_assist(
80 add_impl, 79 generate_impl,
80 "struct Foo {<|>}\n",
81 "struct Foo {}\n\nimpl Foo {\n $0\n}\n",
82 );
83 check_assist(
84 generate_impl,
81 "struct Foo<T: Clone> {<|>}", 85 "struct Foo<T: Clone> {<|>}",
82 "struct Foo<T: Clone> {}\n\nimpl<T: Clone> Foo<T> {\n $0\n}", 86 "struct Foo<T: Clone> {}\n\nimpl<T: Clone> Foo<T> {\n $0\n}",
83 ); 87 );
84 check_assist( 88 check_assist(
85 add_impl, 89 generate_impl,
86 "struct Foo<'a, T: Foo<'a>> {<|>}", 90 "struct Foo<'a, T: Foo<'a>> {<|>}",
87 "struct Foo<'a, T: Foo<'a>> {}\n\nimpl<'a, T: Foo<'a>> Foo<'a, T> {\n $0\n}", 91 "struct Foo<'a, T: Foo<'a>> {}\n\nimpl<'a, T: Foo<'a>> Foo<'a, T> {\n $0\n}",
88 ); 92 );
@@ -91,7 +95,7 @@ mod tests {
91 #[test] 95 #[test]
92 fn add_impl_target() { 96 fn add_impl_target() {
93 check_assist_target( 97 check_assist_target(
94 add_impl, 98 generate_impl,
95 " 99 "
96struct SomeThingIrrelevant; 100struct SomeThingIrrelevant;
97/// Has a lifetime parameter 101/// Has a lifetime parameter
diff --git a/crates/ra_assists/src/handlers/add_new.rs b/crates/ra_assists/src/handlers/generate_new.rs
index 0b3d29c7c..e27def1d8 100644
--- a/crates/ra_assists/src/handlers/add_new.rs
+++ b/crates/ra_assists/src/handlers/generate_new.rs
@@ -9,7 +9,7 @@ use stdx::{format_to, SepBy};
9 9
10use crate::{AssistContext, AssistId, AssistKind, Assists}; 10use crate::{AssistContext, AssistId, AssistKind, Assists};
11 11
12// Assist: add_new 12// Assist: generate_new
13// 13//
14// Adds a new inherent impl for a type. 14// Adds a new inherent impl for a type.
15// 15//
@@ -29,7 +29,7 @@ use crate::{AssistContext, AssistId, AssistKind, Assists};
29// } 29// }
30// 30//
31// ``` 31// ```
32pub(crate) fn add_new(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { 32pub(crate) fn generate_new(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
33 let strukt = ctx.find_node_at_offset::<ast::StructDef>()?; 33 let strukt = ctx.find_node_at_offset::<ast::StructDef>()?;
34 34
35 // We want to only apply this to non-union structs with named fields 35 // We want to only apply this to non-union structs with named fields
@@ -42,7 +42,7 @@ pub(crate) fn add_new(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
42 let impl_def = find_struct_impl(&ctx, &strukt)?; 42 let impl_def = find_struct_impl(&ctx, &strukt)?;
43 43
44 let target = strukt.syntax().text_range(); 44 let target = strukt.syntax().text_range();
45 acc.add(AssistId("add_new", AssistKind::None), "Add default constructor", target, |builder| { 45 acc.add(AssistId("generate_new", AssistKind::Generate), "Generate `new`", target, |builder| {
46 let mut buf = String::with_capacity(512); 46 let mut buf = String::with_capacity(512);
47 47
48 if impl_def.is_some() { 48 if impl_def.is_some() {
@@ -181,10 +181,10 @@ mod tests {
181 181
182 #[test] 182 #[test]
183 #[rustfmt::skip] 183 #[rustfmt::skip]
184 fn test_add_new() { 184 fn test_generate_new() {
185 // Check output of generation 185 // Check output of generation
186 check_assist( 186 check_assist(
187 add_new, 187 generate_new,
188"struct Foo {<|>}", 188"struct Foo {<|>}",
189"struct Foo {} 189"struct Foo {}
190 190
@@ -194,7 +194,7 @@ impl Foo {
194", 194",
195 ); 195 );
196 check_assist( 196 check_assist(
197 add_new, 197 generate_new,
198"struct Foo<T: Clone> {<|>}", 198"struct Foo<T: Clone> {<|>}",
199"struct Foo<T: Clone> {} 199"struct Foo<T: Clone> {}
200 200
@@ -204,7 +204,7 @@ impl<T: Clone> Foo<T> {
204", 204",
205 ); 205 );
206 check_assist( 206 check_assist(
207 add_new, 207 generate_new,
208"struct Foo<'a, T: Foo<'a>> {<|>}", 208"struct Foo<'a, T: Foo<'a>> {<|>}",
209"struct Foo<'a, T: Foo<'a>> {} 209"struct Foo<'a, T: Foo<'a>> {}
210 210
@@ -214,7 +214,7 @@ impl<'a, T: Foo<'a>> Foo<'a, T> {
214", 214",
215 ); 215 );
216 check_assist( 216 check_assist(
217 add_new, 217 generate_new,
218"struct Foo { baz: String <|>}", 218"struct Foo { baz: String <|>}",
219"struct Foo { baz: String } 219"struct Foo { baz: String }
220 220
@@ -224,7 +224,7 @@ impl Foo {
224", 224",
225 ); 225 );
226 check_assist( 226 check_assist(
227 add_new, 227 generate_new,
228"struct Foo { baz: String, qux: Vec<i32> <|>}", 228"struct Foo { baz: String, qux: Vec<i32> <|>}",
229"struct Foo { baz: String, qux: Vec<i32> } 229"struct Foo { baz: String, qux: Vec<i32> }
230 230
@@ -236,7 +236,7 @@ impl Foo {
236 236
237 // Check that visibility modifiers don't get brought in for fields 237 // Check that visibility modifiers don't get brought in for fields
238 check_assist( 238 check_assist(
239 add_new, 239 generate_new,
240"struct Foo { pub baz: String, pub qux: Vec<i32> <|>}", 240"struct Foo { pub baz: String, pub qux: Vec<i32> <|>}",
241"struct Foo { pub baz: String, pub qux: Vec<i32> } 241"struct Foo { pub baz: String, pub qux: Vec<i32> }
242 242
@@ -248,7 +248,7 @@ impl Foo {
248 248
249 // Check that it reuses existing impls 249 // Check that it reuses existing impls
250 check_assist( 250 check_assist(
251 add_new, 251 generate_new,
252"struct Foo {<|>} 252"struct Foo {<|>}
253 253
254impl Foo {} 254impl Foo {}
@@ -261,7 +261,7 @@ impl Foo {
261", 261",
262 ); 262 );
263 check_assist( 263 check_assist(
264 add_new, 264 generate_new,
265"struct Foo {<|>} 265"struct Foo {<|>}
266 266
267impl Foo { 267impl Foo {
@@ -279,7 +279,7 @@ impl Foo {
279 ); 279 );
280 280
281 check_assist( 281 check_assist(
282 add_new, 282 generate_new,
283"struct Foo {<|>} 283"struct Foo {<|>}
284 284
285impl Foo { 285impl Foo {
@@ -304,7 +304,7 @@ impl Foo {
304 304
305 // Check visibility of new fn based on struct 305 // Check visibility of new fn based on struct
306 check_assist( 306 check_assist(
307 add_new, 307 generate_new,
308"pub struct Foo {<|>}", 308"pub struct Foo {<|>}",
309"pub struct Foo {} 309"pub struct Foo {}
310 310
@@ -314,7 +314,7 @@ impl Foo {
314", 314",
315 ); 315 );
316 check_assist( 316 check_assist(
317 add_new, 317 generate_new,
318"pub(crate) struct Foo {<|>}", 318"pub(crate) struct Foo {<|>}",
319"pub(crate) struct Foo {} 319"pub(crate) struct Foo {}
320 320
@@ -326,9 +326,9 @@ impl Foo {
326 } 326 }
327 327
328 #[test] 328 #[test]
329 fn add_new_not_applicable_if_fn_exists() { 329 fn generate_new_not_applicable_if_fn_exists() {
330 check_assist_not_applicable( 330 check_assist_not_applicable(
331 add_new, 331 generate_new,
332 " 332 "
333struct Foo {<|>} 333struct Foo {<|>}
334 334
@@ -340,7 +340,7 @@ impl Foo {
340 ); 340 );
341 341
342 check_assist_not_applicable( 342 check_assist_not_applicable(
343 add_new, 343 generate_new,
344 " 344 "
345struct Foo {<|>} 345struct Foo {<|>}
346 346
@@ -353,9 +353,9 @@ impl Foo {
353 } 353 }
354 354
355 #[test] 355 #[test]
356 fn add_new_target() { 356 fn generate_new_target() {
357 check_assist_target( 357 check_assist_target(
358 add_new, 358 generate_new,
359 " 359 "
360struct SomeThingIrrelevant; 360struct SomeThingIrrelevant;
361/// Has a lifetime parameter 361/// Has a lifetime parameter
@@ -370,7 +370,7 @@ struct Foo<'a, T: Foo<'a>> {}",
370 #[test] 370 #[test]
371 fn test_unrelated_new() { 371 fn test_unrelated_new() {
372 check_assist( 372 check_assist(
373 add_new, 373 generate_new,
374 r##" 374 r##"
375pub struct AstId<N: AstNode> { 375pub struct AstId<N: AstNode> {
376 file_id: HirFileId, 376 file_id: HirFileId,
diff --git a/crates/ra_assists/src/lib.rs b/crates/ra_assists/src/lib.rs
index 65cda95ee..3d61fbded 100644
--- a/crates/ra_assists/src/lib.rs
+++ b/crates/ra_assists/src/lib.rs
@@ -30,6 +30,7 @@ pub use assist_config::AssistConfig;
30pub enum AssistKind { 30pub enum AssistKind {
31 None, 31 None,
32 QuickFix, 32 QuickFix,
33 Generate,
33 Refactor, 34 Refactor,
34 RefactorExtract, 35 RefactorExtract,
35 RefactorInline, 36 RefactorInline,
@@ -112,13 +113,8 @@ mod handlers {
112 pub(crate) type Handler = fn(&mut Assists, &AssistContext) -> Option<()>; 113 pub(crate) type Handler = fn(&mut Assists, &AssistContext) -> Option<()>;
113 114
114 mod add_custom_impl; 115 mod add_custom_impl;
115 mod add_derive;
116 mod add_explicit_type; 116 mod add_explicit_type;
117 mod add_from_impl_for_enum;
118 mod add_function;
119 mod add_impl;
120 mod add_missing_impl_members; 117 mod add_missing_impl_members;
121 mod add_new;
122 mod add_turbo_fish; 118 mod add_turbo_fish;
123 mod apply_demorgan; 119 mod apply_demorgan;
124 mod auto_import; 120 mod auto_import;
@@ -132,6 +128,11 @@ mod handlers {
132 mod flip_binexpr; 128 mod flip_binexpr;
133 mod flip_comma; 129 mod flip_comma;
134 mod flip_trait_bound; 130 mod flip_trait_bound;
131 mod generate_derive;
132 mod generate_from_impl_for_enum;
133 mod generate_function;
134 mod generate_impl;
135 mod generate_new;
135 mod inline_local_variable; 136 mod inline_local_variable;
136 mod introduce_named_lifetime; 137 mod introduce_named_lifetime;
137 mod invert_if; 138 mod invert_if;
@@ -154,12 +155,7 @@ mod handlers {
154 &[ 155 &[
155 // These are alphabetic for the foolish consistency 156 // These are alphabetic for the foolish consistency
156 add_custom_impl::add_custom_impl, 157 add_custom_impl::add_custom_impl,
157 add_derive::add_derive,
158 add_explicit_type::add_explicit_type, 158 add_explicit_type::add_explicit_type,
159 add_from_impl_for_enum::add_from_impl_for_enum,
160 add_function::add_function,
161 add_impl::add_impl,
162 add_new::add_new,
163 add_turbo_fish::add_turbo_fish, 159 add_turbo_fish::add_turbo_fish,
164 apply_demorgan::apply_demorgan, 160 apply_demorgan::apply_demorgan,
165 auto_import::auto_import, 161 auto_import::auto_import,
@@ -173,6 +169,11 @@ mod handlers {
173 flip_binexpr::flip_binexpr, 169 flip_binexpr::flip_binexpr,
174 flip_comma::flip_comma, 170 flip_comma::flip_comma,
175 flip_trait_bound::flip_trait_bound, 171 flip_trait_bound::flip_trait_bound,
172 generate_derive::generate_derive,
173 generate_from_impl_for_enum::generate_from_impl_for_enum,
174 generate_function::generate_function,
175 generate_impl::generate_impl,
176 generate_new::generate_new,
176 inline_local_variable::inline_local_variable, 177 inline_local_variable::inline_local_variable,
177 introduce_named_lifetime::introduce_named_lifetime, 178 introduce_named_lifetime::introduce_named_lifetime,
178 invert_if::invert_if, 179 invert_if::invert_if,
diff --git a/crates/ra_assists/src/tests/generated.rs b/crates/ra_assists/src/tests/generated.rs
index 31ea888c5..eff7feded 100644
--- a/crates/ra_assists/src/tests/generated.rs
+++ b/crates/ra_assists/src/tests/generated.rs
@@ -22,26 +22,6 @@ impl Debug for S {
22} 22}
23 23
24#[test] 24#[test]
25fn doctest_add_derive() {
26 check_doc_test(
27 "add_derive",
28 r#####"
29struct Point {
30 x: u32,
31 y: u32,<|>
32}
33"#####,
34 r#####"
35#[derive($0)]
36struct Point {
37 x: u32,
38 y: u32,
39}
40"#####,
41 )
42}
43
44#[test]
45fn doctest_add_explicit_type() { 25fn doctest_add_explicit_type() {
46 check_doc_test( 26 check_doc_test(
47 "add_explicit_type", 27 "add_explicit_type",
@@ -59,52 +39,6 @@ fn main() {
59} 39}
60 40
61#[test] 41#[test]
62fn doctest_add_from_impl_for_enum() {
63 check_doc_test(
64 "add_from_impl_for_enum",
65 r#####"
66enum A { <|>One(u32) }
67"#####,
68 r#####"
69enum A { One(u32) }
70
71impl From<u32> for A {
72 fn from(v: u32) -> Self {
73 A::One(v)
74 }
75}
76"#####,
77 )
78}
79
80#[test]
81fn doctest_add_function() {
82 check_doc_test(
83 "add_function",
84 r#####"
85struct Baz;
86fn baz() -> Baz { Baz }
87fn foo() {
88 bar<|>("", baz());
89}
90
91"#####,
92 r#####"
93struct Baz;
94fn baz() -> Baz { Baz }
95fn foo() {
96 bar("", baz());
97}
98
99fn bar(arg: &str, baz: Baz) {
100 ${0:todo!()}
101}
102
103"#####,
104 )
105}
106
107#[test]
108fn doctest_add_hash() { 42fn doctest_add_hash() {
109 check_doc_test( 43 check_doc_test(
110 "add_hash", 44 "add_hash",
@@ -122,27 +56,6 @@ fn main() {
122} 56}
123 57
124#[test] 58#[test]
125fn doctest_add_impl() {
126 check_doc_test(
127 "add_impl",
128 r#####"
129struct Ctx<T: Clone> {
130 data: T,<|>
131}
132"#####,
133 r#####"
134struct Ctx<T: Clone> {
135 data: T,
136}
137
138impl<T: Clone> Ctx<T> {
139 $0
140}
141"#####,
142 )
143}
144
145#[test]
146fn doctest_add_impl_default_members() { 59fn doctest_add_impl_default_members() {
147 check_doc_test( 60 check_doc_test(
148 "add_impl_default_members", 61 "add_impl_default_members",
@@ -209,28 +122,6 @@ impl Trait<u32> for () {
209} 122}
210 123
211#[test] 124#[test]
212fn doctest_add_new() {
213 check_doc_test(
214 "add_new",
215 r#####"
216struct Ctx<T: Clone> {
217 data: T,<|>
218}
219"#####,
220 r#####"
221struct Ctx<T: Clone> {
222 data: T,
223}
224
225impl<T: Clone> Ctx<T> {
226 fn $0new(data: T) -> Self { Self { data } }
227}
228
229"#####,
230 )
231}
232
233#[test]
234fn doctest_add_turbo_fish() { 125fn doctest_add_turbo_fish() {
235 check_doc_test( 126 check_doc_test(
236 "add_turbo_fish", 127 "add_turbo_fish",
@@ -467,6 +358,115 @@ fn foo<T: Copy + Clone>() { }
467} 358}
468 359
469#[test] 360#[test]
361fn doctest_generate_derive() {
362 check_doc_test(
363 "generate_derive",
364 r#####"
365struct Point {
366 x: u32,
367 y: u32,<|>
368}
369"#####,
370 r#####"
371#[derive($0)]
372struct Point {
373 x: u32,
374 y: u32,
375}
376"#####,
377 )
378}
379
380#[test]
381fn doctest_generate_from_impl_for_enum() {
382 check_doc_test(
383 "generate_from_impl_for_enum",
384 r#####"
385enum A { <|>One(u32) }
386"#####,
387 r#####"
388enum A { One(u32) }
389
390impl From<u32> for A {
391 fn from(v: u32) -> Self {
392 A::One(v)
393 }
394}
395"#####,
396 )
397}
398
399#[test]
400fn doctest_generate_function() {
401 check_doc_test(
402 "generate_function",
403 r#####"
404struct Baz;
405fn baz() -> Baz { Baz }
406fn foo() {
407 bar<|>("", baz());
408}
409
410"#####,
411 r#####"
412struct Baz;
413fn baz() -> Baz { Baz }
414fn foo() {
415 bar("", baz());
416}
417
418fn bar(arg: &str, baz: Baz) {
419 ${0:todo!()}
420}
421
422"#####,
423 )
424}
425
426#[test]
427fn doctest_generate_impl() {
428 check_doc_test(
429 "generate_impl",
430 r#####"
431struct Ctx<T: Clone> {
432 data: T,<|>
433}
434"#####,
435 r#####"
436struct Ctx<T: Clone> {
437 data: T,
438}
439
440impl<T: Clone> Ctx<T> {
441 $0
442}
443"#####,
444 )
445}
446
447#[test]
448fn doctest_generate_new() {
449 check_doc_test(
450 "generate_new",
451 r#####"
452struct Ctx<T: Clone> {
453 data: T,<|>
454}
455"#####,
456 r#####"
457struct Ctx<T: Clone> {
458 data: T,
459}
460
461impl<T: Clone> Ctx<T> {
462 fn $0new(data: T) -> Self { Self { data } }
463}
464
465"#####,
466 )
467}
468
469#[test]
470fn doctest_inline_local_variable() { 470fn doctest_inline_local_variable() {
471 check_doc_test( 471 check_doc_test(
472 "inline_local_variable", 472 "inline_local_variable",