This commit is contained in:
Aleksey Kladov 2020-05-20 10:28:58 +02:00
parent 36a5ca9a84
commit 2e74df4e2b

View File

@ -19,23 +19,21 @@ use crate::{AssistContext, AssistId, Assists};
// fn foo() -> Result<i32, > { Ok(42i32) } // fn foo() -> Result<i32, > { Ok(42i32) }
// ``` // ```
pub(crate) fn change_return_type_to_result(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { pub(crate) fn change_return_type_to_result(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
let fn_def = ctx.find_node_at_offset::<ast::FnDef>()?; let ret_type = ctx.find_node_at_offset::<ast::RetType>()?;
let ret_type = &fn_def.ret_type()?.type_ref()?; // FIXME: extend to lambdas as well
if ret_type.syntax().text().to_string().starts_with("Result<") { let fn_def = ret_type.syntax().parent().and_then(ast::FnDef::cast)?;
let type_ref = &ret_type.type_ref()?;
if type_ref.syntax().text().to_string().starts_with("Result<") {
return None; return None;
} }
let block_expr = &fn_def.body()?; let block_expr = &fn_def.body()?;
let cursor_in_ret_type =
fn_def.ret_type()?.syntax().text_range().contains_range(ctx.frange.range);
if !cursor_in_ret_type {
return None;
}
acc.add( acc.add(
AssistId("change_return_type_to_result"), AssistId("change_return_type_to_result"),
"Change return type to Result", "Change return type to Result",
ret_type.syntax().text_range(), type_ref.syntax().text_range(),
|edit| { |edit| {
let mut tail_return_expr_collector = TailReturnCollector::new(); let mut tail_return_expr_collector = TailReturnCollector::new();
tail_return_expr_collector.collect_jump_exprs(block_expr, false); tail_return_expr_collector.collect_jump_exprs(block_expr, false);
@ -44,10 +42,10 @@ pub(crate) fn change_return_type_to_result(acc: &mut Assists, ctx: &AssistContex
for ret_expr_arg in tail_return_expr_collector.exprs_to_wrap { for ret_expr_arg in tail_return_expr_collector.exprs_to_wrap {
edit.replace_node_and_indent(&ret_expr_arg, format!("Ok({})", ret_expr_arg)); edit.replace_node_and_indent(&ret_expr_arg, format!("Ok({})", ret_expr_arg));
} }
edit.replace_node_and_indent(ret_type.syntax(), format!("Result<{}, >", ret_type)); edit.replace_node_and_indent(type_ref.syntax(), format!("Result<{}, >", type_ref));
if let Some(node_start) = result_insertion_offset(&ret_type) { if let Some(node_start) = result_insertion_offset(&type_ref) {
edit.set_cursor(node_start + TextSize::of(&format!("Result<{}, ", ret_type))); edit.set_cursor(node_start + TextSize::of(&format!("Result<{}, ", type_ref)));
} }
}, },
) )