Skip to content

Commit

Permalink
[Php56] Skip after infinite loop on AddDefaultValueForUndefinedVariab…
Browse files Browse the repository at this point in the history
…leRector (#3390)

* Add failing test fixture for AddDefaultValueForUndefinedVariableRector with infinite loop

# Failing Test for AddDefaultValueForUndefinedVariableRector

Based on https://getrector.com/demo/e1b4cf4e-c34f-466d-ac1a-4ecdbffca61c

* rename fixture

* Closes #3388 Fixes rectorphp/rector#7777

* remove comment

* add more failing fixture

* rollback

* fix

* Fix

* Fix

* Final touch: clean up

* Final touch: clean up

* Final touch: clean up

* Really Really Final touch: verify when parent is Closure Expr

---------

Co-authored-by: Jack Bentley <jackbentley@iname.com>
  • Loading branch information
samsonasik and jackbentley committed Feb 19, 2023
1 parent bf7648c commit c65e60f
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
use PhpParser\Node\Expr\Assign;
use PhpParser\Node\Expr\AssignOp;
use PhpParser\Node\Expr\BinaryOp;
use PhpParser\Node\Expr\Closure;
use PhpParser\Node\Expr\FuncCall;
use PhpParser\Node\Expr\Ternary;
use PhpParser\Node\Expr\Variable;
Expand Down Expand Up @@ -46,6 +47,7 @@
use Rector\Caching\Detector\ChangedFilesDetector;
use Rector\Caching\FileSystem\DependencyResolver;
use Rector\Core\Exception\ShouldNotHappenException;
use Rector\Core\PhpParser\Node\BetterNodeFinder;
use Rector\Core\StaticReflection\SourceLocator\RenamedClassesSourceLocator;
use Rector\Core\Util\Reflection\PrivatesAccessor;
use Rector\Core\Util\StringUtils;
Expand Down Expand Up @@ -80,7 +82,8 @@ public function __construct(
private readonly ScopeFactory $scopeFactory,
private readonly PrivatesAccessor $privatesAccessor,
private readonly RenamedClassesSourceLocator $renamedClassesSourceLocator,
private readonly NodeNameResolver $nodeNameResolver
private readonly NodeNameResolver $nodeNameResolver,
private readonly BetterNodeFinder $betterNodeFinder
) {
$this->decoratePHPStanNodeScopeResolverWithRenamedClassSourceLocator($this->nodeScopeResolver);
}
Expand Down Expand Up @@ -214,6 +217,10 @@ public function processNodes(
$mutatingScope = $this->resolveClassOrInterfaceScope($node, $mutatingScope, $isScopeRefreshing);
}

if ($node instanceof Stmt) {
$this->setChildOfUnreachableStatementNodeAttribute($node);
}

// special case for unreachable nodes
if ($node instanceof UnreachableStatementNode) {
$this->processUnreachableStatementNode($node, $filePath, $mutatingScope);
Expand All @@ -225,6 +232,30 @@ public function processNodes(
return $this->processNodesWithDependentFiles($filePath, $stmts, $scope, $nodeCallback);
}

private function setChildOfUnreachableStatementNodeAttribute(Stmt $stmt): void
{
if ($stmt->getAttribute(AttributeKey::IS_UNREACHABLE) === true) {
return;
}

$parentStmt = $stmt->getAttribute(AttributeKey::PARENT_NODE);
if (! $parentStmt instanceof Node) {
return;
}

if ($parentStmt instanceof Closure) {
$parentStmt = $this->betterNodeFinder->resolveCurrentStatement($parentStmt);
}

if (! $parentStmt instanceof Stmt) {
return;
}

if ($parentStmt->getAttribute(AttributeKey::IS_UNREACHABLE) === true) {
$stmt->setAttribute(AttributeKey::IS_UNREACHABLE, true);
}
}

private function processArray(Array_ $array, MutatingScope $mutatingScope): void
{
foreach ($array->items as $arrayItem) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

namespace Rector\Tests\Php56\Rector\FunctionLike\AddDefaultValueForUndefinedVariableRector\Fixture;

final class SkipAfterInfiniteLoop
{
public function run(Item $yes)
{
while (true !== false) {
}

$a = [];

if ($b = $yes) {
$a[] = 'test';
}

return $a;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

namespace Rector\Tests\Php56\Rector\FunctionLike\AddDefaultValueForUndefinedVariableRector\Fixture;

final class SkipAfterInfiniteLoop2
{
public function run(Item $yes)
{
echo 'test';

while (true !== false) {
}

$a = [];

if ($b = $yes) {
$a[] = 'test';
}

return $a;
}
}

0 comments on commit c65e60f

Please sign in to comment.