mirror of
https://github.com/rectorphp/rector.git
synced 2025-02-24 11:44:14 +01:00
3.0 KiB
3.0 KiB
4 Steps Create Own Rector
First, make sure your needs is not covered by any existing Rectors.
Let's say you want to prefix private method call names starting with "internal" with _
. Not very practical, but it will show the Rector flow.
1. New Class
Create class that extends Rector\Rector\AbstractRector
. It has many useful methods for checking node type, name, add nodes or remove one. Just run $this->
and let PHPStorm show you all possible methods.
There 3 methods to implement:
<?php declare(strict_types=1);
namespace App\Rector;
use PhpParser\Node;
use Rector\Rector\AbstractRector;
use Rector\RectorDefinition\RectorDefinition;
final class MyFirstRector extends AbstractRector
{
public function getDefinition(): RectorDefinition
{
// what does this do?
// minimalistic before/after sample - to explain in code
}
/**
* @return string[]
*/
public function getNodeTypes(): array
{
// what node types we look for?
// String_? FuncCall?
// pick any from https://github.com/nikic/PHP-Parser/tree/master/lib/PhpParser/Node
return [];
}
public function refactor(Node $node): ?Node
{
// what will happen with the node?
// common work flow:
// - should skip? → return null;
// - modify it? → do it, then return $node;
// - remove/add nodes elsewhere? → do it, then return null;
}
}
2. Add Methods
<?php declare(strict_types=1);
namespace App\Rector;
use PhpParser\Node;
use PhpParser\Node\Identifier;
use PhpParser\Node\Expr\MethodCall;
use Rector\Rector\AbstractRector;
use Rector\RectorDefinition\CodeSample;
use Rector\RectorDefinition\RectorDefinition;
final class MyFirstRector extends AbstractRector
{
public function getDefinition(): RectorDefinition
{
return new RectorDefinition('Add "_" to private method calls that start with "internal"', [
new CodeSample('$this->internalMethod();', '$this->_internalMethod();')
]);
}
/**
* @return string[]
*/
public function getNodeTypes(): array
{
return [MethodCall::class];
}
/**
* @param MethodCall $node - we can add "MethodCall" type here, because only this node is in "getNodeTypes()"
*/
public function refactor(Node $node): ?Node
{
// we only care about "internal*" method names
if (! $this->nameStartsWith($node, 'internal')) {
return null;
}
$node->name = new Identifier('_' . $this->getName($node));
return $node;
}
}
3. Register it rector.yml
services:
+ App\Rector\MyFirstRector: ~
4. Let Rector Refactor Your Code
vendor/bin/rector process src --dry-run
# apply it
vendor/bin/rector process src
If you use rector.yml
from another directory or another name, set it with --config
option:
vendor/bin/rector process src --config ../custom-rector.yml
That's it!