Skip to content

Commit fe687bf

Browse files
authored
[Php84] Skip foreach value used after foreach on ForeachToArray* rules (#7034)
* [Php84] Skip foreach value used after foreach on ForeachToArray* rules * more fixtures
1 parent 992f3ff commit fe687bf

8 files changed

Lines changed: 123 additions & 4 deletions

File tree

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
3+
namespace Rector\Tests\Php84\Rector\Foreach_\ForeachToArrayAllRector\Fixture;
4+
5+
class SkipVariableReUseAfterForeach
6+
{
7+
public function checkAllAnimalsStartWithC(array $animals)
8+
{
9+
$found = true;
10+
foreach ($animals as $animal) {
11+
if (!str_starts_with($animal, 'c')) {
12+
$found = false;
13+
break;
14+
}
15+
}
16+
17+
if (isset($animal)) {
18+
echo 'hit';
19+
}
20+
21+
return $found;
22+
}
23+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
3+
namespace Rector\Tests\Php84\Rector\Foreach_\ForeachToArrayAnyRector\Fixture;
4+
5+
class SkipVariableReUseAfterForeach
6+
{
7+
public function checkAnimal(array $animals)
8+
{
9+
$found = false;
10+
foreach ($animals as $animal) {
11+
if (str_starts_with($animal, 'c')) {
12+
$found = true;
13+
break;
14+
}
15+
}
16+
17+
if (isset($animal)) {
18+
echo 'hit';
19+
}
20+
21+
return $found;
22+
}
23+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
3+
namespace Rector\Tests\Php84\Rector\Foreach_\ForeachToArrayFindKeyRector\Fixture;
4+
5+
class SkipVariableReUseAfterForeach
6+
{
7+
public function findAnimalKey(array $animals)
8+
{
9+
$found = null;
10+
foreach ($animals as $idx => $animal) {
11+
if (str_starts_with($animal, 'c')) {
12+
$found = $idx;
13+
break;
14+
}
15+
}
16+
17+
if (isset($animal)) {
18+
echo 'hit';
19+
}
20+
21+
return $found;
22+
}
23+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?php
2+
3+
namespace Rector\Tests\Php84\Rector\Foreach_\ForeachToArrayFindRector\Fixture;
4+
5+
class SkipVariableReUseAfterForeach
6+
{
7+
/**
8+
* @param array<Url> $urls
9+
*/
10+
public function create(array $urls, string $hash): ?Url
11+
{
12+
$url = null;
13+
foreach ($urls as $urlToCheck) {
14+
if ($urlToCheck->getPathHash() === $hash) {
15+
$url = $urlToCheck;
16+
break;
17+
}
18+
}
19+
20+
if (isset($urlToCheck)) {
21+
echo 'hit';
22+
}
23+
24+
return $url;
25+
}
26+
}

rules/Php84/Rector/Foreach_/ForeachToArrayAllRector.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use PhpParser\Node\Stmt\Foreach_;
1616
use PhpParser\Node\Stmt\If_;
1717
use Rector\Contract\PhpParser\Node\StmtsAwareInterface;
18+
use Rector\NodeManipulator\StmtsManipulator;
1819
use Rector\PhpParser\Node\Value\ValueResolver;
1920
use Rector\Rector\AbstractRector;
2021
use Rector\ValueObject\PhpVersionFeature;
@@ -28,7 +29,8 @@
2829
final class ForeachToArrayAllRector extends AbstractRector implements MinPhpVersionInterface
2930
{
3031
public function __construct(
31-
private readonly ValueResolver $valueResolver
32+
private readonly ValueResolver $valueResolver,
33+
private readonly StmtsManipulator $stmtsManipulator
3234
) {
3335
}
3436

@@ -104,6 +106,10 @@ public function refactor(Node $node): ?Node
104106
continue;
105107
}
106108

109+
if ($this->stmtsManipulator->isVariableUsedInNextStmt($node, $key + 1, (string) $this->getName($foreach->valueVar))) {
110+
continue;
111+
}
112+
107113
/** @var If_ $firstNodeInsideForeach */
108114
$firstNodeInsideForeach = $foreach->stmts[0];
109115

rules/Php84/Rector/Foreach_/ForeachToArrayAnyRector.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use PhpParser\Node\Stmt\Foreach_;
1515
use PhpParser\Node\Stmt\If_;
1616
use Rector\Contract\PhpParser\Node\StmtsAwareInterface;
17+
use Rector\NodeManipulator\StmtsManipulator;
1718
use Rector\PhpParser\Node\Value\ValueResolver;
1819
use Rector\Rector\AbstractRector;
1920
use Rector\ValueObject\PhpVersionFeature;
@@ -27,7 +28,8 @@
2728
final class ForeachToArrayAnyRector extends AbstractRector implements MinPhpVersionInterface
2829
{
2930
public function __construct(
30-
private readonly ValueResolver $valueResolver
31+
private readonly ValueResolver $valueResolver,
32+
private readonly StmtsManipulator $stmtsManipulator
3133
) {
3234
}
3335

@@ -103,6 +105,10 @@ public function refactor(Node $node): ?Node
103105
continue;
104106
}
105107

108+
if ($this->stmtsManipulator->isVariableUsedInNextStmt($node, $key + 1, (string) $this->getName($foreach->valueVar))) {
109+
continue;
110+
}
111+
106112
/** @var If_ $firstNodeInsideForeach */
107113
$firstNodeInsideForeach = $foreach->stmts[0];
108114

rules/Php84/Rector/Foreach_/ForeachToArrayFindKeyRector.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use PhpParser\Node\Stmt\Foreach_;
1616
use PhpParser\Node\Stmt\If_;
1717
use Rector\Contract\PhpParser\Node\StmtsAwareInterface;
18+
use Rector\NodeManipulator\StmtsManipulator;
1819
use Rector\PhpParser\Node\Value\ValueResolver;
1920
use Rector\Rector\AbstractRector;
2021
use Rector\ValueObject\PhpVersionFeature;
@@ -28,7 +29,8 @@
2829
final class ForeachToArrayFindKeyRector extends AbstractRector implements MinPhpVersionInterface
2930
{
3031
public function __construct(
31-
private readonly ValueResolver $valueResolver
32+
private readonly ValueResolver $valueResolver,
33+
private readonly StmtsManipulator $stmtsManipulator,
3234
) {
3335
}
3436

@@ -108,6 +110,10 @@ public function refactor(Node $node): ?Node
108110
continue;
109111
}
110112

113+
if ($this->stmtsManipulator->isVariableUsedInNextStmt($node, $key + 1, (string) $this->getName($foreach->valueVar))) {
114+
continue;
115+
}
116+
111117
/** @var If_ $firstNodeInsideForeach */
112118
$firstNodeInsideForeach = $foreach->stmts[0];
113119

rules/Php84/Rector/Foreach_/ForeachToArrayFindRector.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use PhpParser\Node\Stmt\Foreach_;
1515
use PhpParser\Node\Stmt\If_;
1616
use Rector\Contract\PhpParser\Node\StmtsAwareInterface;
17+
use Rector\NodeManipulator\StmtsManipulator;
1718
use Rector\PhpParser\Node\Value\ValueResolver;
1819
use Rector\Rector\AbstractRector;
1920
use Rector\ValueObject\PhpVersionFeature;
@@ -27,7 +28,8 @@
2728
final class ForeachToArrayFindRector extends AbstractRector implements MinPhpVersionInterface
2829
{
2930
public function __construct(
30-
private readonly ValueResolver $valueResolver
31+
private readonly ValueResolver $valueResolver,
32+
private readonly StmtsManipulator $stmtsManipulator
3133
) {
3234
}
3335

@@ -103,6 +105,10 @@ public function refactor(Node $node): ?Node
103105
continue;
104106
}
105107

108+
if ($this->stmtsManipulator->isVariableUsedInNextStmt($node, $key + 1, (string) $this->getName($foreach->valueVar))) {
109+
continue;
110+
}
111+
106112
/** @var If_ $firstNodeInsideForeach */
107113
$firstNodeInsideForeach = $foreach->stmts[0];
108114

0 commit comments

Comments
 (0)