NodeConnectingVisitor.php 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  1. <?php declare(strict_types=1);
  2. namespace PhpParser\NodeVisitor;
  3. use PhpParser\Node;
  4. use PhpParser\NodeVisitorAbstract;
  5. /**
  6. * Visitor that connects a child node to its parent node
  7. * as well as its sibling nodes.
  8. *
  9. * On the child node, the parent node can be accessed through
  10. * <code>$node->getAttribute('parent')</code>, the previous
  11. * node can be accessed through <code>$node->getAttribute('previous')</code>,
  12. * and the next node can be accessed through <code>$node->getAttribute('next')</code>.
  13. */
  14. final class NodeConnectingVisitor extends NodeVisitorAbstract
  15. {
  16. /**
  17. * @var Node[]
  18. */
  19. private $stack = [];
  20. /**
  21. * @var ?Node
  22. */
  23. private $previous;
  24. public function beforeTraverse(array $nodes) {
  25. $this->stack = [];
  26. $this->previous = null;
  27. }
  28. public function enterNode(Node $node) {
  29. if (!empty($this->stack)) {
  30. $node->setAttribute('parent', $this->stack[count($this->stack) - 1]);
  31. }
  32. if ($this->previous !== null && $this->previous->getAttribute('parent') === $node->getAttribute('parent')) {
  33. $node->setAttribute('previous', $this->previous);
  34. $this->previous->setAttribute('next', $node);
  35. }
  36. $this->stack[] = $node;
  37. }
  38. public function leaveNode(Node $node) {
  39. $this->previous = $node;
  40. array_pop($this->stack);
  41. }
  42. }