Add possibility to delete and merge nodes in traverser

This commit is contained in:
nikic 2011-08-09 12:32:18 +02:00
parent f00701fd8a
commit 567f7c3536

View File

@ -41,21 +41,54 @@ class PHPParser_NodeTraverser
}
protected function _traverse(&$node) {
if ($node instanceof PHPParser_NodeAbstract) {
foreach ($this->visitors as $visitor) {
$visitor->enterNode($node);
if (!is_array($node) && !$node instanceof Traversable) {
return;
}
$delNodes = array();
$mrgNodes = array();
foreach ($node as $subNodeKey => &$subNode) {
if ($subNode instanceof PHPParser_NodeAbstract) {
foreach ($this->visitors as $visitor) {
$visitor->enterNode($subNode);
}
}
$this->_traverse($subNode);
if ($subNode instanceof PHPParser_NodeAbstract) {
foreach ($this->visitors as $visitor) {
$return = $visitor->leaveNode($subNode);
if (false === $return) {
$delNodes[] = $subNodeKey;
} elseif (is_array($return)) {
$mrgNodes[] = array($subNodeKey, $return);
}
}
}
}
if (is_array($node) || $node instanceof Traversable) {
foreach ($node as &$subNode) {
$this->_traverse($subNode);
if (!empty($delNodes)) {
if (is_array($node)) {
while ($delKey = array_pop($delNodes)) {
array_splice($node, $delKey, 1, array());
}
} else {
while ($delKey = array_pop($delNodes)) {
unset($node[$delKey]);
}
}
}
if ($node instanceof PHPParser_NodeAbstract) {
foreach ($this->visitors as $visitor) {
$visitor->leaveNode($node);
if (!empty($mrgNodes)) {
if (is_array($node)) {
while (list($mrgKey, $mrgItems) = array_pop($mrgNodes)) {
array_splice($node, $mrgKey, 1, $mrgItems);
}
} else {
throw new Exception('Nodes can only be merged if the parent is an array');
}
}
}