mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-11-10 15:14:32 +00:00
Auto merge of #12662 - DorianListens:dscheidt/extract-function-duplicate-name, r=DorianListens
fix: Extract Function produces duplicate fn names This change fixes #10037, in more or less the most naive fashion possible. We continue to start with the hardcoded default of "fun_name", and now append a counter to the end of it if that name is already in scope. In the future, we can probably apply more heuristics here to wind up with more useful names by default, but for now this resolves the immediate problem.
This commit is contained in:
commit
cc0bb71e25
1 changed files with 70 additions and 2 deletions
|
@ -81,7 +81,8 @@ pub(crate) fn extract_function(acc: &mut Assists, ctx: &AssistContext) -> Option
|
|||
|
||||
let anchor = if self_param.is_some() { Anchor::Method } else { Anchor::Freestanding };
|
||||
let insert_after = node_to_insert_after(&body, anchor)?;
|
||||
let module = ctx.sema.scope(&insert_after)?.module();
|
||||
let semantics_scope = ctx.sema.scope(&insert_after)?;
|
||||
let module = semantics_scope.module();
|
||||
|
||||
let ret_ty = body.return_ty(ctx)?;
|
||||
let control_flow = body.external_control_flow(ctx, &container_info)?;
|
||||
|
@ -105,8 +106,10 @@ pub(crate) fn extract_function(acc: &mut Assists, ctx: &AssistContext) -> Option
|
|||
let params =
|
||||
body.extracted_function_params(ctx, &container_info, locals_used.iter().copied());
|
||||
|
||||
let name = make_function_name(&semantics_scope);
|
||||
|
||||
let fun = Function {
|
||||
name: make::name_ref("fun_name"),
|
||||
name,
|
||||
self_param,
|
||||
params,
|
||||
control_flow,
|
||||
|
@ -155,6 +158,21 @@ pub(crate) fn extract_function(acc: &mut Assists, ctx: &AssistContext) -> Option
|
|||
)
|
||||
}
|
||||
|
||||
fn make_function_name(semantics_scope: &hir::SemanticsScope) -> ast::NameRef {
|
||||
let mut names_in_scope = vec![];
|
||||
semantics_scope.process_all_names(&mut |name, _| names_in_scope.push(name.to_string()));
|
||||
|
||||
let default_name = "fun_name";
|
||||
|
||||
let mut name = default_name.to_string();
|
||||
let mut counter = 0;
|
||||
while names_in_scope.contains(&name) {
|
||||
counter += 1;
|
||||
name = format!("{}{}", &default_name, counter)
|
||||
}
|
||||
make::name_ref(&name)
|
||||
}
|
||||
|
||||
/// Try to guess what user wants to extract
|
||||
///
|
||||
/// We have basically have two cases:
|
||||
|
@ -4709,6 +4727,56 @@ fn $0fun_name() {
|
|||
/* a comment */
|
||||
let x = 0;
|
||||
}
|
||||
"#,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn it_should_not_generate_duplicate_function_names() {
|
||||
check_assist(
|
||||
extract_function,
|
||||
r#"
|
||||
fn fun_name() {
|
||||
$0let x = 0;$0
|
||||
}
|
||||
"#,
|
||||
r#"
|
||||
fn fun_name() {
|
||||
fun_name1();
|
||||
}
|
||||
|
||||
fn $0fun_name1() {
|
||||
let x = 0;
|
||||
}
|
||||
"#,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_increment_suffix_until_it_finds_space() {
|
||||
check_assist(
|
||||
extract_function,
|
||||
r#"
|
||||
fn fun_name1() {
|
||||
let y = 0;
|
||||
}
|
||||
|
||||
fn fun_name() {
|
||||
$0let x = 0;$0
|
||||
}
|
||||
"#,
|
||||
r#"
|
||||
fn fun_name1() {
|
||||
let y = 0;
|
||||
}
|
||||
|
||||
fn fun_name() {
|
||||
fun_name2();
|
||||
}
|
||||
|
||||
fn $0fun_name2() {
|
||||
let x = 0;
|
||||
}
|
||||
"#,
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue