| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273 |
- <?php declare(strict_types=1);
- namespace PhpParser\NodeVisitor;
- use PhpParser\Node;
- use PhpParser\NodeVisitorAbstract;
- /**
- * Visitor that connects a child node to its parent node
- * as well as its sibling nodes.
- *
- * With <code>$weakReferences=false</code> on the child node, the parent node can be accessed through
- * <code>$node->getAttribute('parent')</code>, the previous
- * node can be accessed through <code>$node->getAttribute('previous')</code>,
- * and the next node can be accessed through <code>$node->getAttribute('next')</code>.
- *
- * With <code>$weakReferences=true</code> attribute names are prefixed by "weak_", e.g. "weak_parent".
- */
- final class NodeConnectingVisitor extends NodeVisitorAbstract {
- /**
- * @var Node[]
- */
- private array $stack = [];
- /**
- * @var ?Node
- */
- private $previous;
- private bool $weakReferences;
- public function __construct(bool $weakReferences = false) {
- $this->weakReferences = $weakReferences;
- }
- public function beforeTraverse(array $nodes) {
- $this->stack = [];
- $this->previous = null;
- }
- public function enterNode(Node $node) {
- if (!empty($this->stack)) {
- $parent = $this->stack[count($this->stack) - 1];
- if ($this->weakReferences) {
- $node->setAttribute('weak_parent', \WeakReference::create($parent));
- } else {
- $node->setAttribute('parent', $parent);
- }
- }
- if ($this->previous !== null) {
- if (
- $this->weakReferences
- ) {
- if ($this->previous->getAttribute('weak_parent') === $node->getAttribute('weak_parent')) {
- $node->setAttribute('weak_previous', \WeakReference::create($this->previous));
- $this->previous->setAttribute('weak_next', \WeakReference::create($node));
- }
- } elseif ($this->previous->getAttribute('parent') === $node->getAttribute('parent')) {
- $node->setAttribute('previous', $this->previous);
- $this->previous->setAttribute('next', $node);
- }
- }
- $this->stack[] = $node;
- }
- public function leaveNode(Node $node) {
- $this->previous = $node;
- array_pop($this->stack);
- }
- }
|