From 9697351b3db9378ff67a5889ce799e6c33d147e0 Mon Sep 17 00:00:00 2001 From: Michael Hirschler Date: Sun, 12 May 2024 17:36:38 +0200 Subject: [PATCH] [PropertyInfo] Adds static cache to `PhpStanExtractor` --- .../Component/PropertyInfo/Extractor/PhpStanExtractor.php | 6 +++++- .../Component/PropertyInfo/PhpStan/NameScopeFactory.php | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/PropertyInfo/Extractor/PhpStanExtractor.php b/src/Symfony/Component/PropertyInfo/Extractor/PhpStanExtractor.php index 016f40677fd4c..003c452d4d340 100644 --- a/src/Symfony/Component/PropertyInfo/Extractor/PhpStanExtractor.php +++ b/src/Symfony/Component/PropertyInfo/Extractor/PhpStanExtractor.php @@ -21,6 +21,7 @@ use PHPStan\PhpDocParser\Parser\PhpDocParser; use PHPStan\PhpDocParser\Parser\TokenIterator; use PHPStan\PhpDocParser\Parser\TypeParser; +use Symfony\Component\PropertyInfo\PhpStan\NameScope; use Symfony\Component\PropertyInfo\PhpStan\NameScopeFactory; use Symfony\Component\PropertyInfo\PropertyTypeExtractorInterface; use Symfony\Component\PropertyInfo\Type as LegacyType; @@ -55,6 +56,9 @@ final class PhpStanExtractor implements PropertyTypeExtractorInterface, Construc private array $accessorPrefixes; private array $arrayMutatorPrefixes; + /** @var array */ + private array $contexts = []; + /** * @param list|null $mutatorPrefixes * @param list|null $accessorPrefixes @@ -86,7 +90,6 @@ public function getTypes(string $class, string $property, array $context = []): { /** @var PhpDocNode|null $docNode */ [$docNode, $source, $prefix, $declaringClass] = $this->getDocBlock($class, $property); - $nameScope = $this->nameScopeFactory->create($class, $declaringClass); if (null === $docNode) { return null; } @@ -120,6 +123,7 @@ public function getTypes(string $class, string $property, array $context = []): continue; } + $nameScope ??= $this->contexts[$class.'/'.$declaringClass] ??= $this->nameScopeFactory->create($class, $declaringClass); foreach ($this->phpStanTypeHelper->getTypes($tagDocNode->value, $nameScope) as $type) { switch ($type->getClassName()) { case 'self': diff --git a/src/Symfony/Component/PropertyInfo/PhpStan/NameScopeFactory.php b/src/Symfony/Component/PropertyInfo/PhpStan/NameScopeFactory.php index 162a72a9e8405..de9a6a69555e7 100644 --- a/src/Symfony/Component/PropertyInfo/PhpStan/NameScopeFactory.php +++ b/src/Symfony/Component/PropertyInfo/PhpStan/NameScopeFactory.php @@ -11,6 +11,7 @@ namespace Symfony\Component\PropertyInfo\PhpStan; +use phpDocumentor\Reflection\Types\Context; use phpDocumentor\Reflection\Types\ContextFactory; /** @@ -20,6 +21,9 @@ */ final class NameScopeFactory { + /** @var array */ + private array $contexts = []; + public function create(string $calledClassName, ?string $declaringClassName = null): NameScope { $declaringClassName ??= $calledClassName; @@ -60,7 +64,7 @@ private function extractFromFullClassName(\ReflectionClass $reflection): array } $factory = new ContextFactory(); - $context = $factory->createForNamespace($namespace, $contents); + $context = $this->contexts[$namespace.$fileName] ??= $factory->createForNamespace($namespace, $contents); return [$namespace, $context->getNamespaceAliases()]; }