Fix nested macro calls into different scopes

This commit is contained in:
bott 2018-09-02 15:25:47 +02:00 committed by Dirkjan Ochtman
parent 979dd1ea11
commit 16b577e307

View File

@ -263,7 +263,7 @@ impl<'a> Generator<'a> {
self.write_loop(ctx, buf, ws1, var, iter, body, ws2); self.write_loop(ctx, buf, ws1, var, iter, body, ws2);
} }
Node::BlockDef(ws1, name, _, ws2) => { Node::BlockDef(ws1, name, _, ws2) => {
if let AstLevel::Nested = level { if let AstLevel::Nested(_) = level {
panic!( panic!(
"blocks ('{}') are only allowed at the top level of a template \ "blocks ('{}') are only allowed at the top level of a template \
or another block", or another block",
@ -277,7 +277,7 @@ impl<'a> Generator<'a> {
self.handle_include(ctx, buf, ws, path); self.handle_include(ctx, buf, ws, path);
} }
Node::Call(ws, scope, name, ref args) => { Node::Call(ws, scope, name, ref args) => {
self.write_call(ctx, buf, ws, scope, name, args); self.write_call(ctx, buf, ws, scope, name, args, level);
} }
Node::Macro(_, ref m) => { Node::Macro(_, ref m) => {
if level != AstLevel::Top { if level != AstLevel::Top {
@ -324,7 +324,7 @@ impl<'a> Generator<'a> {
} }
buf.writeln(" {"); buf.writeln(" {");
self.locals.push(); self.locals.push();
self.handle(ctx, nodes, buf, AstLevel::Nested); self.handle(ctx, nodes, buf, AstLevel::Nested(None));
self.locals.pop(); self.locals.pop();
} }
self.handle_ws(buf, ws); self.handle_ws(buf, ws);
@ -374,7 +374,7 @@ impl<'a> Generator<'a> {
} }
buf.writeln(" => {"); buf.writeln(" => {");
self.handle_ws(buf, ws); self.handle_ws(buf, ws);
self.handle(ctx, body, buf, AstLevel::Nested); self.handle(ctx, body, buf, AstLevel::Nested(None));
buf.writeln("}"); buf.writeln("}");
self.locals.pop(); self.locals.pop();
} }
@ -405,7 +405,7 @@ impl<'a> Generator<'a> {
} }
buf.writeln(&format!(") in (&{}).into_iter().enumerate() {{", expr_code)); buf.writeln(&format!(") in (&{}).into_iter().enumerate() {{", expr_code));
self.handle(ctx, body, buf, AstLevel::Nested); self.handle(ctx, body, buf, AstLevel::Nested(None));
self.handle_ws(buf, ws2); self.handle_ws(buf, ws2);
buf.writeln("}"); buf.writeln("}");
self.locals.pop(); self.locals.pop();
@ -419,13 +419,20 @@ impl<'a> Generator<'a> {
scope: Option<&str>, scope: Option<&str>,
name: &str, name: &str,
args: &[Expr], args: &[Expr],
level: AstLevel,
) { ) {
if name == "super" { if name == "super" {
self.write_block(buf, None, ws); self.write_block(buf, None, ws);
return; return;
} }
let def = if let Some(s) = scope { let def = if let Some(s) = match scope {
None => match level {
AstLevel::Nested(s) => s,
_ => None
},
s => s,
} {
let path = ctx.imports let path = ctx.imports
.get(s) .get(s)
.unwrap_or_else(|| panic!("no import found for scope '{}'", s)); .unwrap_or_else(|| panic!("no import found for scope '{}'", s));
@ -454,7 +461,7 @@ impl<'a> Generator<'a> {
buf.writeln(&format!("let {} = &{};", arg, expr_code)); buf.writeln(&format!("let {} = &{};", arg, expr_code));
self.locals.insert(arg); self.locals.insert(arg);
} }
self.handle(ctx, &def.nodes, buf, AstLevel::Nested); self.handle(ctx, &def.nodes, buf, AstLevel::Nested(scope));
self.flush_ws(buf, def.ws2); self.flush_ws(buf, def.ws2);
buf.writeln("}"); buf.writeln("}");
@ -473,7 +480,7 @@ impl<'a> Generator<'a> {
// Since nodes must not outlive the Generator, we instantiate // Since nodes must not outlive the Generator, we instantiate
// a nested Generator here to handle the include's nodes. // a nested Generator here to handle the include's nodes.
let mut gen = self.child(); let mut gen = self.child();
gen.handle(ctx, &nodes, buf, AstLevel::Nested); gen.handle(ctx, &nodes, buf, AstLevel::Nested(None));
} }
self.prepare_ws(ws); self.prepare_ws(ws);
} }
@ -1004,13 +1011,13 @@ where
} }
#[derive(Clone, PartialEq)] #[derive(Clone, PartialEq)]
enum AstLevel { enum AstLevel<'a> {
Top, Top,
Block, Block,
Nested, Nested(Option<&'a str>),
} }
impl Copy for AstLevel {} impl<'a> Copy for AstLevel<'a> {}
#[derive(Clone)] #[derive(Clone)]
enum DisplayWrap { enum DisplayWrap {