mirror of
https://github.com/rust-lang/rust-analyzer
synced 2025-01-14 06:03:58 +00:00
Move shared assist code to utils
This commit is contained in:
parent
549ce9a9cf
commit
73bef854ab
3 changed files with 35 additions and 48 deletions
|
@ -1,6 +1,5 @@
|
||||||
use std::iter::once;
|
use std::iter::once;
|
||||||
|
|
||||||
use hir::Adt;
|
|
||||||
use ra_syntax::{
|
use ra_syntax::{
|
||||||
ast::{
|
ast::{
|
||||||
self,
|
self,
|
||||||
|
@ -12,6 +11,7 @@ use ra_syntax::{
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
assist_ctx::{Assist, AssistCtx},
|
assist_ctx::{Assist, AssistCtx},
|
||||||
|
utils::happy_try_variant,
|
||||||
AssistId,
|
AssistId,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -45,20 +45,10 @@ pub(crate) fn replace_let_with_if_let(ctx: AssistCtx) -> Option<Assist> {
|
||||||
let init = let_stmt.initializer()?;
|
let init = let_stmt.initializer()?;
|
||||||
let original_pat = let_stmt.pat()?;
|
let original_pat = let_stmt.pat()?;
|
||||||
let ty = ctx.sema.type_of_expr(&init)?;
|
let ty = ctx.sema.type_of_expr(&init)?;
|
||||||
let enum_ = match ty.as_adt() {
|
let happy_variant = happy_try_variant(ctx.sema, &ty);
|
||||||
Some(Adt::Enum(it)) => it,
|
|
||||||
_ => return None,
|
|
||||||
};
|
|
||||||
let happy_case =
|
|
||||||
[("Result", "Ok"), ("Option", "Some")].iter().find_map(|(known_type, happy_case)| {
|
|
||||||
if &enum_.name(ctx.db).to_string() == known_type {
|
|
||||||
return Some(happy_case);
|
|
||||||
}
|
|
||||||
None
|
|
||||||
});
|
|
||||||
|
|
||||||
ctx.add_assist(AssistId("replace_let_with_if_let"), "Replace with if-let", |edit| {
|
ctx.add_assist(AssistId("replace_let_with_if_let"), "Replace with if-let", |edit| {
|
||||||
let with_placeholder: ast::Pat = match happy_case {
|
let with_placeholder: ast::Pat = match happy_variant {
|
||||||
None => make::placeholder_pat().into(),
|
None => make::placeholder_pat().into(),
|
||||||
Some(var_name) => make::tuple_struct_pat(
|
Some(var_name) => make::tuple_struct_pat(
|
||||||
make::path_unqualified(make::path_segment(make::name_ref(var_name))),
|
make::path_unqualified(make::path_segment(make::name_ref(var_name))),
|
||||||
|
|
|
@ -1,12 +1,11 @@
|
||||||
use std::iter;
|
use std::iter;
|
||||||
|
|
||||||
use ra_syntax::{
|
use ra_syntax::{
|
||||||
ast::{self, make},
|
ast::{self, edit::IndentLevel, make},
|
||||||
AstNode,
|
AstNode,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{Assist, AssistCtx, AssistId};
|
use crate::{utils::happy_try_variant, Assist, AssistCtx, AssistId};
|
||||||
use ast::edit::IndentLevel;
|
|
||||||
|
|
||||||
// Assist: replace_unwrap_with_match
|
// Assist: replace_unwrap_with_match
|
||||||
//
|
//
|
||||||
|
@ -38,42 +37,27 @@ pub(crate) fn replace_unwrap_with_match(ctx: AssistCtx) -> Option<Assist> {
|
||||||
}
|
}
|
||||||
let caller = method_call.expr()?;
|
let caller = method_call.expr()?;
|
||||||
let ty = ctx.sema.type_of_expr(&caller)?;
|
let ty = ctx.sema.type_of_expr(&caller)?;
|
||||||
|
let happy_variant = happy_try_variant(ctx.sema, &ty)?;
|
||||||
|
|
||||||
let type_name = ty.as_adt()?.name(ctx.sema.db).to_string();
|
ctx.add_assist(AssistId("replace_unwrap_with_match"), "Replace unwrap with match", |edit| {
|
||||||
|
let ok_path = make::path_unqualified(make::path_segment(make::name_ref(happy_variant)));
|
||||||
|
let it = make::bind_pat(make::name("a")).into();
|
||||||
|
let ok_tuple = make::tuple_struct_pat(ok_path, iter::once(it)).into();
|
||||||
|
|
||||||
for (unwrap_type, variant_name) in [("Result", "Ok"), ("Option", "Some")].iter() {
|
let bind_path = make::path_unqualified(make::path_segment(make::name_ref("a")));
|
||||||
if &type_name == unwrap_type {
|
let ok_arm = make::match_arm(iter::once(ok_tuple), make::expr_path(bind_path));
|
||||||
return ctx.add_assist(
|
|
||||||
AssistId("replace_unwrap_with_match"),
|
|
||||||
"Replace unwrap with match",
|
|
||||||
|edit| {
|
|
||||||
let ok_path =
|
|
||||||
make::path_unqualified(make::path_segment(make::name_ref(variant_name)));
|
|
||||||
let it = make::bind_pat(make::name("a")).into();
|
|
||||||
let ok_tuple = make::tuple_struct_pat(ok_path, iter::once(it)).into();
|
|
||||||
|
|
||||||
let bind_path = make::path_unqualified(make::path_segment(make::name_ref("a")));
|
let unreachable_call = make::unreachable_macro_call().into();
|
||||||
let ok_arm = make::match_arm(iter::once(ok_tuple), make::expr_path(bind_path));
|
let err_arm = make::match_arm(iter::once(make::placeholder_pat().into()), unreachable_call);
|
||||||
|
|
||||||
let unreachable_call = make::unreachable_macro_call().into();
|
let match_arm_list = make::match_arm_list(vec![ok_arm, err_arm]);
|
||||||
let err_arm = make::match_arm(
|
let match_expr = make::expr_match(caller.clone(), match_arm_list);
|
||||||
iter::once(make::placeholder_pat().into()),
|
let match_expr = IndentLevel::from_node(method_call.syntax()).increase_indent(match_expr);
|
||||||
unreachable_call,
|
|
||||||
);
|
|
||||||
|
|
||||||
let match_arm_list = make::match_arm_list(vec![ok_arm, err_arm]);
|
edit.target(method_call.syntax().text_range());
|
||||||
let match_expr = make::expr_match(caller.clone(), match_arm_list);
|
edit.set_cursor(caller.syntax().text_range().start());
|
||||||
let match_expr =
|
edit.replace_ast::<ast::Expr>(method_call.into(), match_expr);
|
||||||
IndentLevel::from_node(method_call.syntax()).increase_indent(match_expr);
|
})
|
||||||
|
|
||||||
edit.target(method_call.syntax().text_range());
|
|
||||||
edit.set_cursor(caller.syntax().text_range().start());
|
|
||||||
edit.replace_ast::<ast::Expr>(method_call.into(), match_expr);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
None
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
//! Assorted functions shared by several assists.
|
//! Assorted functions shared by several assists.
|
||||||
pub(crate) mod insert_use;
|
pub(crate) mod insert_use;
|
||||||
|
|
||||||
use hir::Semantics;
|
use hir::{Adt, Semantics, Type};
|
||||||
use ra_ide_db::RootDatabase;
|
use ra_ide_db::RootDatabase;
|
||||||
use ra_syntax::{
|
use ra_syntax::{
|
||||||
ast::{self, make, NameOwner},
|
ast::{self, make, NameOwner},
|
||||||
|
@ -99,3 +99,16 @@ fn invert_special_case(expr: &ast::Expr) -> Option<ast::Expr> {
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn happy_try_variant(sema: &Semantics<RootDatabase>, ty: &Type) -> Option<&'static str> {
|
||||||
|
let enum_ = match ty.as_adt() {
|
||||||
|
Some(Adt::Enum(it)) => it,
|
||||||
|
_ => return None,
|
||||||
|
};
|
||||||
|
[("Result", "Ok"), ("Option", "Some")].iter().find_map(|(known_type, happy_case)| {
|
||||||
|
if &enum_.name(sema.db).to_string() == known_type {
|
||||||
|
return Some(*happy_case);
|
||||||
|
}
|
||||||
|
None
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue