Skip to content

Commit

Permalink
[TypeDeclaration] Add AddArrowFunctionReturnTypeRector (#2933)
Browse files Browse the repository at this point in the history
* [TypeDeclaration] Add AddArrowFunctionReturnTypeRector

* [ci-review] Rector Rectify

* [ci-review] Rector Rectify

* final touch: clean up

* final touch: clean up

* final touch: test for return declaration exists

* fix min php version

Co-authored-by: GitHub Action <action@github.com>
  • Loading branch information
samsonasik and actions-user committed Sep 17, 2022
1 parent 5cd60b2 commit 6d44ff7
Show file tree
Hide file tree
Showing 9 changed files with 224 additions and 0 deletions.
2 changes: 2 additions & 0 deletions config/set/type-declaration.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
declare(strict_types=1);

use Rector\Config\RectorConfig;
use Rector\TypeDeclaration\Rector\ArrowFunction\AddArrowFunctionReturnTypeRector;
use Rector\TypeDeclaration\Rector\ClassMethod\AddArrayParamDocTypeRector;
use Rector\TypeDeclaration\Rector\ClassMethod\AddArrayReturnDocTypeRector;
use Rector\TypeDeclaration\Rector\ClassMethod\AddReturnTypeDeclarationBasedOnParentClassMethodRector;
Expand All @@ -22,6 +23,7 @@
ReturnTypeDeclarationRector::class,
PropertyTypeDeclarationRector::class,
AddClosureReturnTypeRector::class,
AddArrowFunctionReturnTypeRector::class,
AddArrayParamDocTypeRector::class,
AddArrayReturnDocTypeRector::class,
ParamTypeByMethodCallTypeRector::class,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

declare(strict_types=1);

namespace Rector\Tests\TypeDeclaration\Rector\ArrowFunction\AddArrowFunctionReturnTypeRector;

use Iterator;
use Rector\Testing\PHPUnit\AbstractRectorTestCase;

final class AddArrowFunctionReturnTypeRectorTest extends AbstractRectorTestCase
{
/**
* @dataProvider provideData()
*/
public function test(string $filePath): void
{
$this->doTestFile($filePath);
}

/**
* @return Iterator<array<string>>
*/
public function provideData(): Iterator
{
return $this->yieldFilesFromDirectory(__DIR__ . '/Fixture');
}

public function provideConfigFilePath(): string
{
return __DIR__ . '/config/before_union_types.php';
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

namespace Rector\Tests\TypeDeclaration\Rector\Closure\AddClosureReturnTypeRector\Fixture;

class Fixture
{
public function run()
{
fn () => rand(0, 1) ? []: null;
}
}

?>
-----
<?php

namespace Rector\Tests\TypeDeclaration\Rector\Closure\AddClosureReturnTypeRector\Fixture;

class Fixture
{
public function run()
{
fn (): ?array => rand(0, 1) ? []: null;
}
}

?>
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

namespace Rector\Tests\TypeDeclaration\Rector\Closure\AddClosureReturnTypeRector\Fixture;

class SkipReturnDeclarationExists
{
public function run()
{
fn (): array => [];
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

namespace Rector\Tests\TypeDeclaration\Rector\Closure\AddClosureReturnTypeRector\FixturePhp80;

class Fixture
{
public function run()
{
fn () => rand(0, 1) ? true : (rand(0, 1) ? [] : 0);
}
}

?>
-----
<?php

namespace Rector\Tests\TypeDeclaration\Rector\Closure\AddClosureReturnTypeRector\FixturePhp80;

class Fixture
{
public function run()
{
fn (): array|bool|int => rand(0, 1) ? true : (rand(0, 1) ? [] : 0);
}
}

?>
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

declare(strict_types=1);

namespace Rector\Tests\TypeDeclaration\Rector\ArrowFunction\AddArrowFunctionReturnTypeRector;

use Iterator;
use Rector\Testing\PHPUnit\AbstractRectorTestCase;

final class Php80Test extends AbstractRectorTestCase
{
/**
* @dataProvider provideData()
*/
public function test(string $filePath): void
{
$this->doTestFile($filePath);
}

/**
* @return Iterator<array<string>>
*/
public function provideData(): Iterator
{
return $this->yieldFilesFromDirectory(__DIR__ . '/FixturePhp80');
}

public function provideConfigFilePath(): string
{
return __DIR__ . '/config/union_types.php';
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php

declare(strict_types=1);

use Rector\Config\RectorConfig;
use Rector\Core\ValueObject\PhpVersionFeature;
use Rector\TypeDeclaration\Rector\ArrowFunction\AddArrowFunctionReturnTypeRector;

return static function (RectorConfig $rectorConfig): void {
$rectorConfig->phpVersion(PhpVersionFeature::UNION_TYPES - 1);
$rectorConfig->rule(AddArrowFunctionReturnTypeRector::class);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php

declare(strict_types=1);

use Rector\Config\RectorConfig;
use Rector\Core\ValueObject\PhpVersionFeature;
use Rector\TypeDeclaration\Rector\ArrowFunction\AddArrowFunctionReturnTypeRector;

return static function (RectorConfig $rectorConfig): void {
$rectorConfig->phpVersion(PhpVersionFeature::UNION_TYPES);
$rectorConfig->rule(AddArrowFunctionReturnTypeRector::class);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<?php

declare(strict_types=1);

namespace Rector\TypeDeclaration\Rector\ArrowFunction;

use PhpParser\Node;
use PhpParser\Node\Expr\ArrowFunction;
use Rector\Core\Rector\AbstractRector;
use Rector\Core\ValueObject\PhpVersionFeature;
use Rector\PHPStanStaticTypeMapper\Enum\TypeKind;
use Rector\VersionBonding\Contract\MinPhpVersionInterface;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;

/**
* @see \Rector\Tests\TypeDeclaration\Rector\ArrowFunction\AddArrowFunctionReturnTypeRector\AddArrowFunctionReturnTypeRectorTest
*/
final class AddArrowFunctionReturnTypeRector extends AbstractRector implements MinPhpVersionInterface
{
public function getRuleDefinition(): RuleDefinition
{
return new RuleDefinition('Add known return type to arrow function', [
new CodeSample(
<<<'CODE_SAMPLE'
fn () => [];
CODE_SAMPLE
,
<<<'CODE_SAMPLE'
fn (): array => [];
CODE_SAMPLE
),
]);
}

/**
* @return array<class-string<Node>>
*/
public function getNodeTypes(): array
{
return [ArrowFunction::class];
}

/**
* @param ArrowFunction $node
*/
public function refactor(Node $node): ?Node
{
if ($node->returnType !== null) {
return null;
}

$type = $this->getType($node->expr);
$returnTypeNode = $this->staticTypeMapper->mapPHPStanTypeToPhpParserNode($type, TypeKind::RETURN);

if ($returnTypeNode === null) {
return null;
}

$node->returnType = $returnTypeNode;

return $node;
}

public function provideMinPhpVersion(): int
{
return PhpVersionFeature::ARROW_FUNCTION;
}
}

0 comments on commit 6d44ff7

Please sign in to comment.