use generate_impl_text in generate_from_impl
This commit is contained in:
parent
3fdc556632
commit
ff7ea7c308
2 changed files with 30 additions and 45 deletions
|
@ -1,15 +1,9 @@
|
||||||
use ast::GenericParamsOwner;
|
|
||||||
use ide_db::helpers::FamousDefs;
|
use ide_db::helpers::FamousDefs;
|
||||||
use ide_db::RootDatabase;
|
use ide_db::RootDatabase;
|
||||||
use itertools::Itertools;
|
use syntax::ast::{self, AstNode, NameOwner};
|
||||||
use stdx::format_to;
|
|
||||||
use syntax::{
|
|
||||||
ast::{self, AstNode, NameOwner},
|
|
||||||
SmolStr,
|
|
||||||
};
|
|
||||||
use test_utils::mark;
|
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
|
// 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<()> {
|
pub(crate) fn generate_from_impl_for_enum(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
|
||||||
let variant = ctx.find_node_at_offset::<ast::Variant>()?;
|
let variant = ctx.find_node_at_offset::<ast::Variant>()?;
|
||||||
let variant_name = variant.name()?;
|
let variant_name = variant.name()?;
|
||||||
let enum_name = variant.parent_enum().name()?;
|
let enum_ = ast::Adt::Enum(variant.parent_enum());
|
||||||
let enum_type_params = variant.parent_enum().generic_param_list();
|
|
||||||
let (field_name, field_type) = match variant.kind() {
|
let (field_name, field_type) = match variant.kind() {
|
||||||
ast::StructKind::Tuple(field_list) => {
|
ast::StructKind::Tuple(field_list) => {
|
||||||
if field_list.fields().count() != 1 {
|
if field_list.fields().count() != 1 {
|
||||||
|
@ -62,49 +55,27 @@ pub(crate) fn generate_from_impl_for_enum(acc: &mut Assists, ctx: &AssistContext
|
||||||
target,
|
target,
|
||||||
|edit| {
|
|edit| {
|
||||||
let start_offset = variant.parent_enum().syntax().text_range().end();
|
let start_offset = variant.parent_enum().syntax().text_range().end();
|
||||||
let mut buf = String::from("\n\nimpl");
|
let from_trait = format!("From<{}>", field_type.syntax());
|
||||||
if let Some(type_params) = &enum_type_params {
|
let impl_code = if let Some(name) = field_name {
|
||||||
format_to!(buf, "{}", type_params.syntax());
|
format!(
|
||||||
}
|
r#" fn from({0}: {1}) -> Self {{
|
||||||
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 {{
|
|
||||||
Self::{2} {{ {0} }}
|
Self::{2} {{ {0} }}
|
||||||
}}
|
}}"#,
|
||||||
}}"#,
|
|
||||||
name.text(),
|
name.text(),
|
||||||
field_type.syntax(),
|
field_type.syntax(),
|
||||||
variant_name,
|
variant_name,
|
||||||
);
|
)
|
||||||
} else {
|
} else {
|
||||||
format_to!(
|
format!(
|
||||||
buf,
|
r#" fn from(v: {}) -> Self {{
|
||||||
r#" {{
|
|
||||||
fn from(v: {}) -> Self {{
|
|
||||||
Self::{}(v)
|
Self::{}(v)
|
||||||
}}
|
}}"#,
|
||||||
}}"#,
|
|
||||||
field_type.syntax(),
|
field_type.syntax(),
|
||||||
variant_name,
|
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);
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -367,6 +367,16 @@ pub(crate) fn find_impl_block_end(impl_def: ast::Impl, buf: &mut String) -> Opti
|
||||||
// Generates the surrounding `impl Type { <code> }` including type and lifetime
|
// Generates the surrounding `impl Type { <code> }` including type and lifetime
|
||||||
// parameters
|
// parameters
|
||||||
pub(crate) fn generate_impl_text(adt: &ast::Adt, code: &str) -> String {
|
pub(crate) fn generate_impl_text(adt: &ast::Adt, code: &str) -> String {
|
||||||
|
generate_impl_text_inner(adt, None, code)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generates the surrounding `impl <trait> for Type { <code> }` 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 type_params = adt.generic_param_list();
|
||||||
let mut buf = String::with_capacity(code.len());
|
let mut buf = String::with_capacity(code.len());
|
||||||
buf.push_str("\n\nimpl");
|
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());
|
format_to!(buf, "{}", type_params.syntax());
|
||||||
}
|
}
|
||||||
buf.push(' ');
|
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());
|
buf.push_str(adt.name().unwrap().text());
|
||||||
if let Some(type_params) = type_params {
|
if let Some(type_params) = type_params {
|
||||||
let lifetime_params = type_params
|
let lifetime_params = type_params
|
||||||
|
|
Loading…
Reference in a new issue