1<?php declare(strict_types=1);
2
3namespace PhpParser\NodeVisitor;
4
5use PhpParser\Node;
6use PhpParser\NodeVisitor;
7use PhpParser\NodeVisitorAbstract;
8
9/**
10 * This visitor can be used to find the first node satisfying some criterion determined by
11 * a filter callback.
12 */
13class FirstFindingVisitor extends NodeVisitorAbstract {
14    /** @var callable Filter callback */
15    protected $filterCallback;
16    /** @var null|Node Found node */
17    protected ?Node $foundNode;
18
19    public function __construct(callable $filterCallback) {
20        $this->filterCallback = $filterCallback;
21    }
22
23    /**
24     * Get found node satisfying the filter callback.
25     *
26     * Returns null if no node satisfies the filter callback.
27     *
28     * @return null|Node Found node (or null if not found)
29     */
30    public function getFoundNode(): ?Node {
31        return $this->foundNode;
32    }
33
34    public function beforeTraverse(array $nodes): ?array {
35        $this->foundNode = null;
36
37        return null;
38    }
39
40    public function enterNode(Node $node) {
41        $filterCallback = $this->filterCallback;
42        if ($filterCallback($node)) {
43            $this->foundNode = $node;
44            return NodeVisitor::STOP_TRAVERSAL;
45        }
46
47        return null;
48    }
49}
50