From 2afdbec4bc4aee7194355c0238026a1a649eefb0 Mon Sep 17 00:00:00 2001 From: Tomas Votruba Date: Mon, 12 Oct 2026 11:10:43 +0200 Subject: [PATCH] add generic template to node-returning methods with same param and return union Narrows the return type to the passed node type via @template, or an explicit conditional return type for factory methods that build a new node. Satisfies the new PreferGenericTemplateOnSameUnionTypeRule from symplify/phpstan-rules. --- .../AssertFalseStrposToContainsRector.php | 5 +++++ .../MethodCall/UseSpecificWillMethodRector.php | 5 +++++ .../DelegateExceptionArgumentsRector.php | 5 +++++ ...EqualsParameterToSpecificMethodsTypeRector.php | 15 +++++++++++++++ .../MethodCall/ExplicitPhpErrorApiRector.php | 5 +++++ src/NodeFactory/AssertCallFactory.php | 5 +++++ 6 files changed, 40 insertions(+) diff --git a/rules/CodeQuality/Rector/MethodCall/AssertFalseStrposToContainsRector.php b/rules/CodeQuality/Rector/MethodCall/AssertFalseStrposToContainsRector.php index c179db76..f9367e27 100644 --- a/rules/CodeQuality/Rector/MethodCall/AssertFalseStrposToContainsRector.php +++ b/rules/CodeQuality/Rector/MethodCall/AssertFalseStrposToContainsRector.php @@ -86,6 +86,11 @@ public function refactor(Node $node): ?Node return $this->changeArgumentsOrder($node); } + /** + * @template TCall of MethodCall|StaticCall + * @param TCall $node + * @return TCall|null + */ private function changeArgumentsOrder(MethodCall|StaticCall $node): MethodCall|StaticCall|null { $oldArguments = $node->getArgs(); diff --git a/rules/CodeQuality/Rector/MethodCall/UseSpecificWillMethodRector.php b/rules/CodeQuality/Rector/MethodCall/UseSpecificWillMethodRector.php index 440a392d..25d4f498 100644 --- a/rules/CodeQuality/Rector/MethodCall/UseSpecificWillMethodRector.php +++ b/rules/CodeQuality/Rector/MethodCall/UseSpecificWillMethodRector.php @@ -127,6 +127,11 @@ public function refactor(Node $node): ?Node return null; } + /** + * @template TCall of StaticCall|MethodCall + * @param TCall $call + * @return TCall|null + */ private function refactorNew(New_ $new, StaticCall|MethodCall $call): null|MethodCall|StaticCall { if (! $this->isName($new->class, 'PHPUnit\Framework\MockObject\Stub\ReturnValueMap')) { diff --git a/rules/PHPUnit60/Rector/MethodCall/DelegateExceptionArgumentsRector.php b/rules/PHPUnit60/Rector/MethodCall/DelegateExceptionArgumentsRector.php index ef12cccd..fc1faee9 100644 --- a/rules/PHPUnit60/Rector/MethodCall/DelegateExceptionArgumentsRector.php +++ b/rules/PHPUnit60/Rector/MethodCall/DelegateExceptionArgumentsRector.php @@ -146,6 +146,11 @@ public function refactor(Node $node): ?Node return null; } + /** + * @template TCall of StaticCall|MethodCall + * @param TCall $call + * @return ($call is MethodCall ? MethodCall : StaticCall) + */ private function createFirstArgExtraMethodCall(StaticCall|MethodCall $call): MethodCall|StaticCall { /** @var Identifier $identifierNode */ diff --git a/rules/PHPUnit80/Rector/MethodCall/AssertEqualsParameterToSpecificMethodsTypeRector.php b/rules/PHPUnit80/Rector/MethodCall/AssertEqualsParameterToSpecificMethodsTypeRector.php index 92b905e5..409f807d 100644 --- a/rules/PHPUnit80/Rector/MethodCall/AssertEqualsParameterToSpecificMethodsTypeRector.php +++ b/rules/PHPUnit80/Rector/MethodCall/AssertEqualsParameterToSpecificMethodsTypeRector.php @@ -125,6 +125,11 @@ public function refactor(Node $node): ?Node return $this->processAssertEqualsWithDelta($node); } + /** + * @template TCall of MethodCall|StaticCall + * @param TCall $call + * @return ($call is MethodCall ? MethodCall : StaticCall)|null + */ private function processAssertEqualsIgnoringCase(MethodCall|StaticCall $call): StaticCall|MethodCall|null { $args = $call->getArgs(); @@ -149,6 +154,11 @@ private function processAssertEqualsIgnoringCase(MethodCall|StaticCall $call): S return $newMethodCall; } + /** + * @template TCall of MethodCall|StaticCall + * @param TCall $call + * @return ($call is MethodCall ? MethodCall : StaticCall)|null + */ private function processAssertEqualsCanonicalizing(MethodCall|StaticCall $call): MethodCall|StaticCall|null { $args = $call->getArgs(); @@ -176,6 +186,11 @@ private function processAssertEqualsCanonicalizing(MethodCall|StaticCall $call): return $newMethodCall; } + /** + * @template TCall of MethodCall|StaticCall + * @param TCall $call + * @return ($call is MethodCall ? MethodCall : StaticCall)|null + */ private function processAssertEqualsWithDelta(MethodCall|StaticCall $call): MethodCall|StaticCall|null { $args = $call->getArgs(); diff --git a/rules/PHPUnit90/Rector/MethodCall/ExplicitPhpErrorApiRector.php b/rules/PHPUnit90/Rector/MethodCall/ExplicitPhpErrorApiRector.php index 4a6cf426..95937f1c 100644 --- a/rules/PHPUnit90/Rector/MethodCall/ExplicitPhpErrorApiRector.php +++ b/rules/PHPUnit90/Rector/MethodCall/ExplicitPhpErrorApiRector.php @@ -112,6 +112,11 @@ public function refactor(Node $node): null|MethodCall|StaticCall return null; } + /** + * @template TCall of MethodCall|StaticCall + * @param TCall $node + * @return ($node is MethodCall ? MethodCall : StaticCall)|null + */ private function replaceExceptionWith( MethodCall|StaticCall $node, string $exceptionClass, diff --git a/src/NodeFactory/AssertCallFactory.php b/src/NodeFactory/AssertCallFactory.php index 3dd68c0f..d587bb8b 100644 --- a/src/NodeFactory/AssertCallFactory.php +++ b/src/NodeFactory/AssertCallFactory.php @@ -9,6 +9,11 @@ final class AssertCallFactory { + /** + * @template TCall of StaticCall|MethodCall + * @param TCall $node + * @return ($node is MethodCall ? MethodCall : StaticCall) + */ public function createCallWithName(StaticCall|MethodCall $node, string $name): StaticCall|MethodCall { if ($node instanceof MethodCall) {