2020-12-04 23:22:12 +00:00
|
|
|
<?php
|
|
|
|
|
2021-05-09 20:15:43 +00:00
|
|
|
declare (strict_types=1);
|
2022-06-06 17:12:56 +00:00
|
|
|
namespace Rector\DeadCode\PhpDoc;
|
2020-12-04 23:22:12 +00:00
|
|
|
|
2024-04-03 06:21:54 +00:00
|
|
|
use PHPStan\PhpDocParser\Ast\Type\UnionTypeNode;
|
2022-06-06 17:12:56 +00:00
|
|
|
use PhpParser\Node\FunctionLike;
|
|
|
|
use PhpParser\Node\Name;
|
2024-04-03 06:21:54 +00:00
|
|
|
use PhpParser\Node\Name\FullyQualified;
|
2022-06-06 17:12:56 +00:00
|
|
|
use PhpParser\Node\Param;
|
|
|
|
use PHPStan\PhpDocParser\Ast\PhpDoc\ParamTagValueNode;
|
|
|
|
use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode;
|
|
|
|
use Rector\BetterPhpDocParser\PhpDocManipulator\PhpDocTypeChanger;
|
|
|
|
use Rector\BetterPhpDocParser\ValueObject\Type\BracketsAwareUnionTypeNode;
|
|
|
|
use Rector\DeadCode\TypeNodeAnalyzer\GenericTypeNodeAnalyzer;
|
|
|
|
use Rector\DeadCode\TypeNodeAnalyzer\MixedArrayTypeNodeAnalyzer;
|
|
|
|
use Rector\NodeNameResolver\NodeNameResolver;
|
|
|
|
use Rector\NodeTypeResolver\TypeComparator\TypeComparator;
|
2022-08-31 09:31:19 +00:00
|
|
|
use Rector\TypeDeclaration\NodeAnalyzer\ParamAnalyzer;
|
2020-12-04 23:22:12 +00:00
|
|
|
final class DeadParamTagValueNodeAnalyzer
|
|
|
|
{
|
|
|
|
/**
|
2023-06-11 23:01:39 +00:00
|
|
|
* @readonly
|
2021-05-10 23:39:21 +00:00
|
|
|
* @var \Rector\NodeNameResolver\NodeNameResolver
|
2020-12-04 23:22:12 +00:00
|
|
|
*/
|
|
|
|
private $nodeNameResolver;
|
|
|
|
/**
|
2023-06-11 23:01:39 +00:00
|
|
|
* @readonly
|
2021-05-10 23:39:21 +00:00
|
|
|
* @var \Rector\NodeTypeResolver\TypeComparator\TypeComparator
|
2020-12-04 23:22:12 +00:00
|
|
|
*/
|
|
|
|
private $typeComparator;
|
2021-11-28 17:35:55 +00:00
|
|
|
/**
|
2023-06-11 23:01:39 +00:00
|
|
|
* @readonly
|
2021-11-28 17:35:55 +00:00
|
|
|
* @var \Rector\DeadCode\TypeNodeAnalyzer\GenericTypeNodeAnalyzer
|
|
|
|
*/
|
|
|
|
private $genericTypeNodeAnalyzer;
|
2022-05-25 06:59:11 +00:00
|
|
|
/**
|
2023-06-11 23:01:39 +00:00
|
|
|
* @readonly
|
2022-05-25 06:59:11 +00:00
|
|
|
* @var \Rector\DeadCode\TypeNodeAnalyzer\MixedArrayTypeNodeAnalyzer
|
|
|
|
*/
|
|
|
|
private $mixedArrayTypeNodeAnalyzer;
|
2022-08-31 09:31:19 +00:00
|
|
|
/**
|
2023-06-11 23:01:39 +00:00
|
|
|
* @readonly
|
2022-08-31 09:31:19 +00:00
|
|
|
* @var \Rector\TypeDeclaration\NodeAnalyzer\ParamAnalyzer
|
|
|
|
*/
|
|
|
|
private $paramAnalyzer;
|
2023-04-09 00:39:59 +00:00
|
|
|
/**
|
2023-06-11 23:01:39 +00:00
|
|
|
* @readonly
|
2023-04-09 00:39:59 +00:00
|
|
|
* @var \Rector\BetterPhpDocParser\PhpDocManipulator\PhpDocTypeChanger
|
|
|
|
*/
|
|
|
|
private $phpDocTypeChanger;
|
|
|
|
public function __construct(NodeNameResolver $nodeNameResolver, TypeComparator $typeComparator, GenericTypeNodeAnalyzer $genericTypeNodeAnalyzer, MixedArrayTypeNodeAnalyzer $mixedArrayTypeNodeAnalyzer, ParamAnalyzer $paramAnalyzer, PhpDocTypeChanger $phpDocTypeChanger)
|
2020-12-05 00:31:05 +00:00
|
|
|
{
|
2020-12-04 23:22:12 +00:00
|
|
|
$this->nodeNameResolver = $nodeNameResolver;
|
|
|
|
$this->typeComparator = $typeComparator;
|
2021-11-28 17:35:55 +00:00
|
|
|
$this->genericTypeNodeAnalyzer = $genericTypeNodeAnalyzer;
|
2022-05-25 06:59:11 +00:00
|
|
|
$this->mixedArrayTypeNodeAnalyzer = $mixedArrayTypeNodeAnalyzer;
|
2022-08-31 09:31:19 +00:00
|
|
|
$this->paramAnalyzer = $paramAnalyzer;
|
2023-04-09 00:39:59 +00:00
|
|
|
$this->phpDocTypeChanger = $phpDocTypeChanger;
|
2020-12-04 23:22:12 +00:00
|
|
|
}
|
2022-06-07 08:22:29 +00:00
|
|
|
public function isDead(ParamTagValueNode $paramTagValueNode, FunctionLike $functionLike) : bool
|
2020-12-04 23:22:12 +00:00
|
|
|
{
|
2022-08-31 09:31:19 +00:00
|
|
|
$param = $this->paramAnalyzer->getParamByName($paramTagValueNode->parameterName, $functionLike);
|
2022-06-07 08:22:29 +00:00
|
|
|
if (!$param instanceof Param) {
|
2021-05-09 20:15:43 +00:00
|
|
|
return \false;
|
2020-12-04 23:22:12 +00:00
|
|
|
}
|
|
|
|
if ($param->type === null) {
|
2021-05-09 20:15:43 +00:00
|
|
|
return \false;
|
2020-12-04 23:22:12 +00:00
|
|
|
}
|
2023-09-02 15:59:59 +00:00
|
|
|
if ($paramTagValueNode->description !== '') {
|
|
|
|
return \false;
|
|
|
|
}
|
2024-04-03 06:21:54 +00:00
|
|
|
if ($paramTagValueNode->type instanceof UnionTypeNode && $param->type instanceof FullyQualified) {
|
|
|
|
return \false;
|
|
|
|
}
|
2022-06-07 08:22:29 +00:00
|
|
|
if ($param->type instanceof Name && $this->nodeNameResolver->isName($param->type, 'object')) {
|
|
|
|
return $paramTagValueNode->type instanceof IdentifierTypeNode && (string) $paramTagValueNode->type === 'object';
|
2021-09-07 09:40:30 +00:00
|
|
|
}
|
2021-05-09 20:15:43 +00:00
|
|
|
if (!$this->typeComparator->arePhpParserAndPhpStanPhpDocTypesEqual($param->type, $paramTagValueNode->type, $functionLike)) {
|
|
|
|
return \false;
|
2020-12-04 23:22:12 +00:00
|
|
|
}
|
2023-04-09 00:39:59 +00:00
|
|
|
if ($this->phpDocTypeChanger->isAllowed($paramTagValueNode->type)) {
|
2021-05-09 20:15:43 +00:00
|
|
|
return \false;
|
2021-02-25 08:36:33 +00:00
|
|
|
}
|
2022-06-07 08:22:29 +00:00
|
|
|
if (!$paramTagValueNode->type instanceof BracketsAwareUnionTypeNode) {
|
2023-09-02 15:59:59 +00:00
|
|
|
return \true;
|
2021-08-16 08:22:42 +00:00
|
|
|
}
|
2024-04-03 06:21:54 +00:00
|
|
|
return $this->isAllowedBracketAwareUnion($paramTagValueNode->type);
|
|
|
|
}
|
|
|
|
private function isAllowedBracketAwareUnion(BracketsAwareUnionTypeNode $bracketsAwareUnionTypeNode) : bool
|
|
|
|
{
|
|
|
|
if ($this->mixedArrayTypeNodeAnalyzer->hasMixedArrayType($bracketsAwareUnionTypeNode)) {
|
2022-05-25 06:59:11 +00:00
|
|
|
return \false;
|
|
|
|
}
|
2024-04-03 06:21:54 +00:00
|
|
|
return !$this->genericTypeNodeAnalyzer->hasGenericType($bracketsAwareUnionTypeNode);
|
2021-08-16 08:22:42 +00:00
|
|
|
}
|
2020-12-04 23:22:12 +00:00
|
|
|
}
|