NodeConnectingVisitor.php 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  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. * @var Node[]
  17. */
  18. private array $stack = [];
  19. /**
  20. * @var ?Node
  21. */
  22. private $previous;
  23. public function beforeTraverse(array $nodes) {
  24. $this->stack = [];
  25. $this->previous = null;
  26. }
  27. public function enterNode(Node $node) {
  28. if (!empty($this->stack)) {
  29. $node->setAttribute('parent', $this->stack[count($this->stack) - 1]);
  30. }
  31. if ($this->previous !== null && $this->previous->getAttribute('parent') === $node->getAttribute('parent')) {
  32. $node->setAttribute('previous', $this->previous);
  33. $this->previous->setAttribute('next', $node);
  34. }
  35. $this->stack[] = $node;
  36. }
  37. public function leaveNode(Node $node) {
  38. $this->previous = $node;
  39. array_pop($this->stack);
  40. }
  41. }