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