optimized macros when imported via the "import" tag
authorFabien Potencier <fabien.potencier@gmail.com>
Fri, 12 Oct 2012 13:21:26 +0000 (15:21 +0200)
committerFabien Potencier <fabien.potencier@gmail.com>
Fri, 12 Oct 2012 14:09:40 +0000 (16:09 +0200)
This commit unifies the way macros are called independently of how they
were included (via the from or import tag -- see e81c932).

CHANGELOG
lib/Twig/ExpressionParser.php
lib/Twig/Parser.php
lib/Twig/TokenParser/From.php
lib/Twig/TokenParser/Import.php

index 24ebea9..282c3be 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,5 +1,6 @@
 * 1.10.1 (2012-XX-XX)
 
+ * made a speed optimization to macro calls when imported via the "import" tag
  * fixed C extension compilation on Windows
  * fixed a segfault in the C extension when using DateTime objects
 
index 0f35930..acfef01 100644 (file)
@@ -308,7 +308,7 @@ class Twig_ExpressionParser
 
                 return new Twig_Node_Expression_GetAttr($args->getNode(0), $args->getNode(1), count($args) > 2 ? $args->getNode(2) : new Twig_Node_Expression_Array(array(), $line), Twig_TemplateInterface::ANY_CALL, $line);
             default:
-                if (null !== $alias = $this->parser->getImportedFunction($name)) {
+                if (null !== $alias = $this->parser->getImportedSymbol($name, 'function')) {
                     $arguments = new Twig_Node_Expression_Array(array(), $line);
                     foreach ($args as $n) {
                         $arguments->addElement($n);
@@ -380,6 +380,13 @@ class Twig_ExpressionParser
             $stream->expect(Twig_Token::PUNCTUATION_TYPE, ']');
         }
 
+        if ($node instanceof Twig_Node_Expression_Name && null !== $alias = $this->parser->getImportedSymbol($node->getAttribute('name'), 'template')) {
+            $node = new Twig_Node_Expression_MethodCall($node, 'get'.$arg->getAttribute('value'), $arguments, $lineno);
+            $node->setAttribute('safe', true);
+
+            return $node;
+        }
+
         return new Twig_Node_Expression_GetAttr($node, $arg, $arguments, $type, $lineno);
     }
 
index d73cfde..13b72a0 100644 (file)
@@ -29,7 +29,7 @@ class Twig_Parser implements Twig_ParserInterface
     protected $macros;
     protected $env;
     protected $reservedMacroNames;
-    protected $importedFunctions;
+    protected $importedSymbols;
     protected $traits;
     protected $embeddedTemplates = array();
 
@@ -88,7 +88,7 @@ class Twig_Parser implements Twig_ParserInterface
         $this->macros = array();
         $this->traits = array();
         $this->blockStack = array();
-        $this->importedFunctions = array(array());
+        $this->importedSymbols = array(array());
         $this->embeddedTemplates = array();
 
         try {
@@ -282,15 +282,15 @@ class Twig_Parser implements Twig_ParserInterface
         $this->embeddedTemplates[] = $template;
     }
 
-    public function addImportedFunction($alias, $name, Twig_Node_Expression $node)
+    public function addImportedSymbol($alias, $name, Twig_Node_Expression $node = null, $type)
     {
-        $this->importedFunctions[0][$alias] = array('name' => $name, 'node' => $node);
+        $this->importedSymbols[0][$alias] = array('name' => $name, 'node' => $node, 'type' => $type);
     }
 
-    public function getImportedFunction($alias)
+    public function getImportedSymbol($alias, $type)
     {
-        foreach ($this->importedFunctions as $functions) {
-            if (isset($functions[$alias])) {
+        foreach ($this->importedSymbols as $functions) {
+            if (isset($functions[$alias]) && $type === $functions[$alias]['type']) {
                 return $functions[$alias];
             }
         }
@@ -298,17 +298,17 @@ class Twig_Parser implements Twig_ParserInterface
 
     public function isMainScope()
     {
-        return 1 === count($this->importedFunctions);
+        return 1 === count($this->importedSymbols);
     }
 
     public function pushLocalScope()
     {
-        array_unshift($this->importedFunctions, array());
+        array_unshift($this->importedSymbols, array());
     }
 
     public function popLocalScope()
     {
-        array_shift($this->importedFunctions);
+        array_shift($this->importedSymbols);
     }
 
     /**
index 16999bc..d70b81f 100644 (file)
@@ -56,7 +56,7 @@ class Twig_TokenParser_From extends Twig_TokenParser
         $node = new Twig_Node_Import($macro, new Twig_Node_Expression_AssignName($this->parser->getVarName(), $token->getLine()), $token->getLine(), $this->getTag());
 
         foreach ($targets as $name => $alias) {
-            $this->parser->addImportedFunction($alias, 'get'.$name, $node->getNode('var'));
+            $this->parser->addImportedSymbol($alias, 'get'.$name, $node->getNode('var'), 'function');
         }
 
         return $node;
index 5219289..482a8f5 100644 (file)
@@ -32,6 +32,8 @@ class Twig_TokenParser_Import extends Twig_TokenParser
         $var = new Twig_Node_Expression_AssignName($this->parser->getStream()->expect(Twig_Token::NAME_TYPE)->getValue(), $token->getLine());
         $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
 
+        $this->parser->addImportedSymbol($var->getAttribute('name'), null, null, 'template');
+
         return new Twig_Node_Import($macro, $var, $token->getLine(), $this->getTag());
     }