Verzeichnisstruktur phpBB-3.2.0


Veröffentlicht
06.01.2017

So funktioniert es


Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück

Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis.
Auf den Verzeichnisnamen klicken, dies zeigt nur das Verzeichnis mit Inhalt an

      (Beispiel Datei-Icons)

Auf das Icon klicken um den Quellcode anzuzeigen

Optimizer.php

Zuletzt modifiziert: 09.10.2024, 12:58 - Dateigröße: 8.85 KiB


 001  <?php
 002   
 003  /*
 004   * This file is part of Twig.
 005   *
 006   * (c) 2010 Fabien Potencier
 007   *
 008   * For the full copyright and license information, please view the LICENSE
 009   * file that was distributed with this source code.
 010   */
 011   
 012  /**
 013   * Twig_NodeVisitor_Optimizer tries to optimizes the AST.
 014   *
 015   * This visitor is always the last registered one.
 016   *
 017   * You can configure which optimizations you want to activate via the
 018   * optimizer mode.
 019   *
 020   * @author Fabien Potencier <fabien@symfony.com>
 021   */
 022  class Twig_NodeVisitor_Optimizer extends Twig_BaseNodeVisitor
 023  {
 024      const OPTIMIZE_ALL = -1;
 025      const OPTIMIZE_NONE = 0;
 026      const OPTIMIZE_FOR = 2;
 027      const OPTIMIZE_RAW_FILTER = 4;
 028      const OPTIMIZE_VAR_ACCESS = 8;
 029   
 030      protected $loops = array();
 031      protected $loopsTargets = array();
 032      protected $optimizers;
 033      protected $prependedNodes = array();
 034      protected $inABody = false;
 035   
 036      /**
 037       * Constructor.
 038       *
 039       * @param int $optimizers The optimizer mode
 040       */
 041      public function __construct($optimizers = -1)
 042      {
 043          if (!is_int($optimizers) || $optimizers > (self::OPTIMIZE_FOR | self::OPTIMIZE_RAW_FILTER | self::OPTIMIZE_VAR_ACCESS)) {
 044              throw new InvalidArgumentException(sprintf('Optimizer mode "%s" is not valid.', $optimizers));
 045          }
 046   
 047          $this->optimizers = $optimizers;
 048      }
 049   
 050      /**
 051       * {@inheritdoc}
 052       */
 053      protected function doEnterNode(Twig_Node $node, Twig_Environment $env)
 054      {
 055          if (self::OPTIMIZE_FOR === (self::OPTIMIZE_FOR & $this->optimizers)) {
 056              $this->enterOptimizeFor($node, $env);
 057          }
 058   
 059          if (PHP_VERSION_ID < 50400 && self::OPTIMIZE_VAR_ACCESS === (self::OPTIMIZE_VAR_ACCESS & $this->optimizers) && !$env->isStrictVariables() && !$env->hasExtension('sandbox')) {
 060              if ($this->inABody) {
 061                  if (!$node instanceof Twig_Node_Expression) {
 062                      if (get_class($node) !== 'Twig_Node') {
 063                          array_unshift($this->prependedNodes, array());
 064                      }
 065                  } else {
 066                      $node = $this->optimizeVariables($node, $env);
 067                  }
 068              } elseif ($node instanceof Twig_Node_Body) {
 069                  $this->inABody = true;
 070              }
 071          }
 072   
 073          return $node;
 074      }
 075   
 076      /**
 077       * {@inheritdoc}
 078       */
 079      protected function doLeaveNode(Twig_Node $node, Twig_Environment $env)
 080      {
 081          $expression = $node instanceof Twig_Node_Expression;
 082   
 083          if (self::OPTIMIZE_FOR === (self::OPTIMIZE_FOR & $this->optimizers)) {
 084              $this->leaveOptimizeFor($node, $env);
 085          }
 086   
 087          if (self::OPTIMIZE_RAW_FILTER === (self::OPTIMIZE_RAW_FILTER & $this->optimizers)) {
 088              $node = $this->optimizeRawFilter($node, $env);
 089          }
 090   
 091          $node = $this->optimizePrintNode($node, $env);
 092   
 093          if (self::OPTIMIZE_VAR_ACCESS === (self::OPTIMIZE_VAR_ACCESS & $this->optimizers) && !$env->isStrictVariables() && !$env->hasExtension('sandbox')) {
 094              if ($node instanceof Twig_Node_Body) {
 095                  $this->inABody = false;
 096              } elseif ($this->inABody) {
 097                  if (!$expression && get_class($node) !== 'Twig_Node' && $prependedNodes = array_shift($this->prependedNodes)) {
 098                      $nodes = array();
 099                      foreach (array_unique($prependedNodes) as $name) {
 100                          $nodes[] = new Twig_Node_SetTemp($name, $node->getLine());
 101                      }
 102   
 103                      $nodes[] = $node;
 104                      $node = new Twig_Node($nodes);
 105                  }
 106              }
 107          }
 108   
 109          return $node;
 110      }
 111   
 112      protected function optimizeVariables(Twig_NodeInterface $node, Twig_Environment $env)
 113      {
 114          if ('Twig_Node_Expression_Name' === get_class($node) && $node->isSimple()) {
 115              $this->prependedNodes[0][] = $node->getAttribute('name');
 116   
 117              return new Twig_Node_Expression_TempName($node->getAttribute('name'), $node->getLine());
 118          }
 119   
 120          return $node;
 121      }
 122   
 123      /**
 124       * Optimizes print nodes.
 125       *
 126       * It replaces:
 127       *
 128       *   * "echo $this->render(Parent)Block()" with "$this->display(Parent)Block()"
 129       *
 130       * @param Twig_NodeInterface $node A Node
 131       * @param Twig_Environment   $env  The current Twig environment
 132       *
 133       * @return Twig_NodeInterface
 134       */
 135      protected function optimizePrintNode(Twig_NodeInterface $node, Twig_Environment $env)
 136      {
 137          if (!$node instanceof Twig_Node_Print) {
 138              return $node;
 139          }
 140   
 141          if (
 142              $node->getNode('expr') instanceof Twig_Node_Expression_BlockReference ||
 143              $node->getNode('expr') instanceof Twig_Node_Expression_Parent
 144          ) {
 145              $node->getNode('expr')->setAttribute('output', true);
 146   
 147              return $node->getNode('expr');
 148          }
 149   
 150          return $node;
 151      }
 152   
 153      /**
 154       * Removes "raw" filters.
 155       *
 156       * @param Twig_NodeInterface $node A Node
 157       * @param Twig_Environment   $env  The current Twig environment
 158       *
 159       * @return Twig_NodeInterface
 160       */
 161      protected function optimizeRawFilter(Twig_NodeInterface $node, Twig_Environment $env)
 162      {
 163          if ($node instanceof Twig_Node_Expression_Filter && 'raw' == $node->getNode('filter')->getAttribute('value')) {
 164              return $node->getNode('node');
 165          }
 166   
 167          return $node;
 168      }
 169   
 170      /**
 171       * Optimizes "for" tag by removing the "loop" variable creation whenever possible.
 172       *
 173       * @param Twig_NodeInterface $node A Node
 174       * @param Twig_Environment   $env  The current Twig environment
 175       */
 176      protected function enterOptimizeFor(Twig_NodeInterface $node, Twig_Environment $env)
 177      {
 178          if ($node instanceof Twig_Node_For) {
 179              // disable the loop variable by default
 180              $node->setAttribute('with_loop', false);
 181              array_unshift($this->loops, $node);
 182              array_unshift($this->loopsTargets, $node->getNode('value_target')->getAttribute('name'));
 183              array_unshift($this->loopsTargets, $node->getNode('key_target')->getAttribute('name'));
 184          } elseif (!$this->loops) {
 185              // we are outside a loop
 186              return;
 187          }
 188   
 189          // when do we need to add the loop variable back?
 190   
 191          // the loop variable is referenced for the current loop
 192          elseif ($node instanceof Twig_Node_Expression_Name && 'loop' === $node->getAttribute('name')) {
 193              $node->setAttribute('always_defined', true);
 194              $this->addLoopToCurrent();
 195          }
 196   
 197          // optimize access to loop targets
 198          elseif ($node instanceof Twig_Node_Expression_Name && in_array($node->getAttribute('name'), $this->loopsTargets)) {
 199              $node->setAttribute('always_defined', true);
 200          }
 201   
 202          // block reference
 203          elseif ($node instanceof Twig_Node_BlockReference || $node instanceof Twig_Node_Expression_BlockReference) {
 204              $this->addLoopToCurrent();
 205          }
 206   
 207          // include without the only attribute
 208          elseif ($node instanceof Twig_Node_Include && !$node->getAttribute('only')) {
 209              $this->addLoopToAll();
 210          }
 211   
 212          // include function without the with_context=false parameter
 213          elseif ($node instanceof Twig_Node_Expression_Function
 214              && 'include' === $node->getAttribute('name')
 215              && (!$node->getNode('arguments')->hasNode('with_context')
 216                   || false !== $node->getNode('arguments')->getNode('with_context')->getAttribute('value')
 217                 )
 218          ) {
 219              $this->addLoopToAll();
 220          }
 221   
 222          // the loop variable is referenced via an attribute
 223          elseif ($node instanceof Twig_Node_Expression_GetAttr
 224              && (!$node->getNode('attribute') instanceof Twig_Node_Expression_Constant
 225                  || 'parent' === $node->getNode('attribute')->getAttribute('value')
 226                 )
 227              && (true === $this->loops[0]->getAttribute('with_loop')
 228                  || ($node->getNode('node') instanceof Twig_Node_Expression_Name
 229                      && 'loop' === $node->getNode('node')->getAttribute('name')
 230                     )
 231                 )
 232          ) {
 233              $this->addLoopToAll();
 234          }
 235      }
 236   
 237      /**
 238       * Optimizes "for" tag by removing the "loop" variable creation whenever possible.
 239       *
 240       * @param Twig_NodeInterface $node A Node
 241       * @param Twig_Environment   $env  The current Twig environment
 242       */
 243      protected function leaveOptimizeFor(Twig_NodeInterface $node, Twig_Environment $env)
 244      {
 245          if ($node instanceof Twig_Node_For) {
 246              array_shift($this->loops);
 247              array_shift($this->loopsTargets);
 248              array_shift($this->loopsTargets);
 249          }
 250      }
 251   
 252      protected function addLoopToCurrent()
 253      {
 254          $this->loops[0]->setAttribute('with_loop', true);
 255      }
 256   
 257      protected function addLoopToAll()
 258      {
 259          foreach ($this->loops as $loop) {
 260              $loop->setAttribute('with_loop', true);
 261          }
 262      }
 263   
 264      /**
 265       * {@inheritdoc}
 266       */
 267      public function getPriority()
 268      {
 269          return 255;
 270      }
 271  }
 272