Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

namespace Rector\Tests\DowngradePhp84\Rector\Expression\DowngradeArrayFindRector\Fixture;

class OnReturn
{
public function run(array $animals)
{
return array_find($animals, fn($animal) => str_starts_with($animal, 'c'));
}
}

?>
-----
<?php

namespace Rector\Tests\DowngradePhp84\Rector\Expression\DowngradeArrayFindRector\Fixture;

class OnReturn
{
public function run(array $animals)
{
$found = null;
foreach ($animals as $animal) {
if (str_starts_with($animal, 'c')) {
$found = $animal;
break;
}
}
return $found;
}
}

?>
51 changes: 38 additions & 13 deletions rules/DowngradePhp84/Rector/Expression/DowngradeArrayFindRector.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,16 @@
use PhpParser\Node\Expr\Assign;
use PhpParser\Node\Expr\ConstFetch;
use PhpParser\Node\Expr\FuncCall;
use PhpParser\Node\Expr\Variable;
use PhpParser\Node\Name;
use PhpParser\Node\Stmt;
use PhpParser\Node\Stmt\Break_;
use PhpParser\Node\Stmt\Expression;
use PhpParser\Node\Stmt\Foreach_;
use PhpParser\Node\Stmt\If_;
use PhpParser\Node\Stmt\Return_;
use Rector\Naming\Naming\VariableNaming;
use Rector\PHPStan\ScopeFetcher;
use Rector\Rector\AbstractRector;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
Expand All @@ -26,9 +30,14 @@
*/
final class DowngradeArrayFindRector extends AbstractRector
{
public function __construct(
private readonly VariableNaming $variableNaming
) {
}

public function getNodeTypes(): array
{
return [Expression::class];
return [Expression::class, Return_::class];
}

public function getRuleDefinition(): RuleDefinition
Expand Down Expand Up @@ -56,28 +65,36 @@ public function getRuleDefinition(): RuleDefinition
}

/**
* @param Expression $node
* @param Expression|Return_ $node
* @return Stmt[]|null
*/
public function refactor(Node $node): ?array
{
if (! $node->expr instanceof Assign) {
if ($node instanceof Return_ && ! $node->expr instanceof FuncCall) {
return null;
}

if ($node instanceof Expression && ! $node->expr instanceof Assign) {
return null;
}

if (! $node->expr->expr instanceof FuncCall) {
$expr = $node instanceof Expression && $node->expr instanceof Assign
? $node->expr->expr
: $node->expr;

if (! $expr instanceof FuncCall) {
return null;
}

if (! $this->isName($node->expr->expr, 'array_find')) {
if (! $this->isName($expr, 'array_find')) {
return null;
}

if ($node->expr->expr->isFirstClassCallable()) {
if ($expr->isFirstClassCallable()) {
return null;
}

$args = $node->expr->expr->getArgs();
$args = $expr->getArgs();
if (count($args) !== 2) {
return null;
}
Expand All @@ -86,17 +103,19 @@ public function refactor(Node $node): ?array
return null;
}

$scope = ScopeFetcher::fetch($node);
$variable = $node instanceof Expression && $node->expr instanceof Assign
? $node->expr->var
: new Variable($this->variableNaming->createCountedValueName('found', $scope));

$valueCond = $args[1]->value->expr;
$if = new If_($valueCond, [
'stmts' => [
new Expression(new Assign($node->expr->var, $args[1]->value->params[0]->var)),
new Break_(),
],
'stmts' => [new Expression(new Assign($variable, $args[1]->value->params[0]->var)), new Break_()],
]);

return [
$result = [
// init
new Expression(new Assign($node->expr->var, new ConstFetch(new Name('null')))),
new Expression(new Assign($variable, new ConstFetch(new Name('null')))),

// foreach loop
new Foreach_(
Expand All @@ -112,5 +131,11 @@ public function refactor(Node $node): ?array
],
),
];

if ($node instanceof Return_) {
$result[] = new Return_($variable);
}

return $result;
}
}