From aeba1a9629943489f94b0e7bd1e10d365f8ad449 Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Fri, 11 Jul 2025 15:23:03 +0700 Subject: [PATCH] [DowngradePhp84] Add DowngradeArrayFindKeyRector --- config/set/downgrade-php84.php | 2 + .../DowngradeArrayFindKeyRectorTest.php | 28 ++++ .../Fixture/fixture.php.inc | 33 +++++ .../Fixture/with_key.php.inc | 33 +++++ .../config/configured_rule.php | 10 ++ .../DowngradeArrayFindKeyRector.php | 122 ++++++++++++++++++ 6 files changed, 228 insertions(+) create mode 100644 rules-tests/DowngradePhp84/Rector/Expression/DowngradeArrayFindKeyRector/DowngradeArrayFindKeyRectorTest.php create mode 100644 rules-tests/DowngradePhp84/Rector/Expression/DowngradeArrayFindKeyRector/Fixture/fixture.php.inc create mode 100644 rules-tests/DowngradePhp84/Rector/Expression/DowngradeArrayFindKeyRector/Fixture/with_key.php.inc create mode 100644 rules-tests/DowngradePhp84/Rector/Expression/DowngradeArrayFindKeyRector/config/configured_rule.php create mode 100644 rules/DowngradePhp84/Rector/Expression/DowngradeArrayFindKeyRector.php diff --git a/config/set/downgrade-php84.php b/config/set/downgrade-php84.php index 1182f5e8..6972a98f 100644 --- a/config/set/downgrade-php84.php +++ b/config/set/downgrade-php84.php @@ -5,6 +5,7 @@ use Rector\Config\RectorConfig; use Rector\DowngradePhp84\Rector\Expression\DowngradeArrayAllRector; use Rector\DowngradePhp84\Rector\Expression\DowngradeArrayAnyRector; +use Rector\DowngradePhp84\Rector\Expression\DowngradeArrayFindKeyRector; use Rector\DowngradePhp84\Rector\Expression\DowngradeArrayFindRector; use Rector\DowngradePhp84\Rector\FuncCall\DowngradeRoundingModeEnumRector; use Rector\DowngradePhp84\Rector\MethodCall\DowngradeNewMethodCallWithoutParenthesesRector; @@ -18,5 +19,6 @@ DowngradeArrayAllRector::class, DowngradeArrayAnyRector::class, DowngradeArrayFindRector::class, + DowngradeArrayFindKeyRector::class, ]); }; diff --git a/rules-tests/DowngradePhp84/Rector/Expression/DowngradeArrayFindKeyRector/DowngradeArrayFindKeyRectorTest.php b/rules-tests/DowngradePhp84/Rector/Expression/DowngradeArrayFindKeyRector/DowngradeArrayFindKeyRectorTest.php new file mode 100644 index 00000000..5e08f587 --- /dev/null +++ b/rules-tests/DowngradePhp84/Rector/Expression/DowngradeArrayFindKeyRector/DowngradeArrayFindKeyRectorTest.php @@ -0,0 +1,28 @@ +doTestFile($filePath); + } + + public static function provideData(): Iterator + { + return self::yieldFilesFromDirectory(__DIR__ . '/Fixture'); + } + + public function provideConfigFilePath(): string + { + return __DIR__ . '/config/configured_rule.php'; + } +} diff --git a/rules-tests/DowngradePhp84/Rector/Expression/DowngradeArrayFindKeyRector/Fixture/fixture.php.inc b/rules-tests/DowngradePhp84/Rector/Expression/DowngradeArrayFindKeyRector/Fixture/fixture.php.inc new file mode 100644 index 00000000..84e4e36b --- /dev/null +++ b/rules-tests/DowngradePhp84/Rector/Expression/DowngradeArrayFindKeyRector/Fixture/fixture.php.inc @@ -0,0 +1,33 @@ + str_starts_with($animal, 'c')); + } +} + +?> +----- + $animal) { + if (str_starts_with($animal, 'c')) { + $found = $idx; + break; + } + } + } +} + +?> diff --git a/rules-tests/DowngradePhp84/Rector/Expression/DowngradeArrayFindKeyRector/Fixture/with_key.php.inc b/rules-tests/DowngradePhp84/Rector/Expression/DowngradeArrayFindKeyRector/Fixture/with_key.php.inc new file mode 100644 index 00000000..ade3a3c6 --- /dev/null +++ b/rules-tests/DowngradePhp84/Rector/Expression/DowngradeArrayFindKeyRector/Fixture/with_key.php.inc @@ -0,0 +1,33 @@ + str_starts_with($animal, 'c') && $key > 0); + } +} + +?> +----- + $animal) { + if (str_starts_with($animal, 'c') && $key > 0) { + $found = $key; + break; + } + } + } +} + +?> diff --git a/rules-tests/DowngradePhp84/Rector/Expression/DowngradeArrayFindKeyRector/config/configured_rule.php b/rules-tests/DowngradePhp84/Rector/Expression/DowngradeArrayFindKeyRector/config/configured_rule.php new file mode 100644 index 00000000..260a6e46 --- /dev/null +++ b/rules-tests/DowngradePhp84/Rector/Expression/DowngradeArrayFindKeyRector/config/configured_rule.php @@ -0,0 +1,10 @@ +rule(DowngradeArrayFindKeyRector::class); +}; diff --git a/rules/DowngradePhp84/Rector/Expression/DowngradeArrayFindKeyRector.php b/rules/DowngradePhp84/Rector/Expression/DowngradeArrayFindKeyRector.php new file mode 100644 index 00000000..ff08f559 --- /dev/null +++ b/rules/DowngradePhp84/Rector/Expression/DowngradeArrayFindKeyRector.php @@ -0,0 +1,122 @@ + str_starts_with($animal, 'c')); +CODE_SAMPLE + , + <<<'CODE_SAMPLE' +$found = null; +foreach ($animals as $idx => $animal) { + if (str_starts_with($animal, 'c')) { + $found = $idx; + break; + } +} +CODE_SAMPLE + ), + ] + ); + } + + /** + * @param Expression $node + * @return Stmt[]|null + */ + public function refactor(Node $node): ?array + { + if (! $node->expr instanceof Assign) { + return null; + } + + if (! $node->expr->expr instanceof FuncCall) { + return null; + } + + if (! $this->isName($node->expr->expr, 'array_find_key')) { + return null; + } + + if ($node->expr->expr->isFirstClassCallable()) { + return null; + } + + $args = $node->expr->expr->getArgs(); + if (count($args) !== 2) { + return null; + } + + if (! $args[1]->value instanceof ArrowFunction) { + return null; + } + + $keyVar = $args[1]->value->params[1]->var ?? new Variable($this->variableNaming->createCountedValueName( + 'idx', + ScopeFetcher::fetch($node) + )); + + $valueCond = $args[1]->value->expr; + $if = new If_($valueCond, [ + 'stmts' => [new Expression(new Assign($node->expr->var, $keyVar)), new Break_()], + ]); + + return [ + // init + new Expression(new Assign($node->expr->var, new ConstFetch(new Name('null')))), + + // foreach loop + new Foreach_( + $args[0]->value, + $args[1]->value->params[0]->var, + [ + 'keyVar' => $keyVar, + 'stmts' => [$if], + ] + ), + ]; + } +}