Skip to content

Commit

Permalink
[CodeQuality] Add InlineArrayReturnAssignRector (#2183)
Browse files Browse the repository at this point in the history
* [CodeQuality] Add InlineArrayReturnAssignRector

* enable rule in code-quality

* [ci-review] Rector Rectify

Co-authored-by: GitHub Action <action@github.com>
  • Loading branch information
TomasVotruba and actions-user committed Apr 28, 2022
1 parent aa89fde commit 08bb10d
Show file tree
Hide file tree
Showing 12 changed files with 435 additions and 2 deletions.
27 changes: 25 additions & 2 deletions build/target-repository/docs/rector_rules_overview.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
# 512 Rules Overview
# 513 Rules Overview

<br>

## Categories

- [Arguments](#arguments) (5)

- [CodeQuality](#codequality) (70)
- [CodeQuality](#codequality) (71)

- [CodingStyle](#codingstyle) (35)

Expand Down Expand Up @@ -852,6 +852,29 @@ Changes comparison with get_class to instanceof

<br>

### InlineArrayReturnAssignRector

Inline just in time array dim fetch assigns to direct return

- class: [`Rector\CodeQuality\Rector\ClassMethod\InlineArrayReturnAssignRector`](../rules/CodeQuality/Rector/ClassMethod/InlineArrayReturnAssignRector.php)

```diff
function getPerson()
{
- $person = [];
- $person['name'] = 'Timmy';
- $person['surname'] = 'Back';
-
- return $person;
+ return [
+ 'name' => 'Timmy',
+ 'surname' => 'Back',
+ ];
}
```

<br>

### InlineConstructorDefaultToPropertyRector

Move property default from constructor to property default
Expand Down
2 changes: 2 additions & 0 deletions config/set/code-quality.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
use Rector\CodeQuality\Rector\Catch_\ThrowWithPreviousExceptionRector;
use Rector\CodeQuality\Rector\Class_\CompleteDynamicPropertiesRector;
use Rector\CodeQuality\Rector\ClassMethod\DateTimeToDateTimeInterfaceRector;
use Rector\CodeQuality\Rector\ClassMethod\InlineArrayReturnAssignRector;
use Rector\CodeQuality\Rector\ClassMethod\NarrowUnionTypeDocRector;
use Rector\CodeQuality\Rector\Concat\JoinStringConcatRector;
use Rector\CodeQuality\Rector\Do_\DoWhileBreakFalseToIfElseRector;
Expand Down Expand Up @@ -179,4 +180,5 @@
$rectorConfig->rule(FlipTypeControlToUseExclusiveTypeRector::class);
$rectorConfig->rule(ExplicitMethodCallOverMagicGetSetRector::class);
$rectorConfig->rule(DoWhileBreakFalseToIfElseRector::class);
$rectorConfig->rule(InlineArrayReturnAssignRector::class);
};
1 change: 1 addition & 0 deletions phpstan.neon
Original file line number Diff line number Diff line change
Expand Up @@ -599,3 +599,4 @@ parameters:

- '#Cognitive complexity for "Rector\\TypeDeclaration\\PHPStan\\ObjectTypeSpecifier\:\:matchShortenedObjectType\(\)" is \d+, keep it under 10#'
- '#Cognitive complexity for "Rector\\TypeDeclaration\\PHPStan\\ObjectTypeSpecifier\:\:narrowToFullyQualifiedOrAliasedObjectType\(\)" is \d+, keep it under 10#'
- '#Class "Rector\\CodeQuality\\Rector\\ClassMethod\\InlineArrayReturnAssignRector" has invalid namespace category "ClassMethod"\. Pick one of\: "NodeTypeGroup"#'
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php

namespace Rector\Tests\CodeQuality\Rector\ClassMethod\InlineArrayReturnAssignRector\Fixture;

final class IncludeIf
{
public function run()
{
if (mt_rand(0, 1)) {
$person = [];
$person['name'] = 'Timmy';
$person['surname'] = 'Back';

return $person;
}

return null;
}
}


?>
-----
<?php

namespace Rector\Tests\CodeQuality\Rector\ClassMethod\InlineArrayReturnAssignRector\Fixture;

final class IncludeIf
{
public function run()
{
if (mt_rand(0, 1)) {
return ['name' => 'Timmy', 'surname' => 'Back'];
}

return null;
}
}


?>
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

namespace Rector\Tests\CodeQuality\Rector\ClassMethod\InlineArrayReturnAssignRector\Fixture;

final class SkipVariable
{
public function run($person2)
{
$person = [];

$person2['name'] = 'Timmy';
$person['surname'] = 'Back';

return $person;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

namespace Rector\Tests\CodeQuality\Rector\ClassMethod\InlineArrayReturnAssignRector\Fixture;

function getPerson()
{
$person = [];
$person['name'] = 'Timmy';
$person['surname'] = 'Back';

return $person;
}

?>
-----
<?php

namespace Rector\Tests\CodeQuality\Rector\ClassMethod\InlineArrayReturnAssignRector\Fixture;

function getPerson()
{
return ['name' => 'Timmy', 'surname' => 'Back'];
}

?>
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

declare(strict_types=1);

namespace Rector\Tests\CodeQuality\Rector\ClassMethod\InlineArrayReturnAssignRector;

use Iterator;
use Rector\Testing\PHPUnit\AbstractRectorTestCase;
use Symplify\SmartFileSystem\SmartFileInfo;

final class InlineArrayReturnAssignRectorTest extends AbstractRectorTestCase
{
/**
* @dataProvider provideData()
*/
public function test(SmartFileInfo $fileInfo): void
{
$this->doTestFileInfo($fileInfo);
}

/**
* @return Iterator<SmartFileInfo>
*/
public function provideData(): Iterator
{
return $this->yieldFilesFromDirectory(__DIR__ . '/Fixture');
}

public function provideConfigFilePath(): string
{
return __DIR__ . '/config/configured_rule.php';
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php

declare(strict_types=1);

use Rector\CodeQuality\Rector\ClassMethod\InlineArrayReturnAssignRector;

use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;

return static function (ContainerConfigurator $containerConfigurator): void {
$services = $containerConfigurator->services();
$services->set(InlineArrayReturnAssignRector::class);
};
67 changes: 67 additions & 0 deletions rules/CodeQuality/NodeAnalyzer/VariableDimFetchAssignResolver.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<?php

declare(strict_types=1);

namespace Rector\CodeQuality\NodeAnalyzer;

use PhpParser\Node\Expr;
use PhpParser\Node\Expr\ArrayDimFetch;
use PhpParser\Node\Expr\Assign;
use PhpParser\Node\Expr\Variable;
use PhpParser\Node\Stmt;
use PhpParser\Node\Stmt\Expression;
use Rector\CodeQuality\ValueObject\KeyAndExpr;
use Rector\Core\PhpParser\Comparing\NodeComparator;

final class VariableDimFetchAssignResolver
{
public function __construct(
private readonly NodeComparator $nodeComparator
) {
}

/**
* @param Stmt[] $stmts
* @return KeyAndExpr[]
*/
public function resolveFromStmtsAndVariable(array $stmts, Variable $variable): array
{
$keysAndExprs = [];

foreach ($stmts as $stmt) {
if (! $stmt instanceof Expression) {
return [];
}

$stmtExpr = $stmt->expr;
if (! $stmtExpr instanceof Assign) {
return [];
}

$assign = $stmtExpr;

$keyExpr = $this->matchKeyOnArrayDimFetchOfVariable($assign, $variable);
if (! $keyExpr instanceof Expr) {
return [];
}

$keysAndExprs[] = new KeyAndExpr($keyExpr, $assign->expr);
}

return $keysAndExprs;
}

public function matchKeyOnArrayDimFetchOfVariable(Assign $assign, Variable $variable): ?Expr
{
if (! $assign->var instanceof ArrayDimFetch) {
return null;
}

$arrayDimFetch = $assign->var;
if (! $this->nodeComparator->areNodesEqual($arrayDimFetch->var, $variable)) {
return null;
}

return $arrayDimFetch->dim;
}
}
28 changes: 28 additions & 0 deletions rules/CodeQuality/NodeTypeGroup.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

declare(strict_types=1);

namespace Rector\CodeQuality;

use PhpParser\Node;
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Do_;
use PhpParser\Node\Stmt\Else_;
use PhpParser\Node\Stmt\ElseIf_;
use PhpParser\Node\Stmt\Foreach_;
use PhpParser\Node\Stmt\Function_;
use PhpParser\Node\Stmt\If_;
use PhpParser\Node\Stmt\TryCatch;
use PhpParser\Node\Stmt\While_;

final class NodeTypeGroup
{
/**
* These nodes have a public $stmts property that can be iterated - based on https://github.com/rectorphp/php-parser-nodes-docs
* @todo create a virtual node, getStmts(): array
* @var array<class-string<Node>>
*/
public const STMTS_AWARE = [
ClassMethod::class, Function_::class, If_::class, Else_::class, ElseIf_::class, Do_::class, Foreach_::class, TryCatch::class, While_::class,
];
}
Loading

0 comments on commit 08bb10d

Please sign in to comment.