Skip to content

Commit

Permalink
[CodeQuality] Add TernaryFalseExpressionToIfRector
Browse files Browse the repository at this point in the history
  • Loading branch information
TomasVotruba committed Jun 29, 2022
1 parent 407ad5f commit 2fdd940
Show file tree
Hide file tree
Showing 8 changed files with 230 additions and 0 deletions.
2 changes: 2 additions & 0 deletions config/set/code-quality.php
Expand Up @@ -17,6 +17,7 @@
use Rector\CodeQuality\Rector\Do_\DoWhileBreakFalseToIfElseRector;
use Rector\CodeQuality\Rector\Equal\UseIdenticalOverEqualWithSameTypeRector;
use Rector\CodeQuality\Rector\Expression\InlineIfToExplicitIfRector;
use Rector\CodeQuality\Rector\Expression\TernaryFalseExpressionToIfRector;
use Rector\CodeQuality\Rector\For_\ForRepeatedCountToOwnVariableRector;
use Rector\CodeQuality\Rector\For_\ForToForeachRector;
use Rector\CodeQuality\Rector\Foreach_\ForeachItemsAssignToEmptyArrayToAssignRector;
Expand Down Expand Up @@ -182,5 +183,6 @@
DoWhileBreakFalseToIfElseRector::class,
InlineArrayReturnAssignRector::class,
InlineIsAInstanceOfRector::class,
TernaryFalseExpressionToIfRector::class,
]);
};
@@ -0,0 +1,29 @@
<?php

namespace Rector\Tests\CodeQuality\Rector\Expression\TernaryFalseExpressionToIfRector\Fixture;

final class IncludeNoSideEffectExpr
{
public function run($value, $someMethod)
{
$value ? $someMethod->call($value) : true;
}
}

?>
-----
<?php

namespace Rector\Tests\CodeQuality\Rector\Expression\TernaryFalseExpressionToIfRector\Fixture;

final class IncludeNoSideEffectExpr
{
public function run($value, $someMethod)
{
if ($value) {
$someMethod->call($value);
}
}
}

?>
@@ -0,0 +1,29 @@
<?php

namespace Rector\Tests\CodeQuality\Rector\Expression\TernaryFalseExpressionToIfRector\Fixture;

final class NegatedValue
{
public function run($value)
{
! $value ? 'execute' : false;
}
}

?>
-----
<?php

namespace Rector\Tests\CodeQuality\Rector\Expression\TernaryFalseExpressionToIfRector\Fixture;

final class NegatedValue
{
public function run($value)
{
if (! $value) {
'execute';
}
}
}

?>
@@ -0,0 +1,11 @@
<?php

namespace Rector\Tests\CodeQuality\Rector\Expression\TernaryFalseExpressionToIfRector\Fixture;

final class SkipNullTernary
{
public function run($value, $someMethod)
{
$value ?: $someMethod->call($value);
}
}
@@ -0,0 +1,29 @@
<?php

namespace Rector\Tests\CodeQuality\Rector\Expression\TernaryFalseExpressionToIfRector\Fixture;

final class SomeClass
{
public function run($value, $someMethod)
{
$value ? $someMethod->call($value) : false;
}
}

?>
-----
<?php

namespace Rector\Tests\CodeQuality\Rector\Expression\TernaryFalseExpressionToIfRector\Fixture;

final class SomeClass
{
public function run($value, $someMethod)
{
if ($value) {
$someMethod->call($value);
}
}
}

?>
@@ -0,0 +1,33 @@
<?php

declare(strict_types=1);

namespace Rector\Tests\CodeQuality\Rector\Expression\TernaryFalseExpressionToIfRector;

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

final class TernaryFalseExpressionToIfRectorTest 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';
}
}
@@ -0,0 +1,10 @@
<?php

declare(strict_types=1);

use Rector\CodeQuality\Rector\Expression\TernaryFalseExpressionToIfRector;
use Rector\Config\RectorConfig;

return static function (RectorConfig $rectorConfig): void {
$rectorConfig->rule(TernaryFalseExpressionToIfRector::class);
};
@@ -0,0 +1,87 @@
<?php

declare(strict_types=1);

namespace Rector\CodeQuality\Rector\Expression;

use PhpParser\Node;
use PhpParser\Node\Expr;
use PhpParser\Node\Expr\Ternary;
use PhpParser\Node\Stmt\Expression;
use PhpParser\Node\Stmt\If_;
use Rector\Core\Rector\AbstractRector;
use Rector\DeadCode\SideEffect\SideEffectNodeDetector;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;

/**
* @see \Rector\Tests\CodeQuality\Rector\Expression\TernaryFalseExpressionToIfRector\TernaryFalseExpressionToIfRectorTest
*/
final class TernaryFalseExpressionToIfRector extends AbstractRector
{
public function __construct(
private readonly SideEffectNodeDetector $sideEffectNodeDetector
) {
}

public function getRuleDefinition(): RuleDefinition
{
return new RuleDefinition('Change ternary with false to if and explicit call', [
new CodeSample(
<<<'CODE_SAMPLE'
final class SomeClass
{
public function run($value, $someMethod)
{
$value ? $someMethod->call($value) : false;
}
}
CODE_SAMPLE

,
<<<'CODE_SAMPLE'
final class SomeClass
{
public function run($value, $someMethod)
{
if ($value) {
$someMethod->call($value);
}
}
}
CODE_SAMPLE
),
]);
}

/**
* @return array<class-string<Node>>
*/
public function getNodeTypes(): array
{
return [Expression::class];
}

/**
* @param Expression $node
*/
public function refactor(Node $node): ?Node
{
if (! $node->expr instanceof Ternary) {
return null;
}

$ternary = $node->expr;
if (! $ternary->if instanceof Expr) {
return null;
}

if ($this->sideEffectNodeDetector->detect($ternary->else)) {
return null;
}

return new If_($ternary->cond, [
'stmts' => [new Expression($ternary->if)],
]);
}
}

0 comments on commit 2fdd940

Please sign in to comment.