From 7f5124447e368a479d3827f61c4981282e19caab Mon Sep 17 00:00:00 2001 From: Tomas Votruba Date: Fri, 11 Oct 2024 11:22:44 +0000 Subject: [PATCH] Updated Rector to commit d8f31e7559c9e3e288f2f58228120c71986a80e9 https://github.com/rectorphp/rector-src/commit/d8f31e7559c9e3e288f2f58228120c71986a80e9 Add RemoveTypedPropertyNonMockDocblockRector (#6306) --- .../PhpDoc/TagRemover/VarTagRemover.php | 15 ++ ...moveTypedPropertyNonMockDocblockRector.php | 140 ++++++++++++++++++ .../ReturnTypeFromMockObjectRector.php | 7 +- ...ypedPropertyFromCreateMockAssignRector.php | 7 +- src/Application/VersionResolver.php | 4 +- src/Enum/ClassName.php | 12 ++ vendor/autoload.php | 2 +- vendor/composer/autoload_classmap.php | 2 + vendor/composer/autoload_real.php | 10 +- vendor/composer/autoload_static.php | 10 +- vendor/scoper-autoload.php | 2 +- 11 files changed, 188 insertions(+), 23 deletions(-) create mode 100644 rules/DeadCode/Rector/ClassLike/RemoveTypedPropertyNonMockDocblockRector.php create mode 100644 src/Enum/ClassName.php diff --git a/rules/DeadCode/PhpDoc/TagRemover/VarTagRemover.php b/rules/DeadCode/PhpDoc/TagRemover/VarTagRemover.php index 9c0b8084c8cd..d3e97eac07ea 100644 --- a/rules/DeadCode/PhpDoc/TagRemover/VarTagRemover.php +++ b/rules/DeadCode/PhpDoc/TagRemover/VarTagRemover.php @@ -3,6 +3,7 @@ declare (strict_types=1); namespace Rector\DeadCode\PhpDoc\TagRemover; +use PhpParser\Node; use PhpParser\Node\Param; use PhpParser\Node\Stmt\Expression; use PhpParser\Node\Stmt\Property; @@ -74,6 +75,20 @@ public function removeVarTagIfUseless(PhpDocInfo $phpDocInfo, Property $property $this->docBlockUpdater->updateRefactoredNodeWithPhpDocInfo($property); return \true; } + /** + * @api generic + */ + public function removeVarTag(Node $node) : bool + { + $phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($node); + $varTagValueNode = $phpDocInfo->getVarTagValueNode(); + if (!$varTagValueNode instanceof VarTagValueNode) { + return \false; + } + $phpDocInfo->removeByType(VarTagValueNode::class); + $this->docBlockUpdater->updateRefactoredNodeWithPhpDocInfo($node); + return \true; + } /** * @param \PhpParser\Node\Stmt\Expression|\PhpParser\Node\Stmt\Property|\PhpParser\Node\Param $node */ diff --git a/rules/DeadCode/Rector/ClassLike/RemoveTypedPropertyNonMockDocblockRector.php b/rules/DeadCode/Rector/ClassLike/RemoveTypedPropertyNonMockDocblockRector.php new file mode 100644 index 000000000000..5ce5a8230da1 --- /dev/null +++ b/rules/DeadCode/Rector/ClassLike/RemoveTypedPropertyNonMockDocblockRector.php @@ -0,0 +1,140 @@ +varTagRemover = $varTagRemover; + $this->staticTypeMapper = $staticTypeMapper; + $this->phpDocInfoFactory = $phpDocInfoFactory; + } + public function getRuleDefinition() : RuleDefinition + { + return new RuleDefinition('Remove @var annotation for PHPUnit\\Framework\\MockObject\\MockObject combined with native object type', [new CodeSample(<<<'CODE_SAMPLE' +use PHPUnit\Framework\TestCase; +use PHPUnit\Framework\MockObject\MockObject; + +final class SomeTest extends TestCase +{ + /** + * @var SomeClass|MockObject + */ + private SomeClass $someProperty; +} +CODE_SAMPLE +, <<<'CODE_SAMPLE' +use PHPUnit\Framework\TestCase; +use PHPUnit\Framework\MockObject\MockObject; + +final class SomeTest extends TestCase +{ + private SomeClass $someProperty; +} +CODE_SAMPLE +)]); + } + public function getNodeTypes() : array + { + return [Class_::class]; + } + /** + * @param Class_ $node + */ + public function refactor(Node $node) : ?Node + { + if (!$this->isObjectType($node, new ObjectType(ClassName::TEST_CASE_CLASS))) { + return null; + } + $hasChanged = \false; + foreach ($node->getProperties() as $property) { + // not yet typed + if (!$property->type instanceof Node) { + continue; + } + if (\count($property->props) !== 1) { + continue; + } + if ($this->isObjectType($property->type, new ObjectType(self::MOCK_OBJECT_CLASS))) { + continue; + } + $propertyDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($property); + if (!$this->isVarTagUnionTypeMockObject($propertyDocInfo, $property)) { + continue; + } + // clear var docblock + if ($this->varTagRemover->removeVarTag($property)) { + $hasChanged = \true; + } + } + if (!$hasChanged) { + return null; + } + return $node; + } + public function provideMinPhpVersion() : int + { + return PhpVersionFeature::TYPED_PROPERTIES; + } + private function isVarTagUnionTypeMockObject(PhpDocInfo $phpDocInfo, Property $property) : bool + { + $varTagValueNode = $phpDocInfo->getVarTagValueNode(); + if (!$varTagValueNode instanceof VarTagValueNode) { + return \false; + } + if (!$varTagValueNode->type instanceof UnionTypeNode) { + return \false; + } + $varTagType = $this->staticTypeMapper->mapPHPStanPhpDocTypeNodeToPHPStanType($varTagValueNode->type, $property); + if (!$varTagType instanceof UnionType) { + return \false; + } + foreach ($varTagType->getTypes() as $unionedType) { + if ($unionedType->isSuperTypeOf(new ObjectType(self::MOCK_OBJECT_CLASS))->yes()) { + return \true; + } + } + return \false; + } +} diff --git a/rules/TypeDeclaration/Rector/ClassMethod/ReturnTypeFromMockObjectRector.php b/rules/TypeDeclaration/Rector/ClassMethod/ReturnTypeFromMockObjectRector.php index d0fb0e49cf62..bc30c5a06540 100644 --- a/rules/TypeDeclaration/Rector/ClassMethod/ReturnTypeFromMockObjectRector.php +++ b/rules/TypeDeclaration/Rector/ClassMethod/ReturnTypeFromMockObjectRector.php @@ -12,6 +12,7 @@ use PHPStan\Type\IntersectionType; use PHPStan\Type\ObjectType; use PHPStan\Type\Type; +use Rector\Enum\ClassName; use Rector\PhpParser\Node\BetterNodeFinder; use Rector\Rector\AbstractScopeAwareRector; use Rector\TypeDeclaration\NodeAnalyzer\ReturnAnalyzer; @@ -40,10 +41,6 @@ final class ReturnTypeFromMockObjectRector extends AbstractScopeAwareRector impl * @var \Rector\TypeDeclaration\NodeAnalyzer\ReturnAnalyzer */ private $returnAnalyzer; - /** - * @var string - */ - private const TESTCASE_CLASS = 'PHPUnit\\Framework\\TestCase'; /** * @var string */ @@ -142,6 +139,6 @@ private function isInsideTestCaseClass(Scope $scope) : bool return \false; } // is phpunit test case? - return $classReflection->isSubclassOf(self::TESTCASE_CLASS); + return $classReflection->isSubclassOf(ClassName::TEST_CASE_CLASS); } } diff --git a/rules/TypeDeclaration/Rector/Class_/TypedPropertyFromCreateMockAssignRector.php b/rules/TypeDeclaration/Rector/Class_/TypedPropertyFromCreateMockAssignRector.php index efb08ef764d7..3e0f9f6e23cb 100644 --- a/rules/TypeDeclaration/Rector/Class_/TypedPropertyFromCreateMockAssignRector.php +++ b/rules/TypeDeclaration/Rector/Class_/TypedPropertyFromCreateMockAssignRector.php @@ -8,6 +8,7 @@ use PhpParser\Node\Stmt\Class_; use PHPStan\Type\ObjectType; use PHPStan\Type\Type; +use Rector\Enum\ClassName; use Rector\PHPStanStaticTypeMapper\Enum\TypeKind; use Rector\Rector\AbstractRector; use Rector\StaticTypeMapper\StaticTypeMapper; @@ -37,10 +38,6 @@ final class TypedPropertyFromCreateMockAssignRector extends AbstractRector imple * @var \Rector\TypeDeclaration\AlreadyAssignDetector\ConstructorAssignDetector */ private $constructorAssignDetector; - /** - * @var string - */ - private const TEST_CASE_CLASS = 'PHPUnit\\Framework\\TestCase'; /** * @var string */ @@ -90,7 +87,7 @@ public function getNodeTypes() : array */ public function refactor(Node $node) : ?Node { - if (!$this->isObjectType($node, new ObjectType(self::TEST_CASE_CLASS))) { + if (!$this->isObjectType($node, new ObjectType(ClassName::TEST_CASE_CLASS))) { return null; } $hasChanged = \false; diff --git a/src/Application/VersionResolver.php b/src/Application/VersionResolver.php index 74bfc4fbeaef..3e61f636b9ad 100644 --- a/src/Application/VersionResolver.php +++ b/src/Application/VersionResolver.php @@ -19,12 +19,12 @@ final class VersionResolver * @api * @var string */ - public const PACKAGE_VERSION = 'd553e84b406dbea66f4ca1dcca58f6405147c2c5'; + public const PACKAGE_VERSION = 'd8f31e7559c9e3e288f2f58228120c71986a80e9'; /** * @api * @var string */ - public const RELEASE_DATE = '2024-10-11 15:45:42'; + public const RELEASE_DATE = '2024-10-11 13:20:28'; /** * @var int */ diff --git a/src/Enum/ClassName.php b/src/Enum/ClassName.php new file mode 100644 index 000000000000..80b446eca149 --- /dev/null +++ b/src/Enum/ClassName.php @@ -0,0 +1,12 @@ + $baseDir . '/rules/DeadCode/Rector/Cast/RecastingRemovalRector.php', 'Rector\\DeadCode\\Rector\\ClassConst\\RemoveUnusedPrivateClassConstantRector' => $baseDir . '/rules/DeadCode/Rector/ClassConst/RemoveUnusedPrivateClassConstantRector.php', 'Rector\\DeadCode\\Rector\\ClassLike\\RemoveAnnotationRector' => $baseDir . '/rules/DeadCode/Rector/ClassLike/RemoveAnnotationRector.php', + 'Rector\\DeadCode\\Rector\\ClassLike\\RemoveTypedPropertyNonMockDocblockRector' => $baseDir . '/rules/DeadCode/Rector/ClassLike/RemoveTypedPropertyNonMockDocblockRector.php', 'Rector\\DeadCode\\Rector\\ClassMethod\\RemoveEmptyClassMethodRector' => $baseDir . '/rules/DeadCode/Rector/ClassMethod/RemoveEmptyClassMethodRector.php', 'Rector\\DeadCode\\Rector\\ClassMethod\\RemoveNullTagValueNodeRector' => $baseDir . '/rules/DeadCode/Rector/ClassMethod/RemoveNullTagValueNodeRector.php', 'Rector\\DeadCode\\Rector\\ClassMethod\\RemoveUnusedConstructorParamRector' => $baseDir . '/rules/DeadCode/Rector/ClassMethod/RemoveUnusedConstructorParamRector.php', @@ -1511,6 +1512,7 @@ 'Rector\\EarlyReturn\\Rector\\Return_\\ReturnBinaryOrToEarlyReturnRector' => $baseDir . '/rules/EarlyReturn/Rector/Return_/ReturnBinaryOrToEarlyReturnRector.php', 'Rector\\EarlyReturn\\Rector\\StmtsAwareInterface\\ReturnEarlyIfVariableRector' => $baseDir . '/rules/EarlyReturn/Rector/StmtsAwareInterface/ReturnEarlyIfVariableRector.php', 'Rector\\EarlyReturn\\ValueObject\\BareSingleAssignIf' => $baseDir . '/rules/EarlyReturn/ValueObject/BareSingleAssignIf.php', + 'Rector\\Enum\\ClassName' => $baseDir . '/src/Enum/ClassName.php', 'Rector\\Enum\\JsonConstant' => $vendorDir . '/rector/rector-downgrade-php/src/Enum/JsonConstant.php', 'Rector\\Enum\\ObjectReference' => $baseDir . '/src/Enum/ObjectReference.php', 'Rector\\Exception\\Cache\\CachingException' => $baseDir . '/src/Exception/Cache/CachingException.php', diff --git a/vendor/composer/autoload_real.php b/vendor/composer/autoload_real.php index 82f820f61c65..f74af415e8bf 100644 --- a/vendor/composer/autoload_real.php +++ b/vendor/composer/autoload_real.php @@ -2,7 +2,7 @@ // autoload_real.php @generated by Composer -class ComposerAutoloaderInit7c12491db1a700dd78980ecb6595c088 +class ComposerAutoloaderInit4d4c37b878ce01a3ff505ba7def6aac7 { private static $loader; @@ -22,17 +22,17 @@ public static function getLoader() return self::$loader; } - spl_autoload_register(array('ComposerAutoloaderInit7c12491db1a700dd78980ecb6595c088', 'loadClassLoader'), true, true); + spl_autoload_register(array('ComposerAutoloaderInit4d4c37b878ce01a3ff505ba7def6aac7', 'loadClassLoader'), true, true); self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__)); - spl_autoload_unregister(array('ComposerAutoloaderInit7c12491db1a700dd78980ecb6595c088', 'loadClassLoader')); + spl_autoload_unregister(array('ComposerAutoloaderInit4d4c37b878ce01a3ff505ba7def6aac7', 'loadClassLoader')); require __DIR__ . '/autoload_static.php'; - call_user_func(\Composer\Autoload\ComposerStaticInit7c12491db1a700dd78980ecb6595c088::getInitializer($loader)); + call_user_func(\Composer\Autoload\ComposerStaticInit4d4c37b878ce01a3ff505ba7def6aac7::getInitializer($loader)); $loader->setClassMapAuthoritative(true); $loader->register(true); - $filesToLoad = \Composer\Autoload\ComposerStaticInit7c12491db1a700dd78980ecb6595c088::$files; + $filesToLoad = \Composer\Autoload\ComposerStaticInit4d4c37b878ce01a3ff505ba7def6aac7::$files; $requireFile = \Closure::bind(static function ($fileIdentifier, $file) { if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) { $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true; diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php index f00e2d5b0cf5..c20a1f3907ec 100644 --- a/vendor/composer/autoload_static.php +++ b/vendor/composer/autoload_static.php @@ -4,7 +4,7 @@ namespace Composer\Autoload; -class ComposerStaticInit7c12491db1a700dd78980ecb6595c088 +class ComposerStaticInit4d4c37b878ce01a3ff505ba7def6aac7 { public static $files = array ( 'ad155f8f1cf0d418fe49e248db8c661b' => __DIR__ . '/..' . '/react/promise/src/functions_include.php', @@ -1505,6 +1505,7 @@ class ComposerStaticInit7c12491db1a700dd78980ecb6595c088 'Rector\\DeadCode\\Rector\\Cast\\RecastingRemovalRector' => __DIR__ . '/../..' . '/rules/DeadCode/Rector/Cast/RecastingRemovalRector.php', 'Rector\\DeadCode\\Rector\\ClassConst\\RemoveUnusedPrivateClassConstantRector' => __DIR__ . '/../..' . '/rules/DeadCode/Rector/ClassConst/RemoveUnusedPrivateClassConstantRector.php', 'Rector\\DeadCode\\Rector\\ClassLike\\RemoveAnnotationRector' => __DIR__ . '/../..' . '/rules/DeadCode/Rector/ClassLike/RemoveAnnotationRector.php', + 'Rector\\DeadCode\\Rector\\ClassLike\\RemoveTypedPropertyNonMockDocblockRector' => __DIR__ . '/../..' . '/rules/DeadCode/Rector/ClassLike/RemoveTypedPropertyNonMockDocblockRector.php', 'Rector\\DeadCode\\Rector\\ClassMethod\\RemoveEmptyClassMethodRector' => __DIR__ . '/../..' . '/rules/DeadCode/Rector/ClassMethod/RemoveEmptyClassMethodRector.php', 'Rector\\DeadCode\\Rector\\ClassMethod\\RemoveNullTagValueNodeRector' => __DIR__ . '/../..' . '/rules/DeadCode/Rector/ClassMethod/RemoveNullTagValueNodeRector.php', 'Rector\\DeadCode\\Rector\\ClassMethod\\RemoveUnusedConstructorParamRector' => __DIR__ . '/../..' . '/rules/DeadCode/Rector/ClassMethod/RemoveUnusedConstructorParamRector.php', @@ -1730,6 +1731,7 @@ class ComposerStaticInit7c12491db1a700dd78980ecb6595c088 'Rector\\EarlyReturn\\Rector\\Return_\\ReturnBinaryOrToEarlyReturnRector' => __DIR__ . '/../..' . '/rules/EarlyReturn/Rector/Return_/ReturnBinaryOrToEarlyReturnRector.php', 'Rector\\EarlyReturn\\Rector\\StmtsAwareInterface\\ReturnEarlyIfVariableRector' => __DIR__ . '/../..' . '/rules/EarlyReturn/Rector/StmtsAwareInterface/ReturnEarlyIfVariableRector.php', 'Rector\\EarlyReturn\\ValueObject\\BareSingleAssignIf' => __DIR__ . '/../..' . '/rules/EarlyReturn/ValueObject/BareSingleAssignIf.php', + 'Rector\\Enum\\ClassName' => __DIR__ . '/../..' . '/src/Enum/ClassName.php', 'Rector\\Enum\\JsonConstant' => __DIR__ . '/..' . '/rector/rector-downgrade-php/src/Enum/JsonConstant.php', 'Rector\\Enum\\ObjectReference' => __DIR__ . '/../..' . '/src/Enum/ObjectReference.php', 'Rector\\Exception\\Cache\\CachingException' => __DIR__ . '/../..' . '/src/Exception/Cache/CachingException.php', @@ -2818,9 +2820,9 @@ class ComposerStaticInit7c12491db1a700dd78980ecb6595c088 public static function getInitializer(ClassLoader $loader) { return \Closure::bind(function () use ($loader) { - $loader->prefixLengthsPsr4 = ComposerStaticInit7c12491db1a700dd78980ecb6595c088::$prefixLengthsPsr4; - $loader->prefixDirsPsr4 = ComposerStaticInit7c12491db1a700dd78980ecb6595c088::$prefixDirsPsr4; - $loader->classMap = ComposerStaticInit7c12491db1a700dd78980ecb6595c088::$classMap; + $loader->prefixLengthsPsr4 = ComposerStaticInit4d4c37b878ce01a3ff505ba7def6aac7::$prefixLengthsPsr4; + $loader->prefixDirsPsr4 = ComposerStaticInit4d4c37b878ce01a3ff505ba7def6aac7::$prefixDirsPsr4; + $loader->classMap = ComposerStaticInit4d4c37b878ce01a3ff505ba7def6aac7::$classMap; }, null, ClassLoader::class); } diff --git a/vendor/scoper-autoload.php b/vendor/scoper-autoload.php index 10c86d5e70a9..e89f5b7524b6 100644 --- a/vendor/scoper-autoload.php +++ b/vendor/scoper-autoload.php @@ -30,7 +30,7 @@ function humbug_phpscoper_expose_class($exposed, $prefixed) { } } humbug_phpscoper_expose_class('AutoloadIncluder', 'RectorPrefix202410\AutoloadIncluder'); -humbug_phpscoper_expose_class('ComposerAutoloaderInit7c12491db1a700dd78980ecb6595c088', 'RectorPrefix202410\ComposerAutoloaderInit7c12491db1a700dd78980ecb6595c088'); +humbug_phpscoper_expose_class('ComposerAutoloaderInit4d4c37b878ce01a3ff505ba7def6aac7', 'RectorPrefix202410\ComposerAutoloaderInit4d4c37b878ce01a3ff505ba7def6aac7'); humbug_phpscoper_expose_class('Product', 'RectorPrefix202410\Product'); // Function aliases. For more information see: