Updated Rector to commit 417b208b58da94040e01c5f9629ae33db472df78

417b208b58 [TypeDeclaration] Add TypedPropertyFromCreateMockAssignRector (#6177)
This commit is contained in:
Tomas Votruba 2024-07-23 17:11:54 +00:00
parent cecbffbf7d
commit 8d7c7faf2f
17 changed files with 182 additions and 34 deletions

View File

@ -10,7 +10,7 @@ use Rector\Rector\AbstractRector;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* @see \Utils\Rector\Tests\Rector\RenameSimpleRectorTest
* @see \Rector\Tests\TypeDeclaration\Rector\RenameSimpleRectorTest
*/
final class RenameSimpleRector extends AbstractRector
{

View File

@ -2,7 +2,7 @@
declare(strict_types=1);
namespace Utils\Rector\Tests\Rector\RenameSimpleRector;
namespace Rector\Tests\TypeDeclaration\Rector\RenameSimpleRector;
use Iterator;
use Rector\Testing\PHPUnit\AbstractRectorTestCase;

View File

@ -0,0 +1,147 @@
<?php
declare (strict_types=1);
namespace Rector\TypeDeclaration\Rector\Class_;
use PhpParser\Node;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Name\FullyQualified;
use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\ClassMethod;
use PHPStan\Type\IntersectionType;
use PHPStan\Type\NeverType;
use PHPStan\Type\ObjectType;
use PHPStan\Type\Type;
use Rector\NodeManipulator\ClassMethodPropertyFetchManipulator;
use Rector\Rector\AbstractRector;
use Rector\ValueObject\MethodName;
use Rector\ValueObject\PhpVersionFeature;
use Rector\VersionBonding\Contract\MinPhpVersionInterface;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* @see \Rector\Tests\TypeDeclaration\Rector\Class_\TypedPropertyFromCreateMockAssignRector\TypedPropertyFromCreateMockAssignRectorTest
*/
final class TypedPropertyFromCreateMockAssignRector extends AbstractRector implements MinPhpVersionInterface
{
/**
* @readonly
* @var \Rector\NodeManipulator\ClassMethodPropertyFetchManipulator
*/
private $classMethodPropertyFetchManipulator;
/**
* @var string
*/
private const TEST_CASE_CLASS = 'PHPUnit\\Framework\\TestCase';
/**
* @var string
*/
private const MOCK_OBJECT_CLASS = 'PHPUnit\\Framework\\MockObject\\MockObject';
public function __construct(ClassMethodPropertyFetchManipulator $classMethodPropertyFetchManipulator)
{
$this->classMethodPropertyFetchManipulator = $classMethodPropertyFetchManipulator;
}
public function getRuleDefinition() : RuleDefinition
{
return new RuleDefinition('Add typed property from assigned mock', [new CodeSample(<<<'CODE_SAMPLE'
use PHPUnit\Framework\TestCase;
final class SomeTest extends TestCase
{
private $someProperty;
protected function setUp(): void
{
$this->someProperty = $this->createMock(SomeMockedClass::class);
}
}
CODE_SAMPLE
, <<<'CODE_SAMPLE'
use PHPUnit\Framework\TestCase;
final class SomeTest extends TestCase
{
private \PHPUnit\Framework\MockObject\MockObject $someProperty;
protected function setUp(): void
{
$this->someProperty = $this->createMock(SomeMockedClass::class);
}
}
CODE_SAMPLE
)]);
}
public function getNodeTypes() : array
{
return [Class_::class];
}
/**
* @param Class_ $node
*/
public function refactor(Node $node) : ?Node
{
if (!$this->isObjectType($node, new ObjectType(self::TEST_CASE_CLASS))) {
return null;
}
$hasChanged = \false;
foreach ($node->getProperties() as $property) {
// already typed
if ($property->type instanceof Node) {
continue;
}
$propertyName = $this->getName($property);
$setUpClassMethod = $node->getMethod(MethodName::SET_UP);
if (!$setUpClassMethod instanceof ClassMethod) {
continue;
}
$assignedType = $this->resolveSingleAssignedExprType($setUpClassMethod, $propertyName);
if (!$assignedType instanceof Type) {
continue;
}
if (!$this->isMockObjectType($assignedType)) {
continue;
}
$property->type = new FullyQualified(self::MOCK_OBJECT_CLASS);
$hasChanged = \true;
}
if (!$hasChanged) {
return null;
}
return $node;
}
public function provideMinPhpVersion() : int
{
return PhpVersionFeature::TYPED_PROPERTIES;
}
private function isMockObjectType(Type $type) : bool
{
if ($type instanceof ObjectType && $type->isInstanceOf(self::MOCK_OBJECT_CLASS)->yes()) {
return \true;
}
return $this->isIntersectionWithMockObjectType($type);
}
private function isIntersectionWithMockObjectType(Type $type) : bool
{
if (!$type instanceof IntersectionType) {
return \false;
}
if (\count($type->getTypes()) !== 2) {
return \false;
}
return \in_array(self::MOCK_OBJECT_CLASS, $type->getObjectClassNames());
}
private function resolveSingleAssignedExprType(ClassMethod $setUpClassMethod, string $propertyName) : ?Type
{
$assignedExprs = $this->classMethodPropertyFetchManipulator->findAssignsToPropertyName($setUpClassMethod, $propertyName);
if (\count($assignedExprs) !== 1) {
return null;
}
$assignedExpr = $assignedExprs[0];
$exprType = $this->getType($assignedExpr);
// work around finalized class mock
if ($exprType instanceof NeverType && $assignedExpr instanceof MethodCall && $this->isName($assignedExpr->name, 'createMock')) {
return new ObjectType(self::MOCK_OBJECT_CLASS);
}
return $exprType;
}
}

View File

@ -19,12 +19,12 @@ final class VersionResolver
* @api
* @var string
*/
public const PACKAGE_VERSION = 'b0c89a98a0eb4a62d3141d950484d6e3ea7fdbda';
public const PACKAGE_VERSION = '417b208b58da94040e01c5f9629ae33db472df78';
/**
* @api
* @var string
*/
public const RELEASE_DATE = '2024-07-23 18:02:45';
public const RELEASE_DATE = '2024-07-23 19:09:34';
/**
* @var int
*/

View File

@ -10,6 +10,7 @@ use Rector\TypeDeclaration\Rector\Class_\ChildDoctrineRepositoryClassTypeRector;
use Rector\TypeDeclaration\Rector\Class_\MergeDateTimePropertyTypeDeclarationRector;
use Rector\TypeDeclaration\Rector\Class_\PropertyTypeFromStrictSetterGetterRector;
use Rector\TypeDeclaration\Rector\Class_\ReturnTypeFromStrictTernaryRector;
use Rector\TypeDeclaration\Rector\Class_\TypedPropertyFromCreateMockAssignRector;
use Rector\TypeDeclaration\Rector\Class_\TypedPropertyFromJMSSerializerAttributeTypeRector;
use Rector\TypeDeclaration\Rector\ClassMethod\AddMethodCallBasedStrictParamTypeRector;
use Rector\TypeDeclaration\Rector\ClassMethod\AddParamTypeBasedOnPHPUnitDataProviderRector;
@ -65,6 +66,7 @@ final class TypeDeclarationLevel
AddFunctionVoidReturnTypeWhereNoReturnRector::class,
AddTestsVoidReturnTypeWhereNoReturnRector::class,
ReturnTypeFromMockObjectRector::class,
TypedPropertyFromCreateMockAssignRector::class,
AddArrowFunctionReturnTypeRector::class,
BoolReturnTypeFromBooleanConstReturnsRector::class,
ReturnTypeFromStrictNewArrayRector::class,

View File

@ -10,7 +10,7 @@ use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* @see \Utils\Rector\Tests\Rector\__Name__\__Name__Test
* @see \Rector\Tests\TypeDeclaration\Rector\__Name__\__Name__Test
*/
final class __Name__ extends AbstractRector
{

View File

@ -1,6 +1,6 @@
<?php
namespace Utils\Rector\Tests\Rector\__Name__\Fixture;
namespace Rector\Tests\TypeDeclaration\Rector\__Name__\Fixture;
// @todo fill code before
@ -8,7 +8,7 @@ namespace Utils\Rector\Tests\Rector\__Name__\Fixture;
-----
<?php
namespace Utils\Rector\Tests\Rector\__Name__\Fixture;
namespace Rector\Tests\TypeDeclaration\Rector\__Name__\Fixture;
// @todo fill code after

View File

@ -2,7 +2,7 @@
declare(strict_types=1);
namespace Utils\Rector\Tests\Rector\__Name__;
namespace Rector\Tests\TypeDeclaration\Rector\__Name__;
use PHPUnit\Framework\Attributes\DataProvider;
use Rector\Testing\PHPUnit\AbstractRectorTestCase;

View File

@ -2,7 +2,7 @@
declare(strict_types=1);
namespace Utils\Rector\Tests\Rector\__Name__;
namespace Rector\Tests\TypeDeclaration\Rector\__Name__;
use Rector\Testing\PHPUnit\AbstractRectorTestCase;

2
vendor/autoload.php vendored
View File

@ -22,4 +22,4 @@ if (PHP_VERSION_ID < 50600) {
require_once __DIR__ . '/composer/autoload_real.php';
return ComposerAutoloaderInit2971ea952332f12bcefd9fbb21b5c118::getLoader();
return ComposerAutoloaderInita40fb1533ebdca8bab24fcd004c56dce::getLoader();

View File

@ -2455,6 +2455,7 @@ return array(
'Rector\\TypeDeclaration\\Rector\\Class_\\MergeDateTimePropertyTypeDeclarationRector' => $baseDir . '/rules/TypeDeclaration/Rector/Class_/MergeDateTimePropertyTypeDeclarationRector.php',
'Rector\\TypeDeclaration\\Rector\\Class_\\PropertyTypeFromStrictSetterGetterRector' => $baseDir . '/rules/TypeDeclaration/Rector/Class_/PropertyTypeFromStrictSetterGetterRector.php',
'Rector\\TypeDeclaration\\Rector\\Class_\\ReturnTypeFromStrictTernaryRector' => $baseDir . '/rules/TypeDeclaration/Rector/Class_/ReturnTypeFromStrictTernaryRector.php',
'Rector\\TypeDeclaration\\Rector\\Class_\\TypedPropertyFromCreateMockAssignRector' => $baseDir . '/rules/TypeDeclaration/Rector/Class_/TypedPropertyFromCreateMockAssignRector.php',
'Rector\\TypeDeclaration\\Rector\\Class_\\TypedPropertyFromJMSSerializerAttributeTypeRector' => $baseDir . '/rules/TypeDeclaration/Rector/Class_/TypedPropertyFromJMSSerializerAttributeTypeRector.php',
'Rector\\TypeDeclaration\\Rector\\Closure\\AddClosureNeverReturnTypeRector' => $baseDir . '/rules/TypeDeclaration/Rector/Closure/AddClosureNeverReturnTypeRector.php',
'Rector\\TypeDeclaration\\Rector\\Closure\\AddClosureReturnTypeFromReturnCastRector' => $baseDir . '/rules/TypeDeclaration/Rector/Closure/AddClosureReturnTypeFromReturnCastRector.php',

View File

@ -2,7 +2,7 @@
// autoload_real.php @generated by Composer
class ComposerAutoloaderInit2971ea952332f12bcefd9fbb21b5c118
class ComposerAutoloaderInita40fb1533ebdca8bab24fcd004c56dce
{
private static $loader;
@ -22,17 +22,17 @@ class ComposerAutoloaderInit2971ea952332f12bcefd9fbb21b5c118
return self::$loader;
}
spl_autoload_register(array('ComposerAutoloaderInit2971ea952332f12bcefd9fbb21b5c118', 'loadClassLoader'), true, true);
spl_autoload_register(array('ComposerAutoloaderInita40fb1533ebdca8bab24fcd004c56dce', 'loadClassLoader'), true, true);
self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__));
spl_autoload_unregister(array('ComposerAutoloaderInit2971ea952332f12bcefd9fbb21b5c118', 'loadClassLoader'));
spl_autoload_unregister(array('ComposerAutoloaderInita40fb1533ebdca8bab24fcd004c56dce', 'loadClassLoader'));
require __DIR__ . '/autoload_static.php';
call_user_func(\Composer\Autoload\ComposerStaticInit2971ea952332f12bcefd9fbb21b5c118::getInitializer($loader));
call_user_func(\Composer\Autoload\ComposerStaticInita40fb1533ebdca8bab24fcd004c56dce::getInitializer($loader));
$loader->setClassMapAuthoritative(true);
$loader->register(true);
$filesToLoad = \Composer\Autoload\ComposerStaticInit2971ea952332f12bcefd9fbb21b5c118::$files;
$filesToLoad = \Composer\Autoload\ComposerStaticInita40fb1533ebdca8bab24fcd004c56dce::$files;
$requireFile = \Closure::bind(static function ($fileIdentifier, $file) {
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
$GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;

View File

@ -4,7 +4,7 @@
namespace Composer\Autoload;
class ComposerStaticInit2971ea952332f12bcefd9fbb21b5c118
class ComposerStaticInita40fb1533ebdca8bab24fcd004c56dce
{
public static $files = array (
'ad155f8f1cf0d418fe49e248db8c661b' => __DIR__ . '/..' . '/react/promise/src/functions_include.php',
@ -2674,6 +2674,7 @@ class ComposerStaticInit2971ea952332f12bcefd9fbb21b5c118
'Rector\\TypeDeclaration\\Rector\\Class_\\MergeDateTimePropertyTypeDeclarationRector' => __DIR__ . '/../..' . '/rules/TypeDeclaration/Rector/Class_/MergeDateTimePropertyTypeDeclarationRector.php',
'Rector\\TypeDeclaration\\Rector\\Class_\\PropertyTypeFromStrictSetterGetterRector' => __DIR__ . '/../..' . '/rules/TypeDeclaration/Rector/Class_/PropertyTypeFromStrictSetterGetterRector.php',
'Rector\\TypeDeclaration\\Rector\\Class_\\ReturnTypeFromStrictTernaryRector' => __DIR__ . '/../..' . '/rules/TypeDeclaration/Rector/Class_/ReturnTypeFromStrictTernaryRector.php',
'Rector\\TypeDeclaration\\Rector\\Class_\\TypedPropertyFromCreateMockAssignRector' => __DIR__ . '/../..' . '/rules/TypeDeclaration/Rector/Class_/TypedPropertyFromCreateMockAssignRector.php',
'Rector\\TypeDeclaration\\Rector\\Class_\\TypedPropertyFromJMSSerializerAttributeTypeRector' => __DIR__ . '/../..' . '/rules/TypeDeclaration/Rector/Class_/TypedPropertyFromJMSSerializerAttributeTypeRector.php',
'Rector\\TypeDeclaration\\Rector\\Closure\\AddClosureNeverReturnTypeRector' => __DIR__ . '/../..' . '/rules/TypeDeclaration/Rector/Closure/AddClosureNeverReturnTypeRector.php',
'Rector\\TypeDeclaration\\Rector\\Closure\\AddClosureReturnTypeFromReturnCastRector' => __DIR__ . '/../..' . '/rules/TypeDeclaration/Rector/Closure/AddClosureReturnTypeFromReturnCastRector.php',
@ -2773,9 +2774,9 @@ class ComposerStaticInit2971ea952332f12bcefd9fbb21b5c118
public static function getInitializer(ClassLoader $loader)
{
return \Closure::bind(function () use ($loader) {
$loader->prefixLengthsPsr4 = ComposerStaticInit2971ea952332f12bcefd9fbb21b5c118::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInit2971ea952332f12bcefd9fbb21b5c118::$prefixDirsPsr4;
$loader->classMap = ComposerStaticInit2971ea952332f12bcefd9fbb21b5c118::$classMap;
$loader->prefixLengthsPsr4 = ComposerStaticInita40fb1533ebdca8bab24fcd004c56dce::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInita40fb1533ebdca8bab24fcd004c56dce::$prefixDirsPsr4;
$loader->classMap = ComposerStaticInita40fb1533ebdca8bab24fcd004c56dce::$classMap;
}, null, ClassLoader::class);
}

View File

@ -504,17 +504,17 @@
},
{
"name": "illuminate\/container",
"version": "v11.16.0",
"version_normalized": "11.16.0.0",
"version": "v11.17.0",
"version_normalized": "11.17.0.0",
"source": {
"type": "git",
"url": "https:\/\/github.com\/illuminate\/container.git",
"reference": "49183db6643a7efbe9902ca379b8f8a55c802f88"
"reference": "c3c2713c66d120bf42865e831cfcef6ed9e10db2"
},
"dist": {
"type": "zip",
"url": "https:\/\/api.github.com\/repos\/illuminate\/container\/zipball\/49183db6643a7efbe9902ca379b8f8a55c802f88",
"reference": "49183db6643a7efbe9902ca379b8f8a55c802f88",
"url": "https:\/\/api.github.com\/repos\/illuminate\/container\/zipball\/c3c2713c66d120bf42865e831cfcef6ed9e10db2",
"reference": "c3c2713c66d120bf42865e831cfcef6ed9e10db2",
"shasum": ""
},
"require": {
@ -525,7 +525,7 @@
"provide": {
"psr\/container-implementation": "1.1|2.0"
},
"time": "2024-07-03T21:04:00+00:00",
"time": "2024-07-18T15:50:24+00:00",
"type": "library",
"extra": {
"branch-alias": {
@ -561,8 +561,8 @@
},
{
"name": "illuminate\/contracts",
"version": "v11.16.0",
"version_normalized": "11.16.0.0",
"version": "v11.17.0",
"version_normalized": "11.17.0.0",
"source": {
"type": "git",
"url": "https:\/\/github.com\/illuminate\/contracts.git",

File diff suppressed because one or more lines are too long

View File

@ -1159,11 +1159,8 @@ class Container implements ArrayAccess, ContainerContract
protected function fireAfterResolvingAttributeCallbacks(array $attributes, $object)
{
foreach ($attributes as $attribute) {
if (\is_a($attribute->getName(), ContextualAttribute::class, \true)) {
$instance = $attribute->newInstance();
if (\method_exists($instance, 'after')) {
$instance->after($instance, $object, $this);
}
if (\method_exists($instance = $attribute->newInstance(), 'after')) {
$instance->after($instance, $object, $this);
}
$callbacks = $this->getCallbacksForType($attribute->getName(), $object, $this->afterResolvingAttributeCallbacks);
foreach ($callbacks as $callback) {

View File

@ -30,7 +30,7 @@ if (!function_exists('humbug_phpscoper_expose_class')) {
}
}
humbug_phpscoper_expose_class('AutoloadIncluder', 'RectorPrefix202407\AutoloadIncluder');
humbug_phpscoper_expose_class('ComposerAutoloaderInit2971ea952332f12bcefd9fbb21b5c118', 'RectorPrefix202407\ComposerAutoloaderInit2971ea952332f12bcefd9fbb21b5c118');
humbug_phpscoper_expose_class('ComposerAutoloaderInita40fb1533ebdca8bab24fcd004c56dce', 'RectorPrefix202407\ComposerAutoloaderInita40fb1533ebdca8bab24fcd004c56dce');
humbug_phpscoper_expose_class('Product', 'RectorPrefix202407\Product');
// Function aliases. For more information see: