118 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			118 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php
 | |
| 
 | |
| class PHPParser_NodeTraverser implements PHPParser_NodeTraverserInterface
 | |
| {
 | |
|     /**
 | |
|      * @var PHPParser_NodeVisitor[] Visitors
 | |
|      */
 | |
|     protected $visitors;
 | |
| 
 | |
|     /**
 | |
|      * Constructs a node traverser.
 | |
|      */
 | |
|     public function __construct() {
 | |
|         $this->visitors = array();
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Adds a visitor.
 | |
|      *
 | |
|      * @param PHPParser_NodeVisitor $visitor Visitor to add
 | |
|      */
 | |
|     public function addVisitor(PHPParser_NodeVisitor $visitor) {
 | |
|         $this->visitors[] = $visitor;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Traverses an array of nodes using the registered visitors.
 | |
|      *
 | |
|      * @param PHPParser_Node[] $nodes Array of nodes
 | |
|      *
 | |
|      * @return PHPParser_Node[] Traversed array of nodes
 | |
|      */
 | |
|     public function traverse(array $nodes) {
 | |
|         foreach ($this->visitors as $visitor) {
 | |
|             if (null !== $return = $visitor->beforeTraverse($nodes)) {
 | |
|                 $nodes = $return;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         $nodes = $this->traverseArray($nodes);
 | |
| 
 | |
|         foreach ($this->visitors as $visitor) {
 | |
|             if (null !== $return = $visitor->afterTraverse($nodes)) {
 | |
|                 $nodes = $return;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         return $nodes;
 | |
|     }
 | |
| 
 | |
|     protected function traverseNode(PHPParser_Node $node) {
 | |
|         $node = clone $node;
 | |
| 
 | |
|         foreach ($node->getSubNodeNames() as $name) {
 | |
|             $subNode =& $node->$name;
 | |
| 
 | |
|             if (is_array($subNode)) {
 | |
|                 $subNode = $this->traverseArray($subNode);
 | |
|             } elseif ($subNode instanceof PHPParser_Node) {
 | |
|                 foreach ($this->visitors as $visitor) {
 | |
|                     if (null !== $return = $visitor->enterNode($subNode)) {
 | |
|                         $subNode = $return;
 | |
|                     }
 | |
|                 }
 | |
| 
 | |
|                 $subNode = $this->traverseNode($subNode);
 | |
| 
 | |
|                 foreach ($this->visitors as $visitor) {
 | |
|                     if (null !== $return = $visitor->leaveNode($subNode)) {
 | |
|                         $subNode = $return;
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         return $node;
 | |
|     }
 | |
| 
 | |
|     protected function traverseArray(array $nodes) {
 | |
|         $doNodes = array();
 | |
| 
 | |
|         foreach ($nodes as $i => &$node) {
 | |
|             if (is_array($node)) {
 | |
|                 $node = $this->traverseArray($node);
 | |
|             } elseif ($node instanceof PHPParser_Node) {
 | |
|                 foreach ($this->visitors as $visitor) {
 | |
|                     if (null !== $return = $visitor->enterNode($node)) {
 | |
|                         $node = $return;
 | |
|                     }
 | |
|                 }
 | |
| 
 | |
|                 $node = $this->traverseNode($node);
 | |
| 
 | |
|                 foreach ($this->visitors as $visitor) {
 | |
|                     $return = $visitor->leaveNode($node);
 | |
| 
 | |
|                     if (false === $return) {
 | |
|                         $doNodes[] = array($i, array());
 | |
|                         break;
 | |
|                     } elseif (is_array($return)) {
 | |
|                         $doNodes[] = array($i, $return);
 | |
|                         break;
 | |
|                     } elseif (null !== $return) {
 | |
|                         $node = $return;
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         if (!empty($doNodes)) {
 | |
|             while (list($i, $replace) = array_pop($doNodes)) {
 | |
|                 array_splice($nodes, $i, 1, $replace);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         return $nodes;
 | |
|     }
 | |
| } |