diff --git a/docs/rector_rules_overview.md b/docs/rector_rules_overview.md index ccfd7ec8541..2636e2bbb7f 100644 --- a/docs/rector_rules_overview.md +++ b/docs/rector_rules_overview.md @@ -1,4 +1,4 @@ -# All 515 Rectors Overview +# All 518 Rectors Overview - [Projects](#projects) - [General](#general) @@ -13,6 +13,7 @@ - [CodeQuality](#codequality) (54) - [CodingStyle](#codingstyle) (34) - [DeadCode](#deadcode) (40) +- [Decomplex](#decomplex) (1) - [Decouple](#decouple) (1) - [Doctrine](#doctrine) (16) - [DoctrineCodeQuality](#doctrinecodequality) (2) @@ -24,6 +25,7 @@ - [Laravel](#laravel) (6) - [Legacy](#legacy) (2) - [MagicDisclosure](#magicdisclosure) (5) +- [MockeryToProphecy](#mockerytoprophecy) (1) - [MockistaToMockery](#mockistatomockery) (2) - [MysqlToMysqli](#mysqltomysqli) (4) - [Naming](#naming) (2) @@ -62,7 +64,7 @@ - [SOLID](#solid) (12) - [Sensio](#sensio) (3) - [StrictCodeQuality](#strictcodequality) (1) -- [Symfony](#symfony) (29) +- [Symfony](#symfony) (30) - [SymfonyCodeQuality](#symfonycodequality) (1) - [SymfonyPHPUnit](#symfonyphpunit) (1) - [Twig](#twig) (1) @@ -3240,6 +3242,31 @@ Change ternary of bool : false to && bool

+## Decomplex + +### `UseMessageVariableForSprintfInSymfonyStyleRector` + +- class: [`Rector\Decomplex\Rector\MethodCall\UseMessageVariableForSprintfInSymfonyStyleRector`](/../master/rules/decomplex/src/Rector/MethodCall/UseMessageVariableForSprintfInSymfonyStyleRector.php) +- [test fixtures](/../master/rules/decomplex/tests/Rector/MethodCall/UseMessageVariableForSprintfInSymfonyStyleRector/Fixture) + +Decouple $message property from `sprintf()` calls in `$this->smyfonyStyle->method()` + +```diff + use Symfony\Component\Console\Style\SymfonyStyle; + + final class SomeClass + { + public function run(SymfonyStyle $symfonyStyle) + { +- $symfonyStyle->info(sprintf('Hi %s', 'Tom')); ++ $message = sprintf('Hi %s', 'Tom'); ++ $symfonyStyle->info($message); + } + } +``` + +

+ ## Decouple ### `DecoupleClassMethodToOwnClassRector` @@ -4689,6 +4716,25 @@ services:

+## MockeryToProphecy + +### `MockeryCreateMockToProphizeRector` + +- class: [`Rector\MockeryToProphecy\Rector\MethodCall\MockeryCreateMockToProphizeRector`](/../master/rules/mockery-to-prophecy/src/Rector/MethodCall/MockeryCreateMockToProphizeRector.php) + +Changes mockery mock creation to Prophesize + +```diff +-$mock = \Mockery::mock(\'MyClass\'); ++ $mock = $this->prophesize(\'MyClass\'); ++ + $service = new Service(); +-$service->injectDependency($mock); ++$service->injectDependency($mock->reveal()); +``` + +

+ ## MockistaToMockery ### `MockeryTearDownRector` @@ -10539,6 +10585,36 @@ Change "cascade_validation" option to specific node attribute

+### `ChangeXmlToYamlFileLoaderInExtensionRector` + +- class: [`Rector\Symfony\Rector\Class_\ChangeXmlToYamlFileLoaderInExtensionRector`](/../master/rules/symfony/src/Rector/Class_/ChangeXmlToYamlFileLoaderInExtensionRector.php) +- [test fixtures](/../master/rules/symfony/tests/Rector/Class_/ChangeXmlToYamlFileLoaderInExtensionRector/Fixture) + +Change XML loader to YAML in Bundle Extension + +```diff + use Symfony\Component\Config\FileLocator; + use Symfony\Component\DependencyInjection\ContainerBuilder; +-use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; ++use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; + use Symfony\Component\HttpKernel\DependencyInjection\Extension; + + final class SomeExtension extends Extension + { + public function load(array $configs, ContainerBuilder $container) + { +- $loader = new XmlFileLoader($container, new FileLocator()); +- $loader->load(__DIR__ . '/../Resources/config/controller.xml'); +- $loader->load(__DIR__ . '/../Resources/config/events.xml'); ++ $loader = new YamlFileLoader($container, new FileLocator()); ++ $loader->load(__DIR__ . '/../Resources/config/controller.yaml'); ++ $loader->load(__DIR__ . '/../Resources/config/events.yaml'); + } + } +``` + +

