Skip to content

Commit

Permalink
[Php81] Skip param reassign on ReadOnlyPropertyRector (#2498)
Browse files Browse the repository at this point in the history
* [Php81] Skip param reassign on ReadOnlyPropertyRector

* Fixed 🎉

* clean up

* final touch: eol

* [ci-review] Rector Rectify

Co-authored-by: GitHub Action <action@github.com>
  • Loading branch information
samsonasik and actions-user committed Jun 17, 2022
1 parent 9aec92a commit 064d38b
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

namespace Rector\Tests\Php81\Rector\Property\ReadOnlyPropertyRector\Fixture;

final class SkipParamReassign
{
public function __construct(private string $foo)
{
$foo = 'bar';

$this->foo = $foo;
}
}
6 changes: 6 additions & 0 deletions rules/Php81/Rector/Property/ReadOnlyPropertyRector.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use PhpParser\Node\Expr;
use PhpParser\Node\Param;
use PhpParser\Node\Stmt\Property;
use Rector\Core\NodeAnalyzer\ParamAnalyzer;
use Rector\Core\NodeManipulator\PropertyFetchAssignManipulator;
use Rector\Core\NodeManipulator\PropertyManipulator;
use Rector\Core\Rector\AbstractRector;
Expand All @@ -29,6 +30,7 @@ final class ReadOnlyPropertyRector extends AbstractRector implements MinPhpVersi
public function __construct(
private readonly PropertyManipulator $propertyManipulator,
private readonly PropertyFetchAssignManipulator $propertyFetchAssignManipulator,
private readonly ParamAnalyzer $paramAnalyzer,
private readonly VisibilityManipulator $visibilityManipulator,
) {
}
Expand Down Expand Up @@ -156,6 +158,10 @@ private function refactorParam(Param $param): Param | null
return null;
}

if ($this->paramAnalyzer->isParamReassign($param)) {
return null;
}

$this->visibilityManipulator->makeReadonly($param);
return $param;
}
Expand Down
28 changes: 28 additions & 0 deletions src/NodeAnalyzer/ParamAnalyzer.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace Rector\Core\NodeAnalyzer;

use PhpParser\Node;
use PhpParser\Node\Expr\Assign;
use PhpParser\Node\Expr\CallLike;
use PhpParser\Node\Expr\Closure;
use PhpParser\Node\Expr\ConstFetch;
Expand All @@ -19,8 +20,10 @@
use PhpParser\NodeTraverser;
use Rector\Core\NodeManipulator\FuncCallManipulator;
use Rector\Core\PhpParser\Comparing\NodeComparator;
use Rector\Core\PhpParser\Node\BetterNodeFinder;
use Rector\Core\PhpParser\Node\Value\ValueResolver;
use Rector\NodeNameResolver\NodeNameResolver;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Symplify\Astral\NodeTraverser\SimpleCallableNodeTraverser;

final class ParamAnalyzer
Expand All @@ -31,6 +34,7 @@ public function __construct(
private readonly NodeNameResolver $nodeNameResolver,
private readonly FuncCallManipulator $funcCallManipulator,
private readonly SimpleCallableNodeTraverser $simpleCallableNodeTraverser,
private readonly BetterNodeFinder $betterNodeFinder
) {
}

Expand Down Expand Up @@ -101,6 +105,30 @@ public function hasDefaultNull(Param $param): bool
return $param->default instanceof ConstFetch && $this->valueResolver->isNull($param->default);
}

public function isParamReassign(Param $param): bool
{
$classMethod = $param->getAttribute(AttributeKey::PARENT_NODE);

if (! $classMethod instanceof ClassMethod) {
return false;
}

$paramName = (string) $this->nodeNameResolver->getName($param->var);
return (bool) $this->betterNodeFinder->findFirstInFunctionLikeScoped($classMethod, function (Node $node) use (
$paramName
): bool {
if (! $node instanceof Assign) {
return false;
}

if (! $node->var instanceof Variable) {
return false;
}

return $this->nodeNameResolver->isName($node->var, $paramName);
});
}

private function isVariableInClosureUses(Closure $closure, Variable $variable): bool
{
foreach ($closure->uses as $use) {
Expand Down

0 comments on commit 064d38b

Please sign in to comment.