Skip to content

Commit

Permalink
[DeadCode] Skip used by get_object_vars() when implements JsonSeriali…
Browse files Browse the repository at this point in the history
…zable on RemoveUnusedPromotedPropertyRector (#6472)
  • Loading branch information
samsonasik authored Nov 22, 2024
1 parent 9d022cf commit c322032
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

namespace Rector\Tests\DeadCode\Rector\ClassMethod\RemoveUnusedPromotedPropertyRector\Fixture;

class SkipUsedByGetObjectVarsFromJsonSerializable implements \JsonSerializable
{
public function __construct(private readonly string $foo)
{
}

public function jsonSerialize(): array
{
return get_object_vars($this);
}
}
29 changes: 27 additions & 2 deletions rules/DeadCode/NodeAnalyzer/PropertyWriteonlyAnalyzer.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,49 @@
namespace Rector\DeadCode\NodeAnalyzer;

use PhpParser\Node;
use PhpParser\Node\Arg;
use PhpParser\Node\Expr;
use PhpParser\Node\Expr\FuncCall;
use PhpParser\Node\Expr\NullsafePropertyFetch;
use PhpParser\Node\Expr\PropertyFetch;
use PhpParser\Node\Expr\StaticPropertyFetch;
use PhpParser\Node\Expr\Variable;
use PhpParser\Node\Stmt\Class_;
use PHPStan\Type\ObjectType;
use Rector\NodeNameResolver\NodeNameResolver;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\NodeTypeResolver\NodeTypeResolver;
use Rector\PhpParser\Node\BetterNodeFinder;

final readonly class PropertyWriteonlyAnalyzer
{
public function __construct(
private BetterNodeFinder $betterNodeFinder
private BetterNodeFinder $betterNodeFinder,
private NodeTypeResolver $nodeTypeResolver,
private NodeNameResolver $nodeNameResolver
) {
}

public function hasClassDynamicPropertyNames(Class_ $class): bool
{
return (bool) $this->betterNodeFinder->findFirst($class, static function (Node $node): bool {
$isImplementsJsonSerializable = $this->nodeTypeResolver->isObjectType(
$class,
new ObjectType('JsonSerializable')
);

return (bool) $this->betterNodeFinder->findFirst($class, function (Node $node) use (
$isImplementsJsonSerializable
): bool {
if ($isImplementsJsonSerializable && $node instanceof FuncCall && $this->nodeNameResolver->isName(
$node,
'get_object_vars'
) && ! $node->isFirstClassCallable()) {
$firstArg = $node->getArgs()[0] ?? null;
if ($firstArg instanceof Arg && $firstArg->value instanceof Variable && $firstArg->value->name === 'this') {
return true;
}
}

if (! $node instanceof PropertyFetch && ! $node instanceof NullsafePropertyFetch) {
return false;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,6 @@ private function shouldSkipClass(Class_ $class): bool
}
}

return false;
return $this->propertyWriteonlyAnalyzer->hasClassDynamicPropertyNames($class);
}
}

0 comments on commit c322032

Please sign in to comment.