diff --git a/lib/PhpParser/NameContext.php b/lib/PhpParser/NameContext.php index 2265ecce82..867fbb6cc8 100644 --- a/lib/PhpParser/NameContext.php +++ b/lib/PhpParser/NameContext.php @@ -19,13 +19,17 @@ class NameContext { /** @var ErrorHandler Error handler */ protected ErrorHandler $errorHandler; + protected bool $noCyclicRefs; + /** * Create a name context. * * @param ErrorHandler $errorHandler Error handling used to report errors + * @param array{noCyclicRefs?:bool} $options */ - public function __construct(ErrorHandler $errorHandler) { + public function __construct(ErrorHandler $errorHandler, array $options = []) { $this->errorHandler = $errorHandler; + $this->noCyclicRefs = $options['noCyclicRefs'] ?? false; } /** @@ -107,12 +111,12 @@ public function getResolvedName(Name $name, int $type): ?Name { $name->getAttributes() )); } - return $name; + return $this->noCyclicRefs ? clone $name : $name; } // fully qualified names are already resolved if ($name->isFullyQualified()) { - return $name; + return $this->noCyclicRefs ? clone $name : $name; } // Try to resolve aliases diff --git a/lib/PhpParser/NodeVisitor/NameResolver.php b/lib/PhpParser/NodeVisitor/NameResolver.php index 99449c496f..aceb031b0e 100644 --- a/lib/PhpParser/NodeVisitor/NameResolver.php +++ b/lib/PhpParser/NodeVisitor/NameResolver.php @@ -32,10 +32,13 @@ class NameResolver extends NodeVisitorAbstract { * namespacedName attribute, as usual.) * * @param ErrorHandler|null $errorHandler Error handler - * @param array{preserveOriginalNames?: bool, replaceNodes?: bool} $options Options + * @param array{preserveOriginalNames?: bool, replaceNodes?: bool, noCyclicRefs?: bool} $options Options */ public function __construct(?ErrorHandler $errorHandler = null, array $options = []) { - $this->nameContext = new NameContext($errorHandler ?? new ErrorHandler\Throwing()); + $this->nameContext = new NameContext( + $errorHandler ?? new ErrorHandler\Throwing(), + ['noCyclicRefs' => $options['noCyclicRefs'] ?? false], + ); $this->preserveOriginalNames = $options['preserveOriginalNames'] ?? false; $this->replaceNodes = $options['replaceNodes'] ?? true; }