From 58abaa72572f1ac84786dac2785c876827c96359 Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Fri, 8 Aug 2025 18:28:49 +0700 Subject: [PATCH 1/3] [DeadCode] Early check GenericTypeNode is not dead code on DeadVar/ReturnParam Analyzer --- rules/DeadCode/PhpDoc/DeadParamTagValueNodeAnalyzer.php | 4 ++++ rules/DeadCode/PhpDoc/DeadReturnTagValueNodeAnalyzer.php | 4 ++++ rules/DeadCode/PhpDoc/DeadVarTagValueNodeAnalyzer.php | 4 ++++ 3 files changed, 12 insertions(+) diff --git a/rules/DeadCode/PhpDoc/DeadParamTagValueNodeAnalyzer.php b/rules/DeadCode/PhpDoc/DeadParamTagValueNodeAnalyzer.php index 12380af8887..2aab90dec39 100644 --- a/rules/DeadCode/PhpDoc/DeadParamTagValueNodeAnalyzer.php +++ b/rules/DeadCode/PhpDoc/DeadParamTagValueNodeAnalyzer.php @@ -51,6 +51,10 @@ public function isDead(ParamTagValueNode $paramTagValueNode, FunctionLike $funct return false; } + if ($paramTagValueNode->type instanceof \PHPStan\PhpDocParser\Ast\Type\GenericTypeNode) { + return false; + } + $docType = $this->staticTypeMapper->mapPHPStanPhpDocTypeNodeToPHPStanType( $paramTagValueNode->type, $functionLike diff --git a/rules/DeadCode/PhpDoc/DeadReturnTagValueNodeAnalyzer.php b/rules/DeadCode/PhpDoc/DeadReturnTagValueNodeAnalyzer.php index 89808203aaf..e14d6ff97df 100644 --- a/rules/DeadCode/PhpDoc/DeadReturnTagValueNodeAnalyzer.php +++ b/rules/DeadCode/PhpDoc/DeadReturnTagValueNodeAnalyzer.php @@ -49,6 +49,10 @@ public function isDead(ReturnTagValueNode $returnTagValueNode, ClassMethod|Funct return false; } + if ($returnTagValueNode->type instanceof \PHPStan\PhpDocParser\Ast\Type\GenericTypeNode) { + return false; + } + $docType = $this->staticTypeMapper->mapPHPStanPhpDocTypeNodeToPHPStanType( $returnTagValueNode->type, $functionLike diff --git a/rules/DeadCode/PhpDoc/DeadVarTagValueNodeAnalyzer.php b/rules/DeadCode/PhpDoc/DeadVarTagValueNodeAnalyzer.php index 5a0c2120a7f..90d008b155d 100644 --- a/rules/DeadCode/PhpDoc/DeadVarTagValueNodeAnalyzer.php +++ b/rules/DeadCode/PhpDoc/DeadVarTagValueNodeAnalyzer.php @@ -35,6 +35,10 @@ public function isDead(VarTagValueNode $varTagValueNode, Property|ClassConst $pr return false; } + if ($varTagValueNode->type instanceof \PHPStan\PhpDocParser\Ast\Type\GenericTypeNode) { + return false; + } + // is strict type superior to doc type? keep strict type only $propertyType = $this->staticTypeMapper->mapPhpParserNodePHPStanType($property->type); $docType = $this->staticTypeMapper->mapPHPStanPhpDocTypeNodeToPHPStanType($varTagValueNode->type, $property); From a3e956c901e346d96281ac3e98c3d905a64a56a8 Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Fri, 8 Aug 2025 18:30:37 +0700 Subject: [PATCH 2/3] Fix --- ecs.php | 5 +++++ ...RemoveReadonlyPropertyVisibilityOnReadonlyClassRector.php | 2 +- rules/DeadCode/PhpDoc/DeadParamTagValueNodeAnalyzer.php | 3 ++- rules/DeadCode/PhpDoc/DeadReturnTagValueNodeAnalyzer.php | 3 ++- rules/DeadCode/PhpDoc/DeadVarTagValueNodeAnalyzer.php | 3 ++- .../FuncCall/AddArrayFunctionClosureParamTypeRector.php | 1 + 6 files changed, 13 insertions(+), 4 deletions(-) diff --git a/ecs.php b/ecs.php index 0843e496663..86ec04db345 100644 --- a/ecs.php +++ b/ecs.php @@ -5,6 +5,7 @@ use PhpCsFixer\Fixer\Phpdoc\GeneralPhpdocAnnotationRemoveFixer; use PhpCsFixer\Fixer\Phpdoc\PhpdocTypesFixer; use Symplify\EasyCodingStandard\Config\ECSConfig; +use PhpCsFixer\Fixer\Casing\LowercaseKeywordsFixer; return ECSConfig::configure() ->withPreparedSets(symplify: true, common: true, psr12: true) @@ -34,5 +35,9 @@ // bug remove @author annotation __DIR__ . '/src/Util/ArrayParametersMerger.php', ], + + LowercaseKeywordsFixer::class => [ + __DIR__ . '/src/ValueObject/Visibility.php', + ], ]) ->withRootFiles(); diff --git a/rules/CodeQuality/Rector/Class_/RemoveReadonlyPropertyVisibilityOnReadonlyClassRector.php b/rules/CodeQuality/Rector/Class_/RemoveReadonlyPropertyVisibilityOnReadonlyClassRector.php index c55659eb984..e1bf1ed8e6a 100644 --- a/rules/CodeQuality/Rector/Class_/RemoveReadonlyPropertyVisibilityOnReadonlyClassRector.php +++ b/rules/CodeQuality/Rector/Class_/RemoveReadonlyPropertyVisibilityOnReadonlyClassRector.php @@ -5,8 +5,8 @@ namespace Rector\CodeQuality\Rector\Class_; use PhpParser\Node; -use PhpParser\Node\Stmt\ClassMethod; use PhpParser\Node\Stmt\Class_; +use PhpParser\Node\Stmt\ClassMethod; use Rector\Php81\NodeManipulator\AttributeGroupNewLiner; use Rector\Privatization\NodeManipulator\VisibilityManipulator; use Rector\Rector\AbstractRector; diff --git a/rules/DeadCode/PhpDoc/DeadParamTagValueNodeAnalyzer.php b/rules/DeadCode/PhpDoc/DeadParamTagValueNodeAnalyzer.php index 2aab90dec39..187cb79ed7f 100644 --- a/rules/DeadCode/PhpDoc/DeadParamTagValueNodeAnalyzer.php +++ b/rules/DeadCode/PhpDoc/DeadParamTagValueNodeAnalyzer.php @@ -9,6 +9,7 @@ use PhpParser\Node\Name; use PhpParser\Node\Param; use PHPStan\PhpDocParser\Ast\PhpDoc\ParamTagValueNode; +use PHPStan\PhpDocParser\Ast\Type\GenericTypeNode; use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode; use Rector\BetterPhpDocParser\PhpDocManipulator\PhpDocTypeChanger; use Rector\BetterPhpDocParser\ValueObject\Type\BracketsAwareUnionTypeNode; @@ -51,7 +52,7 @@ public function isDead(ParamTagValueNode $paramTagValueNode, FunctionLike $funct return false; } - if ($paramTagValueNode->type instanceof \PHPStan\PhpDocParser\Ast\Type\GenericTypeNode) { + if ($paramTagValueNode->type instanceof GenericTypeNode) { return false; } diff --git a/rules/DeadCode/PhpDoc/DeadReturnTagValueNodeAnalyzer.php b/rules/DeadCode/PhpDoc/DeadReturnTagValueNodeAnalyzer.php index e14d6ff97df..e55e247c9e1 100644 --- a/rules/DeadCode/PhpDoc/DeadReturnTagValueNodeAnalyzer.php +++ b/rules/DeadCode/PhpDoc/DeadReturnTagValueNodeAnalyzer.php @@ -10,6 +10,7 @@ use PhpParser\Node\Stmt\Function_; use PHPStan\Analyser\Scope; use PHPStan\PhpDocParser\Ast\PhpDoc\ReturnTagValueNode; +use PHPStan\PhpDocParser\Ast\Type\GenericTypeNode; use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode; use PHPStan\PhpDocParser\Ast\Type\ThisTypeNode; use PHPStan\Type\TypeCombinator; @@ -49,7 +50,7 @@ public function isDead(ReturnTagValueNode $returnTagValueNode, ClassMethod|Funct return false; } - if ($returnTagValueNode->type instanceof \PHPStan\PhpDocParser\Ast\Type\GenericTypeNode) { + if ($returnTagValueNode->type instanceof GenericTypeNode) { return false; } diff --git a/rules/DeadCode/PhpDoc/DeadVarTagValueNodeAnalyzer.php b/rules/DeadCode/PhpDoc/DeadVarTagValueNodeAnalyzer.php index 90d008b155d..9d0b078cee3 100644 --- a/rules/DeadCode/PhpDoc/DeadVarTagValueNodeAnalyzer.php +++ b/rules/DeadCode/PhpDoc/DeadVarTagValueNodeAnalyzer.php @@ -8,6 +8,7 @@ use PhpParser\Node\Stmt\ClassConst; use PhpParser\Node\Stmt\Property; use PHPStan\PhpDocParser\Ast\PhpDoc\VarTagValueNode; +use PHPStan\PhpDocParser\Ast\Type\GenericTypeNode; use PHPStan\Type\IntersectionType; use PHPStan\Type\ObjectType; use PHPStan\Type\TypeCombinator; @@ -35,7 +36,7 @@ public function isDead(VarTagValueNode $varTagValueNode, Property|ClassConst $pr return false; } - if ($varTagValueNode->type instanceof \PHPStan\PhpDocParser\Ast\Type\GenericTypeNode) { + if ($varTagValueNode->type instanceof GenericTypeNode) { return false; } diff --git a/rules/TypeDeclaration/Rector/FuncCall/AddArrayFunctionClosureParamTypeRector.php b/rules/TypeDeclaration/Rector/FuncCall/AddArrayFunctionClosureParamTypeRector.php index 14bc2b3b8c7..f9eb8e497de 100644 --- a/rules/TypeDeclaration/Rector/FuncCall/AddArrayFunctionClosureParamTypeRector.php +++ b/rules/TypeDeclaration/Rector/FuncCall/AddArrayFunctionClosureParamTypeRector.php @@ -106,6 +106,7 @@ public function refactor(Node $node): ?Node if (! $singlePassedExprType instanceof Type) { continue; } + if ($singlePassedExprType instanceof MixedType) { continue; } From b4c9dfa9997290c57542d7f2baa49f568e91b31a Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Fri, 8 Aug 2025 18:31:06 +0700 Subject: [PATCH 3/3] Fix --- ecs.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/ecs.php b/ecs.php index 86ec04db345..0497edc8d5b 100644 --- a/ecs.php +++ b/ecs.php @@ -2,10 +2,10 @@ declare(strict_types=1); +use PhpCsFixer\Fixer\Casing\LowercaseKeywordsFixer; use PhpCsFixer\Fixer\Phpdoc\GeneralPhpdocAnnotationRemoveFixer; use PhpCsFixer\Fixer\Phpdoc\PhpdocTypesFixer; use Symplify\EasyCodingStandard\Config\ECSConfig; -use PhpCsFixer\Fixer\Casing\LowercaseKeywordsFixer; return ECSConfig::configure() ->withPreparedSets(symplify: true, common: true, psr12: true) @@ -36,8 +36,6 @@ __DIR__ . '/src/Util/ArrayParametersMerger.php', ], - LowercaseKeywordsFixer::class => [ - __DIR__ . '/src/ValueObject/Visibility.php', - ], + LowercaseKeywordsFixer::class => [__DIR__ . '/src/ValueObject/Visibility.php'], ]) ->withRootFiles();