mirror of
https://github.com/rust-lang/rust.git
synced 2025-06-05 11:48:30 +00:00
Migrate assists to format args captures, part 1
This commit is contained in:
parent
0f46f2773a
commit
d439fb2bc8
@ -69,14 +69,14 @@ pub(crate) fn add_explicit_type(acc: &mut Assists, ctx: &AssistContext<'_>) -> O
|
||||
let inferred_type = ty.display_source_code(ctx.db(), module.into()).ok()?;
|
||||
acc.add(
|
||||
AssistId("add_explicit_type", AssistKind::RefactorRewrite),
|
||||
format!("Insert explicit type `{}`", inferred_type),
|
||||
format!("Insert explicit type `{inferred_type}`"),
|
||||
pat_range,
|
||||
|builder| match ascribed_ty {
|
||||
Some(ascribed_ty) => {
|
||||
builder.replace(ascribed_ty.syntax().text_range(), inferred_type);
|
||||
}
|
||||
None => {
|
||||
builder.insert(pat_range.end(), format!(": {}", inferred_type));
|
||||
builder.insert(pat_range.end(), format!(": {inferred_type}"));
|
||||
}
|
||||
},
|
||||
)
|
||||
|
@ -35,16 +35,16 @@ pub(crate) fn add_return_type(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opt
|
||||
match builder_edit_pos {
|
||||
InsertOrReplace::Insert(insert_pos, needs_whitespace) => {
|
||||
let preceeding_whitespace = if needs_whitespace { " " } else { "" };
|
||||
builder.insert(insert_pos, &format!("{}-> {} ", preceeding_whitespace, ty))
|
||||
builder.insert(insert_pos, &format!("{preceeding_whitespace}-> {ty} "))
|
||||
}
|
||||
InsertOrReplace::Replace(text_range) => {
|
||||
builder.replace(text_range, &format!("-> {}", ty))
|
||||
builder.replace(text_range, &format!("-> {ty}"))
|
||||
}
|
||||
}
|
||||
if let FnType::Closure { wrap_expr: true } = fn_type {
|
||||
cov_mark::hit!(wrap_closure_non_block_expr);
|
||||
// `|x| x` becomes `|x| -> T x` which is invalid, so wrap it in a block
|
||||
builder.replace(tail_expr.syntax().text_range(), &format!("{{{}}}", tail_expr));
|
||||
builder.replace(tail_expr.syntax().text_range(), &format!("{{{tail_expr}}}"));
|
||||
}
|
||||
},
|
||||
)
|
||||
|
@ -93,12 +93,13 @@ pub(crate) fn add_turbo_fish(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opti
|
||||
builder.trigger_signature_help();
|
||||
match ctx.config.snippet_cap {
|
||||
Some(cap) => {
|
||||
let snip = format!("::<{}>", get_snippet_fish_head(number_of_arguments));
|
||||
let fish_head = get_snippet_fish_head(number_of_arguments);
|
||||
let snip = format!("::<{fish_head}>");
|
||||
builder.insert_snippet(cap, ident.text_range().end(), snip)
|
||||
}
|
||||
None => {
|
||||
let fish_head = std::iter::repeat("_").take(number_of_arguments).format(", ");
|
||||
let snip = format!("::<{}>", fish_head);
|
||||
let snip = format!("::<{fish_head}>");
|
||||
builder.insert(ident.text_range().end(), snip);
|
||||
}
|
||||
}
|
||||
@ -109,7 +110,7 @@ pub(crate) fn add_turbo_fish(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opti
|
||||
/// This will create a snippet string with tabstops marked
|
||||
fn get_snippet_fish_head(number_of_arguments: usize) -> String {
|
||||
let mut fish_head = (1..number_of_arguments)
|
||||
.format_with("", |i, f| f(&format_args!("${{{}:_}}, ", i)))
|
||||
.format_with("", |i, f| f(&format_args!("${{{i}:_}}, ")))
|
||||
.to_string();
|
||||
|
||||
// tabstop 0 is a special case and always the last one
|
||||
|
@ -123,20 +123,20 @@ pub(crate) fn apply_demorgan(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opti
|
||||
let lhs_range = lhs.syntax().text_range();
|
||||
let not_lhs = invert_boolean_expression(lhs);
|
||||
|
||||
edit.replace(lhs_range, format!("!({}", not_lhs.syntax().text()));
|
||||
edit.replace(lhs_range, format!("!({not_lhs}"));
|
||||
}
|
||||
|
||||
if let Some(rhs) = terms.pop_back() {
|
||||
let rhs_range = rhs.syntax().text_range();
|
||||
let not_rhs = invert_boolean_expression(rhs);
|
||||
|
||||
edit.replace(rhs_range, format!("{})", not_rhs.syntax().text()));
|
||||
edit.replace(rhs_range, format!("{not_rhs})"));
|
||||
}
|
||||
|
||||
for term in terms {
|
||||
let term_range = term.syntax().text_range();
|
||||
let not_term = invert_boolean_expression(term);
|
||||
edit.replace(term_range, not_term.syntax().text());
|
||||
edit.replace(term_range, not_term.to_string());
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -127,10 +127,12 @@ pub(crate) fn auto_import(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<
|
||||
.sort_by_key(|import| Reverse(relevance_score(ctx, import, current_module.as_ref())));
|
||||
|
||||
for import in proposed_imports {
|
||||
let import_path = import.import_path;
|
||||
|
||||
acc.add_group(
|
||||
&group_label,
|
||||
AssistId("auto_import", AssistKind::QuickFix),
|
||||
format!("Import `{}`", import.import_path),
|
||||
format!("Import `{import_path}`"),
|
||||
range,
|
||||
|builder| {
|
||||
let scope = match scope.clone() {
|
||||
@ -138,7 +140,7 @@ pub(crate) fn auto_import(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<
|
||||
ImportScope::Module(it) => ImportScope::Module(builder.make_mut(it)),
|
||||
ImportScope::Block(it) => ImportScope::Block(builder.make_mut(it)),
|
||||
};
|
||||
insert_use(&scope, mod_path_to_ast(&import.import_path), &ctx.config.insert_use);
|
||||
insert_use(&scope, mod_path_to_ast(&import_path), &ctx.config.insert_use);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
@ -54,16 +54,17 @@ fn block_to_line(acc: &mut Assists, comment: ast::Comment) -> Option<()> {
|
||||
|
||||
let indent_spaces = indentation.to_string();
|
||||
let output = lines
|
||||
.map(|l| l.trim_start_matches(&indent_spaces))
|
||||
.map(|l| {
|
||||
.map(|line| {
|
||||
let line = line.trim_start_matches(&indent_spaces);
|
||||
|
||||
// Don't introduce trailing whitespace
|
||||
if l.is_empty() {
|
||||
if line.is_empty() {
|
||||
line_prefix.to_string()
|
||||
} else {
|
||||
format!("{} {}", line_prefix, l.trim_start_matches(&indent_spaces))
|
||||
format!("{line_prefix} {line}")
|
||||
}
|
||||
})
|
||||
.join(&format!("\n{}", indent_spaces));
|
||||
.join(&format!("\n{indent_spaces}"));
|
||||
|
||||
edit.replace(target, output)
|
||||
},
|
||||
@ -96,7 +97,7 @@ fn line_to_block(acc: &mut Assists, comment: ast::Comment) -> Option<()> {
|
||||
let block_prefix =
|
||||
CommentKind { shape: CommentShape::Block, ..comment.kind() }.prefix();
|
||||
|
||||
let output = format!("{}\n{}\n{}*/", block_prefix, block_comment_body, indentation);
|
||||
let output = format!("{block_prefix}\n{block_comment_body}\n{indentation}*/");
|
||||
|
||||
edit.replace(target, output)
|
||||
},
|
||||
|
@ -32,19 +32,19 @@ pub(crate) fn convert_integer_literal(acc: &mut Assists, ctx: &AssistContext<'_>
|
||||
}
|
||||
|
||||
let mut converted = match target_radix {
|
||||
Radix::Binary => format!("0b{:b}", value),
|
||||
Radix::Octal => format!("0o{:o}", value),
|
||||
Radix::Binary => format!("0b{value:b}"),
|
||||
Radix::Octal => format!("0o{value:o}"),
|
||||
Radix::Decimal => value.to_string(),
|
||||
Radix::Hexadecimal => format!("0x{:X}", value),
|
||||
Radix::Hexadecimal => format!("0x{value:X}"),
|
||||
};
|
||||
|
||||
let label = format!("Convert {} to {}{}", literal, converted, suffix.unwrap_or_default());
|
||||
|
||||
// Appends the type suffix back into the new literal if it exists.
|
||||
if let Some(suffix) = suffix {
|
||||
converted.push_str(suffix);
|
||||
}
|
||||
|
||||
let label = format!("Convert {literal} to {converted}");
|
||||
|
||||
acc.add_group(
|
||||
&group_id,
|
||||
AssistId("convert_integer_literal", AssistKind::RefactorInline),
|
||||
|
@ -86,9 +86,9 @@ pub(crate) fn convert_into_to_from(acc: &mut Assists, ctx: &AssistContext<'_>) -
|
||||
impl_.syntax().text_range(),
|
||||
|builder| {
|
||||
builder.replace(src_type.syntax().text_range(), dest_type.to_string());
|
||||
builder.replace(ast_trait.syntax().text_range(), format!("From<{}>", src_type));
|
||||
builder.replace(ast_trait.syntax().text_range(), format!("From<{src_type}>"));
|
||||
builder.replace(into_fn_return.syntax().text_range(), "-> Self");
|
||||
builder.replace(into_fn_params.syntax().text_range(), format!("(val: {})", src_type));
|
||||
builder.replace(into_fn_params.syntax().text_range(), format!("(val: {src_type})"));
|
||||
builder.replace(into_fn_name.syntax().text_range(), "from");
|
||||
|
||||
for s in selfs {
|
||||
|
@ -119,19 +119,19 @@ pub(crate) fn convert_for_loop_with_for_each(
|
||||
{
|
||||
// We have either "for x in &col" and col implements a method called iter
|
||||
// or "for x in &mut col" and col implements a method called iter_mut
|
||||
format_to!(buf, "{}.{}()", expr_behind_ref, method);
|
||||
format_to!(buf, "{expr_behind_ref}.{method}()");
|
||||
} else if let ast::Expr::RangeExpr(..) = iterable {
|
||||
// range expressions need to be parenthesized for the syntax to be correct
|
||||
format_to!(buf, "({})", iterable);
|
||||
format_to!(buf, "({iterable})");
|
||||
} else if impls_core_iter(&ctx.sema, &iterable) {
|
||||
format_to!(buf, "{}", iterable);
|
||||
format_to!(buf, "{iterable}");
|
||||
} else if let ast::Expr::RefExpr(_) = iterable {
|
||||
format_to!(buf, "({}).into_iter()", iterable);
|
||||
format_to!(buf, "({iterable}).into_iter()");
|
||||
} else {
|
||||
format_to!(buf, "{}.into_iter()", iterable);
|
||||
format_to!(buf, "{iterable}.into_iter()");
|
||||
}
|
||||
|
||||
format_to!(buf, ".for_each(|{}| {});", pat, body);
|
||||
format_to!(buf, ".for_each(|{pat}| {body});");
|
||||
|
||||
builder.replace(for_loop.syntax().text_range(), buf)
|
||||
},
|
||||
|
@ -80,7 +80,7 @@ fn binders_to_str(binders: &[(Name, bool)], addmut: bool) -> String {
|
||||
.map(
|
||||
|(ident, ismut)| {
|
||||
if *ismut && addmut {
|
||||
format!("mut {}", ident)
|
||||
format!("mut {ident}")
|
||||
} else {
|
||||
ident.to_string()
|
||||
}
|
||||
@ -93,7 +93,7 @@ fn binders_to_str(binders: &[(Name, bool)], addmut: bool) -> String {
|
||||
} else if binders.len() == 1 {
|
||||
vars
|
||||
} else {
|
||||
format!("({})", vars)
|
||||
format!("({vars})")
|
||||
}
|
||||
}
|
||||
|
||||
@ -153,7 +153,7 @@ pub(crate) fn convert_let_else_to_match(acc: &mut Assists, ctx: &AssistContext<'
|
||||
|
||||
let only_expr = let_else_block.statements().next().is_none();
|
||||
let branch2 = match &let_else_block.tail_expr() {
|
||||
Some(tail) if only_expr => format!("{},", tail.syntax().text()),
|
||||
Some(tail) if only_expr => format!("{tail},"),
|
||||
_ => let_else_block.syntax().text().to_string(),
|
||||
};
|
||||
let replace = if binders.is_empty() {
|
||||
|
@ -226,7 +226,13 @@ fn edit_field_references(
|
||||
}
|
||||
|
||||
fn generate_names(fields: impl Iterator<Item = ast::TupleField>) -> Vec<ast::Name> {
|
||||
fields.enumerate().map(|(i, _)| ast::make::name(&format!("field{}", i + 1))).collect()
|
||||
fields
|
||||
.enumerate()
|
||||
.map(|(i, _)| {
|
||||
let idx = i + 1;
|
||||
ast::make::name(&format!("field{idx}"))
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -58,16 +58,16 @@ pub(crate) fn convert_two_arm_bool_match_to_matches_macro(
|
||||
target_range,
|
||||
|builder| {
|
||||
let mut arm_str = String::new();
|
||||
if let Some(ref pat) = first_arm.pat() {
|
||||
if let Some(pat) = &first_arm.pat() {
|
||||
arm_str += &pat.to_string();
|
||||
}
|
||||
if let Some(ref guard) = first_arm.guard() {
|
||||
arm_str += &format!(" {}", &guard.to_string());
|
||||
if let Some(guard) = &first_arm.guard() {
|
||||
arm_str += &format!(" {guard}");
|
||||
}
|
||||
if invert_matches {
|
||||
builder.replace(target_range, format!("!matches!({}, {})", expr, arm_str));
|
||||
builder.replace(target_range, format!("!matches!({expr}, {arm_str})"));
|
||||
} else {
|
||||
builder.replace(target_range, format!("matches!({}, {})", expr, arm_str));
|
||||
builder.replace(target_range, format!("matches!({expr}, {arm_str})"));
|
||||
}
|
||||
},
|
||||
)
|
||||
|
@ -133,7 +133,7 @@ fn generate_name(
|
||||
_usages: &Option<UsageSearchResult>,
|
||||
) -> String {
|
||||
// FIXME: detect if name already used
|
||||
format!("_{}", index)
|
||||
format!("_{index}")
|
||||
}
|
||||
|
||||
enum RefType {
|
||||
@ -168,12 +168,12 @@ fn edit_tuple_assignment(
|
||||
let add_cursor = |text: &str| {
|
||||
// place cursor on first tuple item
|
||||
let first_tuple = &data.field_names[0];
|
||||
text.replacen(first_tuple, &format!("$0{}", first_tuple), 1)
|
||||
text.replacen(first_tuple, &format!("$0{first_tuple}"), 1)
|
||||
};
|
||||
|
||||
// with sub_pattern: keep original tuple and add subpattern: `tup @ (_0, _1)`
|
||||
if in_sub_pattern {
|
||||
let text = format!(" @ {}", tuple_pat);
|
||||
let text = format!(" @ {tuple_pat}");
|
||||
match ctx.config.snippet_cap {
|
||||
Some(cap) => {
|
||||
let snip = add_cursor(&text);
|
||||
@ -314,9 +314,9 @@ struct RefData {
|
||||
impl RefData {
|
||||
fn format(&self, field_name: &str) -> String {
|
||||
match (self.needs_deref, self.needs_parentheses) {
|
||||
(true, true) => format!("(*{})", field_name),
|
||||
(true, false) => format!("*{}", field_name),
|
||||
(false, true) => format!("({})", field_name),
|
||||
(true, true) => format!("(*{field_name})"),
|
||||
(true, false) => format!("*{field_name}"),
|
||||
(false, true) => format!("({field_name})"),
|
||||
(false, false) => field_name.to_string(),
|
||||
}
|
||||
}
|
||||
|
@ -181,7 +181,7 @@ fn make_function_name(semantics_scope: &hir::SemanticsScope<'_>) -> ast::NameRef
|
||||
let mut counter = 0;
|
||||
while names_in_scope.contains(&name) {
|
||||
counter += 1;
|
||||
name = format!("{}{}", &default_name, counter)
|
||||
name = format!("{default_name}{counter}")
|
||||
}
|
||||
make::name_ref(&name)
|
||||
}
|
||||
@ -1291,19 +1291,23 @@ fn make_call(ctx: &AssistContext<'_>, fun: &Function, indent: IndentLevel) -> St
|
||||
match fun.outliving_locals.as_slice() {
|
||||
[] => {}
|
||||
[var] => {
|
||||
format_to!(buf, "let {}{} = ", mut_modifier(var), var.local.name(ctx.db()))
|
||||
let modifier = mut_modifier(var);
|
||||
let name = var.local.name(ctx.db());
|
||||
format_to!(buf, "let {modifier}{name} = ")
|
||||
}
|
||||
vars => {
|
||||
buf.push_str("let (");
|
||||
let bindings = vars.iter().format_with(", ", |local, f| {
|
||||
f(&format_args!("{}{}", mut_modifier(local), local.local.name(ctx.db())))
|
||||
let modifier = mut_modifier(local);
|
||||
let name = local.local.name(ctx.db());
|
||||
f(&format_args!("{modifier}{name}"))
|
||||
});
|
||||
format_to!(buf, "{}", bindings);
|
||||
format_to!(buf, "{bindings}");
|
||||
buf.push_str(") = ");
|
||||
}
|
||||
}
|
||||
|
||||
format_to!(buf, "{}", expr);
|
||||
format_to!(buf, "{expr}");
|
||||
let insert_comma = fun
|
||||
.body
|
||||
.parent()
|
||||
@ -1447,6 +1451,8 @@ fn format_function(
|
||||
new_indent: IndentLevel,
|
||||
) -> String {
|
||||
let mut fn_def = String::new();
|
||||
|
||||
let fun_name = &fun.name;
|
||||
let params = fun.make_param_list(ctx, module);
|
||||
let ret_ty = fun.make_ret_ty(ctx, module);
|
||||
let body = make_body(ctx, old_indent, new_indent, fun);
|
||||
@ -1454,42 +1460,28 @@ fn format_function(
|
||||
let async_kw = if fun.control_flow.is_async { "async " } else { "" };
|
||||
let unsafe_kw = if fun.control_flow.is_unsafe { "unsafe " } else { "" };
|
||||
let (generic_params, where_clause) = make_generic_params_and_where_clause(ctx, fun);
|
||||
|
||||
format_to!(fn_def, "\n\n{new_indent}{const_kw}{async_kw}{unsafe_kw}");
|
||||
match ctx.config.snippet_cap {
|
||||
Some(_) => format_to!(
|
||||
fn_def,
|
||||
"\n\n{}{}{}{}fn $0{}",
|
||||
new_indent,
|
||||
const_kw,
|
||||
async_kw,
|
||||
unsafe_kw,
|
||||
fun.name,
|
||||
),
|
||||
None => format_to!(
|
||||
fn_def,
|
||||
"\n\n{}{}{}{}fn {}",
|
||||
new_indent,
|
||||
const_kw,
|
||||
async_kw,
|
||||
unsafe_kw,
|
||||
fun.name,
|
||||
),
|
||||
Some(_) => format_to!(fn_def, "fn $0{fun_name}"),
|
||||
None => format_to!(fn_def, "fn {fun_name}"),
|
||||
}
|
||||
|
||||
if let Some(generic_params) = generic_params {
|
||||
format_to!(fn_def, "{}", generic_params);
|
||||
format_to!(fn_def, "{generic_params}");
|
||||
}
|
||||
|
||||
format_to!(fn_def, "{}", params);
|
||||
format_to!(fn_def, "{params}");
|
||||
|
||||
if let Some(ret_ty) = ret_ty {
|
||||
format_to!(fn_def, " {}", ret_ty);
|
||||
format_to!(fn_def, " {ret_ty}");
|
||||
}
|
||||
|
||||
if let Some(where_clause) = where_clause {
|
||||
format_to!(fn_def, " {}", where_clause);
|
||||
format_to!(fn_def, " {where_clause}");
|
||||
}
|
||||
|
||||
format_to!(fn_def, " {}", body);
|
||||
format_to!(fn_def, " {body}");
|
||||
|
||||
fn_def
|
||||
}
|
||||
|
@ -127,7 +127,7 @@ pub(crate) fn extract_module(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opti
|
||||
for item in items_to_be_processed {
|
||||
let item = item.indent(IndentLevel(1));
|
||||
let mut indented_item = String::new();
|
||||
format_to!(indented_item, "{}{}", new_item_indent, item.to_string());
|
||||
format_to!(indented_item, "{new_item_indent}{item}");
|
||||
body_items.push(indented_item);
|
||||
}
|
||||
|
||||
@ -137,30 +137,28 @@ pub(crate) fn extract_module(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opti
|
||||
let mut impl_body_def = String::new();
|
||||
|
||||
if let Some(self_ty) = impl_.self_ty() {
|
||||
format_to!(
|
||||
impl_body_def,
|
||||
"{}impl {} {{\n{}\n{}}}",
|
||||
old_item_indent + 1,
|
||||
self_ty.to_string(),
|
||||
body,
|
||||
old_item_indent + 1
|
||||
);
|
||||
|
||||
{
|
||||
let impl_indent = old_item_indent + 1;
|
||||
format_to!(
|
||||
impl_body_def,
|
||||
"{impl_indent}impl {self_ty} {{\n{body}\n{impl_indent}}}",
|
||||
);
|
||||
}
|
||||
body = impl_body_def;
|
||||
|
||||
// Add the import for enum/struct corresponding to given impl block
|
||||
module.make_use_stmt_of_node_with_super(self_ty.syntax());
|
||||
for item in module.use_items {
|
||||
let mut indented_item = String::new();
|
||||
format_to!(indented_item, "{}{}", old_item_indent + 1, item.to_string());
|
||||
body = format!("{}\n\n{}", indented_item, body);
|
||||
let item_indent = old_item_indent + 1;
|
||||
body = format!("{item_indent}{item}\n\n{body}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mut module_def = String::new();
|
||||
|
||||
format_to!(module_def, "mod {} {{\n{}\n{}}}", module.name, body, old_item_indent);
|
||||
let module_name = module.name;
|
||||
format_to!(module_def, "mod {module_name} {{\n{body}\n{old_item_indent}}}");
|
||||
|
||||
let mut usages_to_be_updated_for_curr_file = vec![];
|
||||
for usages_to_be_updated_for_file in usages_to_be_processed {
|
||||
@ -199,7 +197,7 @@ pub(crate) fn extract_module(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opti
|
||||
builder.delete(range);
|
||||
}
|
||||
|
||||
builder.insert(impl_.syntax().text_range().end(), format!("\n\n{}", module_def));
|
||||
builder.insert(impl_.syntax().text_range().end(), format!("\n\n{module_def}"));
|
||||
} else {
|
||||
builder.replace(module.text_range, module_def)
|
||||
}
|
||||
@ -343,9 +341,10 @@ impl Module {
|
||||
&& !self.text_range.contains_range(desc.text_range())
|
||||
{
|
||||
if let Some(name_ref) = ast::NameRef::cast(desc) {
|
||||
let mod_name = self.name;
|
||||
return Some((
|
||||
name_ref.syntax().text_range(),
|
||||
format!("{}::{}", self.name, name_ref),
|
||||
format!("{mod_name}::{name_ref}"),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
@ -296,10 +296,14 @@ fn create_struct_def(
|
||||
|
||||
fn update_variant(variant: &ast::Variant, generics: Option<ast::GenericParamList>) -> Option<()> {
|
||||
let name = variant.name()?;
|
||||
let ty = generics
|
||||
let generic_args = generics
|
||||
.filter(|generics| generics.generic_params().count() > 0)
|
||||
.map(|generics| make::ty(&format!("{}{}", &name.text(), generics.to_generic_args())))
|
||||
.unwrap_or_else(|| make::ty(&name.text()));
|
||||
.map(|generics| generics.to_generic_args());
|
||||
// FIXME: replace with a `ast::make` constructor
|
||||
let ty = match generic_args {
|
||||
Some(generic_args) => make::ty(&format!("{name}{generic_args}")),
|
||||
None => make::ty(&name.text()),
|
||||
};
|
||||
|
||||
// change from a record to a tuple field list
|
||||
let tuple_field = make::tuple_field(None, ty);
|
||||
|
@ -1,8 +1,7 @@
|
||||
use either::Either;
|
||||
use ide_db::syntax_helpers::node_ext::walk_ty;
|
||||
use itertools::Itertools;
|
||||
use syntax::{
|
||||
ast::{self, edit::IndentLevel, AstNode, HasGenericParams, HasName},
|
||||
ast::{self, edit::IndentLevel, make, AstNode, HasGenericParams, HasName},
|
||||
match_ast,
|
||||
};
|
||||
|
||||
@ -64,41 +63,29 @@ pub(crate) fn extract_type_alias(acc: &mut Assists, ctx: &AssistContext<'_>) ->
|
||||
known_generics.extend(it.generic_params());
|
||||
}
|
||||
let generics = collect_used_generics(&ty, &known_generics);
|
||||
let generic_params =
|
||||
generics.map(|it| make::generic_param_list(it.into_iter().cloned()));
|
||||
|
||||
let replacement = if !generics.is_empty() {
|
||||
format!(
|
||||
"Type<{}>",
|
||||
generics.iter().format_with(", ", |generic, f| {
|
||||
match generic {
|
||||
ast::GenericParam::ConstParam(cp) => f(&cp.name().unwrap()),
|
||||
ast::GenericParam::LifetimeParam(lp) => f(&lp.lifetime().unwrap()),
|
||||
ast::GenericParam::TypeParam(tp) => f(&tp.name().unwrap()),
|
||||
}
|
||||
})
|
||||
)
|
||||
} else {
|
||||
String::from("Type")
|
||||
};
|
||||
let ty_args = generic_params
|
||||
.as_ref()
|
||||
.map_or(String::new(), |it| it.to_generic_args().to_string());
|
||||
let replacement = format!("Type{ty_args}");
|
||||
builder.replace(target, replacement);
|
||||
|
||||
let indent = IndentLevel::from_node(node);
|
||||
let generics = if !generics.is_empty() {
|
||||
format!("<{}>", generics.iter().format(", "))
|
||||
} else {
|
||||
String::new()
|
||||
};
|
||||
let generic_params = generic_params.map_or(String::new(), |it| it.to_string());
|
||||
match ctx.config.snippet_cap {
|
||||
Some(cap) => {
|
||||
builder.insert_snippet(
|
||||
cap,
|
||||
insert_pos,
|
||||
format!("type $0Type{} = {};\n\n{}", generics, ty, indent),
|
||||
format!("type $0Type{generic_params} = {ty};\n\n{indent}"),
|
||||
);
|
||||
}
|
||||
None => {
|
||||
builder.insert(
|
||||
insert_pos,
|
||||
format!("type Type{} = {};\n\n{}", generics, ty, indent),
|
||||
format!("type Type{generic_params} = {ty};\n\n{indent}"),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -109,7 +96,7 @@ pub(crate) fn extract_type_alias(acc: &mut Assists, ctx: &AssistContext<'_>) ->
|
||||
fn collect_used_generics<'gp>(
|
||||
ty: &ast::Type,
|
||||
known_generics: &'gp [ast::GenericParam],
|
||||
) -> Vec<&'gp ast::GenericParam> {
|
||||
) -> Option<Vec<&'gp ast::GenericParam>> {
|
||||
// can't use a closure -> closure here cause lifetime inference fails for that
|
||||
fn find_lifetime(text: &str) -> impl Fn(&&ast::GenericParam) -> bool + '_ {
|
||||
move |gp: &&ast::GenericParam| match gp {
|
||||
@ -198,7 +185,8 @@ fn collect_used_generics<'gp>(
|
||||
ast::GenericParam::LifetimeParam(_) => 0,
|
||||
ast::GenericParam::TypeParam(_) => 1,
|
||||
});
|
||||
generics
|
||||
|
||||
Some(generics).filter(|it| it.len() > 0)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -91,13 +91,13 @@ pub(crate) fn extract_variable(acc: &mut Assists, ctx: &AssistContext<'_>) -> Op
|
||||
|
||||
match anchor {
|
||||
Anchor::Before(_) | Anchor::Replace(_) => {
|
||||
format_to!(buf, "let {}{} = {}", var_modifier, var_name, reference_modifier)
|
||||
format_to!(buf, "let {var_modifier}{var_name} = {reference_modifier}")
|
||||
}
|
||||
Anchor::WrapInBlock(_) => {
|
||||
format_to!(buf, "{{ let {} = {}", var_name, reference_modifier)
|
||||
format_to!(buf, "{{ let {var_name} = {reference_modifier}")
|
||||
}
|
||||
};
|
||||
format_to!(buf, "{}", to_extract.syntax());
|
||||
format_to!(buf, "{to_extract}");
|
||||
|
||||
if let Anchor::Replace(stmt) = anchor {
|
||||
cov_mark::hit!(test_extract_var_expr_stmt);
|
||||
@ -107,8 +107,8 @@ pub(crate) fn extract_variable(acc: &mut Assists, ctx: &AssistContext<'_>) -> Op
|
||||
match ctx.config.snippet_cap {
|
||||
Some(cap) => {
|
||||
let snip = buf.replace(
|
||||
&format!("let {}{}", var_modifier, var_name),
|
||||
&format!("let {}$0{}", var_modifier, var_name),
|
||||
&format!("let {var_modifier}{var_name}"),
|
||||
&format!("let {var_modifier}$0{var_name}"),
|
||||
);
|
||||
edit.replace_snippet(cap, expr_range, snip)
|
||||
}
|
||||
@ -135,8 +135,8 @@ pub(crate) fn extract_variable(acc: &mut Assists, ctx: &AssistContext<'_>) -> Op
|
||||
match ctx.config.snippet_cap {
|
||||
Some(cap) => {
|
||||
let snip = buf.replace(
|
||||
&format!("let {}{}", var_modifier, var_name),
|
||||
&format!("let {}$0{}", var_modifier, var_name),
|
||||
&format!("let {var_modifier}{var_name}"),
|
||||
&format!("let {var_modifier}$0{var_name}"),
|
||||
);
|
||||
edit.insert_snippet(cap, offset, snip)
|
||||
}
|
||||
|
@ -57,8 +57,8 @@ fn add_vis_to_referenced_module_def(acc: &mut Assists, ctx: &AssistContext<'_>)
|
||||
if current_module.krate() == target_module.krate() { "pub(crate)" } else { "pub" };
|
||||
|
||||
let assist_label = match target_name {
|
||||
None => format!("Change visibility to {}", missing_visibility),
|
||||
Some(name) => format!("Change visibility of {} to {}", name, missing_visibility),
|
||||
None => format!("Change visibility to {missing_visibility}"),
|
||||
Some(name) => format!("Change visibility of {name} to {missing_visibility}"),
|
||||
};
|
||||
|
||||
acc.add(AssistId("fix_visibility", AssistKind::QuickFix), assist_label, target, |builder| {
|
||||
@ -68,15 +68,15 @@ fn add_vis_to_referenced_module_def(acc: &mut Assists, ctx: &AssistContext<'_>)
|
||||
Some(current_visibility) => builder.replace_snippet(
|
||||
cap,
|
||||
current_visibility.syntax().text_range(),
|
||||
format!("$0{}", missing_visibility),
|
||||
format!("$0{missing_visibility}"),
|
||||
),
|
||||
None => builder.insert_snippet(cap, offset, format!("$0{} ", missing_visibility)),
|
||||
None => builder.insert_snippet(cap, offset, format!("$0{missing_visibility} ")),
|
||||
},
|
||||
None => match current_visibility {
|
||||
Some(current_visibility) => {
|
||||
builder.replace(current_visibility.syntax().text_range(), missing_visibility)
|
||||
}
|
||||
None => builder.insert(offset, format!("{} ", missing_visibility)),
|
||||
None => builder.insert(offset, format!("{missing_visibility} ")),
|
||||
},
|
||||
}
|
||||
})
|
||||
@ -114,7 +114,7 @@ fn add_vis_to_referenced_record_field(acc: &mut Assists, ctx: &AssistContext<'_>
|
||||
|
||||
let target_name = record_field_def.name(ctx.db());
|
||||
let assist_label =
|
||||
format!("Change visibility of {}.{} to {}", parent_name, target_name, missing_visibility);
|
||||
format!("Change visibility of {parent_name}.{target_name} to {missing_visibility}");
|
||||
|
||||
acc.add(AssistId("fix_visibility", AssistKind::QuickFix), assist_label, target, |builder| {
|
||||
builder.edit_file(target_file);
|
||||
@ -123,15 +123,15 @@ fn add_vis_to_referenced_record_field(acc: &mut Assists, ctx: &AssistContext<'_>
|
||||
Some(current_visibility) => builder.replace_snippet(
|
||||
cap,
|
||||
current_visibility.syntax().text_range(),
|
||||
format!("$0{}", missing_visibility),
|
||||
format!("$0{missing_visibility}"),
|
||||
),
|
||||
None => builder.insert_snippet(cap, offset, format!("$0{} ", missing_visibility)),
|
||||
None => builder.insert_snippet(cap, offset, format!("$0{missing_visibility} ")),
|
||||
},
|
||||
None => match current_visibility {
|
||||
Some(current_visibility) => {
|
||||
builder.replace(current_visibility.syntax().text_range(), missing_visibility)
|
||||
}
|
||||
None => builder.insert(offset, format!("{} ", missing_visibility)),
|
||||
None => builder.insert(offset, format!("{missing_visibility} ")),
|
||||
},
|
||||
}
|
||||
})
|
||||
|
Loading…
Reference in New Issue
Block a user