mirror of
https://github.com/rectorphp/rector.git
synced 2024-06-16 16:12:22 +00:00
fix union type on ReturnTypeDeclarationRector
This commit is contained in:
parent
2c3f676191
commit
070c41d7c9
|
@ -6,12 +6,17 @@ namespace Rector\TypeDeclaration\TypeAlreadyAddedChecker;
|
|||
|
||||
use Iterator;
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Identifier;
|
||||
use PhpParser\Node\Name;
|
||||
use PhpParser\Node\NullableType;
|
||||
use PhpParser\Node\Stmt\ClassMethod;
|
||||
use PhpParser\Node\Stmt\Function_;
|
||||
use PhpParser\Node\UnionType as PhpParserUnionType;
|
||||
use PHPStan\Type\ArrayType;
|
||||
use PHPStan\Type\Generic\GenericObjectType;
|
||||
use PHPStan\Type\IntersectionType;
|
||||
use PHPStan\Type\IterableType;
|
||||
use PHPStan\Type\NullType;
|
||||
use PHPStan\Type\ObjectType;
|
||||
use PHPStan\Type\Type;
|
||||
use PHPStan\Type\UnionType;
|
||||
|
@ -57,17 +62,24 @@ final class ReturnTypeAlreadyAddedChecker
|
|||
*/
|
||||
public function isReturnTypeAlreadyAdded(Node $node, Type $returnType): bool
|
||||
{
|
||||
$returnNode = $this->staticTypeMapper->mapPHPStanTypeToPhpParserNode($returnType);
|
||||
if ($node->returnType === null) {
|
||||
$nodeReturnType = $node->returnType;
|
||||
|
||||
/** @param Identifier|Name|NullableType|PhpParserUnionType|null $returnTypeNode */
|
||||
if ($nodeReturnType === null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($this->betterStandardPrinter->areNodesEqual($node->returnType, $returnNode)) {
|
||||
$returnNode = $this->staticTypeMapper->mapPHPStanTypeToPhpParserNode($returnType);
|
||||
if ($this->betterStandardPrinter->areNodesEqual($nodeReturnType, $returnNode)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// is array <=> iterable <=> Iterator co-type? → skip
|
||||
if ($this->isArrayIterableIteratorCoType($node, $returnType)) {
|
||||
if ($this->isArrayIterableIteratorCoType($nodeReturnType, $returnType)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($this->isUnionCoType($nodeReturnType, $returnType)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -87,9 +99,12 @@ final class ReturnTypeAlreadyAddedChecker
|
|||
return false;
|
||||
}
|
||||
|
||||
private function isArrayIterableIteratorCoType(Node $node, Type $returnType): bool
|
||||
/**
|
||||
* @param Identifier|Name|NullableType|PhpParserUnionType $returnTypeNode
|
||||
*/
|
||||
private function isArrayIterableIteratorCoType(Node $returnTypeNode, Type $returnType): bool
|
||||
{
|
||||
if (! $this->nodeNameResolver->isNames($node->returnType, self::FOREACHABLE_TYPES)) {
|
||||
if (! $this->nodeNameResolver->isNames($returnTypeNode, self::FOREACHABLE_TYPES)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -127,4 +142,23 @@ final class ReturnTypeAlreadyAddedChecker
|
|||
|
||||
return $type instanceof ObjectType && $type->getClassName() === Iterator::class;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Identifier|Name|NullableType|PhpParserUnionType $returnTypeNode
|
||||
*/
|
||||
private function isUnionCoType(Node $returnTypeNode, Type $type): bool
|
||||
{
|
||||
if (! $type instanceof UnionType) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// skip nullable type
|
||||
$nullType = new NullType();
|
||||
if ($type->isSuperTypeOf($nullType)->yes()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$classMethodReturnType = $this->staticTypeMapper->mapPhpParserNodePHPStanType($returnTypeNode);
|
||||
return $type->isSuperTypeOf($classMethodReturnType)->yes();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\TypeDeclaration\Tests\Rector\ClassMethod\ReturnTypeDeclarationRector\Fixture;
|
||||
|
||||
class Response
|
||||
{
|
||||
}
|
||||
|
||||
final class RedirectResponse extends Response
|
||||
{
|
||||
}
|
||||
|
||||
final class SkipParentAndChild
|
||||
{
|
||||
public function run(bool $response): Response
|
||||
{
|
||||
if ($response) {
|
||||
return new RedirectResponse;
|
||||
}
|
||||
|
||||
return new Response;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user