[DeadCode] Register RemoveDeadInstanceOfRector to dead-code config set (#5474)

* [DeadCode] Register RemoveDeadInstanceOfRector to dead-code config set

* failing fixture nullable type

* null type check

* handle child check and null check

* failing fixture with php doc type

* debug

* ensure different var

* fix

* fixture rename

* skip assign as may has side effect

* Param check

* clean up

* clean up

* final touch

* final touch

* fix

* fix

* [ci-review] Rector Rectify

* [ci-review] Rector Rectify

Co-authored-by: kaizen-ci <info@kaizen-ci.org>
This commit is contained in:
Abdul Malik Ikhsan 2021-02-10 02:04:20 +07:00 committed by GitHub
parent ecbef2bcaa
commit 1a9544f5f4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 96 additions and 13 deletions

View File

@ -30,6 +30,7 @@ use Rector\DeadCode\Rector\FunctionLike\RemoveCodeAfterReturnRector;
use Rector\DeadCode\Rector\FunctionLike\RemoveDeadReturnRector;
use Rector\DeadCode\Rector\FunctionLike\RemoveDuplicatedIfReturnRector;
use Rector\DeadCode\Rector\FunctionLike\RemoveOverriddenValuesRector;
use Rector\DeadCode\Rector\If_\RemoveDeadInstanceOfRector;
use Rector\DeadCode\Rector\If_\RemoveUnusedNonEmptyArrayBeforeForeachRector;
use Rector\DeadCode\Rector\If_\SimplifyIfElseWithSameContentRector;
use Rector\DeadCode\Rector\If_\UnwrapFutureCompatibleIfFunctionExistsRector;
@ -94,4 +95,5 @@ return static function (ContainerConfigurator $containerConfigurator): void {
$services->set(RemoveEmptyMethodCallRector::class);
$services->set(RemoveDeadConditionAboveReturnRector::class);
$services->set(RemoveUnusedConstructorParamRector::class);
$services->set(RemoveDeadInstanceOfRector::class);
};

View File

@ -111,9 +111,6 @@ final class NodeRemovingPostRector extends NodeVisitorAbstract implements PostRe
MethodCall $mainMethodCall,
MethodCall $toBeRemovedMethodCall
): bool {
if (! $mainMethodCall instanceof MethodCall) {
return false;
}
if (! $mainMethodCall->var instanceof MethodCall) {
return false;
}

View File

@ -5,11 +5,17 @@ declare(strict_types=1);
namespace Rector\DeadCode\Rector\If_;
use PhpParser\Node;
use PhpParser\Node\Expr\Assign;
use PhpParser\Node\Expr\BooleanNot;
use PhpParser\Node\Expr\Instanceof_;
use PhpParser\Node\Name\FullyQualified;
use PhpParser\Node\Param;
use PhpParser\Node\Stmt\If_;
use PHPStan\Type\ObjectType;
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo;
use Rector\Core\NodeManipulator\IfManipulator;
use Rector\Core\Rector\AbstractRector;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
@ -89,6 +95,9 @@ CODE_SAMPLE
private function processMayDeadInstanceOf(If_ $if, Instanceof_ $instanceof): ?Node
{
$previousVar = $this->betterNodeFinder->findFirstPrevious($if, function (Node $node) use ($instanceof): bool {
if ($node === $instanceof->expr) {
return false;
}
return $this->areNodesEqual($node, $instanceof->expr);
});
@ -101,7 +110,7 @@ CODE_SAMPLE
return null;
}
$isSameObject = $this->isObjectType($previousVar, $name);
$isSameObject = $this->isSameObject($previousVar, $name);
if (! $isSameObject) {
return null;
}
@ -116,4 +125,37 @@ CODE_SAMPLE
$this->removeNode($if);
return $if;
}
private function isSameObject(Node $node, string $name): bool
{
$objectType = $this->getObjectType($node);
$parentPreviousVar = $node->getAttribute(AttributeKey::PARENT_NODE);
if (! $parentPreviousVar instanceof Param) {
$phpDocInfo = $node->getAttribute(AttributeKey::PHP_DOC_INFO);
if ($phpDocInfo instanceof PhpDocInfo) {
return false;
}
$parentNode = $node->getAttribute(AttributeKey::PARENT_NODE);
if (! $parentNode instanceof Assign) {
return false;
}
$objectType = $this->getObjectType($parentNode->expr);
if (! $objectType instanceof ObjectType) {
return false;
}
return is_a($objectType, $name, true);
}
$type = $parentPreviousVar->type;
if ($type instanceof FullyQualified) {
$type = $type->toString();
return is_a($type, $name, true);
}
return false;
}
}

View File

@ -0,0 +1,28 @@
<?php
namespace Rector\DeadCode\Tests\Rector\If_\RemoveDeadInstanceOfRector\Fixture;
use stdClass;
class SkipAssignUnion
{
public function go()
{
$var = $this->getStdClass();
if (! $var instanceof stdClass) {
return false;
}
return true;
}
private function getStdClass():?stdClass
{
if (rand(0, 1)) {
return new stdClass;
}
return null;
}
}
?>

View File

@ -0,0 +1,23 @@
<?php
namespace Rector\DeadCode\Tests\Rector\If_\RemoveDeadInstanceOfRector\Fixture;
use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\ClassLike;
use PhpParser\Node\Stmt\Interface_;
class SkipUsePhpdocInfo
{
/**
* @param Class_|Interface_ $classLike
*/
public function getClassLikeNodeParentInterfaceNames(ClassLike $classLike): array
{
if ($classLike instanceof Class_) {
return false;
}
return true;
}
}
?>

View File

@ -128,11 +128,6 @@ CODE_SAMPLE
return true;
}
// we look for 2 methods calls in a row
if (! $expression instanceof Expression) {
return true;
}
$prevStmt = $classMethod->stmts[$i - 1];
return ! $prevStmt instanceof Expression;

View File

@ -129,10 +129,6 @@ CODE_SAMPLE
ClassMethod $classMethod,
MethodCallRenameInterface $methodCallRename
): bool {
if (! $classMethod instanceof ClassMethod) {
return false;
}
$classLike = $classMethod->getAttribute(AttributeKey::CLASS_NODE);
if (! $classLike instanceof ClassLike) {
return false;