Skip to content

Commit db13b8f

Browse files
authored
[DowngradePhp80] Fix on Arg and return ternary on DowngradeThrowExprRector (#361)
1 parent a110e2f commit db13b8f

File tree

4 files changed

+110
-7
lines changed

4 files changed

+110
-7
lines changed
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
3+
namespace Rector\Tests\DowngradePhp80\Rector\Expression\DowngradeThrowExprRector\Fixture;
4+
5+
final class OnArg
6+
{
7+
public function run()
8+
{
9+
$this->setImageResource(imagecreatefromstring(ob_get_clean()) ?: throw new Nette\ShouldNotHappenException());
10+
}
11+
}
12+
13+
?>
14+
-----
15+
<?php
16+
17+
namespace Rector\Tests\DowngradePhp80\Rector\Expression\DowngradeThrowExprRector\Fixture;
18+
19+
final class OnArg
20+
{
21+
public function run()
22+
{
23+
$arg = imagecreatefromstring(ob_get_clean());
24+
if (!$arg) {
25+
throw new Nette\ShouldNotHappenException();
26+
}
27+
$this->setImageResource($arg);
28+
}
29+
}
30+
31+
?>
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php
2+
3+
namespace Rector\Tests\DowngradePhp80\Rector\Expression\DowngradeThrowExprRector\Fixture;
4+
5+
final class ReturnTernary
6+
{
7+
public function run($res)
8+
{
9+
return $res === \false ? throw new Nette\ShouldNotHappenException() : $res;
10+
}
11+
}
12+
13+
?>
14+
-----
15+
<?php
16+
17+
namespace Rector\Tests\DowngradePhp80\Rector\Expression\DowngradeThrowExprRector\Fixture;
18+
19+
final class ReturnTernary
20+
{
21+
public function run($res)
22+
{
23+
if ($res === \false) {
24+
throw new Nette\ShouldNotHappenException();
25+
}
26+
return $res;
27+
}
28+
}
29+
30+
?>

rules/DowngradePhp80/Rector/Expression/DowngradeThrowExprRector.php

Lines changed: 47 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
use PhpParser\Node\Expr\BinaryOp\Coalesce;
1313
use PhpParser\Node\Expr\BinaryOp\Identical;
1414
use PhpParser\Node\Expr\BooleanNot;
15+
use PhpParser\Node\Expr\CallLike;
1516
use PhpParser\Node\Expr\Closure;
1617
use PhpParser\Node\Expr\ConstFetch;
1718
use PhpParser\Node\Expr\Isset_;
@@ -25,6 +26,7 @@
2526
use PhpParser\Node\Stmt\If_;
2627
use PhpParser\Node\Stmt\Return_;
2728
use Rector\NodeAnalyzer\CoalesceAnalyzer;
29+
use Rector\NodeFactory\NamedVariableFactory;
2830
use Rector\NodeManipulator\BinaryOpManipulator;
2931
use Rector\Php72\NodeFactory\AnonymousFunctionFactory;
3032
use Rector\PhpParser\Node\BetterNodeFinder;
@@ -43,7 +45,8 @@ public function __construct(
4345
private readonly CoalesceAnalyzer $coalesceAnalyzer,
4446
private readonly BinaryOpManipulator $binaryOpManipulator,
4547
private readonly BetterNodeFinder $betterNodeFinder,
46-
private readonly AnonymousFunctionFactory $anonymousFunctionFactory
48+
private readonly AnonymousFunctionFactory $anonymousFunctionFactory,
49+
private readonly NamedVariableFactory $namedVariableFactory
4750
) {
4851
}
4952

@@ -100,6 +103,22 @@ public function refactor(Node $node): Node|array|null
100103
}
101104
}
102105

106+
if ($node->expr instanceof CallLike && ! $node->expr->isFirstClassCallable()) {
107+
$args = $node->expr->getArgs();
108+
foreach ($args as $arg) {
109+
if ($arg->value instanceof Ternary && $arg->value->else instanceof Throw_) {
110+
$refactorTernary = $this->refactorTernary($arg->value, null, true);
111+
if (is_array($refactorTernary) && $refactorTernary[0] instanceof Expression && $refactorTernary[0]->expr instanceof Assign) {
112+
$arg->value = $refactorTernary[0]->expr->var;
113+
114+
return [...$refactorTernary, $node];
115+
}
116+
}
117+
}
118+
119+
return null;
120+
}
121+
103122
if ($node->expr instanceof Coalesce) {
104123
return $this->refactorCoalesce($node->expr, null);
105124
}
@@ -153,18 +172,36 @@ private function refactorAssign(Assign $assign): If_ | Expression | null | array
153172
/**
154173
* @return If_|Stmt[]|null
155174
*/
156-
private function refactorTernary(Ternary $ternary, ?Assign $assign): If_|null|array
175+
private function refactorTernary(Ternary $ternary, ?Assign $assign, bool $onArg = false): If_|null|array
157176
{
158-
if (! $ternary->else instanceof Throw_) {
177+
if ($ternary->if instanceof Throw_) {
178+
$else = $ternary->if;
179+
} elseif ($ternary->else instanceof Throw_) {
180+
$else = $ternary->else;
181+
} else {
159182
return null;
160183
}
161184

162-
$inversedTernaryExpr = $this->binaryOpManipulator->inverseNode($ternary->cond);
185+
$inversedTernaryExpr = $ternary->if instanceof Throw_
186+
? $ternary->cond
187+
: $this->binaryOpManipulator->inverseNode($ternary->cond);
163188

164189
$if = new If_($inversedTernaryExpr, [
165-
'stmts' => [new Expression($ternary->else)],
190+
'stmts' => [new Expression($else)],
166191
]);
167192

193+
if (! $assign instanceof Assign && $onArg) {
194+
$tempVar = $this->namedVariableFactory->createVariable('arg', $ternary);
195+
$assign = new Assign($tempVar, $ternary->if ?? $ternary->cond);
196+
197+
$inversedTernaryExpr = $this->binaryOpManipulator->inverseNode($tempVar);
198+
$if = new If_($inversedTernaryExpr, [
199+
'stmts' => [new Expression($else)],
200+
]);
201+
202+
return [new Expression($assign), $if];
203+
}
204+
168205
if (! $assign instanceof Assign) {
169206
return $if;
170207
}
@@ -267,7 +304,11 @@ private function refactorReturn(Return_ $return): ?array
267304
return null;
268305
}
269306

270-
return [$if, new Return_($return->expr->cond)];
307+
$returnExpr = $return->expr->if instanceof Throw_
308+
? $return->expr->else
309+
: ($return->expr->if ?? $return->expr->cond);
310+
311+
return [$if, new Return_($returnExpr)];
271312
}
272313

273314
return null;

src/NodeFactory/NamedVariableFactory.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
namespace Rector\NodeFactory;
66

7+
use PhpParser\Node\Expr\Ternary;
78
use PhpParser\Node\Expr\Variable;
89
use PhpParser\Node\Stmt\Expression;
910
use Rector\Naming\Naming\VariableNaming;
@@ -16,7 +17,7 @@ public function __construct(
1617
) {
1718
}
1819

19-
public function createVariable(string $variableName, Expression $expression): Variable
20+
public function createVariable(string $variableName, Expression|Ternary $expression): Variable
2021
{
2122
$scope = $expression->getAttribute(AttributeKey::SCOPE);
2223

0 commit comments

Comments
 (0)