+ ### `ConsoleExceptionToErrorEventConstantRector` - class: [`Rector\Symfony\Rector\Console\ConsoleExceptionToErrorEventConstantRector`](/../master/rules/symfony/src/Rector/Console/ConsoleExceptionToErrorEventConstantRector.php) diff --git a/rules/symfony/src/Rector/Class_/ChangeXmlToYamlFileLoaderInExtensionRector.php b/rules/symfony/src/Rector/Class_/ChangeXmlToYamlFileLoaderInExtensionRector.php new file mode 100644 index 00000000000..1cd1417d1c7 --- /dev/null +++ b/rules/symfony/src/Rector/Class_/ChangeXmlToYamlFileLoaderInExtensionRector.php @@ -0,0 +1,141 @@ +load(__DIR__ . '/../Resources/config/controller.xml'); + $loader->load(__DIR__ . '/../Resources/config/events.xml'); + } +} +PHP +, + <<<'PHP' +use Symfony\Component\Config\FileLocator; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; +use Symfony\Component\HttpKernel\DependencyInjection\Extension; + +final class SomeExtension extends Extension +{ + public function load(array $configs, ContainerBuilder $container) + { + $loader = new YamlFileLoader($container, new FileLocator()); + $loader->load(__DIR__ . '/../Resources/config/controller.yaml'); + $loader->load(__DIR__ . '/../Resources/config/events.yaml'); + } +} +PHP + + ), + ]); + } + + /** + * @return string[] + */ + public function getNodeTypes(): array + { + return [Class_::class]; + } + + /** + * @param Class_ $node + */ + public function refactor(Node $node): ?Node + { + if (! $this->isObjectType($node, 'Symfony\Component\HttpKernel\DependencyInjection\Extension')) { + return null; + } + + $loadClassMethod = $node->getMethod('load'); + if ($loadClassMethod === null) { + return null; + } + + $this->traverseNodesWithCallable((array) $loadClassMethod->stmts, function (Node $node) { + if ($node instanceof New_) { + if (! $this->isName($node->class, 'Symfony\Component\DependencyInjection\Loader\XmlFileLoader')) { + return null; + } + + $node->class = new FullyQualified('Symfony\Component\DependencyInjection\Loader\YamlFileLoader'); + return $node; + } + + return $this->refactorLoadMethodCall($node); + }); + + return $node; + } + + private function refactorLoadMethodCall(Node $node): ?Node + { + if (! $node instanceof MethodCall) { + return null; + } + + if (! $node->var instanceof Variable) { + return null; + } + + if (! $this->isObjectType($node->var, 'Symfony\Component\DependencyInjection\Loader\XmlFileLoader')) { + return null; + } + + if (! $this->isName($node->name, 'load')) { + return null; + } + + $this->replaceXmlWithYamlSuffix($node); + return $node; + } + + private function replaceXmlWithYamlSuffix(MethodCall $methodCall): void + { + // replace XML to YAML suffix in string parts + $fileArgument = $methodCall->args[0]->value; + + $this->traverseNodesWithCallable([$fileArgument], function (Node $node): ?Node { + if (! $node instanceof String_) { + return null; + } + + $node->value = Strings::replace($node->value, '#\.xml$#', '.yaml'); + + return $node; + }); + } +} diff --git a/rules/symfony/tests/Rector/Class_/ChangeXmlToYamlFileLoaderInExtensionRector/ChangeXmlToYamlFileLoaderInExtensionRectorTest.php b/rules/symfony/tests/Rector/Class_/ChangeXmlToYamlFileLoaderInExtensionRector/ChangeXmlToYamlFileLoaderInExtensionRectorTest.php new file mode 100644 index 00000000000..879e54e9546 --- /dev/null +++ b/rules/symfony/tests/Rector/Class_/ChangeXmlToYamlFileLoaderInExtensionRector/ChangeXmlToYamlFileLoaderInExtensionRectorTest.php @@ -0,0 +1,31 @@ +doTestFileInfo($fileInfo); + } + + public function provideData(): Iterator + { + return $this->yieldFilesFromDirectory(__DIR__ . '/Fixture'); + } + + protected function getRectorClass(): string + { + return ChangeXmlToYamlFileLoaderInExtensionRector::class; + } +} diff --git a/rules/symfony/tests/Rector/Class_/ChangeXmlToYamlFileLoaderInExtensionRector/Fixture/fixture.php.inc b/rules/symfony/tests/Rector/Class_/ChangeXmlToYamlFileLoaderInExtensionRector/Fixture/fixture.php.inc new file mode 100644 index 00000000000..9d8680cd848 --- /dev/null +++ b/rules/symfony/tests/Rector/Class_/ChangeXmlToYamlFileLoaderInExtensionRector/Fixture/fixture.php.inc @@ -0,0 +1,41 @@ +load(__DIR__ . '/../Resources/config/controller.xml'); + $loader->load(__DIR__ . '/../Resources/config/events.xml'); + } +} + +?> +----- +load(__DIR__ . '/../Resources/config/controller.yaml'); + $loader->load(__DIR__ . '/../Resources/config/events.yaml'); + } +} + +?>