From 37c1301c5eb496067db5d6217b23055db1928fb5 Mon Sep 17 00:00:00 2001 From: Tomas Votruba Date: Fri, 2 Nov 2018 16:31:20 +0100 Subject: [PATCH] [Symfony] Add RootNodeTreeBuilderRector --- config/level/symfony/symfony42.yml | 1 + .../Rector/New_/RootNodeTreeBuilderRector.php | 128 ++++++++++++++++++ .../Correct/correct.php.inc | 13 ++ .../Correct/correct2.php.inc | 8 ++ .../RootNodeTreeBuilderRectorTest.php | 31 +++++ .../Source/TreeBuilder.php | 8 ++ .../Wrong/wrong.php.inc | 13 ++ .../Wrong/wrong2.php.inc | 8 ++ .../New_/RootNodeTreeBuilderRector/config.yml | 3 + 9 files changed, 213 insertions(+) create mode 100644 packages/Symfony/src/Rector/New_/RootNodeTreeBuilderRector.php create mode 100644 packages/Symfony/tests/Rector/New_/RootNodeTreeBuilderRector/Correct/correct.php.inc create mode 100644 packages/Symfony/tests/Rector/New_/RootNodeTreeBuilderRector/Correct/correct2.php.inc create mode 100644 packages/Symfony/tests/Rector/New_/RootNodeTreeBuilderRector/RootNodeTreeBuilderRectorTest.php create mode 100644 packages/Symfony/tests/Rector/New_/RootNodeTreeBuilderRector/Source/TreeBuilder.php create mode 100644 packages/Symfony/tests/Rector/New_/RootNodeTreeBuilderRector/Wrong/wrong.php.inc create mode 100644 packages/Symfony/tests/Rector/New_/RootNodeTreeBuilderRector/Wrong/wrong2.php.inc create mode 100644 packages/Symfony/tests/Rector/New_/RootNodeTreeBuilderRector/config.yml diff --git a/config/level/symfony/symfony42.yml b/config/level/symfony/symfony42.yml index 41861c3e1a7..a628c4f1805 100644 --- a/config/level/symfony/symfony42.yml +++ b/config/level/symfony/symfony42.yml @@ -1,3 +1,4 @@ services: # https://symfony.com/blog/new-in-symfony-4-2-important-deprecations Rector\Symfony\Rector\New_\StringToArrayArgumentProcessRector: ~ + Rector\Symfony\Rector\New_\RootNodeTreeBuilderRector: ~ diff --git a/packages/Symfony/src/Rector/New_/RootNodeTreeBuilderRector.php b/packages/Symfony/src/Rector/New_/RootNodeTreeBuilderRector.php new file mode 100644 index 00000000000..ccde6489803 --- /dev/null +++ b/packages/Symfony/src/Rector/New_/RootNodeTreeBuilderRector.php @@ -0,0 +1,128 @@ +betterNodeFinder = $betterNodeFinder; + $this->treeBuilderClass = $treeBuilderClass; + } + + public function getDefinition(): RectorDefinition + { + return new RectorDefinition('Changes Process string argument to an array', [ + new CodeSample( + <<<'CODE_SAMPLE' +use Symfony\Component\Config\Definition\Builder\TreeBuilder; + +$treeBuilder = new TreeBuilder(); +$rootNode = $treeBuilder->root('acme_root'); +$rootNode->someCall(); +CODE_SAMPLE + , + <<<'CODE_SAMPLE' +use Symfony\Component\Config\Definition\Builder\TreeBuilder; + +$treeBuilder = new TreeBuilder('acme_root'); +$rootNode = $treeBuilder->getRootNode(); +$rootNode->someCall(); +CODE_SAMPLE + ), + ]); + } + + /** + * @return string[] + */ + public function getNodeTypes(): array + { + return [New_::class]; + } + + /** + * @param New_ $node + */ + public function refactor(Node $node): ?Node + { + if (! $this->isType($node->class, $this->treeBuilderClass)) { + return null; + } + + if (isset($node->args[1])) { + return null; + } + + /** @var MethodCall|null $rootMethodCallNode */ + $rootMethodCallNode = $this->getRootMethodCallNode($node); + if ($rootMethodCallNode === null) { + return null; + } + + $rootNameNode = $rootMethodCallNode->args[0]->value; + if (! $rootNameNode instanceof String_) { + return null; + } + + // switch arguments + [$node->args, $rootMethodCallNode->args] = [$rootMethodCallNode->args, $node->args]; + + $rootMethodCallNode->name = new Identifier('getRootNode'); + + return $node; + } + + private function getRootMethodCallNode(Node $node): ?Node + { + /** @var Node $node */ + $expression = $node->getAttribute(Attribute::CURRENT_EXPRESSION); + $nextExpression = $expression->getAttribute(Attribute::NEXT_NODE); + + return $this->betterNodeFinder->findFirst([$nextExpression], function (Node $node) { + if (! $node instanceof MethodCall) { + return false; + } + + if (! $this->isType($node, $this->treeBuilderClass)) { + return false; + } + + if (! $this->isName($node, 'root')) { + return false; + } + + if (! isset($node->args[0])) { + return false; + } + + return true; + }); + } +} diff --git a/packages/Symfony/tests/Rector/New_/RootNodeTreeBuilderRector/Correct/correct.php.inc b/packages/Symfony/tests/Rector/New_/RootNodeTreeBuilderRector/Correct/correct.php.inc new file mode 100644 index 00000000000..0c401ab6787 --- /dev/null +++ b/packages/Symfony/tests/Rector/New_/RootNodeTreeBuilderRector/Correct/correct.php.inc @@ -0,0 +1,13 @@ +getRootNode(); +$rootNode->someCall(); + +$treeBuilder = new TreeBuilder('already_root'); +$rootNode = $treeBuilder->root(); +$rootNode->someCall(); diff --git a/packages/Symfony/tests/Rector/New_/RootNodeTreeBuilderRector/Correct/correct2.php.inc b/packages/Symfony/tests/Rector/New_/RootNodeTreeBuilderRector/Correct/correct2.php.inc new file mode 100644 index 00000000000..8f32e9a20ab --- /dev/null +++ b/packages/Symfony/tests/Rector/New_/RootNodeTreeBuilderRector/Correct/correct2.php.inc @@ -0,0 +1,8 @@ +getRootNode(); diff --git a/packages/Symfony/tests/Rector/New_/RootNodeTreeBuilderRector/RootNodeTreeBuilderRectorTest.php b/packages/Symfony/tests/Rector/New_/RootNodeTreeBuilderRector/RootNodeTreeBuilderRectorTest.php new file mode 100644 index 00000000000..085fd72fd3b --- /dev/null +++ b/packages/Symfony/tests/Rector/New_/RootNodeTreeBuilderRector/RootNodeTreeBuilderRectorTest.php @@ -0,0 +1,31 @@ +doTestFileMatchesExpectedContent($wrong, $fixed); + } + + public function provideWrongToFixedFiles(): Iterator + { + yield [__DIR__ . '/Wrong/wrong.php.inc', __DIR__ . '/Correct/correct.php.inc']; + yield [__DIR__ . '/Wrong/wrong2.php.inc', __DIR__ . '/Correct/correct2.php.inc']; + } + + protected function provideConfig(): string + { + return __DIR__ . '/config.yml'; + } +} diff --git a/packages/Symfony/tests/Rector/New_/RootNodeTreeBuilderRector/Source/TreeBuilder.php b/packages/Symfony/tests/Rector/New_/RootNodeTreeBuilderRector/Source/TreeBuilder.php new file mode 100644 index 00000000000..53405bed373 --- /dev/null +++ b/packages/Symfony/tests/Rector/New_/RootNodeTreeBuilderRector/Source/TreeBuilder.php @@ -0,0 +1,8 @@ +root('acme_root'); +$rootNode->someCall(); + +$treeBuilder = new TreeBuilder('already_root'); +$rootNode = $treeBuilder->root(); +$rootNode->someCall(); diff --git a/packages/Symfony/tests/Rector/New_/RootNodeTreeBuilderRector/Wrong/wrong2.php.inc b/packages/Symfony/tests/Rector/New_/RootNodeTreeBuilderRector/Wrong/wrong2.php.inc new file mode 100644 index 00000000000..24493ad6674 --- /dev/null +++ b/packages/Symfony/tests/Rector/New_/RootNodeTreeBuilderRector/Wrong/wrong2.php.inc @@ -0,0 +1,8 @@ +root('override', 'array', new \stdClass()); diff --git a/packages/Symfony/tests/Rector/New_/RootNodeTreeBuilderRector/config.yml b/packages/Symfony/tests/Rector/New_/RootNodeTreeBuilderRector/config.yml new file mode 100644 index 00000000000..69062c3ab4e --- /dev/null +++ b/packages/Symfony/tests/Rector/New_/RootNodeTreeBuilderRector/config.yml @@ -0,0 +1,3 @@ +services: + Rector\Symfony\Rector\New_\RootNodeTreeBuilderRector: + $treeBuilderClass: 'Rector\Symfony\Tests\Rector\New_\RootNodeTreeBuilderRector\Source\TreeBuilder'