Updated Rector to commit 23bad1ec21a1ba71c748073cae083ce55484e1a7

23bad1ec21 [EarlyReturn] Add ReturnEarlyIfVariableRector (#2609)
This commit is contained in:
Tomas Votruba 2022-07-02 22:36:41 +00:00
parent 3ebe5dd36e
commit 2ef7fcfcd2
11 changed files with 177 additions and 17 deletions

View File

@ -15,6 +15,7 @@ use Rector\EarlyReturn\Rector\If_\RemoveAlwaysElseRector;
use Rector\EarlyReturn\Rector\Return_\PreparedValueToEarlyReturnRector;
use Rector\EarlyReturn\Rector\Return_\ReturnBinaryAndToEarlyReturnRector;
use Rector\EarlyReturn\Rector\Return_\ReturnBinaryOrToEarlyReturnRector;
use Rector\EarlyReturn\Rector\StmtsAwareInterface\ReturnEarlyIfVariableRector;
return static function (RectorConfig $rectorConfig) : void {
$rectorConfig->rule(ChangeNestedForeachIfsToEarlyContinueRector::class);
$rectorConfig->rule(ChangeAndIfToEarlyReturnRector::class);
@ -27,4 +28,5 @@ return static function (RectorConfig $rectorConfig) : void {
$rectorConfig->rule(ReturnAfterToEarlyOnBreakRector::class);
$rectorConfig->rule(PreparedValueToEarlyReturnRector::class);
$rectorConfig->rule(ReturnBinaryOrToEarlyReturnRector::class);
$rectorConfig->rule(ReturnEarlyIfVariableRector::class);
};

View File

@ -23,7 +23,7 @@ final class AssignVariableTypeResolver
$variableType = $this->nodeTypeResolver->getType($assign->var);
$exprType = $this->nodeTypeResolver->getType($assign->expr);
if ($exprType instanceof UnionType) {
$variableType = $exprType;
return $exprType;
}
return $variableType;
}

View File

@ -0,0 +1,142 @@
<?php
declare (strict_types=1);
namespace Rector\EarlyReturn\Rector\StmtsAwareInterface;
use PhpParser\Node;
use PhpParser\Node\Expr;
use PhpParser\Node\Expr\Assign;
use PhpParser\Node\Expr\Variable;
use PhpParser\Node\Stmt;
use PhpParser\Node\Stmt\Expression;
use PhpParser\Node\Stmt\If_;
use PhpParser\Node\Stmt\Return_;
use Rector\Core\Contract\PhpParser\Node\StmtsAwareInterface;
use Rector\Core\NodeAnalyzer\VariableAnalyzer;
use Rector\Core\Rector\AbstractRector;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* @see \Rector\Tests\EarlyReturn\Rector\StmtsAwareInterface\ReturnEarlyIfVariableRector\ReturnEarlyIfVariableRectorTest
*/
final class ReturnEarlyIfVariableRector extends AbstractRector
{
/**
* @readonly
* @var \Rector\Core\NodeAnalyzer\VariableAnalyzer
*/
private $variableAnalyzer;
public function __construct(VariableAnalyzer $variableAnalyzer)
{
$this->variableAnalyzer = $variableAnalyzer;
}
public function getRuleDefinition() : RuleDefinition
{
return new RuleDefinition('Replace if conditioned variable override with direct return', [new CodeSample(<<<'CODE_SAMPLE'
final class SomeClass
{
public function run($value)
{
if ($value === 50) {
$value = 100;
}
return $value;
}
}
CODE_SAMPLE
, <<<'CODE_SAMPLE'
final class SomeClass
{
public function run($value)
{
if ($value === 50) {
return 100;
}
return $value;
}
}
CODE_SAMPLE
)]);
}
/**
* @return array<class-string<Node>>
*/
public function getNodeTypes() : array
{
return [StmtsAwareInterface::class];
}
/**
* @param StmtsAwareInterface $node
*/
public function refactor(Node $node) : ?Node
{
$stmts = (array) $node->stmts;
foreach ($stmts as $key => $stmt) {
$returnVariable = $this->matchNextStmtReturnVariable($node, $key);
if (!$returnVariable instanceof Variable) {
continue;
}
if ($stmt instanceof If_ && $stmt->else === null && $stmt->elseifs === []) {
// is single condition if
$if = $stmt;
if (\count($if->stmts) !== 1) {
continue;
}
$onlyIfStmt = $if->stmts[0];
$assignedExpr = $this->matchOnlyIfStmtReturnExpr($onlyIfStmt, $returnVariable);
if (!$assignedExpr instanceof Expr) {
continue;
}
$if->stmts[0] = new Return_($assignedExpr);
return $node;
}
}
return null;
}
/**
* @return \PhpParser\Node\Expr|null
*/
private function matchOnlyIfStmtReturnExpr(Stmt $onlyIfStmt, Variable $returnVariable)
{
if (!$onlyIfStmt instanceof Expression) {
return null;
}
if (!$onlyIfStmt->expr instanceof Assign) {
return null;
}
$assign = $onlyIfStmt->expr;
// assign to same variable that is returned
if (!$assign->var instanceof Variable) {
return null;
}
if ($this->variableAnalyzer->isUsedByReference($assign->var)) {
return null;
}
if (!$this->nodeComparator->areNodesEqual($assign->var, $returnVariable)) {
return null;
}
// return directly
return $assign->expr;
}
/**
* @return \PhpParser\Node\Expr\Variable|null
*/
private function matchNextStmtReturnVariable(StmtsAwareInterface $stmtsAware, int $key)
{
$nextStmt = $stmtsAware->stmts[$key + 1] ?? null;
// last item → stop
if (!$nextStmt instanceof Stmt) {
return null;
}
if (!$nextStmt instanceof Return_) {
return null;
}
// next return must be variable
if (!$nextStmt->expr instanceof Variable) {
return null;
}
return $nextStmt->expr;
}
}

View File

@ -154,7 +154,7 @@ final class PropertyNaming
}
// is AbstractClass
if (\strncmp($shortClassName, 'Abstract', \strlen('Abstract')) === 0) {
$shortClassName = Strings::substring($shortClassName, \strlen('Abstract'));
return Strings::substring($shortClassName, \strlen('Abstract'));
}
return $shortClassName;
}

