summaryrefslogtreecommitdiff
path: root/inc/lib/Twig/NodeVisitor/Optimizer.php
diff options
context:
space:
mode:
authorMichael Foster <savetheinternet@tinyboard.org>2013-08-01 15:20:12 -0400
committerMichael Foster <savetheinternet@tinyboard.org>2013-08-01 15:20:12 -0400
commit0fe552857468aa12097a74e08f51f5aaa983be07 (patch)
tree22dbca1be90d7086b20a077752552296abf23325 /inc/lib/Twig/NodeVisitor/Optimizer.php
parent22f3a95e0e421de05a11633eac846df96a2a4768 (diff)
Upgrade Twig library
Diffstat (limited to 'inc/lib/Twig/NodeVisitor/Optimizer.php')
-rw-r--r--inc/lib/Twig/NodeVisitor/Optimizer.php68
1 files changed, 62 insertions, 6 deletions
diff --git a/inc/lib/Twig/NodeVisitor/Optimizer.php b/inc/lib/Twig/NodeVisitor/Optimizer.php
index 3679746e..a254def7 100644
--- a/inc/lib/Twig/NodeVisitor/Optimizer.php
+++ b/inc/lib/Twig/NodeVisitor/Optimizer.php
@@ -17,8 +17,7 @@
* You can configure which optimizations you want to activate via the
* optimizer mode.
*
- * @package twig
- * @author Fabien Potencier <fabien@symfony.com>
+ * @author Fabien Potencier <fabien@symfony.com>
*/
class Twig_NodeVisitor_Optimizer implements Twig_NodeVisitorInterface
{
@@ -26,9 +25,12 @@ class Twig_NodeVisitor_Optimizer implements Twig_NodeVisitorInterface
const OPTIMIZE_NONE = 0;
const OPTIMIZE_FOR = 2;
const OPTIMIZE_RAW_FILTER = 4;
+ const OPTIMIZE_VAR_ACCESS = 8;
protected $loops = array();
protected $optimizers;
+ protected $prependedNodes = array();
+ protected $inABody = false;
/**
* Constructor.
@@ -53,6 +55,20 @@ class Twig_NodeVisitor_Optimizer implements Twig_NodeVisitorInterface
$this->enterOptimizeFor($node, $env);
}
+ if (!version_compare(phpversion(), '5.4.0RC1', '>=') && self::OPTIMIZE_VAR_ACCESS === (self::OPTIMIZE_VAR_ACCESS & $this->optimizers) && !$env->isStrictVariables() && !$env->hasExtension('sandbox')) {
+ if ($this->inABody) {
+ if (!$node instanceof Twig_Node_Expression) {
+ if (get_class($node) !== 'Twig_Node') {
+ array_unshift($this->prependedNodes, array());
+ }
+ } else {
+ $node = $this->optimizeVariables($node, $env);
+ }
+ } elseif ($node instanceof Twig_Node_Body) {
+ $this->inABody = true;
+ }
+ }
+
return $node;
}
@@ -61,6 +77,8 @@ class Twig_NodeVisitor_Optimizer implements Twig_NodeVisitorInterface
*/
public function leaveNode(Twig_NodeInterface $node, Twig_Environment $env)
{
+ $expression = $node instanceof Twig_Node_Expression;
+
if (self::OPTIMIZE_FOR === (self::OPTIMIZE_FOR & $this->optimizers)) {
$this->leaveOptimizeFor($node, $env);
}
@@ -69,20 +87,58 @@ class Twig_NodeVisitor_Optimizer implements Twig_NodeVisitorInterface
$node = $this->optimizeRawFilter($node, $env);
}
- $node = $this->optimizeRenderBlock($node, $env);
+ $node = $this->optimizePrintNode($node, $env);
+
+ if (self::OPTIMIZE_VAR_ACCESS === (self::OPTIMIZE_VAR_ACCESS & $this->optimizers) && !$env->isStrictVariables() && !$env->hasExtension('sandbox')) {
+ if ($node instanceof Twig_Node_Body) {
+ $this->inABody = false;
+ } elseif ($this->inABody) {
+ if (!$expression && get_class($node) !== 'Twig_Node' && $prependedNodes = array_shift($this->prependedNodes)) {
+ $nodes = array();
+ foreach (array_unique($prependedNodes) as $name) {
+ $nodes[] = new Twig_Node_SetTemp($name, $node->getLine());
+ }
+
+ $nodes[] = $node;
+ $node = new Twig_Node($nodes);
+ }
+ }
+ }
+
+ return $node;
+ }
+
+ protected function optimizeVariables($node, $env)
+ {
+ if ('Twig_Node_Expression_Name' === get_class($node) && $node->isSimple()) {
+ $this->prependedNodes[0][] = $node->getAttribute('name');
+
+ return new Twig_Node_Expression_TempName($node->getAttribute('name'), $node->getLine());
+ }
return $node;
}
/**
- * Replaces "echo $this->renderBlock()" with "$this->displayBlock()".
+ * Optimizes print nodes.
+ *
+ * It replaces:
+ *
+ * * "echo $this->render(Parent)Block()" with "$this->display(Parent)Block()"
*
* @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 && $node->getNode('expr') instanceof Twig_Node_Expression_BlockReference) {
+ 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
+ ) {
$node->getNode('expr')->setAttribute('output', true);
return $node->getNode('expr');