Updated Rector to commit 39e552c4c9

39e552c4c9 Various little improvement (#2297)
This commit is contained in:
Tomas Votruba 2022-05-12 06:13:58 +00:00
parent d967349fb9
commit e0323c00f8
19 changed files with 217 additions and 56 deletions

View File

@ -7,7 +7,7 @@
],
"require": {
"php": "^7.2|^8.0",
"phpstan/phpstan": "^1.6"
"phpstan/phpstan": "^1.6.8"
},
"autoload": {
"files": [

View File

@ -4,6 +4,7 @@ declare (strict_types=1);
namespace Rector\CodeQuality\Rector\BooleanNot;
use PhpParser\Node;
use PhpParser\Node\Expr\BinaryOp;
use PhpParser\Node\Expr\BinaryOp\BooleanOr;
use PhpParser\Node\Expr\BooleanNot;
use Rector\Core\NodeManipulator\BinaryOpManipulator;
@ -49,7 +50,7 @@ CODE_SAMPLE
/**
* @param BooleanNot $node
*/
public function refactor(\PhpParser\Node $node) : ?\PhpParser\Node
public function refactor(\PhpParser\Node $node) : ?\PhpParser\Node\Expr\BinaryOp
{
if (!$node->expr instanceof \PhpParser\Node\Expr\BinaryOp\BooleanOr) {
return null;

View File

@ -98,15 +98,20 @@ CODE_SAMPLE
}
return $this->refactorPropertyFetch($node);
}
/**
* @return string[]
*/
public function resolvePossibleGetMethodNames(string $propertyName) : array
{
return ['get' . \ucfirst($propertyName), 'has' . \ucfirst($propertyName), 'is' . \ucfirst($propertyName)];
}
private function shouldSkipPropertyFetch(\PhpParser\Node\Expr\PropertyFetch $propertyFetch) : bool
{
$parentAssign = $this->betterNodeFinder->findParentType($propertyFetch, \PhpParser\Node\Expr\Assign::class);
if (!$parentAssign instanceof \PhpParser\Node\Expr\Assign) {
$parent = $propertyFetch->getAttribute(\Rector\NodeTypeResolver\Node\AttributeKey::PARENT_NODE);
if (!$parent instanceof \PhpParser\Node\Expr\Assign) {
return \false;
}
return (bool) $this->betterNodeFinder->findFirst($parentAssign->var, function (\PhpParser\Node $subNode) use($propertyFetch) : bool {
return $subNode === $propertyFetch;
});
return $parent->var === $propertyFetch;
}
/**
* @return \PhpParser\Node\Expr\MethodCall|null
@ -125,10 +130,7 @@ CODE_SAMPLE
if ($propertyName === null) {
return null;
}
$possibleGetterMethodNames = [];
$possibleGetterMethodNames[] = 'get' . \ucfirst($propertyName);
$possibleGetterMethodNames[] = 'has' . \ucfirst($propertyName);
$possibleGetterMethodNames[] = 'is' . \ucfirst($propertyName);
$possibleGetterMethodNames = $this->resolvePossibleGetMethodNames($propertyName);
foreach ($possibleGetterMethodNames as $possibleGetterMethodName) {
if (!$callerType->hasMethod($possibleGetterMethodName)->yes()) {
continue;

View File

@ -87,7 +87,7 @@ final class NameImporter
}
private function shouldSkipName(\PhpParser\Node\Name $name) : bool
{
$virtualNode = (bool) $name->getAttribute(\Rector\NodeTypeResolver\Node\AttributeKey::VIRTUAL_NODE, \false);
$virtualNode = (bool) $name->getAttribute(\Rector\NodeTypeResolver\Node\AttributeKey::VIRTUAL_NODE);
if ($virtualNode) {
return \true;
}

View File

@ -11,9 +11,7 @@ use PhpParser\Node\Expr\Assign;
use PhpParser\Node\Expr\FuncCall;
use PhpParser\Node\Name;
use PhpParser\Node\Stmt\Foreach_;
use PhpParser\Node\VariadicPlaceholder;
use Rector\Core\Rector\AbstractRector;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
@ -36,24 +34,25 @@ CODE_SAMPLE
*/
public function getNodeTypes() : array
{
return [\PhpParser\Node\Expr\Array_::class];
return [\PhpParser\Node\Expr\Array_::class, \PhpParser\Node\Expr\Assign::class, \PhpParser\Node\Stmt\Foreach_::class];
}
/**
* @param Array_ $node
* @param Array_|Assign|Foreach_ $node
*/
public function refactor(\PhpParser\Node $node) : ?\PhpParser\Node
{
$parentNode = $node->getAttribute(\Rector\NodeTypeResolver\Node\AttributeKey::PARENT_NODE);
if ($parentNode instanceof \PhpParser\Node\Expr\Assign && $this->nodeComparator->areNodesEqual($node, $parentNode->var)) {
return $this->processToList($node);
}
if (!$parentNode instanceof \PhpParser\Node\Stmt\Foreach_) {
if ($node instanceof \PhpParser\Node\Expr\Assign) {
if ($node->var instanceof \PhpParser\Node\Expr\Array_) {
$node->var = $this->processToList($node->var);
return $node;
}
return null;
}
if (!$this->nodeComparator->areNodesEqual($node, $parentNode->valueVar)) {
return null;
if ($node instanceof \PhpParser\Node\Stmt\Foreach_ && $node->valueVar instanceof \PhpParser\Node\Expr\Array_) {
$node->valueVar = $this->processToList($node->valueVar);
return $node;
}
return $this->processToList($node);
return null;
}
private function processToList(\PhpParser\Node\Expr\Array_ $array) : \PhpParser\Node\Expr\FuncCall
{
@ -61,7 +60,6 @@ CODE_SAMPLE
foreach ($array->items as $arrayItem) {
$args[] = $arrayItem instanceof \PhpParser\Node\Expr\ArrayItem ? new \PhpParser\Node\Arg($arrayItem->value) : null;
}
/** @var Arg[]|VariadicPlaceholder[] $args */
return new \PhpParser\Node\Expr\FuncCall(new \PhpParser\Node\Name('list'), $args);
}
}

View File

@ -67,8 +67,8 @@ final class ComplexNodeRemover
{
$propertyName = $this->nodeNameResolver->getName($property);
$hasSideEffect = \false;
$isPartoFAnotherAssign = \false;
$this->simpleCallableNodeTraverser->traverseNodesWithCallable($class->stmts, function (\PhpParser\Node $node) use($removeAssignSideEffect, $propertyName, &$hasSideEffect, &$isPartoFAnotherAssign) {
$isPartOfAnotherAssign = \false;
$this->simpleCallableNodeTraverser->traverseNodesWithCallable($class->stmts, function (\PhpParser\Node $node) use($removeAssignSideEffect, $propertyName, &$hasSideEffect, &$isPartOfAnotherAssign) {
// here should be checked all expr like stmts that can hold assign, e.f. if, foreach etc. etc.
if (!$node instanceof \PhpParser\Node\Stmt\Expression) {
return null;
@ -81,7 +81,7 @@ final class ComplexNodeRemover
$assign = $nodeExpr;
// skip double assigns
if ($assign->expr instanceof \PhpParser\Node\Expr\Assign) {
$isPartoFAnotherAssign = \true;
$isPartOfAnotherAssign = \true;
return null;
}
$propertyFetches = $this->resolvePropertyFetchFromDimFetch($assign->var);
@ -103,7 +103,7 @@ final class ComplexNodeRemover
if ($hasSideEffect) {
return;
}
if ($isPartoFAnotherAssign) {
if ($isPartOfAnotherAssign) {
return;
}
$this->removeConstructorDependency($class, $propertyName);

View File

@ -344,7 +344,7 @@ final class ClassRenamer
$scope = $classLike->getAttribute(\Rector\NodeTypeResolver\Node\AttributeKey::SCOPE);
$classLike->implements = \array_unique($classLike->implements);
foreach ($classLike->implements as $key => $implementName) {
$virtualNode = (bool) $implementName->getAttribute(\Rector\NodeTypeResolver\Node\AttributeKey::VIRTUAL_NODE, \false);
$virtualNode = (bool) $implementName->getAttribute(\Rector\NodeTypeResolver\Node\AttributeKey::VIRTUAL_NODE);
if (!$virtualNode) {
continue;
}

View File

@ -43,7 +43,7 @@ final class RenameFunctionRector extends \Rector\Core\Rector\AbstractRector impl
continue;
}
// not to refactor here
$isVirtual = (bool) $node->name->getAttribute(\Rector\NodeTypeResolver\Node\AttributeKey::VIRTUAL_NODE, \false);
$isVirtual = (bool) $node->name->getAttribute(\Rector\NodeTypeResolver\Node\AttributeKey::VIRTUAL_NODE);
if ($isVirtual) {
continue;
}

View File

@ -88,6 +88,9 @@ CODE_SAMPLE
public function refactor(\PhpParser\Node $node) : ?\PhpParser\Node
{
$oldToNewClasses = $this->renamedClassesDataCollector->getOldToNewClasses();
if ($oldToNewClasses === []) {
return null;
}
if (!$node instanceof \PhpParser\Node\Stmt\Use_) {
return $this->classRenamer->renameNode($node, $oldToNewClasses);
}

View File

@ -16,11 +16,11 @@ final class VersionResolver
/**
* @var string
*/
public const PACKAGE_VERSION = 'cd2a644e0c442b883fda86449148c67e0ae82ec4';
public const PACKAGE_VERSION = '39e552c4c97dbb23ada4470fa1b89773ce5bc2a3';
/**
* @var string
*/
public const RELEASE_DATE = '2022-05-12 07:14:00';
public const RELEASE_DATE = '2022-05-12 08:07:50';
/**
* @var string
*/

2
vendor/autoload.php vendored
View File

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

View File

@ -1949,6 +1949,7 @@ return array(
'Rector\\Doctrine\\Rector\\MethodCall\\ReplaceParentRepositoryCallsByRepositoryPropertyRector' => $vendorDir . '/rector/rector-doctrine/src/Rector/MethodCall/ReplaceParentRepositoryCallsByRepositoryPropertyRector.php',
'Rector\\Doctrine\\Rector\\Property\\ChangeBigIntEntityPropertyToIntTypeRector' => $vendorDir . '/rector/rector-doctrine/src/Rector/Property/ChangeBigIntEntityPropertyToIntTypeRector.php',
'Rector\\Doctrine\\Rector\\Property\\CorrectDefaultTypesOnEntityPropertyRector' => $vendorDir . '/rector/rector-doctrine/src/Rector/Property/CorrectDefaultTypesOnEntityPropertyRector.php',
'Rector\\Doctrine\\Rector\\Property\\DoctrineTargetEntityStringToClassConstantRector' => $vendorDir . '/rector/rector-doctrine/src/Rector/Property/DoctrineTargetEntityStringToClassConstantRector.php',
'Rector\\Doctrine\\Rector\\Property\\ImproveDoctrineCollectionDocTypeInEntityRector' => $vendorDir . '/rector/rector-doctrine/src/Rector/Property/ImproveDoctrineCollectionDocTypeInEntityRector.php',
'Rector\\Doctrine\\Rector\\Property\\MakeEntityDateTimePropertyDateTimeInterfaceRector' => $vendorDir . '/rector/rector-doctrine/src/Rector/Property/MakeEntityDateTimePropertyDateTimeInterfaceRector.php',
'Rector\\Doctrine\\Rector\\Property\\RemoveRedundantDefaultPropertyAnnotationValuesRector' => $vendorDir . '/rector/rector-doctrine/src/Rector/Property/RemoveRedundantDefaultPropertyAnnotationValuesRector.php',

View File

@ -2,7 +2,7 @@
// autoload_real.php @generated by Composer
class ComposerAutoloaderInita92cadfeeeb703ebe0b49394cdda26ce
class ComposerAutoloaderInit10ed0a615d90a5e9a7d6f335d71cd385
{
private static $loader;
@ -22,19 +22,19 @@ class ComposerAutoloaderInita92cadfeeeb703ebe0b49394cdda26ce
return self::$loader;
}
spl_autoload_register(array('ComposerAutoloaderInita92cadfeeeb703ebe0b49394cdda26ce', 'loadClassLoader'), true, true);
spl_autoload_register(array('ComposerAutoloaderInit10ed0a615d90a5e9a7d6f335d71cd385', 'loadClassLoader'), true, true);
self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__));
spl_autoload_unregister(array('ComposerAutoloaderInita92cadfeeeb703ebe0b49394cdda26ce', 'loadClassLoader'));
spl_autoload_unregister(array('ComposerAutoloaderInit10ed0a615d90a5e9a7d6f335d71cd385', 'loadClassLoader'));
require __DIR__ . '/autoload_static.php';
call_user_func(\Composer\Autoload\ComposerStaticInita92cadfeeeb703ebe0b49394cdda26ce::getInitializer($loader));
call_user_func(\Composer\Autoload\ComposerStaticInit10ed0a615d90a5e9a7d6f335d71cd385::getInitializer($loader));
$loader->setClassMapAuthoritative(true);
$loader->register(true);
$includeFiles = \Composer\Autoload\ComposerStaticInita92cadfeeeb703ebe0b49394cdda26ce::$files;
$includeFiles = \Composer\Autoload\ComposerStaticInit10ed0a615d90a5e9a7d6f335d71cd385::$files;
foreach ($includeFiles as $fileIdentifier => $file) {
composerRequirea92cadfeeeb703ebe0b49394cdda26ce($fileIdentifier, $file);
composerRequire10ed0a615d90a5e9a7d6f335d71cd385($fileIdentifier, $file);
}
return $loader;
@ -46,7 +46,7 @@ class ComposerAutoloaderInita92cadfeeeb703ebe0b49394cdda26ce
* @param string $file
* @return void
*/
function composerRequirea92cadfeeeb703ebe0b49394cdda26ce($fileIdentifier, $file)
function composerRequire10ed0a615d90a5e9a7d6f335d71cd385($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 ComposerStaticInita92cadfeeeb703ebe0b49394cdda26ce
class ComposerStaticInit10ed0a615d90a5e9a7d6f335d71cd385
{
public static $files = array (
'320cde22f66dd4f5d3fd621d3e88b98f' => __DIR__ . '/..' . '/symfony/polyfill-ctype/bootstrap.php',
@ -2318,6 +2318,7 @@ class ComposerStaticInita92cadfeeeb703ebe0b49394cdda26ce
'Rector\\Doctrine\\Rector\\MethodCall\\ReplaceParentRepositoryCallsByRepositoryPropertyRector' => __DIR__ . '/..' . '/rector/rector-doctrine/src/Rector/MethodCall/ReplaceParentRepositoryCallsByRepositoryPropertyRector.php',
'Rector\\Doctrine\\Rector\\Property\\ChangeBigIntEntityPropertyToIntTypeRector' => __DIR__ . '/..' . '/rector/rector-doctrine/src/Rector/Property/ChangeBigIntEntityPropertyToIntTypeRector.php',
'Rector\\Doctrine\\Rector\\Property\\CorrectDefaultTypesOnEntityPropertyRector' => __DIR__ . '/..' . '/rector/rector-doctrine/src/Rector/Property/CorrectDefaultTypesOnEntityPropertyRector.php',
'Rector\\Doctrine\\Rector\\Property\\DoctrineTargetEntityStringToClassConstantRector' => __DIR__ . '/..' . '/rector/rector-doctrine/src/Rector/Property/DoctrineTargetEntityStringToClassConstantRector.php',
'Rector\\Doctrine\\Rector\\Property\\ImproveDoctrineCollectionDocTypeInEntityRector' => __DIR__ . '/..' . '/rector/rector-doctrine/src/Rector/Property/ImproveDoctrineCollectionDocTypeInEntityRector.php',
'Rector\\Doctrine\\Rector\\Property\\MakeEntityDateTimePropertyDateTimeInterfaceRector' => __DIR__ . '/..' . '/rector/rector-doctrine/src/Rector/Property/MakeEntityDateTimePropertyDateTimeInterfaceRector.php',
'Rector\\Doctrine\\Rector\\Property\\RemoveRedundantDefaultPropertyAnnotationValuesRector' => __DIR__ . '/..' . '/rector/rector-doctrine/src/Rector/Property/RemoveRedundantDefaultPropertyAnnotationValuesRector.php',
@ -3890,9 +3891,9 @@ class ComposerStaticInita92cadfeeeb703ebe0b49394cdda26ce
public static function getInitializer(ClassLoader $loader)
{
return \Closure::bind(function () use ($loader) {
$loader->prefixLengthsPsr4 = ComposerStaticInita92cadfeeeb703ebe0b49394cdda26ce::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInita92cadfeeeb703ebe0b49394cdda26ce::$prefixDirsPsr4;
$loader->classMap = ComposerStaticInita92cadfeeeb703ebe0b49394cdda26ce::$classMap;
$loader->prefixLengthsPsr4 = ComposerStaticInit10ed0a615d90a5e9a7d6f335d71cd385::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInit10ed0a615d90a5e9a7d6f335d71cd385::$prefixDirsPsr4;
$loader->classMap = ComposerStaticInit10ed0a615d90a5e9a7d6f335d71cd385::$classMap;
}, null, ClassLoader::class);
}

View File

@ -2219,12 +2219,12 @@
"source": {
"type": "git",
"url": "https:\/\/github.com\/rectorphp\/rector-doctrine.git",
"reference": "135530ee850a8244c412ed28a5da99da8fc3cfcf"
"reference": "4a907ede0f35a562aadc63eebadf34e8d3d3d388"
},
"dist": {
"type": "zip",
"url": "https:\/\/api.github.com\/repos\/rectorphp\/rector-doctrine\/zipball\/135530ee850a8244c412ed28a5da99da8fc3cfcf",
"reference": "135530ee850a8244c412ed28a5da99da8fc3cfcf",
"url": "https:\/\/api.github.com\/repos\/rectorphp\/rector-doctrine\/zipball\/4a907ede0f35a562aadc63eebadf34e8d3d3d388",
"reference": "4a907ede0f35a562aadc63eebadf34e8d3d3d388",
"shasum": ""
},
"require": {
@ -2249,7 +2249,7 @@
"symplify\/rule-doc-generator": "^10.2",
"symplify\/vendor-patches": "^10.2"
},
"time": "2022-05-11T11:18:37+00:00",
"time": "2022-05-12T05:32:05+00:00",
"default-branch": true,
"type": "rector-extension",
"extra": {

File diff suppressed because one or more lines are too long

View File

@ -9,7 +9,7 @@ namespace Rector\RectorInstaller;
*/
final class GeneratedConfig
{
public const EXTENSIONS = array('rector/rector-cakephp' => array('install_path' => '/home/runner/work/rector-src/rector-src/vendor/rector/rector-cakephp', 'relative_install_path' => '../../rector-cakephp', 'extra' => array('includes' => array(0 => 'config/config.php')), 'version' => 'dev-main 43ca394'), '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 135530e'), 'rector/rector-generator' => array('install_path' => '/home/runner/work/rector-src/rector-src/vendor/rector/rector-generator', 'relative_install_path' => '../../rector-generator', 'extra' => array('includes' => array(0 => 'config/config.php')), 'version' => 'dev-main 784271e'), 'rector/rector-laravel' => array('install_path' => '/home/runner/work/rector-src/rector-src/vendor/rector/rector-laravel', 'relative_install_path' => '../../rector-laravel', 'extra' => array('includes' => array(0 => 'config/config.php')), 'version' => 'dev-main 352a13b'), 'rector/rector-nette' => array('install_path' => '/home/runner/work/rector-src/rector-src/vendor/rector/rector-nette', 'relative_install_path' => '../../rector-nette', 'extra' => array('includes' => array(0 => 'config/config.php')), 'version' => 'dev-main 5f84d90'), 'rector/rector-phpoffice' => array('install_path' => '/home/runner/work/rector-src/rector-src/vendor/rector/rector-phpoffice', 'relative_install_path' => '../../rector-phpoffice', 'extra' => array('includes' => array(0 => 'config/config.php')), 'version' => 'dev-main e544f2a'), '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 666c8d7'), '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 ca53e28'), 'ssch/typo3-rector' => array('install_path' => '/home/runner/work/rector-src/rector-src/vendor/ssch/typo3-rector', 'relative_install_path' => '../../../ssch/typo3-rector', 'extra' => array('includes' => array(0 => 'config/config.php')), 'version' => 'dev-main 3b659b7'));
public const EXTENSIONS = array('rector/rector-cakephp' => array('install_path' => '/home/runner/work/rector-src/rector-src/vendor/rector/rector-cakephp', 'relative_install_path' => '../../rector-cakephp', 'extra' => array('includes' => array(0 => 'config/config.php')), 'version' => 'dev-main 43ca394'), '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 4a907ed'), 'rector/rector-generator' => array('install_path' => '/home/runner/work/rector-src/rector-src/vendor/rector/rector-generator', 'relative_install_path' => '../../rector-generator', 'extra' => array('includes' => array(0 => 'config/config.php')), 'version' => 'dev-main 784271e'), 'rector/rector-laravel' => array('install_path' => '/home/runner/work/rector-src/rector-src/vendor/rector/rector-laravel', 'relative_install_path' => '../../rector-laravel', 'extra' => array('includes' => array(0 => 'config/config.php')), 'version' => 'dev-main 352a13b'), 'rector/rector-nette' => array('install_path' => '/home/runner/work/rector-src/rector-src/vendor/rector/rector-nette', 'relative_install_path' => '../../rector-nette', 'extra' => array('includes' => array(0 => 'config/config.php')), 'version' => 'dev-main 5f84d90'), 'rector/rector-phpoffice' => array('install_path' => '/home/runner/work/rector-src/rector-src/vendor/rector/rector-phpoffice', 'relative_install_path' => '../../rector-phpoffice', 'extra' => array('includes' => array(0 => 'config/config.php')), 'version' => 'dev-main e544f2a'), '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 666c8d7'), '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 ca53e28'), 'ssch/typo3-rector' => array('install_path' => '/home/runner/work/rector-src/rector-src/vendor/ssch/typo3-rector', 'relative_install_path' => '../../../ssch/typo3-rector', 'extra' => array('includes' => array(0 => 'config/config.php')), 'version' => 'dev-main 3b659b7'));
private function __construct()
{
}

View File

@ -0,0 +1,155 @@
<?php
declare (strict_types=1);
namespace Rector\Doctrine\Rector\Property;
use RectorPrefix20220512\Doctrine\ORM\Mapping\Embedded;
use RectorPrefix20220512\Doctrine\ORM\Mapping\ManyToMany;
use RectorPrefix20220512\Doctrine\ORM\Mapping\ManyToOne;
use RectorPrefix20220512\Doctrine\ORM\Mapping\OneToMany;
use RectorPrefix20220512\Doctrine\ORM\Mapping\OneToOne;
use PhpParser\Node;
use PhpParser\Node\Attribute;
use PhpParser\Node\Identifier;
use PhpParser\Node\Stmt\Property;
use Rector\BetterPhpDocParser\PhpDoc\DoctrineAnnotationTagValueNode;
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo;
use Rector\BetterPhpDocParser\PhpDocParser\ClassAnnotationMatcher;
use Rector\Core\Rector\AbstractRector;
use Rector\Doctrine\NodeAnalyzer\AttributeFinder;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* @see \Rector\Doctrine\Tests\Rector\Property\DoctrineTargetEntityStringToClassConstantRector\DoctrineTargetEntityStringToClassConstantRectorTest
*/
final class DoctrineTargetEntityStringToClassConstantRector extends \Rector\Core\Rector\AbstractRector
{
private const ATTRIBUTE_NAME__TARGET_ENTITY = 'targetEntity';
private const ATTRIBUTE_NAME__CLASS = 'class';
/**
* @var array<class-string<OneToMany|ManyToOne|OneToOne|ManyToMany|Embedded>, string>
*/
private const VALID_DOCTRINE_CLASSES = ['Doctrine\\ORM\\Mapping\\OneToMany' => self::ATTRIBUTE_NAME__TARGET_ENTITY, 'Doctrine\\ORM\\Mapping\\ManyToOne' => self::ATTRIBUTE_NAME__TARGET_ENTITY, 'Doctrine\\ORM\\Mapping\\OneToOne' => self::ATTRIBUTE_NAME__TARGET_ENTITY, 'Doctrine\\ORM\\Mapping\\ManyToMany' => self::ATTRIBUTE_NAME__TARGET_ENTITY, 'Doctrine\\ORM\\Mapping\\Embedded' => self::ATTRIBUTE_NAME__CLASS];
/**
* @readonly
* @var \Rector\BetterPhpDocParser\PhpDocParser\ClassAnnotationMatcher
*/
private $classAnnotationMatcher;
/**
* @readonly
* @var \Rector\Doctrine\NodeAnalyzer\AttributeFinder
*/
private $attributeFinder;
public function __construct(\Rector\BetterPhpDocParser\PhpDocParser\ClassAnnotationMatcher $classAnnotationMatcher, \Rector\Doctrine\NodeAnalyzer\AttributeFinder $attributeFinder)
{
$this->classAnnotationMatcher = $classAnnotationMatcher;
$this->attributeFinder = $attributeFinder;
}
public function getRuleDefinition() : \Symplify\RuleDocGenerator\ValueObject\RuleDefinition
{
return new \Symplify\RuleDocGenerator\ValueObject\RuleDefinition('Convert targetEntities defined as String to <class>::class Constants in Doctrine Entities.', [new \Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample(<<<'CODE_SAMPLE'
final class SomeClass
{
/**
* @ORM\OneToMany(targetEntity="AnotherClass")
*/
private readonly ?Collection $items;
#[ORM\ManyToOne(targetEntity: "AnotherClass")]
private readonly ?Collection $items2;
}
CODE_SAMPLE
, <<<'CODE_SAMPLE'
final class SomeClass
{
/**
* @ORM\OneToMany(targetEntity=\MyNamespace\Source\AnotherClass::class)
*/
private readonly ?Collection $items;
#[ORM\ManyToOne(targetEntity: \MyNamespace\Source\AnotherClass::class)]
private readonly ?Collection $items2;
}
CODE_SAMPLE
)]);
}
public function getNodeTypes() : array
{
return [\PhpParser\Node\Stmt\Property::class];
}
/**
* @param Property $node
*/
public function refactor(\PhpParser\Node $node) : ?\PhpParser\Node
{
$hasChanged = \false;
$phpDocInfo = $this->phpDocInfoFactory->createFromNode($node);
if ($phpDocInfo !== null) {
$property = $this->changeTypeInAnnotationTypes($node, $phpDocInfo);
$hasChanged = $property !== null || $phpDocInfo->hasChanged();
}
return $this->changeTypeInAttributeTypes($node, $hasChanged);
}
private function changeTypeInAttributeTypes(\PhpParser\Node\Stmt\Property $property, bool $hasChanged) : ?\PhpParser\Node\Stmt\Property
{
$attribute = $this->attributeFinder->findAttributeByClasses($property, $this->getAttributeClasses());
if (!$attribute instanceof \PhpParser\Node\Attribute) {
return $hasChanged ? $property : null;
}
$attributeName = $this->getAttributeName($attribute);
foreach ($attribute->args as $arg) {
$argName = $arg->name;
if (!$argName instanceof \PhpParser\Node\Identifier) {
continue;
}
if (!$this->isName($argName, $attributeName)) {
continue;
}
/** @var string $value - Should always be string at this point */
$value = $this->valueResolver->getValue($arg->value);
$fullyQualified = $this->classAnnotationMatcher->resolveTagFullyQualifiedName($value, $property);
if ($fullyQualified === $value) {
continue;
}
$arg->value = $this->nodeFactory->createClassConstFetch($fullyQualified, 'class');
return $property;
}
return $hasChanged ? $property : null;
}
private function changeTypeInAnnotationTypes(\PhpParser\Node\Stmt\Property $property, \Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo $phpDocInfo) : ?\PhpParser\Node\Stmt\Property
{
$doctrineAnnotationTagValueNode = $phpDocInfo->getByAnnotationClasses($this->getAttributeClasses());
if (!$doctrineAnnotationTagValueNode instanceof \Rector\BetterPhpDocParser\PhpDoc\DoctrineAnnotationTagValueNode) {
return null;
}
return $this->processDoctrineToMany($doctrineAnnotationTagValueNode, $property);
}
private function processDoctrineToMany(\Rector\BetterPhpDocParser\PhpDoc\DoctrineAnnotationTagValueNode $doctrineAnnotationTagValueNode, \PhpParser\Node\Stmt\Property $property) : ?\PhpParser\Node\Stmt\Property
{
$key = $doctrineAnnotationTagValueNode->hasClassName('Doctrine\\ORM\\Mapping\\Embedded') ? self::ATTRIBUTE_NAME__CLASS : self::ATTRIBUTE_NAME__TARGET_ENTITY;
/** @var ?string $targetEntity */
$targetEntity = $doctrineAnnotationTagValueNode->getValueWithoutQuotes($key);
if ($targetEntity === null) {
return null;
}
// resolve to FQN
$tagFullyQualifiedName = $this->classAnnotationMatcher->resolveTagFullyQualifiedName($targetEntity, $property);
if ($tagFullyQualifiedName === $targetEntity) {
return null;
}
$doctrineAnnotationTagValueNode->removeValue($key);
$doctrineAnnotationTagValueNode->values[$key] = '\\' . $tagFullyQualifiedName . '::class';
return $property;
}
/**
* @return class-string[]
*/
private function getAttributeClasses() : array
{
return \array_keys(self::VALID_DOCTRINE_CLASSES);
}
private function getAttributeName(\PhpParser\Node\Attribute $attribute) : string
{
return self::VALID_DOCTRINE_CLASSES[$attribute->name->toString()];
}
}

View File

@ -9,8 +9,8 @@ $loader = require_once __DIR__.'/autoload.php';
if (!class_exists('AutoloadIncluder', false) && !interface_exists('AutoloadIncluder', false) && !trait_exists('AutoloadIncluder', false)) {
spl_autoload_call('RectorPrefix20220512\AutoloadIncluder');
}
if (!class_exists('ComposerAutoloaderInita92cadfeeeb703ebe0b49394cdda26ce', false) && !interface_exists('ComposerAutoloaderInita92cadfeeeb703ebe0b49394cdda26ce', false) && !trait_exists('ComposerAutoloaderInita92cadfeeeb703ebe0b49394cdda26ce', false)) {
spl_autoload_call('RectorPrefix20220512\ComposerAutoloaderInita92cadfeeeb703ebe0b49394cdda26ce');
if (!class_exists('ComposerAutoloaderInit10ed0a615d90a5e9a7d6f335d71cd385', false) && !interface_exists('ComposerAutoloaderInit10ed0a615d90a5e9a7d6f335d71cd385', false) && !trait_exists('ComposerAutoloaderInit10ed0a615d90a5e9a7d6f335d71cd385', false)) {
spl_autoload_call('RectorPrefix20220512\ComposerAutoloaderInit10ed0a615d90a5e9a7d6f335d71cd385');
}
if (!class_exists('Helmich\TypoScriptParser\Parser\AST\Statement', false) && !interface_exists('Helmich\TypoScriptParser\Parser\AST\Statement', false) && !trait_exists('Helmich\TypoScriptParser\Parser\AST\Statement', false)) {
spl_autoload_call('RectorPrefix20220512\Helmich\TypoScriptParser\Parser\AST\Statement');
@ -59,9 +59,9 @@ if (!function_exists('print_node')) {
return \RectorPrefix20220512\print_node(...func_get_args());
}
}
if (!function_exists('composerRequirea92cadfeeeb703ebe0b49394cdda26ce')) {
function composerRequirea92cadfeeeb703ebe0b49394cdda26ce() {
return \RectorPrefix20220512\composerRequirea92cadfeeeb703ebe0b49394cdda26ce(...func_get_args());
if (!function_exists('composerRequire10ed0a615d90a5e9a7d6f335d71cd385')) {
function composerRequire10ed0a615d90a5e9a7d6f335d71cd385() {
return \RectorPrefix20220512\composerRequire10ed0a615d90a5e9a7d6f335d71cd385(...func_get_args());
}
}
if (!function_exists('scanPath')) {