Skip to content

Commit

Permalink
[TypeDeclaration] Add ReturnUnionTypeRector (#4655)
Browse files Browse the repository at this point in the history
Co-authored-by: GitHub Action <actions@github.com>
  • Loading branch information
samsonasik and actions-user committed Aug 5, 2023
1 parent 75e46c2 commit 9b03d83
Show file tree
Hide file tree
Showing 17 changed files with 368 additions and 10 deletions.
34 changes: 30 additions & 4 deletions build/target-repository/docs/rector_rules_overview.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# 363 Rules Overview
# 364 Rules Overview

<br>

Expand Down Expand Up @@ -52,7 +52,7 @@

- [Transform](#transform) (22)

- [TypeDeclaration](#typedeclaration) (44)
- [TypeDeclaration](#typedeclaration) (45)

- [Visibility](#visibility) (3)

Expand Down Expand Up @@ -4855,8 +4855,7 @@ Change `money_format()` to equivalent `number_format()`

```diff
-$value = money_format('%i', $value);
+$roundedValue = round($value, 2, PHP_ROUND_HALF_ODD);
+$value = number_format($roundedValue, 2, '.', '');
+$value = number_format(round($value, 2, PHP_ROUND_HALF_ODD), 2, '.', '');
```

<br>
Expand Down Expand Up @@ -8186,6 +8185,33 @@ Add return method return type based on strict typed property

<br>

### ReturnUnionTypeRector

Add union return type

- class: [`Rector\TypeDeclaration\Rector\ClassMethod\ReturnUnionTypeRector`](../rules/TypeDeclaration/Rector/ClassMethod/ReturnUnionTypeRector.php)

```diff
final class SomeClass
{
- public function getData()
+ public function getData(): null|\DateTime|\stdClass
{
if (rand(0, 1)) {
return null;
}

if (rand(0, 1)) {
return new DateTime('now');
}

return new stdClass;
}
}
```

<br>

### StrictArrayParamDimFetchRector

Add array type based on array dim fetch use
Expand Down
2 changes: 2 additions & 0 deletions config/set/type-declaration.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
use Rector\TypeDeclaration\Rector\ClassMethod\ReturnTypeFromStrictParamRector;
use Rector\TypeDeclaration\Rector\ClassMethod\ReturnTypeFromStrictTypedCallRector;
use Rector\TypeDeclaration\Rector\ClassMethod\ReturnTypeFromStrictTypedPropertyRector;
use Rector\TypeDeclaration\Rector\ClassMethod\ReturnUnionTypeRector;
use Rector\TypeDeclaration\Rector\ClassMethod\StrictArrayParamDimFetchRector;
use Rector\TypeDeclaration\Rector\ClassMethod\StrictStringParamConcatRector;
use Rector\TypeDeclaration\Rector\Empty_\EmptyOnNullableObjectToInstanceOfRector;
Expand Down Expand Up @@ -79,6 +80,7 @@
BoolReturnTypeFromStrictScalarReturnsRector::class,
NumericReturnTypeFromStrictScalarReturnsRector::class,
StrictArrayParamDimFetchRector::class,
ReturnUnionTypeRector::class,
]);
$rectorConfig->rule(StrictStringParamConcatRector::class);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php

namespace Rector\Tests\TypeDeclaration\Rector\ClassMethod\ReturnUnionTypeRector\Fixture;

use stdClass;

final class NullableUnion
{
public function run()
{
if (rand(0, 1)) {
return null;
}

return new stdClass;
}
}

?>
-----
<?php

namespace Rector\Tests\TypeDeclaration\Rector\ClassMethod\ReturnUnionTypeRector\Fixture;

use stdClass;

final class NullableUnion
{
public function run(): ?\stdClass
{
if (rand(0, 1)) {
return null;
}

return new stdClass;
}
}

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

namespace Rector\Tests\TypeDeclaration\Rector\ClassMethod\ReturnUnionTypeRector\Fixture;

use stdClass;

final class SkipDocblock
{
/**
* @return null|stdClass
*/
public function run()
{
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

namespace Rector\Tests\TypeDeclaration\Rector\ClassMethod\ReturnUnionTypeRector\Fixture;

final class SkipMixedNull
{
public function run(mixed $param)
{
if (rand(0, 1)) {
return $param;
}

return null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

namespace Rector\Tests\TypeDeclaration\Rector\ClassMethod\ReturnUnionTypeRector\Fixture;

use stdClass;

final class SkipNonUnionType
{
public function run()
{
$stdClass = new stdClass;

if (rand(0, 1)) {
$stdClass->foo = 1;
return $stdClass;
}

if (rand(0, 1)) {
$stdClass->bar = 1;
return $stdClass;
}

return $stdClass;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

namespace Rector\Tests\TypeDeclaration\Rector\ClassMethod\ReturnUnionTypeRector\Fixture;

use stdClass;

final class SkipPossibleVoid
{
public function run()
{
$stdClass = new stdClass;

if (rand(0, 1)) {
$stdClass->foo = 1;
return $stdClass;
}

if (rand(0, 1)) {
$stdClass->bar = 1;
return $stdClass;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<?php

namespace Rector\Tests\TypeDeclaration\Rector\ClassMethod\ReturnUnionTypeRector\Fixture;

use DateTime;
use stdClass;

final class UnionMulti
{
public function run()
{
if (rand(0, 1)) {
return null;
}

if (rand(0, 1)) {
return new DateTime('now');
}

return new stdClass;
}
}

?>
-----
<?php

namespace Rector\Tests\TypeDeclaration\Rector\ClassMethod\ReturnUnionTypeRector\Fixture;

use DateTime;
use stdClass;

final class UnionMulti
{
public function run(): null|\DateTime|\stdClass
{
if (rand(0, 1)) {
return null;
}

if (rand(0, 1)) {
return new DateTime('now');
}

return new stdClass;
}
}

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

declare(strict_types=1);

namespace Rector\Tests\TypeDeclaration\Rector\ClassMethod\ReturnUnionTypeRector;

use Iterator;
use PHPUnit\Framework\Attributes\DataProvider;
use Rector\Testing\PHPUnit\AbstractRectorTestCase;

final class ReturnUnionTypeRectorTest extends AbstractRectorTestCase
{
#[DataProvider('provideData')]
public function test(string $filePath): void
{
$this->doTestFile($filePath);
}

public static function provideData(): Iterator
{
return self::yieldFilesFromDirectory(__DIR__ . '/Fixture');
}

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

declare(strict_types=1);

use Rector\Config\RectorConfig;
use Rector\TypeDeclaration\Rector\ClassMethod\ReturnUnionTypeRector;

return static function (RectorConfig $rectorConfig): void {
$rectorConfig->rule(ReturnUnionTypeRector::class);
};
2 changes: 1 addition & 1 deletion rules/CodeQuality/Rector/FuncCall/SetTypeToCastRector.php
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ public function getNodeTypes(): array
/**
* @param FuncCall|Expression|Assign|Expr\ArrayItem|Node\Arg $node
*/
public function refactor(Node $node)
public function refactor(Node $node): null|int|Expression|Assign|Cast
{
if ($node instanceof Arg || $node instanceof ArrayItem) {
if ($this->isSetTypeFuncCall($node->value)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ public function getNodeTypes(): array
/**
* @param StmtsAwareInterface $node
*/
public function refactor(Node $node)
public function refactor(Node $node): ?StmtsAwareInterface
{
if ($node->stmts === null) {
return null;
Expand Down
4 changes: 3 additions & 1 deletion rules/Php72/Rector/Assign/ListEachRector.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use PhpParser\Node\Expr\Assign;
use PhpParser\Node\Expr\FuncCall;
use PhpParser\Node\Expr\List_;
use PhpParser\Node\Stmt;
use PhpParser\Node\Stmt\Expression;
use Rector\Core\Exception\ShouldNotHappenException;
use Rector\Core\NodeManipulator\AssignManipulator;
Expand Down Expand Up @@ -65,8 +66,9 @@ public function getNodeTypes(): array

/**
* @param Expression $node
* @return null|Expression|Stmt[]
*/
public function refactor(Node $node)
public function refactor(Node $node): null|Expression|array
{
if (! $node->expr instanceof Assign) {
return null;
Expand Down
2 changes: 1 addition & 1 deletion rules/Php81/Rector/Array_/FirstClassCallableRector.php
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ public function getNodeTypes(): array
/**
* @param Array_ $node
*/
public function refactorWithScope(Node $node, Scope $scope)
public function refactorWithScope(Node $node, Scope $scope): null|StaticCall|MethodCall
{
$arrayCallable = $this->arrayCallableMethodMatcher->match($node, $scope);
if (! $arrayCallable instanceof ArrayCallable) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ public function getNodeTypes(): array
/**
* @param Class_ $node
*/
public function refactor(Node $node)
public function refactor(Node $node): ?Node
{
if (! $this->testsNodeAnalyzer->isInTestClass($node)) {
return null;
Expand Down
Loading

0 comments on commit 9b03d83

Please sign in to comment.