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