From a7fada46500dd15609d5846183b89f5a11399f19 Mon Sep 17 00:00:00 2001 From: Young-Flash <871946895@qq.com> Date: Wed, 11 Oct 2023 17:44:27 +0800 Subject: [PATCH 1/2] add replace_is_some_with_if_let_some assist --- .../replace_is_some_with_if_let_some.rs | 90 +++++++++++++++++++ crates/ide-assists/src/lib.rs | 2 + 2 files changed, 92 insertions(+) create mode 100644 crates/ide-assists/src/handlers/replace_is_some_with_if_let_some.rs diff --git a/crates/ide-assists/src/handlers/replace_is_some_with_if_let_some.rs b/crates/ide-assists/src/handlers/replace_is_some_with_if_let_some.rs new file mode 100644 index 000000000000..dfc2a8715003 --- /dev/null +++ b/crates/ide-assists/src/handlers/replace_is_some_with_if_let_some.rs @@ -0,0 +1,90 @@ +use syntax::ast::{self, AstNode}; + +use crate::{AssistContext, AssistId, AssistKind, Assists}; + +// Assist: replace_is_some_with_if_let +// +// Replace `if x.is_some()` with `if let Some(_tmp) = x`. +// +// ``` +// fn main() { +// let x = Some(1); +// if x.is_som$0e() {} +// } +// ``` +// -> +// ``` +// fn main() { +// let x = Some(1); +// if let Some(_tmp) = x {} +// } +// ``` +pub(crate) fn replace_is_some_with_if_let_some( + acc: &mut Assists, + ctx: &AssistContext<'_>, +) -> Option<()> { + let if_expr = ctx.find_node_at_offset::()?; + + let cond = if_expr.condition()?; + let call_expr = match cond { + ast::Expr::MethodCallExpr(call) => call, + _ => return None, + }; + + let name_ref = call_expr.name_ref()?; + if name_ref.text() != "is_some" { + return None; + } + + let receiver = call_expr.receiver()?; + let target = call_expr.syntax().text_range(); + + acc.add( + AssistId("replace_is_some_with_if_let_some", AssistKind::RefactorRewrite), + "Replace `is_some` with `if let Some`", + target, + |edit| { + let replacement = format!("let Some(_tmp) = {}", receiver); + edit.replace(target, replacement); + }, + ) +} + +#[cfg(test)] +mod tests { + use crate::tests::{check_assist, check_assist_not_applicable}; + + use super::replace_is_some_with_if_let_some; + + #[test] + fn replace_is_some_with_if_let_works() { + check_assist( + replace_is_some_with_if_let_some, + r#" +fn main() { + let x = Some(1); + if x.is_som$0e() {} +} +"#, + r#" +fn main() { + let x = Some(1); + if let Some(_tmp) = x {} +} +"#, + ); + } + + #[test] + fn replace_is_some_with_if_let_not_applicable() { + check_assist_not_applicable( + replace_is_some_with_if_let_some, + r#" +fn main() { + let x = Some(1); + if x.is_non$0e() {} +} +"#, + ); + } +} diff --git a/crates/ide-assists/src/lib.rs b/crates/ide-assists/src/lib.rs index 7b1961ae5493..d6accbb097ee 100644 --- a/crates/ide-assists/src/lib.rs +++ b/crates/ide-assists/src/lib.rs @@ -213,6 +213,7 @@ mod handlers { mod unwrap_block; mod unwrap_result_return_type; mod unqualify_method_call; + mod replace_is_some_with_if_let_some; mod wrap_return_type_in_result; mod into_to_qualified_from; @@ -332,6 +333,7 @@ mod handlers { unwrap_result_return_type::unwrap_result_return_type, unwrap_tuple::unwrap_tuple, unqualify_method_call::unqualify_method_call, + replace_is_some_with_if_let_some::replace_is_some_with_if_let_some, wrap_return_type_in_result::wrap_return_type_in_result, // These are manually sorted for better priorities. By default, // priority is determined by the size of the target range (smaller From 3605bb38ff7ecb1b0c9cde25a1c1d9938ac3bb51 Mon Sep 17 00:00:00 2001 From: Young-Flash <871946895@qq.com> Date: Thu, 12 Oct 2023 11:50:44 +0800 Subject: [PATCH 2/2] fix CI: generate doctest --- .../replace_is_some_with_if_let_some.rs | 6 +++--- crates/ide-assists/src/tests/generated.rs | 19 +++++++++++++++++++ 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/crates/ide-assists/src/handlers/replace_is_some_with_if_let_some.rs b/crates/ide-assists/src/handlers/replace_is_some_with_if_let_some.rs index dfc2a8715003..70892fe27025 100644 --- a/crates/ide-assists/src/handlers/replace_is_some_with_if_let_some.rs +++ b/crates/ide-assists/src/handlers/replace_is_some_with_if_let_some.rs @@ -2,7 +2,7 @@ use syntax::ast::{self, AstNode}; use crate::{AssistContext, AssistId, AssistKind, Assists}; -// Assist: replace_is_some_with_if_let +// Assist: replace_is_some_with_if_let_some // // Replace `if x.is_some()` with `if let Some(_tmp) = x`. // @@ -57,7 +57,7 @@ mod tests { use super::replace_is_some_with_if_let_some; #[test] - fn replace_is_some_with_if_let_works() { + fn replace_is_some_with_if_let_some_works() { check_assist( replace_is_some_with_if_let_some, r#" @@ -76,7 +76,7 @@ fn main() { } #[test] - fn replace_is_some_with_if_let_not_applicable() { + fn replace_is_some_with_if_let_some_not_applicable() { check_assist_not_applicable( replace_is_some_with_if_let_some, r#" diff --git a/crates/ide-assists/src/tests/generated.rs b/crates/ide-assists/src/tests/generated.rs index 18f7591cf082..d2b801336a55 100644 --- a/crates/ide-assists/src/tests/generated.rs +++ b/crates/ide-assists/src/tests/generated.rs @@ -2558,6 +2558,25 @@ fn handle(action: Action) { ) } +#[test] +fn doctest_replace_is_some_with_if_let_some() { + check_doc_test( + "replace_is_some_with_if_let_some", + r#####" +fn main() { + let x = Some(1); + if x.is_som$0e() {} +} +"#####, + r#####" +fn main() { + let x = Some(1); + if let Some(_tmp) = x {} +} +"#####, + ) +} + #[test] fn doctest_replace_let_with_if_let() { check_doc_test(