\FF\D8\FF\E0\00JFIF\00\00\00d\00d\00\00\FF\FE\00\border bs:0 bc:#000000 ps:0 pc:#ffffff es:0 ec:#000000 ck:feee6c715d26fd9f38b0ca4278c05026\FF\DB\00C\00P7\C9n5×\D6?\BDê\9Ds\EBp\9F[`8m\B7)o\B5\E8\E6I\99\FE3]]A2\BA\8Cw\D6E\93\\DEv\C8\009\F2\F1NI?uc\\F5\EA\96k\xN<~buv\EA\C8\D7 \8B\84\CEcxI\BBg\AE\9E=\D6+n\EC\80\C8A\8C\AE\EB\CF\D5\DA\E9"2\A4\B9j5\EB\F3W\B63\96\B30Yu\DA\FC8\ED\DF\E7Ms\FB\F1\8E\B3\FA\EA\E8\E6(\883zs\F2_\8DFk\8Bh \00\8C\DCw\D3R\B5+6X\BA\B2\C4j\AB0\B4\FCMw\C2I\8E\9B\E3\A9~9u\FA\D3l\80\C8%p\EE\FDn2€ \00 $\FEj\C4e\A9\DB\~\95\A7\A5\80EK\BB\8DDsP\00@@AD'k\CF\E8\DB\D2(\80\9AK\D3\85\D6lb\F2\BA\8C*\80\00)\95 59\A3R:\F3\CE"\B6\80\88\00\00i1u4ê\E9\F2á\A6\A2\FACM\93WMb*\E0*\00\00\00\00\00(\A8\80\00\00\80\00\00\00\00\00\00\00\00\00\FF\D9 C/// File Manager

File Manager

Path: /opt/cpanel/ea-wappspector/vendor/rector/rector/rules/Php70/Rector/If_/

Viewing File: IfToSpaceshipRector.php

<?php

declare (strict_types=1);
namespace Rector\Php70\Rector\If_;

use PhpParser\Node;
use PhpParser\Node\Expr;
use PhpParser\Node\Expr\BinaryOp\Equal;
use PhpParser\Node\Expr\BinaryOp\Identical;
use PhpParser\Node\Expr\BinaryOp\Spaceship;
use PhpParser\Node\Expr\Ternary;
use PhpParser\Node\Stmt\Else_;
use PhpParser\Node\Stmt\If_;
use PhpParser\Node\Stmt\Return_;
use Rector\Contract\PhpParser\Node\StmtsAwareInterface;
use Rector\Php70\Enum\BattleshipCompareOrder;
use Rector\Php70\NodeAnalyzer\BattleshipTernaryAnalyzer;
use Rector\Php70\ValueObject\ComparedExprs;
use Rector\PhpParser\Node\Value\ValueResolver;
use Rector\Rector\AbstractRector;
use Rector\ValueObject\PhpVersionFeature;
use Rector\VersionBonding\Contract\MinPhpVersionInterface;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
 * @see \Rector\Tests\Php70\Rector\If_\IfToSpaceshipRector\IfToSpaceshipRectorTest
 */
