1: <?php declare(strict_types=1);
2:
3: namespace PhpParser;
4:
5: use PhpParser\NodeVisitor\FindingVisitor;
6: use PhpParser\NodeVisitor\FirstFindingVisitor;
7:
8: class NodeFinder
9: {
10: /**
11: * Find all nodes satisfying a filter callback.
12: *
13: * @param Node|Node[] $nodes Single node or array of nodes to search in
14: * @param callable $filter Filter callback: function(Node $node) : bool
15: *
16: * @return Node[] Found nodes satisfying the filter callback
17: */
18: public function find($nodes, callable $filter) : array {
19: if (!is_array($nodes)) {
20: $nodes = [$nodes];
21: }
22:
23: $visitor = new FindingVisitor($filter);
24:
25: $traverser = new NodeTraverser;
26: $traverser->addVisitor($visitor);
27: $traverser->traverse($nodes);
28:
29: return $visitor->getFoundNodes();
30: }
31:
32: /**
33: * Find all nodes that are instances of a certain class.
34: *
35: * @param Node|Node[] $nodes Single node or array of nodes to search in
36: * @param string $class Class name
37: *
38: * @return Node[] Found nodes (all instances of $class)
39: */
40: public function findInstanceOf($nodes, string $class) : array {
41: return $this->find($nodes, function ($node) use ($class) {
42: return $node instanceof $class;
43: });
44: }
45:
46: /**
47: * Find first node satisfying a filter callback.
48: *
49: * @param Node|Node[] $nodes Single node or array of nodes to search in
50: * @param callable $filter Filter callback: function(Node $node) : bool
51: *
52: * @return null|Node Found node (or null if none found)
53: */
54: public function findFirst($nodes, callable $filter) {
55: if (!is_array($nodes)) {
56: $nodes = [$nodes];
57: }
58:
59: $visitor = new FirstFindingVisitor($filter);
60:
61: $traverser = new NodeTraverser;
62: $traverser->addVisitor($visitor);
63: $traverser->traverse($nodes);
64:
65: return $visitor->getFoundNode();
66: }
67:
68: /**
69: * Find first node that is an instance of a certain class.
70: *
71: * @param Node|Node[] $nodes Single node or array of nodes to search in
72: * @param string $class Class name
73: *
74: * @return null|Node Found node, which is an instance of $class (or null if none found)
75: */
76: public function findFirstInstanceOf($nodes, string $class) {
77: return $this->findFirst($nodes, function ($node) use ($class) {
78: return $node instanceof $class;
79: });
80: }
81: }
82: