Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/syntax/src/ast/make.rs')
-rw-r--r--crates/syntax/src/ast/make.rs47
1 files changed, 30 insertions, 17 deletions
diff --git a/crates/syntax/src/ast/make.rs b/crates/syntax/src/ast/make.rs
index 282cbc4b3a..a920fe4f35 100644
--- a/crates/syntax/src/ast/make.rs
+++ b/crates/syntax/src/ast/make.rs
@@ -63,6 +63,9 @@ pub mod ext {
Some(expr)
}
+ pub fn expr_unit() -> ast::Expr {
+ expr_tuple([]).into()
+ }
pub fn expr_unreachable() -> ast::Expr {
expr_from_text("unreachable!()")
}
@@ -546,10 +549,6 @@ pub fn hacky_block_expr(
ast_from_text(&format!("fn f() {buf}"))
}
-pub fn expr_unit() -> ast::Expr {
- expr_from_text("()")
-}
-
pub fn expr_literal(text: &str) -> ast::Literal {
assert_eq!(text.trim(), text);
ast_from_text(&format!("fn f() {{ let _ = {text}; }}"))
@@ -600,14 +599,14 @@ pub fn expr_try(expr: ast::Expr) -> ast::Expr {
pub fn expr_await(expr: ast::Expr) -> ast::Expr {
expr_from_text(&format!("{expr}.await"))
}
-pub fn expr_match(expr: ast::Expr, match_arm_list: ast::MatchArmList) -> ast::Expr {
+pub fn expr_match(expr: ast::Expr, match_arm_list: ast::MatchArmList) -> ast::MatchExpr {
expr_from_text(&format!("match {expr} {match_arm_list}"))
}
pub fn expr_if(
condition: ast::Expr,
then_branch: ast::BlockExpr,
else_branch: Option<ast::ElseBranch>,
-) -> ast::Expr {
+) -> 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}"),
@@ -623,7 +622,7 @@ pub fn expr_loop(block: ast::BlockExpr) -> ast::Expr {
expr_from_text(&format!("loop {block}"))
}
-pub fn expr_prefix(op: SyntaxKind, expr: ast::Expr) -> ast::Expr {
+pub fn expr_prefix(op: SyntaxKind, expr: ast::Expr) -> ast::PrefixExpr {
let token = token(op);
expr_from_text(&format!("{token}{expr}"))
}
@@ -656,14 +655,14 @@ pub fn expr_field(receiver: ast::Expr, field: &str) -> ast::Expr {
pub fn expr_paren(expr: ast::Expr) -> ast::Expr {
expr_from_text(&format!("({expr})"))
}
-pub fn expr_tuple(elements: impl IntoIterator<Item = ast::Expr>) -> ast::Expr {
+pub fn expr_tuple(elements: impl IntoIterator<Item = ast::Expr>) -> ast::TupleExpr {
let expr = elements.into_iter().format(", ");
expr_from_text(&format!("({expr})"))
}
pub fn expr_assignment(lhs: ast::Expr, rhs: ast::Expr) -> ast::Expr {
expr_from_text(&format!("{lhs} = {rhs}"))
}
-fn expr_from_text(text: &str) -> ast::Expr {
+fn expr_from_text<E: Into<ast::Expr> + AstNode>(text: &str) -> E {
ast_from_text(&format!("const C: () = {text};"))
}
pub fn expr_let(pattern: ast::Pat, expr: ast::Expr) -> ast::LetExpr {
@@ -788,15 +787,21 @@ pub fn path_pat(path: ast::Path) -> ast::Pat {
}
}
-pub fn match_arm(
- pats: impl IntoIterator<Item = ast::Pat>,
- guard: Option<ast::Expr>,
- expr: ast::Expr,
-) -> ast::MatchArm {
- let pats_str = pats.into_iter().join(" | ");
+/// Returns a `Pat` if the path has just one segment, an `OrPat` otherwise.
+pub fn or_pat(pats: impl IntoIterator<Item = ast::Pat>, leading_pipe: bool) -> ast::Pat {
+ let leading_pipe = if leading_pipe { "| " } else { "" };
+ let pats = pats.into_iter().join(" | ");
+
+ return from_text(&format!("{leading_pipe}{pats}"));
+ fn from_text(text: &str) -> ast::Pat {
+ ast_from_text(&format!("fn f({text}: ())"))
+ }
+}
+
+pub fn match_arm(pat: ast::Pat, guard: Option<ast::MatchGuard>, expr: ast::Expr) -> ast::MatchArm {
return match guard {
- Some(guard) => from_text(&format!("{pats_str} if {guard} => {expr}")),
- None => from_text(&format!("{pats_str} => {expr}")),
+ Some(guard) => from_text(&format!("{pat} {guard} => {expr}")),
+ None => from_text(&format!("{pat} => {expr}")),
};
fn from_text(text: &str) -> ast::MatchArm {
@@ -817,6 +822,14 @@ pub fn match_arm_with_guard(
}
}
+pub fn match_guard(condition: ast::Expr) -> ast::MatchGuard {
+ return from_text(&format!("if {condition}"));
+
+ fn from_text(text: &str) -> ast::MatchGuard {
+ ast_from_text(&format!("fn f() {{ match () {{() {text} => () }}"))
+ }
+}
+
pub fn match_arm_list(arms: impl IntoIterator<Item = ast::MatchArm>) -> ast::MatchArmList {
let arms_str = arms.into_iter().fold(String::new(), |mut acc, arm| {
let needs_comma = arm.expr().is_none_or(|it| !it.is_block_like());