mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-11-14 17:07:26 +00:00
Invert if should be smart about is_some, is_none, is_ok, is_err
This commit is contained in:
parent
e65d48d1fb
commit
1d129a7172
3 changed files with 45 additions and 2 deletions
|
@ -106,4 +106,22 @@ mod tests {
|
|||
"fn f() { i<|>f let Some(_) = Some(1) { 1 } else { 0 } }",
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn invert_if_option_case() {
|
||||
check_assist(
|
||||
invert_if,
|
||||
"fn f() { if<|> doc_style.is_some() { Class::DocComment } else { Class::Comment } }",
|
||||
"fn f() { if doc_style.is_none() { Class::Comment } else { Class::DocComment } }",
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn invert_if_result_case() {
|
||||
check_assist(
|
||||
invert_if,
|
||||
"fn f() { i<|>f doc_style.is_err() { Class::Err } else { Class::Ok } }",
|
||||
"fn f() { if doc_style.is_ok() { Class::Ok } else { Class::Err } }",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ use syntax::{
|
|||
ast::{self, make, NameOwner},
|
||||
AstNode, Direction,
|
||||
SyntaxKind::*,
|
||||
SyntaxNode, TextSize, T,
|
||||
SyntaxNode, SyntaxText, TextSize, T,
|
||||
};
|
||||
|
||||
use crate::assist_config::SnippetCap;
|
||||
|
@ -179,6 +179,25 @@ fn invert_special_case(expr: &ast::Expr) -> Option<ast::Expr> {
|
|||
ast::BinOp::EqualityTest => bin.replace_op(T![!=]).map(|it| it.into()),
|
||||
_ => None,
|
||||
},
|
||||
ast::Expr::MethodCallExpr(mce) => {
|
||||
const IS_SOME_TEXT: &str = "is_some";
|
||||
const IS_NONE_TEXT: &str = "is_none";
|
||||
const IS_OK_TEXT: &str = "is_ok";
|
||||
const IS_ERR_TEXT: &str = "is_err";
|
||||
|
||||
let name = mce.name_ref()?;
|
||||
let name_text = name.text();
|
||||
|
||||
let caller = || -> Option<SyntaxText> { Some(mce.receiver()?.syntax().text()) };
|
||||
|
||||
match name_text {
|
||||
x if x == IS_SOME_TEXT => make::expr_method_call(IS_NONE_TEXT, caller),
|
||||
x if x == IS_NONE_TEXT => make::expr_method_call(IS_SOME_TEXT, caller),
|
||||
x if x == IS_OK_TEXT => make::expr_method_call(IS_ERR_TEXT, caller),
|
||||
x if x == IS_ERR_TEXT => make::expr_method_call(IS_OK_TEXT, caller),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
ast::Expr::PrefixExpr(pe) if pe.op_kind()? == ast::PrefixOp::Not => pe.expr(),
|
||||
// FIXME:
|
||||
// ast::Expr::Literal(true | false )
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
use itertools::Itertools;
|
||||
use stdx::format_to;
|
||||
|
||||
use crate::{ast, AstNode, SourceFile, SyntaxKind, SyntaxNode, SyntaxToken};
|
||||
use crate::{ast, AstNode, SourceFile, SyntaxKind, SyntaxNode, SyntaxText, SyntaxToken};
|
||||
|
||||
pub fn name(text: &str) -> ast::Name {
|
||||
ast_from_text(&format!("mod {};", text))
|
||||
|
@ -137,6 +137,12 @@ pub fn expr_prefix(op: SyntaxKind, expr: ast::Expr) -> ast::Expr {
|
|||
pub fn expr_call(f: ast::Expr, arg_list: ast::ArgList) -> ast::Expr {
|
||||
expr_from_text(&format!("{}{}", f, arg_list))
|
||||
}
|
||||
pub fn expr_method_call<F>(text: &str, caller: F) -> Option<ast::Expr>
|
||||
where
|
||||
F: FnOnce() -> Option<SyntaxText>,
|
||||
{
|
||||
try_expr_from_text(&format!("{}.{}()", caller()?, text))
|
||||
}
|
||||
fn expr_from_text(text: &str) -> ast::Expr {
|
||||
ast_from_text(&format!("const C: () = {};", text))
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue