1<?php 2 3/* 4 * This file is part of Twig. 5 * 6 * (c) Fabien Potencier 7 * 8 * For the full copyright and license information, please view the LICENSE 9 * file that was distributed with this source code. 10 */ 11 12namespace Twig; 13 14use Twig\NodeVisitor\NodeVisitorInterface; 15 16/** 17 * A node traverser. 18 * 19 * It visits all nodes and their children and calls the given visitor for each. 20 * 21 * @final 22 * 23 * @author Fabien Potencier <fabien@symfony.com> 24 */ 25class NodeTraverser 26{ 27 protected $env; 28 protected $visitors = []; 29 30 /** 31 * @param NodeVisitorInterface[] $visitors 32 */ 33 public function __construct(Environment $env, array $visitors = []) 34 { 35 $this->env = $env; 36 foreach ($visitors as $visitor) { 37 $this->addVisitor($visitor); 38 } 39 } 40 41 public function addVisitor(NodeVisitorInterface $visitor) 42 { 43 $this->visitors[$visitor->getPriority()][] = $visitor; 44 } 45 46 /** 47 * Traverses a node and calls the registered visitors. 48 * 49 * @return \Twig_NodeInterface 50 */ 51 public function traverse(\Twig_NodeInterface $node) 52 { 53 ksort($this->visitors); 54 foreach ($this->visitors as $visitors) { 55 foreach ($visitors as $visitor) { 56 $node = $this->traverseForVisitor($visitor, $node); 57 } 58 } 59 60 return $node; 61 } 62 63 protected function traverseForVisitor(NodeVisitorInterface $visitor, \Twig_NodeInterface $node = null) 64 { 65 if (null === $node) { 66 return; 67 } 68 69 $node = $visitor->enterNode($node, $this->env); 70 71 foreach ($node as $k => $n) { 72 if (false !== $m = $this->traverseForVisitor($visitor, $n)) { 73 if ($m !== $n) { 74 $node->setNode($k, $m); 75 } 76 } else { 77 $node->removeNode($k); 78 } 79 } 80 81 return $visitor->leaveNode($node, $this->env); 82 } 83} 84 85class_alias('Twig\NodeTraverser', 'Twig_NodeTraverser'); 86