mirror of
https://github.com/rectorphp/rector.git
synced 2024-06-07 03:40:50 +00:00
[TypeDeclaration] Use @return type on Generator on ReturnTypeDeclarationRector (#1794)
* Add failing test fixture for ReturnTypeDeclarationRector # Failing Test for ReturnTypeDeclarationRector Based on https://getrector.org/demo/1ec89bdc-a24f-68ce-b1af-894c7ad7ac39 * Closes #1792 * phpstan * wrong type generator * return Generator when no return type definition * yield generator * Fixed 🎉 * [ci-review] Rector Rectify * final touch: add Generator example Co-authored-by: Yann Eugoné <eugone.yann@gmail.com> Co-authored-by: GitHub Action <action@github.com>
This commit is contained in:
parent
916adb2637
commit
3720a55f51
|
@ -2,7 +2,7 @@
|
|||
|
||||
namespace Rector\Tests\TypeDeclaration\Rector\ClassMethod\AddArrayReturnDocTypeRector\Fixture;
|
||||
|
||||
final class ReturnYieldIterator
|
||||
final class ReturnYieldGenerator
|
||||
{
|
||||
public function someMethod()
|
||||
{
|
||||
|
@ -16,10 +16,10 @@ final class ReturnYieldIterator
|
|||
|
||||
namespace Rector\Tests\TypeDeclaration\Rector\ClassMethod\AddArrayReturnDocTypeRector\Fixture;
|
||||
|
||||
final class ReturnYieldIterator
|
||||
final class ReturnYieldGenerator
|
||||
{
|
||||
/**
|
||||
* @return \Iterator<string[]>
|
||||
* @return \Generator<string[]>
|
||||
*/
|
||||
public function someMethod()
|
||||
{
|
|
@ -0,0 +1,72 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Tests\TypeDeclaration\Rector\ClassMethod\AddArrayReturnDocTypeRector\Fixture;
|
||||
|
||||
use Generator;
|
||||
use Rector\FileSystemRector\ValueObject\AddedFileWithContent;
|
||||
use Symplify\SmartFileSystem\SmartFileInfo;
|
||||
use Symplify\SmartFileSystem\SmartFileSystem;
|
||||
|
||||
final class UniqueReturnGenerator
|
||||
{
|
||||
public function provideData(): Generator
|
||||
{
|
||||
$smartFileSystem = new SmartFileSystem();
|
||||
|
||||
yield [
|
||||
new SmartFileInfo(__DIR__ . '/Source/Entity/RandomInterface.php'),
|
||||
new AddedFileWithContent(
|
||||
'/Source/Contract/RandomInterface.php',
|
||||
$smartFileSystem->readFile(__DIR__ . '/Expected/ExpectedRandomInterface.php')
|
||||
)
|
||||
];
|
||||
|
||||
yield [
|
||||
new SmartFileInfo(__DIR__ . '/Source/Control/ControlFactory.php'),
|
||||
new AddedFileWithContent(
|
||||
'/Source/Control/ControlFactory.php',
|
||||
$smartFileSystem->readFile(__DIR__ . '/Source/Control/ControlFactory.php')
|
||||
),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\Tests\TypeDeclaration\Rector\ClassMethod\AddArrayReturnDocTypeRector\Fixture;
|
||||
|
||||
use Generator;
|
||||
use Rector\FileSystemRector\ValueObject\AddedFileWithContent;
|
||||
use Symplify\SmartFileSystem\SmartFileInfo;
|
||||
use Symplify\SmartFileSystem\SmartFileSystem;
|
||||
|
||||
final class UniqueReturnGenerator
|
||||
{
|
||||
/**
|
||||
* @return \Generator<\Rector\FileSystemRector\ValueObject\AddedFileWithContent[]|\Symplify\SmartFileSystem\SmartFileInfo[]>
|
||||
*/
|
||||
public function provideData(): Generator
|
||||
{
|
||||
$smartFileSystem = new SmartFileSystem();
|
||||
|
||||
yield [
|
||||
new SmartFileInfo(__DIR__ . '/Source/Entity/RandomInterface.php'),
|
||||
new AddedFileWithContent(
|
||||
'/Source/Contract/RandomInterface.php',
|
||||
$smartFileSystem->readFile(__DIR__ . '/Expected/ExpectedRandomInterface.php')
|
||||
)
|
||||
];
|
||||
|
||||
yield [
|
||||
new SmartFileInfo(__DIR__ . '/Source/Control/ControlFactory.php'),
|
||||
new AddedFileWithContent(
|
||||
'/Source/Control/ControlFactory.php',
|
||||
$smartFileSystem->readFile(__DIR__ . '/Source/Control/ControlFactory.php')
|
||||
),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -20,7 +20,7 @@ namespace Rector\Tests\TypeDeclaration\Rector\ClassMethod\AddArrayReturnDocTypeR
|
|||
class YieldStrings
|
||||
{
|
||||
/**
|
||||
* @return \Iterator<string>
|
||||
* @return \Generator<string>
|
||||
*/
|
||||
public function getValues(): iterable
|
||||
{
|
||||
|
|
|
@ -14,7 +14,7 @@ function iterableFunction($value)
|
|||
|
||||
namespace Rector\Tests\TypeDeclaration\Rector\FunctionLike\ReturnTypeDeclarationRector\Fixture\IterableFunction;
|
||||
|
||||
function iterableFunction($value): \Iterator
|
||||
function iterableFunction($value): \Generator
|
||||
{
|
||||
yield 1;
|
||||
yield 2;
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Tests\TypeDeclaration\Rector\FunctionLike\ReturnTypeDeclarationRector\Fixture;
|
||||
|
||||
final class DemoFile
|
||||
{
|
||||
/**
|
||||
* @return \Generator<int>
|
||||
**/
|
||||
public function generator()
|
||||
{
|
||||
yield 5;
|
||||
}
|
||||
}
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\Tests\TypeDeclaration\Rector\FunctionLike\ReturnTypeDeclarationRector\Fixture;
|
||||
|
||||
final class DemoFile
|
||||
{
|
||||
/**
|
||||
* @return \Generator<int>
|
||||
**/
|
||||
public function generator(): \Generator
|
||||
{
|
||||
yield 5;
|
||||
}
|
||||
}
|
||||
?>
|
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Tests\TypeDeclaration\Rector\FunctionLike\ReturnTypeDeclarationRector\Fixture;
|
||||
|
||||
final class WrongTypeGenerator
|
||||
{
|
||||
/**
|
||||
* @return \wrong
|
||||
**/
|
||||
public function generator()
|
||||
{
|
||||
yield 5;
|
||||
}
|
||||
}
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\Tests\TypeDeclaration\Rector\FunctionLike\ReturnTypeDeclarationRector\Fixture;
|
||||
|
||||
final class WrongTypeGenerator
|
||||
{
|
||||
/**
|
||||
* @return \wrong
|
||||
**/
|
||||
public function generator(): \Generator
|
||||
{
|
||||
yield 5;
|
||||
}
|
||||
}
|
||||
?>
|
|
@ -214,7 +214,7 @@ CODE_SAMPLE
|
|||
return false;
|
||||
}
|
||||
|
||||
return ! $this->isNames($classMethod->returnType, ['array', 'iterable', 'Iterator']);
|
||||
return ! $this->isNames($classMethod->returnType, ['array', 'iterable', 'Iterator', 'Generator']);
|
||||
}
|
||||
|
||||
private function hasArrayShapeNode(ClassMethod $classMethod): bool
|
||||
|
|
|
@ -9,9 +9,11 @@ use PhpParser\Node\Expr;
|
|||
use PhpParser\Node\Expr\Yield_;
|
||||
use PhpParser\Node\Expr\YieldFrom;
|
||||
use PhpParser\Node\FunctionLike;
|
||||
use PhpParser\Node\Name;
|
||||
use PhpParser\NodeTraverser;
|
||||
use PHPStan\Type\MixedType;
|
||||
use PHPStan\Type\Type;
|
||||
use Rector\NodeNameResolver\NodeNameResolver;
|
||||
use Rector\NodeTypeResolver\NodeTypeResolver;
|
||||
use Rector\NodeTypeResolver\PHPStan\Type\TypeFactory;
|
||||
use Rector\StaticTypeMapper\ValueObject\Type\FullyQualifiedGenericObjectType;
|
||||
|
@ -24,7 +26,8 @@ final class YieldNodesReturnTypeInfererTypeInferer implements ReturnTypeInfererI
|
|||
public function __construct(
|
||||
private readonly NodeTypeResolver $nodeTypeResolver,
|
||||
private readonly TypeFactory $typeFactory,
|
||||
private readonly SimpleCallableNodeTraverser $simpleCallableNodeTraverser
|
||||
private readonly SimpleCallableNodeTraverser $simpleCallableNodeTraverser,
|
||||
private readonly NodeNameResolver $nodeNameResolver
|
||||
) {
|
||||
}
|
||||
|
||||
|
@ -51,12 +54,19 @@ final class YieldNodesReturnTypeInfererTypeInferer implements ReturnTypeInfererI
|
|||
$types[] = $resolvedType;
|
||||
}
|
||||
|
||||
$returnType = $functionLike->getReturnType();
|
||||
$className = 'Generator';
|
||||
|
||||
if ($returnType instanceof Name && ! $this->nodeNameResolver->isName($returnType, 'Generator')) {
|
||||
$className = $this->nodeNameResolver->getName($returnType);
|
||||
}
|
||||
|
||||
if ($types === []) {
|
||||
return new FullyQualifiedObjectType('Iterator');
|
||||
return new FullyQualifiedObjectType($className);
|
||||
}
|
||||
|
||||
$types = $this->typeFactory->createMixedPassedOrUnionType($types);
|
||||
return new FullyQualifiedGenericObjectType('Iterator', [$types]);
|
||||
return new FullyQualifiedGenericObjectType($className, [$types]);
|
||||
}
|
||||
|
||||
public function getPriority(): int
|
||||
|
|
Loading…
Reference in New Issue
Block a user