From 34cebe0184641402b3e9e318166133094501a14b Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Tue, 14 Jul 2026 13:18:54 +0700 Subject: [PATCH 1/4] skip return $this removal on trait on RemoveReturnTagIncompatibleWithNativeTypeRector --- .../Fixture/skip_this_return_in_trait.php.inc | 16 ++++++++++++++++ .../Source/RouteInterface.php | 9 +++++++++ ...ReturnTagIncompatibleWithNativeTypeRector.php | 16 ++++++++++++---- 3 files changed, 37 insertions(+), 4 deletions(-) create mode 100644 rules-tests/DeadCode/Rector/ClassMethod/RemoveReturnTagIncompatibleWithNativeTypeRector/Fixture/skip_this_return_in_trait.php.inc create mode 100644 rules-tests/DeadCode/Rector/ClassMethod/RemoveReturnTagIncompatibleWithNativeTypeRector/Source/RouteInterface.php diff --git a/rules-tests/DeadCode/Rector/ClassMethod/RemoveReturnTagIncompatibleWithNativeTypeRector/Fixture/skip_this_return_in_trait.php.inc b/rules-tests/DeadCode/Rector/ClassMethod/RemoveReturnTagIncompatibleWithNativeTypeRector/Fixture/skip_this_return_in_trait.php.inc new file mode 100644 index 00000000000..a25261cddc3 --- /dev/null +++ b/rules-tests/DeadCode/Rector/ClassMethod/RemoveReturnTagIncompatibleWithNativeTypeRector/Fixture/skip_this_return_in_trait.php.inc @@ -0,0 +1,16 @@ +isClassTypeAlias($node, $returnTagValueNode)) { + $scope = ScopeFetcher::fetch($node); + if ($this->isClassTypeAlias($scope, $node, $returnTagValueNode)) { + return null; + } + + $classReflection = $scope->getClassReflection(); + if ($scope->isInClass() && $classReflection->isTrait() + && $returnTagValueNode->type instanceof ThisTypeNode) { return null; } @@ -134,10 +143,9 @@ public function refactor(Node $node): ?Node return $node; } - private function isClassTypeAlias(Node $node, ReturnTagValueNode $returnTagValueNode): bool + private function isClassTypeAlias(Scope $scope, Node $node, ReturnTagValueNode $returnTagValueNode): bool { - $scope = $node->getAttribute(AttributeKey::SCOPE); - if (! $scope instanceof Scope || ! $scope->isInClass()) { + if (! $scope->isInClass()) { return false; } From f3ba681cc88e62c7323b79c7456614a5f586e123 Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Tue, 14 Jul 2026 13:19:34 +0700 Subject: [PATCH 2/4] skip return $this removal on trait on RemoveReturnTagIncompatibleWithNativeTypeRector --- .../RemoveReturnTagIncompatibleWithNativeTypeRector.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/rules/DeadCode/Rector/ClassMethod/RemoveReturnTagIncompatibleWithNativeTypeRector.php b/rules/DeadCode/Rector/ClassMethod/RemoveReturnTagIncompatibleWithNativeTypeRector.php index dcc527569e9..c2ed1788831 100644 --- a/rules/DeadCode/Rector/ClassMethod/RemoveReturnTagIncompatibleWithNativeTypeRector.php +++ b/rules/DeadCode/Rector/ClassMethod/RemoveReturnTagIncompatibleWithNativeTypeRector.php @@ -116,13 +116,15 @@ public function refactor(Node $node): ?Node return null; } + $nativeReturnType = $this->staticTypeMapper->mapPhpParserNodePHPStanType($node->returnType); $classReflection = $scope->getClassReflection(); if ($scope->isInClass() && $classReflection->isTrait() - && $returnTagValueNode->type instanceof ThisTypeNode) { + && $returnTagValueNode->type instanceof ThisTypeNode + && $nativeReturnType instanceof ObjectType + ) { return null; } - $nativeReturnType = $this->staticTypeMapper->mapPhpParserNodePHPStanType($node->returnType); if ($this->isReturnTemplate($phpDocInfo, $returnTagValueNode)) { return null; } From 062b831c0dd08489a15dd58354755d86e3f97935 Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Tue, 14 Jul 2026 13:21:26 +0700 Subject: [PATCH 3/4] fix cs --- .../RemoveReturnTagIncompatibleWithNativeTypeRector.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rules/DeadCode/Rector/ClassMethod/RemoveReturnTagIncompatibleWithNativeTypeRector.php b/rules/DeadCode/Rector/ClassMethod/RemoveReturnTagIncompatibleWithNativeTypeRector.php index c2ed1788831..66a4d1b56d4 100644 --- a/rules/DeadCode/Rector/ClassMethod/RemoveReturnTagIncompatibleWithNativeTypeRector.php +++ b/rules/DeadCode/Rector/ClassMethod/RemoveReturnTagIncompatibleWithNativeTypeRector.php @@ -13,10 +13,10 @@ use PHPStan\PhpDocParser\Ast\Type\GenericTypeNode; use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode; use PHPStan\PhpDocParser\Ast\Type\ThisTypeNode; +use PHPStan\Type\ObjectType; use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo; use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory; use Rector\Comments\NodeDocBlock\DocBlockUpdater; -use Rector\NodeTypeResolver\Node\AttributeKey; use Rector\PHPStan\ScopeFetcher; use Rector\Rector\AbstractRector; use Rector\StaticTypeMapper\StaticTypeMapper; @@ -112,7 +112,7 @@ public function refactor(Node $node): ?Node } $scope = ScopeFetcher::fetch($node); - if ($this->isClassTypeAlias($scope, $node, $returnTagValueNode)) { + if ($this->isClassTypeAlias($scope, $returnTagValueNode)) { return null; } @@ -145,7 +145,7 @@ public function refactor(Node $node): ?Node return $node; } - private function isClassTypeAlias(Scope $scope, Node $node, ReturnTagValueNode $returnTagValueNode): bool + private function isClassTypeAlias(Scope $scope, ReturnTagValueNode $returnTagValueNode): bool { if (! $scope->isInClass()) { return false; From 01876c53490a5686f055aa9eed966c08640a6b8c Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Tue, 14 Jul 2026 13:26:06 +0700 Subject: [PATCH 4/4] fix phpstan --- .../RemoveReturnTagIncompatibleWithNativeTypeRector.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/rules/DeadCode/Rector/ClassMethod/RemoveReturnTagIncompatibleWithNativeTypeRector.php b/rules/DeadCode/Rector/ClassMethod/RemoveReturnTagIncompatibleWithNativeTypeRector.php index 66a4d1b56d4..7032886870d 100644 --- a/rules/DeadCode/Rector/ClassMethod/RemoveReturnTagIncompatibleWithNativeTypeRector.php +++ b/rules/DeadCode/Rector/ClassMethod/RemoveReturnTagIncompatibleWithNativeTypeRector.php @@ -13,6 +13,7 @@ use PHPStan\PhpDocParser\Ast\Type\GenericTypeNode; use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode; use PHPStan\PhpDocParser\Ast\Type\ThisTypeNode; +use PHPStan\Reflection\ClassReflection; use PHPStan\Type\ObjectType; use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo; use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory; @@ -118,7 +119,7 @@ public function refactor(Node $node): ?Node $nativeReturnType = $this->staticTypeMapper->mapPhpParserNodePHPStanType($node->returnType); $classReflection = $scope->getClassReflection(); - if ($scope->isInClass() && $classReflection->isTrait() + if ($classReflection instanceof ClassReflection && $classReflection->isTrait() && $returnTagValueNode->type instanceof ThisTypeNode && $nativeReturnType instanceof ObjectType ) {