mirror of
https://github.com/rectorphp/rector.git
synced 2025-04-19 06:52:51 +02:00
Updated Rector to commit a12242df2ad756d59d6f214b3f727dedc0598704
a12242df2a
[AstResolver][Performance] Remove unnecessary double File read on AstResolver::parseFileNameToDecoratedNodes() (#4508)
This commit is contained in:
parent
ea78b6c7c5
commit
a09f711e9b
2
vendor/autoload.php
vendored
2
vendor/autoload.php
vendored
@ -22,4 +22,4 @@ if (PHP_VERSION_ID < 50600) {
|
||||
|
||||
require_once __DIR__ . '/composer/autoload_real.php';
|
||||
|
||||
return ComposerAutoloaderInit4ec4b37318586aea9b7cf86e1eaf6d40::getLoader();
|
||||
return ComposerAutoloaderInitdeffc6913765d186a4f1f1f5dc9ffae4::getLoader();
|
||||
|
12
vendor/composer/autoload_classmap.php
vendored
12
vendor/composer/autoload_classmap.php
vendored
@ -1750,12 +1750,9 @@ return array(
|
||||
'Rector\\Doctrine\\NodeAnalyzer\\AttributeFinder' => $vendorDir . '/rector/rector-doctrine/src/NodeAnalyzer/AttributeFinder.php',
|
||||
'Rector\\Doctrine\\NodeAnalyzer\\AttrinationFinder' => $vendorDir . '/rector/rector-doctrine/src/NodeAnalyzer/AttrinationFinder.php',
|
||||
'Rector\\Doctrine\\NodeAnalyzer\\ConstructorAssignPropertyAnalyzer' => $vendorDir . '/rector/rector-doctrine/src/NodeAnalyzer/ConstructorAssignPropertyAnalyzer.php',
|
||||
'Rector\\Doctrine\\NodeAnalyzer\\EntityObjectTypeResolver' => $vendorDir . '/rector/rector-doctrine/src/NodeAnalyzer/EntityObjectTypeResolver.php',
|
||||
'Rector\\Doctrine\\NodeAnalyzer\\SetterClassMethodAnalyzer' => $vendorDir . '/rector/rector-doctrine/src/NodeAnalyzer/SetterClassMethodAnalyzer.php',
|
||||
'Rector\\Doctrine\\NodeAnalyzer\\TargetEntityResolver' => $vendorDir . '/rector/rector-doctrine/src/NodeAnalyzer/TargetEntityResolver.php',
|
||||
'Rector\\Doctrine\\NodeFactory\\ArrayCollectionAssignFactory' => $vendorDir . '/rector/rector-doctrine/src/NodeFactory/ArrayCollectionAssignFactory.php',
|
||||
'Rector\\Doctrine\\NodeFactory\\RepositoryAssignFactory' => $vendorDir . '/rector/rector-doctrine/src/NodeFactory/RepositoryAssignFactory.php',
|
||||
'Rector\\Doctrine\\NodeFactory\\RepositoryNodeFactory' => $vendorDir . '/rector/rector-doctrine/src/NodeFactory/RepositoryNodeFactory.php',
|
||||
'Rector\\Doctrine\\NodeFactory\\ValueAssignFactory' => $vendorDir . '/rector/rector-doctrine/src/NodeFactory/ValueAssignFactory.php',
|
||||
'Rector\\Doctrine\\NodeManipulator\\ColumnPropertyTypeResolver' => $vendorDir . '/rector/rector-doctrine/src/NodeManipulator/ColumnPropertyTypeResolver.php',
|
||||
'Rector\\Doctrine\\NodeManipulator\\ConstructorManipulator' => $vendorDir . '/rector/rector-doctrine/src/NodeManipulator/ConstructorManipulator.php',
|
||||
@ -1763,22 +1760,15 @@ return array(
|
||||
'Rector\\Doctrine\\NodeManipulator\\PropertyTypeManipulator' => $vendorDir . '/rector/rector-doctrine/src/NodeManipulator/PropertyTypeManipulator.php',
|
||||
'Rector\\Doctrine\\NodeManipulator\\ToManyRelationPropertyTypeResolver' => $vendorDir . '/rector/rector-doctrine/src/NodeManipulator/ToManyRelationPropertyTypeResolver.php',
|
||||
'Rector\\Doctrine\\NodeManipulator\\ToOneRelationPropertyTypeResolver' => $vendorDir . '/rector/rector-doctrine/src/NodeManipulator/ToOneRelationPropertyTypeResolver.php',
|
||||
'Rector\\Doctrine\\Orm214\\Rector\\Param\\ReplaceLifecycleEventArgsByDedicatedEventArgsRector' => $vendorDir . '/rector/rector-doctrine/rules/Orm214/Rector/Param/ReplaceLifecycleEventArgsByDedicatedEventArgsRector.php',
|
||||
'Rector\\Doctrine\\PhpDocParser\\DoctrineClassAnnotationMatcher' => $vendorDir . '/rector/rector-doctrine/src/PhpDocParser/DoctrineClassAnnotationMatcher.php',
|
||||
'Rector\\Doctrine\\PhpDocParser\\DoctrineDocBlockResolver' => $vendorDir . '/rector/rector-doctrine/src/PhpDocParser/DoctrineDocBlockResolver.php',
|
||||
'Rector\\Doctrine\\PhpDoc\\ShortClassExpander' => $vendorDir . '/rector/rector-doctrine/src/PhpDoc/ShortClassExpander.php',
|
||||
'Rector\\Doctrine\\Rector\\ClassMethod\\ServiceEntityRepositoryParentCallToDIRector' => $vendorDir . '/rector/rector-doctrine/src/Rector/ClassMethod/ServiceEntityRepositoryParentCallToDIRector.php',
|
||||
'Rector\\Doctrine\\Rector\\Class_\\MoveRepositoryFromParentToConstructorRector' => $vendorDir . '/rector/rector-doctrine/src/Rector/Class_/MoveRepositoryFromParentToConstructorRector.php',
|
||||
'Rector\\Doctrine\\Rector\\Class_\\RemoveRepositoryFromEntityAnnotationRector' => $vendorDir . '/rector/rector-doctrine/src/Rector/Class_/RemoveRepositoryFromEntityAnnotationRector.php',
|
||||
'Rector\\Doctrine\\Rector\\MethodCall\\EntityAliasToClassConstantReferenceRector' => $vendorDir . '/rector/rector-doctrine/src/Rector/MethodCall/EntityAliasToClassConstantReferenceRector.php',
|
||||
'Rector\\Doctrine\\Rector\\MethodCall\\ReplaceParentRepositoryCallsByRepositoryPropertyRector' => $vendorDir . '/rector/rector-doctrine/src/Rector/MethodCall/ReplaceParentRepositoryCallsByRepositoryPropertyRector.php',
|
||||
'Rector\\Doctrine\\Rector\\Param\\ReplaceLifecycleEventArgsByDedicatedEventArgsRector' => $vendorDir . '/rector/rector-doctrine/src/Rector/Param/ReplaceLifecycleEventArgsByDedicatedEventArgsRector.php',
|
||||
'Rector\\Doctrine\\Set\\DoctrineSetList' => $vendorDir . '/rector/rector-doctrine/src/Set/DoctrineSetList.php',
|
||||
'Rector\\Doctrine\\TypeAnalyzer\\CollectionTypeFactory' => $vendorDir . '/rector/rector-doctrine/src/TypeAnalyzer/CollectionTypeFactory.php',
|
||||
'Rector\\Doctrine\\TypeAnalyzer\\CollectionTypeResolver' => $vendorDir . '/rector/rector-doctrine/src/TypeAnalyzer/CollectionTypeResolver.php',
|
||||
'Rector\\Doctrine\\TypeAnalyzer\\CollectionVarTagValueNodeResolver' => $vendorDir . '/rector/rector-doctrine/src/TypeAnalyzer/CollectionVarTagValueNodeResolver.php',
|
||||
'Rector\\Doctrine\\TypeAnalyzer\\DoctrineCollectionTypeAnalyzer' => $vendorDir . '/rector/rector-doctrine/src/TypeAnalyzer/DoctrineCollectionTypeAnalyzer.php',
|
||||
'Rector\\Doctrine\\TypeAnalyzer\\TypeFinder' => $vendorDir . '/rector/rector-doctrine/src/TypeAnalyzer/TypeFinder.php',
|
||||
'Rector\\Doctrine\\Type\\RepositoryTypeFactory' => $vendorDir . '/rector/rector-doctrine/src/Type/RepositoryTypeFactory.php',
|
||||
'Rector\\DowngradePhp71\\Rector\\Array_\\SymmetricArrayDestructuringToListRector' => $vendorDir . '/rector/rector-downgrade-php/rules/DowngradePhp71/Rector/Array_/SymmetricArrayDestructuringToListRector.php',
|
||||
'Rector\\DowngradePhp71\\Rector\\ClassConst\\DowngradeClassConstantVisibilityRector' => $vendorDir . '/rector/rector-downgrade-php/rules/DowngradePhp71/Rector/ClassConst/DowngradeClassConstantVisibilityRector.php',
|
||||
'Rector\\DowngradePhp71\\Rector\\ConstFetch\\DowngradePhp71JsonConstRector' => $vendorDir . '/rector/rector-downgrade-php/rules/DowngradePhp71/Rector/ConstFetch/DowngradePhp71JsonConstRector.php',
|
||||
|
10
vendor/composer/autoload_real.php
vendored
10
vendor/composer/autoload_real.php
vendored
@ -2,7 +2,7 @@
|
||||
|
||||
// autoload_real.php @generated by Composer
|
||||
|
||||
class ComposerAutoloaderInit4ec4b37318586aea9b7cf86e1eaf6d40
|
||||
class ComposerAutoloaderInitdeffc6913765d186a4f1f1f5dc9ffae4
|
||||
{
|
||||
private static $loader;
|
||||
|
||||
@ -22,17 +22,17 @@ class ComposerAutoloaderInit4ec4b37318586aea9b7cf86e1eaf6d40
|
||||
return self::$loader;
|
||||
}
|
||||
|
||||
spl_autoload_register(array('ComposerAutoloaderInit4ec4b37318586aea9b7cf86e1eaf6d40', 'loadClassLoader'), true, true);
|
||||
spl_autoload_register(array('ComposerAutoloaderInitdeffc6913765d186a4f1f1f5dc9ffae4', 'loadClassLoader'), true, true);
|
||||
self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__));
|
||||
spl_autoload_unregister(array('ComposerAutoloaderInit4ec4b37318586aea9b7cf86e1eaf6d40', 'loadClassLoader'));
|
||||
spl_autoload_unregister(array('ComposerAutoloaderInitdeffc6913765d186a4f1f1f5dc9ffae4', 'loadClassLoader'));
|
||||
|
||||
require __DIR__ . '/autoload_static.php';
|
||||
call_user_func(\Composer\Autoload\ComposerStaticInit4ec4b37318586aea9b7cf86e1eaf6d40::getInitializer($loader));
|
||||
call_user_func(\Composer\Autoload\ComposerStaticInitdeffc6913765d186a4f1f1f5dc9ffae4::getInitializer($loader));
|
||||
|
||||
$loader->setClassMapAuthoritative(true);
|
||||
$loader->register(true);
|
||||
|
||||
$filesToLoad = \Composer\Autoload\ComposerStaticInit4ec4b37318586aea9b7cf86e1eaf6d40::$files;
|
||||
$filesToLoad = \Composer\Autoload\ComposerStaticInitdeffc6913765d186a4f1f1f5dc9ffae4::$files;
|
||||
$requireFile = \Closure::bind(static function ($fileIdentifier, $file) {
|
||||
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
|
||||
$GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
|
||||
|
20
vendor/composer/autoload_static.php
vendored
20
vendor/composer/autoload_static.php
vendored
@ -4,7 +4,7 @@
|
||||
|
||||
namespace Composer\Autoload;
|
||||
|
||||
class ComposerStaticInit4ec4b37318586aea9b7cf86e1eaf6d40
|
||||
class ComposerStaticInitdeffc6913765d186a4f1f1f5dc9ffae4
|
||||
{
|
||||
public static $files = array (
|
||||
'ad155f8f1cf0d418fe49e248db8c661b' => __DIR__ . '/..' . '/react/promise/src/functions_include.php',
|
||||
@ -2004,12 +2004,9 @@ class ComposerStaticInit4ec4b37318586aea9b7cf86e1eaf6d40
|
||||
'Rector\\Doctrine\\NodeAnalyzer\\AttributeFinder' => __DIR__ . '/..' . '/rector/rector-doctrine/src/NodeAnalyzer/AttributeFinder.php',
|
||||
'Rector\\Doctrine\\NodeAnalyzer\\AttrinationFinder' => __DIR__ . '/..' . '/rector/rector-doctrine/src/NodeAnalyzer/AttrinationFinder.php',
|
||||
'Rector\\Doctrine\\NodeAnalyzer\\ConstructorAssignPropertyAnalyzer' => __DIR__ . '/..' . '/rector/rector-doctrine/src/NodeAnalyzer/ConstructorAssignPropertyAnalyzer.php',
|
||||
'Rector\\Doctrine\\NodeAnalyzer\\EntityObjectTypeResolver' => __DIR__ . '/..' . '/rector/rector-doctrine/src/NodeAnalyzer/EntityObjectTypeResolver.php',
|
||||
'Rector\\Doctrine\\NodeAnalyzer\\SetterClassMethodAnalyzer' => __DIR__ . '/..' . '/rector/rector-doctrine/src/NodeAnalyzer/SetterClassMethodAnalyzer.php',
|
||||
'Rector\\Doctrine\\NodeAnalyzer\\TargetEntityResolver' => __DIR__ . '/..' . '/rector/rector-doctrine/src/NodeAnalyzer/TargetEntityResolver.php',
|
||||
'Rector\\Doctrine\\NodeFactory\\ArrayCollectionAssignFactory' => __DIR__ . '/..' . '/rector/rector-doctrine/src/NodeFactory/ArrayCollectionAssignFactory.php',
|
||||
'Rector\\Doctrine\\NodeFactory\\RepositoryAssignFactory' => __DIR__ . '/..' . '/rector/rector-doctrine/src/NodeFactory/RepositoryAssignFactory.php',
|
||||
'Rector\\Doctrine\\NodeFactory\\RepositoryNodeFactory' => __DIR__ . '/..' . '/rector/rector-doctrine/src/NodeFactory/RepositoryNodeFactory.php',
|
||||
'Rector\\Doctrine\\NodeFactory\\ValueAssignFactory' => __DIR__ . '/..' . '/rector/rector-doctrine/src/NodeFactory/ValueAssignFactory.php',
|
||||
'Rector\\Doctrine\\NodeManipulator\\ColumnPropertyTypeResolver' => __DIR__ . '/..' . '/rector/rector-doctrine/src/NodeManipulator/ColumnPropertyTypeResolver.php',
|
||||
'Rector\\Doctrine\\NodeManipulator\\ConstructorManipulator' => __DIR__ . '/..' . '/rector/rector-doctrine/src/NodeManipulator/ConstructorManipulator.php',
|
||||
@ -2017,22 +2014,15 @@ class ComposerStaticInit4ec4b37318586aea9b7cf86e1eaf6d40
|
||||
'Rector\\Doctrine\\NodeManipulator\\PropertyTypeManipulator' => __DIR__ . '/..' . '/rector/rector-doctrine/src/NodeManipulator/PropertyTypeManipulator.php',
|
||||
'Rector\\Doctrine\\NodeManipulator\\ToManyRelationPropertyTypeResolver' => __DIR__ . '/..' . '/rector/rector-doctrine/src/NodeManipulator/ToManyRelationPropertyTypeResolver.php',
|
||||
'Rector\\Doctrine\\NodeManipulator\\ToOneRelationPropertyTypeResolver' => __DIR__ . '/..' . '/rector/rector-doctrine/src/NodeManipulator/ToOneRelationPropertyTypeResolver.php',
|
||||
'Rector\\Doctrine\\Orm214\\Rector\\Param\\ReplaceLifecycleEventArgsByDedicatedEventArgsRector' => __DIR__ . '/..' . '/rector/rector-doctrine/rules/Orm214/Rector/Param/ReplaceLifecycleEventArgsByDedicatedEventArgsRector.php',
|
||||
'Rector\\Doctrine\\PhpDocParser\\DoctrineClassAnnotationMatcher' => __DIR__ . '/..' . '/rector/rector-doctrine/src/PhpDocParser/DoctrineClassAnnotationMatcher.php',
|
||||
'Rector\\Doctrine\\PhpDocParser\\DoctrineDocBlockResolver' => __DIR__ . '/..' . '/rector/rector-doctrine/src/PhpDocParser/DoctrineDocBlockResolver.php',
|
||||
'Rector\\Doctrine\\PhpDoc\\ShortClassExpander' => __DIR__ . '/..' . '/rector/rector-doctrine/src/PhpDoc/ShortClassExpander.php',
|
||||
'Rector\\Doctrine\\Rector\\ClassMethod\\ServiceEntityRepositoryParentCallToDIRector' => __DIR__ . '/..' . '/rector/rector-doctrine/src/Rector/ClassMethod/ServiceEntityRepositoryParentCallToDIRector.php',
|
||||
'Rector\\Doctrine\\Rector\\Class_\\MoveRepositoryFromParentToConstructorRector' => __DIR__ . '/..' . '/rector/rector-doctrine/src/Rector/Class_/MoveRepositoryFromParentToConstructorRector.php',
|
||||
'Rector\\Doctrine\\Rector\\Class_\\RemoveRepositoryFromEntityAnnotationRector' => __DIR__ . '/..' . '/rector/rector-doctrine/src/Rector/Class_/RemoveRepositoryFromEntityAnnotationRector.php',
|
||||
'Rector\\Doctrine\\Rector\\MethodCall\\EntityAliasToClassConstantReferenceRector' => __DIR__ . '/..' . '/rector/rector-doctrine/src/Rector/MethodCall/EntityAliasToClassConstantReferenceRector.php',
|
||||
'Rector\\Doctrine\\Rector\\MethodCall\\ReplaceParentRepositoryCallsByRepositoryPropertyRector' => __DIR__ . '/..' . '/rector/rector-doctrine/src/Rector/MethodCall/ReplaceParentRepositoryCallsByRepositoryPropertyRector.php',
|
||||
'Rector\\Doctrine\\Rector\\Param\\ReplaceLifecycleEventArgsByDedicatedEventArgsRector' => __DIR__ . '/..' . '/rector/rector-doctrine/src/Rector/Param/ReplaceLifecycleEventArgsByDedicatedEventArgsRector.php',
|
||||
'Rector\\Doctrine\\Set\\DoctrineSetList' => __DIR__ . '/..' . '/rector/rector-doctrine/src/Set/DoctrineSetList.php',
|
||||
'Rector\\Doctrine\\TypeAnalyzer\\CollectionTypeFactory' => __DIR__ . '/..' . '/rector/rector-doctrine/src/TypeAnalyzer/CollectionTypeFactory.php',
|
||||
'Rector\\Doctrine\\TypeAnalyzer\\CollectionTypeResolver' => __DIR__ . '/..' . '/rector/rector-doctrine/src/TypeAnalyzer/CollectionTypeResolver.php',
|
||||
'Rector\\Doctrine\\TypeAnalyzer\\CollectionVarTagValueNodeResolver' => __DIR__ . '/..' . '/rector/rector-doctrine/src/TypeAnalyzer/CollectionVarTagValueNodeResolver.php',
|
||||
'Rector\\Doctrine\\TypeAnalyzer\\DoctrineCollectionTypeAnalyzer' => __DIR__ . '/..' . '/rector/rector-doctrine/src/TypeAnalyzer/DoctrineCollectionTypeAnalyzer.php',
|
||||
'Rector\\Doctrine\\TypeAnalyzer\\TypeFinder' => __DIR__ . '/..' . '/rector/rector-doctrine/src/TypeAnalyzer/TypeFinder.php',
|
||||
'Rector\\Doctrine\\Type\\RepositoryTypeFactory' => __DIR__ . '/..' . '/rector/rector-doctrine/src/Type/RepositoryTypeFactory.php',
|
||||
'Rector\\DowngradePhp71\\Rector\\Array_\\SymmetricArrayDestructuringToListRector' => __DIR__ . '/..' . '/rector/rector-downgrade-php/rules/DowngradePhp71/Rector/Array_/SymmetricArrayDestructuringToListRector.php',
|
||||
'Rector\\DowngradePhp71\\Rector\\ClassConst\\DowngradeClassConstantVisibilityRector' => __DIR__ . '/..' . '/rector/rector-downgrade-php/rules/DowngradePhp71/Rector/ClassConst/DowngradeClassConstantVisibilityRector.php',
|
||||
'Rector\\DowngradePhp71\\Rector\\ConstFetch\\DowngradePhp71JsonConstRector' => __DIR__ . '/..' . '/rector/rector-downgrade-php/rules/DowngradePhp71/Rector/ConstFetch/DowngradePhp71JsonConstRector.php',
|
||||
@ -3037,9 +3027,9 @@ class ComposerStaticInit4ec4b37318586aea9b7cf86e1eaf6d40
|
||||
public static function getInitializer(ClassLoader $loader)
|
||||
{
|
||||
return \Closure::bind(function () use ($loader) {
|
||||
$loader->prefixLengthsPsr4 = ComposerStaticInit4ec4b37318586aea9b7cf86e1eaf6d40::$prefixLengthsPsr4;
|
||||
$loader->prefixDirsPsr4 = ComposerStaticInit4ec4b37318586aea9b7cf86e1eaf6d40::$prefixDirsPsr4;
|
||||
$loader->classMap = ComposerStaticInit4ec4b37318586aea9b7cf86e1eaf6d40::$classMap;
|
||||
$loader->prefixLengthsPsr4 = ComposerStaticInitdeffc6913765d186a4f1f1f5dc9ffae4::$prefixLengthsPsr4;
|
||||
$loader->prefixDirsPsr4 = ComposerStaticInitdeffc6913765d186a4f1f1f5dc9ffae4::$prefixDirsPsr4;
|
||||
$loader->classMap = ComposerStaticInitdeffc6913765d186a4f1f1f5dc9ffae4::$classMap;
|
||||
|
||||
}, null, ClassLoader::class);
|
||||
}
|
||||
|
8
vendor/composer/installed.json
vendored
8
vendor/composer/installed.json
vendored
@ -1917,12 +1917,12 @@
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https:\/\/github.com\/rectorphp\/rector-doctrine.git",
|
||||
"reference": "6af6be50bb83c3608e2a9472fb8b0b50d55bb4ff"
|
||||
"reference": "95e66a62877d61085533aaba3a8913eeda6c2b91"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https:\/\/api.github.com\/repos\/rectorphp\/rector-doctrine\/zipball\/6af6be50bb83c3608e2a9472fb8b0b50d55bb4ff",
|
||||
"reference": "6af6be50bb83c3608e2a9472fb8b0b50d55bb4ff",
|
||||
"url": "https:\/\/api.github.com\/repos\/rectorphp\/rector-doctrine\/zipball\/95e66a62877d61085533aaba3a8913eeda6c2b91",
|
||||
"reference": "95e66a62877d61085533aaba3a8913eeda6c2b91",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -1947,7 +1947,7 @@
|
||||
"tomasvotruba\/type-coverage": "^0.2",
|
||||
"tomasvotruba\/unused-public": "^0.1"
|
||||
},
|
||||
"time": "2023-07-13T16:00:12+00:00",
|
||||
"time": "2023-07-13T20:19:23+00:00",
|
||||
"default-branch": true,
|
||||
"type": "rector-extension",
|
||||
"extra": {
|
||||
|
2
vendor/composer/installed.php
vendored
2
vendor/composer/installed.php
vendored
File diff suppressed because one or more lines are too long
@ -9,7 +9,7 @@ namespace Rector\RectorInstaller;
|
||||
*/
|
||||
final class GeneratedConfig
|
||||
{
|
||||
public const EXTENSIONS = array('rector/rector-doctrine' => array('install_path' => '/home/runner/work/rector-src/rector-src/vendor/rector/rector-doctrine', 'relative_install_path' => '../../rector-doctrine', 'extra' => array('includes' => array(0 => 'config/config.php')), 'version' => 'dev-main 6af6be5'), 'rector/rector-downgrade-php' => array('install_path' => '/home/runner/work/rector-src/rector-src/vendor/rector/rector-downgrade-php', 'relative_install_path' => '../../rector-downgrade-php', 'extra' => array('includes' => array(0 => 'config/config.php')), 'version' => 'dev-main 734960f'), 'rector/rector-phpunit' => array('install_path' => '/home/runner/work/rector-src/rector-src/vendor/rector/rector-phpunit', 'relative_install_path' => '../../rector-phpunit', 'extra' => array('includes' => array(0 => 'config/config.php')), 'version' => 'dev-main 59b84b7'), 'rector/rector-symfony' => array('install_path' => '/home/runner/work/rector-src/rector-src/vendor/rector/rector-symfony', 'relative_install_path' => '../../rector-symfony', 'extra' => array('includes' => array(0 => 'config/config.php')), 'version' => 'dev-main e788554'));
|
||||
public const EXTENSIONS = array('rector/rector-doctrine' => array('install_path' => '/home/runner/work/rector-src/rector-src/vendor/rector/rector-doctrine', 'relative_install_path' => '../../rector-doctrine', 'extra' => array('includes' => array(0 => 'config/config.php')), 'version' => 'dev-main 95e66a6'), 'rector/rector-downgrade-php' => array('install_path' => '/home/runner/work/rector-src/rector-src/vendor/rector/rector-downgrade-php', 'relative_install_path' => '../../rector-downgrade-php', 'extra' => array('includes' => array(0 => 'config/config.php')), 'version' => 'dev-main 734960f'), 'rector/rector-phpunit' => array('install_path' => '/home/runner/work/rector-src/rector-src/vendor/rector/rector-phpunit', 'relative_install_path' => '../../rector-phpunit', 'extra' => array('includes' => array(0 => 'config/config.php')), 'version' => 'dev-main 59b84b7'), 'rector/rector-symfony' => array('install_path' => '/home/runner/work/rector-src/rector-src/vendor/rector/rector-symfony', 'relative_install_path' => '../../rector-symfony', 'extra' => array('includes' => array(0 => 'config/config.php')), 'version' => 'dev-main e788554'));
|
||||
private function __construct()
|
||||
{
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ declare (strict_types=1);
|
||||
namespace RectorPrefix202307;
|
||||
|
||||
use Rector\Config\RectorConfig;
|
||||
use Rector\Doctrine\Rector\Param\ReplaceLifecycleEventArgsByDedicatedEventArgsRector;
|
||||
use Rector\Doctrine\Orm214\Rector\Param\ReplaceLifecycleEventArgsByDedicatedEventArgsRector;
|
||||
return static function (RectorConfig $rectorConfig) : void {
|
||||
$rectorConfig->rule(ReplaceLifecycleEventArgsByDedicatedEventArgsRector::class);
|
||||
};
|
||||
|
@ -4,38 +4,12 @@ declare (strict_types=1);
|
||||
namespace RectorPrefix202307;
|
||||
|
||||
use Rector\Config\RectorConfig;
|
||||
use Rector\DeadCode\Rector\ClassLike\RemoveAnnotationRector;
|
||||
use Rector\Doctrine\Rector\Class_\MoveRepositoryFromParentToConstructorRector;
|
||||
use Rector\Doctrine\Rector\Class_\RemoveRepositoryFromEntityAnnotationRector;
|
||||
use Rector\Doctrine\Rector\ClassMethod\ServiceEntityRepositoryParentCallToDIRector;
|
||||
use Rector\Doctrine\Rector\MethodCall\ReplaceParentRepositoryCallsByRepositoryPropertyRector;
|
||||
use Rector\Removing\Rector\Class_\RemoveParentRector;
|
||||
use Rector\Renaming\Rector\PropertyFetch\RenamePropertyRector;
|
||||
use Rector\Renaming\ValueObject\RenameProperty;
|
||||
use Rector\Transform\Rector\MethodCall\MethodCallToPropertyFetchRector;
|
||||
use Rector\Transform\Rector\MethodCall\ReplaceParentCallByPropertyCallRector;
|
||||
use Rector\Transform\ValueObject\MethodCallToPropertyFetch;
|
||||
use Rector\Transform\ValueObject\ReplaceParentCallByPropertyCall;
|
||||
/**
|
||||
* @deprecated Removed as not supporting the framework native approach and rather experimental.
|
||||
*
|
||||
* @see https://tomasvotruba.com/blog/2017/10/16/how-to-use-repository-with-doctrine-as-service-in-symfony/
|
||||
* @see https://tomasvotruba.com/blog/2018/04/02/rectify-turn-repositories-to-services-in-symfony/
|
||||
* @see https://getrector.com/blog/2021/02/08/how-to-instantly-decouple-symfony-doctrine-repository-inheritance-to-clean-composition
|
||||
*/
|
||||
return static function (RectorConfig $rectorConfig) : void {
|
||||
# order matters, this needs to be first to correctly detect parent repository
|
||||
// covers "extends EntityRepository"
|
||||
$rectorConfig->rules([
|
||||
MoveRepositoryFromParentToConstructorRector::class,
|
||||
ReplaceParentRepositoryCallsByRepositoryPropertyRector::class,
|
||||
RemoveRepositoryFromEntityAnnotationRector::class,
|
||||
// covers "extends ServiceEntityRepository"
|
||||
// @see https://github.com/doctrine/DoctrineBundle/pull/727/files
|
||||
ServiceEntityRepositoryParentCallToDIRector::class,
|
||||
]);
|
||||
$rectorConfig->ruleWithConfiguration(RenamePropertyRector::class, [new RenameProperty('Doctrine\\Bundle\\DoctrineBundle\\Repository\\ServiceEntityRepository', '_em', 'entityManager')]);
|
||||
$rectorConfig->ruleWithConfiguration(RemoveAnnotationRector::class, ['method']);
|
||||
$rectorConfig->ruleWithConfiguration(ReplaceParentCallByPropertyCallRector::class, [new ReplaceParentCallByPropertyCall('Doctrine\\Bundle\\DoctrineBundle\\Repository\\ServiceEntityRepository', 'createQueryBuilder', 'entityRepository'), new ReplaceParentCallByPropertyCall('Doctrine\\Bundle\\DoctrineBundle\\Repository\\ServiceEntityRepository', 'createResultSetMappingBuilder', 'entityRepository'), new ReplaceParentCallByPropertyCall('Doctrine\\Bundle\\DoctrineBundle\\Repository\\ServiceEntityRepository', 'clear', 'entityRepository'), new ReplaceParentCallByPropertyCall('Doctrine\\Bundle\\DoctrineBundle\\Repository\\ServiceEntityRepository', 'find', 'entityRepository'), new ReplaceParentCallByPropertyCall('Doctrine\\Bundle\\DoctrineBundle\\Repository\\ServiceEntityRepository', 'findBy', 'entityRepository'), new ReplaceParentCallByPropertyCall('Doctrine\\Bundle\\DoctrineBundle\\Repository\\ServiceEntityRepository', 'findAll', 'entityRepository'), new ReplaceParentCallByPropertyCall('Doctrine\\Bundle\\DoctrineBundle\\Repository\\ServiceEntityRepository', 'count', 'entityRepository'), new ReplaceParentCallByPropertyCall('Doctrine\\Bundle\\DoctrineBundle\\Repository\\ServiceEntityRepository', 'getClassName', 'entityRepository'), new ReplaceParentCallByPropertyCall('Doctrine\\Bundle\\DoctrineBundle\\Repository\\ServiceEntityRepository', 'matching', 'entityRepository')]);
|
||||
// @@todo
|
||||
$rectorConfig->ruleWithConfiguration(MethodCallToPropertyFetchRector::class, [new MethodCallToPropertyFetch('Doctrine\\Bundle\\DoctrineBundle\\Repository\\ServiceEntityRepository', 'getEntityManager', 'entityManager')]);
|
||||
$rectorConfig->ruleWithConfiguration(RemoveParentRector::class, ['Doctrine\\Bundle\\DoctrineBundle\\Repository\\ServiceEntityRepository']);
|
||||
};
|
||||
|
@ -1,4 +1,4 @@
|
||||
# 20 Rules Overview
|
||||
# 15 Rules Overview
|
||||
|
||||
## ChangeBigIntEntityPropertyToIntTypeRector
|
||||
|
||||
@ -95,41 +95,6 @@ Convert targetEntities defined as String to <class>::class Constants in Doctrine
|
||||
|
||||
<br>
|
||||
|
||||
## EntityAliasToClassConstantReferenceRector
|
||||
|
||||
Replaces doctrine alias with class.
|
||||
|
||||
:wrench: **configure it!**
|
||||
|
||||
- class: [`Rector\Doctrine\Rector\MethodCall\EntityAliasToClassConstantReferenceRector`](../src/Rector/MethodCall/EntityAliasToClassConstantReferenceRector.php)
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Rector\Config\RectorConfig;
|
||||
use Rector\Doctrine\Rector\MethodCall\EntityAliasToClassConstantReferenceRector;
|
||||
|
||||
return static function (RectorConfig $rectorConfig): void {
|
||||
$rectorConfig->ruleWithConfiguration(EntityAliasToClassConstantReferenceRector::class, [
|
||||
EntityAliasToClassConstantReferenceRector::ALIASES_TO_NAMESPACES => [
|
||||
'App' => 'App\Entity',
|
||||
],
|
||||
]);
|
||||
};
|
||||
```
|
||||
|
||||
↓
|
||||
|
||||
```diff
|
||||
$entityManager = new Doctrine\ORM\EntityManager();
|
||||
-$entityManager->getRepository("AppBundle:Post");
|
||||
+$entityManager->getRepository(\App\Entity\Post::class);
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
## ImproveDoctrineCollectionDocTypeInEntityRector
|
||||
|
||||
Improve @var, `@param` and `@return` types for Doctrine collections to make them useful both for PHPStan and PHPStorm
|
||||
@ -275,36 +240,6 @@ Move default value for entity property to constructor, the safest place
|
||||
|
||||
<br>
|
||||
|
||||
## MoveRepositoryFromParentToConstructorRector
|
||||
|
||||
Turns parent EntityRepository class to constructor dependency
|
||||
|
||||
- class: [`Rector\Doctrine\Rector\Class_\MoveRepositoryFromParentToConstructorRector`](../src/Rector/Class_/MoveRepositoryFromParentToConstructorRector.php)
|
||||
|
||||
```diff
|
||||
namespace App\Repository;
|
||||
|
||||
+use App\Entity\Post;
|
||||
use Doctrine\ORM\EntityRepository;
|
||||
+use Doctrine\ORM\EntityManagerInterface;
|
||||
|
||||
-final class PostRepository extends EntityRepository
|
||||
+final class PostRepository
|
||||
{
|
||||
+ /**
|
||||
+ * @var \Doctrine\ORM\EntityRepository<Post>
|
||||
+ */
|
||||
+ private EntityRepository $repository;
|
||||
+
|
||||
+ public function __construct(EntityManagerInterface $entityManager)
|
||||
+ {
|
||||
+ $this->repository = $entityManager->getRepository(Post::class);
|
||||
+ }
|
||||
}
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
## RemoveEmptyTableAttributeRector
|
||||
|
||||
Remove empty Table attribute on entities because it's useless
|
||||
@ -325,31 +260,11 @@ Remove empty Table attribute on entities because it's useless
|
||||
|
||||
<br>
|
||||
|
||||
## RemoveRepositoryFromEntityAnnotationRector
|
||||
|
||||
Removes repository class from `@Entity` annotation
|
||||
|
||||
- class: [`Rector\Doctrine\Rector\Class_\RemoveRepositoryFromEntityAnnotationRector`](../src/Rector/Class_/RemoveRepositoryFromEntityAnnotationRector.php)
|
||||
|
||||
```diff
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
|
||||
/**
|
||||
- * @ORM\Entity(repositoryClass="ProductRepository")
|
||||
+ * @ORM\Entity
|
||||
*/
|
||||
class Product
|
||||
{
|
||||
}
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
## ReplaceLifecycleEventArgsByDedicatedEventArgsRector
|
||||
|
||||
Replace `Doctrine\ORM\Event\LifecycleEventArgs` with specific event classes based on the function call
|
||||
|
||||
- class: [`Rector\Doctrine\Rector\Param\ReplaceLifecycleEventArgsByDedicatedEventArgsRector`](../src/Rector/Param/ReplaceLifecycleEventArgsByDedicatedEventArgsRector.php)
|
||||
- class: [`Rector\Doctrine\Orm214\Rector\Param\ReplaceLifecycleEventArgsByDedicatedEventArgsRector`](../rules/Orm214/Rector/Param/ReplaceLifecycleEventArgsByDedicatedEventArgsRector.php)
|
||||
|
||||
```diff
|
||||
-use Doctrine\ORM\Event\LifecycleEventArgs;
|
||||
@ -367,58 +282,6 @@ Replace `Doctrine\ORM\Event\LifecycleEventArgs` with specific event classes base
|
||||
|
||||
<br>
|
||||
|
||||
## ReplaceParentRepositoryCallsByRepositoryPropertyRector
|
||||
|
||||
Handles method calls in child of Doctrine EntityRepository and moves them to `$this->repository` property.
|
||||
|
||||
- class: [`Rector\Doctrine\Rector\MethodCall\ReplaceParentRepositoryCallsByRepositoryPropertyRector`](../src/Rector/MethodCall/ReplaceParentRepositoryCallsByRepositoryPropertyRector.php)
|
||||
|
||||
```diff
|
||||
use Doctrine\ORM\EntityRepository;
|
||||
|
||||
class SomeRepository extends EntityRepository
|
||||
{
|
||||
public function someMethod()
|
||||
{
|
||||
- return $this->findAll();
|
||||
+ return $this->repository->findAll();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
## ServiceEntityRepositoryParentCallToDIRector
|
||||
|
||||
Change ServiceEntityRepository to dependency injection, with repository property
|
||||
|
||||
- class: [`Rector\Doctrine\Rector\ClassMethod\ServiceEntityRepositoryParentCallToDIRector`](../src/Rector/ClassMethod/ServiceEntityRepositoryParentCallToDIRector.php)
|
||||
|
||||
```diff
|
||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||
use Doctrine\Persistence\ManagerRegistry;
|
||||
|
||||
final class ProjectRepository extends ServiceEntityRepository
|
||||
{
|
||||
- public function __construct(ManagerRegistry $registry)
|
||||
+ private \Doctrine\ORM\EntityManagerInterface $entityManager;
|
||||
+
|
||||
+ /**
|
||||
+ * @var \Doctrine\ORM\EntityRepository<Project>
|
||||
+ */
|
||||
+ private \Doctrine\ORM\EntityRepository $repository;
|
||||
+
|
||||
+ public function __construct(\Doctrine\ORM\EntityManagerInterface $entityManager)
|
||||
{
|
||||
- parent::__construct($registry, Project::class);
|
||||
+ $this->repository = $entityManager->getRepository(Project::class);
|
||||
+ $this->entityManager = $entityManager;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
## TypedPropertyFromColumnTypeRector
|
||||
|
||||
Complete `@var` annotations or types based on @ORM\Column
|
||||
|
@ -1,7 +1,7 @@
|
||||
<?php
|
||||
|
||||
declare (strict_types=1);
|
||||
namespace Rector\Doctrine\Rector\Param;
|
||||
namespace Rector\Doctrine\Orm214\Rector\Param;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Name\FullyQualified;
|
||||
@ -12,7 +12,7 @@ use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
|
||||
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||
/**
|
||||
* @see https://github.com/doctrine/orm/pull/10086
|
||||
* @see \Rector\Doctrine\Tests\Rector\Param\ReplaceLifecycleEventArgsByDedicatedEventArgsRector\ReplaceLifecycleEventArgsByDedicatedEventArgsRectorTest
|
||||
* @see \Rector\Doctrine\Tests\Orm214\Rector\Param\ReplaceLifecycleEventArgsByDedicatedEventArgsRector\ReplaceLifecycleEventArgsByDedicatedEventArgsRectorTest
|
||||
*/
|
||||
final class ReplaceLifecycleEventArgsByDedicatedEventArgsRector extends AbstractRector
|
||||
{
|
@ -1,113 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare (strict_types=1);
|
||||
namespace Rector\Doctrine\NodeAnalyzer;
|
||||
|
||||
use PhpParser\Node\Arg;
|
||||
use PhpParser\Node\Expr;
|
||||
use PhpParser\Node\Expr\ClassConstFetch;
|
||||
use PhpParser\Node\Expr\StaticCall;
|
||||
use PhpParser\Node\Stmt\Class_;
|
||||
use PhpParser\Node\Stmt\ClassMethod;
|
||||
use PhpParser\Node\Stmt\Expression;
|
||||
use PHPStan\Type\MixedType;
|
||||
use PHPStan\Type\ObjectType;
|
||||
use PHPStan\Type\SubtractableType;
|
||||
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory;
|
||||
use Rector\Core\ValueObject\MethodName;
|
||||
use Rector\Doctrine\TypeAnalyzer\TypeFinder;
|
||||
use Rector\NodeNameResolver\NodeNameResolver;
|
||||
final class EntityObjectTypeResolver
|
||||
{
|
||||
/**
|
||||
* @readonly
|
||||
* @var \Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory
|
||||
*/
|
||||
private $phpDocInfoFactory;
|
||||
/**
|
||||
* @readonly
|
||||
* @var \Rector\Doctrine\TypeAnalyzer\TypeFinder
|
||||
*/
|
||||
private $typeFinder;
|
||||
/**
|
||||
* @readonly
|
||||
* @var \Rector\NodeNameResolver\NodeNameResolver
|
||||
*/
|
||||
private $nodeNameResolver;
|
||||
public function __construct(PhpDocInfoFactory $phpDocInfoFactory, TypeFinder $typeFinder, NodeNameResolver $nodeNameResolver)
|
||||
{
|
||||
$this->phpDocInfoFactory = $phpDocInfoFactory;
|
||||
$this->typeFinder = $typeFinder;
|
||||
$this->nodeNameResolver = $nodeNameResolver;
|
||||
}
|
||||
public function resolveFromRepositoryClass(Class_ $repositoryClass) : SubtractableType
|
||||
{
|
||||
$subtractableType = $this->resolveFromParentConstruct($repositoryClass);
|
||||
if (!$subtractableType instanceof MixedType) {
|
||||
return $subtractableType;
|
||||
}
|
||||
$getterReturnType = $this->resolveFromGetterReturnType($repositoryClass);
|
||||
if (!$getterReturnType instanceof MixedType) {
|
||||
return $getterReturnType;
|
||||
}
|
||||
return new MixedType();
|
||||
}
|
||||
private function resolveFromGetterReturnType(Class_ $repositoryClass) : SubtractableType
|
||||
{
|
||||
foreach ($repositoryClass->getMethods() as $classMethod) {
|
||||
if (!$classMethod->isPublic()) {
|
||||
continue;
|
||||
}
|
||||
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($classMethod);
|
||||
$returnType = $phpDocInfo->getReturnType();
|
||||
$objectType = $this->typeFinder->find($returnType, ObjectType::class);
|
||||
if (!$objectType instanceof ObjectType) {
|
||||
continue;
|
||||
}
|
||||
return $objectType;
|
||||
}
|
||||
return new MixedType();
|
||||
}
|
||||
private function resolveFromParentConstruct(Class_ $class) : SubtractableType
|
||||
{
|
||||
$constructorClassMethod = $class->getMethod(MethodName::CONSTRUCT);
|
||||
if (!$constructorClassMethod instanceof ClassMethod) {
|
||||
return new MixedType();
|
||||
}
|
||||
foreach ((array) $constructorClassMethod->stmts as $stmt) {
|
||||
if (!$stmt instanceof Expression) {
|
||||
continue;
|
||||
}
|
||||
$argValue = $this->resolveParentConstructSecondArgument($stmt->expr);
|
||||
if (!$argValue instanceof ClassConstFetch) {
|
||||
continue;
|
||||
}
|
||||
if (!$this->nodeNameResolver->isName($argValue->name, 'class')) {
|
||||
continue;
|
||||
}
|
||||
$className = $this->nodeNameResolver->getName($argValue->class);
|
||||
if ($className === null) {
|
||||
continue;
|
||||
}
|
||||
return new ObjectType($className);
|
||||
}
|
||||
return new MixedType();
|
||||
}
|
||||
private function resolveParentConstructSecondArgument(Expr $expr) : ?Expr
|
||||
{
|
||||
if (!$expr instanceof StaticCall) {
|
||||
return null;
|
||||
}
|
||||
if (!$this->nodeNameResolver->isName($expr->class, 'parent')) {
|
||||
return null;
|
||||
}
|
||||
if (!$this->nodeNameResolver->isName($expr->name, MethodName::CONSTRUCT)) {
|
||||
return null;
|
||||
}
|
||||
$secondArg = $expr->args[1] ?? null;
|
||||
if (!$secondArg instanceof Arg) {
|
||||
return null;
|
||||
}
|
||||
return $secondArg->value;
|
||||
}
|
||||
}
|
@ -1,54 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare (strict_types=1);
|
||||
namespace Rector\Doctrine\NodeFactory;
|
||||
|
||||
use PhpParser\Node\Expr\Assign;
|
||||
use PhpParser\Node\Stmt\Class_;
|
||||
use PHPStan\Type\TypeWithClassName;
|
||||
use Rector\Core\Exception\ShouldNotHappenException;
|
||||
use Rector\Core\PhpParser\Node\NodeFactory;
|
||||
use Rector\Doctrine\NodeAnalyzer\EntityObjectTypeResolver;
|
||||
use Rector\NodeNameResolver\NodeNameResolver;
|
||||
final class RepositoryAssignFactory
|
||||
{
|
||||
/**
|
||||
* @readonly
|
||||
* @var \Rector\Doctrine\NodeAnalyzer\EntityObjectTypeResolver
|
||||
*/
|
||||
private $entityObjectTypeResolver;
|
||||
/**
|
||||
* @readonly
|
||||
* @var \Rector\NodeNameResolver\NodeNameResolver
|
||||
*/
|
||||
private $nodeNameResolver;
|
||||
/**
|
||||
* @readonly
|
||||
* @var \Rector\Core\PhpParser\Node\NodeFactory
|
||||
*/
|
||||
private $nodeFactory;
|
||||
public function __construct(EntityObjectTypeResolver $entityObjectTypeResolver, NodeNameResolver $nodeNameResolver, NodeFactory $nodeFactory)
|
||||
{
|
||||
$this->entityObjectTypeResolver = $entityObjectTypeResolver;
|
||||
$this->nodeNameResolver = $nodeNameResolver;
|
||||
$this->nodeFactory = $nodeFactory;
|
||||
}
|
||||
/**
|
||||
* Creates: "$this->repository = $entityManager->getRepository(SomeEntityClass::class)"
|
||||
*/
|
||||
public function create(Class_ $repositoryClass) : Assign
|
||||
{
|
||||
$subtractableType = $this->entityObjectTypeResolver->resolveFromRepositoryClass($repositoryClass);
|
||||
$className = $this->nodeNameResolver->getName($repositoryClass);
|
||||
if (!\is_string($className)) {
|
||||
throw new ShouldNotHappenException();
|
||||
}
|
||||
$repositoryClassName = $className;
|
||||
if (!$subtractableType instanceof TypeWithClassName) {
|
||||
throw new ShouldNotHappenException(\sprintf('An entity was not found for "%s" repository.', $repositoryClassName));
|
||||
}
|
||||
$classConstFetch = $this->nodeFactory->createClassConstReference($subtractableType->getClassName());
|
||||
$methodCall = $this->nodeFactory->createMethodCall('entityManager', 'getRepository', [$classConstFetch]);
|
||||
return $this->nodeFactory->createPropertyAssignmentWithExpr('repository', $methodCall);
|
||||
}
|
||||
}
|
@ -1,25 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare (strict_types=1);
|
||||
namespace Rector\Doctrine\NodeFactory;
|
||||
|
||||
use PhpParser\Node\Arg;
|
||||
use PhpParser\Node\Expr;
|
||||
use PhpParser\Node\Expr\Assign;
|
||||
use PhpParser\Node\Expr\MethodCall;
|
||||
use PhpParser\Node\Expr\PropertyFetch;
|
||||
use PhpParser\Node\Expr\Variable;
|
||||
use PhpParser\Node\Identifier;
|
||||
final class RepositoryNodeFactory
|
||||
{
|
||||
public function createRepositoryAssign(Expr $entityReferenceExpr) : Assign
|
||||
{
|
||||
$propertyFetch = new PropertyFetch(new Variable('this'), new Identifier('repository'));
|
||||
return new Assign($propertyFetch, $this->createGetRepositoryMethodCall($entityReferenceExpr));
|
||||
}
|
||||
private function createGetRepositoryMethodCall(Expr $entityReferenceExpr) : MethodCall
|
||||
{
|
||||
$args = [new Arg($entityReferenceExpr)];
|
||||
return new MethodCall(new Variable('entityManager'), 'getRepository', $args);
|
||||
}
|
||||
}
|
@ -1,182 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare (strict_types=1);
|
||||
namespace Rector\Doctrine\Rector\ClassMethod;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Expr;
|
||||
use PhpParser\Node\Expr\StaticCall;
|
||||
use PhpParser\Node\Stmt\Class_;
|
||||
use PhpParser\Node\Stmt\ClassMethod;
|
||||
use PhpParser\Node\Stmt\Expression;
|
||||
use PhpParser\Node\Stmt\Property;
|
||||
use PHPStan\Analyser\Scope;
|
||||
use PHPStan\Reflection\ClassReflection;
|
||||
use PHPStan\Type\ObjectType;
|
||||
use Rector\Core\NodeManipulator\ClassDependencyManipulator;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Rector\Core\ValueObject\MethodName;
|
||||
use Rector\Doctrine\NodeFactory\RepositoryNodeFactory;
|
||||
use Rector\Doctrine\Type\RepositoryTypeFactory;
|
||||
use Rector\Naming\Naming\PropertyNaming;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
use Rector\PostRector\ValueObject\PropertyMetadata;
|
||||
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
|
||||
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||
/**
|
||||
* @see https://tomasvotruba.com/blog/2017/10/16/how-to-use-repository-with-doctrine-as-service-in-symfony/
|
||||
* @see https://getrector.com/blog/2021/02/08/how-to-instantly-decouple-symfony-doctrine-repository-inheritance-to-clean-composition
|
||||
*
|
||||
* @see \Rector\Doctrine\Tests\Rector\ClassMethod\ServiceEntityRepositoryParentCallToDIRector\ServiceEntityRepositoryParentCallToDIRectorTest
|
||||
*/
|
||||
final class ServiceEntityRepositoryParentCallToDIRector extends AbstractRector
|
||||
{
|
||||
/**
|
||||
* @readonly
|
||||
* @var \Rector\Doctrine\NodeFactory\RepositoryNodeFactory
|
||||
*/
|
||||
private $repositoryNodeFactory;
|
||||
/**
|
||||
* @readonly
|
||||
* @var \Rector\Doctrine\Type\RepositoryTypeFactory
|
||||
*/
|
||||
private $repositoryTypeFactory;
|
||||
/**
|
||||
* @readonly
|
||||
* @var \Rector\Core\NodeManipulator\ClassDependencyManipulator
|
||||
*/
|
||||
private $classDependencyManipulator;
|
||||
/**
|
||||
* @readonly
|
||||
* @var \Rector\Naming\Naming\PropertyNaming
|
||||
*/
|
||||
private $propertyNaming;
|
||||
public function __construct(RepositoryNodeFactory $repositoryNodeFactory, RepositoryTypeFactory $repositoryTypeFactory, ClassDependencyManipulator $classDependencyManipulator, PropertyNaming $propertyNaming)
|
||||
{
|
||||
$this->repositoryNodeFactory = $repositoryNodeFactory;
|
||||
$this->repositoryTypeFactory = $repositoryTypeFactory;
|
||||
$this->classDependencyManipulator = $classDependencyManipulator;
|
||||
$this->propertyNaming = $propertyNaming;
|
||||
}
|
||||
public function getRuleDefinition() : RuleDefinition
|
||||
{
|
||||
return new RuleDefinition('Change ServiceEntityRepository to dependency injection, with repository property', [new CodeSample(<<<'CODE_SAMPLE'
|
||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||
use Doctrine\Persistence\ManagerRegistry;
|
||||
|
||||
final class ProjectRepository extends ServiceEntityRepository
|
||||
{
|
||||
public function __construct(ManagerRegistry $registry)
|
||||
{
|
||||
parent::__construct($registry, Project::class);
|
||||
}
|
||||
}
|
||||
CODE_SAMPLE
|
||||
, <<<'CODE_SAMPLE'
|
||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||
use Doctrine\Persistence\ManagerRegistry;
|
||||
|
||||
final class ProjectRepository extends ServiceEntityRepository
|
||||
{
|
||||
private \Doctrine\ORM\EntityManagerInterface $entityManager;
|
||||
|
||||
/**
|
||||
* @var \Doctrine\ORM\EntityRepository<Project>
|
||||
*/
|
||||
private \Doctrine\ORM\EntityRepository $repository;
|
||||
|
||||
public function __construct(\Doctrine\ORM\EntityManagerInterface $entityManager)
|
||||
{
|
||||
$this->repository = $entityManager->getRepository(Project::class);
|
||||
$this->entityManager = $entityManager;
|
||||
}
|
||||
}
|
||||
CODE_SAMPLE
|
||||
)]);
|
||||
}
|
||||
/**
|
||||
* @return array<class-string<Node>>
|
||||
*/
|
||||
public function getNodeTypes() : array
|
||||
{
|
||||
return [Class_::class];
|
||||
}
|
||||
/**
|
||||
* @param Class_ $node
|
||||
*
|
||||
* For reference, possible manager registry param types:
|
||||
*
|
||||
* - Doctrine\Common\Persistence\ManagerRegistry
|
||||
* - Doctrine\Persistence\ManagerRegistry
|
||||
*/
|
||||
public function refactor(Node $node) : ?Node
|
||||
{
|
||||
$constructClassMethod = $node->getMethod(MethodName::CONSTRUCT);
|
||||
if (!$constructClassMethod instanceof ClassMethod) {
|
||||
return null;
|
||||
}
|
||||
$classScope = $node->getAttribute(AttributeKey::SCOPE);
|
||||
if (!$classScope instanceof Scope) {
|
||||
return null;
|
||||
}
|
||||
$classReflection = $classScope->getClassReflection();
|
||||
if (!$classReflection instanceof ClassReflection) {
|
||||
return null;
|
||||
}
|
||||
if (!$classReflection->isSubclassOf('Doctrine\\Bundle\\DoctrineBundle\\Repository\\ServiceEntityRepository')) {
|
||||
return null;
|
||||
}
|
||||
// 1. remove parent::__construct()
|
||||
$entityReferenceExpr = $this->removeParentConstructAndCollectEntityReference($constructClassMethod);
|
||||
if (!$entityReferenceExpr instanceof Expr) {
|
||||
return null;
|
||||
}
|
||||
// 2. remove params
|
||||
$constructClassMethod->params = [];
|
||||
// 3. add $entityManager->getRepository() fetch assign
|
||||
$repositoryAssign = $this->repositoryNodeFactory->createRepositoryAssign($entityReferenceExpr);
|
||||
$entityManagerObjectType = new ObjectType('Doctrine\\ORM\\EntityManagerInterface');
|
||||
$this->classDependencyManipulator->addConstructorDependencyWithCustomAssign($node, 'entityManager', $entityManagerObjectType, $repositoryAssign);
|
||||
$this->addRepositoryProperty($node, $entityReferenceExpr);
|
||||
// 5. add param + add property, dependency
|
||||
$propertyName = $this->propertyNaming->fqnToVariableName($entityManagerObjectType);
|
||||
// add property as first element
|
||||
$propertyMetadata = new PropertyMetadata($propertyName, $entityManagerObjectType);
|
||||
$this->classDependencyManipulator->addConstructorDependency($node, $propertyMetadata);
|
||||
return $node;
|
||||
}
|
||||
private function removeParentConstructAndCollectEntityReference(ClassMethod $classMethod) : ?Expr
|
||||
{
|
||||
if ($classMethod->stmts === null) {
|
||||
return null;
|
||||
}
|
||||
foreach ($classMethod->stmts as $key => $stmt) {
|
||||
if (!$stmt instanceof Expression) {
|
||||
continue;
|
||||
}
|
||||
if (!$stmt->expr instanceof StaticCall) {
|
||||
continue;
|
||||
}
|
||||
$staticCall = $stmt->expr;
|
||||
if (!$this->isName($staticCall->class, 'parent')) {
|
||||
continue;
|
||||
}
|
||||
if ($staticCall->isFirstClassCallable()) {
|
||||
continue;
|
||||
}
|
||||
unset($classMethod->stmts[$key]);
|
||||
$args = $staticCall->getArgs();
|
||||
return $args[1]->value;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
private function addRepositoryProperty(Class_ $class, Expr $entityReferenceExpr) : void
|
||||
{
|
||||
if ($class->getProperty('repository') instanceof Property) {
|
||||
return;
|
||||
}
|
||||
$genericObjectType = $this->repositoryTypeFactory->createRepositoryPropertyType($entityReferenceExpr);
|
||||
$property = $this->nodeFactory->createPrivatePropertyFromNameAndType('repository', $genericObjectType);
|
||||
$class->stmts = \array_merge([$property], $class->stmts);
|
||||
}
|
||||
}
|
@ -1,109 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare (strict_types=1);
|
||||
namespace Rector\Doctrine\Rector\Class_;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Name;
|
||||
use PhpParser\Node\Stmt\Class_;
|
||||
use PhpParser\Node\Stmt\Property;
|
||||
use PHPStan\Type\Generic\GenericObjectType;
|
||||
use PHPStan\Type\ObjectType;
|
||||
use Rector\Core\NodeManipulator\ClassDependencyManipulator;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Rector\Doctrine\NodeAnalyzer\EntityObjectTypeResolver;
|
||||
use Rector\Doctrine\NodeFactory\RepositoryAssignFactory;
|
||||
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
|
||||
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||
/**
|
||||
* @see \Rector\Doctrine\Tests\Set\DoctrineRepositoryAsServiceSet\DoctrineRepositoryAsServiceSetTest
|
||||
*/
|
||||
final class MoveRepositoryFromParentToConstructorRector extends AbstractRector
|
||||
{
|
||||
/**
|
||||
* @readonly
|
||||
* @var \Rector\Core\NodeManipulator\ClassDependencyManipulator
|
||||
*/
|
||||
private $classDependencyManipulator;
|
||||
/**
|
||||
* @readonly
|
||||
* @var \Rector\Doctrine\NodeFactory\RepositoryAssignFactory
|
||||
*/
|
||||
private $repositoryAssignFactory;
|
||||
/**
|
||||
* @readonly
|
||||
* @var \Rector\Doctrine\NodeAnalyzer\EntityObjectTypeResolver
|
||||
*/
|
||||
private $entityObjectTypeResolver;
|
||||
public function __construct(ClassDependencyManipulator $classDependencyManipulator, RepositoryAssignFactory $repositoryAssignFactory, EntityObjectTypeResolver $entityObjectTypeResolver)
|
||||
{
|
||||
$this->classDependencyManipulator = $classDependencyManipulator;
|
||||
$this->repositoryAssignFactory = $repositoryAssignFactory;
|
||||
$this->entityObjectTypeResolver = $entityObjectTypeResolver;
|
||||
}
|
||||
public function getRuleDefinition() : RuleDefinition
|
||||
{
|
||||
return new RuleDefinition('Turns parent EntityRepository class to constructor dependency', [new CodeSample(<<<'CODE_SAMPLE'
|
||||
namespace App\Repository;
|
||||
|
||||
use Doctrine\ORM\EntityRepository;
|
||||
|
||||
final class PostRepository extends EntityRepository
|
||||
{
|
||||
}
|
||||
CODE_SAMPLE
|
||||
, <<<'CODE_SAMPLE'
|
||||
namespace App\Repository;
|
||||
|
||||
use App\Entity\Post;
|
||||
use Doctrine\ORM\EntityRepository;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
|
||||
final class PostRepository
|
||||
{
|
||||
/**
|
||||
* @var \Doctrine\ORM\EntityRepository<Post>
|
||||
*/
|
||||
private EntityRepository $repository;
|
||||
|
||||
public function __construct(EntityManagerInterface $entityManager)
|
||||
{
|
||||
$this->repository = $entityManager->getRepository(Post::class);
|
||||
}
|
||||
}
|
||||
CODE_SAMPLE
|
||||
)]);
|
||||
}
|
||||
/**
|
||||
* @return array<class-string<Node>>
|
||||
*/
|
||||
public function getNodeTypes() : array
|
||||
{
|
||||
return [Class_::class];
|
||||
}
|
||||
/**
|
||||
* @param Class_ $node
|
||||
*/
|
||||
public function refactor(Node $node) : ?Node
|
||||
{
|
||||
if (!$this->isObjectType($node, new ObjectType('Doctrine\\ORM\\EntityRepository'))) {
|
||||
return null;
|
||||
}
|
||||
if (!$node->extends instanceof Name) {
|
||||
return null;
|
||||
}
|
||||
// remove parent class
|
||||
$node->extends = null;
|
||||
$subtractableType = $this->entityObjectTypeResolver->resolveFromRepositoryClass($node);
|
||||
$genericObjectType = new GenericObjectType('Doctrine\\ORM\\EntityRepository', [$subtractableType]);
|
||||
// add $repository property
|
||||
if (!$node->getProperty('repository') instanceof Property) {
|
||||
$repositoryProperty = $this->nodeFactory->createPrivatePropertyFromNameAndType('repository', $genericObjectType);
|
||||
$node->stmts = \array_merge([$repositoryProperty], $node->stmts);
|
||||
}
|
||||
// add $entityManager and assign to constuctor
|
||||
$repositoryAssign = $this->repositoryAssignFactory->create($node);
|
||||
$this->classDependencyManipulator->addConstructorDependencyWithCustomAssign($node, 'entityManager', new ObjectType('Doctrine\\ORM\\EntityManagerInterface'), $repositoryAssign);
|
||||
return $node;
|
||||
}
|
||||
}
|
@ -1,66 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare (strict_types=1);
|
||||
namespace Rector\Doctrine\Rector\Class_;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Stmt\Class_;
|
||||
use Rector\BetterPhpDocParser\PhpDoc\ArrayItemNode;
|
||||
use Rector\BetterPhpDocParser\PhpDoc\DoctrineAnnotationTagValueNode;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
|
||||
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||
/**
|
||||
* @see \Rector\Doctrine\Tests\Rector\Class_\RemoveRepositoryFromEntityAnnotationRector\RemoveRepositoryFromEntityAnnotationRectorTest
|
||||
*/
|
||||
final class RemoveRepositoryFromEntityAnnotationRector extends AbstractRector
|
||||
{
|
||||
public function getRuleDefinition() : RuleDefinition
|
||||
{
|
||||
return new RuleDefinition('Removes repository class from @Entity annotation', [new CodeSample(<<<'CODE_SAMPLE'
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
|
||||
/**
|
||||
* @ORM\Entity(repositoryClass="ProductRepository")
|
||||
*/
|
||||
class Product
|
||||
{
|
||||
}
|
||||
CODE_SAMPLE
|
||||
, <<<'CODE_SAMPLE'
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
|
||||
/**
|
||||
* @ORM\Entity
|
||||
*/
|
||||
class Product
|
||||
{
|
||||
}
|
||||
CODE_SAMPLE
|
||||
)]);
|
||||
}
|
||||
/**
|
||||
* @return array<class-string<Node>>
|
||||
*/
|
||||
public function getNodeTypes() : array
|
||||
{
|
||||
return [Class_::class];
|
||||
}
|
||||
/**
|
||||
* @param Class_ $node
|
||||
*/
|
||||
public function refactor(Node $node) : ?Node
|
||||
{
|
||||
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($node);
|
||||
$doctrineAnnotationTagValueNode = $phpDocInfo->getByAnnotationClass('Doctrine\\ORM\\Mapping\\Entity');
|
||||
if (!$doctrineAnnotationTagValueNode instanceof DoctrineAnnotationTagValueNode) {
|
||||
return null;
|
||||
}
|
||||
$repositoryClassArrayItemNode = $doctrineAnnotationTagValueNode->getValue('repositoryClass');
|
||||
if (!$repositoryClassArrayItemNode instanceof ArrayItemNode) {
|
||||
return null;
|
||||
}
|
||||
$doctrineAnnotationTagValueNode->removeValue('repositoryClass');
|
||||
return $node;
|
||||
}
|
||||
}
|
@ -1,116 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare (strict_types=1);
|
||||
namespace Rector\Doctrine\Rector\MethodCall;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Arg;
|
||||
use PhpParser\Node\Expr\MethodCall;
|
||||
use PhpParser\Node\Scalar\String_;
|
||||
use PHPStan\Type\ObjectType;
|
||||
use Rector\Core\Contract\Rector\ConfigurableRectorInterface;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Symplify\RuleDocGenerator\ValueObject\CodeSample\ConfiguredCodeSample;
|
||||
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||
use RectorPrefix202307\Webmozart\Assert\Assert;
|
||||
/**
|
||||
* @see \Rector\Doctrine\Tests\Rector\MethodCall\EntityAliasToClassConstantReferenceRector\EntityAliasToClassConstantReferenceRectorTest
|
||||
*/
|
||||
final class EntityAliasToClassConstantReferenceRector extends AbstractRector implements ConfigurableRectorInterface
|
||||
{
|
||||
/**
|
||||
* @api
|
||||
* @var string
|
||||
*/
|
||||
public const ALIASES_TO_NAMESPACES = 'aliases_to_namespaces';
|
||||
/**
|
||||
* @var ObjectType[]
|
||||
*/
|
||||
private $doctrineManagerRegistryObjectTypes = [];
|
||||
/**
|
||||
* @var array<string, string>
|
||||
*/
|
||||
private $aliasesToNamespaces = [];
|
||||
public function __construct()
|
||||
{
|
||||
$this->doctrineManagerRegistryObjectTypes = [new ObjectType('Doctrine\\ORM\\EntityManagerInterface'), new ObjectType('Doctrine\\Persistence\\ObjectManager'), new ObjectType('Doctrine\\Common\\Persistence\\ObjectManager'), new ObjectType('Doctrine\\Persistence\\ManagerRegistry'), new ObjectType('Doctrine\\Common\\Persistence\\ManagerRegistry')];
|
||||
}
|
||||
public function getRuleDefinition() : RuleDefinition
|
||||
{
|
||||
return new RuleDefinition('Replaces doctrine alias with class.', [new ConfiguredCodeSample(<<<'CODE_SAMPLE'
|
||||
$entityManager = new Doctrine\ORM\EntityManager();
|
||||
$entityManager->getRepository("AppBundle:Post");
|
||||
CODE_SAMPLE
|
||||
, <<<'CODE_SAMPLE'
|
||||
$entityManager = new Doctrine\ORM\EntityManager();
|
||||
$entityManager->getRepository(\App\Entity\Post::class);
|
||||
CODE_SAMPLE
|
||||
, [self::ALIASES_TO_NAMESPACES => ['App' => 'App\\Entity']])]);
|
||||
}
|
||||
/**
|
||||
* @return array<class-string<Node>>
|
||||
*/
|
||||
public function getNodeTypes() : array
|
||||
{
|
||||
return [MethodCall::class];
|
||||
}
|
||||
/**
|
||||
* @param MethodCall $node
|
||||
*/
|
||||
public function refactor(Node $node) : ?Node
|
||||
{
|
||||
if (!$this->nodeTypeResolver->isObjectTypes($node->var, $this->doctrineManagerRegistryObjectTypes)) {
|
||||
return null;
|
||||
}
|
||||
if (!$this->isName($node->name, 'getRepository')) {
|
||||
return null;
|
||||
}
|
||||
if ($node->isFirstClassCallable()) {
|
||||
return null;
|
||||
}
|
||||
$firstArg = $node->getArgs()[0] ?? null;
|
||||
if (!$firstArg instanceof Arg) {
|
||||
return null;
|
||||
}
|
||||
if (!$firstArg->value instanceof String_) {
|
||||
return null;
|
||||
}
|
||||
$stringNode = $firstArg->value;
|
||||
if (!$this->isAliasWithConfiguredEntity($stringNode->value)) {
|
||||
return null;
|
||||
}
|
||||
$firstArg->value = $this->nodeFactory->createClassConstReference($this->convertAliasToFqn($stringNode->value));
|
||||
return $node;
|
||||
}
|
||||
/**
|
||||
* @param mixed[] $configuration
|
||||
*/
|
||||
public function configure(array $configuration) : void
|
||||
{
|
||||
$aliasesToNamespaces = $configuration[self::ALIASES_TO_NAMESPACES] ?? $configuration;
|
||||
Assert::isArray($aliasesToNamespaces);
|
||||
Assert::allString(\array_keys($aliasesToNamespaces));
|
||||
Assert::allString($aliasesToNamespaces);
|
||||
$this->aliasesToNamespaces = $aliasesToNamespaces;
|
||||
}
|
||||
private function isAliasWithConfiguredEntity(string $name) : bool
|
||||
{
|
||||
if (!$this->isAlias($name)) {
|
||||
return \false;
|
||||
}
|
||||
return $this->hasAlias($name);
|
||||
}
|
||||
private function convertAliasToFqn(string $name) : string
|
||||
{
|
||||
[$namespaceAlias, $simpleClassName] = \explode(':', $name, 2);
|
||||
return \sprintf('%s\\%s', $this->aliasesToNamespaces[$namespaceAlias], $simpleClassName);
|
||||
}
|
||||
private function isAlias(string $name) : bool
|
||||
{
|
||||
return \strpos($name, ':') !== \false;
|
||||
}
|
||||
private function hasAlias(string $name) : bool
|
||||
{
|
||||
return isset($this->aliasesToNamespaces[\strtok($name, ':')]);
|
||||
}
|
||||
}
|
@ -1,143 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare (strict_types=1);
|
||||
namespace Rector\Doctrine\Rector\MethodCall;
|
||||
|
||||
use RectorPrefix202307\Nette\Utils\Strings;
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Expr;
|
||||
use PhpParser\Node\Expr\ClassConstFetch;
|
||||
use PhpParser\Node\Expr\MethodCall;
|
||||
use PhpParser\Node\Stmt\Class_;
|
||||
use PHPStan\Type\ObjectType;
|
||||
use Rector\Core\Exception\ShouldNotHappenException;
|
||||
use Rector\Core\NodeManipulator\ClassDependencyManipulator;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Rector\PostRector\ValueObject\PropertyMetadata;
|
||||
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
|
||||
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||
/**
|
||||
* @see \Rector\Doctrine\Tests\Set\DoctrineRepositoryAsServiceSet\DoctrineRepositoryAsServiceSetTest
|
||||
*/
|
||||
final class ReplaceParentRepositoryCallsByRepositoryPropertyRector extends AbstractRector
|
||||
{
|
||||
/**
|
||||
* @readonly
|
||||
* @var \Rector\Core\NodeManipulator\ClassDependencyManipulator
|
||||
*/
|
||||
private $classDependencyManipulator;
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
private const ENTITY_REPOSITORY_PUBLIC_METHODS = ['createQueryBuilder', 'createResultSetMappingBuilder', 'clear', 'find', 'findBy', 'findAll', 'findOneBy', 'count', 'getClassName', 'matching'];
|
||||
public function __construct(ClassDependencyManipulator $classDependencyManipulator)
|
||||
{
|
||||
$this->classDependencyManipulator = $classDependencyManipulator;
|
||||
}
|
||||
public function getRuleDefinition() : RuleDefinition
|
||||
{
|
||||
return new RuleDefinition('Handles method calls in child of Doctrine EntityRepository and moves them to $this->repository property.', [new CodeSample(<<<'CODE_SAMPLE'
|
||||
use Doctrine\ORM\EntityRepository;
|
||||
|
||||
class SomeRepository extends EntityRepository
|
||||
{
|
||||
public function someMethod()
|
||||
{
|
||||
return $this->findAll();
|
||||
}
|
||||
}
|
||||
CODE_SAMPLE
|
||||
, <<<'CODE_SAMPLE'
|
||||
use Doctrine\ORM\EntityRepository;
|
||||
|
||||
class SomeRepository extends EntityRepository
|
||||
{
|
||||
public function someMethod()
|
||||
{
|
||||
return $this->repository->findAll();
|
||||
}
|
||||
}
|
||||
CODE_SAMPLE
|
||||
)]);
|
||||
}
|
||||
/**
|
||||
* @return array<class-string<Node>>
|
||||
*/
|
||||
public function getNodeTypes() : array
|
||||
{
|
||||
return [Class_::class];
|
||||
}
|
||||
/**
|
||||
* @param Class_ $node
|
||||
*/
|
||||
public function refactor(Node $node) : ?Node
|
||||
{
|
||||
$hasChanged = \false;
|
||||
$class = $node;
|
||||
$this->traverseNodesWithCallable($node->getMethods(), function (Node $node) use(&$hasChanged, $class) {
|
||||
if (!$node instanceof MethodCall) {
|
||||
return null;
|
||||
}
|
||||
if (!$this->isObjectType($node->var, new ObjectType('Doctrine\\ORM\\EntityRepository'))) {
|
||||
return null;
|
||||
}
|
||||
if (!$this->isNames($node->name, self::ENTITY_REPOSITORY_PUBLIC_METHODS)) {
|
||||
return null;
|
||||
}
|
||||
if ($node->isFirstClassCallable()) {
|
||||
return null;
|
||||
}
|
||||
$hasChanged = \true;
|
||||
// is it getRepository(), replace it with DI property
|
||||
if ($node->var instanceof MethodCall && $this->isName($node->var->name, 'getRepository')) {
|
||||
return $this->refactorGetRepositoryMethodCall($class, $node);
|
||||
}
|
||||
$node->var = $this->nodeFactory->createPropertyFetch('this', 'repository');
|
||||
});
|
||||
if ($hasChanged) {
|
||||
// @todo add constructor property here
|
||||
return $node;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
private function resolveRepositoryName(Expr $expr) : string
|
||||
{
|
||||
$entityReferenceName = $this->valueResolver->getValue($expr);
|
||||
if (!\is_string($entityReferenceName)) {
|
||||
throw new ShouldNotHappenException();
|
||||
}
|
||||
$lastNamePart = (string) Strings::after($entityReferenceName, '\\', -1);
|
||||
return \lcfirst($lastNamePart) . 'Repository';
|
||||
}
|
||||
private function guessRepositoryType(Expr $expr) : ObjectType
|
||||
{
|
||||
if ($expr instanceof ClassConstFetch) {
|
||||
$entityClass = $this->getName($expr->class);
|
||||
if ($entityClass === null) {
|
||||
return new ObjectType('Unknown_Repository_Class');
|
||||
}
|
||||
$entityClassNamespace = (string) Strings::before($entityClass, '\\', -2);
|
||||
$lastNamePart = (string) Strings::after($entityClass, '\\', -1);
|
||||
return new ObjectType($entityClassNamespace . '\\Repository\\' . $lastNamePart . 'Repository');
|
||||
}
|
||||
return new ObjectType('Unknown_Repository_Class');
|
||||
}
|
||||
private function refactorGetRepositoryMethodCall(Class_ $class, MethodCall $methodCall) : ?MethodCall
|
||||
{
|
||||
/** @var MethodCall $parentMethodCall */
|
||||
$parentMethodCall = $methodCall->var;
|
||||
if (\count($parentMethodCall->args) !== 1) {
|
||||
return null;
|
||||
}
|
||||
if ($this->isObjectType($class, new ObjectType('Doctrine\\ORM\\EntityRepository'))) {
|
||||
return null;
|
||||
}
|
||||
$firstArgValue = $parentMethodCall->getArgs()[0]->value;
|
||||
$repositoryPropertyName = $this->resolveRepositoryName($firstArgValue);
|
||||
$repositoryType = $this->guessRepositoryType($firstArgValue);
|
||||
$propertyMetadata = new PropertyMetadata($repositoryPropertyName, $repositoryType);
|
||||
$this->classDependencyManipulator->addConstructorDependency($class, $propertyMetadata);
|
||||
$methodCall->var = $this->nodeFactory->createPropertyFetch('this', $repositoryPropertyName);
|
||||
return $methodCall;
|
||||
}
|
||||
}
|
@ -35,6 +35,7 @@ final class DoctrineSetList implements SetListInterface
|
||||
*/
|
||||
public const DOCTRINE_DBAL_40 = __DIR__ . '/../../config/sets/doctrine-dbal-40.php';
|
||||
/**
|
||||
* @deprecated Removed as not supporting the framework native approach and rather experimental
|
||||
* @var string
|
||||
*/
|
||||
public const DOCTRINE_REPOSITORY_AS_SERVICE = __DIR__ . '/../../config/sets/doctrine-repository-as-service.php';
|
||||
|
@ -1,32 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare (strict_types=1);
|
||||
namespace Rector\Doctrine\Type;
|
||||
|
||||
use PhpParser\Node\Expr;
|
||||
use PhpParser\Node\Expr\ClassConstFetch;
|
||||
use PHPStan\Type\Generic\GenericObjectType;
|
||||
use Rector\Core\Exception\NotImplementedYetException;
|
||||
use Rector\NodeNameResolver\NodeNameResolver;
|
||||
use Rector\StaticTypeMapper\ValueObject\Type\FullyQualifiedObjectType;
|
||||
final class RepositoryTypeFactory
|
||||
{
|
||||
/**
|
||||
* @readonly
|
||||
* @var \Rector\NodeNameResolver\NodeNameResolver
|
||||
*/
|
||||
private $nodeNameResolver;
|
||||
public function __construct(NodeNameResolver $nodeNameResolver)
|
||||
{
|
||||
$this->nodeNameResolver = $nodeNameResolver;
|
||||
}
|
||||
public function createRepositoryPropertyType(Expr $entityReferenceExpr) : GenericObjectType
|
||||
{
|
||||
if (!$entityReferenceExpr instanceof ClassConstFetch) {
|
||||
throw new NotImplementedYetException();
|
||||
}
|
||||
/** @var string $className */
|
||||
$className = $this->nodeNameResolver->getName($entityReferenceExpr->class);
|
||||
return new GenericObjectType('Doctrine\\ORM\\EntityRepository', [new FullyQualifiedObjectType($className)]);
|
||||
}
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare (strict_types=1);
|
||||
namespace Rector\Doctrine\TypeAnalyzer;
|
||||
|
||||
use PHPStan\Type\ArrayType;
|
||||
use PHPStan\Type\IntersectionType;
|
||||
use PHPStan\Type\MixedType;
|
||||
use PHPStan\Type\Type;
|
||||
use PHPStan\Type\UnionType;
|
||||
final class TypeFinder
|
||||
{
|
||||
/**
|
||||
* @template TType as Type
|
||||
* @param class-string<TType> $desiredTypeClass
|
||||
*/
|
||||
public function find(Type $type, string $desiredTypeClass) : Type
|
||||
{
|
||||
if ($type instanceof $desiredTypeClass) {
|
||||
return $type;
|
||||
}
|
||||
if ($type instanceof ArrayType && $type->getItemType() instanceof $desiredTypeClass) {
|
||||
return $type->getItemType();
|
||||
}
|
||||
if ($type instanceof UnionType) {
|
||||
return $this->findInJoinedType($type, $desiredTypeClass);
|
||||
}
|
||||
if ($type instanceof IntersectionType) {
|
||||
return $this->findInJoinedType($type, $desiredTypeClass);
|
||||
}
|
||||
return new MixedType();
|
||||
}
|
||||
/**
|
||||
* @param class-string<Type> $desiredTypeClass
|
||||
* @param \PHPStan\Type\UnionType|\PHPStan\Type\IntersectionType $compoundType
|
||||
*/
|
||||
private function findInJoinedType($compoundType, string $desiredTypeClass) : Type
|
||||
{
|
||||
foreach ($compoundType->getTypes() as $joinedType) {
|
||||
$foundType = $this->find($joinedType, $desiredTypeClass);
|
||||
if (!$foundType instanceof MixedType) {
|
||||
return $foundType;
|
||||
}
|
||||
}
|
||||
return new MixedType();
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user