Skip to content

Commit

Permalink
[Php74] Handle Generic Type on TypedPropertyRector (#6378)
Browse files Browse the repository at this point in the history
Co-authored-by: Ruud Kamphuis <ruudk@users.noreply.github.com>
Co-authored-by: kaizen-ci <info@kaizen-ci.org>
  • Loading branch information
3 people committed May 7, 2021
1 parent 85c8756 commit 6bae025
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 15 deletions.
Original file line number Diff line number Diff line change
@@ -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;
}
}
?>
54 changes: 39 additions & 15 deletions rules/Php74/Rector/Property/TypedPropertyRector.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
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;
Expand Down Expand Up @@ -149,26 +150,23 @@ public function refactor(Node $node): ?Node
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;
}

Expand All @@ -186,6 +184,32 @@ public function configure(array $configuration): void
$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
*/
Expand Down

0 comments on commit 6bae025

Please sign in to comment.