From 0607450f78fb46d6b8e06cf2eee2c052ec5c24e8 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Sat, 21 Jan 2017 15:41:24 +0100 Subject: [PATCH] Add FinderVisitor Allows finding nodes based on a filter callback. --- lib/PhpParser/NodeVisitor/FinderVisitor.php | 43 +++++++++++++++ .../NodeVisitor/FinderVisitorTest.php | 52 +++++++++++++++++++ 2 files changed, 95 insertions(+) create mode 100644 lib/PhpParser/NodeVisitor/FinderVisitor.php create mode 100644 test/PhpParser/NodeVisitor/FinderVisitorTest.php diff --git a/lib/PhpParser/NodeVisitor/FinderVisitor.php b/lib/PhpParser/NodeVisitor/FinderVisitor.php new file mode 100644 index 00000000..be0dba6a --- /dev/null +++ b/lib/PhpParser/NodeVisitor/FinderVisitor.php @@ -0,0 +1,43 @@ +filterCallback = $filterCallback; + } + + /** + * Get found nodes satisfying the filter callback. + * + * Nodes are returned in pre-order. + * + * @return Node[] Found nodes + */ + public function getFoundNodes() { + return $this->foundNodes; + } + + public function beforeTraverse(array $nodes) { + $this->foundNodes = []; + } + + public function enterNode(Node $node) { + $filterCallback = $this->filterCallback; + if ($filterCallback($node)) { + $this->foundNodes[] = $node; + } + } +} \ No newline at end of file diff --git a/test/PhpParser/NodeVisitor/FinderVisitorTest.php b/test/PhpParser/NodeVisitor/FinderVisitorTest.php new file mode 100644 index 00000000..5b091a34 --- /dev/null +++ b/test/PhpParser/NodeVisitor/FinderVisitorTest.php @@ -0,0 +1,52 @@ +addVisitor($visitor); + + $assign = new Expr\Assign(new Expr\Variable('a'), new Expr\BinaryOp\Concat( + new Expr\Variable('b'), new Expr\Variable('c') + )); + $stmts = [new Node\Stmt\Expression($assign)]; + + $traverser->traverse($stmts); + $this->assertSame([ + $assign->var, + $assign->expr->left, + $assign->expr->right, + ], $visitor->getFoundNodes()); + } + + public function testFindAll() { + $traverser = new NodeTraverser(); + $visitor = new FinderVisitor(function(Node $node) { + return true; // All nodes + }); + $traverser->addVisitor($visitor); + + $assign = new Expr\Assign(new Expr\Variable('a'), new Expr\BinaryOp\Concat( + new Expr\Variable('b'), new Expr\Variable('c') + )); + $stmts = [new Node\Stmt\Expression($assign)]; + + $traverser->traverse($stmts); + $this->assertSame([ + $stmts[0], + $assign, + $assign->var, + $assign->expr, + $assign->expr->left, + $assign->expr->right, + ], $visitor->getFoundNodes()); + } +} \ No newline at end of file