mirror of
https://github.com/rectorphp/rector.git
synced 2024-06-07 11:50:51 +00:00
README + recipe improvements (#4017)
* rector-recipe and README improvements * ci: add generate command test
This commit is contained in:
parent
642cda46bd
commit
de4748f935
34
.github/workflows/code_analysis_no_dev.yaml
vendored
Normal file
34
.github/workflows/code_analysis_no_dev.yaml
vendored
Normal file
|
@ -0,0 +1,34 @@
|
|||
name: Code Analysis [no dev]
|
||||
|
||||
on:
|
||||
pull_request: null
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
matrix:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
actions:
|
||||
-
|
||||
name: 'Rector Recipe'
|
||||
run: |
|
||||
cp rector-recipe.php.dist rector-recipe.php
|
||||
bin/rector generate
|
||||
|
||||
name: ${{ matrix.actions.name }}
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
# see https://github.com/shivammathur/setup-php
|
||||
- uses: shivammathur/setup-php@v1
|
||||
with:
|
||||
php-version: 7.4
|
||||
coverage: none
|
||||
|
||||
- run: composer install --no-progress --ansi
|
||||
|
||||
- run: ${{ matrix.actions.run }}
|
381
README.md
381
README.md
|
@ -64,18 +64,14 @@ It supports all versions of PHP from 5.2 and many open-source projects:
|
|||
## What Can Rector Do for You?
|
||||
|
||||
- [Upgrade 30 000 unit tests from PHPUnit 6 to 9 in 2 weeks](https://twitter.com/LBajsarowicz/status/1272947900016967683)
|
||||
- Complete [@var annotations or parameter/return type declarations](https://www.tomasvotruba.com/blog/2019/01/03/how-to-complete-type-declarations-without-docblocks-with-rector/)
|
||||
- [Complete PHP 7.4 property type declarations](https://www.tomasvotruba.com/blog/2018/11/15/how-to-get-php-74-typed-properties-to-your-code-in-few-seconds/)
|
||||
- Complete [@var annotations or parameter/return type declarations](https://tomasvotruba.com/blog/2019/01/03/how-to-complete-type-declarations-without-docblocks-with-rector/)
|
||||
- [Complete PHP 7.4 property type declarations](https://tomasvotruba.com/blog/2018/11/15/how-to-get-php-74-typed-properties-to-your-code-in-few-seconds/)
|
||||
- Upgrade your code from **PHP 5.3 to 8.0**
|
||||
- [Migrate your project from Nette to Symfony](https://www.tomasvotruba.com/blog/2019/02/21/how-we-migrated-from-nette-to-symfony-in-3-weeks-part-1/)
|
||||
- [Refactor Laravel facades to dependency injection](https://www.tomasvotruba.com/blog/2019/03/04/how-to-turn-laravel-from-static-to-dependency-injection-in-one-day/)
|
||||
- [Migrate your project from Nette to Symfony](https://tomasvotruba.com/blog/2019/02/21/how-we-migrated-from-nette-to-symfony-in-3-weeks-part-1/)
|
||||
- [Refactor Laravel facades to dependency injection](https://tomasvotruba.com/blog/2019/03/04/how-to-turn-laravel-from-static-to-dependency-injection-in-one-day/)
|
||||
- And much more...
|
||||
|
||||
## How to Apply Coding Standards?
|
||||
|
||||
Rector uses [nikic/php-parser](https://github.com/nikic/PHP-Parser/), that build on technology called *abstract syntax tree* (AST). AST doesn't care about spaces and produces mall-formatted code. That's why your project needs to have coding standard tool and set of rules, so it can make refactored nice and shiny again.
|
||||
|
||||
Don't have any coding standard tool? Add [EasyCodingStandard](https://github.com/Symplify/EasyCodingStandard) and use prepared [`ecs-after-rector.php`](/ecs-after-rector.php) set.
|
||||
<br>
|
||||
|
||||
## Install
|
||||
|
||||
|
@ -86,160 +82,68 @@ composer require rector/rector --dev
|
|||
- Having conflicts during `composer require`? → Use the [Rector Prefixed](https://github.com/rectorphp/rector-prefixed)
|
||||
- Using a different PHP version than Rector supports? → Use the [Docker image](#run-rector-in-docker)
|
||||
|
||||
<br>
|
||||
|
||||
## Running Rector
|
||||
|
||||
### A. Prepared Sets
|
||||
There a 2 main ways to use Rector:
|
||||
|
||||
Featured open-source projects have **prepared sets**. You can find them in [`/config/set`](/config/set) or by autocomplete of [`Rector\Set\ValueObject\SetList`](/packages/set/src/ValueObject/SetList.php) constants in `rector.php` config.
|
||||
- a *single rule*, to have the change under control - pick [from over 550 rules](/docs/rector_rules_overview.md)
|
||||
- or group of rules called *sets* - pick from [sets](/config/set)
|
||||
|
||||
Let's say you pick the [`symfony40`](/config/set/symfony40.php) set and you want to upgrade your `/src` directory:
|
||||
Sets are suitable for open-source projects and design patterns, like .
|
||||
|
||||
To use them, create a `rector.php` in your root directory:
|
||||
|
||||
```php
|
||||
<?php
|
||||
// rector.php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Rector\Core\Configuration\Option;
|
||||
use Rector\Php74\Rector\Property\TypedPropertyRector;
|
||||
use Rector\Set\ValueObject\SetList;
|
||||
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
|
||||
|
||||
return static function (ContainerConfigurator $containerConfigurator): void {
|
||||
// get parameters
|
||||
$parameters = $containerConfigurator->parameters();
|
||||
|
||||
// here we can define, what sets of rules will be applied
|
||||
$parameters->set(Option::SETS, [
|
||||
SetList::CODE_QUALITY
|
||||
]);
|
||||
|
||||
// get services
|
||||
$services = $containerConfigurator->services();
|
||||
|
||||
// register single rule
|
||||
$services->set(TypedPropertyRector::class);
|
||||
};
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
Then dry run Rector:
|
||||
|
||||
```bash
|
||||
vendor/bin/rector process src --set symfony40 --dry-run
|
||||
vendor/bin/rector process src --dry-run
|
||||
```
|
||||
|
||||
Rector will show you diff of files that it *would* change. To *make* the changes, drop `--dry-run`:
|
||||
|
||||
```bash
|
||||
# apply upgrades to your code
|
||||
vendor/bin/rector process src --set symfony40
|
||||
```
|
||||
|
||||
Some sets, such as [`code-quality`](/config/set/code-quality.php) can be used on a regular basis. **The best practice is to use config over command line**:
|
||||
|
||||
```php
|
||||
<?php
|
||||
// rector.php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Rector\Core\Configuration\Option;
|
||||
use Rector\Set\ValueObject\SetList;
|
||||
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
|
||||
|
||||
return static function (ContainerConfigurator $containerConfigurator): void {
|
||||
$parameters = $containerConfigurator->parameters();
|
||||
|
||||
$parameters->set(Option::SETS, [SetList::CODE_QUALITY]);
|
||||
};
|
||||
```
|
||||
|
||||
PHP config format is a new [Symfony best practice](https://twitter.com/symfony_en/status/1284538366147678208).
|
||||
|
||||
### B. Standalone Rules
|
||||
|
||||
In the end, it's best to combine few of basic sets and drop [particular rules](/docs/rector_rules_overview.md) that you want to try:
|
||||
|
||||
```php
|
||||
<?php
|
||||
// rector.php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Rector\Core\Configuration\Option;
|
||||
use Rector\Set\ValueObject\SetList;
|
||||
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
|
||||
use Rector\Php74\Rector\Property\TypedPropertyRector;
|
||||
|
||||
return static function (ContainerConfigurator $containerConfigurator): void {
|
||||
$parameters = $containerConfigurator->parameters();
|
||||
|
||||
$services = $containerConfigurator->services();
|
||||
$services->set(TypedPropertyRector::class);
|
||||
|
||||
$parameters->set(Option::SETS, [SetList::CODE_QUALITY]);
|
||||
};
|
||||
```
|
||||
|
||||
Then let Rector refactor your code:
|
||||
|
||||
```bash
|
||||
vendor/bin/rector process src
|
||||
```
|
||||
|
||||
:+1:
|
||||
|
||||
<br>
|
||||
|
||||
*Note: `rector.php` is loaded by default. For different location, use `--config` option.*
|
||||
|
||||
## Features
|
||||
<br>
|
||||
|
||||
### Paths
|
||||
|
||||
If you're annoyed by repeating paths in arguments, you can move them to config instead:
|
||||
|
||||
```php
|
||||
<?php
|
||||
// rector.php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Rector\Core\Configuration\Option;
|
||||
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
|
||||
|
||||
return static function (ContainerConfigurator $containerConfigurator): void {
|
||||
$parameters = $containerConfigurator->parameters();
|
||||
|
||||
$parameters->set(Option::PATHS, [
|
||||
__DIR__ . '/src',
|
||||
__DIR__ . '/tests',
|
||||
]);
|
||||
};
|
||||
```
|
||||
|
||||
### Extra Autoloading
|
||||
|
||||
Rector relies on whatever autoload setup the project it is fixing is using by using the Composer autoloader as default. To specify your own autoload file, use `--autoload-file` option:
|
||||
|
||||
```bash
|
||||
vendor/bin/rector process ../project --autoload-file ../project/vendor/autoload.php
|
||||
```
|
||||
|
||||
Or use a `rector.php` configuration file:
|
||||
|
||||
```php
|
||||
<?php
|
||||
// rector.php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Rector\Core\Configuration\Option;
|
||||
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
|
||||
|
||||
return static function (ContainerConfigurator $containerConfigurator): void {
|
||||
$parameters = $containerConfigurator->parameters();
|
||||
|
||||
$parameters->set(Option::AUTOLOAD_PATHS, [
|
||||
__DIR__ . '/vendor/squizlabs/php_codesniffer/autoload.php',
|
||||
__DIR__ . '/vendor/project-without-composer',
|
||||
]);
|
||||
};
|
||||
```
|
||||
|
||||
### Exclude Paths and Rectors
|
||||
|
||||
You can also **exclude files or directories** (with regex or [fnmatch](http://php.net/manual/en/function.fnmatch.php)):
|
||||
|
||||
```php
|
||||
<?php
|
||||
// rector.php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Rector\Core\Configuration\Option;
|
||||
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
|
||||
|
||||
return static function (ContainerConfigurator $containerConfigurator): void {
|
||||
$parameters = $containerConfigurator->parameters();
|
||||
|
||||
$parameters->set(Option::EXCLUDE_PATHS, [
|
||||
__DIR__ . '/src/*/Tests/*',
|
||||
]);
|
||||
};
|
||||
```
|
||||
|
||||
You can use a whole set, except 1 rule:
|
||||
## Configuration
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
@ -249,29 +153,66 @@ declare(strict_types=1);
|
|||
|
||||
use Rector\CodeQuality\Rector\If_\SimplifyIfReturnBoolRector;
|
||||
use Rector\Core\Configuration\Option;
|
||||
use Rector\Set\ValueObject\SetList;
|
||||
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
|
||||
|
||||
return static function (ContainerConfigurator $containerConfigurator): void {
|
||||
$parameters = $containerConfigurator->parameters();
|
||||
|
||||
$parameters->set(Option::SETS, [
|
||||
SetList::CODE_QUALITY,
|
||||
// paths to refactor; solid alternative to CLI arguments
|
||||
$parameters->set(Option::PATHS, [
|
||||
__DIR__ . '/src',
|
||||
__DIR__ . '/tests',
|
||||
]);
|
||||
|
||||
// is there a file you need to skip?
|
||||
$parameters->set(Option::EXCLUDE_PATHS, [
|
||||
// single file
|
||||
__DIR__ . '/src/ComplicatedFile.php',
|
||||
// or directory
|
||||
__DIR__ . '/src/ComplicatedFile.php',
|
||||
// or fnmatch
|
||||
__DIR__ . '/src/*/Tests/*',
|
||||
]);
|
||||
|
||||
// Rector relies on autoload setup of your project; Composer autoload is included by default; to add more:
|
||||
$parameters->set(Option::AUTOLOAD_PATHS, [
|
||||
// autoload specific file
|
||||
__DIR__ . '/vendor/squizlabs/php_codesniffer/autoload.php',
|
||||
// or full directory
|
||||
__DIR__ . '/vendor/project-without-composer',
|
||||
]);
|
||||
|
||||
// is there single rule you don't like from a set you use?
|
||||
$parameters->set(Option::EXCLUDE_RECTORS, [
|
||||
SimplifyIfReturnBoolRector::class,
|
||||
]);
|
||||
|
||||
// is your PHP version different from the one your refactor to? [default: your PHP version]
|
||||
$parameters->set(Option::PHP_VERSION_FEATURES, '7.2');
|
||||
|
||||
// auto import fully qualified class names? [default: false]
|
||||
$parameters->set(Option::AUTO_IMPORT_NAMES, true);
|
||||
// skip root namespace classes, like \DateTime or \Exception [default: true]
|
||||
$parameters->set(Option::IMPORT_SHORT_CLASSES, false);
|
||||
// skip classes used in PHP DocBlocks, like in /** @var \Some\Class */ [default: true]
|
||||
$parameters->set(Option::IMPORT_DOC_BLOCKS, false);
|
||||
};
|
||||
```
|
||||
|
||||
### Ignore Rector Rule in File
|
||||
|
||||
For in-file exclusion, use `@noRector \FQN name` annotation:
|
||||
|
||||
```php
|
||||
class SomeClass
|
||||
{
|
||||
/**
|
||||
* @noRector \Rector\DeadCode\Rector\ClassMethod\RemoveEmptyClassMethodRector
|
||||
* @noRector
|
||||
*/
|
||||
const NAME = '102';
|
||||
|
||||
/**
|
||||
* @noRector
|
||||
*/
|
||||
public function foo()
|
||||
{
|
||||
|
@ -287,39 +228,17 @@ Do you have config that includes many sets and Rectors? You might want to run on
|
|||
|
||||
```bash
|
||||
vendor/bin/rector process src --set solid --only Rector\SOLID\Rector\Class_\FinalizeClassesWithoutChildrenRector
|
||||
```
|
||||
|
||||
Or just short name:
|
||||
|
||||
```bash
|
||||
# or just a short class name
|
||||
vendor/bin/rector process src --set solid --only FinalizeClassesWithoutChildrenRector
|
||||
```
|
||||
|
||||
Both will run only `Rector\SOLID\Rector\Class_\FinalizeClassesWithoutChildrenRector`.
|
||||
|
||||
### Provide PHP Version
|
||||
|
||||
By default Rector uses the language features matching your system version of PHP. You can configure it for a different PHP version:
|
||||
|
||||
```php
|
||||
<?php
|
||||
// rector.php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Rector\Core\Configuration\Option;
|
||||
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
|
||||
|
||||
return static function (ContainerConfigurator $containerConfigurator): void {
|
||||
$parameters = $containerConfigurator->parameters();
|
||||
|
||||
$parameters->set(Option::PHP_VERSION_FEATURES, '7.2'); # your version is 7.3
|
||||
};
|
||||
```
|
||||
|
||||
### Safe Types
|
||||
|
||||
In default setting:
|
||||
|
||||
**Experimental** feature
|
||||
|
||||
In default type resolving settings, all docblocks are taken seriously.
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
@ -333,19 +252,19 @@ use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigura
|
|||
return static function (ContainerConfigurator $containerConfigurator): void {
|
||||
$parameters = $containerConfigurator->parameters();
|
||||
|
||||
$parameters->set(Option::SAFE_TYPES, false);
|
||||
// [default: false]
|
||||
$parameters->set(Option::SAFE_TYPES, true);
|
||||
};
|
||||
```
|
||||
|
||||
All docblocks are taken seriously, e.g. with [typed properties](https://github.com/rectorphp/rector/blob/master/docs/rector_rules_overview.md#typedpropertyrector) rule:
|
||||
E.g. the `TypedPropertyRector` rule will skip this case, as `string` is defined only in docblock:
|
||||
|
||||
```diff
|
||||
<?php
|
||||
```php
|
||||
<?php
|
||||
|
||||
class ValueObject
|
||||
{
|
||||
- public $value;
|
||||
+ public string $value;
|
||||
class ValueObject
|
||||
{
|
||||
public $value;
|
||||
|
||||
/**
|
||||
* @param string $value
|
||||
|
@ -357,88 +276,6 @@ All docblocks are taken seriously, e.g. with [typed properties](https://github.c
|
|||
}
|
||||
```
|
||||
|
||||
Do you want to use only explicit PHP type declaration? Enable `safe_types`:
|
||||
|
||||
```php
|
||||
<?php
|
||||
// rector.php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Rector\Core\Configuration\Option;
|
||||
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
|
||||
|
||||
return static function (ContainerConfigurator $containerConfigurator): void {
|
||||
$parameters = $containerConfigurator->parameters();
|
||||
|
||||
$parameters->set(Option::SAFE_TYPES, true);
|
||||
};
|
||||
```
|
||||
|
||||
Then, docblocks are skipped:
|
||||
|
||||
```diff
|
||||
<?php
|
||||
|
||||
class ValueObject
|
||||
{
|
||||
public $value;
|
||||
|
||||
- public $count;
|
||||
+ public int $count;
|
||||
|
||||
/**
|
||||
* @param string $value
|
||||
*/
|
||||
public function __construct($value, int $count)
|
||||
{
|
||||
$this->value = $value;
|
||||
$this->count = $count
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Import Use Statements
|
||||
|
||||
FQN classes are not imported by default. If you don't want to do it manually after every Rector run, enable it by:
|
||||
|
||||
```php
|
||||
<?php
|
||||
// rector.php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Rector\Core\Configuration\Option;
|
||||
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
|
||||
|
||||
return static function (ContainerConfigurator $containerConfigurator): void {
|
||||
$parameters = $containerConfigurator->parameters();
|
||||
|
||||
$parameters->set(Option::AUTO_IMPORT_NAMES, true);
|
||||
};
|
||||
```
|
||||
|
||||
You can also fine-tune how these imports are processed:
|
||||
|
||||
```php
|
||||
<?php
|
||||
// rector.php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Rector\Core\Configuration\Option;
|
||||
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
|
||||
|
||||
return static function (ContainerConfigurator $containerConfigurator): void {
|
||||
$parameters = $containerConfigurator->parameters();
|
||||
|
||||
// this will not import root namespace classes, like \DateTime or \Exception
|
||||
$parameters->set(Option::IMPORT_SHORT_CLASSES, false);
|
||||
// this will not import classes used in PHP DocBlocks, like in /** @var \Some\Class */
|
||||
$parameters->set(Option::IMPORT_DOC_BLOCKS, false);
|
||||
};
|
||||
```
|
||||
|
||||
### Limit Execution to Changed Files
|
||||
|
||||
Execution can be limited to changed files using the `process` option `--match-git-diff`.
|
||||
|
@ -503,9 +340,9 @@ Using `rector.php`:
|
|||
|
||||
```bash
|
||||
docker run --rm -v $(pwd):/project rector/rector:latest process /project/app \
|
||||
--config /project/rector.php \
|
||||
--autoload-file /project/vendor/autoload.php \
|
||||
--dry-run
|
||||
--config /project/rector.php \
|
||||
--autoload-file /project/vendor/autoload.php \
|
||||
--dry-run
|
||||
```
|
||||
|
||||
<br>
|
||||
|
@ -525,3 +362,11 @@ Do you use Rector to upgrade your code? Add it here:
|
|||
|
||||
- [palantirnet/drupal-rector](https://github.com/palantirnet/drupal-rector) by [Palantir.net](https://github.com/palantirnet) for [Drupal](https://www.drupal.org/)
|
||||
- [sabbelasichon/typo3-rector](https://github.com/sabbelasichon/typo3-rector) for [TYPO3](https://typo3.org/)
|
||||
|
||||
## Known Drawbacks
|
||||
|
||||
### How to Apply Coding Standards?
|
||||
|
||||
Rector uses [nikic/php-parser](https://github.com/nikic/PHP-Parser/), that build on technology called *abstract syntax tree* (AST). AST doesn't care about spaces and produces mall-formatted code in both PHP and docblock annotations. **That's why your project needs to have coding standard tool** and set of rules, so it can make refactored nice and shiny again.
|
||||
|
||||
Don't have any coding standard tool? Add [ECS](https://github.com/Symplify/EasyCodingStandard) and use prepared [`ecs-after-rector.php`](/ecs-after-rector.php) set.
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
"doctrine/annotations": "^1.10.4",
|
||||
"doctrine/inflector": "^1.4|^2.0",
|
||||
"jean85/pretty-package-versions": "^1.2",
|
||||
"migrify/php-config-printer": "^0.3.30",
|
||||
"migrify/php-config-printer": "^0.3.31",
|
||||
"nette/robot-loader": "^3.2",
|
||||
"nette/utils": "^3.1",
|
||||
"nikic/php-parser": "^4.9",
|
||||
|
@ -43,8 +43,8 @@
|
|||
"require-dev": {
|
||||
"friendsofphp/php-cs-fixer": "^2.16",
|
||||
"johnkary/phpunit-speedtrap": "^3.2",
|
||||
"migrify/config-transformer": "^0.3.30",
|
||||
"migrify/easy-ci": "^0.3.30",
|
||||
"migrify/config-transformer": "^0.3.31",
|
||||
"migrify/easy-ci": "^0.3.31",
|
||||
"nette/application": "^3.0",
|
||||
"nette/forms": "^3.0",
|
||||
"ocramius/package-versions": "^1.4|^1.5",
|
||||
|
|
|
@ -11,7 +11,7 @@ use Rector\Renaming\Rector\MethodCall\RenameMethodRector;
|
|||
use Rector\Renaming\Rector\Name\RenameClassRector;
|
||||
use Rector\Renaming\Rector\StaticCall\RenameStaticMethodRector;
|
||||
use Rector\Renaming\ValueObject\StaticCallRename;
|
||||
use function Rector\SymfonyPhpConfig\inline_objects;
|
||||
use function Rector\SymfonyPhpConfig\inline_value_objects;
|
||||
use Rector\TypeDeclaration\Rector\ClassMethod\AddParamTypeDeclarationRector;
|
||||
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
|
||||
|
||||
|
@ -77,7 +77,7 @@ return static function (ContainerConfigurator $containerConfigurator): void {
|
|||
|
||||
$services->set(RenameStaticMethodRector::class)
|
||||
->call('configure', [[
|
||||
RenameStaticMethodRector::OLD_TO_NEW_METHODS_BY_CLASSES => inline_objects($configuration),
|
||||
RenameStaticMethodRector::OLD_TO_NEW_METHODS_BY_CLASSES => inline_value_objects($configuration),
|
||||
]]);
|
||||
|
||||
$services->set(RenamePropertyRector::class)
|
||||
|
|
|
@ -9,7 +9,7 @@ use Rector\Generic\ValueObject\FuncNameToMethodCallName;
|
|||
use Rector\Guzzle\Rector\MethodCall\MessageAsArrayRector;
|
||||
use Rector\MagicDisclosure\Rector\MethodCall\FluentChainMethodCallToNormalMethodCallRector;
|
||||
use Rector\Renaming\Rector\MethodCall\RenameMethodRector;
|
||||
use function Rector\SymfonyPhpConfig\inline_objects;
|
||||
use function Rector\SymfonyPhpConfig\inline_value_objects;
|
||||
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
|
||||
|
||||
return static function (ContainerConfigurator $containerConfigurator): void {
|
||||
|
@ -38,7 +38,7 @@ return static function (ContainerConfigurator $containerConfigurator): void {
|
|||
|
||||
$services->set(FuncCallToMethodCallRector::class)
|
||||
->call('configure', [[
|
||||
FuncCallToMethodCallRector::FUNC_CALL_TO_CLASS_METHOD_CALL => inline_objects($configuration),
|
||||
FuncCallToMethodCallRector::FUNC_CALL_TO_CLASS_METHOD_CALL => inline_value_objects($configuration),
|
||||
]]);
|
||||
|
||||
$services->set(StaticCallToFunctionRector::class)
|
||||
|
|
|
@ -4,7 +4,7 @@ declare(strict_types=1);
|
|||
|
||||
use Rector\Generic\Rector\FuncCall\FuncCallToStaticCallRector;
|
||||
use Rector\Generic\ValueObject\FuncNameToStaticCallName;
|
||||
use function Rector\SymfonyPhpConfig\inline_objects;
|
||||
use function Rector\SymfonyPhpConfig\inline_value_objects;
|
||||
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
|
||||
|
||||
return static function (ContainerConfigurator $containerConfigurator): void {
|
||||
|
@ -57,6 +57,6 @@ return static function (ContainerConfigurator $containerConfigurator): void {
|
|||
|
||||
$services->set(FuncCallToStaticCallRector::class)
|
||||
->call('configure', [[
|
||||
FuncCallToStaticCallRector::FUNC_CALLS_TO_STATIC_CALLS => inline_objects($configuration),
|
||||
FuncCallToStaticCallRector::FUNC_CALLS_TO_STATIC_CALLS => inline_value_objects($configuration),
|
||||
]]);
|
||||
};
|
||||
|
|
|
@ -9,7 +9,7 @@ use Rector\Renaming\Rector\MethodCall\RenameMethodRector;
|
|||
use Rector\Renaming\Rector\Name\RenameClassRector;
|
||||
use Rector\Renaming\Rector\StaticCall\RenameStaticMethodRector;
|
||||
use Rector\Renaming\ValueObject\StaticCallRename;
|
||||
use function Rector\SymfonyPhpConfig\inline_objects;
|
||||
use function Rector\SymfonyPhpConfig\inline_value_objects;
|
||||
use Rector\TypeDeclaration\Rector\FunctionLike\ParamTypeDeclarationRector;
|
||||
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
|
||||
|
||||
|
@ -55,7 +55,7 @@ return static function (ContainerConfigurator $containerConfigurator): void {
|
|||
|
||||
$services->set(RenameStaticMethodRector::class)
|
||||
->call('configure', [[
|
||||
RenameStaticMethodRector::OLD_TO_NEW_METHODS_BY_CLASSES => inline_objects($configuration),
|
||||
RenameStaticMethodRector::OLD_TO_NEW_METHODS_BY_CLASSES => inline_value_objects($configuration),
|
||||
]]);
|
||||
|
||||
$services->set(RenameClassRector::class)
|
||||
|
|
|
@ -16,7 +16,7 @@ use Rector\NetteCodeQuality\Rector\ArrayDimFetch\ChangeFormArrayAccessToAnnotate
|
|||
use Rector\Renaming\Rector\ClassConstFetch\RenameClassConstantRector;
|
||||
use Rector\Renaming\Rector\MethodCall\RenameMethodRector;
|
||||
use Rector\Renaming\Rector\Name\RenameClassRector;
|
||||
use function Rector\SymfonyPhpConfig\inline_objects;
|
||||
use function Rector\SymfonyPhpConfig\inline_value_objects;
|
||||
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
|
||||
|
||||
return static function (ContainerConfigurator $containerConfigurator): void {
|
||||
|
@ -59,7 +59,7 @@ return static function (ContainerConfigurator $containerConfigurator): void {
|
|||
);
|
||||
$services->set(StaticCallToMethodCallRector::class)->call(
|
||||
'configure',
|
||||
[[StaticCallToMethodCallRector::STATIC_CALLS_TO_METHOD_CALLS => inline_objects($configuration)]]
|
||||
[[StaticCallToMethodCallRector::STATIC_CALLS_TO_METHOD_CALLS => inline_value_objects($configuration)]]
|
||||
);
|
||||
// https://github.com/contributte/event-dispatcher-extra/tree/v0.4.3 and higher
|
||||
$services->set(RenameClassConstantRector::class)->call(
|
||||
|
|
|
@ -13,7 +13,7 @@ use Rector\Nette\Rector\Identical\EndsWithFunctionToNetteUtilsStringsRector;
|
|||
use Rector\Nette\Rector\Identical\StartsWithFunctionToNetteUtilsStringsRector;
|
||||
use Rector\Nette\Rector\NotIdentical\StrposToStringsContainsRector;
|
||||
use Rector\NetteUtilsCodeQuality\Rector\LNumber\ReplaceTimeNumberWithDateTimeConstantRector;
|
||||
use function Rector\SymfonyPhpConfig\inline_objects;
|
||||
use function Rector\SymfonyPhpConfig\inline_value_objects;
|
||||
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
|
||||
|
||||
# @see https://www.tomasvotruba.cz/blog/2018/07/30/hidden-gems-of-php-packages-nette-utils
|
||||
|
@ -27,7 +27,7 @@ return static function (ContainerConfigurator $containerConfigurator): void {
|
|||
];
|
||||
$services->set(FuncCallToStaticCallRector::class)
|
||||
->call('configure', [[
|
||||
FuncCallToStaticCallRector::FUNC_CALLS_TO_STATIC_CALLS => inline_objects($configuration),
|
||||
FuncCallToStaticCallRector::FUNC_CALLS_TO_STATIC_CALLS => inline_value_objects($configuration),
|
||||
]]);
|
||||
|
||||
$services->set(StrposToStringsContainsRector::class);
|
||||
|
|
|
@ -20,7 +20,7 @@ use Rector\Renaming\Rector\MethodCall\RenameMethodRector;
|
|||
use Rector\Renaming\Rector\Name\RenameClassRector;
|
||||
use Rector\Renaming\Rector\StaticCall\RenameStaticMethodRector;
|
||||
use Rector\Renaming\ValueObject\StaticCallRename;
|
||||
use function Rector\SymfonyPhpConfig\inline_objects;
|
||||
use function Rector\SymfonyPhpConfig\inline_value_objects;
|
||||
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
|
||||
|
||||
# see https://github.com/PHPOffice/PhpSpreadsheet/blob/master/docs/topics/migration-from-PHPExcel.md
|
||||
|
@ -109,7 +109,7 @@ return static function (ContainerConfigurator $containerConfigurator): void {
|
|||
|
||||
$services->set(RenameStaticMethodRector::class)
|
||||
->call('configure', [[
|
||||
RenameStaticMethodRector::OLD_TO_NEW_METHODS_BY_CLASSES => inline_objects($configuration),
|
||||
RenameStaticMethodRector::OLD_TO_NEW_METHODS_BY_CLASSES => inline_value_objects($configuration),
|
||||
]]);
|
||||
|
||||
$services->set(RenameClassRector::class)
|
||||
|
|
|
@ -5106,7 +5106,7 @@ return function (ContainerConfigurator $containerConfigurator) : void {
|
|||
$services->set(FuncCallToMethodCallRector::class)
|
||||
->call('configure', [[
|
||||
FuncCallToMethodCallRector::FUNC_CALL_TO_CLASS_METHOD_CALL => [
|
||||
\Rector\SymfonyPhpConfig\inline_object(new Rector\Generic\ValueObject\FuncNameToMethodCallName('view', 'Namespaced\SomeRenderer', 'render'))]
|
||||
\Rector\SymfonyPhpConfig\inline_value_object(new Rector\Generic\ValueObject\FuncNameToMethodCallName('view', 'Namespaced\SomeRenderer', 'render'))]
|
||||
]]);
|
||||
};
|
||||
```
|
||||
|
@ -5174,7 +5174,7 @@ return function (ContainerConfigurator $containerConfigurator) : void {
|
|||
$services->set(FuncCallToStaticCallRector::class)
|
||||
->call('configure', [[
|
||||
FuncCallToStaticCallRector::FUNC_CALLS_TO_STATIC_CALLS => [
|
||||
\Rector\SymfonyPhpConfig\inline_object(new Rector\Generic\ValueObject\FuncNameToStaticCallName('view', 'SomeStaticClass', 'render'))]
|
||||
\Rector\SymfonyPhpConfig\inline_value_object(new Rector\Generic\ValueObject\FuncNameToStaticCallName('view', 'SomeStaticClass', 'render'))]
|
||||
]]);
|
||||
};
|
||||
```
|
||||
|
@ -6353,7 +6353,7 @@ return function (ContainerConfigurator $containerConfigurator) : void {
|
|||
$services->set(StaticCallToMethodCallRector::class)
|
||||
->call('configure', [[
|
||||
StaticCallToMethodCallRector::STATIC_CALLS_TO_METHOD_CALLS => [
|
||||
\Rector\SymfonyPhpConfig\inline_object(new Rector\Injection\ValueObject\StaticCallToMethodCall('Nette\Utils\FileSystem', 'write', 'Symplify\SmartFileSystem\SmartFileSystem', 'dumpFile'))]
|
||||
\Rector\SymfonyPhpConfig\inline_value_object(new Rector\Injection\ValueObject\StaticCallToMethodCall('Nette\Utils\FileSystem', 'write', 'Symplify\SmartFileSystem\SmartFileSystem', 'dumpFile'))]
|
||||
]]);
|
||||
};
|
||||
```
|
||||
|
@ -12684,7 +12684,7 @@ return function (ContainerConfigurator $containerConfigurator) : void {
|
|||
$services->set(RenameStaticMethodRector::class)
|
||||
->call('configure', [[
|
||||
RenameStaticMethodRector::OLD_TO_NEW_METHODS_BY_CLASSES => [
|
||||
\Rector\SymfonyPhpConfig\inline_object(new Rector\Renaming\ValueObject\StaticCallRename('SomeClass', 'oldMethod', 'AnotherExampleClass', 'newStaticMethod'))]
|
||||
\Rector\SymfonyPhpConfig\inline_value_object(new Rector\Renaming\ValueObject\StaticCallRename('SomeClass', 'oldMethod', 'AnotherExampleClass', 'newStaticMethod'))]
|
||||
]]);
|
||||
};
|
||||
```
|
||||
|
@ -12707,7 +12707,7 @@ return function (ContainerConfigurator $containerConfigurator) : void {
|
|||
$services->set(RenameStaticMethodRector::class)
|
||||
->call('configure', [[
|
||||
RenameStaticMethodRector::OLD_TO_NEW_METHODS_BY_CLASSES => [
|
||||
\Rector\SymfonyPhpConfig\inline_object(new Rector\Renaming\ValueObject\StaticCallRename('SomeClass', 'oldMethod', 'SomeClass', 'newStaticMethod'))]
|
||||
\Rector\SymfonyPhpConfig\inline_value_object(new Rector\Renaming\ValueObject\StaticCallRename('SomeClass', 'oldMethod', 'SomeClass', 'newStaticMethod'))]
|
||||
]]);
|
||||
};
|
||||
```
|
||||
|
@ -12741,7 +12741,7 @@ return function (ContainerConfigurator $containerConfigurator) : void {
|
|||
$services->set(CompleteImportForPartialAnnotationRector::class)
|
||||
->call('configure', [[
|
||||
CompleteImportForPartialAnnotationRector::USE_IMPORTS_TO_RESTORE => [
|
||||
\Rector\SymfonyPhpConfig\inline_object(new Rector\Restoration\ValueObject\UseWithAlias('Doctrine\ORM\Mapping', 'ORM'))]
|
||||
\Rector\SymfonyPhpConfig\inline_value_object(new Rector\Restoration\ValueObject\UseWithAlias('Doctrine\ORM\Mapping', 'ORM'))]
|
||||
]]);
|
||||
};
|
||||
```
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
<?php declare(strict_types=1);
|
||||
|
||||
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
|
||||
|
||||
use PhpCsFixer\Fixer\ClassNotation\ClassAttributesSeparationFixer;
|
||||
use PhpCsFixer\Fixer\Comment\NoTrailingWhitespaceInCommentFixer;
|
||||
use PhpCsFixer\Fixer\Import\NoLeadingImportSlashFixer;
|
||||
|
@ -9,21 +8,23 @@ use PhpCsFixer\Fixer\Import\NoUnusedImportsFixer;
|
|||
use PhpCsFixer\Fixer\Import\OrderedImportsFixer;
|
||||
use PhpCsFixer\Fixer\Phpdoc\NoEmptyPhpdocFixer;
|
||||
use PhpCsFixer\Fixer\Strict\DeclareStrictTypesFixer;
|
||||
use Symplify\EasyCodingStandard\Configuration\Option;
|
||||
use Symplify\EasyCodingStandard\ValueObject\Set\SetList;
|
||||
|
||||
return static function (ContainerConfigurator $containerConfigurator): void {
|
||||
$services = $containerConfigurator->services();
|
||||
|
||||
$services->set(NoUnusedImportsFixer::class);
|
||||
|
||||
$services->set(OrderedImportsFixer::class);
|
||||
|
||||
$services->set(NoLeadingImportSlashFixer::class);
|
||||
|
||||
$services->set(NoTrailingWhitespaceInCommentFixer::class);
|
||||
|
||||
$services->set(NoEmptyPhpdocFixer::class);
|
||||
|
||||
$services->set(ClassAttributesSeparationFixer::class);
|
||||
|
||||
$services->set(DeclareStrictTypesFixer::class);
|
||||
|
||||
$parameters = $containerConfigurator->parameters();
|
||||
|
||||
$parameters->set(Option::SETS, [
|
||||
SetList::DOCTRINE_ANNOTATIONS,
|
||||
]);
|
||||
};
|
||||
|
|
|
@ -43,10 +43,11 @@ final class ArrayPartPhpDocTagPrinterTest extends TestCase
|
|||
yield [['strict' => false], 'option', 'option={"strict":false}'];
|
||||
|
||||
// multiple items, separated by comma
|
||||
yield [[
|
||||
'less' => 'NO',
|
||||
'more' => 'YES',
|
||||
], 'what', 'what={"less":"NO", "more":"YES"}'];
|
||||
yield [
|
||||
[
|
||||
'less' => 'NO',
|
||||
'more' => 'YES',
|
||||
], 'what', 'what={"less":"NO", "more":"YES"}', ];
|
||||
|
||||
// preslash
|
||||
yield [['\John'], 'name', 'name={"\John"}'];
|
||||
|
|
|
@ -62,7 +62,7 @@ final class TemplateFinder
|
|||
*/
|
||||
private function addRuleAndTestCase(RectorRecipe $rectorRecipe, array $filePaths): array
|
||||
{
|
||||
if ($rectorRecipe->getConfigration() !== []) {
|
||||
if ($rectorRecipe->getConfiguration() !== []) {
|
||||
$filePaths[] = __DIR__ . '/../../templates/rules/__package__/src/Rector/__Category__/__Configured__Name__.php';
|
||||
|
||||
if ($rectorRecipe->getExtraFileContent()) {
|
||||
|
|
|
@ -66,7 +66,7 @@ final class TemplateVariablesFactory
|
|||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function createFromRectorRecipe(RectorRecipe $rectorRecipe): array
|
||||
{
|
||||
|
@ -85,26 +85,26 @@ final class TemplateVariablesFactory
|
|||
|
||||
$rectorClass = $this->templateFactory->create(ConfigFilesystem::RECTOR_FQN_NAME_PATTERN, $data);
|
||||
|
||||
if ($rectorRecipe->getConfigration() !== []) {
|
||||
if ($rectorRecipe->getConfiguration() !== []) {
|
||||
$data['__TestRuleConfiguration__'] = $this->createRuleConfiguration(
|
||||
$rectorClass,
|
||||
$rectorRecipe->getConfigration()
|
||||
$rectorRecipe->getConfiguration()
|
||||
);
|
||||
$data['__RuleConfiguration__'] = $this->createRuleConfiguration(
|
||||
self::SELF,
|
||||
$rectorRecipe->getConfigration()
|
||||
$rectorRecipe->getConfiguration()
|
||||
);
|
||||
|
||||
$data['__ConfigurationProperties__'] = $this->createConfigurationProperty(
|
||||
$rectorRecipe->getConfigration()
|
||||
$rectorRecipe->getConfiguration()
|
||||
);
|
||||
|
||||
$data['__ConfigurationConstants__'] = $this->createConfigurationConstants(
|
||||
$rectorRecipe->getConfigration()
|
||||
$rectorRecipe->getConfiguration()
|
||||
);
|
||||
|
||||
$data['__ConfigureClassMethod__'] = $this->createConfigureClassMethod(
|
||||
$rectorRecipe->getConfigration()
|
||||
$rectorRecipe->getConfiguration()
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -66,12 +66,13 @@ final class RectorRecipe
|
|||
/**
|
||||
* @var mixed[]
|
||||
*/
|
||||
private $configration = [];
|
||||
private $configuration = [];
|
||||
|
||||
/**
|
||||
* @var string|null
|
||||
* Use default package name, if not overriden manually
|
||||
* @var string
|
||||
*/
|
||||
private $package;
|
||||
private $package = self::PACKAGE_UTILS;
|
||||
|
||||
/**
|
||||
* @var string|null
|
||||
|
@ -88,24 +89,15 @@ final class RectorRecipe
|
|||
*/
|
||||
private $extraFileContent;
|
||||
|
||||
/**
|
||||
* @param class-string[] $nodeTypes
|
||||
* @param mixed[] $configration
|
||||
*/
|
||||
public function __construct(
|
||||
?string $package,
|
||||
string $name,
|
||||
array $nodeTypes,
|
||||
string $description,
|
||||
string $codeBefore,
|
||||
string $codeAfter,
|
||||
array $resources,
|
||||
?string $set = null,
|
||||
array $configration = [],
|
||||
?string $extraFileName = null,
|
||||
?string $extraFileContent = null,
|
||||
?bool $isRectorRepository = null
|
||||
string $codeAfter
|
||||
) {
|
||||
$this->isRectorRepository = file_exists(__DIR__ . '/../../../../vendor');
|
||||
|
||||
$this->setName($name);
|
||||
$this->setNodeTypes($nodeTypes);
|
||||
|
||||
|
@ -113,28 +105,13 @@ final class RectorRecipe
|
|||
|
||||
$this->setCodeBefore($codeBefore);
|
||||
$this->setCodeAfter($codeAfter);
|
||||
$this->setResources($resources);
|
||||
|
||||
$this->set = $set;
|
||||
$this->configration = $configration;
|
||||
$this->extraFileName = $extraFileName;
|
||||
$this->setExtraFileContent($extraFileContent);
|
||||
$this->setIsRectorRepository($isRectorRepository);
|
||||
|
||||
// last on purpose, depends on isRectorRepository
|
||||
$this->setPackage($package);
|
||||
|
||||
$this->resolveCategory();
|
||||
$this->resolveCategory($nodeTypes);
|
||||
}
|
||||
|
||||
public function getPackage(): string
|
||||
{
|
||||
$recipePackage = $this->package;
|
||||
if (! $this->isRectorRepository || $recipePackage === null || $recipePackage === '') {
|
||||
return self::PACKAGE_UTILS;
|
||||
}
|
||||
|
||||
return $recipePackage;
|
||||
return $this->package;
|
||||
}
|
||||
|
||||
public function getName(): string
|
||||
|
@ -167,6 +144,11 @@ final class RectorRecipe
|
|||
return $this->resources;
|
||||
}
|
||||
|
||||
public function setSet(string $set): void
|
||||
{
|
||||
$this->set = $set;
|
||||
}
|
||||
|
||||
public function getSet(): ?string
|
||||
{
|
||||
return $this->set;
|
||||
|
@ -175,9 +157,9 @@ final class RectorRecipe
|
|||
/**
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function getConfigration(): array
|
||||
public function getConfiguration(): array
|
||||
{
|
||||
return $this->configration;
|
||||
return $this->configuration;
|
||||
}
|
||||
|
||||
public function getExtraFileName(): ?string
|
||||
|
@ -219,6 +201,50 @@ final class RectorRecipe
|
|||
return StaticRectorStrings::camelCaseToDashes($this->getPackage());
|
||||
}
|
||||
|
||||
/**
|
||||
* @api
|
||||
*/
|
||||
public function setPackage(string $package): void
|
||||
{
|
||||
$this->package = $package;
|
||||
}
|
||||
|
||||
/**
|
||||
* @api
|
||||
*/
|
||||
public function addExtraFile(string $extraFileName, string $extraFileContent): void
|
||||
{
|
||||
$this->extraFileName = $extraFileName;
|
||||
$this->extraFileContent = $this->normalizeCode($extraFileContent);
|
||||
}
|
||||
|
||||
/**
|
||||
* @api
|
||||
* @param mixed[] $configuration
|
||||
*/
|
||||
public function setConfiguration(array $configuration): void
|
||||
{
|
||||
$this->configuration = $configuration;
|
||||
}
|
||||
|
||||
/**
|
||||
* @api
|
||||
* @param string[] $resources
|
||||
*/
|
||||
public function setResources(array $resources): void
|
||||
{
|
||||
$this->resources = array_filter($resources);
|
||||
}
|
||||
|
||||
/**
|
||||
* For testing purposes
|
||||
* @api
|
||||
*/
|
||||
public function setIsRectorRepository(bool $isRectorRepository): void
|
||||
{
|
||||
$this->isRectorRepository = $isRectorRepository;
|
||||
}
|
||||
|
||||
private function setName(string $name): void
|
||||
{
|
||||
if (! Strings::endsWith($name, 'Rector')) {
|
||||
|
@ -267,45 +293,12 @@ final class RectorRecipe
|
|||
$this->codeAfter = $this->normalizeCode($codeAfter);
|
||||
}
|
||||
|
||||
private function setResources(array $resources): void
|
||||
/**
|
||||
* @param string[] $nodeTypes
|
||||
*/
|
||||
private function resolveCategory(array $nodeTypes): void
|
||||
{
|
||||
$this->resources = array_filter($resources);
|
||||
}
|
||||
|
||||
private function setExtraFileContent(?string $extraFileContent): void
|
||||
{
|
||||
if ($extraFileContent === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->extraFileContent = $this->normalizeCode($extraFileContent);
|
||||
}
|
||||
|
||||
private function setIsRectorRepository(?bool $isRectorRepository): void
|
||||
{
|
||||
$this->isRectorRepository = $isRectorRepository ?? file_exists(__DIR__ . '/../../../../vendor');
|
||||
}
|
||||
|
||||
private function setPackage(?string $package): void
|
||||
{
|
||||
if ($package !== '' && $package !== null && $package !== self::PACKAGE_UTILS) {
|
||||
$this->package = $package;
|
||||
return;
|
||||
}
|
||||
|
||||
// only can be empty or utils when outside Rector repository
|
||||
if (! $this->isRectorRepository) {
|
||||
$this->package = $package;
|
||||
return;
|
||||
}
|
||||
|
||||
$message = sprintf('Parameter "package" cannot be empty or "Utils", when in Rector repository');
|
||||
throw new ConfigurationException($message);
|
||||
}
|
||||
|
||||
private function resolveCategory(): void
|
||||
{
|
||||
$this->category = (string) Strings::after($this->nodeTypes[0], '\\', -1);
|
||||
$this->category = (string) Strings::after($nodeTypes[0], '\\', -1);
|
||||
}
|
||||
|
||||
private function detectIsPhpSnippet(string $codeBefore): void
|
||||
|
|
|
@ -6,17 +6,17 @@ namespace Rector\RectorGenerator\Tests\RectorGenerator\Source;
|
|||
|
||||
use PhpParser\Node\Expr\MethodCall;
|
||||
use Rector\RectorGenerator\ValueObject\RectorRecipe;
|
||||
use Rector\Set\ValueObject\SetList;
|
||||
|
||||
final class StaticRectorRecipeFactory
|
||||
{
|
||||
public static function createRectorRecipe(bool $isRectorRepository): RectorRecipe
|
||||
{
|
||||
return new RectorRecipe(
|
||||
'ModeratePackage',
|
||||
$rectorRecipe = new RectorRecipe(
|
||||
'WhateverRector',
|
||||
[MethodCall::class],
|
||||
'Change $service->arg(...) to $service->call(...)',
|
||||
<<<'CODE_SAMPLE'
|
||||
<<<'CODE_SAMPLE'
|
||||
<?php
|
||||
|
||||
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
|
||||
|
@ -27,8 +27,8 @@ return static function (ContainerConfigurator $containerConfigurator): void {
|
|||
$services->set(SomeClass::class)
|
||||
->arg('$key', 'value');
|
||||
}
|
||||
CODE_SAMPLE,
|
||||
<<<'CODE_SAMPLE'
|
||||
CODE_SAMPLE
|
||||
, <<<'CODE_SAMPLE'
|
||||
<?php
|
||||
|
||||
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
|
||||
|
@ -41,21 +41,23 @@ return static function (ContainerConfigurator $containerConfigurator): void {
|
|||
'$key' => 'value'
|
||||
]]);
|
||||
}
|
||||
CODE_SAMPLE,
|
||||
// e.g. link to RFC or headline in upgrade guide, 1 or more in the list
|
||||
[],
|
||||
// e.g. symfony30, target set to add this Rule to; keep null if part of core
|
||||
null,
|
||||
|
||||
// OPTIONAL: only when configured
|
||||
[
|
||||
'CLASS_TYPE_TO_METHOD_NAME' => [
|
||||
'SomeClass' => 'configure'
|
||||
]
|
||||
],
|
||||
null,
|
||||
null,
|
||||
$isRectorRepository
|
||||
CODE_SAMPLE
|
||||
);
|
||||
|
||||
$rectorRecipe->setConfiguration([
|
||||
'CLASS_TYPE_TO_METHOD_NAME' => [
|
||||
'SomeClass' => 'configure'
|
||||
]
|
||||
]);
|
||||
|
||||
$rectorRecipe->setIsRectorRepository($isRectorRepository);
|
||||
|
||||
if ($isRectorRepository) {
|
||||
$rectorRecipe->setPackage('ModeratePackage');
|
||||
}
|
||||
|
||||
$rectorRecipe->setSet(SetList::DEAD_CODE);
|
||||
|
||||
return $rectorRecipe;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -56,6 +56,9 @@ return static function (ContainerConfigurator $containerConfigurator): void {
|
|||
__DIR__ . '/packages/doctrine-annotation-generated/src/*',
|
||||
// tempalte files
|
||||
__DIR__ . '/packages/rector-generator/templates/*',
|
||||
// public api
|
||||
__DIR__ . '/packages/rector-generator/src/ValueObject/RectorRecipe.php',
|
||||
__DIR__ . '/rules/symfony-php-config/functions/functions.php',
|
||||
]);
|
||||
|
||||
$parameters->set(Option::EXCLUDE_RECTORS, [
|
||||
|
|
|
@ -2,27 +2,29 @@
|
|||
|
||||
declare(strict_types=1);
|
||||
|
||||
use PhpParser\Node\Stmt\ClassMethod;
|
||||
use PhpParser\Node\Expr\MethodCall;
|
||||
use Rector\RectorGenerator\Provider\RectorRecipeProvider;
|
||||
use Rector\RectorGenerator\ValueObject\RectorRecipe;
|
||||
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
|
||||
use function Rector\SymfonyPhpConfig\inline_object;
|
||||
use function Rector\SymfonyPhpConfig\inline_single_object;
|
||||
|
||||
// run "bin/rector generate" to a new Rector basic schema + tests from this config
|
||||
return static function (ContainerConfigurator $containerConfigurator): void {
|
||||
$services = $containerConfigurator->services();
|
||||
// [REQUIRED]
|
||||
|
||||
$rectorRecipe = new RectorRecipe(
|
||||
// category
|
||||
'Symfony',
|
||||
// name
|
||||
'RenameClassMethod',
|
||||
// node types - this will get in "getNodeTypes()" method
|
||||
[ClassMethod::class],
|
||||
// description
|
||||
'Change some class method to different name',
|
||||
// name, basically short class name; use PascalCase
|
||||
'RenameMethodCallRector',
|
||||
|
||||
// code before
|
||||
// particular node types to change
|
||||
// the best practise is to have just 1 type here if possible, and make separated rule for other node types
|
||||
[MethodCall::class],
|
||||
|
||||
// describe what the rule does
|
||||
'"something()" will be renamed to "somethingElse()"',
|
||||
|
||||
// code before change
|
||||
// this is used for documentation and first test fixture
|
||||
<<<'CODE_SAMPLE'
|
||||
<?php
|
||||
|
||||
|
@ -30,40 +32,51 @@ class SomeClass
|
|||
{
|
||||
public function run()
|
||||
{
|
||||
$this->something();
|
||||
}
|
||||
}
|
||||
CODE_SAMPLE,
|
||||
// code after
|
||||
<<<'CODE_SAMPLE'
|
||||
|
||||
CODE_SAMPLE
|
||||
|
||||
// code after change
|
||||
, <<<'CODE_SAMPLE'
|
||||
<?php
|
||||
|
||||
class SomeClass
|
||||
{
|
||||
public function go()
|
||||
public function run()
|
||||
{
|
||||
$this->somethingElse();
|
||||
}
|
||||
}
|
||||
CODE_SAMPLE,
|
||||
// informational resources on "why" the change, e.g. RFC, upgrade guide on Github
|
||||
[
|
||||
'https://...'
|
||||
],
|
||||
|
||||
// OPTIONAL ↓
|
||||
|
||||
// e.g. symfony30, target set to add this Rule to; keep null if part of core
|
||||
// set, use `SetList::SOME_CONSTANT` for this
|
||||
null,
|
||||
|
||||
// configuration in array
|
||||
[],
|
||||
|
||||
// extra file name
|
||||
null,
|
||||
// extra file content
|
||||
null
|
||||
CODE_SAMPLE
|
||||
);
|
||||
|
||||
// [OPTIONAL - UNCOMMENT TO USE]
|
||||
|
||||
// links to useful websites, that explain why the change is needed
|
||||
// $rectorRecipe->setResources([
|
||||
// 'https://github.com/symfony/symfony/blob/704c648ba53be38ef2b0105c97c6497744fef8d8/UPGRADE-6.0.md'
|
||||
// ]);
|
||||
|
||||
// do you need to check for extra generated file?
|
||||
// $rectorRecipe->addExtraFile('SomeExtraFile.php', '<?php ... SomeExtraFileContent');
|
||||
|
||||
// is the rule configurable? add default configuration here
|
||||
// $rectorRecipe->addConfiguration(['SOME_CONSTANT_KEY' => ['before' => 'after']]);
|
||||
|
||||
|
||||
// [RECTOR CORE CONTRIBUTION]
|
||||
// [RECTOR CORE CONTRIBUTION - REQUIRED]
|
||||
// package name, basically part namespace in `rule/<package>/src`, use PascalCase
|
||||
// $rectorRecipe->setPackage('Generic');
|
||||
|
||||
// [RECTOR CORE CONTRIBUTION - OPTIONAL]
|
||||
// set the rule belongs to; is optional, because e.g. generic rules don't need a specific set to belong to
|
||||
// $rectorRecipe->setSet(\Rector\Set\ValueObject\SetList::NAMING);
|
||||
|
||||
$services = $containerConfigurator->services();
|
||||
|
||||
$services->set(RectorRecipeProvider::class)
|
||||
->arg('$rectorRecipe', inline_object($rectorRecipe));
|
||||
->arg('$rectorRecipe', inline_single_object($rectorRecipe, $services));
|
||||
};
|
||||
|
|
|
@ -1,396 +0,0 @@
|
|||
includes:
|
||||
- utils/phpstan-extensions/config/phpstan-extensions.neon
|
||||
- vendor/symplify/phpstan-extensions/config/config.neon
|
||||
- vendor/thecodingmachine/phpstan-strict-rules/phpstan-strict-rules.neon
|
||||
- vendor/slam/phpstan-extensions/conf/slam-rules.neon
|
||||
|
||||
# see https://github.com/symplify/coding-standard
|
||||
- vendor/symplify/coding-standard/config/symplify-rules.neon
|
||||
|
||||
rules:
|
||||
# should be fixed in next part of symplify CS release
|
||||
- Symplify\CodingStandard\Rules\NoClassWithStaticMethodWithoutStaticNameRule
|
||||
- Symplify\CodingStandard\Rules\SeeAnnotationToTestRule
|
||||
|
||||
services:
|
||||
# this rule prevents bug in phar like these: https://github.com/rectorphp/rector/pull/3692/files
|
||||
-
|
||||
class: Rector\PHPStanExtensions\Rule\RequireStringArgumentInMethodCallRule
|
||||
tags: [phpstan.rules.rule]
|
||||
arguments:
|
||||
constantArgByMethodByType:
|
||||
Rector\Core\Rector\AbstractRector:
|
||||
isObjectType: [1]
|
||||
|
||||
parameters:
|
||||
level: max
|
||||
|
||||
# see https://github.com/symplify/coding-standard
|
||||
symplify:
|
||||
max_cognitive_complexity: 9 # default: 8
|
||||
max_class_cognitive_complexity: 50
|
||||
|
||||
parent_classes:
|
||||
- Rector
|
||||
|
||||
required_see_types:
|
||||
- PHPStan\Rules\Rule
|
||||
- Rector\Core\Rector\AbstractRector
|
||||
- Rector\FileSystemRector\Rector\AbstractFileSystemRector
|
||||
|
||||
old_to_preffered_classes:
|
||||
# prevent PHPStorm autocomplete mess
|
||||
'Symfony\Component\DependencyInjection\Variable': 'PhpParser\Node\Expr\Variable'
|
||||
'phpDocumentor\Reflection\Types\Expression': 'PhpParser\Node\Stmt\Expression'
|
||||
'phpDocumentor\Reflection\DocBlock\Tags\Param': 'PhpParser\Node\Param'
|
||||
'phpDocumentor\Reflection\DocBlock\Tags\Return_': 'PhpParser\Node\Stmt\Return_'
|
||||
'Closure': 'PhpParser\Node\Expr\Closure'
|
||||
'PHPUnit\TextUI\Configuration\Variable': 'PhpParser\Node\Expr\Variable'
|
||||
'PhpCsFixer\FixerDefinition\CodeSample': 'Rector\Core\RectorDefinition\CodeSample'
|
||||
'SebastianBergmann\Type\MixedType': 'PHPStan\Type\MixedType'
|
||||
'Hoa\Protocol\Node\Node': 'PhpParser\Node'
|
||||
|
||||
# to allow installing with various phsptan versions without reporting old errors here
|
||||
reportUnmatchedIgnoredErrors: false
|
||||
|
||||
checkGenericClassInNonGenericObjectType: false
|
||||
|
||||
scanDirectories:
|
||||
- stubs
|
||||
|
||||
bootstrapFiles:
|
||||
- vendor/symfony/dependency-injection/Loader/Configurator/ContainerConfigurator.php
|
||||
|
||||
paths:
|
||||
- bin
|
||||
- src
|
||||
- rules
|
||||
- packages
|
||||
- tests
|
||||
- compiler/src
|
||||
- utils
|
||||
# this cannot be put it, because it wipes PHPStan cache on each run
|
||||
#- config
|
||||
|
||||
excludes_analyse:
|
||||
# iterable types
|
||||
- '#with no value type specified in iterable type array#'
|
||||
- '#type specified in iterable type (array|iterable)#'
|
||||
|
||||
# phsptan bug
|
||||
- utils/phpstan-extensions/src/Rule/PreventParentMethodVisibilityOverrideRule.php
|
||||
- utils/phpstan-extensions/src/Rule/KeepRectorNamespaceForRectorRule.php
|
||||
- packages/rector-generator/templates/*
|
||||
|
||||
# generated files
|
||||
- 'packages/doctrine-annotation-generated/src/ConstantPreservingDocParser.php'
|
||||
- 'packages/doctrine-annotation-generated/src/ConstantPreservingAnnotationReader.php'
|
||||
|
||||
- "*/Expected/*"
|
||||
# complex printer
|
||||
- '*tests/Rector/MethodCall/RenameMethodRector/**/SomeClass.php'
|
||||
# tests files
|
||||
- '*tests/*/Fixture/*'
|
||||
- '*tests/*/Source/*'
|
||||
- '*tests/Source/*'
|
||||
# part of composer
|
||||
- '*/tests/Rector/Psr4/MultipleClassFileToPsr4ClassesRector/Expected/Just*ExceptionWithoutNamespace.php'
|
||||
|
||||
ignoreErrors:
|
||||
# @todo remove
|
||||
# iterable types
|
||||
- '#with no value type specified in iterable type array#'
|
||||
- '#type specified in iterable type (array|iterable)#'
|
||||
|
||||
# false positive
|
||||
- '#PHPDoc tag \@param for parameter \$node with type float is incompatible with native type PhpParser\\Node#'
|
||||
|
||||
# misuse of interface and class
|
||||
- '#Parameter \#1 (.*?) expects Symfony\\Component\\DependencyInjection\\ContainerBuilder, Symfony\\Component\\DependencyInjection\\ContainerInterface given#'
|
||||
- '#Strict comparison using === between string and null will always evaluate to false#'
|
||||
|
||||
# false positive - type is set by annotation above
|
||||
- '#Array \(array<PhpParser\\Node\\Stmt>\) does not accept PhpParser\\Node#'
|
||||
|
||||
# irrelevant
|
||||
- '#Call to function in_array\(\) with arguments string, (.*?) and true will always evaluate to false#'
|
||||
|
||||
# known values
|
||||
- '#Access to an undefined property PhpParser\\Node\\Expr::\$right#'
|
||||
|
||||
- '#Access to an undefined property PhpParser\\Node\\Expr\\MethodCall\|PhpParser\\Node\\Stmt\\ClassMethod::\$params#'
|
||||
- '#Cannot call method getName\(\) on PHPStan\\Reflection\\ClassReflection\|null#'
|
||||
|
||||
# false positive, has annotation type above
|
||||
- '#Method Rector\\CodeQuality\\Rector\\Foreach_\\SimplifyForeachToCoalescingRector\:\:matchReturnOrAssignNode\(\) should return PhpParser\\Node\\Expr\\Assign\|PhpParser\\Node\\Stmt\\Return_\|null but returns PhpParser\\Node\|null#'
|
||||
- '#Access to an undefined property PhpParser\\Node::\$(\w+)#'
|
||||
|
||||
# intentionally incorrect - part of the test
|
||||
- '#Parameter \#2 \$codeSamples of class Rector\\Core\\RectorDefinition\\RectorDefinition constructor expects array<Rector\\Core\\Contract\\RectorDefinition\\CodeSampleInterface>, array<int, stdClass> given#'
|
||||
|
||||
# known values
|
||||
- '#Cannot access property \$value on PhpParser\\Node\\Expr\\ArrayItem\|null#'
|
||||
|
||||
# known values
|
||||
- '#Strict comparison using === between PhpParser\\Node\\Expr and null will always evaluate to false#'
|
||||
|
||||
- '#Access to an undefined property PhpParser\\Node\\Stmt\:\:\$expr#'
|
||||
- '#Cannot access property \$stmts on PhpParser\\Node\\Stmt\\Else_\|null#'
|
||||
|
||||
# node finder
|
||||
- '#Method Rector\\(.*?) should return array<PhpParser\\Node\\(.*?)> but returns array<PhpParser\\Node\>#'
|
||||
|
||||
# part of test
|
||||
- '#(.*?)(AttributeAwareNodeInterface|AttributeAware(.*?)TagValueNode)(.*?)#'
|
||||
|
||||
- '#Parameter \#1 \$children of class PHPStan\\PhpDocParser\\Ast\\PhpDoc\\PhpDocNode constructor expects array<PHPStan\\PhpDocParser\\Ast\\PhpDoc\\PhpDocChildNode\>, array<int, PHPStan\\PhpDocParser\\Ast\\Node\> given#'
|
||||
- '#Method Rector\\PHPUnit\\Rector\\MethodCall\\ReplaceAssertArraySubsetRector\:\:matchArray\(\) should return PhpParser\\Node\\Expr\\Array_\|null but returns PhpParser\\Node\\Expr#'
|
||||
|
||||
- '#(.*?)PhpParser\\Node\\Expr\\Error\|PhpParser\\Node\\Expr\\Variable given#'
|
||||
|
||||
# false positive 0.11.5
|
||||
- '#Unreachable statement \- code above always terminates#'
|
||||
- '#Negated boolean expression is always true#'
|
||||
- '#Strict comparison using \=\=\= between PhpParser\\Node and null will always evaluate to false#'
|
||||
|
||||
# known types
|
||||
- '#Access to an undefined property PhpParser\\Node\\Expr\\Error\|PhpParser\\Node\\Expr\\Variable\:\:\$name#'
|
||||
- '#Strict comparison using \=\=\= between PhpParser\\Node\\Expr\\ArrayItem and null will always evaluate to false#'
|
||||
- '#Parameter \#2 \.\.\.\$args of function array_merge expects array, array<int, string\>\|false given#'
|
||||
- '#Access to an undefined property PhpParser\\Node\\Expr\:\:\$args#'
|
||||
|
||||
- '#Parameter \#2 \$name of method Rector\\Core\\Rector\\AbstractRector\:\:isName\(\) expects string, string\|null given#'
|
||||
# cascade irrelevant
|
||||
- '#Parameter (.*?) expects array<PhpParser\\Node\\Stmt\>, array<PhpParser\\Node\> given#'
|
||||
|
||||
# known value
|
||||
- '#Cannot cast array<string\>\|bool\|string\|null to string#'
|
||||
- '#Method Rector\\Legacy\\Rector\\Class_\\ChangeSingletonToServiceRector\:\:matchStaticPropertyFetchAndGetSingletonMethodName\(\) should return array<string\>\|null but returns array<int, string\|null\>#'
|
||||
|
||||
- '#Parameter \#2 \$currentNode of method Rector\\CodingStyle\\Rector\\Assign\\ManualJsonStringToJsonEncodeArrayRector\:\:matchNextExpressionAssignConcatToSameVariable\(\) expects PhpParser\\Node\\Expr\\Assign\|PhpParser\\Node\\Expr\\AssignOp\\Concat, PhpParser\\Node given#'
|
||||
|
||||
# array is callable
|
||||
- '#If condition is always true#'
|
||||
|
||||
- '#Ternary operator condition is always true#'
|
||||
|
||||
- '#Access to an undefined property PhpParser\\Node\\FunctionLike\|PhpParser\\Node\\Stmt\\ClassLike\:\:\$stmts#'
|
||||
|
||||
- '#Property Rector\\TypeDeclaration\\TypeInferer\\(.*?)\:\:\$(.*?)TypeInferers \(array<Rector\\TypeDeclaration\\Contract\\TypeInferer\\(.*?)TypeInfererInterface\>\) does not accept array<Rector\\TypeDeclaration\\Contract\\TypeInferer\\PriorityAwareTypeInfererInterface\>#'
|
||||
# sense-less errors
|
||||
|
||||
# 3rd party
|
||||
-
|
||||
message: '#Use default null value and nullable compare instead of isset on object#'
|
||||
path: 'rules/symfony/src/ServiceMapProvider.php'
|
||||
|
||||
# PHP 7.4 1_000 support
|
||||
- '#Property PhpParser\\Node\\Scalar\\DNumber\:\:\$value \(float\) does not accept string#'
|
||||
- '#Call to function is_string\(\) with float will always evaluate to false#'
|
||||
|
||||
- '#Method Rector\\Doctrine\\Rector\\MethodCall\\ChangeSetIdToUuidValueRector\:\:getSetUuidMethodCallOnSameVariable\(\) should return PhpParser\\Node\\Expr\\MethodCall\|null but returns PhpParser\\Node\|null#'
|
||||
|
||||
# known value
|
||||
- '#Method Rector\\StrictCodeQuality\\Rector\\Stmt\\VarInlineAnnotationToAssertRector\:\:findVariableByName\(\) should return PhpParser\\Node\\Expr\\Variable\|null but returns PhpParser\\Node\|null#'
|
||||
|
||||
- '#Method Rector\\NodeTypeResolver\\PHPStan\\Type\\TypeFactory\:\:createUnionOrSingleType\(\) should return PHPStan\\Type\\MixedType\|PHPStan\\Type\\UnionType but returns PHPStan\\Type\\Type#'
|
||||
|
||||
# test
|
||||
- '#Class Rector\\DynamicTypeAnalysis\\Tests\\Rector\\ClassMethod\\AddArgumentTypeWithProbeDataRector\\Fixture\\SomeClass not found#'
|
||||
|
||||
-
|
||||
message: '#Class Rector\\Generic\\Tests\\Rector\\StaticCall\\SwapClassMethodArgumentsRector\\Fixture\\SomeClass not found#'
|
||||
path: rules/generic/tests/Rector/StaticCall/SwapClassMethodArgumentsRector/SwapClassMethodArgumentsRectorTest.php
|
||||
|
||||
# internal rule
|
||||
- '#Class "Rector\\Utils\\(.*?)" is missing @see annotation with test case class reference#'
|
||||
|
||||
# mixed
|
||||
- '#Offset int\|string\|null does not exist on array<PhpParser\\Node\\Stmt>\|null#'
|
||||
- '#class-string<T of object>\|T of object#'
|
||||
|
||||
# known values
|
||||
- '#Offset 0 does not exist on array<PhpParser\\Node\\Stmt>\|null#'
|
||||
- '#Parameter \#1 \$left of class PhpParser\\Node\\Expr\\BinaryOp\\Spaceship constructor expects PhpParser\\Node\\Expr, PhpParser\\Node\\Expr\|null given#'
|
||||
- '#Parameter \#2 \$right of class PhpParser\\Node\\Expr\\BinaryOp\\Spaceship constructor expects PhpParser\\Node\\Expr, PhpParser\\Node\\Expr\|null given#'
|
||||
- '#Parameter \#3 \$nodeCallback of method PHPStan\\Analyser\\NodeScopeResolver::processNodes\(\) expects Closure\(PhpParser\\Node, PHPStan\\Analyser\\Scope\): void, Closure\(PhpParser\\Node, PHPStan\\Analyser\\MutatingScope\): void given#'
|
||||
|
||||
# false positive
|
||||
- '#Comparison operation "<" between 0 and 2 is always true#'
|
||||
|
||||
- '#Method Rector\\Symfony\\Rector\\MethodCall\\AbstractToConstructorInjectionRector\:\:getServiceTypeFromMethodCallArgument\(\) should return PHPStan\\Type\\Type but returns PHPStan\\Type\\Type\|null#'
|
||||
|
||||
- '#Parameter \#1 \$expected of method PHPUnit\\Framework\\Assert\:\:assertInstanceOf\(\) expects class\-string<object\>, string given#'
|
||||
- '#Unable to resolve the template type ExpectedType in call to method PHPUnit\\Framework\\Assert\:\:assertInstanceOf\(\)#'
|
||||
|
||||
# fix Symplify 7.2 later
|
||||
- '#Method (.*?) returns bool type, so the name should start with is/has/was#'
|
||||
|
||||
# known value
|
||||
- '#Cannot cast \(array<string\>\)\|string\|true to string#'
|
||||
|
||||
- '#In method "Rector\\BetterPhpDocParser\\AnnotationReader\\NodeAnnotationReader\:\:createPropertyReflectionFromPropertyNode", caught "Throwable" must be rethrown\. Either catch a more specific exception or add a "throw" clause in the "catch" block to propagate the exception\. More info\: http\://bit\.ly/failloud#'
|
||||
# doc is not enough
|
||||
- '#Result of \|\| is always true#'
|
||||
|
||||
# known value
|
||||
- '#Parameter \#2 \$name of class PhpParser\\Node\\Expr\\MethodCall constructor expects PhpParser\\Node\\Expr\|PhpParser\\Node\\Identifier\|string, string\|null given#'
|
||||
|
||||
- '#Parameter \#1 \$eventListenerTag of method Rector\\SymfonyCodeQuality\\Rector\\Class_\\EventListenerToEventSubscriberRector\:\:createEventItem\(\) expects Rector\\Symfony\\ValueObject\\Tag\\EventListenerTag, Rector\\Symfony\\Contract\\Tag\\TagInterface given#'
|
||||
- '#Method Rector\\BetterPhpDocParser\\PhpDocInfo\\PhpDocInfoFactory\:\:parseTokensToPhpDocNode\(\) should return Rector\\AttributeAwarePhpDoc\\Ast\\PhpDoc\\AttributeAwarePhpDocNode but returns PHPStan\\PhpDocParser\\Ast\\PhpDoc\\PhpDocNode#'
|
||||
|
||||
- '#Property PhpParser\\Node\\Stmt\\Expression\:\:\$expr \(PhpParser\\Node\\Expr\) does not accept PhpParser\\Node\\Expr\|null#'
|
||||
- '#Call to an undefined method PHPStan\\Type\\Type\:\:getClassName\(\)#'
|
||||
- '#Parameter \#1 \$typeNode of method Rector\\StaticTypeMapper\\StaticTypeMapper\:\:mapPHPStanPhpDocTypeNodeToPHPStanType\(\) expects PHPStan\\PhpDocParser\\Ast\\Type\\TypeNode, PHPStan\\PhpDocParser\\Ast\\Node given#'
|
||||
- '#Parameter \#1 \$str of function preg_quote expects string, int\|string given#'
|
||||
|
||||
- '#Parameter \#1 \$sprintfFuncCall of method Rector\\Core\\PhpParser\\NodeTransformer\:\:transformSprintfToArray\(\) expects PhpParser\\Node\\Expr\\FuncCall, PhpParser\\Node given#'
|
||||
- '#Parameter \#1 \$nodes of method Rector\\Core\\PhpParser\\Node\\BetterNodeFinder\:\:find\(\) expects array<PhpParser\\Node\>\|PhpParser\\Node, array<PhpParser\\Node\\Stmt\>\|null given#'
|
||||
- '#Method Rector\\SOLID\\Reflection\\ParentConstantReflectionResolver\:\:(.*?)\(\) should return ReflectionClassConstant\|null but returns ReflectionClassConstant\|false#'
|
||||
- '#Parameter \#1 \$firstStmt of method Rector\\Generic\\Rector\\ClassMethod\\NormalToFluentRector\:\:isBothMethodCallMatch\(\) expects PhpParser\\Node\\Stmt\\Expression, PhpParser\\Node\\Stmt given#'
|
||||
- '#Method Rector\\Core\\Rector\\AbstractRector\:\:wrapToArg\(\) should return array<PhpParser\\Node\\Arg\> but returns array<PhpParser\\Node\\Arg\|PhpParser\\Node\\Expr\>#'
|
||||
|
||||
- '#Method Rector\\FileSystemRector\\Rector\\AbstractFileSystemRector\:\:wrapToArg\(\) should return array<PhpParser\\Node\\Arg\> but returns array<PhpParser\\Node\\Arg\|PhpParser\\Node\\Expr\>#'
|
||||
- '#Cannot call method (.*?)\(\) on Rector\\BetterPhpDocParser\\PhpDocInfo\\PhpDocInfo\|null#'
|
||||
|
||||
- '#Right side of && is always true#'
|
||||
- '#Parameter \#(.*?) (.*?) of class PhpParser\\Node\\Expr\\BinaryOp\\(.*?) constructor expects PhpParser\\Node\\Expr, PhpParser\\Node given#'
|
||||
|
||||
- '#Access to an undefined property PHPStan\\PhpDocParser\\Ast\\PhpDoc\\PhpDocTagValueNode\:\:\$description#'
|
||||
|
||||
- '#Method Rector\\Php80\\Rector\\NotIdentical\\StrContainsRector\:\:matchNotIdenticalToFalse\(\) should return PhpParser\\Node\\Expr\\FuncCall\|null but returns PhpParser\\Node\\Expr#'
|
||||
|
||||
- '#Parameter \#2 \$name of method Rector\\Core\\Rector\\AbstractRector\:\:isVariableName\(\) expects string, string\|null given#'
|
||||
|
||||
# node finder
|
||||
- '#Method Rector\\Core\\PhpParser\\Node\\Manipulator\\MethodCallManipulator\:\:findAssignToVariableName\(\) should return PhpParser\\Node\\Expr\\Assign\|null but returns PhpParser\\Node\|null#'
|
||||
|
||||
# broken
|
||||
- '#Cannot call method getParentNode\(\) on Rector\\DeadCode\\ValueObject\\VariableNodeUse\|null#'
|
||||
- '#Method Rector\\DeadCode\\NodeFinder\\PreviousVariableAssignNodeFinder\:\:find\(\) should return PhpParser\\Node\\Expr\\Assign\|null but returns PhpParser\\Node\|null#'
|
||||
- '#Parameter \#2 \$name of method Rector\\NodeNameResolver\\NodeNameResolver\:\:isName\(\) expects string, string\|null given#'
|
||||
- '#Method Rector\\PHPOffice\\Rector\\MethodCall\\IncreaseColumnIndexRector\:\:findVariableAssignName\(\) should return PhpParser\\Node\\Expr\\Assign\|null but returns PhpParser\\Node\|null#'
|
||||
|
||||
- '#Parameter \#1 \$keyName of method Rector\\AttributeAwarePhpDoc\\Ast\\Type\\AttributeAwareArrayShapeItemNode\:\:createKeyWithSpacePattern\(\) expects PHPStan\\PhpDocParser\\Ast\\ConstExpr\\ConstExprIntegerNode\|PHPStan\\PhpDocParser\\Ast\\Type\\IdentifierTypeNode\|null, PHPStan\\PhpDocParser\\Ast\\ConstExpr\\ConstExprIntegerNode\|PHPStan\\PhpDocParser\\Ast\\ConstExpr\\ConstExprStringNode\|PHPStan\\PhpDocParser\\Ast\\Type\\IdentifierTypeNode\|null given#'
|
||||
- '#Method Rector\\Caching\\ChangedFilesDetector\:\:hashFile\(\) should return string but returns string\|false#'
|
||||
|
||||
- '#If condition is always false#'
|
||||
|
||||
- '#Parameter \#1 \$funcCall of method Rector\\Php80\\MatchAndRefactor\\StrStartsWithMatchAndRefactor\\AbstractMatchAndRefactor\:\:createStrStartsWithValueObjectFromFuncCall\(\) expects PhpParser\\Node\\Expr\\FuncCall, PhpParser\\Node\\Expr given#'
|
||||
|
||||
# mostly strings in tests
|
||||
- '#Class (.*?) should be written with \:\:class notation, string found#'
|
||||
- '#Parameter \#2 \$key of method Rector\\BetterPhpDocParser\\PhpDocNode\\AbstractTagValueNode\:\:printArrayItem\(\) expects string\|null, int\|string given#'
|
||||
- '#Method Rector\\Naming\\Naming\\PropertyNaming\:\:resolveShortClassName\(\) should return string but returns string\|null#'
|
||||
|
||||
-
|
||||
message: "#^Class cognitive complexity for \"PhpDocInfo\" is 53, keep it under 50$#"
|
||||
count: 1
|
||||
path: packages/better-php-doc-parser/src/PhpDocInfo/PhpDocInfo.php
|
||||
|
||||
-
|
||||
message: "#in iterable type Iterator#"
|
||||
paths:
|
||||
- *Test.php
|
||||
- *TestCase.php
|
||||
|
||||
-
|
||||
message: "#^Cognitive complexity for \"Rector\\\\BetterPhpDocParser\\\\Printer\\\\WhitespaceDetector\\:\\:detectOldWhitespaces\\(\\)\" is 18, keep it under 9$#"
|
||||
count: 1
|
||||
path: packages/better-php-doc-parser/src/Printer/WhitespaceDetector.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$input of function array_splice expects array, array\\<PhpParser\\\\Node\\\\Stmt\\>\\|null given\\.$#"
|
||||
count: 1
|
||||
path: rules/coding-style/src/Rector/ClassMethod/NewlineBeforeNewAssignSetRector.php
|
||||
|
||||
-
|
||||
message: "#^Cognitive complexity for \"Rector\\\\PhpSpecToPHPUnit\\\\Rector\\\\MethodCall\\\\PhpSpecPromisesToPHPUnitAssertRector\\:\\:refactor\\(\\)\" is 13, keep it under 9$#"
|
||||
count: 1
|
||||
path: rules/php-spec-to-phpunit/src/Rector/MethodCall/PhpSpecPromisesToPHPUnitAssertRector.php
|
||||
|
||||
-
|
||||
message: "#^Class cognitive complexity for \"EregToPcreTransformer\" is (.*?), keep it under 50$#"
|
||||
path: rules/php70/src/EregToPcreTransformer.php
|
||||
|
||||
-
|
||||
message: "#Use explicit property fetch names over dynamic#"
|
||||
path: packages/doctrine-annotation-generated/src/PhpDocNode/ConstantReferenceIdentifierRestorer.php
|
||||
|
||||
- "#^Cognitive complexity for \"Rector\\\\Php70\\\\EregToPcreTransformer\\:\\:(.*?)\" is (.*?), keep it under 9$#"
|
||||
|
||||
- '#Use explicit return value over magic &reference#'
|
||||
|
||||
- '#In method "Rector\\Utils\\ProjectValidator\\Process\\ParallelTaskRunner\:\:(.*?)", caught "Throwable" must be rethrown\. Either catch a more specific exception or add a "throw" clause in the "catch" block to propagate the exception#'
|
||||
# weird
|
||||
|
||||
- '#Method (.*?) specified in iterable type Symfony\\Component\\Process\\Process#'
|
||||
- '#Cannot cast PhpParser\\Node\\Expr\\Error\|PhpParser\\Node\\Identifier to string#'
|
||||
- '#Class cognitive complexity for "DumpNodesCommand" is \d+, keep it under 50#'
|
||||
- '#Cognitive complexity for "Rector\\Utils\\DocumentationGenerator\\Command\\DumpNodesCommand\:\:execute\(\)" is \d+, keep it under 9#'
|
||||
|
||||
- '#Parameter \#1 \$node of method Rector\\PostRector\\Collector\\NodesToAddCollector\:\:wrapToExpression\(\) expects PhpParser\\Node\\Expr\|PhpParser\\Node\\Stmt, PhpParser\\Node given#'
|
||||
- '#Access to an undefined property PhpParser\\Node\\Expr\:\:\$class#'
|
||||
- '#Method Rector\\BetterPhpDocParser\\Tests\\PhpDocParser\\AbstractPhpDocInfoTest\:\:parseFileAndGetFirstNodeOfType\(\) should return PhpParser\\Node but returns PhpParser\\Node\|null#'
|
||||
- '#Property PhpParser\\Node\\Stmt\\Namespace_\:\:\$stmts \(array<PhpParser\\Node\\Stmt\>\) does not accept array<PhpParser\\Node\>#'
|
||||
|
||||
- '#Cognitive complexity for "Rector\\TypeDeclaration\\PHPStan\\Type\\ObjectTypeSpecifier\:\:matchShortenedObjectType\(\)" is 10, keep it under 9#'
|
||||
- '#Parameter \#1 \$type of method PhpParser\\Builder\\FunctionLike\:\:setReturnType\(\) expects PhpParser\\Node\\Name\|PhpParser\\Node\\NullableType\|string, PhpParser\\Node\\Identifier\|PhpParser\\Node\\Name\|PhpParser\\Node\\NullableType\|PhpParser\\Node\\UnionType given#'
|
||||
- '#Cognitive complexity for "Rector\\Core\\PhpParser\\Node\\Value\\ValueResolver\:\:getValue\(\)" is \d+, keep it under 9#'
|
||||
- '#Cognitive complexity for "Rector\\NetteKdyby\\ContributeEventClassResolver\:\:resolveGetterMethodByEventClassAndParam\(\)" is \d+, keep it under 9#'
|
||||
- '#Parameter \#1 \$type of class PhpParser\\Node\\NullableType constructor expects PhpParser\\Node\\Identifier\|PhpParser\\Node\\Name\|string, PhpParser\\Node\\Identifier\|PhpParser\\Node\\Name\|PhpParser\\Node\\NullableType\|PhpParser\\Node\\UnionType given#'
|
||||
- '#Parameter \#1 \$object of function get_class expects object, PhpParser\\Node\|null given#'
|
||||
- '#Class "Rector\\FileSystemRector\\Rector\\Removing\\RemoveProjectFileRector" is missing @see annotation with test case class reference#'
|
||||
- '#Parameter \#1 \$type of method PhpParser\\Builder\\Param\:\:setType\(\) expects PhpParser\\Node\\Name\|PhpParser\\Node\\NullableType\|PhpParser\\Node\\UnionType\|string, PhpParser\\Node\\Identifier\|PhpParser\\Node\\Name\|PhpParser\\Node\\NullableType\|PhpParser\\Node\\UnionType given#'
|
||||
- '#Parameter \#1 \$node of method Rector\\Core\\PhpParser\\Node\\BetterNodeFinder\:\:findFirstAncestorInstanceOf\(\) expects PhpParser\\Node, PhpParser\\Node\\Expr\\Variable\|null given#'
|
||||
- '#Parameter \#1 \$objectType of method Rector\\Naming\\Naming\\PropertyNaming\:\:fqnToVariableName\(\) expects PHPStan\\Type\\ObjectType\|string, PHPStan\\Type\\Type given#'
|
||||
- '#Method Rector\\Core\\PhpParser\\Node\\NodeFactory\:\:createConcat\(\) should return PhpParser\\Node\\Expr\\BinaryOp\\Concat\|null but returns PhpParser\\Node\\Expr#'
|
||||
- '#Method Rector\\Core\\PhpParser\\Node\\BetterNodeFinder\:\:findFirstNonAnonymousClass\(\) should return PhpParser\\Node\\Stmt\\Class_\|null but returns PhpParser\\Node\|null#'
|
||||
# known value
|
||||
- '#Property PhpParser\\Node\\Stmt\\Foreach_\:\:\$valueVar \(PhpParser\\Node\\Expr\) does not accept PhpParser\\Node\\Expr\|null#'
|
||||
- '#Access to an undefined property PHPStan\\PhpDocParser\\Ast\\PhpDoc\\PhpDocTagValueNode\:\:\$type#'
|
||||
|
||||
# local type
|
||||
-
|
||||
message: '#Method call "isObjectType\(\)" argument on position 1 cannot use "\:\:class" reference#'
|
||||
path: 'packages/dynamic-type-analysis/src/Rector/StaticCall/RemoveArgumentTypeProbeRector.php'
|
||||
|
||||
# only local use
|
||||
-
|
||||
message: '#Class "Rector\\RectorGenerator\\Rector\\Closure\\AddNewServiceToSymfonyPhpConfigRector" is missing @see annotation with test case class reference#'
|
||||
path: 'packages/rector-generator/src/Rector/Closure/AddNewServiceToSymfonyPhpConfigRector.php'
|
||||
|
||||
- '#Call to an undefined method PhpParser\\Node\\Expr\\Error\|PhpParser\\Node\\Identifier\:\:toString\(\)#'
|
||||
- '#Class Rector\\Renaming\\Tests\\Rector\\MethodCall\\RenameMethodRector\\Fixture\\SkipSelfMethodRename not found#'
|
||||
|
||||
# fixed in symplfiy dev
|
||||
-
|
||||
message: '#Separate function "Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\ref\(\)" in method call to standalone row to improve readability#'
|
||||
path: 'packages/rector-generator/config/config.php'
|
||||
|
||||
- '#Method Rector\\Core\\PhpParser\\Node\\BetterNodeFinder\:\:findPreviousAssignToExpr\(\) should return PhpParser\\Node\\Expr\\Assign\|null but returns PhpParser\\Node\|null#'
|
||||
- '#Parameter \#1 \$shortControlString of method Rector\\NetteCodeQuality\\Rector\\Assign\\MakeGetComponentAssignAnnotatedRector\:\:resolveTypeFromShortControlNameAndVariable\(\) expects PhpParser\\Node\\Scalar\\String_, PhpParser\\Node\\Expr\|null given#'
|
||||
- '#Parameter \#1 \$variable of class Rector\\Php70\\ValueObject\\VariableAssignPair constructor expects PhpParser\\Node\\Expr\\ArrayDimFetch\|PhpParser\\Node\\Expr\\PropertyFetch\|PhpParser\\Node\\Expr\\StaticPropertyFetch\|PhpParser\\Node\\Expr\\Variable, PhpParser\\Node\\Expr given#'
|
||||
|
||||
# is nested expr
|
||||
- '#Access to an undefined property PhpParser\\Node\\Expr\:\:\$expr#'
|
||||
- '#Cognitive complexity for "Rector\\DeadCode\\NodeManipulator\\LivingCodeManipulator\:\:keepLivingCodeFromExpr\(\)" is \d+, keep it under 9#'
|
||||
- '#Parameter \#1 \$files of method Symplify\\SmartFileSystem\\Finder\\FinderSanitizer\:\:sanitize\(\) expects \(iterable<SplFileInfo\|string\>&Nette\\Utils\\Finder\)\|Symfony\\Component\\Finder\\Finder, array<string\> given#'
|
||||
- '#Static property Rector\\Core\\Testing\\PHPUnit\\AbstractGenericRectorTestCase\:\:\$allRectorContainer \(Rector\\Naming\\Tests\\Rector\\Class_\\RenamePropertyToMatchTypeRector\\Source\\ContainerInterface\|Symfony\\Component\\DependencyInjection\\Container\|null\) does not accept Psr\\Container\\ContainerInterface#'
|
||||
# stubs
|
||||
- '#Static property Symplify\\PackageBuilder\\Tests\\AbstractKernelTestCase\:\:\$container \(Psr\\Container\\ContainerInterface\) does not accept Rector\\Naming\\Tests\\Rector\\Class_\\RenamePropertyToMatchTypeRector\\Source\\ContainerInterface\|Symfony\\Component\\DependencyInjection\\Container#'
|
||||
|
||||
# wtf
|
||||
-
|
||||
message: '#Else branch is unreachable because ternary operator condition is always true#'
|
||||
path: 'rules/psr4/src/Composer/PSR4NamespaceMatcher.php'
|
||||
|
||||
# false positive
|
||||
- '#Parameter \#1 \$arrayItem of method Rector\\NetteKdyby\\NodeResolver\\ListeningMethodsCollector\:\:resolveCustomClassMethodAndEventClass\(\) expects PhpParser\\Node\\Expr\\ArrayItem, PhpParser\\Node given#'
|
||||
- '#Parameter \#1 \$type of method Rector\\NodeCollector\\NodeCollector\\ParsedNodeCollector<TNodeType of PhpParser\\Node\>\:\:getNodesByType\(\) expects class\-string<TNodeType of PhpParser\\Node\>, string given#'
|
||||
|
||||
- '#Class with base "(.*?)" name is already used in "_HumbugBox(.*?)"#'
|
||||
|
||||
-
|
||||
message: '#Class "Rector\\RectorGenerator\\ValueObject\\RectorRecipe" has invalid namespace category "ValueObject"\. Pick one of\: ""#'
|
||||
path: packages/rector-generator/src/ValueObject/RectorRecipe.php
|
|
@ -3,15 +3,12 @@
|
|||
declare(strict_types=1);
|
||||
|
||||
use Rector\Core\Configuration\Option;
|
||||
use Rector\Set\ValueObject\SetList;
|
||||
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
|
||||
|
||||
return static function (ContainerConfigurator $containerConfigurator): void {
|
||||
$containerConfigurator->import(__DIR__ . '/rector-recipe.php', null, 'not_found');
|
||||
|
||||
$parameters = $containerConfigurator->parameters();
|
||||
$parameters->set(Option::AUTO_IMPORT_NAMES, true);
|
||||
//$parameters->set(Option::SETS, [SetList::NAMING]);
|
||||
|
||||
$parameters->set(Option::PATHS, [
|
||||
__DIR__ . '/src',
|
||||
__DIR__ . '/tests',
|
||||
|
|
|
@ -5,11 +5,34 @@ declare(strict_types=1);
|
|||
namespace Rector\SymfonyPhpConfig;
|
||||
|
||||
use Rector\Core\Exception\ShouldNotHappenException;
|
||||
use Rector\SymfonyPhpConfig\Reflection\ArgumentAndParameterFactory;
|
||||
use ReflectionClass;
|
||||
use function Symfony\Component\DependencyInjection\Loader\Configurator\inline_service;
|
||||
use Symfony\Component\DependencyInjection\Loader\Configurator\InlineServiceConfigurator;
|
||||
use Symfony\Component\DependencyInjection\Loader\Configurator\ReferenceConfigurator;
|
||||
use function Symfony\Component\DependencyInjection\Loader\Configurator\service;
|
||||
use Symfony\Component\DependencyInjection\Loader\Configurator\ServicesConfigurator;
|
||||
|
||||
function inline_object(object $object): InlineServiceConfigurator
|
||||
function inline_single_object(object $object, ServicesConfigurator $servicesConfigurator): ReferenceConfigurator
|
||||
{
|
||||
$reflectionClass = new ReflectionClass($object);
|
||||
|
||||
$className = $reflectionClass->getName();
|
||||
$propertyValues = resolve_property_values($reflectionClass, $object);
|
||||
$argumentValues = resolve_argument_values($reflectionClass, $object);
|
||||
|
||||
// create fake factory with private accessor, as properties are different
|
||||
// @see https://symfony.com/doc/current/service_container/factories.html#passing-arguments-to-the-factory-method
|
||||
$servicesConfigurator->set(ArgumentAndParameterFactory::class);
|
||||
|
||||
$servicesConfigurator->set($className)
|
||||
->factory([service(ArgumentAndParameterFactory::class), 'create'])
|
||||
->args([$className, $argumentValues, $propertyValues]);
|
||||
|
||||
return service($className);
|
||||
}
|
||||
|
||||
function inline_value_object(object $object): InlineServiceConfigurator
|
||||
{
|
||||
$reflectionClass = new ReflectionClass($object);
|
||||
|
||||
|
@ -19,15 +42,16 @@ function inline_object(object $object): InlineServiceConfigurator
|
|||
return inline_service($className)->args($argumentValues);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param object[] $objects
|
||||
* @return InlineServiceConfigurator[]
|
||||
*/
|
||||
function inline_objects(array $objects): array
|
||||
function inline_value_objects(array $objects): array
|
||||
{
|
||||
$inlineServices = [];
|
||||
foreach ($objects as $object) {
|
||||
$inlineServices[] = inline_object($object);
|
||||
$inlineServices[] = inline_value_object($object);
|
||||
}
|
||||
|
||||
return $inlineServices;
|
||||
|
@ -59,3 +83,20 @@ function resolve_argument_values(ReflectionClass $reflectionClass, object $objec
|
|||
|
||||
return $argumentValues;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
function resolve_property_values(ReflectionClass $reflectionClass, object $object): array
|
||||
{
|
||||
$propertyValues = [];
|
||||
|
||||
foreach ($reflectionClass->getProperties() as $reflectionProperty) {
|
||||
$parameterName = $reflectionProperty->getName();
|
||||
$reflectionProperty->setAccessible(true);
|
||||
|
||||
$propertyValues[$parameterName] = $reflectionProperty->getValue($object);
|
||||
}
|
||||
|
||||
return $propertyValues;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\SymfonyPhpConfig\Reflection;
|
||||
|
||||
use Symplify\PackageBuilder\Reflection\PrivatesAccessor;
|
||||
|
||||
final class ArgumentAndParameterFactory
|
||||
{
|
||||
/**
|
||||
* @var PrivatesAccessor
|
||||
*/
|
||||
private $privatesAccessor;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->privatesAccessor = new PrivatesAccessor();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $arguments
|
||||
* @param array<string, mixed> $properties
|
||||
*/
|
||||
public function create(string $className, array $arguments, array $properties): object
|
||||
{
|
||||
$object = new $className(...$arguments);
|
||||
|
||||
foreach ($properties as $name => $value) {
|
||||
$this->privatesAccessor->setPrivateProperty($object, $name, $value);
|
||||
}
|
||||
|
||||
return $object;
|
||||
}
|
||||
}
|
|
@ -81,6 +81,12 @@ final class RectorConfigsResolver
|
|||
|
||||
$setFileInfos = $this->resolveSetFileInfosFromConfigFileInfos($configFileInfos);
|
||||
|
||||
// autoload rector recipe file if present
|
||||
$rectorRecipeFilePath = getcwd() . '/rector-recipe.php';
|
||||
if (file_exists($rectorRecipeFilePath)) {
|
||||
$configFileInfos[] = new SmartFileInfo($rectorRecipeFilePath);
|
||||
}
|
||||
|
||||
return array_merge($configFileInfos, $setFileInfos);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user