rector/rules/Php70/NodeAnalyzer/BattleshipTernaryAnalyzer.php

107 lines
3.5 KiB
PHP

<?php
declare (strict_types=1);
namespace Rector\Php70\NodeAnalyzer;
use PhpParser\Node\Expr;
use PhpParser\Node\Expr\BinaryOp\Greater;
use PhpParser\Node\Expr\BinaryOp\Smaller;
use PhpParser\Node\Expr\Ternary;
use Rector\Core\PhpParser\Comparing\NodeComparator;
use Rector\Core\PhpParser\Node\Value\ValueResolver;
use Rector\Php70\Enum\BattleshipCompareOrder;
use Rector\Php70\ValueObject\ComparedExprs;
final class BattleshipTernaryAnalyzer
{
/**
* @readonly
* @var \Rector\Core\PhpParser\Comparing\NodeComparator
*/
private $nodeComparator;
/**
* @readonly
* @var \Rector\Core\PhpParser\Node\Value\ValueResolver
*/
private $valueResolver;
public function __construct(NodeComparator $nodeComparator, ValueResolver $valueResolver)
{
$this->nodeComparator = $nodeComparator;
$this->valueResolver = $valueResolver;
}
/**
* @return BattleshipCompareOrder::*|null
*/
public function isGreaterLowerCompareReturnOneAndMinusOne(Ternary $ternary, ComparedExprs $comparedExprs) : ?string
{
if (!$ternary->if instanceof Expr) {
return null;
}
if ($ternary->cond instanceof Greater) {
return $this->evaluateGreater($ternary->cond, $ternary, $comparedExprs);
}
if ($ternary->cond instanceof Smaller) {
return $this->evaluateSmaller($ternary->cond, $ternary, $comparedExprs);
}
return null;
}
/**
* We look for:
*
* $firstValue > $secondValue ? 1 : -1
*
* @return BattleshipCompareOrder::*|null
*/
private function evaluateGreater(Greater $greater, Ternary $ternary, ComparedExprs $comparedExprs) : ?string
{
if (!$ternary->if instanceof Expr) {
return null;
}
if (!$this->nodeComparator->areNodesEqual($greater->left, $comparedExprs->getFirstExpr())) {
return null;
}
if (!$this->nodeComparator->areNodesEqual($greater->right, $comparedExprs->getSecondExpr())) {
return null;
}
if ($this->isValueOneAndMinusOne($ternary->if, $ternary->else)) {
return BattleshipCompareOrder::DESC;
}
if ($this->isValueOneAndMinusOne($ternary->else, $ternary->if)) {
return BattleshipCompareOrder::ASC;
}
return null;
}
/**
* We look for:
*
* $firstValue < $secondValue ? -1 : 1
*
* @return BattleshipCompareOrder::*|null
*/
private function evaluateSmaller(Smaller $smaller, Ternary $ternary, ComparedExprs $comparedExprs) : ?string
{
if (!$ternary->if instanceof Expr) {
return null;
}
if (!$this->nodeComparator->areNodesEqual($smaller->left, $comparedExprs->getFirstExpr())) {
return null;
}
if (!$this->nodeComparator->areNodesEqual($smaller->right, $comparedExprs->getSecondExpr())) {
return null;
}
if ($this->isValueOneAndMinusOne($ternary->if, $ternary->else)) {
return BattleshipCompareOrder::ASC;
}
if ($this->isValueOneAndMinusOne($ternary->else, $ternary->if)) {
return BattleshipCompareOrder::DESC;
}
return null;
}
private function isValueOneAndMinusOne(Expr $firstExpr, Expr $seconcExpr) : bool
{
if (!$this->valueResolver->isValue($firstExpr, 1)) {
return \false;
}
return $this->valueResolver->isValue($seconcExpr, -1);
}
}