diff --git a/rules-tests/TypeDeclaration/Rector/ClassMethod/ReturnTypeFromMockObjectRector/Fixture/skip_filled_type.php.inc b/rules-tests/TypeDeclaration/Rector/ClassMethod/ReturnTypeFromMockObjectRector/Fixture/skip_filled_type.php.inc index 4618e9b517..dcab3ae935 100644 --- a/rules-tests/TypeDeclaration/Rector/ClassMethod/ReturnTypeFromMockObjectRector/Fixture/skip_filled_type.php.inc +++ b/rules-tests/TypeDeclaration/Rector/ClassMethod/ReturnTypeFromMockObjectRector/Fixture/skip_filled_type.php.inc @@ -9,7 +9,7 @@ use PHPUnit\Framework\TestCase; final class SkipFilledType extends TestCase { - public function createMock(): MockObject + public function test(): MockObject { return $this->createMock('SomeType'); } diff --git a/rules-tests/TypeDeclaration/Rector/ClassMethod/ReturnTypeFromMockObjectRector/Fixture/some_test_with_mock.php.inc b/rules-tests/TypeDeclaration/Rector/ClassMethod/ReturnTypeFromMockObjectRector/Fixture/some_test_with_mock.php.inc index 411c4f0cbe..376e88a118 100644 --- a/rules-tests/TypeDeclaration/Rector/ClassMethod/ReturnTypeFromMockObjectRector/Fixture/some_test_with_mock.php.inc +++ b/rules-tests/TypeDeclaration/Rector/ClassMethod/ReturnTypeFromMockObjectRector/Fixture/some_test_with_mock.php.inc @@ -8,7 +8,7 @@ use PHPUnit\Framework\TestCase; final class SomeTestWithMock extends TestCase { - public function createMock() + public function test() { return $this->createMock('SomeType'); } @@ -26,7 +26,7 @@ use PHPUnit\Framework\TestCase; final class SomeTestWithMock extends TestCase { - public function createMock(): \PHPUnit\Framework\MockObject\MockObject + public function test(): \PHPUnit\Framework\MockObject\MockObject { return $this->createMock('SomeType'); } diff --git a/rules/TypeDeclaration/Rector/ClassMethod/ReturnTypeFromMockObjectRector.php b/rules/TypeDeclaration/Rector/ClassMethod/ReturnTypeFromMockObjectRector.php index a42fe359fd..f5e4d5c886 100644 --- a/rules/TypeDeclaration/Rector/ClassMethod/ReturnTypeFromMockObjectRector.php +++ b/rules/TypeDeclaration/Rector/ClassMethod/ReturnTypeFromMockObjectRector.php @@ -13,11 +13,10 @@ use PHPStan\Type\IntersectionType; use PHPStan\Type\ObjectType; use PHPStan\Type\Type; -use PHPUnit\Framework\TestCase; -use Rector\NodeTypeResolver\Node\AttributeKey; use Rector\PhpParser\Node\BetterNodeFinder; -use Rector\Rector\AbstractRector; +use Rector\Rector\AbstractScopeAwareRector; use Rector\ValueObject\PhpVersionFeature; +use Rector\VendorLocker\NodeVendorLocker\ClassMethodReturnTypeOverrideGuard; use Rector\VersionBonding\Contract\MinPhpVersionInterface; use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample; use Symplify\RuleDocGenerator\ValueObject\RuleDefinition; @@ -25,15 +24,21 @@ /** * @see \Rector\Tests\TypeDeclaration\Rector\ClassMethod\ReturnTypeFromMockObjectRector\ReturnTypeFromMockObjectRectorTest */ -final class ReturnTypeFromMockObjectRector extends AbstractRector implements MinPhpVersionInterface +final class ReturnTypeFromMockObjectRector extends AbstractScopeAwareRector implements MinPhpVersionInterface { + /** + * @var string + */ + private const TESTCASE_CLASS = 'PHPUnit\Framework\TestCase'; + /** * @var string */ private const MOCK_OBJECT_CLASS = 'PHPUnit\Framework\MockObject\MockObject'; public function __construct( - private readonly BetterNodeFinder $betterNodeFinder + private readonly BetterNodeFinder $betterNodeFinder, + private readonly ClassMethodReturnTypeOverrideGuard $classMethodReturnTypeOverrideGuard ) { } @@ -75,14 +80,18 @@ public function getNodeTypes(): array /** * @param ClassMethod $node */ - public function refactor(Node $node): ?Node + public function refactorWithScope(Node $node, Scope $scope): ?Node { // type is already known if ($node->returnType instanceof Node) { return null; } - if (! $this->isInsideTestCaseClass($node)) { + if (! $this->isInsideTestCaseClass($scope)) { + return null; + } + + if ($this->classMethodReturnTypeOverrideGuard->shouldSkipClassMethod($node, $scope)) { return null; } @@ -134,19 +143,14 @@ private function isMockObjectType(Type $returnType): bool return $this->isIntersectionWithMockObjectType($returnType); } - private function isInsideTestCaseClass(ClassMethod $classMethod): bool + private function isInsideTestCaseClass(Scope $scope): bool { - $scope = $classMethod->getAttribute(AttributeKey::SCOPE); - if (! $scope instanceof Scope) { - return false; - } - $classReflection = $scope->getClassReflection(); if (! $classReflection instanceof ClassReflection) { return false; } // is phpunit test case? - return $classReflection->isSubclassOf(TestCase::class); + return $classReflection->isSubclassOf(self::TESTCASE_CLASS); } }