Chris@13: addVisitor($visitor); Chris@13: $traverser->traverse($nodes); Chris@13: Chris@13: return $visitor->getFoundNodes(); Chris@13: } Chris@13: Chris@13: /** Chris@13: * Find all nodes that are instances of a certain class. Chris@13: * Chris@13: * @param Node|Node[] $nodes Single node or array of nodes to search in Chris@13: * @param string $class Class name Chris@13: * Chris@13: * @return Node[] Found nodes (all instances of $class) Chris@13: */ Chris@13: public function findInstanceOf($nodes, string $class) : array { Chris@13: return $this->find($nodes, function ($node) use ($class) { Chris@13: return $node instanceof $class; Chris@13: }); Chris@13: } Chris@13: Chris@13: /** Chris@13: * Find first node satisfying a filter callback. Chris@13: * Chris@13: * @param Node|Node[] $nodes Single node or array of nodes to search in Chris@13: * @param callable $filter Filter callback: function(Node $node) : bool Chris@13: * Chris@13: * @return null|Node Found node (or null if none found) Chris@13: */ Chris@13: public function findFirst($nodes, callable $filter) { Chris@13: if (!is_array($nodes)) { Chris@13: $nodes = [$nodes]; Chris@13: } Chris@13: Chris@13: $visitor = new FirstFindingVisitor($filter); Chris@13: Chris@13: $traverser = new NodeTraverser; Chris@13: $traverser->addVisitor($visitor); Chris@13: $traverser->traverse($nodes); Chris@13: Chris@13: return $visitor->getFoundNode(); Chris@13: } Chris@13: Chris@13: /** Chris@13: * Find first node that is an instance of a certain class. Chris@13: * Chris@13: * @param Node|Node[] $nodes Single node or array of nodes to search in Chris@13: * @param string $class Class name Chris@13: * Chris@13: * @return null|Node Found node, which is an instance of $class (or null if none found) Chris@13: */ Chris@13: public function findFirstInstanceOf($nodes, string $class) { Chris@13: return $this->findFirst($nodes, function ($node) use ($class) { Chris@13: return $node instanceof $class; Chris@13: }); Chris@13: } Chris@13: }