aboutsummaryrefslogtreecommitdiffstats
path: root/askama_shared/src/generator.rs
diff options
context:
space:
mode:
authorLibravatar René Kijewski <kijewski@library.vetmed.fu-berlin.de>2021-07-01 20:38:47 +0200
committerLibravatar Dirkjan Ochtman <dirkjan@ochtman.nl>2021-07-05 10:34:20 +0200
commit5c367f5021e615bfa9595aad71080de6de32f22b (patch)
tree7dea68d7db7bd7118f86364b90236095f44d07c8 /askama_shared/src/generator.rs
parent6e754506d8f38b987ba4a4e67f19e8c2ad9f9b66 (diff)
downloadaskama-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.rs56
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());