ActionSuffixRemoverRector

This commit is contained in:
mssimi 2018-04-10 21:29:55 +02:00
parent b74f88e786
commit 7c5fe14828
9 changed files with 145 additions and 3 deletions

View File

@ -10,6 +10,14 @@ use Rector\Node\Attribute;
final class ControllerMethodAnalyzer final class ControllerMethodAnalyzer
{ {
/**
* @var string[]
*/
private $supportedClasses = [
'Symfony\Bundle\FrameworkBundle\Controller\Controller',
'Symfony\Bundle\FrameworkBundle\Controller\AbstractController',
];
/** /**
* Detect if is <some>Action() in Controller * Detect if is <some>Action() in Controller
*/ */
@ -20,9 +28,8 @@ final class ControllerMethodAnalyzer
} }
$parentClassName = $node->getAttribute(Attribute::PARENT_CLASS_NAME); $parentClassName = $node->getAttribute(Attribute::PARENT_CLASS_NAME);
$controllerClass = 'Symfony\Bundle\FrameworkBundle\Controller\Controller';
if ($parentClassName !== $controllerClass) { if (! in_array($parentClassName, $this->supportedClasses, true)) {
return false; return false;
} }

View File

@ -8,6 +8,7 @@ use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Expr\PropertyFetch; use PhpParser\Node\Expr\PropertyFetch;
use PhpParser\Node\Expr\StaticCall; use PhpParser\Node\Expr\StaticCall;
use PhpParser\Node\Identifier; use PhpParser\Node\Identifier;
use PhpParser\Node\Stmt\ClassMethod;
use Rector\Exception\NodeChanger\NodeMissingIdentifierException; use Rector\Exception\NodeChanger\NodeMissingIdentifierException;
final class IdentifierRenamer final class IdentifierRenamer
@ -16,7 +17,7 @@ final class IdentifierRenamer
* @var string[] * @var string[]
*/ */
private $nodeClassesWithIdentifier = [ private $nodeClassesWithIdentifier = [
ClassConstFetch::class, MethodCall::class, PropertyFetch::class, StaticCall::class, ClassConstFetch::class, MethodCall::class, PropertyFetch::class, StaticCall::class, ClassMethod::class,
]; ];
public function renameNode(Node $node, string $newMethodName): void public function renameNode(Node $node, string $newMethodName): void
@ -38,6 +39,13 @@ final class IdentifierRenamer
$node->name = new Identifier($renameMethodMap[$oldNodeMethodName]); $node->name = new Identifier($renameMethodMap[$oldNodeMethodName]);
} }
public function removeSuffix(Node $node, string $suffixToRemove): void
{
$this->ensureNodeHasIdentifier($node);
$node->name = new Identifier(preg_replace(sprintf('/%s$/', $suffixToRemove), '', $node->name));
}
private function ensureNodeHasIdentifier(Node $node): void private function ensureNodeHasIdentifier(Node $node): void
{ {
if (in_array(get_class($node), $this->nodeClassesWithIdentifier, true)) { if (in_array(get_class($node), $this->nodeClassesWithIdentifier, true)) {

View File

@ -0,0 +1,50 @@
<?php declare(strict_types=1);
namespace Rector\Rector\Contrib\Symfony\Controller;
use PhpParser\Node;
use Rector\NodeAnalyzer\Contrib\Symfony\ControllerMethodAnalyzer;
use Rector\NodeChanger\IdentifierRenamer;
use Rector\Rector\AbstractRector;
use Rector\RectorDefinition\CodeSample;
use Rector\RectorDefinition\RectorDefinition;
final class ActionSuffixRemoverRector extends AbstractRector
{
/**
* @var ControllerMethodAnalyzer
*/
private $controllerMethodAnalyzer;
/**
* @var IdentifierRenamer
*/
private $identifierRenamer;
public function __construct(
ControllerMethodAnalyzer $controllerMethodAnalyzer,
IdentifierRenamer $identifierRenamer
) {
$this->controllerMethodAnalyzer = $controllerMethodAnalyzer;
$this->identifierRenamer = $identifierRenamer;
}
public function isCandidate(Node $node): bool
{
return $this->controllerMethodAnalyzer->isAction($node);
}
public function refactor(Node $node): ?Node
{
$this->identifierRenamer->removeSuffix($node, 'Action');
return $node;
}
public function getDefinition(): RectorDefinition
{
return new RectorDefinition('Removes Action suffixes from methods in Symfony Controllers', [
new CodeSample('public function indexAction(){...}', 'public function index(){...}'),
]);
}
}

View File

@ -0,0 +1,35 @@
<?php declare(strict_types=1);
namespace Rector\Tests\Rector\Contrib\Symfony\Controller\ActionSuffixRemoverRector;
use Rector\Testing\PHPUnit\AbstractRectorTestCase;
/**
* @covers \Rector\Rector\Contrib\Symfony\Controller\ActionSuffixRemoverRector
*/
final class AddFlashRectorTest extends AbstractRectorTestCase
{
/**
* @dataProvider provideWrongToFixedFiles()
*/
public function test(string $wrong, string $fixed): void
{
$this->doTestFileMatchesExpectedContent($wrong, $fixed);
}
/**
* @return string[][]
*/
public function provideWrongToFixedFiles(): array
{
return [
[__DIR__ . '/Wrong/wrong.php.inc', __DIR__ . '/Correct/correct.php.inc'],
[__DIR__ . '/Wrong/wrong2.php.inc', __DIR__ . '/Correct/correct2.php.inc'],
];
}
protected function provideConfig(): string
{
return __DIR__ . '/config.yml';
}
}

View File

@ -0,0 +1,10 @@
<?php declare (strict_types=1);
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class AppController extends Controller
{
public function index()
{
}
}

View File

@ -0,0 +1,10 @@
<?php declare (strict_types=1);
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
class AppController extends AbstractController
{
public function index()
{
}
}

View File

@ -0,0 +1,10 @@
<?php declare (strict_types=1);
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class AppController extends Controller
{
public function indexAction()
{
}
}

View File

@ -0,0 +1,10 @@
<?php declare (strict_types=1);
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
class AppController extends AbstractController
{
public function indexAction()
{
}
}

View File

@ -0,0 +1,2 @@
services:
Rector\Rector\Contrib\Symfony\Controller\ActionSuffixRemoverRector: ~