Skip to content

Commit

Permalink
[Naming] Skip used on next foreach on RenameForeachValueVariableToMat…
Browse files Browse the repository at this point in the history
…chExprVariableRector (#4469)

* [Naming] Skip used on next foreach on RenameForeachValueVariableToMatchExprVariableRector

* clean up

* more fixture rollback

* more fixture rollback
  • Loading branch information
samsonasik committed Jul 10, 2023
1 parent 5b64258 commit 28412a4
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 29 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

namespace Rector\Tests\Naming\Rector\Foreach_\RenameForeachValueVariableToMatchExprVariableRector\Fixture;

final class SkipOldValueUsedNext
{
public function run()
{
$numbers = ['one', 'two'];

foreach ($numbers as $txt) {
echo "This is number ".$txt;
}

echo $txt;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

namespace Rector\Tests\Naming\Rector\Foreach_\RenameForeachValueVariableToMatchExprVariableRector\Fixture;

class SkipUsedNextForeach
{
public function run()
{
$array = [];
foreach ($variables as $property) {
$array[] = $property;
}

echo $variable;
}
}

?>
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
use PhpParser\Node;
use PhpParser\Node\Expr\Variable;
use PhpParser\Node\Stmt\Foreach_;
use Rector\Core\Contract\PhpParser\Node\StmtsAwareInterface;
use Rector\Core\NodeAnalyzer\PropertyFetchAnalyzer;
use Rector\Core\NodeManipulator\StmtsManipulator;
use Rector\Core\Rector\AbstractRector;
use Rector\Naming\ExpectedNameResolver\InflectorSingularResolver;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
Expand All @@ -20,7 +22,8 @@ final class RenameForeachValueVariableToMatchExprVariableRector extends Abstract
{
public function __construct(
private readonly InflectorSingularResolver $inflectorSingularResolver,
private readonly PropertyFetchAnalyzer $propertyFetchAnalyzer
private readonly PropertyFetchAnalyzer $propertyFetchAnalyzer,
private readonly StmtsManipulator $stmtsManipulator
) {
}

Expand Down Expand Up @@ -63,51 +66,78 @@ public function run()
*/
public function getNodeTypes(): array
{
return [Foreach_::class];
return [StmtsAwareInterface::class];
}

/**
* @param Foreach_ $node
* @param StmtsAwareInterface $node
*/
public function refactor(Node $node): ?Node
{
$isPropertyFetch = $this->propertyFetchAnalyzer->isLocalPropertyFetch($node->expr);
if (! $node->expr instanceof Variable && ! $isPropertyFetch) {
if ($node->stmts === null) {
return null;
}

$exprName = $this->getName($node->expr);
if ($exprName === null) {
return null;
}
$hasChanged = false;

if ($node->keyVar instanceof Node) {
return null;
}
foreach ($node->stmts as $key => $stmt) {
if (! $stmt instanceof Foreach_) {
continue;
}

$valueVarName = $this->getName($node->valueVar);
if ($valueVarName === null) {
return null;
}
$isPropertyFetch = $this->propertyFetchAnalyzer->isLocalPropertyFetch($stmt->expr);
if (! $stmt->expr instanceof Variable && ! $isPropertyFetch) {
continue;
}

$singularValueVarName = $this->inflectorSingularResolver->resolve($exprName);
if ($singularValueVarName === $exprName) {
return null;
}
$exprName = $this->getName($stmt->expr);
if ($exprName === null) {
continue;
}

if ($singularValueVarName === $valueVarName) {
return null;
if ($stmt->keyVar instanceof Node) {
continue;
}

$valueVarName = $this->getName($stmt->valueVar);
if ($valueVarName === null) {
continue;
}

$singularValueVarName = $this->inflectorSingularResolver->resolve($exprName);
if ($singularValueVarName === $exprName) {
continue;
}

if ($singularValueVarName === $valueVarName) {
continue;
}

$alreadyUsedVariable = $this->betterNodeFinder->findVariableOfName($stmt->stmts, $singularValueVarName);
if ($alreadyUsedVariable instanceof Variable) {
continue;
}

if ($this->stmtsManipulator->isVariableUsedInNextStmt($node, $key + 1, $singularValueVarName)) {
continue;
}

if ($this->stmtsManipulator->isVariableUsedInNextStmt($node, $key + 1, $valueVarName)) {
continue;
}

$this->processRename($stmt, $valueVarName, $singularValueVarName);
$hasChanged = true;
}

$alreadyUsedVariable = $this->betterNodeFinder->findVariableOfName($node->stmts, $singularValueVarName);
if ($alreadyUsedVariable instanceof Variable) {
return null;
if ($hasChanged) {
return $node;
}

return $this->processRename($node, $valueVarName, $singularValueVarName);
return null;
}

private function processRename(Foreach_ $foreach, string $valueVarName, string $singularValueVarName): Foreach_
private function processRename(Foreach_ $foreach, string $valueVarName, string $singularValueVarName): void
{
$foreach->valueVar = new Variable($singularValueVarName);
$this->traverseNodesWithCallable($foreach->stmts, function (Node $node) use (
Expand All @@ -124,7 +154,5 @@ private function processRename(Foreach_ $foreach, string $valueVarName, string $

return new Variable($singularValueVarName);
});

return $foreach;
}
}

0 comments on commit 28412a4

Please sign in to comment.