Updated Rector to commit 35b0d39f63b1d8dff169ee673c6e6de1268304b3

35b0d39f63 Skip method of abstract class for StaticCallOnNonStaticToInstanceCallRector. (#2938)
This commit is contained in:
Tomas Votruba 2022-09-19 21:06:34 +00:00
parent e46f4f4e38
commit 7f4c965d08
14 changed files with 347 additions and 26 deletions

2
vendor/autoload.php vendored
View File

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

View File

@ -2551,6 +2551,7 @@ return array(
'Rector\\Symfony\\Rector\\ClassMethod\\RouteCollectionBuilderToRoutingConfiguratorRector' => $vendorDir . '/rector/rector-symfony/src/Rector/ClassMethod/RouteCollectionBuilderToRoutingConfiguratorRector.php',
'Rector\\Symfony\\Rector\\ClassMethod\\TemplateAnnotationToThisRenderRector' => $vendorDir . '/rector/rector-symfony/src/Rector/ClassMethod/TemplateAnnotationToThisRenderRector.php',
'Rector\\Symfony\\Rector\\Class_\\ChangeFileLoaderInExtensionAndKernelRector' => $vendorDir . '/rector/rector-symfony/src/Rector/Class_/ChangeFileLoaderInExtensionAndKernelRector.php',
'Rector\\Symfony\\Rector\\Class_\\CommandDescriptionToPropertyRector' => $vendorDir . '/rector/rector-symfony/src/Rector/Class_/CommandDescriptionToPropertyRector.php',
'Rector\\Symfony\\Rector\\Class_\\CommandPropertyToAttributeRector' => $vendorDir . '/rector/rector-symfony/src/Rector/Class_/CommandPropertyToAttributeRector.php',
'Rector\\Symfony\\Rector\\Class_\\EventListenerToEventSubscriberRector' => $vendorDir . '/rector/rector-symfony/src/Rector/Class_/EventListenerToEventSubscriberRector.php',
'Rector\\Symfony\\Rector\\Class_\\FormTypeWithDependencyToOptionsRector' => $vendorDir . '/rector/rector-symfony/src/Rector/Class_/FormTypeWithDependencyToOptionsRector.php',
@ -2579,6 +2580,7 @@ return array(
'Rector\\Symfony\\Rector\\MethodCall\\GetToConstructorInjectionRector' => $vendorDir . '/rector/rector-symfony/src/Rector/MethodCall/GetToConstructorInjectionRector.php',
'Rector\\Symfony\\Rector\\MethodCall\\LiteralGetToRequestClassConstantRector' => $vendorDir . '/rector/rector-symfony/src/Rector/MethodCall/LiteralGetToRequestClassConstantRector.php',
'Rector\\Symfony\\Rector\\MethodCall\\MakeDispatchFirstArgumentEventRector' => $vendorDir . '/rector/rector-symfony/src/Rector/MethodCall/MakeDispatchFirstArgumentEventRector.php',
'Rector\\Symfony\\Rector\\MethodCall\\MaxLengthSymfonyFormOptionToAttrRector' => $vendorDir . '/rector/rector-symfony/src/Rector/MethodCall/MaxLengthSymfonyFormOptionToAttrRector.php',
'Rector\\Symfony\\Rector\\MethodCall\\OptionNameRector' => $vendorDir . '/rector/rector-symfony/src/Rector/MethodCall/OptionNameRector.php',
'Rector\\Symfony\\Rector\\MethodCall\\ProcessBuilderGetProcessRector' => $vendorDir . '/rector/rector-symfony/src/Rector/MethodCall/ProcessBuilderGetProcessRector.php',
'Rector\\Symfony\\Rector\\MethodCall\\ReadOnlyOptionToAttributeRector' => $vendorDir . '/rector/rector-symfony/src/Rector/MethodCall/ReadOnlyOptionToAttributeRector.php',

View File

@ -2,7 +2,7 @@
// autoload_real.php @generated by Composer
class ComposerAutoloaderInitff57b92ef8ea795f7486de04122ffd5b
class ComposerAutoloaderInit50808688ff91876faccf17ae58554fd3
{
private static $loader;
@ -22,19 +22,19 @@ class ComposerAutoloaderInitff57b92ef8ea795f7486de04122ffd5b
return self::$loader;
}
spl_autoload_register(array('ComposerAutoloaderInitff57b92ef8ea795f7486de04122ffd5b', 'loadClassLoader'), true, true);
spl_autoload_register(array('ComposerAutoloaderInit50808688ff91876faccf17ae58554fd3', 'loadClassLoader'), true, true);
self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__));
spl_autoload_unregister(array('ComposerAutoloaderInitff57b92ef8ea795f7486de04122ffd5b', 'loadClassLoader'));
spl_autoload_unregister(array('ComposerAutoloaderInit50808688ff91876faccf17ae58554fd3', 'loadClassLoader'));
require __DIR__ . '/autoload_static.php';
call_user_func(\Composer\Autoload\ComposerStaticInitff57b92ef8ea795f7486de04122ffd5b::getInitializer($loader));
call_user_func(\Composer\Autoload\ComposerStaticInit50808688ff91876faccf17ae58554fd3::getInitializer($loader));
$loader->setClassMapAuthoritative(true);
$loader->register(true);
$includeFiles = \Composer\Autoload\ComposerStaticInitff57b92ef8ea795f7486de04122ffd5b::$files;
$includeFiles = \Composer\Autoload\ComposerStaticInit50808688ff91876faccf17ae58554fd3::$files;
foreach ($includeFiles as $fileIdentifier => $file) {
composerRequireff57b92ef8ea795f7486de04122ffd5b($fileIdentifier, $file);
composerRequire50808688ff91876faccf17ae58554fd3($fileIdentifier, $file);
}
return $loader;
@ -46,7 +46,7 @@ class ComposerAutoloaderInitff57b92ef8ea795f7486de04122ffd5b
* @param string $file
* @return void
*/
function composerRequireff57b92ef8ea795f7486de04122ffd5b($fileIdentifier, $file)
function composerRequire50808688ff91876faccf17ae58554fd3($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 ComposerStaticInitff57b92ef8ea795f7486de04122ffd5b
class ComposerStaticInit50808688ff91876faccf17ae58554fd3
{
public static $files = array (
'ad155f8f1cf0d418fe49e248db8c661b' => __DIR__ . '/..' . '/react/promise/src/functions_include.php',
@ -2811,6 +2811,7 @@ class ComposerStaticInitff57b92ef8ea795f7486de04122ffd5b
'Rector\\Symfony\\Rector\\ClassMethod\\RouteCollectionBuilderToRoutingConfiguratorRector' => __DIR__ . '/..' . '/rector/rector-symfony/src/Rector/ClassMethod/RouteCollectionBuilderToRoutingConfiguratorRector.php',
'Rector\\Symfony\\Rector\\ClassMethod\\TemplateAnnotationToThisRenderRector' => __DIR__ . '/..' . '/rector/rector-symfony/src/Rector/ClassMethod/TemplateAnnotationToThisRenderRector.php',
'Rector\\Symfony\\Rector\\Class_\\ChangeFileLoaderInExtensionAndKernelRector' => __DIR__ . '/..' . '/rector/rector-symfony/src/Rector/Class_/ChangeFileLoaderInExtensionAndKernelRector.php',
'Rector\\Symfony\\Rector\\Class_\\CommandDescriptionToPropertyRector' => __DIR__ . '/..' . '/rector/rector-symfony/src/Rector/Class_/CommandDescriptionToPropertyRector.php',
'Rector\\Symfony\\Rector\\Class_\\CommandPropertyToAttributeRector' => __DIR__ . '/..' . '/rector/rector-symfony/src/Rector/Class_/CommandPropertyToAttributeRector.php',
'Rector\\Symfony\\Rector\\Class_\\EventListenerToEventSubscriberRector' => __DIR__ . '/..' . '/rector/rector-symfony/src/Rector/Class_/EventListenerToEventSubscriberRector.php',
'Rector\\Symfony\\Rector\\Class_\\FormTypeWithDependencyToOptionsRector' => __DIR__ . '/..' . '/rector/rector-symfony/src/Rector/Class_/FormTypeWithDependencyToOptionsRector.php',
@ -2839,6 +2840,7 @@ class ComposerStaticInitff57b92ef8ea795f7486de04122ffd5b
'Rector\\Symfony\\Rector\\MethodCall\\GetToConstructorInjectionRector' => __DIR__ . '/..' . '/rector/rector-symfony/src/Rector/MethodCall/GetToConstructorInjectionRector.php',
'Rector\\Symfony\\Rector\\MethodCall\\LiteralGetToRequestClassConstantRector' => __DIR__ . '/..' . '/rector/rector-symfony/src/Rector/MethodCall/LiteralGetToRequestClassConstantRector.php',
'Rector\\Symfony\\Rector\\MethodCall\\MakeDispatchFirstArgumentEventRector' => __DIR__ . '/..' . '/rector/rector-symfony/src/Rector/MethodCall/MakeDispatchFirstArgumentEventRector.php',
'Rector\\Symfony\\Rector\\MethodCall\\MaxLengthSymfonyFormOptionToAttrRector' => __DIR__ . '/..' . '/rector/rector-symfony/src/Rector/MethodCall/MaxLengthSymfonyFormOptionToAttrRector.php',
'Rector\\Symfony\\Rector\\MethodCall\\OptionNameRector' => __DIR__ . '/..' . '/rector/rector-symfony/src/Rector/MethodCall/OptionNameRector.php',
'Rector\\Symfony\\Rector\\MethodCall\\ProcessBuilderGetProcessRector' => __DIR__ . '/..' . '/rector/rector-symfony/src/Rector/MethodCall/ProcessBuilderGetProcessRector.php',
'Rector\\Symfony\\Rector\\MethodCall\\ReadOnlyOptionToAttributeRector' => __DIR__ . '/..' . '/rector/rector-symfony/src/Rector/MethodCall/ReadOnlyOptionToAttributeRector.php',
@ -3101,9 +3103,9 @@ class ComposerStaticInitff57b92ef8ea795f7486de04122ffd5b
public static function getInitializer(ClassLoader $loader)
{
return \Closure::bind(function () use ($loader) {
$loader->prefixLengthsPsr4 = ComposerStaticInitff57b92ef8ea795f7486de04122ffd5b::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInitff57b92ef8ea795f7486de04122ffd5b::$prefixDirsPsr4;
$loader->classMap = ComposerStaticInitff57b92ef8ea795f7486de04122ffd5b::$classMap;
$loader->prefixLengthsPsr4 = ComposerStaticInit50808688ff91876faccf17ae58554fd3::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInit50808688ff91876faccf17ae58554fd3::$prefixDirsPsr4;
$loader->classMap = ComposerStaticInit50808688ff91876faccf17ae58554fd3::$classMap;
}, null, ClassLoader::class);
}

View File

@ -2264,12 +2264,12 @@
"source": {
"type": "git",
"url": "https:\/\/github.com\/rectorphp\/rector-symfony.git",
"reference": "137e52b4a7b17dc9753ed4ce6aa00d4569d7dc80"
"reference": "113df7c4196be6d196bd7606e2daa98f7b7cd289"
},
"dist": {
"type": "zip",
"url": "https:\/\/api.github.com\/repos\/rectorphp\/rector-symfony\/zipball\/137e52b4a7b17dc9753ed4ce6aa00d4569d7dc80",
"reference": "137e52b4a7b17dc9753ed4ce6aa00d4569d7dc80",
"url": "https:\/\/api.github.com\/repos\/rectorphp\/rector-symfony\/zipball\/113df7c4196be6d196bd7606e2daa98f7b7cd289",
"reference": "113df7c4196be6d196bd7606e2daa98f7b7cd289",
"shasum": ""
},
"require": {
@ -2300,7 +2300,7 @@
"symplify\/rule-doc-generator": "^11.1",
"symplify\/vendor-patches": "^11.1"
},
"time": "2022-09-12T07:21:22+00:00",
"time": "2022-09-19T21:01:13+00:00",
"default-branch": true,
"type": "rector-extension",
"extra": {
@ -2327,7 +2327,7 @@
"description": "Rector upgrades rules for Symfony Framework",
"support": {
"issues": "https:\/\/github.com\/rectorphp\/rector-symfony\/issues",
"source": "https:\/\/github.com\/rectorphp\/rector-symfony\/tree\/main"
"source": "https:\/\/github.com\/rectorphp\/rector-symfony\/tree\/0.14.0"
},
"install-path": "..\/rector\/rector-symfony"
},

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 a489bf0'), '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 c56069f'), '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 d75c674'), '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 2decdcf'), 'rector/rector-php-parser' => array('install_path' => '/home/runner/work/rector-src/rector-src/vendor/rector/rector-php-parser', 'relative_install_path' => '../../rector-php-parser', 'extra' => array('includes' => array(0 => 'config/config.php')), 'version' => 'dev-main 8d6cbe9'), '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 294de0c'), '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 cf30315'), '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 137e52b'));
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 a489bf0'), '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 c56069f'), '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 d75c674'), '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 2decdcf'), 'rector/rector-php-parser' => array('install_path' => '/home/runner/work/rector-src/rector-src/vendor/rector/rector-php-parser', 'relative_install_path' => '../../rector-php-parser', 'extra' => array('includes' => array(0 => 'config/config.php')), 'version' => 'dev-main 8d6cbe9'), '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 294de0c'), '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 cf30315'), '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 113df7c'));
private function __construct()
{
}

View File

@ -5,6 +5,7 @@ namespace RectorPrefix202209;
use Rector\Config\RectorConfig;
use Rector\Symfony\Rector\MethodCall\AddViolationToBuildViolationRector;
use Rector\Symfony\Rector\MethodCall\MaxLengthSymfonyFormOptionToAttrRector;
return static function (RectorConfig $rectorConfig) : void {
$rectorConfig->rule(AddViolationToBuildViolationRector::class);
$rectorConfig->rules([AddViolationToBuildViolationRector::class, MaxLengthSymfonyFormOptionToAttrRector::class]);
};

View File

@ -10,6 +10,7 @@ use Rector\Renaming\Rector\MethodCall\RenameMethodRector;
use Rector\Renaming\Rector\Name\RenameClassRector;
use Rector\Renaming\ValueObject\MethodCallRename;
use Rector\Renaming\ValueObject\RenameClassConstFetch;
use Rector\Symfony\Rector\Class_\CommandDescriptionToPropertyRector;
use Rector\Symfony\Rector\StaticPropertyFetch\KernelTestCaseContainerPropertyDeprecationRector;
use Rector\Symfony\Set\SymfonySetList;
use Rector\TypeDeclaration\Rector\ClassMethod\AddReturnTypeDeclarationRector;
@ -50,4 +51,5 @@ return static function (RectorConfig $rectorConfig) : void {
new RenameClassConstFetch('Symfony\\Component\\HttpKernel\\HttpKernelInterface', 'MASTER_REQUEST', 'MAIN_REQUEST'),
]);
$rectorConfig->rule(KernelTestCaseContainerPropertyDeprecationRector::class);
$rectorConfig->rule(CommandDescriptionToPropertyRector::class);
};

View File

@ -1,4 +1,4 @@
# 68 Rules Overview
# 70 Rules Overview
## ActionSuffixRemoverRector
@ -714,6 +714,27 @@ Turns properties with `@inject` to private properties and constructor injection
<br>
## KernelTestCaseContainerPropertyDeprecationRector
Simplify use of assertions in WebTestCase
- class: [`Rector\Symfony\Rector\StaticPropertyFetch\KernelTestCaseContainerPropertyDeprecationRector`](../src/Rector/StaticPropertyFetch/KernelTestCaseContainerPropertyDeprecationRector.php)
```diff
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
class SomeTest extends KernelTestCase
{
protected function setUp(): void
{
- $container = self::$container;
+ $container = self::getContainer();
}
}
```
<br>
## LiteralGetToRequestClassConstantRector
Replace "GET" string by Symfony Request object class constants
@ -927,6 +948,23 @@ Make event object a first argument of `dispatch()` method, event name as second
<br>
## MaxLengthSymfonyFormOptionToAttrRector
Change form option "max_length" to a form "attr" > "max_length"
- class: [`Rector\Symfony\Rector\MethodCall\MaxLengthSymfonyFormOptionToAttrRector`](../src/Rector/MethodCall/MaxLengthSymfonyFormOptionToAttrRector.php)
```diff
$formBuilder = new Symfony\Component\Form\FormBuilder();
$form = $formBuilder->create('name', 'text', [
- 'max_length' => 123,
+ 'attr' => ['maxlength' => 123],
]);
```
<br>
## MergeMethodAnnotationToRouteAnnotationRector
Merge removed `@Method` annotation to `@Route` one
@ -1354,9 +1392,9 @@ Change RouteCollectionBuilder to RoutingConfiguratorRector
## ServiceSetStringNameToClassNameRector
Change `$service->set()` string names to class-type-based names, to allow `$container->get()` by types in Symfony 2.8
Change `$service->set()` string names to class-type-based names, to allow `$container->get()` by types in Symfony 2.8. Provide XML config via `$rectorConfig->symfonyContainerXml(...);`
- class: [`Rector\Symfony\Rector\Closure\ServiceSetStringNameToClassNameRector`](../src/Rector/MethodCall/ServiceSetStringNameToClassNameRector.php)
- class: [`Rector\Symfony\Rector\Closure\ServiceSetStringNameToClassNameRector`](../src/Rector/Closure/ServiceSetStringNameToClassNameRector.php)
```diff
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;

View File

@ -130,7 +130,7 @@ CODE_SAMPLE
$arrayItemNodes[] = new ArrayItemNode($defaultsWithoutControllerCurlyList, 'defaults');
}
if ($symfonyRouteMetadata->getHost() !== '') {
$arrayItemNodes[] = new ArrayItemNode($symfonyRouteMetadata->getHost(), 'host');
$arrayItemNodes[] = new ArrayItemNode($symfonyRouteMetadata->getHost(), 'host', String_::KIND_DOUBLE_QUOTED);
}
if ($symfonyRouteMetadata->getSchemes() !== []) {
$schemesArrayItemNodes = $this->createCurlyQuoted($symfonyRouteMetadata->getSchemes());
@ -171,12 +171,17 @@ CODE_SAMPLE
$methodsArrayItems = $this->arrayParser->createArrayFromValues($values);
$curlyListNode = new CurlyListNode($methodsArrayItems);
foreach ($curlyListNode->values as $nestedMethodsArrayItem) {
if (!\is_numeric($nestedMethodsArrayItem->value)) {
if (\is_string($nestedMethodsArrayItem->value)) {
$nestedMethodsArrayItem->kindValueQuoted = String_::KIND_DOUBLE_QUOTED;
}
if (\is_string($nestedMethodsArrayItem->key)) {
$nestedMethodsArrayItem->kindKeyQuoted = String_::KIND_DOUBLE_QUOTED;
}
if ($nestedMethodsArrayItem->value === null) {
$nestedMethodsArrayItem->value = 'null';
} elseif (\is_bool($nestedMethodsArrayItem->value)) {
$nestedMethodsArrayItem->value = $nestedMethodsArrayItem->value ? 'true' : 'false';
}
}
return $curlyListNode;
}

View File

@ -0,0 +1,146 @@
<?php
declare (strict_types=1);
namespace Rector\Symfony\Rector\Class_;
use PhpParser\Node;
use PhpParser\Node\Expr;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\Property;
use PHPStan\Type\ObjectType;
use PHPStan\Type\StringType;
use Rector\Core\NodeAnalyzer\ExprAnalyzer;
use Rector\Core\Rector\AbstractRector;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* @see https://symfony.com/blog/new-in-symfony-5-3-lazy-command-description
*
* @see \Rector\Symfony\Tests\Rector\Class_\CommandDescriptionToPropertyRector\CommandDescriptionToPropertyRectorTest
*/
final class CommandDescriptionToPropertyRector extends AbstractRector
{
/**
* @readonly
* @var \Rector\Core\NodeAnalyzer\ExprAnalyzer
*/
private $exprAnalyzer;
public function __construct(ExprAnalyzer $exprAnalyzer)
{
$this->exprAnalyzer = $exprAnalyzer;
}
public function getRuleDefinition() : RuleDefinition
{
return new RuleDefinition('Symfony Command description setters are moved to properties', [new CodeSample(<<<'CODE_SAMPLE'
use Symfony\Component\Console\Command\Command
final class SunshineCommand extends Command
{
protected static $defaultName = 'sunshine';
public function configure()
{
$this->setDescription('sunshine description');
}
}
CODE_SAMPLE
, <<<'CODE_SAMPLE'
use Symfony\Component\Console\Command\Command
final class SunshineCommand extends Command
{
protected static $defaultName = 'sunshine';
protected static $defaultDescription = 'sunshine description';
public function configure()
{
}
}
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('Symfony\\Component\\Console\\Command\\Command'))) {
return null;
}
$defaultNameProperty = $node->getProperty('defaultDescription');
if ($defaultNameProperty instanceof Property) {
return null;
}
$commandDescription = $this->resolveCommandDescription($node);
if (!$commandDescription instanceof Expr) {
return null;
}
if ($this->exprAnalyzer->isDynamicExpr($commandDescription)) {
return null;
}
$defaultDescriptionProperty = $this->createStaticProtectedPropertyWithDefault('defaultDescription', $commandDescription);
return $this->addDefaultDescriptionProperty($node, $defaultDescriptionProperty);
}
private function resolveCommandDescription(Class_ $class) : ?Node
{
return $this->resolveCommandDescriptionFromSetDescription($class);
}
private function resolveCommandDescriptionFromSetDescription(Class_ $class) : ?Node
{
$commandDescription = null;
$this->traverseNodesWithCallable($class->stmts, function (Node $node) use(&$commandDescription) {
if (!$node instanceof MethodCall) {
return null;
}
if (!$this->isObjectType($node->var, new ObjectType('Symfony\\Component\\Console\\Command\\Command'))) {
return null;
}
if (!$this->isName($node->name, 'setDescription')) {
return null;
}
$commandDescription = $node->getArgs()[0]->value;
$commandDescriptionStaticType = $this->getType($commandDescription);
if (!$commandDescriptionStaticType instanceof StringType) {
return null;
}
// is chain call? → remove by variable nulling
if ($node->var instanceof MethodCall) {
return $node->var;
}
$this->removeNode($node);
});
return $commandDescription;
}
private function createStaticProtectedPropertyWithDefault(string $name, Node $node) : Property
{
$property = new \PhpParser\Builder\Property($name);
$property->makeProtected();
$property->makeStatic();
$property->setDefault($node);
return $property->getNode();
}
private function addDefaultDescriptionProperty(Class_ $class, Property $defaultDescriptionProperty) : Node
{
// When we have property defaultName insert defaultDescription after it.
if ($class->getProperty('defaultName') instanceof Property) {
foreach ($class->stmts as $key => $value) {
if (!$value instanceof Property) {
continue;
}
if ($value->props[0]->name->name === 'defaultName') {
\array_splice($class->stmts, ++$key, 0, [$defaultDescriptionProperty]);
break;
}
}
} else {
$class->stmts = \array_merge($class->stmts, [$defaultDescriptionProperty]);
}
return $class;
}
}

View File

@ -9,7 +9,6 @@ use PhpParser\Node\Expr\ClassConstFetch;
use PhpParser\Node\Expr\ConstFetch;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Expr\StaticCall;
use PhpParser\Node\Param;
use PhpParser\Node\Scalar\String_;
use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\ClassMethod;

View File

@ -0,0 +1,126 @@
<?php
declare (strict_types=1);
namespace Rector\Symfony\Rector\MethodCall;
use PhpParser\Node;
use PhpParser\Node\Arg;
use PhpParser\Node\Expr\Array_;
use PhpParser\Node\Expr\ArrayItem;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Scalar\String_;
use PHPStan\Type\ObjectType;
use Rector\Core\Exception\ShouldNotHappenException;
use Rector\Core\Rector\AbstractRector;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* @changelog https://github.com/symfony/symfony/commit/feea36df99205fd12be52515edeb10fc18523232
* @changelog https://github.com/symfony/symfony-docs/pull/3461
* @changelog https://github.com/symfony/symfony/issues/7148
*
* @see \Rector\Symfony\Tests\Rector\Array_\MaxLengthSymfonyFormOptionToAttrRector\MaxLengthSymfonyFormOptionToAttrRectorTest
*/
final class MaxLengthSymfonyFormOptionToAttrRector extends AbstractRector
{
public function getRuleDefinition() : RuleDefinition
{
return new RuleDefinition('Change form option "max_length" to a form "attr" > "max_length"', [new CodeSample(<<<'CODE_SAMPLE'
$formBuilder = new Symfony\Component\Form\FormBuilder();
$form = $formBuilder->create('name', 'text', [
'max_length' => 123,
]);
CODE_SAMPLE
, <<<'CODE_SAMPLE'
$formBuilder = new Symfony\Component\Form\FormBuilder();
$form = $formBuilder->create('name', 'text', [
'attr' => ['maxlength' => 123],
]);
CODE_SAMPLE
)]);
}
/**
* @return array<class-string<Node>>
*/
public function getNodeTypes() : array
{
return [MethodCall::class];
}
/**
* @param MethodCall $node
*/
public function refactor(Node $node) : ?Node
{
if (!$this->isFormCreateMethodCallMatch($node)) {
return null;
}
$optionsArg = $node->getArgs()[2] ?? null;
if (!$optionsArg instanceof Arg) {
return null;
}
if (!$optionsArg->value instanceof Array_) {
return null;
}
$optionsArray = $optionsArg->value;
$itemToAddToAttrs = null;
foreach ($optionsArray->items as $arrayKey => $arrayItem) {
if (!$arrayItem instanceof ArrayItem) {
continue;
}
if (!$arrayItem->key instanceof String_) {
continue;
}
if (!$this->valueResolver->isValue($arrayItem->key, 'max_length')) {
continue;
}
unset($optionsArray->items[$arrayKey]);
$itemToAddToAttrs = $arrayItem;
break;
}
if (!$itemToAddToAttrs instanceof ArrayItem) {
return null;
}
$this->addArrayItemToAttrsItemOrCreateOne($optionsArray, $itemToAddToAttrs);
return $node;
}
private function matchAttrArrayItem(Array_ $array) : ?ArrayItem
{
foreach ($array->items as $arrayItem) {
if (!$arrayItem instanceof ArrayItem) {
continue;
}
if (!$arrayItem->key instanceof String_) {
continue;
}
if (!$this->valueResolver->isValue($arrayItem->key, 'attrs')) {
continue;
}
return $arrayItem;
}
return null;
}
private function addArrayItemToAttrsItemOrCreateOne(Array_ $array, ArrayItem $arrayItem) : Array_
{
// rename
$arrayItem->key = new String_('maxlength');
$attrArrayItem = $this->matchAttrArrayItem($array);
if ($attrArrayItem instanceof ArrayItem) {
if (!$attrArrayItem->value instanceof Array_) {
throw new ShouldNotHappenException();
}
$attrArrayItem->value->items[] = $arrayItem;
return $array;
}
$array->items[] = new ArrayItem(new Array_([$arrayItem]), new String_('attr'));
return $array;
}
private function isFormCreateMethodCallMatch(MethodCall $methodCall) : bool
{
if (!$this->isObjectType($methodCall->var, new ObjectType('Symfony\\Component\\Form\\FormFactoryInterface')) && !$this->isObjectType($methodCall->var, new ObjectType('Symfony\\Component\\Form\\FormBuilderInterface'))) {
return \false;
}
return $this->isNames($methodCall->name, ['create', 'add']);
}
}