From 14e18bfa38dc445a07109cd8fbd98d6ff804f076 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Sat, 3 Jul 2021 17:13:56 +0200 Subject: [PATCH] Merge the inline function/method assists into `inline_call` --- .../{inline_function.rs => inline_call.rs} | 125 ++++++------------ crates/ide_assists/src/lib.rs | 5 +- crates/ide_assists/src/tests/generated.rs | 4 +- crates/syntax/src/ast/make.rs | 3 +- 4 files changed, 47 insertions(+), 90 deletions(-) rename crates/ide_assists/src/handlers/{inline_function.rs => inline_call.rs} (73%) diff --git a/crates/ide_assists/src/handlers/inline_function.rs b/crates/ide_assists/src/handlers/inline_call.rs similarity index 73% rename from crates/ide_assists/src/handlers/inline_function.rs rename to crates/ide_assists/src/handlers/inline_call.rs index b00569bf01..93f8edb1a8 100644 --- a/crates/ide_assists/src/handlers/inline_function.rs +++ b/crates/ide_assists/src/handlers/inline_call.rs @@ -10,59 +10,9 @@ use crate::{ AssistId, AssistKind, }; -// Assist: inline_method +// Assist: inline_call // -// Inlines a method body. -// -// ``` -// struct Foo(u32); -// impl Foo { -// fn add(self, a: u32) -> Self { -// Foo(self.0 + a) -// } -// } -// fn main() { -// let x = Foo(3).add$0(2); -// } -// ``` -// -> -// ``` -// struct Foo(u32); -// impl Foo { -// fn add(self, a: u32) -> Self { -// Foo(self.0 + a) -// } -// } -// fn main() { -// let x = { -// let this = Foo(3); -// let a = 2; -// Foo(this.0 + a) -// }; -// } -// ``` -pub(crate) fn inline_method(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { - let name_ref: ast::NameRef = ctx.find_node_at_offset()?; - let call = name_ref.syntax().parent().and_then(ast::MethodCallExpr::cast)?; - let receiver = call.receiver()?; - let function = ctx.sema.resolve_method_call(&call)?; - let mut arguments = vec![receiver]; - arguments.extend(call.arg_list()?.args()); - - inline_( - acc, - ctx, - "inline_method", - &format!("Inline `{}`", name_ref), - function, - arguments, - ast::Expr::MethodCallExpr(call), - ) -} - -// Assist: inline_function -// -// Inlines a function body. +// Inlines a function or method body. // // ``` // fn add(a: u32, b: u32) -> u32 { a + b } @@ -81,32 +31,40 @@ pub(crate) fn inline_method(acc: &mut Assists, ctx: &AssistContext) -> Option<() // }; // } // ``` -pub(crate) fn inline_function(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { - let path_expr: ast::PathExpr = ctx.find_node_at_offset()?; - let call = path_expr.syntax().parent().and_then(ast::CallExpr::cast)?; - let path = path_expr.path()?; +pub(crate) fn inline_call(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { + let (label, function, arguments, expr) = + if let Some(path_expr) = ctx.find_node_at_offset::() { + let call = path_expr.syntax().parent().and_then(ast::CallExpr::cast)?; + let path = path_expr.path()?; - let function = match dbg!(ctx.sema.resolve_path(&path)?) { - PathResolution::Def(hir::ModuleDef::Function(f)) - | PathResolution::AssocItem(hir::AssocItem::Function(f)) => f, - _ => return None, - }; - inline_( - acc, - ctx, - "inline_function", - &format!("Inline `{}`", path), - function, - call.arg_list()?.args().collect(), - ast::Expr::CallExpr(call), - ) + let function = match ctx.sema.resolve_path(&path)? { + PathResolution::Def(hir::ModuleDef::Function(f)) + | PathResolution::AssocItem(hir::AssocItem::Function(f)) => f, + _ => return None, + }; + ( + format!("Inline `{}`", path), + function, + call.arg_list()?.args().collect(), + ast::Expr::CallExpr(call), + ) + } else { + let name_ref: ast::NameRef = ctx.find_node_at_offset()?; + let call = name_ref.syntax().parent().and_then(ast::MethodCallExpr::cast)?; + let receiver = call.receiver()?; + let function = ctx.sema.resolve_method_call(&call)?; + let mut arguments = vec![receiver]; + arguments.extend(call.arg_list()?.args()); + (format!("Inline `{}`", name_ref), function, arguments, ast::Expr::MethodCallExpr(call)) + }; + + inline_(acc, ctx, label, function, arguments, expr) } pub(crate) fn inline_( acc: &mut Assists, ctx: &AssistContext, - assist_id: &'static str, - label: &str, + label: String, function: hir::Function, arg_list: Vec, expr: ast::Expr, @@ -133,7 +91,7 @@ pub(crate) fn inline_( if arg_list.len() != params.len() { // Can't inline the function because they've passed the wrong number of // arguments to this function - cov_mark::hit!(inline_function_incorrect_number_of_arguments); + cov_mark::hit!(inline_call_incorrect_number_of_arguments); return None; } @@ -142,11 +100,12 @@ pub(crate) fn inline_( let body = function_source.body()?; acc.add( - AssistId(assist_id, AssistKind::RefactorInline), + AssistId("inline_call", AssistKind::RefactorInline), label, expr.syntax().text_range(), |builder| { // FIXME: emit type ascriptions when a coercion happens? + // FIXME: dont create locals when its not required let statements = new_bindings .map(|(pattern, value)| make::let_stmt(pattern, Some(value)).into()) .chain(body.statements()); @@ -184,7 +143,7 @@ mod tests { #[test] fn no_args_or_return_value_gets_inlined_without_block() { check_assist( - inline_function, + inline_call, r#" fn foo() { println!("Hello, World!"); } fn main() { @@ -205,7 +164,7 @@ fn main() { #[test] fn args_with_side_effects() { check_assist( - inline_function, + inline_call, r#" fn foo(name: String) { println!("Hello, {}!", name); } fn main() { @@ -226,9 +185,9 @@ fn main() { #[test] fn not_applicable_when_incorrect_number_of_parameters_are_provided() { - cov_mark::check!(inline_function_incorrect_number_of_arguments); + cov_mark::check!(inline_call_incorrect_number_of_arguments); check_assist_not_applicable( - inline_function, + inline_call, r#" fn add(a: u32, b: u32) -> u32 { a + b } fn main() { let x = add$0(42); } @@ -239,7 +198,7 @@ fn main() { let x = add$0(42); } #[test] fn function_with_multiple_statements() { check_assist( - inline_function, + inline_call, r#" fn foo(a: u32, b: u32) -> u32 { let x = a + b; @@ -274,7 +233,7 @@ fn main() { #[test] fn function_with_self_param() { check_assist( - inline_function, + inline_call, r#" struct Foo(u32); @@ -311,7 +270,7 @@ fn main() { #[test] fn method_by_val() { check_assist( - inline_method, + inline_call, r#" struct Foo(u32); @@ -348,7 +307,7 @@ fn main() { #[test] fn method_by_ref() { check_assist( - inline_method, + inline_call, r#" struct Foo(u32); @@ -385,7 +344,7 @@ fn main() { #[test] fn method_by_ref_mut() { check_assist( - inline_method, + inline_call, r#" struct Foo(u32); diff --git a/crates/ide_assists/src/lib.rs b/crates/ide_assists/src/lib.rs index ac05491c6a..bc30020f1f 100644 --- a/crates/ide_assists/src/lib.rs +++ b/crates/ide_assists/src/lib.rs @@ -85,7 +85,7 @@ mod handlers { mod generate_new; mod generate_setter; mod infer_function_return_type; - mod inline_function; + mod inline_call; mod inline_local_variable; mod introduce_named_lifetime; mod invert_if; @@ -155,8 +155,7 @@ mod handlers { generate_new::generate_new, generate_setter::generate_setter, infer_function_return_type::infer_function_return_type, - inline_function::inline_function, - inline_function::inline_method, + inline_call::inline_call, inline_local_variable::inline_local_variable, introduce_named_lifetime::introduce_named_lifetime, invert_if::invert_if, diff --git a/crates/ide_assists/src/tests/generated.rs b/crates/ide_assists/src/tests/generated.rs index c3c2131734..cae2ad57eb 100644 --- a/crates/ide_assists/src/tests/generated.rs +++ b/crates/ide_assists/src/tests/generated.rs @@ -919,9 +919,9 @@ fn foo() -> i32 { 42i32 } } #[test] -fn doctest_inline_function() { +fn doctest_inline_call() { check_doc_test( - "inline_function", + "inline_call", r#####" fn add(a: u32, b: u32) -> u32 { a + b } fn main() { diff --git a/crates/syntax/src/ast/make.rs b/crates/syntax/src/ast/make.rs index ea0f27756f..e00ec7f196 100644 --- a/crates/syntax/src/ast/make.rs +++ b/crates/syntax/src/ast/make.rs @@ -338,7 +338,6 @@ pub fn arg_list(args: impl IntoIterator) -> ast::ArgList { } pub fn ident_pat(ref_: bool, mut_: bool, name: ast::Name) -> ast::IdentPat { - use std::fmt::Write as _; let mut s = String::from("fn f("); if ref_ { s.push_str("ref "); @@ -346,7 +345,7 @@ pub fn ident_pat(ref_: bool, mut_: bool, name: ast::Name) -> ast::IdentPat { if mut_ { s.push_str("mut "); } - let _ = write!(s, "{}", name); + format_to!(s, "{}", name); s.push_str(": ())"); ast_from_text(&s) }