Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

namespace Rector\Tests\DeadCode\Rector\Property\RemoveUselessVarTagRector\Fixture;

use DateTime;

/** @var DateTime */
$a = new DateTime('now');

?>
-----
<?php

namespace Rector\Tests\DeadCode\Rector\Property\RemoveUselessVarTagRector\Fixture;

use DateTime;

$a = new DateTime('now');

?>
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

namespace Rector\Tests\DeadCode\Rector\Property\RemoveUselessVarTagRector\Fixture;

use DateTime;
use Rector\Tests\DeadCode\Rector\Property\RemoveUselessVarTagRector\Source\SomeReturnDocblock;

$obj = new SomeReturnDocblock();
/** @var DateTime $return */
$return = $obj->get();
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

namespace Rector\Tests\DeadCode\Rector\Property\RemoveUselessVarTagRector\Source;

use DateTime;

class SomeReturnDocblock
{
/**
* @return DateTime
*/
public function get()
{
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,6 @@ public function refactor(Node $node): ?Node
/** @var Variable $catchVar */
$catchVar = $catch->var;

/** @var string $oldVariableName */
$oldVariableName = (string) $this->getName($catchVar);

$typeShortName = $this->resolveVariableName($catch->types[0]);
Expand Down
45 changes: 38 additions & 7 deletions rules/DeadCode/PhpDoc/DeadVarTagValueNodeAnalyzer.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@
namespace Rector\DeadCode\PhpDoc;

use PhpParser\Node;
use PhpParser\Node\Expr;
use PhpParser\Node\Expr\Assign;
use PhpParser\Node\Stmt\ClassConst;
use PhpParser\Node\Stmt\Expression;
use PhpParser\Node\Stmt\Property;
use PHPStan\PhpDocParser\Ast\PhpDoc\VarTagValueNode;
use PHPStan\PhpDocParser\Ast\Type\GenericTypeNode;
Expand All @@ -15,34 +18,62 @@
use PHPStan\Type\UnionType;
use Rector\DeadCode\PhpDoc\Guard\TemplateTypeRemovalGuard;
use Rector\NodeTypeResolver\TypeComparator\TypeComparator;
use Rector\PHPStan\ScopeFetcher;
use Rector\StaticTypeMapper\StaticTypeMapper;

final readonly class DeadVarTagValueNodeAnalyzer
{
public function __construct(
private TypeComparator $typeComparator,
private StaticTypeMapper $staticTypeMapper,
private TemplateTypeRemovalGuard $templateTypeRemovalGuard
private TemplateTypeRemovalGuard $templateTypeRemovalGuard,
) {
}

public function isDead(VarTagValueNode $varTagValueNode, Property|ClassConst $property): bool
public function isDead(VarTagValueNode $varTagValueNode, Property|ClassConst|Expression $node): bool
{
if (! $property->type instanceof Node) {
if (! $node instanceof Expression && ! $node->type instanceof Node) {
return false;
}

if ($varTagValueNode->description !== '') {
return false;
}

$targetNode = null;

if ($node instanceof Expression && $node->expr instanceof Assign) {
$targetNode = $node->expr->expr;
} elseif ($node instanceof Property || $node instanceof ClassConst) {
$targetNode = $node->type;
}

// allow Identifier, ComplexType, and Name on Property and ClassConst
if (! $targetNode instanceof Node) {
return false;
}

if ($varTagValueNode->type instanceof 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);
$propertyType = $this->staticTypeMapper->mapPhpParserNodePHPStanType($targetNode);
$docType = $this->staticTypeMapper->mapPHPStanPhpDocTypeNodeToPHPStanType($varTagValueNode->type, $node);

if ($node instanceof Expression) {
$scope = ScopeFetcher::fetch($node);

// only allow Expr on assign expr
if (! $targetNode instanceof Expr) {
return false;
}

$nativeType = $scope->getNativeType($targetNode);
if (! $docType->equals($nativeType)) {
return false;
}
}

if (! $this->templateTypeRemovalGuard->isLegal($docType)) {
return false;
Expand All @@ -59,9 +90,9 @@ public function isDead(VarTagValueNode $varTagValueNode, Property|ClassConst $pr
}

if ($this->typeComparator->arePhpParserAndPhpStanPhpDocTypesEqual(
$property->type,
$targetNode,
$varTagValueNode->type,
$property
$node
)) {
return true;
}
Expand Down
2 changes: 1 addition & 1 deletion rules/DeadCode/PhpDoc/TagRemover/VarTagRemover.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public function __construct(
) {
}

public function removeVarTagIfUseless(PhpDocInfo $phpDocInfo, Property|ClassConst $property): bool
public function removeVarTagIfUseless(PhpDocInfo $phpDocInfo, Property|ClassConst|Expression $property): bool
{
$varTagValueNode = $phpDocInfo->getVarTagValueNode();
if (! $varTagValueNode instanceof VarTagValueNode) {
Expand Down
5 changes: 3 additions & 2 deletions rules/DeadCode/Rector/Property/RemoveUselessVarTagRector.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use PhpParser\Node;
use PhpParser\Node\Stmt\ClassConst;
use PhpParser\Node\Stmt\Expression;
use PhpParser\Node\Stmt\Property;
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory;
use Rector\DeadCode\PhpDoc\TagRemover\VarTagRemover;
Expand Down Expand Up @@ -54,11 +55,11 @@ final class SomeClass
*/
public function getNodeTypes(): array
{
return [Property::class, ClassConst::class];
return [Property::class, ClassConst::class, Expression::class];
}

/**
* @param Property|ClassConst $node
* @param Property|ClassConst|Expression $node
*/
public function refactor(Node $node): ?Node
{
Expand Down
1 change: 0 additions & 1 deletion rules/Php55/RegexMatcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ public function resolvePatternExpressionWithoutEIfFound(Expr $expr): Concat|Stri
default => $delimiter
};

/** @var string $modifiers */
$modifiers = $this->resolveModifiers((string) Strings::after($pattern, $delimiter, -1));
if (! \str_contains($modifiers, 'e')) {
return null;
Expand Down