diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 770c6285b3d..78e4e248a54 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -1,28 +1,36 @@
# How to Contribute
-Contributions here are more than welcomed! You can contribute to [rector-src](https://github.com/rectorphp/rector-src) repository.
+Contributions here are more than welcomed! You can contribute to [rector-src](https://github.com/rectorphp/rector-src) repository or one of [extension packages](https://github.com/rectorphp/).
## Preparing Local Environment
-If you have PHP 8 and Composer installed locally you can use it straight away. You can validate your environment with:
+1. Fork the [rector/rector-src](https://github.com/rectorphp/rector-src) repository and clone it
+
+```bash
+git clone git@github.com:rectorphp/rector-src.git
+cd rector-src
+```
+
+2. We use PHP 8.1 and composer
+
+Verify your local environment and update dependencies:
```bash
composer check-platform-reqs
+composer update
```
-Alternatively you can use Docker runtime. All you need to do is wrap every command with `docker-compose run php`, so commands will be executed inside Docker container.
+*Note: using Docker for contributing is strongly discouraged, as it requires [extra knowledge of composer internals](https://github.com/composer/composer/issues/9368#issuecomment-718112361).*
-For example, to download PHP dependencies:
+Then you can start working with the code :+1:
-```bash
-docker-compose run php composer install
-```
+
-Now you can start using all scripts and work with the code.
+Do you want to **contribute a failing test**? [This tutorial will sow you how](https://github.com/rectorphp/rector/blob/main/docs/how_to_add_test_for_rector_rule.md)
## Preparing Pull Request
-There 3 rules will highly increase chance to get your PR merged:
+There 3 steps will make your pull-request easy to merge:
- **1 feature per pull-request**
- **new features need tests**
diff --git a/README.md b/README.md
index bb7f7905675..b1f147a193b 100644
--- a/README.md
+++ b/README.md
@@ -8,7 +8,7 @@ Rector instantly upgrades and refactors the PHP code of your application. It ca
### 1. Instant Upgrades
-Rector now supports upgrades from PHP 5.3 to 8.0 and major open-source projects like [Symfony](https://github.com/rectorphp/rector-symfony), [PHPUnit](https://github.com/rectorphp/rector-phpunit), [Nette](https://github.com/rectorphp/rector-nette), [Laravel](https://github.com/rectorphp/rector-laravel), [CakePHP](https://github.com/rectorphp/rector-cakephp), [Doctrine](https://github.com/rectorphp/rector-doctrine), [PHPOffice](https://github.com/rectorphp/rector-phpoffice) and [TYPO3](https://github.com/sabbelasichon/typo3-rector) out of the box. Do you want to **be constantly on the latest PHP/framework version without effort**?
+Rector now supports upgrades from PHP 5.3 to 8.1 and major open-source projects like [Symfony](https://github.com/rectorphp/rector-symfony), [PHPUnit](https://github.com/rectorphp/rector-phpunit), [Nette](https://github.com/rectorphp/rector-nette), [Laravel](https://github.com/rectorphp/rector-laravel), [CakePHP](https://github.com/rectorphp/rector-cakephp), [Doctrine](https://github.com/rectorphp/rector-doctrine) and [TYPO3](https://github.com/sabbelasichon/typo3-rector) out of the box. Do you want to **be constantly on the latest PHP and Framework without effort**?
Use Rector to handle **instant upgrades** for you.
@@ -34,21 +34,22 @@ By [buying a book](https://leanpub.com/rector-the-power-of-automated-refactoring
## Documentation
-- [Explore 450+ Rector Rules](/docs/rector_rules_overview.md)
-- [Auto Import Names](/docs/auto_import_names.md)
+- [Explore 500+ Rector Rules](/docs/rector_rules_overview.md)
- [How to Ignore Rule or Paths](/docs/how_to_ignore_rule_or_paths.md)
- [Static Reflection and Autoload](/docs/static_reflection_and_autoload.md)
- [How to Configure Rule](/docs/how_to_configure_rules.md)
-- [Beyond PHP - Entering the realm of FileProcessors](/docs/beyond_php_file_processors.md)
+- [Auto Import Names](/docs/auto_import_names.md)
### For Rule Developers and Contributors
+- [How to add Test for Rector Rule](/docs/how_to_add_test_for_rector_rule.md)
- [How Does Rector Work?](/docs/how_it_works.md)
- [PHP Parser Nodes](https://github.com/rectorphp/php-parser-nodes-docs/)
- [How to Work with Doc Block and Comments](/docs/how_to_work_with_doc_block_and_comments.md)
- [How to Generate New Rector Rule](/docs/create_own_rule.md)
-- [How to add Test for Rector Rule](/docs/how_to_add_test_for_rector_rule.md)
-- [How to create a custom FileProcessor](/docs/how_to_create_custom_fileprocessor.md)
+
+See [the full documentation](/docs).
+
## Install
diff --git a/docs/auto_import_names.md b/docs/auto_import_names.md
index b728a51318c..da37a3b155b 100644
--- a/docs/auto_import_names.md
+++ b/docs/auto_import_names.md
@@ -16,7 +16,7 @@ Rector works with all class names as fully qualified by default, so it knows the
To import FQN like these, configure `rector.php` with:
```php
-$parameters->set(Option::AUTO_IMPORT_NAMES, true);
+$rectorConfig->autoImportNames();
```
@@ -37,8 +37,9 @@ $parameters->set(Option::IMPORT_SHORT_CLASSES, false);
-If you have set Option::AUTO_IMPORT_NAMES to true, rector is applying this to every analyzed file, even if no real change by a rector was applied to the file.
-The reason is that a so-called post rector is responsible for this, namely the NameImportingPostRector.
+If you have set `Option::AUTO_IMPORT_NAMES` to `true`, rector is applying this to every analyzed file, even if no real change by a rector was applied to the file.
+
+The reason is that a so-called post-rector is responsible for this, namely the `NameImportingPostRector`.
If you like to apply the Option::AUTO_IMPORT_NAMES only for real changed files, you can configure this.
```php
@@ -65,3 +66,7 @@ Run it:
```bash
vendor/bin/ecs check src --fix
```
+
+
+
+Happy coding!
diff --git a/docs/how_to_add_test_for_rector_rule.md b/docs/how_to_add_test_for_rector_rule.md
index af80ac9b98f..ebf572dbf91 100644
--- a/docs/how_to_add_test_for_rector_rule.md
+++ b/docs/how_to_add_test_for_rector_rule.md
@@ -9,37 +9,11 @@ When using Rector to update your own code, you will typically be using release r
- Install dependencies by executing `composer install`
- Tests your installation by executing `composer fix-cs` and `composer phpstan`
- Create a new branch for your test
-- Add your test as described below. Note that the rector binary is located at `bin/rector` instead of the typical `vendor/bin/rector`
-- Push the branch and create a new pull request to https://github.com/rectorphp/rector-src
+- Add your test as described below. Note that the rector binary is located at `bin/rector` instead of the typical `vendor/bin/rector`
+- Push the branch
+- Create a new pull request to https://github.com/rectorphp/rector-src
-Alternatively, the above may be performed on the CLI
-
-```bash
-# Authenticate
-gh auth login
-
-# Fork and clone the repository
-gh repo fork https://github.com/rectorphp/rector-src
-
-# Install dependencies
-cd rector-src
-composer install
-
-# Test installation
-composer fix-cs
-composer phpstan
-
-# Create and checkout a branch
-git checkout -b your_branch_name
-
-# Create test as described below
-
-# Push the branch
-git push -u origin your_branch_name
-
-# create new pull request to https://github.com/rectorphp/rector-src
-gh pr create --title "Your title text" --body "Your body text"
-```
+
## 2. Detect the Rector Rule
@@ -57,6 +31,8 @@ Our rule in this example is: `Rector\Privatization\Rector\Class_\FinalizeClasses
This rule's job is to add `final` to every class that has no children and is not a Doctrine entity = everywhere it can without breaking our code.
+
+
## 3. Detect the Minimal File
Usually, the Rector diff output is long and contains many other errors related to other rules. It's a mess; we can't use that for a test fixture. We need to find **1 responsible line**.
@@ -79,6 +55,8 @@ bin/rector process app/SomeFile.php
Do we have the same diff? Great!
+
+
## 4. Find the Rector Test Case
Now we need to find the test case. The test case name is rule + `Test` suffix.
@@ -89,14 +67,12 @@ Now we need to find the test case. The test case name is rule + `Test` suffix.
`FinalizeClassesWithoutChildrenRectorTest` (test class)
-↓
-
-`FinalizeClassesWithoutChildrenRectorTest.php` (test file)
-
Right here:
![Rule Test Case](/docs/images/docs_rule_test_case.png)
+
+
## 5. Add Change or No-Change Test Fixture File
Next to the test case, there is `/Fixture` directory. It contains many test fixture files that verified the Rector rule work correctly in all possible cases.
@@ -105,9 +81,11 @@ Do you see *test fixture file* first time? It's a file with real-life PHP code t
In the `/Fixture` directory, we create our test fixture file, e.g., `add_final.php.inc`. The `.php.inc` is there on purpose, so the file is hidden from coding standard tools and static analysis.
-There are 2 fixture formats.
+
-### 1. The Code Should Change
+There are 2 fixture formats:
+
+### A. The Code Should Change
```bash
@@ -115,7 +93,7 @@ There are 2 fixture formats.
```
-### 2. The Code Should Be Skipped
+### B. The Code Should Be Skipped
```bash
@@ -164,3 +142,7 @@ vendor/bin/phpunit rules-tests/Privatization/Rector/Class_/FinalizeClassesWithou
```
If PHPUnit fails, you've successfully added a test case! :)
+
+
+
+Thank you
diff --git a/packages/Config/RectorConfig.php b/packages/Config/RectorConfig.php
index 04ba42a6fb0..f95ed524245 100644
--- a/packages/Config/RectorConfig.php
+++ b/packages/Config/RectorConfig.php
@@ -74,4 +74,13 @@ final class RectorConfig extends \Symfony\Component\DependencyInjection\Loader\C
$services = $this->services();
$services->set($rectorClass)->configure($configuration);
}
+ /**
+ * @param class-string $rectorClass
+ */
+ public function rule(string $rectorClass) : void
+ {
+ \RectorPrefix20220412\Webmozart\Assert\Assert::isAOf($rectorClass, \Rector\Core\Contract\Rector\RectorInterface::class);
+ $services = $this->services();
+ $services->set($rectorClass);
+ }
}
diff --git a/src/Application/VersionResolver.php b/src/Application/VersionResolver.php
index 84c91cfe9bb..1e69f80ffe9 100644
--- a/src/Application/VersionResolver.php
+++ b/src/Application/VersionResolver.php
@@ -16,11 +16,11 @@ final class VersionResolver
/**
* @var string
*/
- public const PACKAGE_VERSION = 'a1ac1b6fdf09744e2b1ca427e44715f28c24d22d';
+ public const PACKAGE_VERSION = '51e89c3f32c7f588dfd82b4b914f0ba9518adb0f';
/**
* @var string
*/
- public const RELEASE_DATE = '2022-04-12 08:52:34';
+ public const RELEASE_DATE = '2022-04-12 10:52:46';
public static function resolvePackageVersion() : string
{
$process = new \RectorPrefix20220412\Symfony\Component\Process\Process(['git', 'log', '--pretty="%H"', '-n1', 'HEAD'], __DIR__);
diff --git a/templates/rector.php.dist b/templates/rector.php.dist
index 08a29eebb3d..062b41b93b6 100644
--- a/templates/rector.php.dist
+++ b/templates/rector.php.dist
@@ -2,24 +2,20 @@
declare(strict_types=1);
-use Rector\Core\Configuration\Option;
-use Rector\Php74\Rector\Property\TypedPropertyRector;
+use Rector\CodeQuality\Rector\Class_\InlineConstructorDefaultToPropertyRector;
+use Rector\Config\RectorConfig;
use Rector\Set\ValueObject\LevelSetList;
-use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
-return static function (ContainerConfigurator $containerConfigurator): void {
- // get parameters
- $parameters = $containerConfigurator->parameters();
- $parameters->set(Option::PATHS, [
+return static function (RectorConfig $rectorConfig): void {
+ $rectorConfig->paths([
__DIR__ . '/src'
]);
- // Define what rule sets will be applied
- $containerConfigurator->import(LevelSetList::UP_TO_PHP_XY);
-
- // get services (needed for register a single rule)
- // $services = $containerConfigurator->services();
-
// register a single rule
- // $services->set(TypedPropertyRector::class);
+ $rectorConfig->rule(InlineConstructorDefaultToPropertyRector::class);
+
+ // define sets of rules
+ // $rectorConfig->sets([
+ // LevelSetList::UP_TO_PHP_XY
+ // ]);
};
diff --git a/vendor/autoload.php b/vendor/autoload.php
index e2fac59ca4f..1d789390898 100644
--- a/vendor/autoload.php
+++ b/vendor/autoload.php
@@ -9,4 +9,4 @@ if (PHP_VERSION_ID < 50600) {
require_once __DIR__ . '/composer/autoload_real.php';
-return ComposerAutoloaderInitd5d78cf2aef17b350099f921107fc425::getLoader();
+return ComposerAutoloaderInita23a41ba9fb80270682522b773f3fbd4::getLoader();
diff --git a/vendor/composer/autoload_real.php b/vendor/composer/autoload_real.php
index d7791a01f2d..9173ab0bee5 100644
--- a/vendor/composer/autoload_real.php
+++ b/vendor/composer/autoload_real.php
@@ -2,7 +2,7 @@
// autoload_real.php @generated by Composer
-class ComposerAutoloaderInitd5d78cf2aef17b350099f921107fc425
+class ComposerAutoloaderInita23a41ba9fb80270682522b773f3fbd4
{
private static $loader;
@@ -22,19 +22,19 @@ class ComposerAutoloaderInitd5d78cf2aef17b350099f921107fc425
return self::$loader;
}
- spl_autoload_register(array('ComposerAutoloaderInitd5d78cf2aef17b350099f921107fc425', 'loadClassLoader'), true, true);
+ spl_autoload_register(array('ComposerAutoloaderInita23a41ba9fb80270682522b773f3fbd4', 'loadClassLoader'), true, true);
self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__));
- spl_autoload_unregister(array('ComposerAutoloaderInitd5d78cf2aef17b350099f921107fc425', 'loadClassLoader'));
+ spl_autoload_unregister(array('ComposerAutoloaderInita23a41ba9fb80270682522b773f3fbd4', 'loadClassLoader'));
require __DIR__ . '/autoload_static.php';
- call_user_func(\Composer\Autoload\ComposerStaticInitd5d78cf2aef17b350099f921107fc425::getInitializer($loader));
+ call_user_func(\Composer\Autoload\ComposerStaticInita23a41ba9fb80270682522b773f3fbd4::getInitializer($loader));
$loader->setClassMapAuthoritative(true);
$loader->register(true);
- $includeFiles = \Composer\Autoload\ComposerStaticInitd5d78cf2aef17b350099f921107fc425::$files;
+ $includeFiles = \Composer\Autoload\ComposerStaticInita23a41ba9fb80270682522b773f3fbd4::$files;
foreach ($includeFiles as $fileIdentifier => $file) {
- composerRequired5d78cf2aef17b350099f921107fc425($fileIdentifier, $file);
+ composerRequirea23a41ba9fb80270682522b773f3fbd4($fileIdentifier, $file);
}
return $loader;
@@ -46,7 +46,7 @@ class ComposerAutoloaderInitd5d78cf2aef17b350099f921107fc425
* @param string $file
* @return void
*/
-function composerRequired5d78cf2aef17b350099f921107fc425($fileIdentifier, $file)
+function composerRequirea23a41ba9fb80270682522b773f3fbd4($fileIdentifier, $file)
{
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
$GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php
index 2a8aa2f25d0..97f87e2d9ba 100644
--- a/vendor/composer/autoload_static.php
+++ b/vendor/composer/autoload_static.php
@@ -4,7 +4,7 @@
namespace Composer\Autoload;
-class ComposerStaticInitd5d78cf2aef17b350099f921107fc425
+class ComposerStaticInita23a41ba9fb80270682522b773f3fbd4
{
public static $files = array (
'320cde22f66dd4f5d3fd621d3e88b98f' => __DIR__ . '/..' . '/symfony/polyfill-ctype/bootstrap.php',
@@ -3862,9 +3862,9 @@ class ComposerStaticInitd5d78cf2aef17b350099f921107fc425
public static function getInitializer(ClassLoader $loader)
{
return \Closure::bind(function () use ($loader) {
- $loader->prefixLengthsPsr4 = ComposerStaticInitd5d78cf2aef17b350099f921107fc425::$prefixLengthsPsr4;
- $loader->prefixDirsPsr4 = ComposerStaticInitd5d78cf2aef17b350099f921107fc425::$prefixDirsPsr4;
- $loader->classMap = ComposerStaticInitd5d78cf2aef17b350099f921107fc425::$classMap;
+ $loader->prefixLengthsPsr4 = ComposerStaticInita23a41ba9fb80270682522b773f3fbd4::$prefixLengthsPsr4;
+ $loader->prefixDirsPsr4 = ComposerStaticInita23a41ba9fb80270682522b773f3fbd4::$prefixDirsPsr4;
+ $loader->classMap = ComposerStaticInita23a41ba9fb80270682522b773f3fbd4::$classMap;
}, null, ClassLoader::class);
}
diff --git a/vendor/scoper-autoload.php b/vendor/scoper-autoload.php
index d58dbce0533..fe16d26493a 100644
--- a/vendor/scoper-autoload.php
+++ b/vendor/scoper-autoload.php
@@ -9,8 +9,8 @@ $loader = require_once __DIR__.'/autoload.php';
if (!class_exists('AutoloadIncluder', false) && !interface_exists('AutoloadIncluder', false) && !trait_exists('AutoloadIncluder', false)) {
spl_autoload_call('RectorPrefix20220412\AutoloadIncluder');
}
-if (!class_exists('ComposerAutoloaderInitd5d78cf2aef17b350099f921107fc425', false) && !interface_exists('ComposerAutoloaderInitd5d78cf2aef17b350099f921107fc425', false) && !trait_exists('ComposerAutoloaderInitd5d78cf2aef17b350099f921107fc425', false)) {
- spl_autoload_call('RectorPrefix20220412\ComposerAutoloaderInitd5d78cf2aef17b350099f921107fc425');
+if (!class_exists('ComposerAutoloaderInita23a41ba9fb80270682522b773f3fbd4', false) && !interface_exists('ComposerAutoloaderInita23a41ba9fb80270682522b773f3fbd4', false) && !trait_exists('ComposerAutoloaderInita23a41ba9fb80270682522b773f3fbd4', false)) {
+ spl_autoload_call('RectorPrefix20220412\ComposerAutoloaderInita23a41ba9fb80270682522b773f3fbd4');
}
if (!class_exists('Helmich\TypoScriptParser\Parser\AST\Statement', false) && !interface_exists('Helmich\TypoScriptParser\Parser\AST\Statement', false) && !trait_exists('Helmich\TypoScriptParser\Parser\AST\Statement', false)) {
spl_autoload_call('RectorPrefix20220412\Helmich\TypoScriptParser\Parser\AST\Statement');
@@ -59,9 +59,9 @@ if (!function_exists('print_node')) {
return \RectorPrefix20220412\print_node(...func_get_args());
}
}
-if (!function_exists('composerRequired5d78cf2aef17b350099f921107fc425')) {
- function composerRequired5d78cf2aef17b350099f921107fc425() {
- return \RectorPrefix20220412\composerRequired5d78cf2aef17b350099f921107fc425(...func_get_args());
+if (!function_exists('composerRequirea23a41ba9fb80270682522b773f3fbd4')) {
+ function composerRequirea23a41ba9fb80270682522b773f3fbd4() {
+ return \RectorPrefix20220412\composerRequirea23a41ba9fb80270682522b773f3fbd4(...func_get_args());
}
}
if (!function_exists('scanPath')) {