More consistent naming

This commit is contained in:
Aleksey Kladov 2020-11-09 13:07:18 +01:00
parent 2f24714081
commit 29bf6bed9b
4 changed files with 89 additions and 70 deletions

View file

@ -16,24 +16,31 @@ use crate::{
AssistId, AssistKind, AssistId, AssistKind,
}; };
// Assist: add_custom_impl // Assist: replace_derive_with_manual_impl
// //
// Adds impl block for derived trait. // Converts a `derive` impl into a manual one.
// //
// ``` // ```
// # trait Debug { fn fmt(&self, f: &mut Formatter) -> Result<()>; }
// #[derive(Deb<|>ug, Display)] // #[derive(Deb<|>ug, Display)]
// struct S; // struct S;
// ``` // ```
// -> // ->
// ``` // ```
// # trait Debug { fn fmt(&self, f: &mut Formatter) -> Result<()>; }
// #[derive(Display)] // #[derive(Display)]
// struct S; // struct S;
// //
// impl Debug for S { // impl Debug for S {
// $0 // fn fmt(&self, f: &mut Formatter) -> Result<()> {
// ${0:todo!()}
// }
// } // }
// ``` // ```
pub(crate) fn add_custom_impl(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { pub(crate) fn replace_derive_with_manual_impl(
acc: &mut Assists,
ctx: &AssistContext,
) -> Option<()> {
let attr = ctx.find_node_at_offset::<ast::Attr>()?; let attr = ctx.find_node_at_offset::<ast::Attr>()?;
let attr_name = attr let attr_name = attr
@ -90,43 +97,49 @@ fn add_assist(
) -> Option<()> { ) -> Option<()> {
let target = attr.syntax().text_range(); let target = attr.syntax().text_range();
let input = attr.token_tree()?; let input = attr.token_tree()?;
let label = format!("Add custom impl `{}` for `{}`", trait_path, annotated_name); let label = format!("Convert to manual `impl {} for {}`", trait_path, annotated_name);
let trait_name = trait_path.segment().and_then(|seg| seg.name_ref())?; let trait_name = trait_path.segment().and_then(|seg| seg.name_ref())?;
acc.add(AssistId("add_custom_impl", AssistKind::Refactor), label, target, |builder| { acc.add(
let impl_def_with_items = AssistId("replace_derive_with_manual_impl", AssistKind::Refactor),
impl_def_from_trait(&ctx.sema, annotated_name, trait_, trait_path); label,
update_attribute(builder, &input, &trait_name, &attr); target,
match (ctx.config.snippet_cap, impl_def_with_items) { |builder| {
(None, _) => builder.insert( let impl_def_with_items =
insert_pos, impl_def_from_trait(&ctx.sema, annotated_name, trait_, trait_path);
format!("\n\nimpl {} for {} {{\n\n}}", trait_path, annotated_name), update_attribute(builder, &input, &trait_name, &attr);
), match (ctx.config.snippet_cap, impl_def_with_items) {
(Some(cap), None) => builder.insert_snippet( (None, _) => builder.insert(
cap, insert_pos,
insert_pos, format!("\n\nimpl {} for {} {{\n\n}}", trait_path, annotated_name),
format!("\n\nimpl {} for {} {{\n $0\n}}", trait_path, annotated_name), ),
), (Some(cap), None) => builder.insert_snippet(
(Some(cap), Some((impl_def, first_assoc_item))) => {
let mut cursor = Cursor::Before(first_assoc_item.syntax());
let placeholder;
if let ast::AssocItem::Fn(ref func) = first_assoc_item {
if let Some(m) = func.syntax().descendants().find_map(ast::MacroCall::cast) {
if m.syntax().text() == "todo!()" {
placeholder = m;
cursor = Cursor::Replace(placeholder.syntax());
}
}
}
builder.insert_snippet(
cap, cap,
insert_pos, insert_pos,
format!("\n\n{}", render_snippet(cap, impl_def.syntax(), cursor)), format!("\n\nimpl {} for {} {{\n $0\n}}", trait_path, annotated_name),
) ),
} (Some(cap), Some((impl_def, first_assoc_item))) => {
}; let mut cursor = Cursor::Before(first_assoc_item.syntax());
}) let placeholder;
if let ast::AssocItem::Fn(ref func) = first_assoc_item {
if let Some(m) = func.syntax().descendants().find_map(ast::MacroCall::cast)
{
if m.syntax().text() == "todo!()" {
placeholder = m;
cursor = Cursor::Replace(placeholder.syntax());
}
}
}
builder.insert_snippet(
cap,
insert_pos,
format!("\n\n{}", render_snippet(cap, impl_def.syntax(), cursor)),
)
}
};
},
)
} }
fn impl_def_from_trait( fn impl_def_from_trait(
@ -192,7 +205,7 @@ mod tests {
#[test] #[test]
fn add_custom_impl_debug() { fn add_custom_impl_debug() {
check_assist( check_assist(
add_custom_impl, replace_derive_with_manual_impl,
" "
mod fmt { mod fmt {
pub struct Error; pub struct Error;
@ -233,7 +246,7 @@ impl fmt::Debug for Foo {
#[test] #[test]
fn add_custom_impl_all() { fn add_custom_impl_all() {
check_assist( check_assist(
add_custom_impl, replace_derive_with_manual_impl,
" "
mod foo { mod foo {
pub trait Bar { pub trait Bar {
@ -282,7 +295,7 @@ impl foo::Bar for Foo {
#[test] #[test]
fn add_custom_impl_for_unique_input() { fn add_custom_impl_for_unique_input() {
check_assist( check_assist(
add_custom_impl, replace_derive_with_manual_impl,
" "
#[derive(Debu<|>g)] #[derive(Debu<|>g)]
struct Foo { struct Foo {
@ -304,7 +317,7 @@ impl Debug for Foo {
#[test] #[test]
fn add_custom_impl_for_with_visibility_modifier() { fn add_custom_impl_for_with_visibility_modifier() {
check_assist( check_assist(
add_custom_impl, replace_derive_with_manual_impl,
" "
#[derive(Debug<|>)] #[derive(Debug<|>)]
pub struct Foo { pub struct Foo {
@ -326,7 +339,7 @@ impl Debug for Foo {
#[test] #[test]
fn add_custom_impl_when_multiple_inputs() { fn add_custom_impl_when_multiple_inputs() {
check_assist( check_assist(
add_custom_impl, replace_derive_with_manual_impl,
" "
#[derive(Display, Debug<|>, Serialize)] #[derive(Display, Debug<|>, Serialize)]
struct Foo {} struct Foo {}
@ -345,7 +358,7 @@ impl Debug for Foo {
#[test] #[test]
fn test_ignore_derive_macro_without_input() { fn test_ignore_derive_macro_without_input() {
check_assist_not_applicable( check_assist_not_applicable(
add_custom_impl, replace_derive_with_manual_impl,
" "
#[derive(<|>)] #[derive(<|>)]
struct Foo {} struct Foo {}
@ -356,7 +369,7 @@ struct Foo {}
#[test] #[test]
fn test_ignore_if_cursor_on_param() { fn test_ignore_if_cursor_on_param() {
check_assist_not_applicable( check_assist_not_applicable(
add_custom_impl, replace_derive_with_manual_impl,
" "
#[derive<|>(Debug)] #[derive<|>(Debug)]
struct Foo {} struct Foo {}
@ -364,7 +377,7 @@ struct Foo {}
); );
check_assist_not_applicable( check_assist_not_applicable(
add_custom_impl, replace_derive_with_manual_impl,
" "
#[derive(Debug)<|>] #[derive(Debug)<|>]
struct Foo {} struct Foo {}
@ -375,7 +388,7 @@ struct Foo {}
#[test] #[test]
fn test_ignore_if_not_derive() { fn test_ignore_if_not_derive() {
check_assist_not_applicable( check_assist_not_applicable(
add_custom_impl, replace_derive_with_manual_impl,
" "
#[allow(non_camel_<|>case_types)] #[allow(non_camel_<|>case_types)]
struct Foo {} struct Foo {}

View file

@ -120,7 +120,6 @@ mod handlers {
pub(crate) type Handler = fn(&mut Assists, &AssistContext) -> Option<()>; pub(crate) type Handler = fn(&mut Assists, &AssistContext) -> Option<()>;
mod add_custom_impl;
mod add_explicit_type; mod add_explicit_type;
mod add_missing_impl_members; mod add_missing_impl_members;
mod add_turbo_fish; mod add_turbo_fish;
@ -157,6 +156,7 @@ mod handlers {
mod remove_mut; mod remove_mut;
mod remove_unused_param; mod remove_unused_param;
mod reorder_fields; mod reorder_fields;
mod replace_derive_with_manual_impl;
mod replace_if_let_with_match; mod replace_if_let_with_match;
mod replace_impl_trait_with_generic; mod replace_impl_trait_with_generic;
mod replace_let_with_if_let; mod replace_let_with_if_let;
@ -169,7 +169,6 @@ mod handlers {
pub(crate) fn all() -> &'static [Handler] { pub(crate) fn all() -> &'static [Handler] {
&[ &[
// These are alphabetic for the foolish consistency // These are alphabetic for the foolish consistency
add_custom_impl::add_custom_impl,
add_explicit_type::add_explicit_type, add_explicit_type::add_explicit_type,
add_turbo_fish::add_turbo_fish, add_turbo_fish::add_turbo_fish,
apply_demorgan::apply_demorgan, apply_demorgan::apply_demorgan,
@ -208,6 +207,7 @@ mod handlers {
remove_mut::remove_mut, remove_mut::remove_mut,
remove_unused_param::remove_unused_param, remove_unused_param::remove_unused_param,
reorder_fields::reorder_fields, reorder_fields::reorder_fields,
replace_derive_with_manual_impl::replace_derive_with_manual_impl,
replace_if_let_with_match::replace_if_let_with_match, replace_if_let_with_match::replace_if_let_with_match,
replace_impl_trait_with_generic::replace_impl_trait_with_generic, replace_impl_trait_with_generic::replace_impl_trait_with_generic,
replace_let_with_if_let::replace_let_with_if_let, replace_let_with_if_let::replace_let_with_if_let,

View file

@ -2,25 +2,6 @@
use super::check_doc_test; use super::check_doc_test;
#[test]
fn doctest_add_custom_impl() {
check_doc_test(
"add_custom_impl",
r#####"
#[derive(Deb<|>ug, Display)]
struct S;
"#####,
r#####"
#[derive(Display)]
struct S;
impl Debug for S {
$0
}
"#####,
)
}
#[test] #[test]
fn doctest_add_explicit_type() { fn doctest_add_explicit_type() {
check_doc_test( check_doc_test(
@ -831,6 +812,29 @@ const test: Foo = Foo {foo: 1, bar: 0}
) )
} }
#[test]
fn doctest_replace_derive_with_manual_impl() {
check_doc_test(
"replace_derive_with_manual_impl",
r#####"
trait Debug { fn fmt(&self, f: &mut Formatter) -> Result<()>; }
#[derive(Deb<|>ug, Display)]
struct S;
"#####,
r#####"
trait Debug { fn fmt(&self, f: &mut Formatter) -> Result<()>; }
#[derive(Display)]
struct S;
impl Debug for S {
fn fmt(&self, f: &mut Formatter) -> Result<()> {
${0:todo!()}
}
}
"#####,
)
}
#[test] #[test]
fn doctest_replace_if_let_with_match() { fn doctest_replace_if_let_with_match() {
check_doc_test( check_doc_test(

View file

@ -214,9 +214,6 @@ fn check_todo(path: &Path, text: &str) {
// This file itself obviously needs to use todo (<- like this!). // This file itself obviously needs to use todo (<- like this!).
"tests/cli.rs", "tests/cli.rs",
// Some of our assists generate `todo!()`. // Some of our assists generate `todo!()`.
"tests/generated.rs",
"handlers/add_custom_impl.rs",
"handlers/add_missing_impl_members.rs",
"handlers/add_turbo_fish.rs", "handlers/add_turbo_fish.rs",
"handlers/generate_function.rs", "handlers/generate_function.rs",
// To support generating `todo!()` in assists, we have `expr_todo()` in // To support generating `todo!()` in assists, we have `expr_todo()` in
@ -229,6 +226,11 @@ fn check_todo(path: &Path, text: &str) {
return; return;
} }
if text.contains("TODO") || text.contains("TOOD") || text.contains("todo!") { if text.contains("TODO") || text.contains("TOOD") || text.contains("todo!") {
// Generated by an assist
if text.contains("${0:todo!()}") {
return;
}
panic!( panic!(
"\nTODO markers or todo! macros should not be committed to the master branch,\n\ "\nTODO markers or todo! macros should not be committed to the master branch,\n\
use FIXME instead\n\ use FIXME instead\n\