Skip to content

Commit 3dacd70

Browse files
authored
[CodeQuality] Properly handle Goto_ on ExplicitReturnNullRector take 3 (#7020)
* [CodeQuality] Properly handle Goto_ on ExplicitReturnNullRector take 3 * more fixture * typo fix
1 parent 0966124 commit 3dacd70

4 files changed

Lines changed: 93 additions & 6 deletions

File tree

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<?php
2+
3+
namespace Rector\Tests\CodeQuality\Rector\ClassMethod\ExplicitReturnNullRector\Fixture;
4+
5+
final class MaybeNotReturnedBeforeLabel
6+
{
7+
public function run()
8+
{
9+
if (rand(0, 1)) {
10+
return 1;
11+
} elseif (rand(0, 2)) {
12+
return null;
13+
} else {
14+
// nothing to do here...
15+
}
16+
17+
unusedLabel:
18+
echo 'unused';
19+
}
20+
}
21+
22+
?>
23+
-----
24+
<?php
25+
26+
namespace Rector\Tests\CodeQuality\Rector\ClassMethod\ExplicitReturnNullRector\Fixture;
27+
28+
final class MaybeNotReturnedBeforeLabel
29+
{
30+
public function run()
31+
{
32+
if (rand(0, 1)) {
33+
return 1;
34+
} elseif (rand(0, 2)) {
35+
return null;
36+
} else {
37+
// nothing to do here...
38+
}
39+
40+
unusedLabel:
41+
echo 'unused';
42+
return null;
43+
}
44+
}
45+
46+
?>
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php
2+
3+
namespace Rector\Tests\CodeQuality\Rector\ClassMethod\ExplicitReturnNullRector\Fixture;
4+
5+
final class SkipExitTooEarlyBeforeLabel
6+
{
7+
public function run()
8+
{
9+
exit;
10+
11+
if (rand(0, 1)) {
12+
return 1;
13+
}
14+
15+
unusedLabel:
16+
echo 'unused';
17+
}
18+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php
2+
3+
namespace Rector\Tests\CodeQuality\Rector\ClassMethod\ExplicitReturnNullRector\Fixture;
4+
5+
final class SkipReturnTooEarlyBeforeLabel
6+
{
7+
public function run()
8+
{
9+
if (rand(0, 1)) {
10+
return 1;
11+
} else {
12+
return null;
13+
}
14+
15+
unusedLabel:
16+
echo 'unused';
17+
}
18+
}

rules/TypeDeclaration/TypeInferer/SilentVoidResolver.php

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -84,15 +84,17 @@ public function hasSilentVoid(FunctionLike $functionLike): bool
8484
*/
8585
private function hasStmtsAlwaysReturnOrExit(array $stmts): bool
8686
{
87-
// early label check
87+
// early label check position key stmt
8888
// as label can be defined later after goto
89+
$hasAlwaysReturnOrExitAfterLabelPosition = null;
8990
foreach ($stmts as $key => $stmt) {
90-
if ($stmt instanceof Label && isset($stmts[$key + 1])) {
91-
return $this->hasStmtsAlwaysReturnOrExit(array_slice($stmts, $key + 1));
91+
if ($stmt instanceof Label && isset($stmts[$key + 1]) && $this->hasStmtsAlwaysReturnOrExit(array_slice($stmts, $key + 1))) {
92+
$hasAlwaysReturnOrExitAfterLabelPosition = $key;
93+
break;
9294
}
9395
}
9496

95-
foreach ($stmts as $stmt) {
97+
foreach ($stmts as $key => $stmt) {
9698
if ($this->neverFuncCallAnalyzer->isWithNeverTypeExpr($stmt)) {
9799
return true;
98100
}
@@ -101,6 +103,10 @@ private function hasStmtsAlwaysReturnOrExit(array $stmts): bool
101103
return true;
102104
}
103105

106+
if ($stmt instanceof Goto_ && $hasAlwaysReturnOrExitAfterLabelPosition < $key) {
107+
return true;
108+
}
109+
104110
// has switch with always return
105111
if ($stmt instanceof Switch_ && $this->isSwitchWithAlwaysReturnOrExit($stmt)) {
106112
return true;
@@ -194,8 +200,7 @@ private function isStopped(Stmt $stmt): bool
194200
|| $stmt instanceof Exit_
195201
|| ($stmt instanceof Return_ && $stmt->expr instanceof Expr)
196202
|| $stmt instanceof Yield_
197-
|| $stmt instanceof YieldFrom
198-
|| $stmt instanceof Goto_;
203+
|| $stmt instanceof YieldFrom;
199204
}
200205

201206
private function isSwitchWithAlwaysReturnOrExit(Switch_ $switch): bool

0 commit comments

Comments
 (0)