diff --git a/config/set/code-quality/code-quality.yaml b/config/set/code-quality/code-quality.yaml index 5558e91b450f..1f4d8d0c5201 100644 --- a/config/set/code-quality/code-quality.yaml +++ b/config/set/code-quality/code-quality.yaml @@ -46,3 +46,4 @@ services: Rector\CodeQuality\Rector\FuncCall\AddPregQuoteDelimiterRector: ~ Rector\CodeQuality\Rector\FuncCall\ArrayMergeOfNonArraysToSimpleArrayRector: ~ Rector\CodeQuality\Rector\FuncCall\IntvalToTypeCastRector: ~ + Rector\CodeQuality\Rector\Ternary\ArrayKeyExistsTernaryThenValueToCoalescingRector: ~ diff --git a/packages/CodeQuality/src/Rector/Foreach_/SimplifyForeachToCoalescingRector.php b/packages/CodeQuality/src/Rector/Foreach_/SimplifyForeachToCoalescingRector.php index 9169f9e867bb..02b9e8d049af 100644 --- a/packages/CodeQuality/src/Rector/Foreach_/SimplifyForeachToCoalescingRector.php +++ b/packages/CodeQuality/src/Rector/Foreach_/SimplifyForeachToCoalescingRector.php @@ -21,6 +21,8 @@ use Rector\ValueObject\PhpVersionFeature; /** + * @see https://3v4l.org/bfsdY + * * @see \Rector\CodeQuality\Tests\Rector\Foreach_\SimplifyForeachToCoalescingRector\SimplifyForeachToCoalescingRectorTest */ final class SimplifyForeachToCoalescingRector extends AbstractRector diff --git a/packages/CodeQuality/src/Rector/Ternary/ArrayKeyExistsTernaryThenValueToCoalescingRector.php b/packages/CodeQuality/src/Rector/Ternary/ArrayKeyExistsTernaryThenValueToCoalescingRector.php new file mode 100644 index 000000000000..bf3b2d085df9 --- /dev/null +++ b/packages/CodeQuality/src/Rector/Ternary/ArrayKeyExistsTernaryThenValueToCoalescingRector.php @@ -0,0 +1,105 @@ +cond instanceof FuncCall) { + return null; + } + + if (! $this->isName($node->cond, 'array_key_exists')) { + return null; + } + + if (! $node->if instanceof ArrayDimFetch) { + return null; + } + + if (! $this->areArrayKeysExistsArgsMatchingDimFetch($node->cond, $node->if)) { + return null; + } + + return new Coalesce($node->if, $node->else); + } + + /** + * Equals if: + * + * array_key_exists($key, $values); + * = + * $values[$key] + */ + private function areArrayKeysExistsArgsMatchingDimFetch(FuncCall $funcCall, ArrayDimFetch $arrayDimFetch): bool + { + $keyExpr = $funcCall->args[0]->value; + $valuesExpr = $funcCall->args[1]->value; + + if (! $this->areNodesEqual($arrayDimFetch->var, $valuesExpr)) { + return false; + } + + if (! $this->areNodesEqual($arrayDimFetch->dim, $keyExpr)) { + return false; + } + + return true; + } +} diff --git a/packages/CodeQuality/tests/Rector/Ternary/ArrayKeyExistsTernaryThenValueToCoalescingRector/ArrayKeyExistsTernaryThenValueToCoalescingRectorTest.php b/packages/CodeQuality/tests/Rector/Ternary/ArrayKeyExistsTernaryThenValueToCoalescingRector/ArrayKeyExistsTernaryThenValueToCoalescingRectorTest.php new file mode 100644 index 000000000000..7fa4f421b4e0 --- /dev/null +++ b/packages/CodeQuality/tests/Rector/Ternary/ArrayKeyExistsTernaryThenValueToCoalescingRector/ArrayKeyExistsTernaryThenValueToCoalescingRectorTest.php @@ -0,0 +1,30 @@ +doTestFile($file); + } + + public function provideDataForTest(): Iterator + { + return $this->yieldFilesFromDirectory(__DIR__ . '/Fixture'); + } + + protected function getRectorClass(): string + { + return ArrayKeyExistsTernaryThenValueToCoalescingRector::class; + } +} diff --git a/packages/CodeQuality/tests/Rector/Ternary/ArrayKeyExistsTernaryThenValueToCoalescingRector/Fixture/fixture.php.inc b/packages/CodeQuality/tests/Rector/Ternary/ArrayKeyExistsTernaryThenValueToCoalescingRector/Fixture/fixture.php.inc new file mode 100644 index 000000000000..4fd2a730451f --- /dev/null +++ b/packages/CodeQuality/tests/Rector/Ternary/ArrayKeyExistsTernaryThenValueToCoalescingRector/Fixture/fixture.php.inc @@ -0,0 +1,27 @@ + +----- + diff --git a/packages/CodeQuality/tests/Rector/Ternary/ArrayKeyExistsTernaryThenValueToCoalescingRector/Fixture/skip_mismatch.php.inc b/packages/CodeQuality/tests/Rector/Ternary/ArrayKeyExistsTernaryThenValueToCoalescingRector/Fixture/skip_mismatch.php.inc new file mode 100644 index 000000000000..7f7812f8f18a --- /dev/null +++ b/packages/CodeQuality/tests/Rector/Ternary/ArrayKeyExistsTernaryThenValueToCoalescingRector/Fixture/skip_mismatch.php.inc @@ -0,0 +1,11 @@ +