Skip to content

Commit

Permalink
[Php80] Handle Iterable typed on ClassPropertyAssignToConstructorProm…
Browse files Browse the repository at this point in the history
…otionRector (#753)

Co-authored-by: Jáchym Toušek <enumag@gmail.com>
  • Loading branch information
samsonasik and enumag committed Aug 25, 2021
1 parent f78ffe3 commit aa22210
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 16 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

namespace Rector\Tests\Php80\Rector\Class_\ClassPropertyAssignToConstructorPromotionRector\Fixture;

class IterableTyped
{
/**
* @var iterable<string>
*/
private iterable $property;

/**
* @param iterable<string> $property
*/
public function __construct(iterable $property)
{
$this->property = $property;
}
}
?>
-----
<?php

namespace Rector\Tests\Php80\Rector\Class_\ClassPropertyAssignToConstructorPromotionRector\Fixture;

class IterableTyped
{
/**
* @param iterable<string> $property
*/
public function __construct(private iterable $property)
{
}
}
?>
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

namespace Rector\Tests\Php80\Rector\Class_\ClassPropertyAssignToConstructorPromotionRector\Fixture;

use stdClass;
use DateTime;

final class UnionTyped
{
public stdClass|DateTime $property;

public function __construct(stdClass|DateTime $property)
{
$this->property = $property;
}
}

?>
-----
<?php

namespace Rector\Tests\Php80\Rector\Class_\ClassPropertyAssignToConstructorPromotionRector\Fixture;

use stdClass;
use DateTime;

final class UnionTyped
{
public function __construct(public stdClass|DateTime $property)
{
}
}

?>
32 changes: 16 additions & 16 deletions rules/Php80/NodeAnalyzer/PromotedPropertyCandidateResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
use PhpParser\Node\Stmt\Expression;
use PhpParser\Node\Stmt\Property;
use PHPStan\Type\Generic\TemplateType;
use PHPStan\Type\MixedType;
use PHPStan\Type\Type;
use PHPStan\Type\UnionType;
use Rector\Core\PhpParser\Comparing\NodeComparator;
Expand All @@ -23,7 +24,6 @@
use Rector\NodeTypeResolver\PHPStan\Type\TypeFactory;
use Rector\NodeTypeResolver\TypeComparator\TypeComparator;
use Rector\Php80\ValueObject\PropertyPromotionCandidate;
use Rector\StaticTypeMapper\ValueObject\Type\FullyQualifiedObjectType;
use Rector\TypeDeclaration\TypeInferer\PropertyTypeInferer;

final class PromotedPropertyCandidateResolver
Expand Down Expand Up @@ -185,37 +185,37 @@ private function hasConflictingParamType(Param $param, Type $propertyType): bool
);
}

$isAllFullyQualifiedObjectType = true;
if ($propertyType instanceof UnionType) {
if ($this->hasGenericTemplateType($propertyType)) {
return false;
}
if (! $propertyType instanceof UnionType) {
return false;
}

$isAllFullyQualifiedObjectType = ! $this->hasNonFullyQualifiedObjectType($propertyType);
if ($this->typeComparator->areTypesEqual($propertyType, $matchedParamType)) {
return false;
}

// different types, not a good to fit
return ! $isAllFullyQualifiedObjectType && ! $this->typeComparator->areTypesEqual(
$propertyType,
$matchedParamType
);
// different types, check not has mixed and not has templated generic types
if (! $this->hasMixedType($propertyType)) {
return false;
}

return ! $this->hasTemplatedGenericType($propertyType);
}

private function hasNonFullyQualifiedObjectType(UnionType $unionType): bool
private function hasTemplatedGenericType(UnionType $unionType): bool
{
foreach ($unionType->getTypes() as $type) {
if (! $type instanceof FullyQualifiedObjectType) {
if ($type instanceof TemplateType) {
return true;
}
}

return false;
}

private function hasGenericTemplateType(UnionType $unionType): bool
private function hasMixedType(UnionType $unionType): bool
{
foreach ($unionType->getTypes() as $type) {
if ($type instanceof TemplateType) {
if ($type instanceof MixedType) {
return true;
}
}
Expand Down

0 comments on commit aa22210

Please sign in to comment.