5213: Add AssistKind::Generate r=matklad a=matklad



bors r+
🤖

Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
This commit is contained in:
bors[bot] 2020-07-03 17:32:44 +00:00 committed by GitHub
commit a095cdb879
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 243 additions and 228 deletions

View file

@ -6,7 +6,7 @@ use ra_syntax::{
use crate::{AssistContext, AssistId, AssistKind, Assists};
// Assist: add_derive
// Assist: generate_derive
//
// Adds a new `#[derive()]` clause to a struct or enum.
//
@ -24,12 +24,16 @@ use crate::{AssistContext, AssistId, AssistKind, Assists};
// y: u32,
// }
// ```
pub(crate) fn add_derive(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
pub(crate) fn generate_derive(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
let cap = ctx.config.snippet_cap?;
let nominal = ctx.find_node_at_offset::<ast::NominalDef>()?;
let node_start = derive_insertion_offset(&nominal)?;
let target = nominal.syntax().text_range();
acc.add(AssistId("add_derive", AssistKind::None), "Add `#[derive]`", target, |builder| {
acc.add(
AssistId("generate_derive", AssistKind::Generate),
"Add `#[derive]`",
target,
|builder| {
let derive_attr = nominal
.attrs()
.filter_map(|x| x.as_simple_call())
@ -49,7 +53,8 @@ pub(crate) fn add_derive(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
)
}
};
})
},
)
}
// Insert `derive` after doc comments.
@ -70,12 +75,12 @@ mod tests {
#[test]
fn add_derive_new() {
check_assist(
add_derive,
generate_derive,
"struct Foo { a: i32, <|>}",
"#[derive($0)]\nstruct Foo { a: i32, }",
);
check_assist(
add_derive,
generate_derive,
"struct Foo { <|> a: i32, }",
"#[derive($0)]\nstruct Foo { a: i32, }",
);
@ -84,7 +89,7 @@ mod tests {
#[test]
fn add_derive_existing() {
check_assist(
add_derive,
generate_derive,
"#[derive(Clone)]\nstruct Foo { a: i32<|>, }",
"#[derive(Clone$0)]\nstruct Foo { a: i32, }",
);
@ -93,7 +98,7 @@ mod tests {
#[test]
fn add_derive_new_with_doc_comment() {
check_assist(
add_derive,
generate_derive,
"
/// `Foo` is a pretty important struct.
/// It does stuff.
@ -111,7 +116,7 @@ struct Foo { a: i32, }
#[test]
fn add_derive_target() {
check_assist_target(
add_derive,
generate_derive,
"
struct SomeThingIrrelevant;
/// `Foo` is a pretty important struct.

View file

@ -4,7 +4,7 @@ use test_utils::mark;
use crate::{utils::FamousDefs, AssistContext, AssistId, AssistKind, Assists};
// Assist: add_from_impl_for_enum
// Assist: generate_from_impl_for_enum
//
// Adds a From impl for an enum variant with one tuple field.
//
@ -21,7 +21,7 @@ use crate::{utils::FamousDefs, AssistContext, AssistId, AssistKind, Assists};
// }
// }
// ```
pub(crate) fn add_from_impl_for_enum(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
pub(crate) fn generate_from_impl_for_enum(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
let variant = ctx.find_node_at_offset::<ast::EnumVariant>()?;
let variant_name = variant.name()?;
let enum_name = variant.parent_enum().name()?;
@ -45,8 +45,8 @@ pub(crate) fn add_from_impl_for_enum(acc: &mut Assists, ctx: &AssistContext) ->
let target = variant.syntax().text_range();
acc.add(
AssistId("add_from_impl_for_enum", AssistKind::Refactor),
"Add From impl for this enum variant",
AssistId("generate_from_impl_for_enum", AssistKind::Generate),
"Generate `From` impl for this enum variant",
target,
|edit| {
let start_offset = variant.parent_enum().syntax().text_range().end();
@ -97,9 +97,9 @@ mod tests {
use super::*;
#[test]
fn test_add_from_impl_for_enum() {
fn test_generate_from_impl_for_enum() {
check_assist(
add_from_impl_for_enum,
generate_from_impl_for_enum,
"enum A { <|>One(u32) }",
r#"enum A { One(u32) }
@ -112,9 +112,9 @@ impl From<u32> for A {
}
#[test]
fn test_add_from_impl_for_enum_complicated_path() {
fn test_generate_from_impl_for_enum_complicated_path() {
check_assist(
add_from_impl_for_enum,
generate_from_impl_for_enum,
r#"enum A { <|>One(foo::bar::baz::Boo) }"#,
r#"enum A { One(foo::bar::baz::Boo) }
@ -129,7 +129,7 @@ impl From<foo::bar::baz::Boo> for A {
fn check_not_applicable(ra_fixture: &str) {
let fixture =
format!("//- /main.rs crate:main deps:core\n{}\n{}", ra_fixture, FamousDefs::FIXTURE);
check_assist_not_applicable(add_from_impl_for_enum, &fixture)
check_assist_not_applicable(generate_from_impl_for_enum, &fixture)
}
#[test]
@ -166,7 +166,7 @@ impl From<u32> for A {
#[test]
fn test_add_from_impl_different_variant_impl_exists() {
check_assist(
add_from_impl_for_enum,
generate_from_impl_for_enum,
r#"enum A { <|>One(u32), Two(String), }
impl From<String> for A {

View file

@ -16,7 +16,7 @@ use crate::{
AssistContext, AssistId, AssistKind, Assists,
};
// Assist: add_function
// Assist: generate_function
//
// Adds a stub function with a signature matching the function under the cursor.
//
@ -41,7 +41,7 @@ use crate::{
// }
//
// ```
pub(crate) fn add_function(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
pub(crate) fn generate_function(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
let path_expr: ast::PathExpr = ctx.find_node_at_offset()?;
let call = path_expr.syntax().parent().and_then(ast::CallExpr::cast)?;
let path = path_expr.path()?;
@ -62,7 +62,11 @@ pub(crate) fn add_function(acc: &mut Assists, ctx: &AssistContext) -> Option<()>
let function_builder = FunctionBuilder::from_call(&ctx, &call, &path, target_module)?;
let target = call.syntax().text_range();
acc.add(AssistId("add_function", AssistKind::None), "Add function", target, |builder| {
acc.add(
AssistId("generate_function", AssistKind::Generate),
format!("Generate `{}` function", function_builder.fn_name),
target,
|builder| {
let function_template = function_builder.render();
builder.edit_file(function_template.file);
let new_fn = function_template.to_string(ctx.config.snippet_cap);
@ -70,7 +74,8 @@ pub(crate) fn add_function(acc: &mut Assists, ctx: &AssistContext) -> Option<()>
Some(cap) => builder.insert_snippet(cap, function_template.insert_offset, new_fn),
None => builder.insert(function_template.insert_offset, new_fn),
}
})
},
)
}
struct FunctionTemplate {
@ -333,7 +338,7 @@ mod tests {
#[test]
fn add_function_with_no_args() {
check_assist(
add_function,
generate_function,
r"
fn foo() {
bar<|>();
@ -356,7 +361,7 @@ fn bar() {
// This ensures that the function is correctly generated
// in the next outer mod or file
check_assist(
add_function,
generate_function,
r"
impl Foo {
fn foo() {
@ -382,7 +387,7 @@ fn bar() {
fn add_function_directly_after_current_block() {
// The new fn should not be created at the end of the file or module
check_assist(
add_function,
generate_function,
r"
fn foo1() {
bar<|>();
@ -407,7 +412,7 @@ fn foo2() {}
#[test]
fn add_function_with_no_args_in_same_module() {
check_assist(
add_function,
generate_function,
r"
mod baz {
fn foo() {
@ -432,7 +437,7 @@ mod baz {
#[test]
fn add_function_with_function_call_arg() {
check_assist(
add_function,
generate_function,
r"
struct Baz;
fn baz() -> Baz { todo!() }
@ -457,7 +462,7 @@ fn bar(baz: Baz) {
#[test]
fn add_function_with_method_call_arg() {
check_assist(
add_function,
generate_function,
r"
struct Baz;
impl Baz {
@ -490,7 +495,7 @@ fn bar(baz: Baz) {
#[test]
fn add_function_with_string_literal_arg() {
check_assist(
add_function,
generate_function,
r#"
fn foo() {
<|>bar("bar")
@ -511,7 +516,7 @@ fn bar(arg: &str) {
#[test]
fn add_function_with_char_literal_arg() {
check_assist(
add_function,
generate_function,
r#"
fn foo() {
<|>bar('x')
@ -532,7 +537,7 @@ fn bar(arg: char) {
#[test]
fn add_function_with_int_literal_arg() {
check_assist(
add_function,
generate_function,
r"
fn foo() {
<|>bar(42)
@ -553,7 +558,7 @@ fn bar(arg: i32) {
#[test]
fn add_function_with_cast_int_literal_arg() {
check_assist(
add_function,
generate_function,
r"
fn foo() {
<|>bar(42 as u8)
@ -576,7 +581,7 @@ fn bar(arg: u8) {
// Ensures that the name of the cast type isn't used
// in the generated function signature.
check_assist(
add_function,
generate_function,
r"
fn foo() {
let x = 42;
@ -599,7 +604,7 @@ fn bar(x: u8) {
#[test]
fn add_function_with_variable_arg() {
check_assist(
add_function,
generate_function,
r"
fn foo() {
let worble = ();
@ -622,7 +627,7 @@ fn bar(worble: ()) {
#[test]
fn add_function_with_impl_trait_arg() {
check_assist(
add_function,
generate_function,
r"
trait Foo {}
fn foo() -> impl Foo {
@ -651,7 +656,7 @@ fn bar(foo: impl Foo) {
#[test]
fn borrowed_arg() {
check_assist(
add_function,
generate_function,
r"
struct Baz;
fn baz() -> Baz { todo!() }
@ -678,7 +683,7 @@ fn bar(baz: &Baz) {
#[test]
fn add_function_with_qualified_path_arg() {
check_assist(
add_function,
generate_function,
r"
mod Baz {
pub struct Bof;
@ -709,7 +714,7 @@ fn bar(baz: Baz::Bof) {
// FIXME fix printing the generics of a `Ty` to make this test pass
fn add_function_with_generic_arg() {
check_assist(
add_function,
generate_function,
r"
fn foo<T>(t: T) {
<|>bar(t)
@ -732,7 +737,7 @@ fn bar<T>(t: T) {
// FIXME Fix function type printing to make this test pass
fn add_function_with_fn_arg() {
check_assist(
add_function,
generate_function,
r"
struct Baz;
impl Baz {
@ -763,7 +768,7 @@ fn bar(arg: fn() -> Baz) {
// FIXME Fix closure type printing to make this test pass
fn add_function_with_closure_arg() {
check_assist(
add_function,
generate_function,
r"
fn foo() {
let closure = |x: i64| x - 1;
@ -786,7 +791,7 @@ fn bar(closure: impl Fn(i64) -> i64) {
#[test]
fn unresolveable_types_default_to_unit() {
check_assist(
add_function,
generate_function,
r"
fn foo() {
<|>bar(baz)
@ -807,7 +812,7 @@ fn bar(baz: ()) {
#[test]
fn arg_names_dont_overlap() {
check_assist(
add_function,
generate_function,
r"
struct Baz;
fn baz() -> Baz { Baz }
@ -832,7 +837,7 @@ fn bar(baz_1: Baz, baz_2: Baz) {
#[test]
fn arg_name_counters_start_at_1_per_name() {
check_assist(
add_function,
generate_function,
r#"
struct Baz;
fn baz() -> Baz { Baz }
@ -857,7 +862,7 @@ fn bar(baz_1: Baz, baz_2: Baz, arg_1: &str, arg_2: &str) {
#[test]
fn add_function_in_module() {
check_assist(
add_function,
generate_function,
r"
mod bar {}
@ -885,7 +890,7 @@ fn foo() {
// See https://github.com/rust-analyzer/rust-analyzer/issues/1165
fn qualified_path_uses_correct_scope() {
check_assist(
add_function,
generate_function,
"
mod foo {
pub struct Foo;
@ -916,7 +921,7 @@ fn baz(foo: foo::Foo) {
#[test]
fn add_function_in_module_containing_other_items() {
check_assist(
add_function,
generate_function,
r"
mod bar {
fn something_else() {}
@ -945,7 +950,7 @@ fn foo() {
#[test]
fn add_function_in_nested_module() {
check_assist(
add_function,
generate_function,
r"
mod bar {
mod baz {}
@ -974,7 +979,7 @@ fn foo() {
#[test]
fn add_function_in_another_file() {
check_assist(
add_function,
generate_function,
r"
//- /main.rs
mod foo;
@ -996,7 +1001,7 @@ pub(crate) fn bar() {
#[test]
fn add_function_not_applicable_if_function_already_exists() {
check_assist_not_applicable(
add_function,
generate_function,
r"
fn foo() {
bar<|>();
@ -1013,7 +1018,7 @@ fn bar() {}
// bar is resolved, but baz isn't.
// The assist is only active if the cursor is on an unresolved path,
// but the assist should only be offered if the path is a function call.
add_function,
generate_function,
r"
fn foo() {
bar(b<|>az);
@ -1028,7 +1033,7 @@ fn bar(baz: ()) {}
#[ignore]
fn create_method_with_no_args() {
check_assist(
add_function,
generate_function,
r"
struct Foo;
impl Foo {

View file

@ -3,7 +3,7 @@ use stdx::{format_to, SepBy};
use crate::{AssistContext, AssistId, AssistKind, Assists};
// Assist: add_impl
// Assist: generate_impl
//
// Adds a new inherent impl for a type.
//
@ -22,13 +22,13 @@ use crate::{AssistContext, AssistId, AssistKind, Assists};
// $0
// }
// ```
pub(crate) fn add_impl(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
pub(crate) fn generate_impl(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
let nominal = ctx.find_node_at_offset::<ast::NominalDef>()?;
let name = nominal.name()?;
let target = nominal.syntax().text_range();
acc.add(
AssistId("add_impl", AssistKind::Refactor),
format!("Implement {}", name.text().as_str()),
AssistId("generate_impl", AssistKind::Generate),
format!("Generate impl for `{}`", name),
target,
|edit| {
let type_params = nominal.type_param_list();
@ -75,14 +75,18 @@ mod tests {
#[test]
fn test_add_impl() {
check_assist(add_impl, "struct Foo {<|>}\n", "struct Foo {}\n\nimpl Foo {\n $0\n}\n");
check_assist(
add_impl,
generate_impl,
"struct Foo {<|>}\n",
"struct Foo {}\n\nimpl Foo {\n $0\n}\n",
);
check_assist(
generate_impl,
"struct Foo<T: Clone> {<|>}",
"struct Foo<T: Clone> {}\n\nimpl<T: Clone> Foo<T> {\n $0\n}",
);
check_assist(
add_impl,
generate_impl,
"struct Foo<'a, T: Foo<'a>> {<|>}",
"struct Foo<'a, T: Foo<'a>> {}\n\nimpl<'a, T: Foo<'a>> Foo<'a, T> {\n $0\n}",
);
@ -91,7 +95,7 @@ mod tests {
#[test]
fn add_impl_target() {
check_assist_target(
add_impl,
generate_impl,
"
struct SomeThingIrrelevant;
/// Has a lifetime parameter

View file

@ -9,7 +9,7 @@ use stdx::{format_to, SepBy};
use crate::{AssistContext, AssistId, AssistKind, Assists};
// Assist: add_new
// Assist: generate_new
//
// Adds a new inherent impl for a type.
//
@ -29,7 +29,7 @@ use crate::{AssistContext, AssistId, AssistKind, Assists};
// }
//
// ```
pub(crate) fn add_new(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
pub(crate) fn generate_new(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
let strukt = ctx.find_node_at_offset::<ast::StructDef>()?;
// 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<()> {
let impl_def = find_struct_impl(&ctx, &strukt)?;
let target = strukt.syntax().text_range();
acc.add(AssistId("add_new", AssistKind::None), "Add default constructor", target, |builder| {
acc.add(AssistId("generate_new", AssistKind::Generate), "Generate `new`", target, |builder| {
let mut buf = String::with_capacity(512);
if impl_def.is_some() {
@ -181,10 +181,10 @@ mod tests {
#[test]
#[rustfmt::skip]
fn test_add_new() {
fn test_generate_new() {
// Check output of generation
check_assist(
add_new,
generate_new,
"struct Foo {<|>}",
"struct Foo {}
@ -194,7 +194,7 @@ impl Foo {
",
);
check_assist(
add_new,
generate_new,
"struct Foo<T: Clone> {<|>}",
"struct Foo<T: Clone> {}
@ -204,7 +204,7 @@ impl<T: Clone> Foo<T> {
",
);
check_assist(
add_new,
generate_new,
"struct Foo<'a, T: Foo<'a>> {<|>}",
"struct Foo<'a, T: Foo<'a>> {}
@ -214,7 +214,7 @@ impl<'a, T: Foo<'a>> Foo<'a, T> {
",
);
check_assist(
add_new,
generate_new,
"struct Foo { baz: String <|>}",
"struct Foo { baz: String }
@ -224,7 +224,7 @@ impl Foo {
",
);
check_assist(
add_new,
generate_new,
"struct Foo { baz: String, qux: Vec<i32> <|>}",
"struct Foo { baz: String, qux: Vec<i32> }
@ -236,7 +236,7 @@ impl Foo {
// Check that visibility modifiers don't get brought in for fields
check_assist(
add_new,
generate_new,
"struct Foo { pub baz: String, pub qux: Vec<i32> <|>}",
"struct Foo { pub baz: String, pub qux: Vec<i32> }
@ -248,7 +248,7 @@ impl Foo {
// Check that it reuses existing impls
check_assist(
add_new,
generate_new,
"struct Foo {<|>}
impl Foo {}
@ -261,7 +261,7 @@ impl Foo {
",
);
check_assist(
add_new,
generate_new,
"struct Foo {<|>}
impl Foo {
@ -279,7 +279,7 @@ impl Foo {
);
check_assist(
add_new,
generate_new,
"struct Foo {<|>}
impl Foo {
@ -304,7 +304,7 @@ impl Foo {
// Check visibility of new fn based on struct
check_assist(
add_new,
generate_new,
"pub struct Foo {<|>}",
"pub struct Foo {}
@ -314,7 +314,7 @@ impl Foo {
",
);
check_assist(
add_new,
generate_new,
"pub(crate) struct Foo {<|>}",
"pub(crate) struct Foo {}
@ -326,9 +326,9 @@ impl Foo {
}
#[test]
fn add_new_not_applicable_if_fn_exists() {
fn generate_new_not_applicable_if_fn_exists() {
check_assist_not_applicable(
add_new,
generate_new,
"
struct Foo {<|>}
@ -340,7 +340,7 @@ impl Foo {
);
check_assist_not_applicable(
add_new,
generate_new,
"
struct Foo {<|>}
@ -353,9 +353,9 @@ impl Foo {
}
#[test]
fn add_new_target() {
fn generate_new_target() {
check_assist_target(
add_new,
generate_new,
"
struct SomeThingIrrelevant;
/// Has a lifetime parameter
@ -370,7 +370,7 @@ struct Foo<'a, T: Foo<'a>> {}",
#[test]
fn test_unrelated_new() {
check_assist(
add_new,
generate_new,
r##"
pub struct AstId<N: AstNode> {
file_id: HirFileId,

View file

@ -30,6 +30,7 @@ pub use assist_config::AssistConfig;
pub enum AssistKind {
None,
QuickFix,
Generate,
Refactor,
RefactorExtract,
RefactorInline,
@ -112,13 +113,8 @@ mod handlers {
pub(crate) type Handler = fn(&mut Assists, &AssistContext) -> Option<()>;
mod add_custom_impl;
mod add_derive;
mod add_explicit_type;
mod add_from_impl_for_enum;
mod add_function;
mod add_impl;
mod add_missing_impl_members;
mod add_new;
mod add_turbo_fish;
mod apply_demorgan;
mod auto_import;
@ -132,6 +128,11 @@ mod handlers {
mod flip_binexpr;
mod flip_comma;
mod flip_trait_bound;
mod generate_derive;
mod generate_from_impl_for_enum;
mod generate_function;
mod generate_impl;
mod generate_new;
mod inline_local_variable;
mod introduce_named_lifetime;
mod invert_if;
@ -154,12 +155,7 @@ mod handlers {
&[
// These are alphabetic for the foolish consistency
add_custom_impl::add_custom_impl,
add_derive::add_derive,
add_explicit_type::add_explicit_type,
add_from_impl_for_enum::add_from_impl_for_enum,
add_function::add_function,
add_impl::add_impl,
add_new::add_new,
add_turbo_fish::add_turbo_fish,
apply_demorgan::apply_demorgan,
auto_import::auto_import,
@ -173,6 +169,11 @@ mod handlers {
flip_binexpr::flip_binexpr,
flip_comma::flip_comma,
flip_trait_bound::flip_trait_bound,
generate_derive::generate_derive,
generate_from_impl_for_enum::generate_from_impl_for_enum,
generate_function::generate_function,
generate_impl::generate_impl,
generate_new::generate_new,
inline_local_variable::inline_local_variable,
introduce_named_lifetime::introduce_named_lifetime,
invert_if::invert_if,

View file

@ -21,26 +21,6 @@ impl Debug for S {
)
}
#[test]
fn doctest_add_derive() {
check_doc_test(
"add_derive",
r#####"
struct Point {
x: u32,
y: u32,<|>
}
"#####,
r#####"
#[derive($0)]
struct Point {
x: u32,
y: u32,
}
"#####,
)
}
#[test]
fn doctest_add_explicit_type() {
check_doc_test(
@ -58,52 +38,6 @@ fn main() {
)
}
#[test]
fn doctest_add_from_impl_for_enum() {
check_doc_test(
"add_from_impl_for_enum",
r#####"
enum A { <|>One(u32) }
"#####,
r#####"
enum A { One(u32) }
impl From<u32> for A {
fn from(v: u32) -> Self {
A::One(v)
}
}
"#####,
)
}
#[test]
fn doctest_add_function() {
check_doc_test(
"add_function",
r#####"
struct Baz;
fn baz() -> Baz { Baz }
fn foo() {
bar<|>("", baz());
}
"#####,
r#####"
struct Baz;
fn baz() -> Baz { Baz }
fn foo() {
bar("", baz());
}
fn bar(arg: &str, baz: Baz) {
${0:todo!()}
}
"#####,
)
}
#[test]
fn doctest_add_hash() {
check_doc_test(
@ -121,27 +55,6 @@ fn main() {
)
}
#[test]
fn doctest_add_impl() {
check_doc_test(
"add_impl",
r#####"
struct Ctx<T: Clone> {
data: T,<|>
}
"#####,
r#####"
struct Ctx<T: Clone> {
data: T,
}
impl<T: Clone> Ctx<T> {
$0
}
"#####,
)
}
#[test]
fn doctest_add_impl_default_members() {
check_doc_test(
@ -208,28 +121,6 @@ impl Trait<u32> for () {
)
}
#[test]
fn doctest_add_new() {
check_doc_test(
"add_new",
r#####"
struct Ctx<T: Clone> {
data: T,<|>
}
"#####,
r#####"
struct Ctx<T: Clone> {
data: T,
}
impl<T: Clone> Ctx<T> {
fn $0new(data: T) -> Self { Self { data } }
}
"#####,
)
}
#[test]
fn doctest_add_turbo_fish() {
check_doc_test(
@ -466,6 +357,115 @@ fn foo<T: Copy + Clone>() { }
)
}
#[test]
fn doctest_generate_derive() {
check_doc_test(
"generate_derive",
r#####"
struct Point {
x: u32,
y: u32,<|>
}
"#####,
r#####"
#[derive($0)]
struct Point {
x: u32,
y: u32,
}
"#####,
)
}
#[test]
fn doctest_generate_from_impl_for_enum() {
check_doc_test(
"generate_from_impl_for_enum",
r#####"
enum A { <|>One(u32) }
"#####,
r#####"
enum A { One(u32) }
impl From<u32> for A {
fn from(v: u32) -> Self {
A::One(v)
}
}
"#####,
)
}
#[test]
fn doctest_generate_function() {
check_doc_test(
"generate_function",
r#####"
struct Baz;
fn baz() -> Baz { Baz }
fn foo() {
bar<|>("", baz());
}
"#####,
r#####"
struct Baz;
fn baz() -> Baz { Baz }
fn foo() {
bar("", baz());
}
fn bar(arg: &str, baz: Baz) {
${0:todo!()}
}
"#####,
)
}
#[test]
fn doctest_generate_impl() {
check_doc_test(
"generate_impl",
r#####"
struct Ctx<T: Clone> {
data: T,<|>
}
"#####,
r#####"
struct Ctx<T: Clone> {
data: T,
}
impl<T: Clone> Ctx<T> {
$0
}
"#####,
)
}
#[test]
fn doctest_generate_new() {
check_doc_test(
"generate_new",
r#####"
struct Ctx<T: Clone> {
data: T,<|>
}
"#####,
r#####"
struct Ctx<T: Clone> {
data: T,
}
impl<T: Clone> Ctx<T> {
fn $0new(data: T) -> Self { Self { data } }
}
"#####,
)
}
#[test]
fn doctest_inline_local_variable() {
check_doc_test(

View file

@ -629,7 +629,7 @@ pub(crate) fn call_hierarchy_item(
pub(crate) fn code_action_kind(kind: AssistKind) -> String {
match kind {
AssistKind::None => lsp_types::code_action_kind::EMPTY,
AssistKind::None | AssistKind::Generate => lsp_types::code_action_kind::EMPTY,
AssistKind::QuickFix => lsp_types::code_action_kind::QUICKFIX,
AssistKind::Refactor => lsp_types::code_action_kind::REFACTOR,
AssistKind::RefactorExtract => lsp_types::code_action_kind::REFACTOR_EXTRACT,

View file

@ -56,8 +56,8 @@ fn check_todo(path: &Path, text: &str) {
// Some of our assists generate `todo!()` so those files are whitelisted.
"tests/generated.rs",
"handlers/add_missing_impl_members.rs",
"handlers/add_function.rs",
"handlers/add_turbo_fish.rs",
"handlers/generate_function.rs",
// To support generating `todo!()` in assists, we have `expr_todo()` in ast::make.
"ast/make.rs",
];