Unnamed repository; edit this file 'description' to name the repository.
Merge pull request #22764 from Veykril/lukaswirth/push-kmzwrkxlxpos
internal: Use expression parsing entrypoint in `make` constructor
| -rw-r--r-- | crates/syntax/src/ast/make.rs | 47 |
1 files changed, 37 insertions, 10 deletions
diff --git a/crates/syntax/src/ast/make.rs b/crates/syntax/src/ast/make.rs index 8b7f91c937..b0e59ff159 100644 --- a/crates/syntax/src/ast/make.rs +++ b/crates/syntax/src/ast/make.rs @@ -660,12 +660,12 @@ pub fn expr_if( else_branch: Option<ast::ElseBranch>, ) -> ast::IfExpr { let else_branch = match else_branch { - Some(ast::ElseBranch::Block(block)) => format!("else {block}"), - Some(ast::ElseBranch::IfExpr(if_expr)) => format!("else {if_expr}"), + Some(ast::ElseBranch::Block(block)) => format!(" else {block}"), + Some(ast::ElseBranch::IfExpr(if_expr)) => format!(" else {if_expr}"), None => String::new(), }; let ws = block_whitespace(&condition); - expr_from_text(&format!("if {condition}{ws}{then_branch} {else_branch}")) + expr_from_text(&format!("if {condition}{ws}{then_branch}{else_branch}")) } pub fn expr_for_loop(pat: ast::Pat, expr: ast::Expr, block: ast::BlockExpr) -> ast::ForExpr { let ws = block_whitespace(&expr); @@ -731,16 +731,9 @@ pub fn expr_tuple(elements: impl IntoIterator<Item = ast::Expr>) -> ast::TupleEx pub fn expr_assignment(lhs: ast::Expr, rhs: ast::Expr) -> ast::BinExpr { expr_from_text(&format!("{lhs} = {rhs}")) } -fn expr_from_text<E: Into<ast::Expr> + AstNode>(text: &str) -> E { - ast_from_text(&format!("const C: () = {text};")) -} fn block_whitespace(after: &impl AstNode) -> &'static str { if after.syntax().text().contains_char('\n') { "\n" } else { " " } } -pub fn expr_let(pattern: ast::Pat, expr: ast::Expr) -> ast::LetExpr { - ast_from_text(&format!("const _: () = while let {pattern} = {expr} {{}};")) -} - pub fn arg_list(args: impl IntoIterator<Item = ast::Expr>) -> ast::ArgList { let args = args.into_iter().format(", "); ast_from_text(&format!("fn main() {{ ()({args}) }}")) @@ -1352,6 +1345,30 @@ pub fn token_tree( ast_from_text(&format!("tt!{l_delimiter}{tt}{r_delimiter}")) } +pub fn expr_let(pattern: ast::Pat, expr: ast::Expr) -> ast::LetExpr { + expr_from_text(&format!("while let {pattern} = {expr} {{}}")) +} + +#[track_caller] +fn expr_from_text<E: Into<ast::Expr> + AstNode>(text: &str) -> E { + expr_from_text_with_edition(text, Edition::CURRENT) +} + +#[track_caller] +fn expr_from_text_with_edition<E: Into<ast::Expr> + AstNode>(text: &str, edition: Edition) -> E { + let parse = ast::Expr::parse(text, edition); + let node = match parse.tree().syntax().descendants().find_map(E::cast) { + Some(it) => it, + None => { + let node = std::any::type_name::<E>(); + panic!("Failed to make ast node `{node}` from text {text}") + } + }; + let node = node.clone_subtree(); + assert_eq!(node.syntax().text_range().start(), 0.into()); + node +} + #[track_caller] fn ast_from_text<N: AstNode>(text: &str) -> N { ast_from_text_with_edition(text, Edition::CURRENT) @@ -1474,6 +1491,16 @@ mod tests { } #[test] + fn expr_if_without_else_has_no_trailing_whitespace() { + let if_expr = expr_if(ext::expr_underscore(), block_expr(None, None), None); + assert_eq!(if_expr.syntax().to_string(), "if _ {\n}"); + + let stmt = expr_stmt(if_expr.into()); + let block = block_expr([stmt.into()], None); + assert_eq!(block.syntax().to_string(), "{\n if _ {\n}\n}"); + } + + #[test] fn test_untyped_param() { check( untyped_param(path_pat(ext::ident_path("name"))), |