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
Lukas Wirth 5 weeks ago
parent 2967707 · parent cdc3597 · commit 1be8e0f
-rw-r--r--crates/syntax/src/ast/make.rs47
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"))),