Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Template node structs & whitespace semantics #829

Open
wants to merge 27 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
ec8301d
Add test for parsing Node::Call
couchand Mar 6, 2023
fcb01b6
Extract Call struct from Node
couchand Mar 6, 2023
586c770
Extract Match struct from Node
couchand Mar 6, 2023
a31b7ad
Make When a proper struct
couchand Mar 6, 2023
b586040
Make Cond a proper struct
couchand Mar 6, 2023
27a2075
Extract Lit struct from Node
couchand Mar 6, 2023
0b6bbca
Push name into Macro struct
couchand Mar 6, 2023
ccc6f50
Add test for Macro parse
couchand Mar 6, 2023
00c4e93
Clarify Macro Ws semantics
couchand Mar 6, 2023
92bf3b8
Add test for parsing raw blocks
couchand Mar 6, 2023
cfcf8c8
Extract Raw struct from Node and clarify inner/outer Ws
couchand Mar 6, 2023
eb71bdc
Add test for BlockDef parse
couchand Mar 6, 2023
21bf9a5
Extract BlockDef struct from Node and clarify inner/outer Ws
couchand Mar 6, 2023
8dd962a
Add test for parsing Node::Loop
couchand Mar 4, 2023
3ea5da8
Clarify Loop outer/body/else Ws
couchand Mar 6, 2023
d551120
Add test for parsing Node::Match Ws
couchand Mar 4, 2023
4140503
Clarify Match arms/outer Ws semantics
couchand Mar 6, 2023
15cbcd8
Add test for parsing Node::Cond
couchand Mar 6, 2023
265702f
Clarify Cond branch/outer Ws semantics
couchand Mar 6, 2023
9469675
Inline write_comment in Generator::handle
couchand Mar 6, 2023
2657abd
Handle Expr Ws in Generator::handle
couchand Mar 6, 2023
ad83909
Handle LetDecl Ws in Generator::handle
couchand Mar 6, 2023
0b02a31
Handle Let Ws in Generator::handle
couchand Mar 6, 2023
64fbc47
Move Node::Include Ws handling to caller
couchand Mar 6, 2023
15c4e82
Inline handle_ws in Generator::handle
couchand Mar 6, 2023
3a37e8c
Don't destructure Call in Generator::handle
couchand Mar 6, 2023
981fb6b
Don't destructure Match in Generator::handle
couchand Mar 6, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions askama_derive/src/generator.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::config::{get_template_source, read_config_file, Config, WhitespaceHandling};
use crate::heritage::{Context, Heritage};
use crate::input::{Print, Source, TemplateInput};
use crate::parser::{parse, Cond, CondTest, Expr, Loop, Node, Target, When, Whitespace, Ws};
use crate::parser::{parse, Call, Cond, CondTest, Expr, Loop, Node, Target, When, Whitespace, Ws};
use crate::CompileError;

use proc_macro::TokenStream;
Expand Down Expand Up @@ -665,7 +665,14 @@ impl<'a> Generator<'a> {
Node::Include(ws, path) => {
size_hint += self.handle_include(ctx, buf, ws, path)?;
}
Node::Call(ws, scope, name, ref args) => {
Node::Call(
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we're going to do this, I think we should just pass the &Call directly to write_call()... Not much point in destructing it here. (Same for other node types.)

ws,
Call {
scope,
name,
ref args,
},
) => {
size_hint += self.write_call(ctx, buf, ws, scope, name, args)?;
}
Node::Macro(_, ref m) => {
Expand Down
4 changes: 3 additions & 1 deletion askama_derive/src/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ use nom::sequence::{delimited, pair, tuple};
use nom::{error_position, AsChar, IResult, InputTakeAtPosition};

pub(crate) use self::expr::Expr;
pub(crate) use self::node::{Cond, CondTest, Loop, Macro, Node, Target, When, Whitespace, Ws};
pub(crate) use self::node::{
Call, Cond, CondTest, Loop, Macro, Node, Target, When, Whitespace, Ws,
};
use crate::config::Syntax;
use crate::CompileError;

Expand Down
15 changes: 13 additions & 2 deletions askama_derive/src/parser/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ pub(crate) enum Node<'a> {
Lit(&'a str, &'a str, &'a str),
Comment(Ws),
Expr(Ws, Expr<'a>),
Call(Ws, Option<&'a str>, &'a str, Vec<Expr<'a>>),
Call(Ws, Call<'a>),
LetDecl(Ws, Target<'a>),
Let(Ws, Target<'a>, Expr<'a>),
Cond(Vec<Cond<'a>>, Ws),
Expand Down Expand Up @@ -66,6 +66,17 @@ impl From<WhitespaceHandling> for Whitespace {
}
}

/// A macro call statement.
#[derive(Debug, PartialEq)]
pub(crate) struct Call<'a> {
/// If the macro is imported, the scope name.
pub(crate) scope: Option<&'a str>,
/// The name of the macro to call.
pub(crate) name: &'a str,
/// The arguments to the macro.
pub(crate) args: Vec<Expr<'a>>,
}

#[derive(Debug, PartialEq)]
pub(crate) struct Loop<'a> {
pub(crate) ws1: Ws,
Expand Down Expand Up @@ -140,7 +151,7 @@ fn block_call(i: &str) -> IResult<&str, Node<'_>> {
let (i, (pws, _, (scope, name, args, nws))) = p(i)?;
let scope = scope.map(|(scope, _)| scope);
let args = args.unwrap_or_default();
Ok((i, Node::Call(Ws(pws, nws), scope, name, args)))
Ok((i, Node::Call(Ws(pws, nws), Call { scope, name, args })))
}

fn cond_if(i: &str) -> IResult<&str, CondTest<'_>> {
Expand Down
19 changes: 11 additions & 8 deletions askama_derive/src/parser/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -669,25 +669,28 @@ fn test_missing_space_after_kw() {

#[test]
fn test_parse_call_statement() {
use super::Call;
let syntax = Syntax::default();
assert_eq!(
super::parse("{% call foo(bar) %}", &syntax).unwrap(),
vec![Node::Call(
Ws(None, None),
None,
"foo",
vec![
Expr::Var("bar"),
],
Call {
scope: None,
name: "foo",
args: vec![Expr::Var("bar"),],
}
)],
);
assert_eq!(
super::parse("{% call foo::bar() %}", &syntax).unwrap(),
vec![Node::Call(
Ws(None, None),
Some("foo"),
"bar",
vec![],
Call {
scope: Some("foo"),
name: "bar",
args: vec![],
}
)],
);
}