diff options
author | bott <mhpoin@gmail.com> | 2018-09-07 19:28:21 +0200 |
---|---|---|
committer | Dirkjan Ochtman <dirkjan@ochtman.nl> | 2018-09-07 20:09:52 +0200 |
commit | 4f2176a3ad2d174c40617c9f3af13b6bd8270b29 (patch) | |
tree | f668ac581353be6086b8c95684887b8c1ca56e0c | |
parent | 49b0c95f6c60f96ab434efb53a52f1c2e35d1450 (diff) | |
download | askama-4f2176a3ad2d174c40617c9f3af13b6bd8270b29.tar.gz askama-4f2176a3ad2d174c40617c9f3af13b6bd8270b29.tar.bz2 askama-4f2176a3ad2d174c40617c9f3af13b6bd8270b29.zip |
Fix deep nested imports in macro calls
-rw-r--r-- | askama_derive/src/generator.rs | 47 | ||||
-rw-r--r-- | testing/templates/deep-import-child.html | 4 | ||||
-rw-r--r-- | testing/templates/deep-import-parent.html | 2 | ||||
-rw-r--r-- | testing/templates/deep-nested-macro.html | 4 | ||||
-rw-r--r-- | testing/tests/macro.rs | 10 |
5 files changed, 39 insertions, 28 deletions
diff --git a/askama_derive/src/generator.rs b/askama_derive/src/generator.rs index 81c0e27..07a90e5 100644 --- a/askama_derive/src/generator.rs +++ b/askama_derive/src/generator.rs @@ -264,7 +264,7 @@ impl<'a> Generator<'a> { self.write_loop(ctx, buf, ws1, var, iter, body, ws2); } Node::BlockDef(ws1, name, _, ws2) => { - if let AstLevel::Nested(_) = level { + if AstLevel::Nested == level { panic!( "blocks ('{}') are only allowed at the top level of a template \ or another block", @@ -278,7 +278,7 @@ impl<'a> Generator<'a> { self.handle_include(ctx, buf, ws, path); } Node::Call(ws, scope, name, ref args) => { - self.write_call(ctx, buf, ws, scope, name, args, level); + self.write_call(ctx, buf, ws, scope, name, args); } Node::Macro(_, ref m) => { if level != AstLevel::Top { @@ -325,7 +325,7 @@ impl<'a> Generator<'a> { } buf.writeln(" {"); self.locals.push(); - self.handle(ctx, nodes, buf, AstLevel::Nested(None)); + self.handle(ctx, nodes, buf, AstLevel::Nested); self.locals.pop(); } self.handle_ws(buf, ws); @@ -375,7 +375,7 @@ impl<'a> Generator<'a> { } buf.writeln(" => {"); self.handle_ws(buf, ws); - self.handle(ctx, body, buf, AstLevel::Nested(None)); + self.handle(ctx, body, buf, AstLevel::Nested); buf.writeln("}"); self.locals.pop(); } @@ -406,7 +406,7 @@ impl<'a> Generator<'a> { } buf.writeln(&format!(") in (&{}).into_iter().enumerate() {{", expr_code)); - self.handle(ctx, body, buf, AstLevel::Nested(None)); + self.handle(ctx, body, buf, AstLevel::Nested); self.handle_ws(buf, ws2); buf.writeln("}"); self.locals.pop(); @@ -420,22 +420,13 @@ impl<'a> Generator<'a> { scope: Option<&str>, name: &str, args: &[Expr], - level: AstLevel, ) { if name == "super" { self.write_block(buf, None, ws); return; } - let own_scope = match scope { - None => match level { - AstLevel::Nested(s) => s, - _ => None, - }, - s => s, - }; - - let def = if let Some(s) = own_scope { + let (def, own_ctx) = if let Some(s) = scope { let path = ctx .imports .get(s) @@ -444,15 +435,18 @@ impl<'a> Generator<'a> { .contexts .get(path) .unwrap_or_else(|| panic!("context for '{:?}' not found", path)); - mctx.macros - .get(name) - .unwrap_or_else(|| panic!("macro '{}' not found in scope '{}'", s, name)) + (mctx.macros + .get(name) + .unwrap_or_else(|| panic!("macro '{}' not found in scope '{}'", s, name)), + mctx) } else { - ctx.macros - .get(name) - .unwrap_or_else(|| panic!("macro '{}' not found", name)) + (ctx.macros + .get(name) + .unwrap_or_else(|| panic!("macro '{}' not found", name)), + ctx) }; + self.flush_ws(buf, ws); // Cannot handle_ws() here: whitespace from macro definition comes first self.locals.push(); buf.writeln("{"); @@ -466,7 +460,8 @@ impl<'a> Generator<'a> { buf.writeln(&format!("let {} = &{};", arg, expr_code)); self.locals.insert(arg); } - self.handle(ctx, &def.nodes, buf, AstLevel::Nested(own_scope)); + + self.handle(own_ctx, &def.nodes, buf, AstLevel::Nested); self.flush_ws(buf, def.ws2); buf.writeln("}"); @@ -486,7 +481,7 @@ impl<'a> Generator<'a> { // Since nodes must not outlive the Generator, we instantiate // a nested Generator here to handle the include's nodes. let mut gen = self.child(); - gen.handle(ctx, &nodes, buf, AstLevel::Nested(None)); + gen.handle(ctx, &nodes, buf, AstLevel::Nested); } self.prepare_ws(ws); } @@ -1018,13 +1013,13 @@ where } #[derive(Clone, PartialEq)] -enum AstLevel<'a> { +enum AstLevel { Top, Block, - Nested(Option<&'a str>), + Nested, } -impl<'a> Copy for AstLevel<'a> {} +impl Copy for AstLevel {} #[derive(Clone)] enum DisplayWrap { diff --git a/testing/templates/deep-import-child.html b/testing/templates/deep-import-child.html new file mode 100644 index 0000000..268d6d0 --- /dev/null +++ b/testing/templates/deep-import-child.html @@ -0,0 +1,4 @@ +{%- import "nested-macro.html" as libi -%} +{%- macro parent() -%} + {% call libi::parent() %} +{%- endmacro -%} diff --git a/testing/templates/deep-import-parent.html b/testing/templates/deep-import-parent.html new file mode 100644 index 0000000..6aa6009 --- /dev/null +++ b/testing/templates/deep-import-parent.html @@ -0,0 +1,2 @@ +{%- import "deep-import-child.html" as libj -%} +{% call libj::parent() %} diff --git a/testing/templates/deep-nested-macro.html b/testing/templates/deep-nested-macro.html index 39e8e91..c34dd5f 100644 --- a/testing/templates/deep-nested-macro.html +++ b/testing/templates/deep-nested-macro.html @@ -1,2 +1,2 @@ -{%- import "nested-macro.html" as libk -%} -{%- call libk::parent() -%} +{%- import "nested-macro.html" as libi -%} +{%- call libi::parent() -%} diff --git a/testing/tests/macro.rs b/testing/tests/macro.rs index 4e43d7c..77e0e59 100644 --- a/testing/tests/macro.rs +++ b/testing/tests/macro.rs @@ -36,3 +36,13 @@ fn test_nested() { let t = NestedTemplate; assert_eq!(t.render().unwrap(), "foo"); } + +#[derive(Template)] +#[template(path = "deep-import-parent.html")] +struct DeepImportTemplate; + +#[test] +fn test_deep_import() { + let t = DeepImportTemplate; + assert_eq!(t.render().unwrap(), "foo"); +} |