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