Invert boolean literals in assist negation logic

This commit is contained in:
Lukas Wirth
2021-07-06 20:30:26 +02:00
parent 112e53f10e
commit d91704cac5
6 changed files with 50 additions and 51 deletions

View File

@@ -144,6 +144,7 @@ fn group_label(import_candidate: &ImportCandidate) -> GroupLabel {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use crate::tests::{check_assist, check_assist_not_applicable, check_assist_target}; use crate::tests::{check_assist, check_assist_not_applicable, check_assist_target};
#[test] #[test]

View File

@@ -211,7 +211,7 @@ mod tests {
r#" r#"
fn main() { fn main() {
bar(); bar();
if !true { if false {
return; return;
} }
foo(); foo();
@@ -387,7 +387,7 @@ mod tests {
r#" r#"
fn main() { fn main() {
while true { while true {
if !true { if false {
continue; continue;
} }
foo(); foo();
@@ -444,7 +444,7 @@ mod tests {
r#" r#"
fn main() { fn main() {
loop { loop {
if !true { if false {
continue; continue;
} }
foo(); foo();

View File

@@ -65,8 +65,7 @@ pub(crate) fn inline_local_variable(acc: &mut Assists, ctx: &AssistContext) -> O
Some(u) => u, Some(u) => u,
None => return Some(false), None => return Some(false),
}; };
Some( let initializer = matches!(
!(matches!(
initializer_expr, initializer_expr,
ast::Expr::CallExpr(_) ast::Expr::CallExpr(_)
| ast::Expr::IndexExpr(_) | ast::Expr::IndexExpr(_)
@@ -81,7 +80,8 @@ pub(crate) fn inline_local_variable(acc: &mut Assists, ctx: &AssistContext) -> O
| ast::Expr::PathExpr(_) | ast::Expr::PathExpr(_)
| ast::Expr::BlockExpr(_) | ast::Expr::BlockExpr(_)
| ast::Expr::EffectExpr(_), | ast::Expr::EffectExpr(_),
) || matches!( );
let parent = matches!(
usage_parent, usage_parent,
ast::Expr::CallExpr(_) ast::Expr::CallExpr(_)
| ast::Expr::TupleExpr(_) | ast::Expr::TupleExpr(_)
@@ -92,8 +92,8 @@ pub(crate) fn inline_local_variable(acc: &mut Assists, ctx: &AssistContext) -> O
| ast::Expr::BreakExpr(_) | ast::Expr::BreakExpr(_)
| ast::Expr::ReturnExpr(_) | ast::Expr::ReturnExpr(_)
| ast::Expr::MatchExpr(_) | ast::Expr::MatchExpr(_)
)), );
) Some(!(initializer || parent))
}) })
.collect::<Option<_>>() .collect::<Option<_>>()
.map(|b| (file_id, b)) .map(|b| (file_id, b))

View File

@@ -11,7 +11,6 @@ use crate::{
// Assist: invert_if // Assist: invert_if
// //
// Apply invert_if
// This transforms if expressions of the form `if !x {A} else {B}` into `if x {B} else {A}` // This transforms if expressions of the form `if !x {A} else {B}` into `if x {B} else {A}`
// This also works with `!=`. This assist can only be applied with the cursor // This also works with `!=`. This assist can only be applied with the cursor
// on `if`. // on `if`.

View File

@@ -41,8 +41,6 @@ pub(crate) fn replace_let_with_if_let(acc: &mut Assists, ctx: &AssistContext) ->
let let_stmt = let_kw.ancestors().find_map(ast::LetStmt::cast)?; let let_stmt = let_kw.ancestors().find_map(ast::LetStmt::cast)?;
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 happy_variant = TryEnum::from_ty(&ctx.sema, &ty).map(|it| it.happy_case());
let target = let_kw.text_range(); let target = let_kw.text_range();
acc.add( acc.add(
@@ -50,6 +48,9 @@ pub(crate) fn replace_let_with_if_let(acc: &mut Assists, ctx: &AssistContext) ->
"Replace with if-let", "Replace with if-let",
target, target,
|edit| { |edit| {
let ty = ctx.sema.type_of_expr(&init);
let happy_variant =
ty.and_then(|ty| TryEnum::from_ty(&ctx.sema, &ty)).map(|it| it.happy_case());
let pat = match happy_variant { let pat = match happy_variant {
None => original_pat, None => original_pat,
Some(var_name) => { Some(var_name) => {

View File

@@ -4,7 +4,6 @@ pub(crate) mod suggest_name;
use std::ops; use std::ops;
use ast::TypeBoundsOwner;
use hir::{Adt, HasSource, Semantics}; use hir::{Adt, HasSource, Semantics};
use ide_db::{ use ide_db::{
helpers::{FamousDefs, SnippetCap}, helpers::{FamousDefs, SnippetCap},
@@ -14,10 +13,11 @@ use ide_db::{
use itertools::Itertools; use itertools::Itertools;
use stdx::format_to; use stdx::format_to;
use syntax::{ use syntax::{
ast::edit::AstNodeEdit, ast::{
ast::AttrsOwner, self,
ast::NameOwner, edit::{self, AstNodeEdit},
ast::{self, edit, make, ArgListOwner, GenericParamsOwner}, make, ArgListOwner, AttrsOwner, GenericParamsOwner, NameOwner, TypeBoundsOwner,
},
ted, AstNode, Direction, SmolStr, ted, AstNode, Direction, SmolStr,
SyntaxKind::*, SyntaxKind::*,
SyntaxNode, TextSize, T, SyntaxNode, TextSize, T,
@@ -70,11 +70,7 @@ pub fn extract_trivial_expression(block: &ast::BlockExpr) -> Option<ast::Expr> {
pub fn test_related_attribute(fn_def: &ast::Fn) -> Option<ast::Attr> { pub fn test_related_attribute(fn_def: &ast::Fn) -> Option<ast::Attr> {
fn_def.attrs().find_map(|attr| { fn_def.attrs().find_map(|attr| {
let path = attr.path()?; let path = attr.path()?;
if path.syntax().text().to_string().contains("test") { path.syntax().text().to_string().contains("test").then(|| attr)
Some(attr)
} else {
None
}
}) })
} }
@@ -216,10 +212,7 @@ pub(crate) fn invert_boolean_expression(
sema: &Semantics<RootDatabase>, sema: &Semantics<RootDatabase>,
expr: ast::Expr, expr: ast::Expr,
) -> ast::Expr { ) -> ast::Expr {
if let Some(expr) = invert_special_case(sema, &expr) { invert_special_case(sema, &expr).unwrap_or_else(|| make::expr_prefix(T![!], expr))
return expr;
}
make::expr_prefix(T![!], expr)
} }
fn invert_special_case(sema: &Semantics<RootDatabase>, expr: &ast::Expr) -> Option<ast::Expr> { fn invert_special_case(sema: &Semantics<RootDatabase>, expr: &ast::Expr) -> Option<ast::Expr> {
@@ -264,8 +257,13 @@ fn invert_special_case(sema: &Semantics<RootDatabase>, expr: &ast::Expr) -> Opti
pe.expr() pe.expr()
} }
} }
// FIXME: ast::Expr::Literal(lit) => match lit.kind() {
// ast::Expr::Literal(true | false ) ast::LiteralKind::Bool(b) => match b {
true => Some(ast::Expr::Literal(make::expr_literal("false"))),
false => Some(ast::Expr::Literal(make::expr_literal("true"))),
},
_ => None,
},
_ => None, _ => None,
} }
} }