[Order] Order __constructor dependencies by type alphabetically

This commit is contained in:
dobryy 2020-07-26 00:11:30 +02:00
parent 812dea97d2
commit 99494d4c32
13 changed files with 344 additions and 1 deletions

View File

@ -6,6 +6,7 @@ use Rector\Order\Rector\Class_\OrderClassConstantsByIntegerValueRector;
use Rector\Order\Rector\Class_\OrderPrivateMethodsByUseRector;
use Rector\Order\Rector\Class_\OrderPropertyByComplexityRector;
use Rector\Order\Rector\Class_\OrderPublicInterfaceMethodRector;
use Rector\Order\Rector\ClassMethod\OrderConstructorDependenciesByTypeAlphabeticallyRector;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
return static function (ContainerConfigurator $containerConfigurator): void {
@ -18,4 +19,6 @@ return static function (ContainerConfigurator $containerConfigurator): void {
$services->set(OrderPropertyByComplexityRector::class);
$services->set(OrderClassConstantsByIntegerValueRector::class);
$services->set(OrderConstructorDependenciesByTypeAlphabeticallyRector::class);
};

View File

@ -37,7 +37,7 @@
- [NetteTesterToPHPUnit](#nettetestertophpunit) (3)
- [NetteToSymfony](#nettetosymfony) (9)
- [NetteUtilsCodeQuality](#netteutilscodequality) (1)
- [Order](#order) (4)
- [Order](#order) (5)
- [PHPOffice](#phpoffice) (14)
- [PHPStan](#phpstan) (3)
- [PHPUnit](#phpunit) (37)
@ -6059,6 +6059,30 @@ Order class constant order by their integer value
<br><br>
### `OrderConstructorDependenciesByTypeAlphabeticallyRector`
- class: [`Rector\Order\Rector\ClassMethod\OrderConstructorDependenciesByTypeAlphabeticallyRector`](/../master/rules/order/src/Rector/ClassMethod/OrderConstructorDependenciesByTypeAlphabeticallyRector.php)
- [test fixtures](/../master/rules/order/tests/Rector/ClassMethod/OrderConstructorDependenciesByTypeAlphabeticallyRector/Fixture)
Order __constructor dependencies by type A-Z
```diff
class SomeClass
{
public function __construct(
+ LatteAndTwigFinder $latteAndTwigFinder,
LatteToTwigConverter $latteToTwigConverter,
+ SmartFileSystem $smartFileSystem,
SymfonyStyle $symfonyStyle,
- LatteAndTwigFinder $latteAndTwigFinder,
- SmartFileSystem $smartFileSystem,
) {
}
}
```
<br><br>
### `OrderPrivateMethodsByUseRector`
- class: [`Rector\Order\Rector\Class_\OrderPrivateMethodsByUseRector`](/../master/rules/order/src/Rector/Class_/OrderPrivateMethodsByUseRector.php)

View File

@ -0,0 +1,128 @@
<?php
declare(strict_types=1);
namespace Rector\Order\Rector\ClassMethod;
use PhpParser\Node;
use PhpParser\Node\Expr;
use PhpParser\Node\Identifier;
use PhpParser\Node\Name;
use PhpParser\Node\NullableType;
use PhpParser\Node\Param;
use PhpParser\Node\Stmt\ClassMethod;
use Rector\Core\Rector\AbstractRector;
use Rector\Core\RectorDefinition\CodeSample;
use Rector\Core\RectorDefinition\RectorDefinition;
/**
* @see \Rector\Order\Tests\Rector\ClassMethod\OrderConstructorDependenciesByTypeAlphabeticallyRector\OrderConstructorDependenciesByTypeAlphabeticallyRectorTest
*/
final class OrderConstructorDependenciesByTypeAlphabeticallyRector extends AbstractRector
{
public function getDefinition(): RectorDefinition
{
return new RectorDefinition('Order __constructor dependencies by type A-Z', [
new CodeSample(
<<<'PHP'
class SomeClass
{
public function __construct(
LatteToTwigConverter $latteToTwigConverter,
SymfonyStyle $symfonyStyle,
LatteAndTwigFinder $latteAndTwigFinder,
SmartFileSystem $smartFileSystem,
) {
}
}
PHP
,
<<<'PHP'
class SomeClass
{
public function __construct(
LatteAndTwigFinder $latteAndTwigFinder,
LatteToTwigConverter $latteToTwigConverter,
SmartFileSystem $smartFileSystem,
SymfonyStyle $symfonyStyle,
) {
}
}
PHP
),
]);
}
/**
* @return string[]
*/
public function getNodeTypes(): array
{
return [ClassMethod::class];
}
/**
* @param ClassMethod $node
*/
public function refactor(Node $node): ?Node
{
if ($this->shouldSkip($node)) {
return null;
}
$node->params = $this->getSortedParams($node);
return $node;
}
/**
* @return Param[]
*/
private function getSortedParams(ClassMethod $classMethod): array
{
$params = $classMethod->getParams();
usort($params, function (Param $firstParam, Param $secondParam) {
/** @var Name $typeA */
$typeA = $firstParam->type;
/** @var Name $typeB */
$typeB = $secondParam->type;
return strcmp($this->getShortName($typeA), $this->getShortName($typeB));
});
return $params;
}
private function isPrimitiveDataTypeParam(Param $param): bool
{
return $param->type instanceof Identifier;
}
private function isDefaultValueParam(Param $param): bool
{
return $param->default instanceof Expr || $param->type instanceof NullableType;
}
private function shouldSkip(ClassMethod $classMethod): bool
{
if (! $this->isName($classMethod, '__construct')) {
return true;
}
if ($classMethod->params === []) {
return true;
}
foreach ($classMethod->params as $param) {
if ($this->isDefaultValueParam($param)) {
return true;
}
if ($this->isPrimitiveDataTypeParam($param)) {
return true;
}
}
return false;
}
}

View File

@ -0,0 +1,29 @@
<?php
namespace Rector\Order\Tests\Rector\ClassMethod\OrderConstructorDependenciesByTypeAlphabeticallyRector\Fixture;
class SomeClass
{
public function __construct(
LatteToTwigConverter $latteToTwigConverter,
SymfonyStyle $symfonyStyle,
LatteAndTwigFinder $latteAndTwigFinder,
SmartFileSystem $smartFileSystem
) {
}
}
?>
-----
<?php
namespace Rector\Order\Tests\Rector\ClassMethod\OrderConstructorDependenciesByTypeAlphabeticallyRector\Fixture;
class SomeClass
{
public function __construct(LatteAndTwigFinder $latteAndTwigFinder, LatteToTwigConverter $latteToTwigConverter, SmartFileSystem $smartFileSystem, SymfonyStyle $symfonyStyle)
{
}
}
?>

View File

@ -0,0 +1,33 @@
<?php
namespace Rector\Order\Tests\Rector\ClassMethod\OrderConstructorDependenciesByTypeAlphabeticallyRector\Fixture;
use Rector\Order\Tests\Rector\ClassMethod\OrderConstructorDependenciesByTypeAlphabeticallyRector\Source\Apple\Red;
use Rector\Order\Tests\Rector\ClassMethod\OrderConstructorDependenciesByTypeAlphabeticallyRector\Source\Banana\Green;
class IgnoreNamespaceClass
{
public function __construct(
Red $red,
Green $green
) {
}
}
?>
-----
<?php
namespace Rector\Order\Tests\Rector\ClassMethod\OrderConstructorDependenciesByTypeAlphabeticallyRector\Fixture;
use Rector\Order\Tests\Rector\ClassMethod\OrderConstructorDependenciesByTypeAlphabeticallyRector\Source\Apple\Red;
use Rector\Order\Tests\Rector\ClassMethod\OrderConstructorDependenciesByTypeAlphabeticallyRector\Source\Banana\Green;
class IgnoreNamespaceClass
{
public function __construct(Green $green, Red $red)
{
}
}
?>

View File

@ -0,0 +1,11 @@
<?php
namespace Rector\Order\Tests\Rector\ClassMethod\OrderConstructorDependenciesByTypeAlphabeticallyRector\Fixture;
class SkipConstructHasNoParams
{
public function __construct() {
}
}
?>

View File

@ -0,0 +1,16 @@
<?php
namespace Rector\Order\Tests\Rector\ClassMethod\OrderConstructorDependenciesByTypeAlphabeticallyRector\Fixture;
class SkipHasBoolTypeParamClass
{
public function __construct(
LatteToTwigConverter $latteToTwigConverter,
SymfonyStyle $symfonyStyle,
LatteAndTwigFinder $latteAndTwigFinder,
bool $smartFileSystem
) {
}
}
?>

View File

@ -0,0 +1,16 @@
<?php
namespace Rector\Order\Tests\Rector\ClassMethod\OrderConstructorDependenciesByTypeAlphabeticallyRector\Fixture;
class SkipHasIntTypeParam
{
public function __construct(
LatteToTwigConverter $latteToTwigConverter,
SymfonyStyle $symfonyStyle,
LatteAndTwigFinder $latteAndTwigFinder,
int $smartFileSystem
) {
}
}
?>

View File

@ -0,0 +1,16 @@
<?php
namespace Rector\Order\Tests\Rector\ClassMethod\OrderConstructorDependenciesByTypeAlphabeticallyRector\Fixture;
class SkipHasOptionalParam
{
public function __construct(
LatteToTwigConverter $latteToTwigConverter,
SymfonyStyle $symfonyStyle,
LatteAndTwigFinder $latteAndTwigFinder,
SmartFileSystem $smartFileSystem = null
) {
}
}
?>

View File

@ -0,0 +1,16 @@
<?php
namespace Rector\Order\Tests\Rector\ClassMethod\OrderConstructorDependenciesByTypeAlphabeticallyRector\Fixture;
class SkipHasStringType
{
public function __construct(
LatteToTwigConverter $latteToTwigConverter,
SymfonyStyle $symfonyStyle,
LatteAndTwigFinder $latteAndTwigFinder,
string $smartFileSystem
) {
}
}
?>

View File

@ -0,0 +1,31 @@
<?php
declare(strict_types=1);
namespace Rector\Order\Tests\Rector\ClassMethod\OrderConstructorDependenciesByTypeAlphabeticallyRector;
use Iterator;
use Rector\Core\Testing\PHPUnit\AbstractRectorTestCase;
use Rector\Order\Rector\ClassMethod\OrderConstructorDependenciesByTypeAlphabeticallyRector;
use Symplify\SmartFileSystem\SmartFileInfo;
final class OrderConstructorDependenciesByTypeAlphabeticallyRectorTest extends AbstractRectorTestCase
{
/**
* @dataProvider provideData()
*/
public function test(SmartFileInfo $fileInfo): void
{
$this->doTestFileInfo($fileInfo);
}
public function provideData(): Iterator
{
return $this->yieldFilesFromDirectory(__DIR__ . '/Fixture');
}
protected function getRectorClass(): string
{
return OrderConstructorDependenciesByTypeAlphabeticallyRector::class;
}
}

View File

@ -0,0 +1,10 @@
<?php
namespace Rector\Order\Tests\Rector\ClassMethod\OrderConstructorDependenciesByTypeAlphabeticallyRector\Source\Apple;
class Red
{
}

View File

@ -0,0 +1,10 @@
<?php
namespace Rector\Order\Tests\Rector\ClassMethod\OrderConstructorDependenciesByTypeAlphabeticallyRector\Source\Banana;
class Green
{
}