Skip to content

Commit 8c66667

Browse files
authored
[CodeQuality] Skip with if on YieldDataProviderRector with yield from and return (#557)
* YieldDataProviderRector: Added failling test * fix * Update skip_yield_from_with_return.php.inc * added another test * Update YieldDataProviderRector.php * rector * Update YieldDataProviderRector.php * skip multiple yield from * run rector * run rector
1 parent eb751d4 commit 8c66667

File tree

4 files changed

+140
-4
lines changed

4 files changed

+140
-4
lines changed
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
<?php
2+
3+
namespace Rector\PHPUnit\Tests\CodeQuality\Rector\Class_\YieldDataProviderRector\Fixture;
4+
5+
use PHPUnit\Framework\TestCase;
6+
7+
final class MultiStmtsReturnTest extends TestCase
8+
{
9+
#[\PHPUnit\Framework\Attributes\DataProvider('dataProvider')]
10+
public function test(string $val1, string $val2): void
11+
{
12+
}
13+
14+
public static function dataProvider(): iterable
15+
{
16+
$a = 1;
17+
$b = 2;
18+
$c = 3;
19+
$d = 4;
20+
21+
return [
22+
[$a, $b],
23+
[$c, $d]
24+
];
25+
}
26+
27+
}
28+
29+
?>
30+
-----
31+
<?php
32+
33+
namespace Rector\PHPUnit\Tests\CodeQuality\Rector\Class_\YieldDataProviderRector\Fixture;
34+
35+
use PHPUnit\Framework\TestCase;
36+
37+
final class MultiStmtsReturnTest extends TestCase
38+
{
39+
#[\PHPUnit\Framework\Attributes\DataProvider('dataProvider')]
40+
public function test(string $val1, string $val2): void
41+
{
42+
}
43+
44+
public static function dataProvider(): \Iterator
45+
{
46+
$a = 1;
47+
$b = 2;
48+
$c = 3;
49+
$d = 4;
50+
yield [$a, $b];
51+
yield [$c, $d];
52+
}
53+
54+
}
55+
56+
?>
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
namespace Rector\PHPUnit\Tests\CodeQuality\Rector\Class_\YieldDataProviderRector\Fixture;
4+
5+
use PHPUnit\Framework\TestCase;
6+
7+
final class SkipMultipleYieldFrom extends TestCase
8+
{
9+
#[\PHPUnit\Framework\Attributes\DataProvider('dataProvider')]
10+
public function test(string $val1, string $val2): void
11+
{
12+
}
13+
14+
public static function dataProvider(): iterable
15+
{
16+
yield from [
17+
['value1', 'value2'],
18+
['value3', 'value4'],
19+
];
20+
yield from [
21+
['value5', 'value6'],
22+
['value7', 'value8'],
23+
];
24+
}
25+
26+
}
27+
28+
?>
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
3+
namespace Rector\PHPUnit\Tests\CodeQuality\Rector\Class_\YieldDataProviderRector\Fixture;
4+
5+
use PHPUnit\Framework\TestCase;
6+
7+
final class SkipYieldFromExprWithReturn extends TestCase
8+
{
9+
#[\PHPUnit\Framework\Attributes\DataProvider('dataProvider')]
10+
public function test(string $val1, string $val2): void
11+
{
12+
}
13+
14+
public static function dataProvider(): iterable
15+
{
16+
yield from [
17+
['value3', 'value4'],
18+
['value5', 'value6'],
19+
['value7', 'value8'],
20+
];
21+
22+
if (PHP_VERSION_ID < 80100) {
23+
return;
24+
}
25+
26+
return [['value1', 'value2']];
27+
}
28+
29+
}
30+
31+
?>

rules/CodeQuality/Rector/Class_/YieldDataProviderRector.php

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66

77
use PhpParser\Node;
88
use PhpParser\Node\Expr\Array_;
9+
use PhpParser\Node\Expr\Assign;
10+
use PhpParser\Node\Expr\AssignOp;
11+
use PhpParser\Node\Expr\AssignRef;
912
use PhpParser\Node\Expr\YieldFrom;
1013
use PhpParser\Node\Name\FullyQualified;
1114
use PhpParser\Node\Stmt\Class_;
@@ -42,7 +45,7 @@ public function __construct(
4245
private readonly PhpDocInfoFactory $phpDocInfoFactory,
4346
private readonly IsClassMethodUsedAnalyzer $isClassMethodUsedAnalyzer,
4447
private readonly PhpDocTypeChanger $phpDocTypeChanger,
45-
private readonly DocBlockUpdater $docBlockUpdater
48+
private readonly DocBlockUpdater $docBlockUpdater,
4649
) {
4750
}
4851

@@ -127,23 +130,41 @@ private function collectReturnArrayNodesFromClassMethod(ClassMethod $classMethod
127130
return null;
128131
}
129132

130-
$totalStmts = count($classMethod->stmts);
133+
$yieldedFromExpr = null;
131134
foreach ($classMethod->stmts as $statement) {
132135
if ($statement instanceof Expression) {
133136
$statement = $statement->expr;
134137
}
135138

136-
if ($statement instanceof Return_ || ($statement instanceof YieldFrom && $totalStmts === 1)) {
139+
if ($statement instanceof Return_) {
137140
$returnedExpr = $statement->expr;
138141
if (! $returnedExpr instanceof Array_) {
139142
return null;
140143
}
141144

142145
return $returnedExpr;
143146
}
147+
148+
if ($statement instanceof YieldFrom) {
149+
if (! $statement->expr instanceof Array_) {
150+
return null;
151+
}
152+
153+
if ($yieldedFromExpr instanceof Array_) {
154+
return null;
155+
}
156+
157+
$yieldedFromExpr = $statement->expr;
158+
} elseif (
159+
! $statement instanceof Assign
160+
&& ! $statement instanceof AssignRef
161+
&& ! $statement instanceof AssignOp
162+
) {
163+
return null;
164+
}
144165
}
145166

146-
return null;
167+
return $yieldedFromExpr;
147168
}
148169

149170
private function transformArrayToYieldsOnMethodNode(ClassMethod $classMethod, Array_ $array): void

0 commit comments

Comments
 (0)