From a4e10c14edfb5fa2b2996c7a10ef5348ea8115c5 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Fri, 12 Oct 2012 15:21:26 +0200 Subject: [PATCH] optimized macros when imported via the "import" tag This commit unifies the way macros are called independently of how they were included (via the from or import tag -- see e81c932). --- CHANGELOG | 1 + lib/Twig/ExpressionParser.php | 9 ++++++++- lib/Twig/Parser.php | 20 ++++++++++---------- lib/Twig/TokenParser/From.php | 2 +- lib/Twig/TokenParser/Import.php | 2 ++ 5 files changed, 22 insertions(+), 12 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 24ebea9..282c3be 100644 --- 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 diff --git a/lib/Twig/ExpressionParser.php b/lib/Twig/ExpressionParser.php index 0f35930..acfef01 100644 --- a/lib/Twig/ExpressionParser.php +++ b/lib/Twig/ExpressionParser.php @@ -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); } diff --git a/lib/Twig/Parser.php b/lib/Twig/Parser.php index d73cfde..13b72a0 100644 --- a/lib/Twig/Parser.php +++ b/lib/Twig/Parser.php @@ -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); } /** diff --git a/lib/Twig/TokenParser/From.php b/lib/Twig/TokenParser/From.php index 16999bc..d70b81f 100644 --- a/lib/Twig/TokenParser/From.php +++ b/lib/Twig/TokenParser/From.php @@ -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; diff --git a/lib/Twig/TokenParser/Import.php b/lib/Twig/TokenParser/Import.php index 5219289..482a8f5 100644 --- a/lib/Twig/TokenParser/Import.php +++ b/lib/Twig/TokenParser/Import.php @@ -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()); } -- 1.7.2.5