Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

namespace Rector\Tests\DowngradePhp80\Rector\Expression\DowngradeThrowExprRector\Fixture;

final class OnArg
{
public function run()
{
$this->setImageResource(imagecreatefromstring(ob_get_clean()) ?: throw new Nette\ShouldNotHappenException());
}
}

?>
-----
<?php

namespace Rector\Tests\DowngradePhp80\Rector\Expression\DowngradeThrowExprRector\Fixture;

final class OnArg
{
public function run()
{
$arg = imagecreatefromstring(ob_get_clean());
if (!$arg) {
throw new Nette\ShouldNotHappenException();
}
$this->setImageResource($arg);
}
}

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

namespace Rector\Tests\DowngradePhp80\Rector\Expression\DowngradeThrowExprRector\Fixture;

final class ReturnTernary
{
public function run($res)
{
return $res === \false ? throw new Nette\ShouldNotHappenException() : $res;
}
}

?>
-----
<?php

namespace Rector\Tests\DowngradePhp80\Rector\Expression\DowngradeThrowExprRector\Fixture;

final class ReturnTernary
{
public function run($res)
{
if ($res === \false) {
throw new Nette\ShouldNotHappenException();
}
return $res;
}
}

?>
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
use PhpParser\Node\Expr\BinaryOp\Coalesce;
use PhpParser\Node\Expr\BinaryOp\Identical;
use PhpParser\Node\Expr\BooleanNot;
use PhpParser\Node\Expr\CallLike;
use PhpParser\Node\Expr\Closure;
use PhpParser\Node\Expr\ConstFetch;
use PhpParser\Node\Expr\Isset_;
Expand All @@ -25,6 +26,7 @@
use PhpParser\Node\Stmt\If_;
use PhpParser\Node\Stmt\Return_;
use Rector\NodeAnalyzer\CoalesceAnalyzer;
use Rector\NodeFactory\NamedVariableFactory;
use Rector\NodeManipulator\BinaryOpManipulator;
use Rector\Php72\NodeFactory\AnonymousFunctionFactory;
use Rector\PhpParser\Node\BetterNodeFinder;
Expand All @@ -43,7 +45,8 @@ public function __construct(
private readonly CoalesceAnalyzer $coalesceAnalyzer,
private readonly BinaryOpManipulator $binaryOpManipulator,
private readonly BetterNodeFinder $betterNodeFinder,
private readonly AnonymousFunctionFactory $anonymousFunctionFactory
private readonly AnonymousFunctionFactory $anonymousFunctionFactory,
private readonly NamedVariableFactory $namedVariableFactory
) {
}

Expand Down Expand Up @@ -100,6 +103,22 @@ public function refactor(Node $node): Node|array|null
}
}

if ($node->expr instanceof CallLike && ! $node->expr->isFirstClassCallable()) {
$args = $node->expr->getArgs();
foreach ($args as $arg) {
if ($arg->value instanceof Ternary && $arg->value->else instanceof Throw_) {
$refactorTernary = $this->refactorTernary($arg->value, null, true);
if (is_array($refactorTernary) && $refactorTernary[0] instanceof Expression && $refactorTernary[0]->expr instanceof Assign) {
$arg->value = $refactorTernary[0]->expr->var;

return [...$refactorTernary, $node];
}
}
}

return null;
}

if ($node->expr instanceof Coalesce) {
return $this->refactorCoalesce($node->expr, null);
}
Expand Down Expand Up @@ -153,18 +172,36 @@ private function refactorAssign(Assign $assign): If_ | Expression | null | array
/**
* @return If_|Stmt[]|null
*/
private function refactorTernary(Ternary $ternary, ?Assign $assign): If_|null|array
private function refactorTernary(Ternary $ternary, ?Assign $assign, bool $onArg = false): If_|null|array
{
if (! $ternary->else instanceof Throw_) {
if ($ternary->if instanceof Throw_) {
$else = $ternary->if;
} elseif ($ternary->else instanceof Throw_) {
$else = $ternary->else;
} else {
return null;
}

$inversedTernaryExpr = $this->binaryOpManipulator->inverseNode($ternary->cond);
$inversedTernaryExpr = $ternary->if instanceof Throw_
? $ternary->cond
: $this->binaryOpManipulator->inverseNode($ternary->cond);

$if = new If_($inversedTernaryExpr, [
'stmts' => [new Expression($ternary->else)],
'stmts' => [new Expression($else)],
]);

if (! $assign instanceof Assign && $onArg) {
$tempVar = $this->namedVariableFactory->createVariable('arg', $ternary);
$assign = new Assign($tempVar, $ternary->if ?? $ternary->cond);

$inversedTernaryExpr = $this->binaryOpManipulator->inverseNode($tempVar);
$if = new If_($inversedTernaryExpr, [
'stmts' => [new Expression($else)],
]);

return [new Expression($assign), $if];
}

if (! $assign instanceof Assign) {
return $if;
}
Expand Down Expand Up @@ -267,7 +304,11 @@ private function refactorReturn(Return_ $return): ?array
return null;
}

return [$if, new Return_($return->expr->cond)];
$returnExpr = $return->expr->if instanceof Throw_
? $return->expr->else
: ($return->expr->if ?? $return->expr->cond);

return [$if, new Return_($returnExpr)];
}

return null;
Expand Down
3 changes: 2 additions & 1 deletion src/NodeFactory/NamedVariableFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace Rector\NodeFactory;

use PhpParser\Node\Expr\Ternary;
use PhpParser\Node\Expr\Variable;
use PhpParser\Node\Stmt\Expression;
use Rector\Naming\Naming\VariableNaming;
Expand All @@ -16,7 +17,7 @@ public function __construct(
) {
}

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

Expand Down