Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/syntax/src/ast/node_ext.rs')
| -rw-r--r-- | crates/syntax/src/ast/node_ext.rs | 34 |
1 files changed, 32 insertions, 2 deletions
diff --git a/crates/syntax/src/ast/node_ext.rs b/crates/syntax/src/ast/node_ext.rs index 067e13ee14..2915e7aab1 100644 --- a/crates/syntax/src/ast/node_ext.rs +++ b/crates/syntax/src/ast/node_ext.rs @@ -528,9 +528,39 @@ impl ast::Item { } } -impl ast::Condition { +impl ast::Expr { + /// Returns the `let` only if there is exactly one (that is, `let pat = expr` + /// or `((let pat = expr))`, but not `let pat = expr && expr` or `non_let_expr`). + pub fn single_let(&self) -> Option<ast::LetExpr> { + return get_pat(self.clone()); + + fn get_pat(expr: ast::Expr) -> Option<ast::LetExpr> { + match expr { + ast::Expr::ParenExpr(expr) => expr.expr().and_then(get_pat), + ast::Expr::LetExpr(expr) => Some(expr), + _ => None, + } + } + } + pub fn is_pattern_cond(&self) -> bool { - self.let_token().is_some() + return contains_let(self.clone()); + + fn contains_let(expr: ast::Expr) -> bool { + match expr { + ast::Expr::BinExpr(expr) + if expr.op_kind() == Some(ast::BinaryOp::LogicOp(ast::LogicOp::And)) => + { + expr.lhs() + .map(contains_let) + .or_else(|| expr.rhs().map(contains_let)) + .unwrap_or(false) + } + ast::Expr::ParenExpr(expr) => expr.expr().map_or(false, contains_let), + ast::Expr::LetExpr(_) => true, + _ => false, + } + } } } |