diff --git a/rules/DeadCode/PhpDoc/DeadParamTagValueNodeAnalyzer.php b/rules/DeadCode/PhpDoc/DeadParamTagValueNodeAnalyzer.php index 099cd4bde912..1f9351ce52f1 100644 --- a/rules/DeadCode/PhpDoc/DeadParamTagValueNodeAnalyzer.php +++ b/rules/DeadCode/PhpDoc/DeadParamTagValueNodeAnalyzer.php @@ -8,10 +8,10 @@ use PhpParser\Node\Param; use PHPStan\PhpDocParser\Ast\PhpDoc\ParamTagValueNode; use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode; -use PHPStan\Type\Generic\TemplateType; use Rector\BetterPhpDocParser\PhpDocManipulator\PhpDocTypeChanger; use Rector\BetterPhpDocParser\ValueObject\Type\BracketsAwareUnionTypeNode; use Rector\DeadCode\PhpDoc\Guard\StandaloneTypeRemovalGuard; +use Rector\DeadCode\PhpDoc\Guard\TemplateTypeRemovalGuard; use Rector\DeadCode\TypeNodeAnalyzer\GenericTypeNodeAnalyzer; use Rector\DeadCode\TypeNodeAnalyzer\MixedArrayTypeNodeAnalyzer; use Rector\NodeNameResolver\NodeNameResolver; @@ -60,7 +60,12 @@ final class DeadParamTagValueNodeAnalyzer * @var \Rector\StaticTypeMapper\StaticTypeMapper */ private $staticTypeMapper; - public function __construct(NodeNameResolver $nodeNameResolver, TypeComparator $typeComparator, GenericTypeNodeAnalyzer $genericTypeNodeAnalyzer, MixedArrayTypeNodeAnalyzer $mixedArrayTypeNodeAnalyzer, ParamAnalyzer $paramAnalyzer, PhpDocTypeChanger $phpDocTypeChanger, StandaloneTypeRemovalGuard $standaloneTypeRemovalGuard, StaticTypeMapper $staticTypeMapper) + /** + * @readonly + * @var \Rector\DeadCode\PhpDoc\Guard\TemplateTypeRemovalGuard + */ + private $templateTypeRemovalGuard; + public function __construct(NodeNameResolver $nodeNameResolver, TypeComparator $typeComparator, GenericTypeNodeAnalyzer $genericTypeNodeAnalyzer, MixedArrayTypeNodeAnalyzer $mixedArrayTypeNodeAnalyzer, ParamAnalyzer $paramAnalyzer, PhpDocTypeChanger $phpDocTypeChanger, StandaloneTypeRemovalGuard $standaloneTypeRemovalGuard, StaticTypeMapper $staticTypeMapper, TemplateTypeRemovalGuard $templateTypeRemovalGuard) { $this->nodeNameResolver = $nodeNameResolver; $this->typeComparator = $typeComparator; @@ -70,6 +75,7 @@ public function __construct(NodeNameResolver $nodeNameResolver, TypeComparator $ $this->phpDocTypeChanger = $phpDocTypeChanger; $this->standaloneTypeRemovalGuard = $standaloneTypeRemovalGuard; $this->staticTypeMapper = $staticTypeMapper; + $this->templateTypeRemovalGuard = $templateTypeRemovalGuard; } public function isDead(ParamTagValueNode $paramTagValueNode, FunctionLike $functionLike) : bool { @@ -84,7 +90,7 @@ public function isDead(ParamTagValueNode $paramTagValueNode, FunctionLike $funct return \false; } $docType = $this->staticTypeMapper->mapPHPStanPhpDocTypeNodeToPHPStanType($paramTagValueNode->type, $functionLike); - if ($docType instanceof TemplateType) { + if (!$this->templateTypeRemovalGuard->isLegal($docType)) { return \false; } if ($param->type instanceof Name && $this->nodeNameResolver->isName($param->type, 'object')) { diff --git a/rules/DeadCode/PhpDoc/DeadReturnTagValueNodeAnalyzer.php b/rules/DeadCode/PhpDoc/DeadReturnTagValueNodeAnalyzer.php index 13f7182bca9f..020e610236a2 100644 --- a/rules/DeadCode/PhpDoc/DeadReturnTagValueNodeAnalyzer.php +++ b/rules/DeadCode/PhpDoc/DeadReturnTagValueNodeAnalyzer.php @@ -11,12 +11,12 @@ use PHPStan\PhpDocParser\Ast\PhpDoc\ReturnTagValueNode; use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode; use PHPStan\PhpDocParser\Ast\Type\ThisTypeNode; -use PHPStan\Type\Generic\TemplateType; use PHPStan\Type\TypeCombinator; use PHPStan\Type\UnionType; use Rector\BetterPhpDocParser\PhpDocManipulator\PhpDocTypeChanger; use Rector\BetterPhpDocParser\ValueObject\Type\BracketsAwareUnionTypeNode; use Rector\DeadCode\PhpDoc\Guard\StandaloneTypeRemovalGuard; +use Rector\DeadCode\PhpDoc\Guard\TemplateTypeRemovalGuard; use Rector\DeadCode\TypeNodeAnalyzer\GenericTypeNodeAnalyzer; use Rector\DeadCode\TypeNodeAnalyzer\MixedArrayTypeNodeAnalyzer; use Rector\NodeTypeResolver\Node\AttributeKey; @@ -54,7 +54,12 @@ final class DeadReturnTagValueNodeAnalyzer * @var \Rector\StaticTypeMapper\StaticTypeMapper */ private $staticTypeMapper; - public function __construct(TypeComparator $typeComparator, GenericTypeNodeAnalyzer $genericTypeNodeAnalyzer, MixedArrayTypeNodeAnalyzer $mixedArrayTypeNodeAnalyzer, StandaloneTypeRemovalGuard $standaloneTypeRemovalGuard, PhpDocTypeChanger $phpDocTypeChanger, StaticTypeMapper $staticTypeMapper) + /** + * @readonly + * @var \Rector\DeadCode\PhpDoc\Guard\TemplateTypeRemovalGuard + */ + private $templateTypeRemovalGuard; + public function __construct(TypeComparator $typeComparator, GenericTypeNodeAnalyzer $genericTypeNodeAnalyzer, MixedArrayTypeNodeAnalyzer $mixedArrayTypeNodeAnalyzer, StandaloneTypeRemovalGuard $standaloneTypeRemovalGuard, PhpDocTypeChanger $phpDocTypeChanger, StaticTypeMapper $staticTypeMapper, TemplateTypeRemovalGuard $templateTypeRemovalGuard) { $this->typeComparator = $typeComparator; $this->genericTypeNodeAnalyzer = $genericTypeNodeAnalyzer; @@ -62,6 +67,7 @@ public function __construct(TypeComparator $typeComparator, GenericTypeNodeAnaly $this->standaloneTypeRemovalGuard = $standaloneTypeRemovalGuard; $this->phpDocTypeChanger = $phpDocTypeChanger; $this->staticTypeMapper = $staticTypeMapper; + $this->templateTypeRemovalGuard = $templateTypeRemovalGuard; } /** * @param \PhpParser\Node\Stmt\ClassMethod|\PhpParser\Node\Stmt\Function_ $functionLike @@ -76,7 +82,7 @@ public function isDead(ReturnTagValueNode $returnTagValueNode, $functionLike) : return \false; } $docType = $this->staticTypeMapper->mapPHPStanPhpDocTypeNodeToPHPStanType($returnTagValueNode->type, $functionLike); - if ($docType instanceof TemplateType) { + if (!$this->templateTypeRemovalGuard->isLegal($docType)) { return \false; } $scope = $functionLike->getAttribute(AttributeKey::SCOPE); diff --git a/rules/DeadCode/PhpDoc/DeadVarTagValueNodeAnalyzer.php b/rules/DeadCode/PhpDoc/DeadVarTagValueNodeAnalyzer.php index b0c240350745..e2f953d6b977 100644 --- a/rules/DeadCode/PhpDoc/DeadVarTagValueNodeAnalyzer.php +++ b/rules/DeadCode/PhpDoc/DeadVarTagValueNodeAnalyzer.php @@ -5,11 +5,11 @@ use PhpParser\Node\Stmt\Property; use PHPStan\PhpDocParser\Ast\PhpDoc\VarTagValueNode; -use PHPStan\Type\Generic\TemplateType; use PHPStan\Type\IntersectionType; use PHPStan\Type\ObjectType; use PHPStan\Type\TypeCombinator; use PHPStan\Type\UnionType; +use Rector\DeadCode\PhpDoc\Guard\TemplateTypeRemovalGuard; use Rector\NodeTypeResolver\TypeComparator\TypeComparator; use Rector\StaticTypeMapper\StaticTypeMapper; final class DeadVarTagValueNodeAnalyzer @@ -24,10 +24,16 @@ final class DeadVarTagValueNodeAnalyzer * @var \Rector\StaticTypeMapper\StaticTypeMapper */ private $staticTypeMapper; - public function __construct(TypeComparator $typeComparator, StaticTypeMapper $staticTypeMapper) + /** + * @readonly + * @var \Rector\DeadCode\PhpDoc\Guard\TemplateTypeRemovalGuard + */ + private $templateTypeRemovalGuard; + public function __construct(TypeComparator $typeComparator, StaticTypeMapper $staticTypeMapper, TemplateTypeRemovalGuard $templateTypeRemovalGuard) { $this->typeComparator = $typeComparator; $this->staticTypeMapper = $staticTypeMapper; + $this->templateTypeRemovalGuard = $templateTypeRemovalGuard; } public function isDead(VarTagValueNode $varTagValueNode, Property $property) : bool { @@ -40,7 +46,7 @@ public function isDead(VarTagValueNode $varTagValueNode, Property $property) : b // is strict type superior to doc type? keep strict type only $propertyType = $this->staticTypeMapper->mapPhpParserNodePHPStanType($property->type); $docType = $this->staticTypeMapper->mapPHPStanPhpDocTypeNodeToPHPStanType($varTagValueNode->type, $property); - if ($docType instanceof TemplateType) { + if (!$this->templateTypeRemovalGuard->isLegal($docType)) { return \false; } if ($propertyType instanceof UnionType && !$docType instanceof UnionType) { diff --git a/rules/DeadCode/PhpDoc/Guard/TemplateTypeRemovalGuard.php b/rules/DeadCode/PhpDoc/Guard/TemplateTypeRemovalGuard.php new file mode 100644 index 000000000000..c93146d2cba0 --- /dev/null +++ b/rules/DeadCode/PhpDoc/Guard/TemplateTypeRemovalGuard.php @@ -0,0 +1,26 @@ +getTypes() : [$docType]; + foreach ($types as $type) { + if ($type instanceof TemplateType) { + return \false; + } + } + return \true; + } +} diff --git a/src/Application/VersionResolver.php b/src/Application/VersionResolver.php index ab44c66cd5d4..b1f84da7a1d4 100644 --- a/src/Application/VersionResolver.php +++ b/src/Application/VersionResolver.php @@ -19,12 +19,12 @@ final class VersionResolver * @api * @var string */ - public const PACKAGE_VERSION = '1afc64719771eae635df76bf5f85b225b459b3d6'; + public const PACKAGE_VERSION = 'afe7c46c0387e27e1eae37cf76f8a3a4119a1d39'; /** * @api * @var string */ - public const RELEASE_DATE = '2024-11-04 22:15:08'; + public const RELEASE_DATE = '2024-11-05 21:18:05'; /** * @var int */ diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php index 06b70357c758..5108ab0d7660 100644 --- a/vendor/composer/autoload_classmap.php +++ b/vendor/composer/autoload_classmap.php @@ -1279,6 +1279,7 @@ 'Rector\\DeadCode\\PhpDoc\\DeadReturnTagValueNodeAnalyzer' => $baseDir . '/rules/DeadCode/PhpDoc/DeadReturnTagValueNodeAnalyzer.php', 'Rector\\DeadCode\\PhpDoc\\DeadVarTagValueNodeAnalyzer' => $baseDir . '/rules/DeadCode/PhpDoc/DeadVarTagValueNodeAnalyzer.php', 'Rector\\DeadCode\\PhpDoc\\Guard\\StandaloneTypeRemovalGuard' => $baseDir . '/rules/DeadCode/PhpDoc/Guard/StandaloneTypeRemovalGuard.php', + 'Rector\\DeadCode\\PhpDoc\\Guard\\TemplateTypeRemovalGuard' => $baseDir . '/rules/DeadCode/PhpDoc/Guard/TemplateTypeRemovalGuard.php', 'Rector\\DeadCode\\PhpDoc\\TagRemover\\ParamTagRemover' => $baseDir . '/rules/DeadCode/PhpDoc/TagRemover/ParamTagRemover.php', 'Rector\\DeadCode\\PhpDoc\\TagRemover\\ReturnTagRemover' => $baseDir . '/rules/DeadCode/PhpDoc/TagRemover/ReturnTagRemover.php', 'Rector\\DeadCode\\PhpDoc\\TagRemover\\VarTagRemover' => $baseDir . '/rules/DeadCode/PhpDoc/TagRemover/VarTagRemover.php', diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php index 739eb91900d4..8ac4dcb09cc7 100644 --- a/vendor/composer/autoload_static.php +++ b/vendor/composer/autoload_static.php @@ -1498,6 +1498,7 @@ class ComposerStaticInit4d4c37b878ce01a3ff505ba7def6aac7 'Rector\\DeadCode\\PhpDoc\\DeadReturnTagValueNodeAnalyzer' => __DIR__ . '/../..' . '/rules/DeadCode/PhpDoc/DeadReturnTagValueNodeAnalyzer.php', 'Rector\\DeadCode\\PhpDoc\\DeadVarTagValueNodeAnalyzer' => __DIR__ . '/../..' . '/rules/DeadCode/PhpDoc/DeadVarTagValueNodeAnalyzer.php', 'Rector\\DeadCode\\PhpDoc\\Guard\\StandaloneTypeRemovalGuard' => __DIR__ . '/../..' . '/rules/DeadCode/PhpDoc/Guard/StandaloneTypeRemovalGuard.php', + 'Rector\\DeadCode\\PhpDoc\\Guard\\TemplateTypeRemovalGuard' => __DIR__ . '/../..' . '/rules/DeadCode/PhpDoc/Guard/TemplateTypeRemovalGuard.php', 'Rector\\DeadCode\\PhpDoc\\TagRemover\\ParamTagRemover' => __DIR__ . '/../..' . '/rules/DeadCode/PhpDoc/TagRemover/ParamTagRemover.php', 'Rector\\DeadCode\\PhpDoc\\TagRemover\\ReturnTagRemover' => __DIR__ . '/../..' . '/rules/DeadCode/PhpDoc/TagRemover/ReturnTagRemover.php', 'Rector\\DeadCode\\PhpDoc\\TagRemover\\VarTagRemover' => __DIR__ . '/../..' . '/rules/DeadCode/PhpDoc/TagRemover/VarTagRemover.php',