View File

@ -92,7 +92,7 @@ final class ResourceReturnToObject
// - in the right position of BooleanOr, it be NeverType
// - the object changed after init
if (!$argValueType instanceof FullyQualifiedObjectType) {
$argValueType = $this->resolveArgValueTypeFromPreviousAssign($funcCall, $argResourceValue, $collectionFunctionToReturnObject);
return $this->resolveArgValueTypeFromPreviousAssign($funcCall, $argResourceValue, $collectionFunctionToReturnObject);
}
return $argValueType;
}

View File

@ -17,12 +17,12 @@ final class VersionResolver
* @api
* @var string
*/
public const PACKAGE_VERSION = '7222eccac1827abdb9ce1565ea18d2de0c98f743';
public const PACKAGE_VERSION = '23bad1ec21a1ba71c748073cae083ce55484e1a7';
/**
* @api
* @var string
*/
public const RELEASE_DATE = '2022-07-02 23:24:02';
public const RELEASE_DATE = '2022-07-03 00:30:52';
/**
* @var int
*/

View File

@ -6,6 +6,7 @@ namespace Rector\Core\NodeAnalyzer;
use PhpParser\Node;
use PhpParser\Node\Expr\ClosureUse;
use PhpParser\Node\Expr\Variable;
use PhpParser\Node\Param;
use PhpParser\Node\Stmt\Global_;
use PhpParser\Node\Stmt\Static_;
use PhpParser\Node\Stmt\StaticVar;
@ -55,6 +56,9 @@ final class VariableAnalyzer
public function isUsedByReference(Variable $variable) : bool
{
return (bool) $this->betterNodeFinder->findFirstPrevious($variable, function (Node $subNode) use($variable) : bool {
if ($this->isParamRefrenced($subNode, $variable)) {
return \true;
}
if (!$subNode instanceof Variable) {
return \false;
}
@ -83,4 +87,14 @@ final class VariableAnalyzer
$parentParentNode = $parentNode->getAttribute(AttributeKey::PARENT_NODE);
return $parentParentNode instanceof Static_;
}
private function isParamRefrenced(Node $node, Variable $variable) : bool
{
if (!$node instanceof Param) {
return \false;
}
if (!$this->nodeComparator->areNodesEqual($node->var, $variable)) {
return \false;
}
return $node->byRef;
}
}

2
vendor/autoload.php vendored
View File

@ -9,4 +9,4 @@ if (PHP_VERSION_ID < 50600) {
require_once __DIR__ . '/composer/autoload_real.php';
return ComposerAutoloaderInitba155cf4ae068d8f259d841ace7436d2::getLoader();
return ComposerAutoloaderInit70cb0b7998b14f59b5ef2112d08f87e3::getLoader();

View File

@ -1978,6 +1978,7 @@ return array(
'Rector\\EarlyReturn\\Rector\\Return_\\PreparedValueToEarlyReturnRector' => $baseDir . '/rules/EarlyReturn/Rector/Return_/PreparedValueToEarlyReturnRector.php',
'Rector\\EarlyReturn\\Rector\\Return_\\ReturnBinaryAndToEarlyReturnRector' => $baseDir . '/rules/EarlyReturn/Rector/Return_/ReturnBinaryAndToEarlyReturnRector.php',
'Rector\\EarlyReturn\\Rector\\Return_\\ReturnBinaryOrToEarlyReturnRector' => $baseDir . '/rules/EarlyReturn/Rector/Return_/ReturnBinaryOrToEarlyReturnRector.php',
'Rector\\EarlyReturn\\Rector\\StmtsAwareInterface\\ReturnEarlyIfVariableRector' => $baseDir . '/rules/EarlyReturn/Rector/StmtsAwareInterface/ReturnEarlyIfVariableRector.php',
'Rector\\FamilyTree\\NodeAnalyzer\\ClassChildAnalyzer' => $baseDir . '/packages/FamilyTree/NodeAnalyzer/ClassChildAnalyzer.php',
'Rector\\FamilyTree\\Reflection\\FamilyRelationsAnalyzer' => $baseDir . '/packages/FamilyTree/Reflection/FamilyRelationsAnalyzer.php',
'Rector\\FamilyTree\\ValueObject\\PropertyType' => $baseDir . '/packages/FamilyTree/ValueObject/PropertyType.php',

View File

@ -2,7 +2,7 @@
// autoload_real.php @generated by Composer
class ComposerAutoloaderInitba155cf4ae068d8f259d841ace7436d2
class ComposerAutoloaderInit70cb0b7998b14f59b5ef2112d08f87e3
{
private static $loader;
@ -22,19 +22,19 @@ class ComposerAutoloaderInitba155cf4ae068d8f259d841ace7436d2
return self::$loader;
}
spl_autoload_register(array('ComposerAutoloaderInitba155cf4ae068d8f259d841ace7436d2', 'loadClassLoader'), true, true);
spl_autoload_register(array('ComposerAutoloaderInit70cb0b7998b14f59b5ef2112d08f87e3', 'loadClassLoader'), true, true);
self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__));
spl_autoload_unregister(array('ComposerAutoloaderInitba155cf4ae068d8f259d841ace7436d2', 'loadClassLoader'));
spl_autoload_unregister(array('ComposerAutoloaderInit70cb0b7998b14f59b5ef2112d08f87e3', 'loadClassLoader'));
require __DIR__ . '/autoload_static.php';
call_user_func(\Composer\Autoload\ComposerStaticInitba155cf4ae068d8f259d841ace7436d2::getInitializer($loader));
call_user_func(\Composer\Autoload\ComposerStaticInit70cb0b7998b14f59b5ef2112d08f87e3::getInitializer($loader));
$loader->setClassMapAuthoritative(true);
$loader->register(true);
$includeFiles = \Composer\Autoload\ComposerStaticInitba155cf4ae068d8f259d841ace7436d2::$files;
$includeFiles = \Composer\Autoload\ComposerStaticInit70cb0b7998b14f59b5ef2112d08f87e3::$files;
foreach ($includeFiles as $fileIdentifier => $file) {
composerRequireba155cf4ae068d8f259d841ace7436d2($fileIdentifier, $file);
composerRequire70cb0b7998b14f59b5ef2112d08f87e3($fileIdentifier, $file);
}
return $loader;
@ -46,7 +46,7 @@ class ComposerAutoloaderInitba155cf4ae068d8f259d841ace7436d2
* @param string $file
* @return void
*/
function composerRequireba155cf4ae068d8f259d841ace7436d2($fileIdentifier, $file)
function composerRequire70cb0b7998b14f59b5ef2112d08f87e3($fileIdentifier, $file)
{
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
$GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;

View File

@ -4,7 +4,7 @@
namespace Composer\Autoload;
class ComposerStaticInitba155cf4ae068d8f259d841ace7436d2
class ComposerStaticInit70cb0b7998b14f59b5ef2112d08f87e3
{
public static $files = array (
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php',
@ -2285,6 +2285,7 @@ class ComposerStaticInitba155cf4ae068d8f259d841ace7436d2
'Rector\\EarlyReturn\\Rector\\Return_\\PreparedValueToEarlyReturnRector' => __DIR__ . '/../..' . '/rules/EarlyReturn/Rector/Return_/PreparedValueToEarlyReturnRector.php',
'Rector\\EarlyReturn\\Rector\\Return_\\ReturnBinaryAndToEarlyReturnRector' => __DIR__ . '/../..' . '/rules/EarlyReturn/Rector/Return_/ReturnBinaryAndToEarlyReturnRector.php',
'Rector\\EarlyReturn\\Rector\\Return_\\ReturnBinaryOrToEarlyReturnRector' => __DIR__ . '/../..' . '/rules/EarlyReturn/Rector/Return_/ReturnBinaryOrToEarlyReturnRector.php',
'Rector\\EarlyReturn\\Rector\\StmtsAwareInterface\\ReturnEarlyIfVariableRector' => __DIR__ . '/../..' . '/rules/EarlyReturn/Rector/StmtsAwareInterface/ReturnEarlyIfVariableRector.php',
'Rector\\FamilyTree\\NodeAnalyzer\\ClassChildAnalyzer' => __DIR__ . '/../..' . '/packages/FamilyTree/NodeAnalyzer/ClassChildAnalyzer.php',
'Rector\\FamilyTree\\Reflection\\FamilyRelationsAnalyzer' => __DIR__ . '/../..' . '/packages/FamilyTree/Reflection/FamilyRelationsAnalyzer.php',
'Rector\\FamilyTree\\ValueObject\\PropertyType' => __DIR__ . '/../..' . '/packages/FamilyTree/ValueObject/PropertyType.php',
@ -3418,9 +3419,9 @@ class ComposerStaticInitba155cf4ae068d8f259d841ace7436d2
public static function getInitializer(ClassLoader $loader)
{
return \Closure::bind(function () use ($loader) {
$loader->prefixLengthsPsr4 = ComposerStaticInitba155cf4ae068d8f259d841ace7436d2::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInitba155cf4ae068d8f259d841ace7436d2::$prefixDirsPsr4;
$loader->classMap = ComposerStaticInitba155cf4ae068d8f259d841ace7436d2::$classMap;
$loader->prefixLengthsPsr4 = ComposerStaticInit70cb0b7998b14f59b5ef2112d08f87e3::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInit70cb0b7998b14f59b5ef2112d08f87e3::$prefixDirsPsr4;
$loader->classMap = ComposerStaticInit70cb0b7998b14f59b5ef2112d08f87e3::$classMap;
}, null, ClassLoader::class);
}