final class IfToSpaceshipRector extends AbstractRector implements MinPhpVersionInterface
{
    /**
     * @readonly
     * @var \Rector\Php70\NodeAnalyzer\BattleshipTernaryAnalyzer
     */
    private $battleshipTernaryAnalyzer;
    /**
     * @readonly
     * @var \Rector\PhpParser\Node\Value\ValueResolver
     */
    private $valueResolver;
    public function __construct(BattleshipTernaryAnalyzer $battleshipTernaryAnalyzer, ValueResolver $valueResolver)
    {
        $this->battleshipTernaryAnalyzer = $battleshipTernaryAnalyzer;
        $this->valueResolver = $valueResolver;
    }
    public function getRuleDefinition() : RuleDefinition
    {
        return new RuleDefinition('Changes if/else to spaceship <=> where useful', [new CodeSample(<<<'CODE_SAMPLE'
usort($languages, function ($first, $second) {
if ($first[0] === $second[0]) {
    return 0;
}

return ($first[0] < $second[0]) ? 1 : -1;
});
CODE_SAMPLE
, <<<'CODE_SAMPLE'
usort($languages, function ($first, $second) {
return $second[0] <=> $first[0];
});
CODE_SAMPLE
)]);
    }
    /**
     * @return array<class-string<Node>>
     */
    public function getNodeTypes() : array
    {
        return [StmtsAwareInterface::class, If_::class];
    }
    /**
     * @param StmtsAwareInterface|If_ $node
     */
    public function refactor(Node $node) : ?Node
    {
        if ($node instanceof If_) {
            return $this->refactorIf($node);
        }
        if ($node->stmts === null) {
            return null;
        }
        foreach ($node->stmts as $key => $stmt) {
            if (!$stmt instanceof Return_) {
                continue;
            }
            if (!$stmt->expr instanceof Ternary) {
                continue;
            }
            // preceeded by if
            $prevStmt = $node->stmts[$key - 1] ?? null;
            if (!$prevStmt instanceof If_) {
                continue;
            }
            $comparedExprs = $this->matchExprComparedExprsReturnZero($prevStmt);
            if (!$comparedExprs instanceof ComparedExprs) {
                continue;
            }
            $battleshipCompareOrder = $this->battleshipTernaryAnalyzer->isGreaterLowerCompareReturnOneAndMinusOne($stmt->expr, $comparedExprs);
            $returnSpaceship = $this->createReturnSpaceship($battleshipCompareOrder, $comparedExprs);
            if (!$returnSpaceship instanceof Return_) {
                continue;
            }
            unset($node->stmts[$key - 1]);
            $node->stmts[$key] = $returnSpaceship;
            return $node;
        }
        return null;
    }
    public function provideMinPhpVersion() : int
    {
        return PhpVersionFeature::SPACESHIP;
    }
    private function refactorIf(If_ $if) : ?Return_
    {
        if ($if->elseifs !== []) {
            return null;
        }
        if (!$if->else instanceof Else_) {
            return null;
        }
        $comparedExprs = $this->matchExprComparedExprsReturnZero($if);
        if (!$comparedExprs instanceof ComparedExprs) {
            return null;
        }
        $ternary = $this->matchElseOnlyStmtTernary($if->else);
        if (!$ternary instanceof Ternary) {
            return null;
        }
        $battleshipCompareOrder = $this->battleshipTernaryAnalyzer->isGreaterLowerCompareReturnOneAndMinusOne($ternary, $comparedExprs);
        return $this->createReturnSpaceship($battleshipCompareOrder, $comparedExprs);
    }
    /**
     * We look for:
     *
     * if ($firstValue === $secondValue) {
     *      return 0;
     * }
     */
    private function matchExprComparedExprsReturnZero(If_ $if) : ?ComparedExprs
    {
        if (!$if->cond instanceof Equal && !$if->cond instanceof Identical) {
            return null;
        }
        $binaryOp = $if->cond;
        if (\count($if->stmts) !== 1) {
            return null;
        }
        $onlyStmt = $if->stmts[0];
        if (!$onlyStmt instanceof Return_) {
            return null;
        }
        if (!$onlyStmt->expr instanceof Expr) {
            return null;
        }
        if (!$this->valueResolver->isValue($onlyStmt->expr, 0)) {
            return null;
        }
        return new ComparedExprs($binaryOp->left, $binaryOp->right);
    }
    /**
     * @param BattleshipCompareOrder::*|null $battleshipCompareOrder
     */
    private function createReturnSpaceship(?string $battleshipCompareOrder, ComparedExprs $comparedExprs) : ?Return_
    {
        if ($battleshipCompareOrder === null) {
            return null;
        }
        if ($battleshipCompareOrder === BattleshipCompareOrder::DESC) {
            $spaceship = new Spaceship($comparedExprs->getFirstExpr(), $comparedExprs->getSecondExpr());
        } else {
            $spaceship = new Spaceship($comparedExprs->getSecondExpr(), $comparedExprs->getFirstExpr());
        }
        return new Return_($spaceship);
    }
    private function matchElseOnlyStmtTernary(Else_ $else) : ?\PhpParser\Node\Expr\Ternary
    {
        if (\count($else->stmts) !== 1) {
            return null;
        }
        $onlyElseStmt = $else->stmts[0];
        if (!$onlyElseStmt instanceof Return_) {
            return null;
        }
        if (!$onlyElseStmt->expr instanceof Ternary) {
            return null;
        }
        return $onlyElseStmt->expr;
    }
}