mirror of
https://github.com/rectorphp/rector.git
synced 2024-06-07 20:00:50 +00:00
[Php80] Handle Generic TemplateType on ClassPropertyAssignToConstructorPromotionRector (#751)
* Add failing test fixture for ClassPropertyAssignToConstructorPromotionRector # Failing Test for ClassPropertyAssignToConstructorPromotionRector Based on https://getrector.org/demo/1ec04a84-bde1-6cb0-a397-d7c0f606a738 * Closes #749 * naming * phpstan * early check is param used before assign Co-authored-by: Jáchym Toušek <enumag@gmail.com>
This commit is contained in:
parent
6ff80ba037
commit
885ef768e5
|
@ -0,0 +1,41 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Tests\Php80\Rector\Class_\ClassPropertyAssignToConstructorPromotionRector\Fixture;
|
||||
|
||||
/**
|
||||
* @template T
|
||||
*/
|
||||
final class Generic
|
||||
{
|
||||
/**
|
||||
* @var T
|
||||
*/
|
||||
public mixed $value;
|
||||
|
||||
/**
|
||||
* @param T $value
|
||||
*/
|
||||
public function __construct(mixed $value)
|
||||
{
|
||||
$this->value = $value;
|
||||
}
|
||||
}
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\Tests\Php80\Rector\Class_\ClassPropertyAssignToConstructorPromotionRector\Fixture;
|
||||
|
||||
/**
|
||||
* @template T
|
||||
*/
|
||||
final class Generic
|
||||
{
|
||||
/**
|
||||
* @param T $value
|
||||
*/
|
||||
public function __construct(public mixed $value)
|
||||
{
|
||||
}
|
||||
}
|
||||
?>
|
|
@ -12,6 +12,7 @@ use PhpParser\Node\Stmt\Class_;
|
|||
use PhpParser\Node\Stmt\ClassMethod;
|
||||
use PhpParser\Node\Stmt\Expression;
|
||||
use PhpParser\Node\Stmt\Property;
|
||||
use PHPStan\Type\Generic\TemplateType;
|
||||
use PHPStan\Type\Type;
|
||||
use PHPStan\Type\UnionType;
|
||||
use Rector\Core\PhpParser\Comparing\NodeComparator;
|
||||
|
@ -186,12 +187,11 @@ final class PromotedPropertyCandidateResolver
|
|||
|
||||
$isAllFullyQualifiedObjectType = true;
|
||||
if ($propertyType instanceof UnionType) {
|
||||
foreach ($propertyType->getTypes() as $type) {
|
||||
if (! $type instanceof FullyQualifiedObjectType) {
|
||||
$isAllFullyQualifiedObjectType = false;
|
||||
break;
|
||||
}
|
||||
if ($this->hasGenericTemplateType($propertyType)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$isAllFullyQualifiedObjectType = ! $this->hasNonFullyQualifiedObjectType($propertyType);
|
||||
}
|
||||
|
||||
// different types, not a good to fit
|
||||
|
@ -201,6 +201,28 @@ final class PromotedPropertyCandidateResolver
|
|||
);
|
||||
}
|
||||
|
||||
private function hasNonFullyQualifiedObjectType(UnionType $unionType): bool
|
||||
{
|
||||
foreach ($unionType->getTypes() as $type) {
|
||||
if (! $type instanceof FullyQualifiedObjectType) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private function hasGenericTemplateType(UnionType $unionType): bool
|
||||
{
|
||||
foreach ($unionType->getTypes() as $type) {
|
||||
if ($type instanceof TemplateType) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int[] $firstParamAsVariable
|
||||
*/
|
||||
|
@ -215,12 +237,12 @@ final class PromotedPropertyCandidateResolver
|
|||
return true;
|
||||
}
|
||||
|
||||
// @todo unknown type, not suitable?
|
||||
$propertyType = $this->propertyTypeInferer->inferProperty($property);
|
||||
if ($this->hasConflictingParamType($matchedParam, $propertyType)) {
|
||||
if ($this->isParamUsedBeforeAssign($assignedVariable, $firstParamAsVariable)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return $this->isParamUsedBeforeAssign($assignedVariable, $firstParamAsVariable);
|
||||
// @todo unknown type, not suitable?
|
||||
$propertyType = $this->propertyTypeInferer->inferProperty($property);
|
||||
return $this->hasConflictingParamType($matchedParam, $propertyType);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user