[DeadCode] Skip Union with Interface on RemoveUselessParamTagRector (#1127)

* [DeadCode] Skip Union with Interface on RemoveUselessParamTagRector

* Fixed 🎉

* [ci-review] Rector Rectify

* eol

* union type

* fix

* [ci-review] Rector Rectify

* [ci-review] Rector Rectify

* add failing fixture for add some comment before param

* fix

* clean up

* clean up

* [ci-review] Rector Rectify

* rectify

* clean up

Co-authored-by: GitHub Action <action@github.com>
This commit is contained in:
Abdul Malik Ikhsan 2021-11-02 14:52:50 +07:00 committed by GitHub
parent 2b09156f51
commit 8e9ef8786e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 108 additions and 6 deletions

View File

@ -0,0 +1,20 @@
<?php
declare(strict_types = 1);
namespace Rector\Tests\DeadCode\Rector\ClassMethod\RemoveUselessParamTagRector\Fixture;
use Rector\Tests\DeadCode\Rector\ClassMethod\RemoveUselessParamTagRector\Source\SomeInterface;
use Rector\Tests\DeadCode\Rector\ClassMethod\RemoveUselessParamTagRector\Source\SomeClass;
class SkipUnionOfInterface {
/**
* @param SomeClass|SomeInterface $someInterface
*/
public function run(SomeInterface $someInterface)
{
if (method_exists($someInterface, 'run')) {
$someInterface->run();
}
}
}

View File

@ -0,0 +1,22 @@
<?php
declare(strict_types = 1);
namespace Rector\Tests\DeadCode\Rector\ClassMethod\RemoveUselessParamTagRector\Fixture;
use Rector\Tests\DeadCode\Rector\ClassMethod\RemoveUselessParamTagRector\Source\SomeInterface;
use Rector\Tests\DeadCode\Rector\ClassMethod\RemoveUselessParamTagRector\Source\SomeClass;
class SkipUnionOfInterface {
/**
* Some comment
*
* @param SomeClass|SomeInterface $someInterface
*/
public function run(SomeInterface $someInterface)
{
if (method_exists($someInterface, 'run')) {
$someInterface->run();
}
}
}

View File

@ -0,0 +1,12 @@
<?php
declare(strict_types=1);
namespace Rector\Tests\DeadCode\Rector\ClassMethod\RemoveUselessParamTagRector\Source;
class SomeClass implements SomeInterface
{
public function run()
{
}
}

View File

@ -0,0 +1,9 @@
<?php
declare(strict_types=1);
namespace Rector\Tests\DeadCode\Rector\ClassMethod\RemoveUselessParamTagRector\Source;
interface SomeInterface
{
}

View File

@ -4,15 +4,19 @@ declare(strict_types=1);
namespace Rector\DeadCode\PhpDoc;
use PhpParser\Node;
use PhpParser\Node\FunctionLike;
use PhpParser\Node\Name;
use PhpParser\Node\Name\FullyQualified;
use PhpParser\Node\Param;
use PHPStan\PhpDocParser\Ast\PhpDoc\ParamTagValueNode;
use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocChildNode;
use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocNode;
use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagNode;
use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTextNode;
use PHPStan\PhpDocParser\Ast\Type\GenericTypeNode;
use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode;
use Rector\BetterPhpDocParser\ValueObject\PhpDoc\VariadicAwareParamTagValueNode;
use Rector\BetterPhpDocParser\ValueObject\PhpDocAttributeKey;
use Rector\BetterPhpDocParser\ValueObject\Type\BracketsAwareUnionTypeNode;
use Rector\BetterPhpDocParser\ValueObject\Type\SpacingAwareCallableTypeNode;
@ -58,17 +62,17 @@ final class DeadParamTagValueNodeAnalyzer
}
if (! $paramTagValueNode->type instanceof BracketsAwareUnionTypeNode) {
return $this->isEmptyDescription($paramTagValueNode);
return $this->isEmptyDescription($paramTagValueNode, $param->type);
}
if (! $this->hasGenericType($paramTagValueNode->type)) {
return $this->isEmptyDescription($paramTagValueNode);
return $this->isEmptyDescription($paramTagValueNode, $param->type);
}
return false;
}
private function isEmptyDescription(ParamTagValueNode $paramTagValueNode): bool
private function isEmptyDescription(ParamTagValueNode $paramTagValueNode, Node $node): bool
{
if ($paramTagValueNode->description !== '') {
return false;
@ -86,15 +90,50 @@ final class DeadParamTagValueNodeAnalyzer
$children = $parent->children;
if (! isset($children[1])) {
foreach ($children as $key => $child) {
if ($child instanceof PhpDocTagNode && $node instanceof FullyQualified) {
return $this->isUnionIdentifier($child);
}
if (! $this->isTextNextline($key, $child)) {
return false;
}
}
return true;
}
private function isTextNextline(int $key, PhpDocChildNode $phpDocChildNode): bool
{
if ($key < 1) {
return true;
}
if (! $children[1] instanceof PhpDocTextNode) {
if (! $phpDocChildNode instanceof PhpDocTextNode) {
return true;
}
return (string) $children[1] === '';
return (string) $phpDocChildNode === '';
}
private function isUnionIdentifier(PhpDocTagNode $phpDocTagNode): bool
{
if (! $phpDocTagNode->value instanceof VariadicAwareParamTagValueNode) {
return true;
}
if (! $phpDocTagNode->value->type instanceof BracketsAwareUnionTypeNode) {
return true;
}
$types = $phpDocTagNode->value->type->types;
foreach ($types as $type) {
if ($type instanceof IdentifierTypeNode) {
return false;
}
}
return true;
}
private function hasGenericType(BracketsAwareUnionTypeNode $bracketsAwareUnionTypeNode): bool