added an optimization for simple variables output
authorFabien Potencier <fabien.potencier@gmail.com>
Fri, 30 Sep 2011 12:54:26 +0000 (14:54 +0200)
committerFabien Potencier <fabien.potencier@gmail.com>
Fri, 30 Sep 2011 15:11:02 +0000 (17:11 +0200)
lib/Twig/Node/Expression/Name.php
lib/Twig/NodeVisitor/Optimizer.php
test/Twig/Tests/NodeVisitor/OptimizerTest.php

index 74065bb..1dacc87 100644 (file)
@@ -13,7 +13,7 @@ class Twig_Node_Expression_Name extends Twig_Node_Expression
 {
     public function __construct($name, $lineno)
     {
-        parent::__construct(array(), array('name' => $name), $lineno);
+        parent::__construct(array(), array('name' => $name, 'output' => false), $lineno);
     }
 
     public function compile(Twig_Compiler $compiler)
@@ -34,6 +34,19 @@ class Twig_Node_Expression_Name extends Twig_Node_Expression
             }
         } elseif (isset($specialVars[$name])) {
             $compiler->raw($specialVars[$name]);
+        } elseif ($this->getAttribute('output')) {
+            $compiler
+                ->addDebugInfo($this)
+                ->write('if (isset($context[')
+                ->string($name)
+                ->raw("])) {\n")
+                ->indent()
+                ->write('echo $context[')
+                ->string($name)
+                ->raw("];\n")
+                ->outdent()
+                ->write("}\n")
+            ;
         } else {
             $compiler
                 ->raw('$this->getContext($context, ')
index d08e902..9bb3b8f 100644 (file)
@@ -69,24 +69,33 @@ class Twig_NodeVisitor_Optimizer implements Twig_NodeVisitorInterface
             $node = $this->optimizeRawFilter($node, $env);
         }
 
-        $node = $this->optimizeRenderBlock($node, $env);
+        $node = $this->optimizePrintNode($node, $env);
 
         return $node;
     }
 
     /**
-     * Replaces "echo $this->render(Parent)Block()" with "$this->display(Parent)Block()".
+     * Optimizes print nodes.
+     *
+     * It replaces:
+     *
+     *   * "echo $this->render(Parent)Block()" with "$this->display(Parent)Block()"
+     *   * "echo $this->getContext('...')" with "if (isset('...')) { echo '...' }"
      *
      * @param Twig_NodeInterface $node A Node
      * @param Twig_Environment   $env  The current Twig environment
      */
-    protected function optimizeRenderBlock($node, $env)
+    protected function optimizePrintNode($node, $env)
     {
         if (!$node instanceof Twig_Node_Print) {
             return $node;
         }
 
-        if ($node->getNode('expr') instanceof Twig_Node_Expression_BlockReference || $node->getNode('expr') instanceof Twig_Node_Expression_Parent) {
+        if (
+            $node->getNode('expr') instanceof Twig_Node_Expression_BlockReference ||
+            $node->getNode('expr') instanceof Twig_Node_Expression_Parent ||
+            ($node->getNode('expr') instanceof Twig_Node_Expression_Name && !$env->hasExtension('sandbox'))
+        ) {
             $node->getNode('expr')->setAttribute('output', true);
 
             return $node->getNode('expr');
index e0f3453..b6aa979 100644 (file)
@@ -48,6 +48,18 @@ class Twig_Tests_NodeVisitor_OptimizerTest extends PHPUnit_Framework_TestCase
         $this->assertTrue($node->getAttribute('output'));
     }
 
+    public function testRenderNameOptimizer()
+    {
+        $env = new Twig_Environment(new Twig_Loader_String(), array('cache' => false, 'autoescape' => false));
+        $env->addExtension(new Twig_Extension_Optimizer());
+        $stream = $env->parse($env->tokenize('{{ name }}', 'index'));
+
+        $node = $stream->getNode('body');
+
+        $this->assertInstanceOf('Twig_Node_Expression_Name', $node);
+        $this->assertTrue($node->getAttribute('output'));
+    }
+
     /**
      * @dataProvider getTestsForForOptimizer
      */