Do not use Node_Expression_Name for function names, just use strings for those
authornikic <nikita.ppv@googlemail.com>
Sun, 3 Jul 2011 10:26:50 +0000 (12:26 +0200)
committernikic <nikita.ppv@googlemail.com>
Sat, 6 Aug 2011 09:21:23 +0000 (11:21 +0200)
lib/Twig/ExpressionParser.php
lib/Twig/Node/Expression/Function.php
lib/Twig/NodeVisitor/SafeAnalysis.php
lib/Twig/NodeVisitor/Sandbox.php
test/Twig/Tests/Node/Expression/FunctionTest.php

index 2be47fb..db5b6b5 100644 (file)
@@ -134,7 +134,11 @@ class Twig_ExpressionParser
                         break;
 
                     default:
-                        $node = new Twig_Node_Expression_Name($token->getValue(), $token->getLine());
+                        if ('(' === $this->parser->getCurrentToken()->getValue()) {
+                            $node = $this->getFunctionNode($token->getValue(), $token->getLine());
+                        } else {
+                            $node = new Twig_Node_Expression_Name($token->getValue(), $token->getLine());
+                        }
                 }
                 break;
 
@@ -210,7 +214,6 @@ class Twig_ExpressionParser
 
     public function parsePostfixExpression($node)
     {
-        $firstPass = true;
         while (true) {
             $token = $this->parser->getCurrentToken();
             if ($token->getType() == Twig_Token::PUNCTUATION_TYPE) {
@@ -218,46 +221,42 @@ class Twig_ExpressionParser
                     $node = $this->parseSubscriptExpression($node);
                 } elseif ('|' == $token->getValue()) {
                     $node = $this->parseFilterExpression($node);
-                } elseif ($firstPass && $node instanceof Twig_Node_Expression_Name && '(' == $token->getValue()) {
-                    $node = $this->getFunctionNode($node);
                 } else {
                     break;
                 }
             } else {
                 break;
             }
-
-            $firstPass = false;
         }
 
         return $node;
     }
 
-    public function getFunctionNode(Twig_Node_Expression_Name $node)
+    public function getFunctionNode($name, $line)
     {
         $args = $this->parseArguments();
 
-        if ('parent' === $node->getAttribute('name')) {
+        if ('parent' === $name) {
             if (!count($this->parser->getBlockStack())) {
-                throw new Twig_Error_Syntax('Calling "parent" outside a block is forbidden', $node->getLine());
+                throw new Twig_Error_Syntax('Calling "parent" outside a block is forbidden', $line);
             }
 
             if (!$this->parser->getParent()) {
-                throw new Twig_Error_Syntax('Calling "parent" on a template that does not extend another one is forbidden', $node->getLine());
+                throw new Twig_Error_Syntax('Calling "parent" on a template that does not extend another one is forbidden', $line);
             }
 
-            return new Twig_Node_Expression_Parent($this->parser->peekBlockStack(), $node->getLine());
+            return new Twig_Node_Expression_Parent($this->parser->peekBlockStack(), $line);
         }
 
-        if ('block' === $node->getAttribute('name')) {
-            return new Twig_Node_Expression_BlockReference($args->getNode(0), false, $node->getLine());
+        if ('block' === $name) {
+            return new Twig_Node_Expression_BlockReference($args->getNode(0), false, $line);
         }
 
-        if (null !== $alias = $this->parser->getImportedFunction($node->getAttribute('name'))) {
-            return new Twig_Node_Expression_GetAttr($alias['node'], new Twig_Node_Expression_Constant($alias['name'], $node->getLine()), $args, Twig_TemplateInterface::METHOD_CALL, $node->getLine());
+        if (null !== $alias = $this->parser->getImportedFunction($name)) {
+            return new Twig_Node_Expression_GetAttr($alias['node'], new Twig_Node_Expression_Constant($alias['name'], $line), $args, Twig_TemplateInterface::METHOD_CALL, $line);
         }
 
-        return new Twig_Node_Expression_Function($node, $args, $node->getLine());
+        return new Twig_Node_Expression_Function($name, $args, $line);
     }
 
     public function parseSubscriptExpression($node)
index ffa0515..3f45719 100644 (file)
  */
 class Twig_Node_Expression_Function extends Twig_Node_Expression
 {
-    public function __construct(Twig_Node_Expression_Name $name, Twig_NodeInterface $arguments, $lineno)
+    public function __construct($name, Twig_NodeInterface $arguments, $lineno)
     {
-        parent::__construct(array('name' => $name, 'arguments' => $arguments), array(), $lineno);
+        parent::__construct(array('arguments' => $arguments), array('name' => $name), $lineno);
     }
 
     public function compile(Twig_Compiler $compiler)
     {
-        $function = $compiler->getEnvironment()->getFunction($this->getNode('name')->getAttribute('name'));
+        $function = $compiler->getEnvironment()->getFunction($this->getAttribute('name'));
         if (false === $function) {
-            throw new Twig_Error_Syntax(sprintf('The function "%s" does not exist', $this->getNode('name')->getAttribute('name')), $this->getLine());
+            throw new Twig_Error_Syntax(sprintf('The function "%s" does not exist', $this->getAttribute('name')), $this->getLine());
         }
 
         $compiler
index 1874581..5961ba2 100644 (file)
@@ -65,7 +65,7 @@ class Twig_NodeVisitor_SafeAnalysis implements Twig_NodeVisitorInterface
             }
         } elseif ($node instanceof Twig_Node_Expression_Function) {
             // function expression is safe when the function is safe
-            $name = $node->getNode('name')->getAttribute('name');
+            $name = $node->getAttribute('name');
             $args = $node->getNode('arguments');
             $function = $env->getFunction($name);
             if (false !== $function) {
index e9e1e1a..356b661 100644 (file)
@@ -52,7 +52,7 @@ class Twig_NodeVisitor_Sandbox implements Twig_NodeVisitorInterface
 
             // look for functions
             if ($node instanceof Twig_Node_Expression_Function) {
-                $this->functions[] = $node->getNode('name')->getAttribute('name');
+                $this->functions[] = $node->getAttribute('name');
             }
 
             // wrap print to check __toString() calls
index 69f5225..5f1e5a6 100644 (file)
@@ -18,11 +18,11 @@ class Twig_Tests_Node_Expression_FunctionTest extends Twig_Tests_Node_TestCase
      */
     public function testConstructor()
     {
-        $name = new Twig_Node_Expression_Name('function', 0);
+        $name = 'function';
         $args = new Twig_Node();
         $node = new Twig_Node_Expression_Function($name, $args, 0);
 
-        $this->assertEquals($name, $node->getNode('name'));
+        $this->assertEquals($name, $node->getAttribute('name'));
         $this->assertEquals($args, $node->getNode('arguments'));
     }
 
@@ -85,7 +85,6 @@ class Twig_Tests_Node_Expression_FunctionTest extends Twig_Tests_Node_TestCase
 
     protected function createFunction($name, array $arguments = array())
     {
-        $name = new Twig_Node_Expression_Name($name, 0);
         $arguments = new Twig_Node($arguments);
         return new Twig_Node_Expression_Function($name, $arguments, 0);
     }