ParentConnectingVisitor.php 1.3 KB

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