From 1f6b145a677f663860f96ab99698939cfda1a0fd Mon Sep 17 00:00:00 2001 From: Tomas Votruba Date: Thu, 15 Oct 2026 13:22:42 +0200 Subject: [PATCH 1/2] [perf] Speed up type declaration rules by resolving reflection only when needed --- .../ReturnTypeFromStrictFluentReturnRector.php | 7 +++++-- .../ReturnTypeFromStrictTypedPropertyRector.php | 8 ++++---- .../Class_/ChildDoctrineRepositoryClassTypeRector.php | 5 +++++ .../Class_/PropertyTypeFromStrictSetterGetterRector.php | 8 ++++---- 4 files changed, 18 insertions(+), 10 deletions(-) diff --git a/rules/TypeDeclaration/Rector/ClassMethod/ReturnTypeFromStrictFluentReturnRector.php b/rules/TypeDeclaration/Rector/ClassMethod/ReturnTypeFromStrictFluentReturnRector.php index 47ddb34d8bb..9f034236977 100644 --- a/rules/TypeDeclaration/Rector/ClassMethod/ReturnTypeFromStrictFluentReturnRector.php +++ b/rules/TypeDeclaration/Rector/ClassMethod/ReturnTypeFromStrictFluentReturnRector.php @@ -90,13 +90,16 @@ public function refactor(Node $node): ?Node return null; } + $returnType = $this->returnTypeInferer->inferFunctionLike($node); + if (! $returnType instanceof StaticType && ! $returnType instanceof ObjectType) { + return null; + } + $classReflection = $this->reflectionResolver->resolveClassReflection($node); if (! $classReflection instanceof ClassReflection) { return null; } - $returnType = $this->returnTypeInferer->inferFunctionLike($node); - if ($returnType instanceof StaticType && $returnType->getStaticObjectType()->getClassName() === $classReflection->getName()) { return $this->processAddReturnSelfOrStatic($node, $classReflection); } diff --git a/rules/TypeDeclaration/Rector/ClassMethod/ReturnTypeFromStrictTypedPropertyRector.php b/rules/TypeDeclaration/Rector/ClassMethod/ReturnTypeFromStrictTypedPropertyRector.php index 4592e5b04ff..d9710243f44 100644 --- a/rules/TypeDeclaration/Rector/ClassMethod/ReturnTypeFromStrictTypedPropertyRector.php +++ b/rules/TypeDeclaration/Rector/ClassMethod/ReturnTypeFromStrictTypedPropertyRector.php @@ -128,6 +128,10 @@ private function resolveReturnPropertyType(ClassMethod $classMethod): array { $returns = $this->betterNodeFinder->findReturnsScoped($classMethod); + if (! $this->returnAnalyzer->hasOnlyReturnWithExpr($classMethod, $returns)) { + return []; + } + $propertyTypes = []; foreach ($returns as $return) { @@ -154,10 +158,6 @@ private function resolveReturnPropertyType(ClassMethod $classMethod): array $propertyTypes[] = $this->nodeTypeResolver->getNativeType($return->expr); } - if (! $this->returnAnalyzer->hasOnlyReturnWithExpr($classMethod, $returns)) { - return []; - } - return $propertyTypes; } } diff --git a/rules/TypeDeclaration/Rector/Class_/ChildDoctrineRepositoryClassTypeRector.php b/rules/TypeDeclaration/Rector/Class_/ChildDoctrineRepositoryClassTypeRector.php index 0fa67e794c6..965b788da4a 100644 --- a/rules/TypeDeclaration/Rector/Class_/ChildDoctrineRepositoryClassTypeRector.php +++ b/rules/TypeDeclaration/Rector/Class_/ChildDoctrineRepositoryClassTypeRector.php @@ -94,6 +94,11 @@ public function getNodeTypes(): array */ public function refactor(Node $node): ?Node { + // entity type is resolved from the @extends docblock, bail early when absent + if ($node->getDocComment() === null) { + return null; + } + if (! $this->isObjectType($node, new ObjectType('Doctrine\ORM\EntityRepository'))) { return null; } diff --git a/rules/TypeDeclaration/Rector/Class_/PropertyTypeFromStrictSetterGetterRector.php b/rules/TypeDeclaration/Rector/Class_/PropertyTypeFromStrictSetterGetterRector.php index cdca5a86165..6713642b2e1 100644 --- a/rules/TypeDeclaration/Rector/Class_/PropertyTypeFromStrictSetterGetterRector.php +++ b/rules/TypeDeclaration/Rector/Class_/PropertyTypeFromStrictSetterGetterRector.php @@ -119,13 +119,13 @@ public function refactor(Node $node): ?Node continue; } - // constructor assignment can set a different type than the setter/getter → skip - if ($this->isAssignedInConstructor($node, $property)) { + $getterSetterPropertyType = $this->matchGetterSetterIdenticalType($property, $node); + if (! $getterSetterPropertyType instanceof Type) { continue; } - $getterSetterPropertyType = $this->matchGetterSetterIdenticalType($property, $node); - if (! $getterSetterPropertyType instanceof Type) { + // constructor assignment can set a different type than the setter/getter → skip + if ($this->isAssignedInConstructor($node, $property)) { continue; } From bd6e2512c1969415090e1ffde9ecbfbbc852e346 Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Thu, 15 Oct 2026 11:23:42 +0000 Subject: [PATCH 2/2] [ci-review] Rector Rectify --- .../Rector/Class_/ChildDoctrineRepositoryClassTypeRector.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/rules/TypeDeclaration/Rector/Class_/ChildDoctrineRepositoryClassTypeRector.php b/rules/TypeDeclaration/Rector/Class_/ChildDoctrineRepositoryClassTypeRector.php index 965b788da4a..a34f09a8f17 100644 --- a/rules/TypeDeclaration/Rector/Class_/ChildDoctrineRepositoryClassTypeRector.php +++ b/rules/TypeDeclaration/Rector/Class_/ChildDoctrineRepositoryClassTypeRector.php @@ -4,6 +4,7 @@ namespace Rector\TypeDeclaration\Rector\Class_; +use PhpParser\Comment\Doc; use PhpParser\Node; use PhpParser\Node\Expr\MethodCall; use PhpParser\Node\Identifier; @@ -95,7 +96,7 @@ public function getNodeTypes(): array public function refactor(Node $node): ?Node { // entity type is resolved from the @extends docblock, bail early when absent - if ($node->getDocComment() === null) { + if (!$node->getDocComment() instanceof Doc) { return null; }