made a speed optimization to macro calls when imported via the from tag
authorFabien Potencier <fabien.potencier@gmail.com>
Mon, 23 Jan 2012 08:22:43 +0000 (09:22 +0100)
committerFabien Potencier <fabien.potencier@gmail.com>
Mon, 23 Jan 2012 08:22:43 +0000 (09:22 +0100)
CHANGELOG
lib/Twig/ExpressionParser.php
lib/Twig/Node/Expression/MethodCall.php [new file with mode: 0644]
lib/Twig/NodeVisitor/SafeAnalysis.php
lib/Twig/Template.php
lib/Twig/TokenParser/From.php

index be00af0..efb0adc 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,5 +1,6 @@
 * 1.6.0-DEV
 
+ * made a speed optimization to macro calls when imported via the "from" tag
  * fixed globals, parsers, visitors, filters, tests, and functions management in Twig_Environment when a new one or new extension is added
  * fixed the attribute function when passing arguments
  * added slice notation support for the [] operator (syntactic sugar for the slice operator)
index ca2c5f0..8cf91d8 100644 (file)
@@ -314,7 +314,10 @@ class Twig_ExpressionParser
                         $arguments->addElement($n);
                     }
 
-                    return new Twig_Node_Expression_GetAttr($alias['node'], new Twig_Node_Expression_Constant($alias['name'], $line), $arguments, Twig_TemplateInterface::METHOD_CALL, $line);
+                    $node = new Twig_Node_Expression_MethodCall($alias['node'], $alias['name'], $arguments, $line);
+                    $node->setAttribute('safe', true);
+
+                    return $node;
                 }
 
                 $class = $this->getFunctionNodeClass($name);
diff --git a/lib/Twig/Node/Expression/MethodCall.php b/lib/Twig/Node/Expression/MethodCall.php
new file mode 100644 (file)
index 0000000..5093808
--- /dev/null
@@ -0,0 +1,37 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2012 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class Twig_Node_Expression_MethodCall extends Twig_Node_Expression
+{
+    public function __construct(Twig_Node_Expression $node, $method, Twig_Node_Expression_Array $arguments, $lineno)
+    {
+        parent::__construct(array('node' => $node, 'arguments' => $arguments), array('method' => $method, 'safe' => false), $lineno);
+    }
+
+    public function compile(Twig_Compiler $compiler)
+    {
+        $compiler
+            ->subcompile($this->getNode('node'))
+            ->raw('->')
+            ->raw($this->getAttribute('method'))
+            ->raw('(')
+        ;
+        $first = true;
+        foreach ($this->getNode('arguments')->getKeyValuePairs() as $pair) {
+            if (!$first) {
+                $compiler->raw(', ');
+            }
+            $first = false;
+
+            $compiler->subcompile($pair['value']);
+        }
+        $compiler->raw(')');
+    }
+}
index 5961ba2..f068a16 100644 (file)
@@ -73,6 +73,12 @@ class Twig_NodeVisitor_SafeAnalysis implements Twig_NodeVisitorInterface
             } else {
                 $this->setSafe($node, array());
             }
+        } elseif ($node instanceof Twig_Node_Expression_MethodCall) {
+            if ($node->getAttribute('safe')) {
+                $this->setSafe($node, array('all'));
+            } else {
+                $this->setSafe($node, array());
+            }
         } else {
             $this->setSafe($node, array());
         }
index 86ca5c6..324410e 100644 (file)
@@ -427,6 +427,7 @@ abstract class Twig_Template implements Twig_TemplateInterface
 
         $ret = call_user_func_array(array($object, $method), $arguments);
 
+        // hack to be removed when macro calls are refactored
         if ($object instanceof Twig_TemplateInterface) {
             return new Twig_Markup($ret, $this->env->getCharset());
         }
index ba4d7ff..4e20f5c 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, $name, $node->getNode('var'));
+            $this->parser->addImportedFunction($alias, 'get'.$name, $node->getNode('var'));
         }
 
         return $node;