diff options
author | René Kijewski <kijewski@library.vetmed.fu-berlin.de> | 2021-07-01 20:38:47 +0200 |
---|---|---|
committer | Dirkjan Ochtman <dirkjan@ochtman.nl> | 2021-07-05 10:34:20 +0200 |
commit | 5c367f5021e615bfa9595aad71080de6de32f22b (patch) | |
tree | 7dea68d7db7bd7118f86364b90236095f44d07c8 /askama_shared/src/generator.rs | |
parent | 6e754506d8f38b987ba4a4e67f19e8c2ad9f9b66 (diff) | |
download | askama-5c367f5021e615bfa9595aad71080de6de32f22b.tar.gz askama-5c367f5021e615bfa9595aad71080de6de32f22b.tar.bz2 askama-5c367f5021e615bfa9595aad71080de6de32f22b.zip |
Move logic where target shadows or declares a variable into method
Diffstat (limited to 'askama_shared/src/generator.rs')
-rw-r--r-- | askama_shared/src/generator.rs | 56 |
1 files changed, 33 insertions, 23 deletions
diff --git a/askama_shared/src/generator.rs b/askama_shared/src/generator.rs index eb6b514..efdeb85 100644 --- a/askama_shared/src/generator.rs +++ b/askama_shared/src/generator.rs @@ -811,6 +811,25 @@ impl<'a, S: std::hash::BuildHasher> Generator<'a, S> { buf.writeln(";") } + fn is_shadowing_variable(&self, var: &Target<'a>) -> bool { + match var { + Target::Name(name) => { + let name = normalize_identifier(name); + match self.locals.get(&name) { + // declares a new variable + None => false, + // an initialized variable gets shadowed + Some(meta) if meta.initialized => true, + // initializes a variable that was introduced in a LetDecl before + _ => false, + } + } + Target::Tuple(targets) => targets + .iter() + .any(|name| self.is_shadowing_variable(&Target::Name(name))), + } + } + fn write_let( &mut self, buf: &mut Buffer, @@ -822,36 +841,27 @@ impl<'a, S: std::hash::BuildHasher> Generator<'a, S> { let mut expr_buf = Buffer::new(0); self.visit_expr(&mut expr_buf, val)?; + let shadowed = self.is_shadowing_variable(var); + if shadowed { + // Need to flush the buffer if the variable is being shadowed, + // to ensure the old variable is used. + self.write_buf_writable(buf)?; + } + if shadowed + || !matches!(var, &Target::Name(_)) + || matches!(var, Target::Name(name) if self.locals.get(name).is_none()) + { + buf.write("let "); + } + match var { Target::Name(name) => { let name = normalize_identifier(name); - let meta = self.locals.get(&name).cloned(); - - let shadowed = matches!(&meta, Some(meta) if meta.initialized); - if shadowed { - // Need to flush the buffer if the variable is being shadowed, - // to ensure the old variable is used. - self.write_buf_writable(buf)?; - } - if shadowed || meta.is_none() { - buf.write("let "); - } buf.write(name); - self.locals.insert(name, LocalMeta::initialized()); } Target::Tuple(targets) => { - let shadowed = targets.iter().any(|name| { - let name = normalize_identifier(name); - matches!(self.locals.get(&name), Some(meta) if meta.initialized) - }); - if shadowed { - // Need to flush the buffer if the variable is being shadowed, - // to ensure the old variable is used. - self.write_buf_writable(buf)?; - } - - buf.write("let ("); + buf.write("("); for name in targets { let name = normalize_identifier(name); self.locals.insert(name, LocalMeta::initialized()); |