From ff7ea7c30843e576be6ab3fb70f79d8053006652 Mon Sep 17 00:00:00 2001 From: Domantas Jadenkus Date: Sat, 13 Feb 2021 22:26:58 +0200 Subject: use generate_impl_text in generate_from_impl --- .../src/handlers/generate_from_impl_for_enum.rs | 61 ++++++---------------- crates/assists/src/utils.rs | 14 +++++ 2 files changed, 30 insertions(+), 45 deletions(-) (limited to 'crates') diff --git a/crates/assists/src/handlers/generate_from_impl_for_enum.rs b/crates/assists/src/handlers/generate_from_impl_for_enum.rs index f6febd3aa..fac2447c9 100644 --- a/crates/assists/src/handlers/generate_from_impl_for_enum.rs +++ b/crates/assists/src/handlers/generate_from_impl_for_enum.rs @@ -1,15 +1,9 @@ -use ast::GenericParamsOwner; use ide_db::helpers::FamousDefs; use ide_db::RootDatabase; -use itertools::Itertools; -use stdx::format_to; -use syntax::{ - ast::{self, AstNode, NameOwner}, - SmolStr, -}; +use syntax::ast::{self, AstNode, NameOwner}; use test_utils::mark; -use crate::{AssistContext, AssistId, AssistKind, Assists}; +use crate::{AssistContext, AssistId, AssistKind, Assists, utils::generate_trait_impl_text}; // Assist: generate_from_impl_for_enum // @@ -31,8 +25,7 @@ use crate::{AssistContext, AssistId, AssistKind, Assists}; pub(crate) fn generate_from_impl_for_enum(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { let variant = ctx.find_node_at_offset::()?; let variant_name = variant.name()?; - let enum_name = variant.parent_enum().name()?; - let enum_type_params = variant.parent_enum().generic_param_list(); + let enum_ = ast::Adt::Enum(variant.parent_enum()); let (field_name, field_type) = match variant.kind() { ast::StructKind::Tuple(field_list) => { if field_list.fields().count() != 1 { @@ -62,49 +55,27 @@ pub(crate) fn generate_from_impl_for_enum(acc: &mut Assists, ctx: &AssistContext target, |edit| { let start_offset = variant.parent_enum().syntax().text_range().end(); - let mut buf = String::from("\n\nimpl"); - if let Some(type_params) = &enum_type_params { - format_to!(buf, "{}", type_params.syntax()); - } - format_to!(buf, " From<{}> for {}", field_type.syntax(), enum_name); - if let Some(type_params) = enum_type_params { - let lifetime_params = type_params - .lifetime_params() - .filter_map(|it| it.lifetime()) - .map(|it| SmolStr::from(it.text())); - let type_params = type_params - .type_params() - .filter_map(|it| it.name()) - .map(|it| SmolStr::from(it.text())); - - let generic_params = lifetime_params.chain(type_params).format(", "); - format_to!(buf, "<{}>", generic_params) - } - if let Some(name) = field_name { - format_to!( - buf, - r#" {{ - fn from({0}: {1}) -> Self {{ + let from_trait = format!("From<{}>", field_type.syntax()); + let impl_code = if let Some(name) = field_name { + format!( + r#" fn from({0}: {1}) -> Self {{ Self::{2} {{ {0} }} - }} -}}"#, + }}"#, name.text(), field_type.syntax(), variant_name, - ); + ) } else { - format_to!( - buf, - r#" {{ - fn from(v: {}) -> Self {{ + format!( + r#" fn from(v: {}) -> Self {{ Self::{}(v) - }} -}}"#, + }}"#, field_type.syntax(), variant_name, - ); - } - edit.insert(start_offset, buf); + ) + }; + let from_impl = generate_trait_impl_text(&enum_, &from_trait, &impl_code); + edit.insert(start_offset, from_impl); }, ) } diff --git a/crates/assists/src/utils.rs b/crates/assists/src/utils.rs index 5dd32aef1..69c107f63 100644 --- a/crates/assists/src/utils.rs +++ b/crates/assists/src/utils.rs @@ -367,6 +367,16 @@ pub(crate) fn find_impl_block_end(impl_def: ast::Impl, buf: &mut String) -> Opti // Generates the surrounding `impl Type { }` including type and lifetime // parameters pub(crate) fn generate_impl_text(adt: &ast::Adt, code: &str) -> String { + generate_impl_text_inner(adt, None, code) +} + +// Generates the surrounding `impl for Type { }` including type +// and lifetime parameters +pub(crate) fn generate_trait_impl_text(adt: &ast::Adt, trait_text: &str, code: &str) -> String { + generate_impl_text_inner(adt, Some(trait_text), code) +} + +fn generate_impl_text_inner(adt: &ast::Adt, trait_text: Option<&str>, code: &str) -> String { let type_params = adt.generic_param_list(); let mut buf = String::with_capacity(code.len()); buf.push_str("\n\nimpl"); @@ -374,6 +384,10 @@ pub(crate) fn generate_impl_text(adt: &ast::Adt, code: &str) -> String { format_to!(buf, "{}", type_params.syntax()); } buf.push(' '); + if let Some(trait_text) = trait_text { + buf.push_str(trait_text); + buf.push_str(" for "); + } buf.push_str(adt.name().unwrap().text()); if let Some(type_params) = type_params { let lifetime_params = type_params -- cgit v1.2.3 From 3364ac8b1106f6f0d8a52a8981c6c598152b5642 Mon Sep 17 00:00:00 2001 From: Domantas Jadenkus Date: Sat, 13 Feb 2021 22:38:52 +0200 Subject: use generate_impl_text in generate_impl --- crates/assists/src/handlers/generate_impl.rs | 46 ++++------------------------ crates/assists/src/utils.rs | 9 +++++- 2 files changed, 14 insertions(+), 41 deletions(-) (limited to 'crates') diff --git a/crates/assists/src/handlers/generate_impl.rs b/crates/assists/src/handlers/generate_impl.rs index 61d1bd25c..e2762e5d2 100644 --- a/crates/assists/src/handlers/generate_impl.rs +++ b/crates/assists/src/handlers/generate_impl.rs @@ -1,11 +1,6 @@ -use itertools::Itertools; -use stdx::format_to; -use syntax::{ - ast::{self, AstNode, AttrsOwner, GenericParamsOwner, NameOwner}, - SmolStr, -}; +use syntax::ast::{self, AstNode, NameOwner}; -use crate::{AssistContext, AssistId, AssistKind, Assists}; +use crate::{AssistContext, AssistId, AssistKind, Assists, utils::generate_impl_text}; // Assist: generate_impl // @@ -36,44 +31,15 @@ pub(crate) fn generate_impl(acc: &mut Assists, ctx: &AssistContext) -> Option<() format!("Generate impl for `{}`", name), target, |edit| { - let type_params = nominal.generic_param_list(); let start_offset = nominal.syntax().text_range().end(); - let mut buf = String::new(); - buf.push_str("\n\n"); - nominal - .attrs() - .filter(|attr| { - attr.as_simple_call().map(|(name, _arg)| name == "cfg").unwrap_or(false) - }) - .for_each(|attr| buf.push_str(format!("{}\n", attr.to_string()).as_str())); - - buf.push_str("impl"); - if let Some(type_params) = &type_params { - format_to!(buf, "{}", type_params.syntax()); - } - buf.push_str(" "); - buf.push_str(name.text()); - if let Some(type_params) = type_params { - let lifetime_params = type_params - .lifetime_params() - .filter_map(|it| it.lifetime()) - .map(|it| SmolStr::from(it.text())); - let type_params = type_params - .type_params() - .filter_map(|it| it.name()) - .map(|it| SmolStr::from(it.text())); - - let generic_params = lifetime_params.chain(type_params).format(", "); - format_to!(buf, "<{}>", generic_params) - } match ctx.config.snippet_cap { Some(cap) => { - buf.push_str(" {\n $0\n}"); - edit.insert_snippet(cap, start_offset, buf); + let snippet = generate_impl_text(&nominal, " $0"); + edit.insert_snippet(cap, start_offset, snippet); } None => { - buf.push_str(" {\n}"); - edit.insert(start_offset, buf); + let snippet = generate_impl_text(&nominal, ""); + edit.insert(start_offset, snippet); } } }, diff --git a/crates/assists/src/utils.rs b/crates/assists/src/utils.rs index 69c107f63..b51d703db 100644 --- a/crates/assists/src/utils.rs +++ b/crates/assists/src/utils.rs @@ -379,7 +379,14 @@ pub(crate) fn generate_trait_impl_text(adt: &ast::Adt, trait_text: &str, code: & fn generate_impl_text_inner(adt: &ast::Adt, trait_text: Option<&str>, code: &str) -> String { let type_params = adt.generic_param_list(); let mut buf = String::with_capacity(code.len()); - buf.push_str("\n\nimpl"); + buf.push_str("\n\n"); + adt + .attrs() + .filter(|attr| { + attr.as_simple_call().map(|(name, _arg)| name == "cfg").unwrap_or(false) + }) + .for_each(|attr| buf.push_str(format!("{}\n", attr.to_string()).as_str())); + buf.push_str("impl"); if let Some(type_params) = &type_params { format_to!(buf, "{}", type_params.syntax()); } -- cgit v1.2.3 From 36e8a55bee478d296f3903eb4b14914914801b38 Mon Sep 17 00:00:00 2001 From: Domantas Jadenkus Date: Sat, 13 Feb 2021 22:50:04 +0200 Subject: use generate_impl_text in replace_derive_with_manual_impl --- .../handlers/replace_derive_with_manual_impl.rs | 32 ++++++++-------------- 1 file changed, 12 insertions(+), 20 deletions(-) (limited to 'crates') diff --git a/crates/assists/src/handlers/replace_derive_with_manual_impl.rs b/crates/assists/src/handlers/replace_derive_with_manual_impl.rs index 6aa9d2f2c..7f44d752f 100644 --- a/crates/assists/src/handlers/replace_derive_with_manual_impl.rs +++ b/crates/assists/src/handlers/replace_derive_with_manual_impl.rs @@ -1,20 +1,9 @@ use ide_db::helpers::mod_path_to_ast; use ide_db::imports_locator; use itertools::Itertools; -use syntax::{ - ast::{self, make, AstNode}, - Direction, - SyntaxKind::{IDENT, WHITESPACE}, - TextSize, -}; - -use crate::{ - assist_context::{AssistBuilder, AssistContext, Assists}, - utils::{ - add_trait_assoc_items_to_impl, filter_assoc_items, render_snippet, Cursor, DefaultMethods, - }, - AssistId, AssistKind, -}; +use syntax::{SyntaxKind::{IDENT, WHITESPACE}, TextSize, ast::{self, AstNode, NameOwner, make}}; + +use crate::{AssistId, AssistKind, assist_context::{AssistBuilder, AssistContext, Assists}, utils::{Cursor, DefaultMethods, add_trait_assoc_items_to_impl, filter_assoc_items, generate_trait_impl_text, render_snippet}}; // Assist: replace_derive_with_manual_impl // @@ -57,8 +46,9 @@ pub(crate) fn replace_derive_with_manual_impl( let trait_token = ctx.token_at_offset().find(|t| t.kind() == IDENT && t.text() != "derive")?; let trait_path = make::path_unqualified(make::path_segment(make::name_ref(trait_token.text()))); - let annotated_name = attr.syntax().siblings(Direction::Next).find_map(ast::Name::cast)?; - let insert_pos = annotated_name.syntax().parent()?.text_range().end(); + let adt = attr.syntax().parent().and_then(ast::Adt::cast)?; + let annotated_name = adt.name()?; + let insert_pos = adt.syntax().text_range().end(); let current_module = ctx.sema.scope(annotated_name.syntax()).module()?; let current_crate = current_module.krate(); @@ -82,10 +72,10 @@ pub(crate) fn replace_derive_with_manual_impl( let mut no_traits_found = true; for (trait_path, trait_) in found_traits.inspect(|_| no_traits_found = false) { - add_assist(acc, ctx, &attr, &trait_path, Some(trait_), &annotated_name, insert_pos)?; + add_assist(acc, ctx, &attr, &trait_path, Some(trait_), &adt, &annotated_name, insert_pos)?; } if no_traits_found { - add_assist(acc, ctx, &attr, &trait_path, None, &annotated_name, insert_pos)?; + add_assist(acc, ctx, &attr, &trait_path, None, &adt, &annotated_name, insert_pos)?; } Some(()) } @@ -96,6 +86,7 @@ fn add_assist( attr: &ast::Attr, trait_path: &ast::Path, trait_: Option, + adt: &ast::Adt, annotated_name: &ast::Name, insert_pos: TextSize, ) -> Option<()> { @@ -112,15 +103,16 @@ fn add_assist( let impl_def_with_items = impl_def_from_trait(&ctx.sema, annotated_name, trait_, trait_path); update_attribute(builder, &input, &trait_name, &attr); + let trait_path = format!("{}", trait_path); match (ctx.config.snippet_cap, impl_def_with_items) { (None, _) => builder.insert( insert_pos, - format!("\n\nimpl {} for {} {{\n\n}}", trait_path, annotated_name), + generate_trait_impl_text(adt, &trait_path, ""), ), (Some(cap), None) => builder.insert_snippet( cap, insert_pos, - format!("\n\nimpl {} for {} {{\n $0\n}}", trait_path, annotated_name), + generate_trait_impl_text(adt, &trait_path, " $0"), ), (Some(cap), Some((impl_def, first_assoc_item))) => { let mut cursor = Cursor::Before(first_assoc_item.syntax()); -- cgit v1.2.3 From 7f100fff92ab4944f3d49cf7ffdcd91fc3578936 Mon Sep 17 00:00:00 2001 From: Domantas Jadenkus Date: Sat, 13 Feb 2021 22:51:48 +0200 Subject: cargo fmt --- .../src/handlers/generate_from_impl_for_enum.rs | 2 +- crates/assists/src/handlers/generate_impl.rs | 2 +- .../handlers/replace_derive_with_manual_impl.rs | 24 +++++++++++++++------- crates/assists/src/utils.rs | 7 ++----- 4 files changed, 21 insertions(+), 14 deletions(-) (limited to 'crates') diff --git a/crates/assists/src/handlers/generate_from_impl_for_enum.rs b/crates/assists/src/handlers/generate_from_impl_for_enum.rs index fac2447c9..d9388a737 100644 --- a/crates/assists/src/handlers/generate_from_impl_for_enum.rs +++ b/crates/assists/src/handlers/generate_from_impl_for_enum.rs @@ -3,7 +3,7 @@ use ide_db::RootDatabase; use syntax::ast::{self, AstNode, NameOwner}; use test_utils::mark; -use crate::{AssistContext, AssistId, AssistKind, Assists, utils::generate_trait_impl_text}; +use crate::{utils::generate_trait_impl_text, AssistContext, AssistId, AssistKind, Assists}; // Assist: generate_from_impl_for_enum // diff --git a/crates/assists/src/handlers/generate_impl.rs b/crates/assists/src/handlers/generate_impl.rs index e2762e5d2..050bcd4e2 100644 --- a/crates/assists/src/handlers/generate_impl.rs +++ b/crates/assists/src/handlers/generate_impl.rs @@ -1,6 +1,6 @@ use syntax::ast::{self, AstNode, NameOwner}; -use crate::{AssistContext, AssistId, AssistKind, Assists, utils::generate_impl_text}; +use crate::{utils::generate_impl_text, AssistContext, AssistId, AssistKind, Assists}; // Assist: generate_impl // diff --git a/crates/assists/src/handlers/replace_derive_with_manual_impl.rs b/crates/assists/src/handlers/replace_derive_with_manual_impl.rs index 7f44d752f..c69bc5cac 100644 --- a/crates/assists/src/handlers/replace_derive_with_manual_impl.rs +++ b/crates/assists/src/handlers/replace_derive_with_manual_impl.rs @@ -1,9 +1,20 @@ use ide_db::helpers::mod_path_to_ast; use ide_db::imports_locator; use itertools::Itertools; -use syntax::{SyntaxKind::{IDENT, WHITESPACE}, TextSize, ast::{self, AstNode, NameOwner, make}}; - -use crate::{AssistId, AssistKind, assist_context::{AssistBuilder, AssistContext, Assists}, utils::{Cursor, DefaultMethods, add_trait_assoc_items_to_impl, filter_assoc_items, generate_trait_impl_text, render_snippet}}; +use syntax::{ + ast::{self, make, AstNode, NameOwner}, + SyntaxKind::{IDENT, WHITESPACE}, + TextSize, +}; + +use crate::{ + assist_context::{AssistBuilder, AssistContext, Assists}, + utils::{ + add_trait_assoc_items_to_impl, filter_assoc_items, generate_trait_impl_text, + render_snippet, Cursor, DefaultMethods, + }, + AssistId, AssistKind, +}; // Assist: replace_derive_with_manual_impl // @@ -105,10 +116,9 @@ fn add_assist( update_attribute(builder, &input, &trait_name, &attr); let trait_path = format!("{}", trait_path); match (ctx.config.snippet_cap, impl_def_with_items) { - (None, _) => builder.insert( - insert_pos, - generate_trait_impl_text(adt, &trait_path, ""), - ), + (None, _) => { + builder.insert(insert_pos, generate_trait_impl_text(adt, &trait_path, "")) + } (Some(cap), None) => builder.insert_snippet( cap, insert_pos, diff --git a/crates/assists/src/utils.rs b/crates/assists/src/utils.rs index b51d703db..98c4462bb 100644 --- a/crates/assists/src/utils.rs +++ b/crates/assists/src/utils.rs @@ -380,11 +380,8 @@ fn generate_impl_text_inner(adt: &ast::Adt, trait_text: Option<&str>, code: &str let type_params = adt.generic_param_list(); let mut buf = String::with_capacity(code.len()); buf.push_str("\n\n"); - adt - .attrs() - .filter(|attr| { - attr.as_simple_call().map(|(name, _arg)| name == "cfg").unwrap_or(false) - }) + adt.attrs() + .filter(|attr| attr.as_simple_call().map(|(name, _arg)| name == "cfg").unwrap_or(false)) .for_each(|attr| buf.push_str(format!("{}\n", attr.to_string()).as_str())); buf.push_str("impl"); if let Some(type_params) = &type_params { -- cgit v1.2.3