[DeadCode] Fix RemoveUnusedPrivatePropertyRector for nested chain method callable

This commit is contained in:
Tomas Votruba 2019-07-09 21:18:43 +02:00
parent f70c9aad1c
commit 21f72206b1
7 changed files with 56 additions and 16 deletions

View File

@ -6,7 +6,7 @@ use PhpParser\Node;
use PhpParser\Node\Expr\Assign;
use PhpParser\Node\Expr\PropertyFetch;
use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\ClassLike;
use PhpParser\Node\Stmt\Interface_;
use PhpParser\Node\Stmt\Property;
use PhpParser\Node\Stmt\Trait_;
use Rector\NodeTypeResolver\Node\AttributeKey;
@ -64,13 +64,13 @@ CODE_SAMPLE
return null;
}
/** @var ClassLike|null $classNode */
/** @var Class_|Interface_|Trait_|null $classNode */
$classNode = $node->getAttribute(AttributeKey::CLASS_NODE);
if ($classNode === null || $classNode instanceof Trait_) {
if ($classNode === null || $classNode instanceof Trait_ || $classNode instanceof Interface_) {
return null;
}
if ($classNode instanceof Class_ && $classNode->isAnonymous()) {
if ($classNode->isAnonymous()) {
return null;
}
@ -86,7 +86,6 @@ CODE_SAMPLE
}
$uselessAssigns = $this->resolveUselessAssignNode($propertyFetches);
if (count($uselessAssigns) > 0) {
$this->removeNode($node);
foreach ($uselessAssigns as $uselessAssign) {
@ -98,6 +97,9 @@ CODE_SAMPLE
}
/**
* Matches all-only: "$this->property = x"
* If these is ANY OTHER use of property, e.g. process($this->property), it returns []
*
* @param PropertyFetch[] $propertyFetches
* @return Assign[]
*/
@ -107,9 +109,11 @@ CODE_SAMPLE
foreach ($propertyFetches as $propertyFetch) {
$propertyFetchParentNode = $propertyFetch->getAttribute(AttributeKey::PARENT_NODE);
if ($propertyFetchParentNode instanceof Assign && $propertyFetchParentNode->var === $propertyFetch) {
$uselessAssigns[] = $propertyFetchParentNode;
} else {
// it is used another way as well → nothing to remove
return [];
}
}

View File

@ -2,10 +2,6 @@
namespace Rector\DeadCode\Tests\Rector\Property\RemoveUnusedPrivatePropertyRector\Fixture;
use PhpParser\Node;
use PhpParser\NodeVisitor;
use PhpParser\NodeVisitorAbstract;
class SkipAnonymousFunction
{
/**

View File

@ -0,0 +1,38 @@
<?php
declare(strict_types=1);
namespace Tests\Unit\Exceptions;
use stdClass;
class SkipNestedClosure
{
private $mailer;
private $message;
public function setUp()
{
$this->message = new stdClass();
$this->mailer = new stdClass();
}
public function test()
{
$this->mailer->method()
->with(
$this->anything(),
$this->callback(
function () {
$this->message
->expects($this->once())
->method()
->with($this->a(), $this->b());
$this->call();
return true;
}
)
);
}
}

View File

@ -12,9 +12,10 @@ final class RemoveUnusedPrivatePropertyRectorTest extends AbstractRectorTestCase
$this->doTestFiles([
__DIR__ . '/Fixture/fixture.php.inc',
__DIR__ . '/Fixture/property_assign.php.inc',
__DIR__ . '/Fixture/with_trait.php.inc',
__DIR__ . '/Fixture/skip_anonymous_class.php.inc',
__DIR__ . '/Fixture/skip_anonymous_function.php.inc',
__DIR__ . '/Fixture/with_trait.php.inc',
__DIR__ . '/Fixture/skip_nested_closure.php.inc',
]);
}

View File

@ -16,9 +16,10 @@ use Rector\PhpParser\Node\BetterNodeFinder;
final class RemoveDeepChainMethodCallNodeVisitor extends NodeVisitorAbstract
{
/**
* @warning might cause bugs with fluent interfaces like https://github.com/rectorphp/rector/issues/1646
* @var int
*/
private const NESTED_CHAIN_METHOD_CALL_LIMIT = 10;
private const NESTED_CHAIN_METHOD_CALL_LIMIT = 15;
/**
* @var BetterNodeFinder

View File

@ -17,4 +17,4 @@ parameters:
php_version_features: '7.1'
services:
Rector\CodingStyle\Rector\Namespace_\ImportFullyQualifiedNamesRector: ~
# Rector\CodingStyle\Rector\Namespace_\ImportFullyQualifiedNamesRector: ~

View File

@ -63,13 +63,13 @@ final class PropertyManipulator
$nodesToSearch[] = $classNode;
return $this->betterNodeFinder->find($nodesToSearch, function (Node $node) use ($property) {
// itself
if ($this->betterStandardPrinter->areNodesEqual($node, $property)) {
// property + static fetch
if (! $node instanceof PropertyFetch && ! $node instanceof StaticPropertyFetch) {
return null;
}
// property + static fetch
if (! $node instanceof PropertyFetch && ! $node instanceof StaticPropertyFetch) {
// itself
if ($this->betterStandardPrinter->areNodesEqual($node, $property)) {
return null;
}