mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-12-23 08:48:08 +00:00
Merge pull request #20973 from Natural-selection1/demorgan
Some checks failed
rustdoc / rustdoc (push) Has been cancelled
metrics / build_metrics (push) Has been cancelled
metrics / generate_final_metrics (push) Has been cancelled
metrics / other_metrics (ripgrep-13.0.0) (push) Has been cancelled
metrics / other_metrics (self) (push) Has been cancelled
metrics / other_metrics (webrender-2022) (push) Has been cancelled
metrics / other_metrics (diesel-1.4.8) (push) Has been cancelled
metrics / other_metrics (hyper-0.14.18) (push) Has been cancelled
Some checks failed
rustdoc / rustdoc (push) Has been cancelled
metrics / build_metrics (push) Has been cancelled
metrics / generate_final_metrics (push) Has been cancelled
metrics / other_metrics (ripgrep-13.0.0) (push) Has been cancelled
metrics / other_metrics (self) (push) Has been cancelled
metrics / other_metrics (webrender-2022) (push) Has been cancelled
metrics / other_metrics (diesel-1.4.8) (push) Has been cancelled
metrics / other_metrics (hyper-0.14.18) (push) Has been cancelled
fix demorgan assist to handle method call
This commit is contained in:
commit
4bf516ee5a
1 changed files with 53 additions and 29 deletions
|
|
@ -124,40 +124,37 @@ pub(crate) fn apply_demorgan(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opti
|
|||
op_range,
|
||||
|builder| {
|
||||
let make = SyntaxFactory::with_mappings();
|
||||
let paren_expr = bin_expr.syntax().parent().and_then(ast::ParenExpr::cast);
|
||||
let neg_expr = paren_expr
|
||||
.clone()
|
||||
let (target_node, result_expr) = if let Some(neg_expr) = bin_expr
|
||||
.syntax()
|
||||
.parent()
|
||||
.and_then(ast::ParenExpr::cast)
|
||||
.and_then(|paren_expr| paren_expr.syntax().parent())
|
||||
.and_then(ast::PrefixExpr::cast)
|
||||
.filter(|prefix_expr| matches!(prefix_expr.op_kind(), Some(ast::UnaryOp::Not)))
|
||||
.map(ast::Expr::PrefixExpr);
|
||||
|
||||
let mut editor;
|
||||
if let Some(paren_expr) = paren_expr {
|
||||
if let Some(neg_expr) = neg_expr {
|
||||
cov_mark::hit!(demorgan_double_negation);
|
||||
let parent = neg_expr.syntax().parent();
|
||||
editor = builder.make_editor(neg_expr.syntax());
|
||||
|
||||
if parent.is_some_and(|parent| {
|
||||
demorganed.needs_parens_in_place_of(&parent, neg_expr.syntax())
|
||||
}) {
|
||||
cov_mark::hit!(demorgan_keep_parens_for_op_precedence2);
|
||||
editor.replace(neg_expr.syntax(), make.expr_paren(demorganed).syntax());
|
||||
} else {
|
||||
editor.replace(neg_expr.syntax(), demorganed.syntax());
|
||||
};
|
||||
} else {
|
||||
cov_mark::hit!(demorgan_double_parens);
|
||||
editor = builder.make_editor(paren_expr.syntax());
|
||||
|
||||
editor.replace(paren_expr.syntax(), add_bang_paren(&make, demorganed).syntax());
|
||||
}
|
||||
{
|
||||
cov_mark::hit!(demorgan_double_negation);
|
||||
(ast::Expr::from(neg_expr).syntax().clone(), demorganed)
|
||||
} else if let Some(paren_expr) =
|
||||
bin_expr.syntax().parent().and_then(ast::ParenExpr::cast)
|
||||
{
|
||||
cov_mark::hit!(demorgan_double_parens);
|
||||
(paren_expr.syntax().clone(), add_bang_paren(&make, demorganed))
|
||||
} else {
|
||||
editor = builder.make_editor(bin_expr.syntax());
|
||||
editor.replace(bin_expr.syntax(), add_bang_paren(&make, demorganed).syntax());
|
||||
}
|
||||
(bin_expr.syntax().clone(), add_bang_paren(&make, demorganed))
|
||||
};
|
||||
|
||||
let final_expr = if target_node
|
||||
.parent()
|
||||
.is_some_and(|p| result_expr.needs_parens_in_place_of(&p, &target_node))
|
||||
{
|
||||
cov_mark::hit!(demorgan_keep_parens_for_op_precedence2);
|
||||
make.expr_paren(result_expr).into()
|
||||
} else {
|
||||
result_expr
|
||||
};
|
||||
|
||||
let mut editor = builder.make_editor(&target_node);
|
||||
editor.replace(&target_node, final_expr.syntax());
|
||||
editor.add_mappings(make.finish_with_mappings());
|
||||
builder.add_file_edits(ctx.vfs_file_id(), editor);
|
||||
},
|
||||
|
|
@ -636,4 +633,31 @@ fn main() {
|
|||
"#,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn demorgan_method_call_receiver() {
|
||||
check_assist(
|
||||
apply_demorgan,
|
||||
"fn f() { (x ||$0 !y).then_some(42) }",
|
||||
"fn f() { (!(!x && y)).then_some(42) }",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn demorgan_method_call_receiver_complex() {
|
||||
check_assist(
|
||||
apply_demorgan,
|
||||
"fn f() { (a && b ||$0 c && d).then_some(42) }",
|
||||
"fn f() { (!(!(a && b) && !(c && d))).then_some(42) }",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn demorgan_method_call_receiver_chained() {
|
||||
check_assist(
|
||||
apply_demorgan,
|
||||
"fn f() { (a ||$0 b).then_some(42).or(Some(0)) }",
|
||||
"fn f() { (!(!a && !b)).then_some(42).or(Some(0)) }",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue