mirror of
https://github.com/rectorphp/rector.git
synced 2025-02-13 20:36:23 +01:00
[TypeDeclaration] Prevent array-iterable-Iterator override in ReturnTypeDeclarationRector
This commit is contained in:
parent
6c8f13a8b5
commit
d6d337e85e
@ -2,12 +2,18 @@
|
|||||||
|
|
||||||
namespace Rector\TypeDeclaration\Rector\FunctionLike;
|
namespace Rector\TypeDeclaration\Rector\FunctionLike;
|
||||||
|
|
||||||
|
use Iterator;
|
||||||
use PhpParser\Node;
|
use PhpParser\Node;
|
||||||
use PhpParser\Node\Stmt\ClassLike;
|
use PhpParser\Node\Stmt\ClassLike;
|
||||||
use PhpParser\Node\Stmt\ClassMethod;
|
use PhpParser\Node\Stmt\ClassMethod;
|
||||||
use PhpParser\Node\Stmt\Function_;
|
use PhpParser\Node\Stmt\Function_;
|
||||||
|
use PHPStan\Type\ArrayType;
|
||||||
|
use PHPStan\Type\IntersectionType;
|
||||||
|
use PHPStan\Type\IterableType;
|
||||||
use PHPStan\Type\MixedType;
|
use PHPStan\Type\MixedType;
|
||||||
|
use PHPStan\Type\ObjectType;
|
||||||
use PHPStan\Type\Type;
|
use PHPStan\Type\Type;
|
||||||
|
use PHPStan\Type\UnionType;
|
||||||
use Rector\Exception\ShouldNotHappenException;
|
use Rector\Exception\ShouldNotHappenException;
|
||||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||||
use Rector\RectorDefinition\CodeSample;
|
use Rector\RectorDefinition\CodeSample;
|
||||||
@ -230,7 +236,12 @@ PHP
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->print($node->returnType) === $this->print($returnNode)) {
|
if ($this->areNodesEqual($node->returnType, $returnNode)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// is array <=> iterable <=> Iterator co-type? → skip
|
||||||
|
if ($this->isArrayIterableIteratorCoType($node, $returnType)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -244,4 +255,42 @@ PHP
|
|||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function isStaticTypeIterable(Type $type): bool
|
||||||
|
{
|
||||||
|
if ($type instanceof ArrayType) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($type instanceof IterableType) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($type instanceof ObjectType) {
|
||||||
|
if ($type->getClassName() === Iterator::class) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($type instanceof UnionType || $type instanceof IntersectionType) {
|
||||||
|
foreach ($type->getTypes() as $joinedType) {
|
||||||
|
if (! $this->isStaticTypeIterable($joinedType)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function isArrayIterableIteratorCoType(Node $node, Type $returnType): bool
|
||||||
|
{
|
||||||
|
if (! $this->isNames($node->returnType, ['iterable', 'Iterator', 'array'])) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->isStaticTypeIterable($returnType);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,13 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Rector\TypeDeclaration\Tests\Rector\ClassMethod\ReturnTypeDeclarationRector\Fixture;
|
||||||
|
|
||||||
|
use Iterator;
|
||||||
|
|
||||||
|
class SkipIterableArrayIteratorCoType
|
||||||
|
{
|
||||||
|
public function run(): Iterator
|
||||||
|
{
|
||||||
|
yield 5;
|
||||||
|
}
|
||||||
|
}
|
@ -60,6 +60,8 @@ final class ReturnTypeDeclarationRectorTest extends AbstractRectorTestCase
|
|||||||
yield [__DIR__ . '/Fixture/dunglas/nullable_types.php.inc'];
|
yield [__DIR__ . '/Fixture/dunglas/nullable_types.php.inc'];
|
||||||
// anonymous class
|
// anonymous class
|
||||||
yield [__DIR__ . '/Fixture/a_new_class.php.inc'];
|
yield [__DIR__ . '/Fixture/a_new_class.php.inc'];
|
||||||
|
|
||||||
|
yield [__DIR__ . '/Fixture/skip_iterable_array_iterator_co_type.php.inc'];
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getRectorClass(): string
|
protected function getRectorClass(): string
|
||||||
|
Loading…
x
Reference in New Issue
Block a user