optimize access to loop, key and value variables
authorSergey Linnik <linniksa@gmail.com>
Fri, 11 Jul 2014 13:00:19 +0000 (17:00 +0400)
committerSergey Linnik <linniksa@gmail.com>
Fri, 11 Jul 2014 13:00:19 +0000 (17:00 +0400)
lib/Twig/NodeVisitor/Optimizer.php

index 06f69db..3cc3312 100644 (file)
@@ -28,6 +28,7 @@ class Twig_NodeVisitor_Optimizer implements Twig_NodeVisitorInterface
     const OPTIMIZE_VAR_ACCESS  = 8;
 
     protected $loops = array();
+    protected $loopsTargets = array();
     protected $optimizers;
     protected $prependedNodes = array();
     protected $inABody = false;
@@ -174,6 +175,8 @@ class Twig_NodeVisitor_Optimizer implements Twig_NodeVisitorInterface
             // disable the loop variable by default
             $node->setAttribute('with_loop', false);
             array_unshift($this->loops, $node);
+            array_unshift($this->loopsTargets, $node->getNode('value_target')->getAttribute('name'));
+            array_unshift($this->loopsTargets, $node->getNode('key_target')->getAttribute('name'));
         } elseif (!$this->loops) {
             // we are outside a loop
             return;
@@ -183,9 +186,15 @@ class Twig_NodeVisitor_Optimizer implements Twig_NodeVisitorInterface
 
         // the loop variable is referenced for the current loop
         elseif ($node instanceof Twig_Node_Expression_Name && 'loop' === $node->getAttribute('name')) {
+            $node->setAttribute('always_defined', true);
             $this->addLoopToCurrent();
         }
 
+        // optimize access to loop targets
+        elseif ($node instanceof Twig_Node_Expression_Name && in_array($node->getAttribute('name'), $this->loopsTargets)) {
+            $node->setAttribute('always_defined', true);
+        }
+
         // block reference
         elseif ($node instanceof Twig_Node_BlockReference || $node instanceof Twig_Node_Expression_BlockReference) {
             $this->addLoopToCurrent();
@@ -221,6 +230,8 @@ class Twig_NodeVisitor_Optimizer implements Twig_NodeVisitorInterface
     {
         if ($node instanceof Twig_Node_For) {
             array_shift($this->loops);
+            array_shift($this->loopsTargets);
+            array_shift($this->loopsTargets);
         }
     }