|
11 | 11 | use PhpParser\Node\Expr\BinaryOp\Coalesce; |
12 | 12 | use PhpParser\Node\Expr\BinaryOp\Identical; |
13 | 13 | use PhpParser\Node\Expr\BooleanNot; |
| 14 | +use PhpParser\Node\Expr\CallLike; |
14 | 15 | use PhpParser\Node\Expr\Closure; |
15 | 16 | use PhpParser\Node\Expr\ConstFetch; |
16 | 17 | use PhpParser\Node\Expr\Isset_; |
|
24 | 25 | use PhpParser\Node\Stmt\If_; |
25 | 26 | use PhpParser\Node\Stmt\Return_; |
26 | 27 | use Rector\NodeAnalyzer\CoalesceAnalyzer; |
| 28 | +use Rector\NodeFactory\NamedVariableFactory; |
27 | 29 | use Rector\NodeManipulator\BinaryOpManipulator; |
28 | 30 | use Rector\Php72\NodeFactory\AnonymousFunctionFactory; |
29 | 31 | use Rector\PhpParser\Node\BetterNodeFinder; |
@@ -53,12 +55,17 @@ final class DowngradeThrowExprRector extends AbstractRector |
53 | 55 | * @readonly |
54 | 56 | */ |
55 | 57 | private AnonymousFunctionFactory $anonymousFunctionFactory; |
56 | | - public function __construct(CoalesceAnalyzer $coalesceAnalyzer, BinaryOpManipulator $binaryOpManipulator, BetterNodeFinder $betterNodeFinder, AnonymousFunctionFactory $anonymousFunctionFactory) |
| 58 | + /** |
| 59 | + * @readonly |
| 60 | + */ |
| 61 | + private NamedVariableFactory $namedVariableFactory; |
| 62 | + public function __construct(CoalesceAnalyzer $coalesceAnalyzer, BinaryOpManipulator $binaryOpManipulator, BetterNodeFinder $betterNodeFinder, AnonymousFunctionFactory $anonymousFunctionFactory, NamedVariableFactory $namedVariableFactory) |
57 | 63 | { |
58 | 64 | $this->coalesceAnalyzer = $coalesceAnalyzer; |
59 | 65 | $this->binaryOpManipulator = $binaryOpManipulator; |
60 | 66 | $this->betterNodeFinder = $betterNodeFinder; |
61 | 67 | $this->anonymousFunctionFactory = $anonymousFunctionFactory; |
| 68 | + $this->namedVariableFactory = $namedVariableFactory; |
62 | 69 | } |
63 | 70 | public function getRuleDefinition(): RuleDefinition |
64 | 71 | { |
@@ -102,6 +109,19 @@ public function refactor(Node $node) |
102 | 109 | return $resultNode; |
103 | 110 | } |
104 | 111 | } |
| 112 | + if ($node->expr instanceof CallLike && !$node->expr->isFirstClassCallable()) { |
| 113 | + $args = $node->expr->getArgs(); |
| 114 | + foreach ($args as $arg) { |
| 115 | + if ($arg->value instanceof Ternary && $arg->value->else instanceof Throw_) { |
| 116 | + $refactorTernary = $this->refactorTernary($arg->value, null, \true); |
| 117 | + if (is_array($refactorTernary) && $refactorTernary[0] instanceof Expression && $refactorTernary[0]->expr instanceof Assign) { |
| 118 | + $arg->value = $refactorTernary[0]->expr->var; |
| 119 | + return array_merge($refactorTernary, [$node]); |
| 120 | + } |
| 121 | + } |
| 122 | + } |
| 123 | + return null; |
| 124 | + } |
105 | 125 | if ($node->expr instanceof Coalesce) { |
106 | 126 | return $this->refactorCoalesce($node->expr, null); |
107 | 127 | } |
@@ -140,13 +160,24 @@ private function refactorAssign(Assign $assign) |
140 | 160 | /** |
141 | 161 | * @return If_|Stmt[]|null |
142 | 162 | */ |
143 | | - private function refactorTernary(Ternary $ternary, ?Assign $assign) |
| 163 | + private function refactorTernary(Ternary $ternary, ?Assign $assign, bool $onArg = \false) |
144 | 164 | { |
145 | | - if (!$ternary->else instanceof Throw_) { |
| 165 | + if ($ternary->if instanceof Throw_) { |
| 166 | + $else = $ternary->if; |
| 167 | + } elseif ($ternary->else instanceof Throw_) { |
| 168 | + $else = $ternary->else; |
| 169 | + } else { |
146 | 170 | return null; |
147 | 171 | } |
148 | | - $inversedTernaryExpr = $this->binaryOpManipulator->inverseNode($ternary->cond); |
149 | | - $if = new If_($inversedTernaryExpr, ['stmts' => [new Expression($ternary->else)]]); |
| 172 | + $inversedTernaryExpr = $ternary->if instanceof Throw_ ? $ternary->cond : $this->binaryOpManipulator->inverseNode($ternary->cond); |
| 173 | + $if = new If_($inversedTernaryExpr, ['stmts' => [new Expression($else)]]); |
| 174 | + if (!$assign instanceof Assign && $onArg) { |
| 175 | + $tempVar = $this->namedVariableFactory->createVariable('arg', $ternary); |
| 176 | + $assign = new Assign($tempVar, $ternary->if ?? $ternary->cond); |
| 177 | + $inversedTernaryExpr = $this->binaryOpManipulator->inverseNode($tempVar); |
| 178 | + $if = new If_($inversedTernaryExpr, ['stmts' => [new Expression($else)]]); |
| 179 | + return [new Expression($assign), $if]; |
| 180 | + } |
150 | 181 | if (!$assign instanceof Assign) { |
151 | 182 | return $if; |
152 | 183 | } |
@@ -223,7 +254,8 @@ private function refactorReturn(Return_ $return): ?array |
223 | 254 | if (!$if instanceof If_) { |
224 | 255 | return null; |
225 | 256 | } |
226 | | - return [$if, new Return_($return->expr->cond)]; |
| 257 | + $returnExpr = $return->expr->if instanceof Throw_ ? $return->expr->else : $return->expr->if ?? $return->expr->cond; |
| 258 | + return [$if, new Return_($returnExpr)]; |
227 | 259 | } |
228 | 260 | return null; |
229 | 261 | } |
|
0 commit comments