[TypeDeclaration] Fix parent method param override (#1945)

This commit is contained in:
Tomas Votruba 2022-03-17 10:54:51 +01:00 committed by GitHub
parent feae0cfa0c
commit dd842d6e60
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 55 additions and 17 deletions

View File

@ -2,6 +2,8 @@
namespace Rector\Tests\TypeDeclaration\Rector\Param\ParamTypeFromStrictTypedPropertyRector\Fixture; namespace Rector\Tests\TypeDeclaration\Rector\Param\ParamTypeFromStrictTypedPropertyRector\Fixture;
use Rector\Tests\TypeDeclaration\Rector\Param\ParamTypeFromStrictTypedPropertyRector\Source\ExternalClass;
final class ExternalType final class ExternalType
{ {
public function setValues($age, ExternalClass $externalClass) public function setValues($age, ExternalClass $externalClass)
@ -10,17 +12,14 @@ final class ExternalType
} }
} }
final class ExternalClass
{
public int $age;
}
?> ?>
----- -----
<?php <?php
namespace Rector\Tests\TypeDeclaration\Rector\Param\ParamTypeFromStrictTypedPropertyRector\Fixture; namespace Rector\Tests\TypeDeclaration\Rector\Param\ParamTypeFromStrictTypedPropertyRector\Fixture;
use Rector\Tests\TypeDeclaration\Rector\Param\ParamTypeFromStrictTypedPropertyRector\Source\ExternalClass;
final class ExternalType final class ExternalType
{ {
public function setValues(int $age, ExternalClass $externalClass) public function setValues(int $age, ExternalClass $externalClass)
@ -29,9 +28,4 @@ final class ExternalType
} }
} }
final class ExternalClass
{
public int $age;
}
?> ?>

View File

@ -0,0 +1,15 @@
<?php
namespace Rector\Tests\TypeDeclaration\Rector\Param\ParamTypeFromStrictTypedPropertyRector\Fixture;
use Rector\Tests\TypeDeclaration\Rector\Param\ParamTypeFromStrictTypedPropertyRector\Source\ParentClassWithArgs;
final class SkipParentClassWithArgs extends ParentClassWithArgs
{
private array $items = [];
public function redirect(string $path, $args = [])
{
$this->items = $args;
}
}

View File

@ -0,0 +1,10 @@
<?php
declare(strict_types=1);
namespace Rector\Tests\TypeDeclaration\Rector\Param\ParamTypeFromStrictTypedPropertyRector\Source;
final class ExternalClass
{
public int $age;
}

View File

@ -0,0 +1,12 @@
<?php
declare(strict_types=1);
namespace Rector\Tests\TypeDeclaration\Rector\Param\ParamTypeFromStrictTypedPropertyRector\Source;
class ParentClassWithArgs
{
public function redirect(string $path, $args = [])
{
}
}

View File

@ -5,11 +5,13 @@ declare(strict_types=1);
namespace Rector\TypeDeclaration\Rector\Param; namespace Rector\TypeDeclaration\Rector\Param;
use PhpParser\Node; use PhpParser\Node;
use PhpParser\Node\ComplexType;
use PhpParser\Node\Expr\Assign; use PhpParser\Node\Expr\Assign;
use PhpParser\Node\Expr\PropertyFetch; use PhpParser\Node\Expr\PropertyFetch;
use PhpParser\Node\FunctionLike; use PhpParser\Node\Name;
use PhpParser\Node\NullableType; use PhpParser\Node\NullableType;
use PhpParser\Node\Param; use PhpParser\Node\Param;
use PhpParser\Node\Stmt\ClassMethod;
use PHPStan\Analyser\Scope; use PHPStan\Analyser\Scope;
use PHPStan\Reflection\Php\PhpPropertyReflection; use PHPStan\Reflection\Php\PhpPropertyReflection;
use PHPStan\Type\MixedType; use PHPStan\Type\MixedType;
@ -20,6 +22,7 @@ use Rector\Core\Reflection\ReflectionResolver;
use Rector\Core\ValueObject\PhpVersionFeature; use Rector\Core\ValueObject\PhpVersionFeature;
use Rector\NodeTypeResolver\Node\AttributeKey; use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\PHPStanStaticTypeMapper\Enum\TypeKind; use Rector\PHPStanStaticTypeMapper\Enum\TypeKind;
use Rector\VendorLocker\ParentClassMethodTypeOverrideGuard;
use Rector\VersionBonding\Contract\MinPhpVersionInterface; use Rector\VersionBonding\Contract\MinPhpVersionInterface;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample; use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition; use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
@ -30,7 +33,8 @@ use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
final class ParamTypeFromStrictTypedPropertyRector extends AbstractRector implements MinPhpVersionInterface final class ParamTypeFromStrictTypedPropertyRector extends AbstractRector implements MinPhpVersionInterface
{ {
public function __construct( public function __construct(
private readonly ReflectionResolver $reflectionResolver private readonly ReflectionResolver $reflectionResolver,
private readonly ParentClassMethodTypeOverrideGuard $parentClassMethodTypeOverrideGuard
) { ) {
} }
@ -80,25 +84,29 @@ CODE_SAMPLE
public function refactor(Node $node): ?Node public function refactor(Node $node): ?Node
{ {
$parent = $node->getAttribute(AttributeKey::PARENT_NODE); $parent = $node->getAttribute(AttributeKey::PARENT_NODE);
if (! $parent instanceof FunctionLike) { if (! $parent instanceof ClassMethod) {
return null; return null;
} }
return $this->decorateParamWithType($parent, $node); return $this->decorateParamWithType($parent, $node);
} }
public function decorateParamWithType(FunctionLike $functionLike, Param $param): ?Param public function decorateParamWithType(ClassMethod $classMethod, Param $param): ?Param
{ {
if ($param->type !== null) { if ($param->type !== null) {
return null; return null;
} }
if ($this->parentClassMethodTypeOverrideGuard->hasParentClassMethod($classMethod)) {
return null;
}
$originalParamType = $this->resolveParamOriginalType($param); $originalParamType = $this->resolveParamOriginalType($param);
$paramName = $this->getName($param); $paramName = $this->getName($param);
/** @var Assign[] $assigns */ /** @var Assign[] $assigns */
$assigns = $this->betterNodeFinder->findInstanceOf((array) $functionLike->getStmts(), Assign::class); $assigns = $this->betterNodeFinder->findInstanceOf((array) $classMethod->getStmts(), Assign::class);
foreach ($assigns as $assign) { foreach ($assigns as $assign) {
if (! $this->nodeComparator->areNodesEqual($assign->expr, $param->var)) { if (! $this->nodeComparator->areNodesEqual($assign->expr, $param->var)) {
continue; continue;
@ -130,7 +138,7 @@ CODE_SAMPLE
} }
/** /**
* @return Node\Name|Node\ComplexType|null * @return Name|ComplexType|null
*/ */
private function matchPropertySingleTypeNode(PropertyFetch $propertyFetch): ?Node private function matchPropertySingleTypeNode(PropertyFetch $propertyFetch): ?Node
{ {
@ -140,7 +148,6 @@ CODE_SAMPLE
} }
$propertyType = $phpPropertyReflection->getNativeType(); $propertyType = $phpPropertyReflection->getNativeType();
if ($propertyType instanceof MixedType) { if ($propertyType instanceof MixedType) {
return null; return null;
} }