Updated Rector to commit 3942c1336b9650e7013094e6ae7118675ea04685

3942c1336b Use link to getrector.com/documentation for create_own_rule.md on build scoped (#4973)
This commit is contained in:
Tomas Votruba 2023-09-10 18:55:54 +00:00
parent aaa2d927d5
commit e9556eff4d
5 changed files with 15 additions and 179 deletions

View File

@ -1,169 +1,5 @@
# 3 Steps to Create Your Own Rector
# Steps to Create Your Own Rector
First, make sure it's not covered by [any existing Rectors](/docs/rector_rules_overview.md).
Let's say we want to **change method calls from `set*` to `change*`**.
This page was moved to new documentation.
```diff
$user = new User();
-$user->setPassword('123456');
+$user->changePassword('123456');
```
## 1. Create a New Rector and Implement Methods
Create a class that extends [`Rector\Core\Rector\AbstractRector`](/src/Rector/AbstractRector.php). It will inherit useful methods e.g. to check node type and name. See the source (or type `$this->` in an IDE) for a list of available methods.
```php
declare(strict_types=1);
namespace Utils\Rector\Rector;
use Nette\Utils\Strings;
use PhpParser\Node;
use PhpParser\Node\Identifier;
use PhpParser\Node\Expr\MethodCall;
use Rector\Core\Rector\AbstractRector;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
final class MyFirstRector extends AbstractRector
{
/**
* @return array<class-string<Node>>
*/
public function getNodeTypes(): array
{
// what node types are we looking for?
// pick any node from https://github.com/rectorphp/php-parser-nodes-docs/
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 "set*" method names
if (! $this->isName($node->name, 'set*')) {
// return null to skip it
return null;
}
$methodCallName = $this->getName($node->name);
$newMethodCallName = Strings::replace($methodCallName, '#^set#', 'change');
$node->name = new Identifier($newMethodCallName);
// return $node if you modified it
return $node;
}
/**
* This method helps other to understand the rule and to generate documentation.
*/
public function getRuleDefinition(): RuleDefinition
{
return new RuleDefinition(
'Change method calls from set* to change*.', [
new CodeSample(
// code before
'$user->setPassword("123456");',
// code after
'$user->changePassword("123456");'
),
]
);
}
}
```
## File Structure
This is how the file structure for custom rule in your own project will look like:
```bash
/src/
/YourCode.php
/utils
/rector
/src
/Rector
MyFirstRector.php
rector.php
composer.json
```
Writing test saves you lot of time in future debugging. Here is a file structure with tests:
```bash
/src/
/YourCode.php
/utils
/rector
/src
/Rector
MyFirstRector.php
/tests
/Rector
/MyFirstRector
/Fixture
test_fixture.php.inc
/config
config.php
MyFirstRectorTest.php
rector.php
composer.json
```
## Update `composer.json`
We also need to load Rector rules in `composer.json`:
```json
{
"autoload": {
"psr-4": {
"App\\": "src"
}
},
"autoload-dev": {
"psr-4": {
"Utils\\Rector\\": "utils/rector/src",
"Utils\\Rector\\Tests\\": "utils/rector/tests"
}
}
}
```
After adding this to `composer.json`, be sure to reload Composer's class map:
```bash
composer dump-autoload
```
## 2. Register It
```php
use Utils\Rector\Rector\MyFirstRector;
use Rector\Config\RectorConfig;
return static function (RectorConfig $rectorConfig): void {
$rectorConfig->rule(MyFirstRector::class);
};
```
## 3. Let Rector Refactor Your Code
The `rector.php` configuration is loaded by default, so we can skip it.
```bash
# see the diff first
vendor/bin/rector process src --dry-run
# if it's ok, apply
vendor/bin/rector process src
```
That's it!
You can find it here: https://getrector.com/documentation/

View File

@ -19,12 +19,12 @@ final class VersionResolver
* @api
* @var string
*/
public const PACKAGE_VERSION = 'cda957718f1eb9d1629bc27ed8b060c6f41ce033';
public const PACKAGE_VERSION = '3942c1336b9650e7013094e6ae7118675ea04685';
/**
* @api
* @var string
*/
public const RELEASE_DATE = '2023-09-11 01:44:58';
public const RELEASE_DATE = '2023-09-10 18:52:57';
/**
* @var int
*/

2
vendor/autoload.php vendored
View File

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

View File

@ -2,7 +2,7 @@
// autoload_real.php @generated by Composer
class ComposerAutoloaderInit8bff98b209525c681c1ca842fdc76b10
class ComposerAutoloaderInit6efda7140e08060e1e4da3c76bc70d34
{
private static $loader;
@ -22,17 +22,17 @@ class ComposerAutoloaderInit8bff98b209525c681c1ca842fdc76b10
return self::$loader;
}
spl_autoload_register(array('ComposerAutoloaderInit8bff98b209525c681c1ca842fdc76b10', 'loadClassLoader'), true, true);
spl_autoload_register(array('ComposerAutoloaderInit6efda7140e08060e1e4da3c76bc70d34', 'loadClassLoader'), true, true);
self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__));
spl_autoload_unregister(array('ComposerAutoloaderInit8bff98b209525c681c1ca842fdc76b10', 'loadClassLoader'));
spl_autoload_unregister(array('ComposerAutoloaderInit6efda7140e08060e1e4da3c76bc70d34', 'loadClassLoader'));
require __DIR__ . '/autoload_static.php';
call_user_func(\Composer\Autoload\ComposerStaticInit8bff98b209525c681c1ca842fdc76b10::getInitializer($loader));
call_user_func(\Composer\Autoload\ComposerStaticInit6efda7140e08060e1e4da3c76bc70d34::getInitializer($loader));
$loader->setClassMapAuthoritative(true);
$loader->register(true);
$filesToLoad = \Composer\Autoload\ComposerStaticInit8bff98b209525c681c1ca842fdc76b10::$files;
$filesToLoad = \Composer\Autoload\ComposerStaticInit6efda7140e08060e1e4da3c76bc70d34::$files;
$requireFile = \Closure::bind(static function ($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 ComposerStaticInit8bff98b209525c681c1ca842fdc76b10
class ComposerStaticInit6efda7140e08060e1e4da3c76bc70d34
{
public static $files = array (
'ad155f8f1cf0d418fe49e248db8c661b' => __DIR__ . '/..' . '/react/promise/src/functions_include.php',
@ -2599,9 +2599,9 @@ class ComposerStaticInit8bff98b209525c681c1ca842fdc76b10
public static function getInitializer(ClassLoader $loader)
{
return \Closure::bind(function () use ($loader) {
$loader->prefixLengthsPsr4 = ComposerStaticInit8bff98b209525c681c1ca842fdc76b10::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInit8bff98b209525c681c1ca842fdc76b10::$prefixDirsPsr4;
$loader->classMap = ComposerStaticInit8bff98b209525c681c1ca842fdc76b10::$classMap;
$loader->prefixLengthsPsr4 = ComposerStaticInit6efda7140e08060e1e4da3c76bc70d34::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInit6efda7140e08060e1e4da3c76bc70d34::$prefixDirsPsr4;
$loader->classMap = ComposerStaticInit6efda7140e08060e1e4da3c76bc70d34::$classMap;
}, null, ClassLoader::class);
}