1
0
mirror of https://github.com/danog/PHP-Parser.git synced 2024-11-30 04:19:30 +01:00

Use classes for visitors

This commit is contained in:
nikic 2011-08-09 09:27:47 +02:00
parent ffecbf8ca5
commit f00701fd8a
3 changed files with 68 additions and 49 deletions

View File

@ -2,83 +2,61 @@
class PHPParser_NodeTraverser
{
const ON_ENTER = 1;
const ON_LEAVE = 2;
protected $enterVisitors;
protected $leaveVisitors;
/**
* @var PHPParser_NodeVisitorInterface[] Visitors
*/
protected $visitors;
/**
* Constructs a node traverser.
*/
public function __construct() {
$this->enterVisitors = $this->leaveVisitors = array();
$this->visitors = array();
}
/**
* Adds a node visitor.
* Adds a visitor.
*
* The callback gets the node passed as only argument and may return a replacement for the node
* or return null/nothing, in which case the node is left untouched.
*
* The mode specifies when the node should be visited:
* * using self::ON_ENTER the node is visited before traversing its sub nodes
* * using self::ON_LEAVE the node is visited after traversing its sub nodes
* * using self::ON_ENTER | self::ON_LEAVE the node is visited both before and after traversing
* its subnodes
* The default is to visit the node ON_ENTER.
*
* Visitors are called in the order they were registered in.
*
* @param callback $visitor Visitor callback
* @param int $mode Visitor mode (bitmap using self::ON_ENTER and self::ON_LEAVE)
*
* @throws InvalidArgumentException if visitor is not callable
* @param PHPParser_NodeVisitorInterface $visitor Visitor to add
*/
public function addVisitor($visitor, $mode = self::ON_ENTER) {
if (!is_callable($visitor)) {
throw new InvalidArgumentException('Visitor not callable');
}
if ($mode & self::ON_ENTER) {
$this->enterVisitors[] = $visitor;
}
if ($mode & self::ON_LEAVE) {
$this->leaveVisitors[] = $visitor;
}
public function addVisitor(PHPParser_NodeVisitorInterface $visitor) {
$this->visitors[] = $visitor;
}
/**
* Traverses a node or an array using the registered visitors.
*
* @param PHPParser_NodeAbstract|array $node Node or array
*
* @return mixed Node after all visitors were applied.
*/
public function traverse($node) {
public function traverse(&$node) {
foreach ($this->visitors as $visitor) {
$visitor->beforeTraverse($node);
}
$this->_traverse($node);
foreach ($this->visitors as $visitor) {
$visitor->afterTraverse($node);
}
}
protected function _traverse(&$node) {
if ($node instanceof PHPParser_NodeAbstract) {
foreach ($this->enterVisitors as $visitor) {
if (null !== $return = call_user_func($visitor, $node)) {
$node = $return;
}
foreach ($this->visitors as $visitor) {
$visitor->enterNode($node);
}
}
if (is_array($node) || $node instanceof Traversable) {
foreach ($node as &$subNode) {
$subNode = $this->traverse($subNode);
$this->_traverse($subNode);
}
}
if ($node instanceof PHPParser_NodeAbstract) {
foreach ($this->leaveVisitors as $visitor) {
if (null !== $return = call_user_func($visitor, $node)) {
$node = $return;
}
foreach ($this->visitors as $visitor) {
$visitor->leaveNode($node);
}
}
return $node;
}
}

View File

@ -0,0 +1,9 @@
<?php
class PHPParser_NodeVisitorAbstract implements PHPParser_NodeVisitorInterface
{
public function beforeTraverse(&$node) { }
public function enterNode(PHPParser_NodeAbstract &$node) { }
public function leaveNode(PHPParser_NodeAbstract &$node) { }
public function afterTraverse(&$node) { }
}

View File

@ -0,0 +1,32 @@
<?php
interface PHPParser_NodeVisitorInterface
{
/**
* Called once before traversal.
*
* @param $node
*/
public function beforeTraverse(&$node);
/**
* Called when entering a node.
*
* @param PHPParser_NodeAbstract $node
*/
public function enterNode(PHPParser_NodeAbstract &$node);
/**
* Called when leaving a node.
*
* @param PHPParser_NodeAbstract $node
*/
public function leaveNode(PHPParser_NodeAbstract &$node);
/**
* Called once after traversal.
*
* @param $node
*/
public function afterTraverse(&$node);
}