derive: remove parentheses before handling {{ (expr) }}

This commit is contained in:
René Kijewski 2025-07-24 16:53:51 +02:00
parent bbb2932da2
commit bbf9d1c234
2 changed files with 53 additions and 11 deletions

View File

@ -943,8 +943,12 @@ impl<'a> Generator<'a, '_> {
ctx: &Context<'a>,
buf: &mut Buffer,
ws: Ws,
expr: &'a WithSpan<'a, Expr<'a>>,
mut expr: &'a WithSpan<'a, Expr<'a>>,
) -> Result<usize, CompileError> {
while let Expr::Group(inner) = &**expr {
expr = inner;
}
if let Expr::Call(call) = &**expr
&& let ControlFlow::Break(size_hint) =
self.write_expr_call(ctx, buf, ws, expr.span(), call)?
@ -953,19 +957,26 @@ impl<'a> Generator<'a, '_> {
}
self.handle_ws(ws);
let items = if let Expr::Concat(exprs) = &**expr {
exprs
} else {
std::slice::from_ref(expr)
};
for s in items {
self.buf_writable
.push(compile_time_escape(s, self.input.escaper).unwrap_or(Writable::Expr(s)));
}
self.write_expr_item(expr);
Ok(0)
}
fn write_expr_item(&mut self, expr: &'a WithSpan<'a, Expr<'a>>) {
match &**expr {
Expr::Group(expr) => self.write_expr_item(expr),
Expr::Concat(items) => {
for expr in items {
self.write_expr_item(expr);
}
}
_ => {
self.buf_writable.push(
compile_time_escape(expr, self.input.escaper).unwrap_or(Writable::Expr(expr)),
);
}
}
}
fn write_expr_call(
&mut self,
ctx: &Context<'a>,

View File

@ -1410,3 +1410,34 @@ fn test_bare_cr_doc_comment() -> Result<(), syn::Error> {
Ok(())
}
#[test]
fn check_expr_ungrouping() {
// In this test we ensure that superfluous parentheses around expressions are stripped before
// handling the expression.
compare(
r#"{{ ("hello") }}"#,
r#"__askama_writer.write_str("hello")?;"#,
&[],
5,
);
compare(
r#"{{ ("hello") ~ " " ~ ("world") }}"#,
r#"__askama_writer.write_str("hello world")?;"#,
&[],
11,
);
compare(
r#"{{ ("hello") ~ (" " ~ ("world")) }}"#,
r#"__askama_writer.write_str("hello world")?;"#,
&[],
11,
);
compare(
r#"{{ ((((((((((("hello") ~ " ")))) ~ ((("world"))))))))) }}"#,
r#"__askama_writer.write_str("hello world")?;"#,
&[],
11,
);
}