Skip to content

Commit f70512c

Browse files
Change single_let() and is_pattern_cond() to free functions
1 parent 9881614 commit f70512c

File tree

7 files changed

+44
-46
lines changed

7 files changed

+44
-46
lines changed

crates/ide_assists/src/handlers/convert_bool_then.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use hir::{known, AsAssocItem, Semantics};
22
use ide_db::{
33
helpers::{
44
for_each_tail_expr,
5-
node_ext::{block_as_lone_tail, preorder_expr},
5+
node_ext::{block_as_lone_tail, is_pattern_cond, preorder_expr},
66
FamousDefs,
77
},
88
RootDatabase,
@@ -45,7 +45,7 @@ pub(crate) fn convert_if_to_bool_then(acc: &mut Assists, ctx: &AssistContext) ->
4545
return None;
4646
}
4747

48-
let cond = expr.condition().filter(|cond| !cond.is_pattern_cond())?;
48+
let cond = expr.condition().filter(|cond| !is_pattern_cond(cond.clone()))?;
4949
let then = expr.then_branch()?;
5050
let else_ = match expr.else_branch()? {
5151
ast::ElseBranch::Block(b) => b,

crates/ide_assists/src/handlers/convert_to_guarded_return.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use std::iter::once;
22

3+
use ide_db::helpers::node_ext::{is_pattern_cond, single_let};
34
use syntax::{
45
ast::{
56
self,
@@ -48,8 +49,8 @@ pub(crate) fn convert_to_guarded_return(acc: &mut Assists, ctx: &AssistContext)
4849
let cond = if_expr.condition()?;
4950

5051
// Check if there is an IfLet that we can handle.
51-
let (if_let_pat, cond_expr) = if cond.is_pattern_cond() {
52-
let let_ = cond.single_let()?;
52+
let (if_let_pat, cond_expr) = if is_pattern_cond(cond.clone()) {
53+
let let_ = single_let(cond)?;
5354
match let_.pat() {
5455
Some(ast::Pat::TupleStructPat(pat)) if pat.fields().count() == 1 => {
5556
let path = pat.path()?;

crates/ide_assists/src/handlers/convert_while_to_loop.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use std::iter::once;
22

3+
use ide_db::helpers::node_ext::is_pattern_cond;
34
use syntax::{
45
ast::{
56
self,
@@ -54,7 +55,7 @@ pub(crate) fn convert_while_to_loop(acc: &mut Assists, ctx: &AssistContext) -> O
5455
let break_block =
5556
make::block_expr(once(make::expr_stmt(make::expr_break(None)).into()), None)
5657
.indent(while_indent_level);
57-
let block_expr = if while_cond.is_pattern_cond() {
58+
let block_expr = if is_pattern_cond(while_cond.clone()) {
5859
let if_expr = make::expr_if(while_cond, while_body, Some(break_block.into()));
5960
let stmts = once(make::expr_stmt(if_expr).into());
6061
make::block_expr(stmts, None)

crates/ide_assists/src/handlers/invert_if.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use ide_db::helpers::node_ext::is_pattern_cond;
12
use syntax::{
23
ast::{self, AstNode},
34
T,
@@ -36,7 +37,7 @@ pub(crate) fn invert_if(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
3637

3738
let cond = expr.condition()?;
3839
// This assist should not apply for if-let.
39-
if cond.is_pattern_cond() {
40+
if is_pattern_cond(cond.clone()) {
4041
return None;
4142
}
4243

crates/ide_assists/src/handlers/replace_if_let_with_match.rs

+9-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
use std::iter::{self, successors};
22

33
use either::Either;
4-
use ide_db::{defs::NameClass, ty_filter::TryEnum, RootDatabase};
4+
use ide_db::{
5+
defs::NameClass,
6+
helpers::node_ext::{is_pattern_cond, single_let},
7+
ty_filter::TryEnum,
8+
RootDatabase,
9+
};
510
use syntax::{
611
ast::{
712
self,
@@ -61,7 +66,7 @@ pub(crate) fn replace_if_let_with_match(acc: &mut Assists, ctx: &AssistContext)
6166
}
6267
});
6368
let scrutinee_to_be_expr = if_expr.condition()?;
64-
let scrutinee_to_be_expr = match scrutinee_to_be_expr.single_let() {
69+
let scrutinee_to_be_expr = match single_let(scrutinee_to_be_expr.clone()) {
6570
Some(cond) => cond.expr()?,
6671
None => scrutinee_to_be_expr,
6772
};
@@ -70,7 +75,7 @@ pub(crate) fn replace_if_let_with_match(acc: &mut Assists, ctx: &AssistContext)
7075
let mut cond_bodies = Vec::new();
7176
for if_expr in if_exprs {
7277
let cond = if_expr.condition()?;
73-
let cond = match cond.single_let() {
78+
let cond = match single_let(cond.clone()) {
7479
Some(let_) => {
7580
let pat = let_.pat()?;
7681
let expr = let_.expr()?;
@@ -84,7 +89,7 @@ pub(crate) fn replace_if_let_with_match(acc: &mut Assists, ctx: &AssistContext)
8489
Either::Left(pat)
8590
}
8691
// Multiple `let`, unsupported.
87-
None if cond.is_pattern_cond() => return None,
92+
None if is_pattern_cond(cond.clone()) => return None,
8893
None => Either::Right(cond),
8994
};
9095
let body = if_expr.then_branch()?;

crates/ide_db/src/helpers/node_ext.rs

+26
Original file line numberDiff line numberDiff line change
@@ -216,3 +216,29 @@ pub fn vis_eq(this: &ast::Visibility, other: &ast::Visibility) -> bool {
216216
_ => false,
217217
}
218218
}
219+
220+
/// Returns the `let` only if there is exactly one (that is, `let pat = expr`
221+
/// or `((let pat = expr))`, but not `let pat = expr && expr` or `non_let_expr`).
222+
pub fn single_let(expr: ast::Expr) -> Option<ast::LetExpr> {
223+
match expr {
224+
ast::Expr::ParenExpr(expr) => expr.expr().and_then(single_let),
225+
ast::Expr::LetExpr(expr) => Some(expr),
226+
_ => None,
227+
}
228+
}
229+
230+
pub fn is_pattern_cond(expr: ast::Expr) -> bool {
231+
match expr {
232+
ast::Expr::BinExpr(expr)
233+
if expr.op_kind() == Some(ast::BinaryOp::LogicOp(ast::LogicOp::And)) =>
234+
{
235+
expr.lhs()
236+
.map(is_pattern_cond)
237+
.or_else(|| expr.rhs().map(is_pattern_cond))
238+
.unwrap_or(false)
239+
}
240+
ast::Expr::ParenExpr(expr) => expr.expr().map_or(false, is_pattern_cond),
241+
ast::Expr::LetExpr(_) => true,
242+
_ => false,
243+
}
244+
}

crates/syntax/src/ast/node_ext.rs

-36
Original file line numberDiff line numberDiff line change
@@ -528,42 +528,6 @@ impl ast::Item {
528528
}
529529
}
530530

531-
impl ast::Expr {
532-
/// Returns the `let` only if there is exactly one (that is, `let pat = expr`
533-
/// or `((let pat = expr))`, but not `let pat = expr && expr` or `non_let_expr`).
534-
pub fn single_let(&self) -> Option<ast::LetExpr> {
535-
return get_pat(self.clone());
536-
537-
fn get_pat(expr: ast::Expr) -> Option<ast::LetExpr> {
538-
match expr {
539-
ast::Expr::ParenExpr(expr) => expr.expr().and_then(get_pat),
540-
ast::Expr::LetExpr(expr) => Some(expr),
541-
_ => None,
542-
}
543-
}
544-
}
545-
546-
pub fn is_pattern_cond(&self) -> bool {
547-
return contains_let(self.clone());
548-
549-
fn contains_let(expr: ast::Expr) -> bool {
550-
match expr {
551-
ast::Expr::BinExpr(expr)
552-
if expr.op_kind() == Some(ast::BinaryOp::LogicOp(ast::LogicOp::And)) =>
553-
{
554-
expr.lhs()
555-
.map(contains_let)
556-
.or_else(|| expr.rhs().map(contains_let))
557-
.unwrap_or(false)
558-
}
559-
ast::Expr::ParenExpr(expr) => expr.expr().map_or(false, contains_let),
560-
ast::Expr::LetExpr(_) => true,
561-
_ => false,
562-
}
563-
}
564-
}
565-
}
566-
567531
#[derive(Debug, Clone, PartialEq, Eq)]
568532
pub enum FieldKind {
569533
Name(ast::NameRef),

0 commit comments

Comments
 (0)