From 54fe3dc0f1a7ca2de2d7b0fccb4422d89e0fb213 Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Sun, 27 Feb 2022 00:12:22 +0000 Subject: [PATCH] Fix `if` in #11561 --- crates/syntax/src/ast/expr_ext.rs | 66 ++++++++++++++++++++++++++++--- 1 file changed, 61 insertions(+), 5 deletions(-) diff --git a/crates/syntax/src/ast/expr_ext.rs b/crates/syntax/src/ast/expr_ext.rs index 28b4f5bc02..ae3a3c9393 100644 --- a/crates/syntax/src/ast/expr_ext.rs +++ b/crates/syntax/src/ast/expr_ext.rs @@ -49,25 +49,81 @@ impl From for ElseBranch { impl ast::IfExpr { pub fn then_branch(&self) -> Option { - self.blocks().next() + self.children_after_condition().next() } pub fn else_branch(&self) -> Option { - let res = match self.blocks().nth(1) { + let res = match self.children_after_condition().nth(1) { Some(block) => ElseBranch::Block(block), None => { - let elif: ast::IfExpr = support::child(self.syntax())?; + let elif = self.children_after_condition().next()?; ElseBranch::IfExpr(elif) } }; Some(res) } - pub fn blocks(&self) -> AstChildren { - support::children(self.syntax()) + fn children_after_condition(&self) -> impl Iterator { + self.syntax().children().skip(1).filter_map(N::cast) } } +#[test] +fn if_block_condition() { + let parse = ast::SourceFile::parse( + r#" + fn test() { + if { true } { "if" } + else if { false } { "first elif" } + else if true { "second elif" } + else if (true) { "third elif" } + else { "else" } + } + "#, + ); + let if_ = parse.tree().syntax().descendants().find_map(ast::IfExpr::cast).unwrap(); + assert_eq!(if_.then_branch().unwrap().syntax().text(), r#"{ "if" }"#); + let elif = match if_.else_branch().unwrap() { + ElseBranch::IfExpr(elif) => elif, + ElseBranch::Block(_) => panic!("should be `else if`"), + }; + assert_eq!(elif.then_branch().unwrap().syntax().text(), r#"{ "first elif" }"#); + let elif = match elif.else_branch().unwrap() { + ElseBranch::IfExpr(elif) => elif, + ElseBranch::Block(_) => panic!("should be `else if`"), + }; + assert_eq!(elif.then_branch().unwrap().syntax().text(), r#"{ "second elif" }"#); + let elif = match elif.else_branch().unwrap() { + ElseBranch::IfExpr(elif) => elif, + ElseBranch::Block(_) => panic!("should be `else if`"), + }; + assert_eq!(elif.then_branch().unwrap().syntax().text(), r#"{ "third elif" }"#); + let else_ = match elif.else_branch().unwrap() { + ElseBranch::Block(else_) => else_, + ElseBranch::IfExpr(_) => panic!("should be `else`"), + }; + assert_eq!(else_.syntax().text(), r#"{ "else" }"#); +} + +#[test] +fn if_condition_with_if_inside() { + let parse = ast::SourceFile::parse( + r#" + fn test() { + if if true { true } else { false } { "if" } + else { "else" } + } + "#, + ); + let if_ = parse.tree().syntax().descendants().find_map(ast::IfExpr::cast).unwrap(); + assert_eq!(if_.then_branch().unwrap().syntax().text(), r#"{ "if" }"#); + let else_ = match if_.else_branch().unwrap() { + ElseBranch::Block(else_) => else_, + ElseBranch::IfExpr(_) => panic!("should be `else`"), + }; + assert_eq!(else_.syntax().text(), r#"{ "else" }"#); +} + impl ast::PrefixExpr { pub fn op_kind(&self) -> Option { let res = match self.op_token()?.kind() {