Updated Rector to commit 1cc39145a5e35b926f0cf96fb0c3c12321154d7a

1cc39145a5 [PHP 8.0] Extract AssignMatchTransformer (#2805)
This commit is contained in:
Tomas Votruba 2022-08-19 13:40:05 +00:00
parent 95f1eab654
commit 0bc18b2647
8 changed files with 159 additions and 74 deletions

View File

@ -0,0 +1,94 @@
<?php
declare (strict_types=1);
namespace Rector\Php80\NodeManipulator;
use PhpParser\Node\Expr;
use PhpParser\Node\Expr\Assign;
use PhpParser\Node\Expr\Match_;
use PhpParser\Node\MatchArm;
use PhpParser\Node\Stmt;
use PhpParser\Node\Stmt\Expression;
use PhpParser\Node\Stmt\Return_;
use Rector\Core\PhpParser\Comparing\NodeComparator;
use Rector\Core\PhpParser\Node\BetterNodeFinder;
use Rector\Php80\ValueObject\MatchAssignResult;
final class AssignMatchTransformer
{
/**
* @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 unwrapMatchArmAssignsToAssign(Match_ $match, Expr $expr, bool $hasDefaultValue, ?Stmt $previousStmt, ?Stmt $nextStmt) : ?MatchAssignResult
{
// containts next this expr?
if (!$hasDefaultValue && $this->isFollowedByReturnWithExprUsage($nextStmt, $expr)) {
return null;
}
$prevInitializedAssign = $this->resolvePreviousInitializedAssign($previousStmt, $expr);
$assign = new Assign($expr, $match);
if (!$prevInitializedAssign instanceof Assign) {
$currentAssign = $this->resolveCurrentAssign($hasDefaultValue, $assign);
if ($currentAssign instanceof Assign) {
return new MatchAssignResult($currentAssign, \false);
}
return null;
}
$matchArmCount = \count($match->arms);
if ($hasDefaultValue) {
$default = $match->arms[$matchArmCount - 1]->body;
if ($this->nodeComparator->areNodesEqual($default, $prevInitializedAssign->var)) {
return new MatchAssignResult($assign, \false);
}
} else {
$match->arms[$matchArmCount] = new MatchArm(null, $prevInitializedAssign->expr);
}
return new MatchAssignResult($assign, \true);
}
private function resolveCurrentAssign(bool $hasDefaultValue, Assign $assign) : ?Assign
{
return $hasDefaultValue ? $assign : null;
}
private function isFollowedByReturnWithExprUsage(?\PhpParser\Node\Stmt $nextStmt, Expr $expr) : bool
{
if (!$nextStmt instanceof Return_) {
return \false;
}
if (!$nextStmt->expr instanceof Expr) {
return \false;
}
$returnExprs = $this->betterNodeFinder->findInstanceOf($nextStmt, Expr::class);
foreach ($returnExprs as $returnExpr) {
if ($this->nodeComparator->areNodesEqual($expr, $returnExpr)) {
return \true;
}
}
return \false;
}
private function resolvePreviousInitializedAssign(?Stmt $previousStmt, Expr $expr) : ?Assign
{
if (!$previousStmt instanceof Expression) {
return null;
}
$previousExpr = $previousStmt->expr;
if (!$previousExpr instanceof Assign) {
return null;
}
// is that assign to our variable?
if (!$this->nodeComparator->areNodesEqual($previousExpr->var, $expr)) {
return null;
}
return $previousExpr;
}
}

View File

@ -6,22 +6,20 @@ namespace Rector\Php80\Rector\Switch_;
use PhpParser\Node;
use PhpParser\Node\Expr;
use PhpParser\Node\Expr\Assign;
use PhpParser\Node\Expr\Match_;
use PhpParser\Node\Expr\Throw_;
use PhpParser\Node\MatchArm;
use PhpParser\Node\Stmt;
use PhpParser\Node\Stmt\Expression;
use PhpParser\Node\Stmt\Return_;
use PhpParser\Node\Stmt\Switch_;
use Rector\Core\Contract\PhpParser\Node\StmtsAwareInterface;
use Rector\Core\Rector\AbstractRector;
use Rector\Core\ValueObject\PhpVersionFeature;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\Php80\Enum\MatchKind;
use Rector\Php80\NodeAnalyzer\MatchSwitchAnalyzer;
use Rector\Php80\NodeFactory\MatchFactory;
use Rector\Php80\NodeManipulator\AssignMatchTransformer;
use Rector\Php80\NodeResolver\SwitchExprsResolver;
use Rector\Php80\ValueObject\CondAndExpr;
use Rector\Php80\ValueObject\MatchAssignResult;
use Rector\Php80\ValueObject\MatchResult;
use Rector\VersionBonding\Contract\MinPhpVersionInterface;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
@ -49,11 +47,17 @@ final class ChangeSwitchToMatchRector extends AbstractRector implements MinPhpVe
* @var \Rector\Php80\NodeFactory\MatchFactory
*/
private $matchFactory;
public function __construct(SwitchExprsResolver $switchExprsResolver, MatchSwitchAnalyzer $matchSwitchAnalyzer, MatchFactory $matchFactory)
/**
* @readonly
* @var \Rector\Php80\NodeManipulator\AssignMatchTransformer
*/
private $assignMatchTransformer;
public function __construct(SwitchExprsResolver $switchExprsResolver, MatchSwitchAnalyzer $matchSwitchAnalyzer, MatchFactory $matchFactory, AssignMatchTransformer $assignMatchTransformer)
{
$this->switchExprsResolver = $switchExprsResolver;
$this->matchSwitchAnalyzer = $matchSwitchAnalyzer;
$this->matchFactory = $matchFactory;
$this->assignMatchTransformer = $assignMatchTransformer;
}
public function getRuleDefinition() : RuleDefinition
{
@ -132,10 +136,14 @@ CODE_SAMPLE
$hasDefaultValue = $this->matchSwitchAnalyzer->hasDefaultValue($match);
if ($assignVar instanceof Expr) {
$previousStmt = $node->stmts[$key - 1] ?? null;
$assign = $this->changeToAssign($match, $assignVar, $hasDefaultValue, $previousStmt, $nextStmt);
if (!$assign instanceof Assign) {
$assignResult = $this->assignMatchTransformer->unwrapMatchArmAssignsToAssign($match, $assignVar, $hasDefaultValue, $previousStmt, $nextStmt);
if (!$assignResult instanceof MatchAssignResult) {
continue;
}
$assign = $assignResult->getAssign();
if ($assignResult->isShouldRemovePreviousStmt()) {
unset($node->stmts[$key - 1]);
}
$node->stmts[$key] = new Expression($assign);
$hasChanged = \true;
continue;
@ -155,43 +163,6 @@ CODE_SAMPLE
{
return PhpVersionFeature::MATCH_EXPRESSION;
}
private function changeToAssign(Match_ $match, Expr $expr, bool $hasDefaultValue, ?Stmt $previousStmt, ?Stmt $nextStmt) : ?Assign
{
// containts next this expr?
if (!$hasDefaultValue && $this->isFollowedByReturnWithExprUsage($nextStmt, $expr)) {
return null;
}
// @todo extract?
$prevInitializedAssign = null;
if ($previousStmt instanceof Expression) {
$previousExpr = $previousStmt->expr;
if ($previousExpr instanceof Assign && $this->nodeComparator->areNodesEqual($previousExpr->var, $expr)) {
$prevInitializedAssign = $previousExpr;
}
}
$assign = new Assign($expr, $match);
if (!$prevInitializedAssign instanceof Assign) {
return $this->resolveCurrentAssign($hasDefaultValue, $assign);
}
if ($hasDefaultValue) {
$default = $match->arms[\count($match->arms) - 1]->body;
if ($this->nodeComparator->areNodesEqual($default, $prevInitializedAssign->var)) {
return $assign;
}
} else {
$lastArmPosition = \count($match->arms);
$match->arms[$lastArmPosition] = new MatchArm(null, $prevInitializedAssign->expr);
}
$node = $prevInitializedAssign->getAttribute(AttributeKey::PARENT_NODE);
if ($node instanceof Expression) {
$this->removeNode($node);
}
return $assign;
}
private function resolveCurrentAssign(bool $hasDefaultValue, Assign $assign) : ?Assign
{
return $hasDefaultValue ? $assign : null;
}
/**
* @param CondAndExpr[] $condAndExprs
*/
@ -206,20 +177,4 @@ CODE_SAMPLE
}
return null;
}
private function isFollowedByReturnWithExprUsage(?\PhpParser\Node\Stmt $nextStmt, Expr $expr) : bool
{
if (!$nextStmt instanceof Return_) {
return \false;
}
if (!$nextStmt->expr instanceof Expr) {
return \false;
}
$returnExprs = $this->betterNodeFinder->findInstanceOf($nextStmt, Expr::class);
foreach ($returnExprs as $returnExpr) {
if ($this->nodeComparator->areNodesEqual($expr, $returnExpr)) {
return \true;
}
}
return \false;
}
}

View File

@ -0,0 +1,32 @@
<?php
declare (strict_types=1);
namespace Rector\Php80\ValueObject;
use PhpParser\Node\Expr\Assign;
final class MatchAssignResult
{
/**
* @readonly
* @var \PhpParser\Node\Expr\Assign
*/
private $assign;
/**
* @readonly
* @var bool
*/
private $shouldRemovePrevoiusStmt;
public function __construct(Assign $assign, bool $shouldRemovePrevoiusStmt)
{
$this->assign = $assign;
$this->shouldRemovePrevoiusStmt = $shouldRemovePrevoiusStmt;
}
public function getAssign() : Assign
{
return $this->assign;
}
public function isShouldRemovePreviousStmt() : bool
{
return $this->shouldRemovePrevoiusStmt;
}
}

View File

@ -17,12 +17,12 @@ final class VersionResolver
* @api
* @var string
*/
public const PACKAGE_VERSION = '7f7bb193c5f16dec72e4a9a15f9e1a9eae902985';
public const PACKAGE_VERSION = '1cc39145a5e35b926f0cf96fb0c3c12321154d7a';
/**
* @api
* @var string
*/
public const RELEASE_DATE = '2022-08-19 15:21:43';
public const RELEASE_DATE = '2022-08-19 13:35:52';
/**
* @var int
*/

2
vendor/autoload.php vendored
View File

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

View File

@ -2369,6 +2369,7 @@ return array(
'Rector\\Php80\\NodeFactory\\MatchFactory' => $baseDir . '/rules/Php80/NodeFactory/MatchFactory.php',
'Rector\\Php80\\NodeFactory\\NestedAttrGroupsFactory' => $baseDir . '/rules/Php80/NodeFactory/NestedAttrGroupsFactory.php',
'Rector\\Php80\\NodeFactory\\StrStartsWithFuncCallFactory' => $baseDir . '/rules/Php80/NodeFactory/StrStartsWithFuncCallFactory.php',
'Rector\\Php80\\NodeManipulator\\AssignMatchTransformer' => $baseDir . '/rules/Php80/NodeManipulator/AssignMatchTransformer.php',
'Rector\\Php80\\NodeManipulator\\AttributeGroupNamedArgumentManipulator' => $baseDir . '/rules/Php80/NodeManipulator/AttributeGroupNamedArgumentManipulator.php',
'Rector\\Php80\\NodeManipulator\\ResourceReturnToObject' => $baseDir . '/rules/Php80/NodeManipulator/ResourceReturnToObject.php',
'Rector\\Php80\\NodeManipulator\\TokenManipulator' => $baseDir . '/rules/Php80/NodeManipulator/TokenManipulator.php',
@ -2400,6 +2401,7 @@ return array(
'Rector\\Php80\\ValueObject\\ClassNameAndTagValueNode' => $baseDir . '/rules/Php80/ValueObject/ClassNameAndTagValueNode.php',
'Rector\\Php80\\ValueObject\\CondAndExpr' => $baseDir . '/rules/Php80/ValueObject/CondAndExpr.php',
'Rector\\Php80\\ValueObject\\DoctrineTagAndAnnotationToAttribute' => $baseDir . '/rules/Php80/ValueObject/DoctrineTagAndAnnotationToAttribute.php',
'Rector\\Php80\\ValueObject\\MatchAssignResult' => $baseDir . '/rules/Php80/ValueObject/MatchAssignResult.php',
'Rector\\Php80\\ValueObject\\MatchResult' => $baseDir . '/rules/Php80/ValueObject/MatchResult.php',
'Rector\\Php80\\ValueObject\\NestedAnnotationToAttribute' => $baseDir . '/rules/Php80/ValueObject/NestedAnnotationToAttribute.php',
'Rector\\Php80\\ValueObject\\NestedDoctrineTagAndAnnotationToAttribute' => $baseDir . '/rules/Php80/ValueObject/NestedDoctrineTagAndAnnotationToAttribute.php',

View File

@ -2,7 +2,7 @@
// autoload_real.php @generated by Composer
class ComposerAutoloaderInitcfa8797e6218a2451bd84105dd9b6e87
class ComposerAutoloaderInit59fcfe89c117908f50df1d31a6e02df0
{
private static $loader;
@ -22,19 +22,19 @@ class ComposerAutoloaderInitcfa8797e6218a2451bd84105dd9b6e87
return self::$loader;
}
spl_autoload_register(array('ComposerAutoloaderInitcfa8797e6218a2451bd84105dd9b6e87', 'loadClassLoader'), true, true);
spl_autoload_register(array('ComposerAutoloaderInit59fcfe89c117908f50df1d31a6e02df0', 'loadClassLoader'), true, true);
self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__));
spl_autoload_unregister(array('ComposerAutoloaderInitcfa8797e6218a2451bd84105dd9b6e87', 'loadClassLoader'));
spl_autoload_unregister(array('ComposerAutoloaderInit59fcfe89c117908f50df1d31a6e02df0', 'loadClassLoader'));
require __DIR__ . '/autoload_static.php';
call_user_func(\Composer\Autoload\ComposerStaticInitcfa8797e6218a2451bd84105dd9b6e87::getInitializer($loader));
call_user_func(\Composer\Autoload\ComposerStaticInit59fcfe89c117908f50df1d31a6e02df0::getInitializer($loader));
$loader->setClassMapAuthoritative(true);
$loader->register(true);
$includeFiles = \Composer\Autoload\ComposerStaticInitcfa8797e6218a2451bd84105dd9b6e87::$files;
$includeFiles = \Composer\Autoload\ComposerStaticInit59fcfe89c117908f50df1d31a6e02df0::$files;
foreach ($includeFiles as $fileIdentifier => $file) {
composerRequirecfa8797e6218a2451bd84105dd9b6e87($fileIdentifier, $file);
composerRequire59fcfe89c117908f50df1d31a6e02df0($fileIdentifier, $file);
}
return $loader;
@ -46,7 +46,7 @@ class ComposerAutoloaderInitcfa8797e6218a2451bd84105dd9b6e87
* @param string $file
* @return void
*/
function composerRequirecfa8797e6218a2451bd84105dd9b6e87($fileIdentifier, $file)
function composerRequire59fcfe89c117908f50df1d31a6e02df0($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 ComposerStaticInitcfa8797e6218a2451bd84105dd9b6e87
class ComposerStaticInit59fcfe89c117908f50df1d31a6e02df0
{
public static $files = array (
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php',
@ -2666,6 +2666,7 @@ class ComposerStaticInitcfa8797e6218a2451bd84105dd9b6e87
'Rector\\Php80\\NodeFactory\\MatchFactory' => __DIR__ . '/../..' . '/rules/Php80/NodeFactory/MatchFactory.php',
'Rector\\Php80\\NodeFactory\\NestedAttrGroupsFactory' => __DIR__ . '/../..' . '/rules/Php80/NodeFactory/NestedAttrGroupsFactory.php',
'Rector\\Php80\\NodeFactory\\StrStartsWithFuncCallFactory' => __DIR__ . '/../..' . '/rules/Php80/NodeFactory/StrStartsWithFuncCallFactory.php',
'Rector\\Php80\\NodeManipulator\\AssignMatchTransformer' => __DIR__ . '/../..' . '/rules/Php80/NodeManipulator/AssignMatchTransformer.php',
'Rector\\Php80\\NodeManipulator\\AttributeGroupNamedArgumentManipulator' => __DIR__ . '/../..' . '/rules/Php80/NodeManipulator/AttributeGroupNamedArgumentManipulator.php',
'Rector\\Php80\\NodeManipulator\\ResourceReturnToObject' => __DIR__ . '/../..' . '/rules/Php80/NodeManipulator/ResourceReturnToObject.php',
'Rector\\Php80\\NodeManipulator\\TokenManipulator' => __DIR__ . '/../..' . '/rules/Php80/NodeManipulator/TokenManipulator.php',
@ -2697,6 +2698,7 @@ class ComposerStaticInitcfa8797e6218a2451bd84105dd9b6e87
'Rector\\Php80\\ValueObject\\ClassNameAndTagValueNode' => __DIR__ . '/../..' . '/rules/Php80/ValueObject/ClassNameAndTagValueNode.php',
'Rector\\Php80\\ValueObject\\CondAndExpr' => __DIR__ . '/../..' . '/rules/Php80/ValueObject/CondAndExpr.php',
'Rector\\Php80\\ValueObject\\DoctrineTagAndAnnotationToAttribute' => __DIR__ . '/../..' . '/rules/Php80/ValueObject/DoctrineTagAndAnnotationToAttribute.php',
'Rector\\Php80\\ValueObject\\MatchAssignResult' => __DIR__ . '/../..' . '/rules/Php80/ValueObject/MatchAssignResult.php',
'Rector\\Php80\\ValueObject\\MatchResult' => __DIR__ . '/../..' . '/rules/Php80/ValueObject/MatchResult.php',
'Rector\\Php80\\ValueObject\\NestedAnnotationToAttribute' => __DIR__ . '/../..' . '/rules/Php80/ValueObject/NestedAnnotationToAttribute.php',
'Rector\\Php80\\ValueObject\\NestedDoctrineTagAndAnnotationToAttribute' => __DIR__ . '/../..' . '/rules/Php80/ValueObject/NestedDoctrineTagAndAnnotationToAttribute.php',
@ -3254,9 +3256,9 @@ class ComposerStaticInitcfa8797e6218a2451bd84105dd9b6e87
public static function getInitializer(ClassLoader $loader)
{
return \Closure::bind(function () use ($loader) {
$loader->prefixLengthsPsr4 = ComposerStaticInitcfa8797e6218a2451bd84105dd9b6e87::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInitcfa8797e6218a2451bd84105dd9b6e87::$prefixDirsPsr4;
$loader->classMap = ComposerStaticInitcfa8797e6218a2451bd84105dd9b6e87::$classMap;
$loader->prefixLengthsPsr4 = ComposerStaticInit59fcfe89c117908f50df1d31a6e02df0::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInit59fcfe89c117908f50df1d31a6e02df0::$prefixDirsPsr4;
$loader->classMap = ComposerStaticInit59fcfe89c117908f50df1d31a6e02df0::$classMap;
}, null, ClassLoader::class);
}