mirror of https://github.com/rectorphp/rector.git
Updated Rector to commit 6306f9e8ecd8e367e7220b02a6613461a34dcc8a
6306f9e8ec
[EarlyReturn] Skip ChangeAndIfToEarlyReturnRector in case of simple scalar return (#2826)
This commit is contained in:
parent
88b118d794
commit
1db8339e7c
|
@ -3883,12 +3883,12 @@ Changes if && to early return
|
|||
{
|
||||
- if ($car->hasWheels && $car->hasFuel) {
|
||||
- return true;
|
||||
+ if (!$car->hasWheels) {
|
||||
+ if (! $car->hasWheels) {
|
||||
+ return false;
|
||||
}
|
||||
|
||||
- return false;
|
||||
+ if (!$car->hasFuel) {
|
||||
+ if (! $car->hasFuel) {
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
<?php
|
||||
|
||||
declare (strict_types=1);
|
||||
namespace Rector\EarlyReturn\NodeAnalyzer;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Expr;
|
||||
use PhpParser\Node\Expr\BinaryOp\BooleanAnd;
|
||||
use PhpParser\Node\Expr\Instanceof_;
|
||||
use PhpParser\Node\Stmt\If_;
|
||||
use PhpParser\Node\Stmt\Return_;
|
||||
use Rector\Core\PhpParser\Comparing\NodeComparator;
|
||||
use Rector\Core\PhpParser\Node\BetterNodeFinder;
|
||||
final class IfAndAnalyzer
|
||||
{
|
||||
/**
|
||||
* @readonly
|
||||
* @var \Rector\Core\PhpParser\Node\BetterNodeFinder
|
||||
*/
|
||||
private $betterNodeFinder;
|
||||
/**
|
||||
* @readonly
|
||||
* @var \Rector\Core\PhpParser\Comparing\NodeComparator
|
||||
*/
|
||||
private $nodeComparator;
|
||||
public function __construct(BetterNodeFinder $betterNodeFinder, NodeComparator $nodeComparator)
|
||||
{
|
||||
$this->betterNodeFinder = $betterNodeFinder;
|
||||
$this->nodeComparator = $nodeComparator;
|
||||
}
|
||||
public function isIfAndWithInstanceof(BooleanAnd $booleanAnd) : bool
|
||||
{
|
||||
if (!$booleanAnd->left instanceof Instanceof_) {
|
||||
return \false;
|
||||
}
|
||||
// only one instanceof check
|
||||
return !$booleanAnd->right instanceof Instanceof_;
|
||||
}
|
||||
public function isIfStmtExprUsedInNextReturn(If_ $if, Return_ $return) : bool
|
||||
{
|
||||
if (!$return->expr instanceof Expr) {
|
||||
return \false;
|
||||
}
|
||||
$ifExprs = $this->betterNodeFinder->findInstanceOf($if->stmts, Expr::class);
|
||||
foreach ($ifExprs as $ifExpr) {
|
||||
$isExprFoundInReturn = (bool) $this->betterNodeFinder->findFirst($return->expr, function (Node $node) use($ifExpr) : bool {
|
||||
return $this->nodeComparator->areNodesEqual($node, $ifExpr);
|
||||
});
|
||||
if ($isExprFoundInReturn) {
|
||||
return \true;
|
||||
}
|
||||
}
|
||||
return \false;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
<?php
|
||||
|
||||
declare (strict_types=1);
|
||||
namespace Rector\EarlyReturn\NodeAnalyzer;
|
||||
|
||||
use PhpParser\Node\Expr;
|
||||
use PhpParser\Node\Expr\Array_;
|
||||
use PhpParser\Node\Scalar\String_;
|
||||
final class SimpleScalarAnalyzer
|
||||
{
|
||||
public function isSimpleScalar(Expr $expr) : bool
|
||||
{
|
||||
// empty array
|
||||
if ($expr instanceof Array_ && $expr->items === []) {
|
||||
return \true;
|
||||
}
|
||||
// empty string
|
||||
return $expr instanceof String_ && $expr->value === '';
|
||||
}
|
||||
}
|
|
@ -16,6 +16,8 @@ use PhpParser\Node\Stmt\Return_;
|
|||
use Rector\Core\Contract\PhpParser\Node\StmtsAwareInterface;
|
||||
use Rector\Core\NodeManipulator\IfManipulator;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Rector\EarlyReturn\NodeAnalyzer\IfAndAnalyzer;
|
||||
use Rector\EarlyReturn\NodeAnalyzer\SimpleScalarAnalyzer;
|
||||
use Rector\EarlyReturn\NodeFactory\InvertedIfFactory;
|
||||
use Rector\NodeCollector\BinaryOpConditionsCollector;
|
||||
use Rector\NodeNestingScope\ContextAnalyzer;
|
||||
|
@ -47,12 +49,24 @@ final class ChangeAndIfToEarlyReturnRector extends AbstractRector
|
|||
* @var \Rector\NodeCollector\BinaryOpConditionsCollector
|
||||
*/
|
||||
private $binaryOpConditionsCollector;
|
||||
public function __construct(IfManipulator $ifManipulator, InvertedIfFactory $invertedIfFactory, ContextAnalyzer $contextAnalyzer, BinaryOpConditionsCollector $binaryOpConditionsCollector)
|
||||
/**
|
||||
* @readonly
|
||||
* @var \Rector\EarlyReturn\NodeAnalyzer\SimpleScalarAnalyzer
|
||||
*/
|
||||
private $simpleScalarAnalyzer;
|
||||
/**
|
||||
* @readonly
|
||||
* @var \Rector\EarlyReturn\NodeAnalyzer\IfAndAnalyzer
|
||||
*/
|
||||
private $ifAndAnalyzer;
|
||||
public function __construct(IfManipulator $ifManipulator, InvertedIfFactory $invertedIfFactory, ContextAnalyzer $contextAnalyzer, BinaryOpConditionsCollector $binaryOpConditionsCollector, SimpleScalarAnalyzer $simpleScalarAnalyzer, IfAndAnalyzer $ifAndAnalyzer)
|
||||
{
|
||||
$this->ifManipulator = $ifManipulator;
|
||||
$this->invertedIfFactory = $invertedIfFactory;
|
||||
$this->contextAnalyzer = $contextAnalyzer;
|
||||
$this->binaryOpConditionsCollector = $binaryOpConditionsCollector;
|
||||
$this->simpleScalarAnalyzer = $simpleScalarAnalyzer;
|
||||
$this->ifAndAnalyzer = $ifAndAnalyzer;
|
||||
}
|
||||
public function getRuleDefinition() : RuleDefinition
|
||||
{
|
||||
|
@ -74,11 +88,11 @@ class SomeClass
|
|||
{
|
||||
public function canDrive(Car $car)
|
||||
{
|
||||
if (!$car->hasWheels) {
|
||||
if (! $car->hasWheels) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!$car->hasFuel) {
|
||||
if (! $car->hasFuel) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -107,6 +121,7 @@ CODE_SAMPLE
|
|||
$newStmts = [];
|
||||
foreach ($stmts as $key => $stmt) {
|
||||
if (!$stmt instanceof If_) {
|
||||
// keep natural original order
|
||||
$newStmts[] = $stmt;
|
||||
continue;
|
||||
}
|
||||
|
@ -116,7 +131,7 @@ CODE_SAMPLE
|
|||
continue;
|
||||
}
|
||||
if ($nextStmt instanceof Return_) {
|
||||
if ($this->isIfStmtExprUsedInNextReturn($stmt, $nextStmt)) {
|
||||
if ($this->ifAndAnalyzer->isIfStmtExprUsedInNextReturn($stmt, $nextStmt)) {
|
||||
continue;
|
||||
}
|
||||
if ($nextStmt->expr instanceof BooleanAnd) {
|
||||
|
@ -194,24 +209,16 @@ CODE_SAMPLE
|
|||
if ($this->isNestedIfInLoop($if, $stmtsAware)) {
|
||||
return \true;
|
||||
}
|
||||
// is simple return? skip it
|
||||
$onlyStmt = $if->stmts[0];
|
||||
if ($onlyStmt instanceof Return_ && $onlyStmt->expr instanceof Expr && $this->simpleScalarAnalyzer->isSimpleScalar($onlyStmt->expr)) {
|
||||
return \true;
|
||||
}
|
||||
if ($this->ifAndAnalyzer->isIfAndWithInstanceof($if->cond)) {
|
||||
return \true;
|
||||
}
|
||||
return !$this->isLastIfOrBeforeLastReturn($if, $nexStmt);
|
||||
}
|
||||
private function isIfStmtExprUsedInNextReturn(If_ $if, Return_ $return) : bool
|
||||
{
|
||||
if (!$return->expr instanceof Expr) {
|
||||
return \false;
|
||||
}
|
||||
$ifExprs = $this->betterNodeFinder->findInstanceOf($if->stmts, Expr::class);
|
||||
foreach ($ifExprs as $ifExpr) {
|
||||
$isExprFoundInReturn = (bool) $this->betterNodeFinder->findFirst($return->expr, function (Node $node) use($ifExpr) : bool {
|
||||
return $this->nodeComparator->areNodesEqual($node, $ifExpr);
|
||||
});
|
||||
if ($isExprFoundInReturn) {
|
||||
return \true;
|
||||
}
|
||||
}
|
||||
return \false;
|
||||
}
|
||||
private function isParentIfReturnsVoidOrParentIfHasNextNode(StmtsAwareInterface $stmtsAware) : bool
|
||||
{
|
||||
if (!$stmtsAware instanceof If_) {
|
||||
|
|
|
@ -17,12 +17,12 @@ final class VersionResolver
|
|||
* @api
|
||||
* @var string
|
||||
*/
|
||||
public const PACKAGE_VERSION = '58edce71bb42b06df87e863ee9bf3df4c7b65e27';
|
||||
public const PACKAGE_VERSION = '6306f9e8ecd8e367e7220b02a6613461a34dcc8a';
|
||||
/**
|
||||
* @api
|
||||
* @var string
|
||||
*/
|
||||
public const RELEASE_DATE = '2022-08-24 14:50:04';
|
||||
public const RELEASE_DATE = '2022-08-24 08:07:35';
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
|
|
|
@ -233,16 +233,16 @@ final class IfManipulator
|
|||
if ($if->else !== null) {
|
||||
return \false;
|
||||
}
|
||||
return !(bool) $if->elseifs;
|
||||
return $if->elseifs === [];
|
||||
}
|
||||
public function createIfNegation(Expr $expr, Return_ $return) : If_
|
||||
{
|
||||
$expr = $this->conditionInverter->createInvertedCondition($expr);
|
||||
return $this->createIfStmt($expr, $return);
|
||||
}
|
||||
public function createIfStmt(Expr $expr, Stmt $stmt) : If_
|
||||
public function createIfStmt(Expr $condExpr, Stmt $stmt) : If_
|
||||
{
|
||||
return new If_($expr, ['stmts' => [$stmt]]);
|
||||
return new If_($condExpr, ['stmts' => [$stmt]]);
|
||||
}
|
||||
private function matchComparedAndReturnedNode(NotIdentical $notIdentical, Return_ $return) : ?Expr
|
||||
{
|
||||
|
|
|
@ -9,4 +9,4 @@ if (PHP_VERSION_ID < 50600) {
|
|||
|
||||
require_once __DIR__ . '/composer/autoload_real.php';
|
||||
|
||||
return ComposerAutoloaderInit23a203334751054f9dcaf69831e79efd::getLoader();
|
||||
return ComposerAutoloaderInit83af4ed37a67c995d5c32428732bd8ba::getLoader();
|
||||
|
|
|
@ -1930,6 +1930,8 @@ return array(
|
|||
'Rector\\DowngradePhp81\\Rector\\Instanceof_\\DowngradePhp81ResourceReturnToObjectRector' => $vendorDir . '/rector/rector-downgrade-php/rules/DowngradePhp81/Rector/Instanceof_/DowngradePhp81ResourceReturnToObjectRector.php',
|
||||
'Rector\\DowngradePhp81\\Rector\\Property\\DowngradeReadonlyPropertyRector' => $vendorDir . '/rector/rector-downgrade-php/rules/DowngradePhp81/Rector/Property/DowngradeReadonlyPropertyRector.php',
|
||||
'Rector\\DowngradePhp82\\Rector\\Class_\\DowngradeReadonlyClassRector' => $vendorDir . '/rector/rector-downgrade-php/rules/DowngradePhp82/Rector/Class_/DowngradeReadonlyClassRector.php',
|
||||
'Rector\\EarlyReturn\\NodeAnalyzer\\IfAndAnalyzer' => $baseDir . '/rules/EarlyReturn/NodeAnalyzer/IfAndAnalyzer.php',
|
||||
'Rector\\EarlyReturn\\NodeAnalyzer\\SimpleScalarAnalyzer' => $baseDir . '/rules/EarlyReturn/NodeAnalyzer/SimpleScalarAnalyzer.php',
|
||||
'Rector\\EarlyReturn\\NodeFactory\\InvertedIfFactory' => $baseDir . '/rules/EarlyReturn/NodeFactory/InvertedIfFactory.php',
|
||||
'Rector\\EarlyReturn\\NodeTransformer\\ConditionInverter' => $baseDir . '/rules/EarlyReturn/NodeTransformer/ConditionInverter.php',
|
||||
'Rector\\EarlyReturn\\Rector\\Foreach_\\ChangeNestedForeachIfsToEarlyContinueRector' => $baseDir . '/rules/EarlyReturn/Rector/Foreach_/ChangeNestedForeachIfsToEarlyContinueRector.php',
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
// autoload_real.php @generated by Composer
|
||||
|
||||
class ComposerAutoloaderInit23a203334751054f9dcaf69831e79efd
|
||||
class ComposerAutoloaderInit83af4ed37a67c995d5c32428732bd8ba
|
||||
{
|
||||
private static $loader;
|
||||
|
||||
|
@ -22,19 +22,19 @@ class ComposerAutoloaderInit23a203334751054f9dcaf69831e79efd
|
|||
return self::$loader;
|
||||
}
|
||||
|
||||
spl_autoload_register(array('ComposerAutoloaderInit23a203334751054f9dcaf69831e79efd', 'loadClassLoader'), true, true);
|
||||
spl_autoload_register(array('ComposerAutoloaderInit83af4ed37a67c995d5c32428732bd8ba', 'loadClassLoader'), true, true);
|
||||
self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__));
|
||||
spl_autoload_unregister(array('ComposerAutoloaderInit23a203334751054f9dcaf69831e79efd', 'loadClassLoader'));
|
||||
spl_autoload_unregister(array('ComposerAutoloaderInit83af4ed37a67c995d5c32428732bd8ba', 'loadClassLoader'));
|
||||
|
||||
require __DIR__ . '/autoload_static.php';
|
||||
call_user_func(\Composer\Autoload\ComposerStaticInit23a203334751054f9dcaf69831e79efd::getInitializer($loader));
|
||||
call_user_func(\Composer\Autoload\ComposerStaticInit83af4ed37a67c995d5c32428732bd8ba::getInitializer($loader));
|
||||
|
||||
$loader->setClassMapAuthoritative(true);
|
||||
$loader->register(true);
|
||||
|
||||
$includeFiles = \Composer\Autoload\ComposerStaticInit23a203334751054f9dcaf69831e79efd::$files;
|
||||
$includeFiles = \Composer\Autoload\ComposerStaticInit83af4ed37a67c995d5c32428732bd8ba::$files;
|
||||
foreach ($includeFiles as $fileIdentifier => $file) {
|
||||
composerRequire23a203334751054f9dcaf69831e79efd($fileIdentifier, $file);
|
||||
composerRequire83af4ed37a67c995d5c32428732bd8ba($fileIdentifier, $file);
|
||||
}
|
||||
|
||||
return $loader;
|
||||
|
@ -46,7 +46,7 @@ class ComposerAutoloaderInit23a203334751054f9dcaf69831e79efd
|
|||
* @param string $file
|
||||
* @return void
|
||||
*/
|
||||
function composerRequire23a203334751054f9dcaf69831e79efd($fileIdentifier, $file)
|
||||
function composerRequire83af4ed37a67c995d5c32428732bd8ba($fileIdentifier, $file)
|
||||
{
|
||||
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
|
||||
$GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
namespace Composer\Autoload;
|
||||
|
||||
class ComposerStaticInit23a203334751054f9dcaf69831e79efd
|
||||
class ComposerStaticInit83af4ed37a67c995d5c32428732bd8ba
|
||||
{
|
||||
public static $files = array (
|
||||
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php',
|
||||
|
@ -2227,6 +2227,8 @@ class ComposerStaticInit23a203334751054f9dcaf69831e79efd
|
|||
'Rector\\DowngradePhp81\\Rector\\Instanceof_\\DowngradePhp81ResourceReturnToObjectRector' => __DIR__ . '/..' . '/rector/rector-downgrade-php/rules/DowngradePhp81/Rector/Instanceof_/DowngradePhp81ResourceReturnToObjectRector.php',
|
||||
'Rector\\DowngradePhp81\\Rector\\Property\\DowngradeReadonlyPropertyRector' => __DIR__ . '/..' . '/rector/rector-downgrade-php/rules/DowngradePhp81/Rector/Property/DowngradeReadonlyPropertyRector.php',
|
||||
'Rector\\DowngradePhp82\\Rector\\Class_\\DowngradeReadonlyClassRector' => __DIR__ . '/..' . '/rector/rector-downgrade-php/rules/DowngradePhp82/Rector/Class_/DowngradeReadonlyClassRector.php',
|
||||
'Rector\\EarlyReturn\\NodeAnalyzer\\IfAndAnalyzer' => __DIR__ . '/../..' . '/rules/EarlyReturn/NodeAnalyzer/IfAndAnalyzer.php',
|
||||
'Rector\\EarlyReturn\\NodeAnalyzer\\SimpleScalarAnalyzer' => __DIR__ . '/../..' . '/rules/EarlyReturn/NodeAnalyzer/SimpleScalarAnalyzer.php',
|
||||
'Rector\\EarlyReturn\\NodeFactory\\InvertedIfFactory' => __DIR__ . '/../..' . '/rules/EarlyReturn/NodeFactory/InvertedIfFactory.php',
|
||||
'Rector\\EarlyReturn\\NodeTransformer\\ConditionInverter' => __DIR__ . '/../..' . '/rules/EarlyReturn/NodeTransformer/ConditionInverter.php',
|
||||
'Rector\\EarlyReturn\\Rector\\Foreach_\\ChangeNestedForeachIfsToEarlyContinueRector' => __DIR__ . '/../..' . '/rules/EarlyReturn/Rector/Foreach_/ChangeNestedForeachIfsToEarlyContinueRector.php',
|
||||
|
@ -3258,9 +3260,9 @@ class ComposerStaticInit23a203334751054f9dcaf69831e79efd
|
|||
public static function getInitializer(ClassLoader $loader)
|
||||
{
|
||||
return \Closure::bind(function () use ($loader) {
|
||||
$loader->prefixLengthsPsr4 = ComposerStaticInit23a203334751054f9dcaf69831e79efd::$prefixLengthsPsr4;
|
||||
$loader->prefixDirsPsr4 = ComposerStaticInit23a203334751054f9dcaf69831e79efd::$prefixDirsPsr4;
|
||||
$loader->classMap = ComposerStaticInit23a203334751054f9dcaf69831e79efd::$classMap;
|
||||
$loader->prefixLengthsPsr4 = ComposerStaticInit83af4ed37a67c995d5c32428732bd8ba::$prefixLengthsPsr4;
|
||||
$loader->prefixDirsPsr4 = ComposerStaticInit83af4ed37a67c995d5c32428732bd8ba::$prefixDirsPsr4;
|
||||
$loader->classMap = ComposerStaticInit83af4ed37a67c995d5c32428732bd8ba::$classMap;
|
||||
|
||||
}, null, ClassLoader::class);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue