add ssr fragment for statements

This commit is contained in:
Aleksey Kladov 2021-12-27 21:17:40 +03:00
parent df2a996cb0
commit 2cbfcf431e
2 changed files with 25 additions and 6 deletions

View File

@ -19,7 +19,7 @@ pub(crate) fn ty(s: &str) -> Result<SyntaxNode, ()> {
if node.to_string() != s {
return Err(());
}
Ok(node.syntax().clone())
Ok(node.syntax().clone_subtree())
}
pub(crate) fn item(s: &str) -> Result<SyntaxNode, ()> {
@ -33,7 +33,7 @@ pub(crate) fn item(s: &str) -> Result<SyntaxNode, ()> {
if node.to_string() != s {
return Err(());
}
Ok(node.syntax().clone())
Ok(node.syntax().clone_subtree())
}
pub(crate) fn expr(s: &str) -> Result<SyntaxNode, ()> {
@ -47,5 +47,24 @@ pub(crate) fn expr(s: &str) -> Result<SyntaxNode, ()> {
if node.to_string() != s {
return Err(());
}
Ok(node.syntax().clone())
Ok(node.syntax().clone_subtree())
}
pub(crate) fn stmt(s: &str) -> Result<SyntaxNode, ()> {
let template = "const _: () = { {}; };";
let input = template.replace("{}", s);
let parse = syntax::SourceFile::parse(&input);
if !parse.errors().is_empty() {
return Err(());
}
let mut node =
parse.tree().syntax().descendants().skip(2).find_map(ast::Stmt::cast).ok_or(())?;
if !s.ends_with(';') && node.to_string().ends_with(';') {
node = node.clone_for_update();
node.syntax().last_token().map(|it| it.detach());
}
if node.to_string() != s {
return Err(());
}
Ok(node.syntax().clone_subtree())
}

View File

@ -73,17 +73,17 @@ impl ParsedRule {
rules: Vec::new(),
};
let raw_template_stmt = raw_template.map(ast::Stmt::parse);
let raw_template_stmt = raw_template.map(fragments::stmt);
if let raw_template_expr @ Some(Ok(_)) = raw_template.map(fragments::expr) {
builder.try_add2(fragments::expr(&raw_pattern), raw_template_expr);
} else {
builder.try_add(ast::Expr::parse(&raw_pattern), raw_template_stmt.clone());
builder.try_add2(fragments::expr(&raw_pattern), raw_template_stmt.clone());
}
builder.try_add2(fragments::ty(&raw_pattern), raw_template.map(fragments::ty));
builder.try_add2(fragments::item(&raw_pattern), raw_template.map(fragments::item));
builder.try_add(ast::Path::parse(&raw_pattern), raw_template.map(ast::Path::parse));
builder.try_add(ast::Pat::parse(&raw_pattern), raw_template.map(ast::Pat::parse));
builder.try_add(ast::Stmt::parse(&raw_pattern), raw_template_stmt);
builder.try_add2(fragments::stmt(&raw_pattern), raw_template_stmt);
builder.build()
}
}