From 47d353c9c336afb9484b1ee368235c09562d10fb Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Sat, 26 Apr 2025 19:17:59 +0200 Subject: [PATCH] Use more efficient AttributeParentConnectingVisitor --- .../AttributeParentConnectingVisitor.php | 63 +++++++++++++++++++ src/StaticAnalysis/ParsingFileAnalyser.php | 3 +- 2 files changed, 64 insertions(+), 2 deletions(-) create mode 100644 src/StaticAnalysis/AttributeParentConnectingVisitor.php diff --git a/src/StaticAnalysis/AttributeParentConnectingVisitor.php b/src/StaticAnalysis/AttributeParentConnectingVisitor.php new file mode 100644 index 000000000..4436e9a86 --- /dev/null +++ b/src/StaticAnalysis/AttributeParentConnectingVisitor.php @@ -0,0 +1,63 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\CodeCoverage\StaticAnalysis; + +use function array_pop; +use function count; +use PhpParser\Node; +use PhpParser\NodeVisitor; + +/** + * Visitor that connects a child node to its parent node optimzed for Attribute nodes. + * + * On the child node, the parent node can be accessed through + * $node->getAttribute('parent'). + */ +final class AttributeParentConnectingVisitor implements NodeVisitor +{ + /** + * @var Node[] + */ + private array $stack = []; + + public function beforeTraverse(array $nodes): null + { + $this->stack = []; + + return null; + } + + public function enterNode(Node $node): null + { + if ( + $this->stack !== [] && + ($node instanceof Node\Attribute || $node instanceof Node\AttributeGroup) + ) { + $node->setAttribute('parent', $this->stack[count($this->stack) - 1]); + } + + $this->stack[] = $node; + + return null; + } + + public function leaveNode(Node $node): null + { + array_pop($this->stack); + + return null; + } + + public function afterTraverse(array $nodes): null + { + return null; + } +} diff --git a/src/StaticAnalysis/ParsingFileAnalyser.php b/src/StaticAnalysis/ParsingFileAnalyser.php index 79f51e987..dfca1dd0c 100644 --- a/src/StaticAnalysis/ParsingFileAnalyser.php +++ b/src/StaticAnalysis/ParsingFileAnalyser.php @@ -26,7 +26,6 @@ use PhpParser\Error; use PhpParser\NodeTraverser; use PhpParser\NodeVisitor\NameResolver; -use PhpParser\NodeVisitor\ParentConnectingVisitor; use PhpParser\ParserFactory; use SebastianBergmann\CodeCoverage\ParserException; use SebastianBergmann\LinesOfCode\LineCountingVisitor; @@ -180,7 +179,7 @@ private function analyse(string $filename): void $executableLinesFindingVisitor = new ExecutableLinesFindingVisitor($source); $traverser->addVisitor(new NameResolver); - $traverser->addVisitor(new ParentConnectingVisitor); + $traverser->addVisitor(new AttributeParentConnectingVisitor); $traverser->addVisitor($codeUnitFindingVisitor); $traverser->addVisitor($lineCountingVisitor); $traverser->addVisitor($ignoredLinesFindingVisitor);