Auto merge of #13399 - DropDemBits:assists-format-args-capture-pt2, r=Veykril

Migrate assists to format args captures, part 2

Continuation of #13379

Migrates:

- `generate_constant`
- `generate_default_from_enum_variant`
- `generate_default_from_new`
- `generate_delegate_methods`
- `generate_deref`
- `generate_documentation_template`
- `generate_enum_is_method`
- `generate_enum_projection_method`
- `generate_from_impl_for_enum`
- `generate_function`
- `generate_getter`
- `generate_impl`
- `generate_new`
- `generate_setter`
This commit is contained in:
bors 2022-10-17 09:54:07 +00:00
commit a2e4f783a2
14 changed files with 150 additions and 157 deletions

View file

@ -77,7 +77,7 @@ pub(crate) fn generate_constant(acc: &mut Assists, ctx: &AssistContext<'_>) -> O
target_data_for_generate_constant(ctx, current_module, constant_module).unwrap_or_else( target_data_for_generate_constant(ctx, current_module, constant_module).unwrap_or_else(
|| { || {
let indent = IndentLevel::from_node(statement.syntax()); let indent = IndentLevel::from_node(statement.syntax());
(statement.syntax().text_range().start(), indent, None, format!("\n{}", indent)) (statement.syntax().text_range().start(), indent, None, format!("\n{indent}"))
}, },
); );
@ -90,7 +90,7 @@ pub(crate) fn generate_constant(acc: &mut Assists, ctx: &AssistContext<'_>) -> O
if let Some(file_id) = file_id { if let Some(file_id) = file_id {
builder.edit_file(file_id); builder.edit_file(file_id);
} }
builder.insert(offset, format!("{}{}", text, post_string)); builder.insert(offset, format!("{text}{post_string}"));
}, },
) )
} }
@ -103,13 +103,13 @@ fn get_text_for_generate_constant(
) -> Option<String> { ) -> Option<String> {
let constant_token = not_exist_name_ref.pop()?; let constant_token = not_exist_name_ref.pop()?;
let vis = if not_exist_name_ref.len() == 0 && !outer_exists { "" } else { "\npub " }; let vis = if not_exist_name_ref.len() == 0 && !outer_exists { "" } else { "\npub " };
let mut text = format!("{}const {}: {} = $0;", vis, constant_token, type_name); let mut text = format!("{vis}const {constant_token}: {type_name} = $0;");
while let Some(name_ref) = not_exist_name_ref.pop() { while let Some(name_ref) = not_exist_name_ref.pop() {
let vis = if not_exist_name_ref.len() == 0 && !outer_exists { "" } else { "\npub " }; let vis = if not_exist_name_ref.len() == 0 && !outer_exists { "" } else { "\npub " };
text = text.replace("\n", "\n "); text = text.replace("\n", "\n ");
text = format!("{}mod {} {{{}\n}}", vis, name_ref.to_string(), text); text = format!("{vis}mod {name_ref} {{{text}\n}}");
} }
Some(text.replace("\n", &format!("\n{}", indent))) Some(text.replace("\n", &format!("\n{indent}")))
} }
fn target_data_for_generate_constant( fn target_data_for_generate_constant(
@ -134,7 +134,7 @@ fn target_data_for_generate_constant(
.find(|it| it.kind() == SyntaxKind::WHITESPACE && it.to_string().contains("\n")) .find(|it| it.kind() == SyntaxKind::WHITESPACE && it.to_string().contains("\n"))
.is_some(); .is_some();
let post_string = let post_string =
if siblings_has_newline { format!("{}", indent) } else { format!("\n{}", indent) }; if siblings_has_newline { format!("{indent}") } else { format!("\n{indent}") };
Some((offset, indent + 1, Some(file_id), post_string)) Some((offset, indent + 1, Some(file_id), post_string))
} }
_ => Some((TextSize::from(0), 0.into(), Some(file_id), "\n".into())), _ => Some((TextSize::from(0), 0.into(), Some(file_id), "\n".into())),

View file

@ -55,12 +55,11 @@ pub(crate) fn generate_default_from_enum_variant(
let buf = format!( let buf = format!(
r#" r#"
impl Default for {0} {{ impl Default for {enum_name} {{
fn default() -> Self {{ fn default() -> Self {{
Self::{1} Self::{variant_name}
}} }}
}}"#, }}"#,
enum_name, variant_name
); );
edit.insert(start_offset, buf); edit.insert(start_offset, buf);
}, },

View file

@ -1,8 +1,7 @@
use ide_db::famous_defs::FamousDefs; use ide_db::famous_defs::FamousDefs;
use itertools::Itertools;
use stdx::format_to; use stdx::format_to;
use syntax::{ use syntax::{
ast::{self, HasGenericParams, HasName, HasTypeBounds, Impl}, ast::{self, make, HasGenericParams, HasName, Impl},
AstNode, AstNode,
}; };
@ -77,45 +76,47 @@ pub(crate) fn generate_default_from_new(acc: &mut Assists, ctx: &AssistContext<'
) )
} }
// FIXME: based on from utils::generate_impl_text_inner
fn generate_trait_impl_text_from_impl(impl_: &ast::Impl, trait_text: &str, code: &str) -> String { fn generate_trait_impl_text_from_impl(impl_: &ast::Impl, trait_text: &str, code: &str) -> String {
let generic_params = impl_.generic_param_list(); let impl_ty = impl_.self_ty().unwrap();
let generic_params = impl_.generic_param_list().map(|generic_params| {
let lifetime_params =
generic_params.lifetime_params().map(ast::GenericParam::LifetimeParam);
let ty_or_const_params = generic_params.type_or_const_params().filter_map(|param| {
// remove defaults since they can't be specified in impls
match param {
ast::TypeOrConstParam::Type(param) => {
let param = param.clone_for_update();
param.remove_default();
Some(ast::GenericParam::TypeParam(param))
}
ast::TypeOrConstParam::Const(param) => {
let param = param.clone_for_update();
param.remove_default();
Some(ast::GenericParam::ConstParam(param))
}
}
});
make::generic_param_list(itertools::chain(lifetime_params, ty_or_const_params))
});
let mut buf = String::with_capacity(code.len()); let mut buf = String::with_capacity(code.len());
buf.push_str("\n\n"); buf.push_str("\n\n");
// `impl{generic_params} {trait_text} for {impl_.self_ty()}`
buf.push_str("impl"); buf.push_str("impl");
if let Some(generic_params) = &generic_params { if let Some(generic_params) = &generic_params {
let lifetimes = generic_params.lifetime_params().map(|lt| format!("{}", lt.syntax())); format_to!(buf, "{generic_params}")
let toc_params = generic_params.type_or_const_params().map(|toc_param| match toc_param {
ast::TypeOrConstParam::Type(type_param) => {
let mut buf = String::new();
if let Some(it) = type_param.name() {
format_to!(buf, "{}", it.syntax());
}
if let Some(it) = type_param.colon_token() {
format_to!(buf, "{} ", it);
}
if let Some(it) = type_param.type_bound_list() {
format_to!(buf, "{}", it.syntax());
}
buf
}
ast::TypeOrConstParam::Const(const_param) => const_param.syntax().to_string(),
});
let generics = lifetimes.chain(toc_params).format(", ");
format_to!(buf, "<{}>", generics);
} }
format_to!(buf, " {trait_text} for {impl_ty}");
buf.push(' ');
buf.push_str(trait_text);
buf.push_str(" for ");
buf.push_str(&impl_.self_ty().unwrap().syntax().text().to_string());
match impl_.where_clause() { match impl_.where_clause() {
Some(where_clause) => { Some(where_clause) => {
format_to!(buf, "\n{}\n{{\n{}\n}}", where_clause, code); format_to!(buf, "\n{where_clause}\n{{\n{code}\n}}");
} }
None => { None => {
format_to!(buf, " {{\n{}\n}}", code); format_to!(buf, " {{\n{code}\n}}");
} }
} }

View file

@ -51,14 +51,14 @@ pub(crate) fn generate_delegate_methods(acc: &mut Assists, ctx: &AssistContext<'
Some(field) => { Some(field) => {
let field_name = field.name()?; let field_name = field.name()?;
let field_ty = field.ty()?; let field_ty = field.ty()?;
(format!("{}", field_name), field_ty, field.syntax().text_range()) (format!("{field_name}"), field_ty, field.syntax().text_range())
} }
None => { None => {
let field = ctx.find_node_at_offset::<ast::TupleField>()?; let field = ctx.find_node_at_offset::<ast::TupleField>()?;
let field_list = ctx.find_node_at_offset::<ast::TupleFieldList>()?; let field_list = ctx.find_node_at_offset::<ast::TupleFieldList>()?;
let field_list_index = field_list.fields().position(|it| it == field)?; let field_list_index = field_list.fields().position(|it| it == field)?;
let field_ty = field.ty()?; let field_ty = field.ty()?;
(format!("{}", field_list_index), field_ty, field.syntax().text_range()) (format!("{field_list_index}"), field_ty, field.syntax().text_range())
} }
}; };
@ -78,10 +78,12 @@ pub(crate) fn generate_delegate_methods(acc: &mut Assists, ctx: &AssistContext<'
let adt = ast::Adt::Struct(strukt.clone()); let adt = ast::Adt::Struct(strukt.clone());
let name = method.name(ctx.db()).to_string(); let name = method.name(ctx.db()).to_string();
let impl_def = find_struct_impl(ctx, &adt, &name).flatten(); let impl_def = find_struct_impl(ctx, &adt, &name).flatten();
let method_name = method.name(ctx.db());
acc.add_group( acc.add_group(
&GroupLabel("Generate delegate methods…".to_owned()), &GroupLabel("Generate delegate methods…".to_owned()),
AssistId("generate_delegate_methods", AssistKind::Generate), AssistId("generate_delegate_methods", AssistKind::Generate),
format!("Generate delegate for `{}.{}()`", field_name, method.name(ctx.db())), format!("Generate delegate for `{field_name}.{method_name}()`"),
target, target,
|builder| { |builder| {
// Create the function // Create the function
@ -151,12 +153,12 @@ pub(crate) fn generate_delegate_methods(acc: &mut Assists, ctx: &AssistContext<'
Some(cap) => { Some(cap) => {
let offset = strukt.syntax().text_range().end(); let offset = strukt.syntax().text_range().end();
let snippet = render_snippet(cap, impl_def.syntax(), cursor); let snippet = render_snippet(cap, impl_def.syntax(), cursor);
let snippet = format!("\n\n{}", snippet); let snippet = format!("\n\n{snippet}");
builder.insert_snippet(cap, offset, snippet); builder.insert_snippet(cap, offset, snippet);
} }
None => { None => {
let offset = strukt.syntax().text_range().end(); let offset = strukt.syntax().text_range().end();
let snippet = format!("\n\n{}", impl_def.syntax()); let snippet = format!("\n\n{impl_def}");
builder.insert(offset, snippet); builder.insert(offset, snippet);
} }
} }

View file

@ -66,7 +66,7 @@ fn generate_record_deref(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<(
let target = field.syntax().text_range(); let target = field.syntax().text_range();
acc.add( acc.add(
AssistId("generate_deref", AssistKind::Generate), AssistId("generate_deref", AssistKind::Generate),
format!("Generate `{:?}` impl using `{}`", deref_type_to_generate, field_name), format!("Generate `{deref_type_to_generate:?}` impl using `{field_name}`"),
target, target,
|edit| { |edit| {
generate_edit( generate_edit(
@ -106,7 +106,7 @@ fn generate_tuple_deref(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()
let target = field.syntax().text_range(); let target = field.syntax().text_range();
acc.add( acc.add(
AssistId("generate_deref", AssistKind::Generate), AssistId("generate_deref", AssistKind::Generate),
format!("Generate `{:?}` impl using `{}`", deref_type_to_generate, field.syntax()), format!("Generate `{deref_type_to_generate:?}` impl using `{field}`"),
target, target,
|edit| { |edit| {
generate_edit( generate_edit(
@ -132,18 +132,16 @@ fn generate_edit(
let start_offset = strukt.syntax().text_range().end(); let start_offset = strukt.syntax().text_range().end();
let impl_code = match deref_type { let impl_code = match deref_type {
DerefType::Deref => format!( DerefType::Deref => format!(
r#" type Target = {0}; r#" type Target = {field_type_syntax};
fn deref(&self) -> &Self::Target {{ fn deref(&self) -> &Self::Target {{
&self.{1} &self.{field_name}
}}"#, }}"#,
field_type_syntax, field_name
), ),
DerefType::DerefMut => format!( DerefType::DerefMut => format!(
r#" fn deref_mut(&mut self) -> &mut Self::Target {{ r#" fn deref_mut(&mut self) -> &mut Self::Target {{
&mut self.{} &mut self.{field_name}
}}"#, }}"#,
field_name
), ),
}; };
let strukt_adt = ast::Adt::Struct(strukt); let strukt_adt = ast::Adt::Struct(strukt);

View file

@ -139,40 +139,44 @@ fn make_example_for_fn(ast_func: &ast::Fn, ctx: &AssistContext<'_>) -> Option<St
let mut example = String::new(); let mut example = String::new();
let use_path = build_path(ast_func, ctx)?;
let is_unsafe = ast_func.unsafe_token().is_some(); let is_unsafe = ast_func.unsafe_token().is_some();
let param_list = ast_func.param_list()?; let param_list = ast_func.param_list()?;
let ref_mut_params = ref_mut_params(&param_list); let ref_mut_params = ref_mut_params(&param_list);
let self_name = self_name(ast_func); let self_name = self_name(ast_func);
format_to!(example, "use {};\n\n", build_path(ast_func, ctx)?); format_to!(example, "use {use_path};\n\n");
if let Some(self_name) = &self_name { if let Some(self_name) = &self_name {
if let Some(mtbl) = is_ref_mut_self(ast_func) { if let Some(mut_) = is_ref_mut_self(ast_func) {
let mtbl = if mtbl == true { " mut" } else { "" }; let mut_ = if mut_ == true { "mut " } else { "" };
format_to!(example, "let{} {} = ;\n", mtbl, self_name); format_to!(example, "let {mut_}{self_name} = ;\n");
} }
} }
for param_name in &ref_mut_params { for param_name in &ref_mut_params {
format_to!(example, "let mut {} = ;\n", param_name); format_to!(example, "let mut {param_name} = ;\n");
} }
// Call the function, check result // Call the function, check result
let function_call = function_call(ast_func, &param_list, self_name.as_deref(), is_unsafe)?; let function_call = function_call(ast_func, &param_list, self_name.as_deref(), is_unsafe)?;
if returns_a_value(ast_func, ctx) { if returns_a_value(ast_func, ctx) {
if count_parameters(&param_list) < 3 { if count_parameters(&param_list) < 3 {
format_to!(example, "assert_eq!({}, );\n", function_call); format_to!(example, "assert_eq!({function_call}, );\n");
} else { } else {
format_to!(example, "let result = {};\n", function_call); format_to!(example, "let result = {function_call};\n");
example.push_str("assert_eq!(result, );\n"); example.push_str("assert_eq!(result, );\n");
} }
} else { } else {
format_to!(example, "{};\n", function_call); format_to!(example, "{function_call};\n");
} }
// Check the mutated values // Check the mutated values
if is_ref_mut_self(ast_func) == Some(true) { if let Some(self_name) = &self_name {
format_to!(example, "assert_eq!({}, );", self_name?); if is_ref_mut_self(ast_func) == Some(true) {
format_to!(example, "assert_eq!({self_name}, );");
}
} }
for param_name in &ref_mut_params { for param_name in &ref_mut_params {
format_to!(example, "assert_eq!({}, );", param_name); format_to!(example, "assert_eq!({param_name}, );");
} }
Some(example) Some(example)
} }
@ -189,7 +193,8 @@ fn introduction_builder(ast_func: &ast::Fn, ctx: &AssistContext<'_>) -> Option<S
let intro_for_new = || { let intro_for_new = || {
let is_new = name == "new"; let is_new = name == "new";
if is_new && ret_ty == self_ty { if is_new && ret_ty == self_ty {
Some(format!("Creates a new [`{}`].", linkable_self_ty?)) let self_ty = linkable_self_ty?;
Some(format!("Creates a new [`{self_ty}`]."))
} else { } else {
None None
} }
@ -214,7 +219,9 @@ fn introduction_builder(ast_func: &ast::Fn, ctx: &AssistContext<'_>) -> Option<S
} else { } else {
"" ""
}; };
Some(format!("Returns{reference} the {what} of this [`{}`].", linkable_self_ty?))
let self_ty = linkable_self_ty?;
Some(format!("Returns{reference} the {what} of this [`{self_ty}`]."))
} }
_ => None, _ => None,
}; };
@ -228,7 +235,9 @@ fn introduction_builder(ast_func: &ast::Fn, ctx: &AssistContext<'_>) -> Option<S
if what == "len" { if what == "len" {
what = "length".into() what = "length".into()
}; };
Some(format!("Sets the {what} of this [`{}`].", linkable_self_ty?))
let self_ty = linkable_self_ty?;
Some(format!("Sets the {what} of this [`{self_ty}`]."))
}; };
if let Some(intro) = intro_for_new() { if let Some(intro) = intro_for_new() {
@ -404,7 +413,7 @@ fn arguments_from_params(param_list: &ast::ParamList) -> String {
// instance `TuplePat`) could be managed later. // instance `TuplePat`) could be managed later.
Some(ast::Pat::IdentPat(ident_pat)) => match ident_pat.name() { Some(ast::Pat::IdentPat(ident_pat)) => match ident_pat.name() {
Some(name) => match is_a_ref_mut_param(&param) { Some(name) => match is_a_ref_mut_param(&param) {
true => format!("&mut {}", name), true => format!("&mut {name}"),
false => name.to_string(), false => name.to_string(),
}, },
None => "_".to_string(), None => "_".to_string(),
@ -424,14 +433,15 @@ fn function_call(
let name = ast_func.name()?; let name = ast_func.name()?;
let arguments = arguments_from_params(param_list); let arguments = arguments_from_params(param_list);
let function_call = if param_list.self_param().is_some() { let function_call = if param_list.self_param().is_some() {
format!("{}.{}({})", self_name?, name, arguments) let self_ = self_name?;
format!("{self_}.{name}({arguments})")
} else if let Some(implementation) = self_partial_type(ast_func) { } else if let Some(implementation) = self_partial_type(ast_func) {
format!("{}::{}({})", implementation, name, arguments) format!("{implementation}::{name}({arguments})")
} else { } else {
format!("{}({})", name, arguments) format!("{name}({arguments})")
}; };
match is_unsafe { match is_unsafe {
true => Some(format!("unsafe {{ {} }}", function_call)), true => Some(format!("unsafe {{ {function_call} }}")),
false => Some(function_call), false => Some(function_call),
} }
} }
@ -469,8 +479,8 @@ fn build_path(ast_func: &ast::Fn, ctx: &AssistContext<'_>) -> Option<String> {
.unwrap_or_else(|| "*".into()); .unwrap_or_else(|| "*".into());
let module_def: ModuleDef = ctx.sema.to_def(ast_func)?.module(ctx.db()).into(); let module_def: ModuleDef = ctx.sema.to_def(ast_func)?.module(ctx.db()).into();
match module_def.canonical_path(ctx.db()) { match module_def.canonical_path(ctx.db()) {
Some(path) => Some(format!("{}::{}::{}", crate_name, path, leaf)), Some(path) => Some(format!("{crate_name}::{path}::{leaf}")),
None => Some(format!("{}::{}", crate_name, leaf)), None => Some(format!("{crate_name}::{leaf}")),
} }
} }

View file

@ -61,21 +61,15 @@ pub(crate) fn generate_enum_is_method(acc: &mut Assists, ctx: &AssistContext<'_>
"Generate an `is_` method for this enum variant", "Generate an `is_` method for this enum variant",
target, target,
|builder| { |builder| {
let vis = parent_enum.visibility().map_or(String::new(), |v| format!("{} ", v)); let vis = parent_enum.visibility().map_or(String::new(), |v| format!("{v} "));
let method = format!( let method = format!(
" /// Returns `true` if the {} is [`{variant}`]. " /// Returns `true` if the {enum_lowercase_name} is [`{variant_name}`].
/// ///
/// [`{variant}`]: {}::{variant} /// [`{variant_name}`]: {enum_name}::{variant_name}
#[must_use] #[must_use]
{}fn {}(&self) -> bool {{ {vis}fn {fn_name}(&self) -> bool {{
matches!(self, Self::{variant}{}) matches!(self, Self::{variant_name}{pattern_suffix})
}}", }}",
enum_lowercase_name,
enum_name,
vis,
fn_name,
pattern_suffix,
variant = variant_name
); );
add_method_to_adt(builder, &parent_enum, impl_def, &method); add_method_to_adt(builder, &parent_enum, impl_def, &method);

View file

@ -116,6 +116,14 @@ fn generate_enum_projection_method(
assist_description: &str, assist_description: &str,
props: ProjectionProps, props: ProjectionProps,
) -> Option<()> { ) -> Option<()> {
let ProjectionProps {
fn_name_prefix,
self_param,
return_prefix,
return_suffix,
happy_case,
sad_case,
} = props;
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 parent_enum = ast::Adt::Enum(variant.parent_enum()); let parent_enum = ast::Adt::Enum(variant.parent_enum());
@ -125,7 +133,7 @@ fn generate_enum_projection_method(
let (field,) = record.fields().collect_tuple()?; let (field,) = record.fields().collect_tuple()?;
let name = field.name()?.to_string(); let name = field.name()?.to_string();
let ty = field.ty()?; let ty = field.ty()?;
let pattern_suffix = format!(" {{ {} }}", name); let pattern_suffix = format!(" {{ {name} }}");
(pattern_suffix, ty, name) (pattern_suffix, ty, name)
} }
ast::StructKind::Tuple(tuple) => { ast::StructKind::Tuple(tuple) => {
@ -136,8 +144,7 @@ fn generate_enum_projection_method(
ast::StructKind::Unit => return None, ast::StructKind::Unit => return None,
}; };
let fn_name = let fn_name = format!("{}_{}", fn_name_prefix, &to_lower_snake_case(&variant_name.text()));
format!("{}_{}", props.fn_name_prefix, &to_lower_snake_case(&variant_name.text()));
// Return early if we've found an existing new fn // Return early if we've found an existing new fn
let impl_def = find_struct_impl(ctx, &parent_enum, &fn_name)?; let impl_def = find_struct_impl(ctx, &parent_enum, &fn_name)?;
@ -149,27 +156,15 @@ fn generate_enum_projection_method(
assist_description, assist_description,
target, target,
|builder| { |builder| {
let vis = parent_enum.visibility().map_or(String::new(), |v| format!("{} ", v)); let vis = parent_enum.visibility().map_or(String::new(), |v| format!("{v} "));
let method = format!( let method = format!(
" {0}fn {1}({2}) -> {3}{4}{5} {{ " {vis}fn {fn_name}({self_param}) -> {return_prefix}{field_type}{return_suffix} {{
if let Self::{6}{7} = self {{ if let Self::{variant_name}{pattern_suffix} = self {{
{8}({9}) {happy_case}({bound_name})
}} else {{ }} else {{
{10} {sad_case}
}} }}
}}", }}");
vis,
fn_name,
props.self_param,
props.return_prefix,
field_type.syntax(),
props.return_suffix,
variant_name,
pattern_suffix,
props.happy_case,
bound_name,
props.sad_case,
);
add_method_to_adt(builder, &parent_enum, impl_def, &method); add_method_to_adt(builder, &parent_enum, impl_def, &method);
}, },

View file

@ -56,23 +56,18 @@ pub(crate) fn generate_from_impl_for_enum(
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 from_trait = format!("From<{}>", field_type.syntax()); let from_trait = format!("From<{field_type}>");
let impl_code = if let Some(name) = field_name { let impl_code = if let Some(name) = field_name {
format!( format!(
r#" fn from({0}: {1}) -> Self {{ r#" fn from({name}: {field_type}) -> Self {{
Self::{2} {{ {0} }} Self::{variant_name} {{ {name} }}
}}"#, }}"#
name.text(),
field_type.syntax(),
variant_name,
) )
} else { } else {
format!( format!(
r#" fn from(v: {}) -> Self {{ r#" fn from(v: {field_type}) -> Self {{
Self::{}(v) Self::{variant_name}(v)
}}"#, }}"#
field_type.syntax(),
variant_name,
) )
}; };
let from_impl = generate_trait_impl_text(&enum_, &from_trait, &impl_code); let from_impl = generate_trait_impl_text(&enum_, &from_trait, &impl_code);

View file

@ -179,7 +179,7 @@ fn add_func_to_accumulator(
let function_template = function_builder.render(adt_name.is_some()); let function_template = function_builder.render(adt_name.is_some());
let mut func = function_template.to_string(ctx.config.snippet_cap); let mut func = function_template.to_string(ctx.config.snippet_cap);
if let Some(name) = adt_name { if let Some(name) = adt_name {
func = format!("\n{}impl {} {{\n{}\n{}}}", indent, name, func, indent); func = format!("\n{indent}impl {name} {{\n{func}\n{indent}}}");
} }
builder.edit_file(file); builder.edit_file(file);
match ctx.config.snippet_cap { match ctx.config.snippet_cap {
@ -212,23 +212,26 @@ struct FunctionTemplate {
impl FunctionTemplate { impl FunctionTemplate {
fn to_string(&self, cap: Option<SnippetCap>) -> String { fn to_string(&self, cap: Option<SnippetCap>) -> String {
let Self { leading_ws, fn_def, ret_type, should_focus_return_type, trailing_ws, tail_expr } =
self;
let f = match cap { let f = match cap {
Some(cap) => { Some(cap) => {
let cursor = if self.should_focus_return_type { let cursor = if *should_focus_return_type {
// Focus the return type if there is one // Focus the return type if there is one
match self.ret_type { match ret_type {
Some(ref ret_type) => ret_type.syntax(), Some(ret_type) => ret_type.syntax(),
None => self.tail_expr.syntax(), None => tail_expr.syntax(),
} }
} else { } else {
self.tail_expr.syntax() tail_expr.syntax()
}; };
render_snippet(cap, self.fn_def.syntax(), Cursor::Replace(cursor)) render_snippet(cap, fn_def.syntax(), Cursor::Replace(cursor))
} }
None => self.fn_def.to_string(), None => fn_def.to_string(),
}; };
format!("{}{}{}", self.leading_ws, f, self.trailing_ws) format!("{leading_ws}{f}{trailing_ws}")
} }
} }
@ -330,9 +333,9 @@ impl FunctionBuilder {
let mut indent = IndentLevel::from_node(&it); let mut indent = IndentLevel::from_node(&it);
if is_method { if is_method {
indent = indent + 1; indent = indent + 1;
leading_ws = format!("{}", indent); leading_ws = format!("{indent}");
} else { } else {
leading_ws = format!("\n\n{}", indent); leading_ws = format!("\n\n{indent}");
} }
fn_def = fn_def.indent(indent); fn_def = fn_def.indent(indent);
@ -340,9 +343,10 @@ impl FunctionBuilder {
} }
GeneratedFunctionTarget::InEmptyItemList(it) => { GeneratedFunctionTarget::InEmptyItemList(it) => {
let indent = IndentLevel::from_node(&it); let indent = IndentLevel::from_node(&it);
leading_ws = format!("\n{}", indent + 1); let leading_indent = indent + 1;
fn_def = fn_def.indent(indent + 1); leading_ws = format!("\n{leading_indent}");
trailing_ws = format!("\n{}", indent); fn_def = fn_def.indent(leading_indent);
trailing_ws = format!("\n{indent}");
} }
}; };

View file

@ -108,9 +108,9 @@ pub(crate) fn generate_getter_impl(
buf.push('\n'); buf.push('\n');
} }
let vis = strukt.visibility().map_or(String::new(), |v| format!("{} ", v)); let vis = strukt.visibility().map_or(String::new(), |v| format!("{v} "));
let (ty, body) = if mutable { let (ty, body) = if mutable {
(format!("&mut {}", field_ty), format!("&mut self.{}", field_name)) (format!("&mut {field_ty}"), format!("&mut self.{field_name}"))
} else { } else {
(|| { (|| {
let krate = ctx.sema.scope(field_ty.syntax())?.krate(); let krate = ctx.sema.scope(field_ty.syntax())?.krate();
@ -126,19 +126,15 @@ pub(crate) fn generate_getter_impl(
) )
}) })
})() })()
.unwrap_or_else(|| (format!("&{}", field_ty), format!("&self.{}", field_name))) .unwrap_or_else(|| (format!("&{field_ty}"), format!("&self.{field_name}")))
}; };
let mut_ = mutable.then(|| "mut ").unwrap_or_default();
format_to!( format_to!(
buf, buf,
" {}fn {}(&{}self) -> {} {{ " {vis}fn {fn_name}(&{mut_}self) -> {ty} {{
{} {body}
}}", }}"
vis,
fn_name,
mutable.then(|| "mut ").unwrap_or_default(),
ty,
body,
); );
let start_offset = impl_def let start_offset = impl_def

View file

@ -28,7 +28,7 @@ pub(crate) fn generate_impl(acc: &mut Assists, ctx: &AssistContext<'_>) -> Optio
acc.add( acc.add(
AssistId("generate_impl", AssistKind::Generate), AssistId("generate_impl", AssistKind::Generate),
format!("Generate impl for `{}`", name), format!("Generate impl for `{name}`"),
target, target,
|edit| { |edit| {
let start_offset = nominal.syntax().text_range().end(); let start_offset = nominal.syntax().text_range().end();

View file

@ -51,11 +51,13 @@ pub(crate) fn generate_new(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option
buf.push('\n'); buf.push('\n');
} }
let vis = strukt.visibility().map_or(String::new(), |v| format!("{} ", v)); let vis = strukt.visibility().map_or(String::new(), |v| format!("{v} "));
let trivial_constructors = field_list let trivial_constructors = field_list
.fields() .fields()
.map(|f| { .map(|f| {
let name = f.name()?;
let ty = ctx.sema.resolve_type(&f.ty()?)?; let ty = ctx.sema.resolve_type(&f.ty()?)?;
let item_in_ns = hir::ItemInNs::from(hir::ModuleDef::from(ty.as_adt()?)); let item_in_ns = hir::ItemInNs::from(hir::ModuleDef::from(ty.as_adt()?));
@ -72,7 +74,7 @@ pub(crate) fn generate_new(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option
&ty, &ty,
)?; )?;
Some(format!("{}: {}", f.name()?.syntax(), expr)) Some(format!("{name}: {expr}"))
}) })
.collect::<Vec<_>>(); .collect::<Vec<_>>();
@ -81,7 +83,10 @@ pub(crate) fn generate_new(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option
.enumerate() .enumerate()
.filter_map(|(i, f)| { .filter_map(|(i, f)| {
if trivial_constructors[i].is_none() { if trivial_constructors[i].is_none() {
Some(format!("{}: {}", f.name()?.syntax(), f.ty()?.syntax())) let name = f.name()?;
let ty = f.ty()?;
Some(format!("{name}: {ty}"))
} else { } else {
None None
} }
@ -101,7 +106,7 @@ pub(crate) fn generate_new(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option
}) })
.format(", "); .format(", ");
format_to!(buf, " {}fn new({}) -> Self {{ Self {{ {} }} }}", vis, params, fields); format_to!(buf, " {vis}fn new({params}) -> Self {{ Self {{ {fields} }} }}");
let start_offset = impl_def let start_offset = impl_def
.and_then(|impl_def| find_impl_block_start(impl_def, &mut buf)) .and_then(|impl_def| find_impl_block_start(impl_def, &mut buf))

View file

@ -39,7 +39,7 @@ pub(crate) fn generate_setter(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opt
let impl_def = find_struct_impl( let impl_def = find_struct_impl(
ctx, ctx,
&ast::Adt::Struct(strukt.clone()), &ast::Adt::Struct(strukt.clone()),
format!("set_{}", fn_name).as_str(), format!("set_{fn_name}").as_str(),
)?; )?;
let target = field.syntax().text_range(); let target = field.syntax().text_range();
@ -55,18 +55,12 @@ pub(crate) fn generate_setter(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opt
buf.push('\n'); buf.push('\n');
} }
let vis = strukt.visibility().map_or(String::new(), |v| format!("{} ", v)); let vis = strukt.visibility().map_or(String::new(), |v| format!("{v} "));
format_to!( format_to!(
buf, buf,
" {}fn set_{}(&mut self, {}: {}) {{ " {vis}fn set_{fn_name}(&mut self, {fn_name}: {field_ty}) {{
self.{} = {}; self.{fn_name} = {fn_name};
}}", }}"
vis,
fn_name,
fn_name,
field_ty,
fn_name,
fn_name,
); );
let start_offset = impl_def let start_offset = impl_def