mirror of
https://github.com/rectorphp/rector.git
synced 2025-01-18 05:48:21 +01:00
[Php74] Handle Generic Type on TypedPropertyRector (#6378)
Co-authored-by: Ruud Kamphuis <ruudk@users.noreply.github.com> Co-authored-by: kaizen-ci <info@kaizen-ci.org>
This commit is contained in:
parent
85c87561aa
commit
6bae0256e3
@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
namespace Rector\Php74\Tests\Rector\Property\TypedPropertyRector\Fixture;
|
||||
|
||||
/**
|
||||
* @template T of object
|
||||
*/
|
||||
final class GenericObjectType
|
||||
{
|
||||
/**
|
||||
* @var T
|
||||
*/
|
||||
private $command;
|
||||
|
||||
/**
|
||||
* @param T $command
|
||||
*/
|
||||
public function __construct(object $command)
|
||||
{
|
||||
$this->command = $command;
|
||||
}
|
||||
}
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\Php74\Tests\Rector\Property\TypedPropertyRector\Fixture;
|
||||
|
||||
/**
|
||||
* @template T of object
|
||||
*/
|
||||
final class GenericObjectType
|
||||
{
|
||||
/**
|
||||
* @var T
|
||||
*/
|
||||
private object $command;
|
||||
|
||||
/**
|
||||
* @param T $command
|
||||
*/
|
||||
public function __construct(object $command)
|
||||
{
|
||||
$this->command = $command;
|
||||
}
|
||||
}
|
||||
?>
|
@ -10,6 +10,7 @@ use PhpParser\Node\NullableType;
|
||||
use PhpParser\Node\Stmt\Property;
|
||||
use PhpParser\Node\UnionType as PhpParserUnionType;
|
||||
use PHPStan\Reflection\ReflectionProvider;
|
||||
use PHPStan\Type\Generic\TemplateType;
|
||||
use PHPStan\Type\MixedType;
|
||||
use PHPStan\Type\NullType;
|
||||
use PHPStan\Type\Type;
|
||||
@ -149,26 +150,23 @@ CODE_SAMPLE
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($varType instanceof UnionType) {
|
||||
$types = $varType->getTypes();
|
||||
if (count($types) === 2 && $types[0] instanceof TemplateType) {
|
||||
$node->type = $this->staticTypeMapper->mapPHPStanTypeToPhpParserNode(
|
||||
$types[0]->getBound(),
|
||||
TypeKind::KIND_PROPERTY
|
||||
);
|
||||
return $node;
|
||||
}
|
||||
}
|
||||
|
||||
$propertyTypeNode = $this->staticTypeMapper->mapPHPStanTypeToPhpParserNode(
|
||||
$varType,
|
||||
TypeKind::KIND_PROPERTY
|
||||
);
|
||||
|
||||
if (! $propertyTypeNode instanceof Node) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// is not class-type and should be skipped
|
||||
if ($this->shouldSkipNonClassLikeType($propertyTypeNode)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// false positive
|
||||
if ($propertyTypeNode instanceof Name && $this->isName($propertyTypeNode, 'mixed')) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($this->vendorLockResolver->isPropertyTypeChangeVendorLockedIn($node)) {
|
||||
if ($this->isNullOrNonClassLikeTypeOrMixedOrVendorLockedIn($propertyTypeNode, $node)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -186,6 +184,32 @@ CODE_SAMPLE
|
||||
$this->classLikeTypeOnly = $configuration[self::CLASS_LIKE_TYPE_ONLY] ?? false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Name|NullableType|PhpParserUnionType|null $node
|
||||
*/
|
||||
private function isNullOrNonClassLikeTypeOrMixedOrVendorLockedIn(?Node $node, Property $property): bool
|
||||
{
|
||||
if (! $node instanceof Node) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// is not class-type and should be skipped
|
||||
if ($this->shouldSkipNonClassLikeType($node)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// false positive
|
||||
if (! $node instanceof Name) {
|
||||
return $this->vendorLockResolver->isPropertyTypeChangeVendorLockedIn($property);
|
||||
}
|
||||
|
||||
if (! $this->isName($node, 'mixed')) {
|
||||
return $this->vendorLockResolver->isPropertyTypeChangeVendorLockedIn($property);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Name|NullableType|PhpParserUnionType $node
|
||||
*/
|
||||
|
Loading…
x
Reference in New Issue
Block a user