Updated Rector to commit 81e9cbab101d6ef15de00b2da39d3095d7ad64fb

81e9cbab10 [Downgrade PHP 5.6] Add DowngradeArgumentUnpackingRector (#1219)
This commit is contained in:
Tomas Votruba 2021-11-13 14:51:42 +00:00
parent 2fe1ccafc6
commit 6cee4f1782
10 changed files with 335 additions and 19 deletions

View File

@ -5,6 +5,7 @@ namespace RectorPrefix20211113;
use Rector\Core\Configuration\Option;
use Rector\Core\ValueObject\PhpVersion;
use Rector\DowngradePhp56\Rector\CallLike\DowngradeArgumentUnpackingRector;
use Rector\DowngradePhp56\Rector\Pow\DowngradeExponentialAssignmentOperatorRector;
use Rector\DowngradePhp56\Rector\Pow\DowngradeExponentialOperatorRector;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
@ -12,6 +13,7 @@ return static function (\Symfony\Component\DependencyInjection\Loader\Configurat
$parameters = $containerConfigurator->parameters();
$parameters->set(\Rector\Core\Configuration\Option::PHP_VERSION_FEATURES, \Rector\Core\ValueObject\PhpVersion::PHP_55);
$services = $containerConfigurator->services();
$services->set(\Rector\DowngradePhp56\Rector\CallLike\DowngradeArgumentUnpackingRector::class);
$services->set(\Rector\DowngradePhp56\Rector\Pow\DowngradeExponentialAssignmentOperatorRector::class);
$services->set(\Rector\DowngradePhp56\Rector\Pow\DowngradeExponentialOperatorRector::class);
};

View File

@ -0,0 +1,47 @@
<?php
declare (strict_types=1);
namespace Rector\DowngradePhp56\NodeManipulator;
use PhpParser\Node\Arg;
use PhpParser\Node\Expr\Array_;
final class ArgManipulator
{
/**
* @param Arg[] $args
*/
public function hasUnpackedArg(array $args) : bool
{
foreach ($args as $arg) {
if ($arg->unpack) {
return \true;
}
}
return \false;
}
/**
* @param Arg[] $args
* @return Arg[]
*/
public function unpack(array $args) : array
{
$unpackedArgList = new \Rector\DowngradePhp56\NodeManipulator\UnpackedArgList($args);
return $unpackedArgList->toArray();
}
/**
* @param Arg[] $args
*/
public function canBeInlined(array $args) : bool
{
foreach ($args as $arg) {
if (!$arg->unpack) {
continue;
}
if ($arg->value instanceof \PhpParser\Node\Expr\Array_) {
continue;
}
return \false;
}
return \true;
}
}

View File

@ -0,0 +1,82 @@
<?php
declare (strict_types=1);
namespace Rector\DowngradePhp56\NodeManipulator;
use PhpParser\Node\Arg;
use PhpParser\Node\Expr\Array_;
use PhpParser\Node\Expr\ArrayItem;
final class UnpackedArgList
{
/**
* @var Arg[]
*/
private $args = [];
/**
* @var int
*/
private $pointer = 0;
/**
* @param Arg[] $args
*/
public function __construct(array $args = [])
{
foreach ($args as $arg) {
$this->addArg($arg);
}
}
/**
* @return Arg[]
*/
public function toArray() : array
{
return $this->args;
}
public function addArg(\PhpParser\Node\Arg $arg) : void
{
$this->args[$this->pointer] = $this->args[$this->pointer] ?? new \PhpParser\Node\Arg(new \PhpParser\Node\Expr\Array_());
if ($arg->unpack) {
$arg->unpack = \false;
$this->unpack($arg);
return;
}
$this->addAsItem($arg);
}
private function unpack(\PhpParser\Node\Arg $arg) : void
{
if ($arg->value instanceof \PhpParser\Node\Expr\Array_) {
foreach ($arg->value->items as $arrayItem) {
if ($arrayItem === null) {
continue;
}
$this->addArrayItem($arrayItem);
}
return;
}
$this->addNextArg($arg);
}
private function addAsItem(\PhpParser\Node\Arg $arg) : void
{
$this->addArrayItem(new \PhpParser\Node\Expr\ArrayItem($arg->value));
}
private function addArrayItem(\PhpParser\Node\Expr\ArrayItem $arrayItem) : void
{
/** @var Array_ $array */
$array = $this->args[$this->pointer]->value;
$array->items[] = $arrayItem;
}
private function addNextArg(\PhpParser\Node\Arg $arg) : void
{
$this->next();
$this->args[$this->pointer] = $arg;
++$this->pointer;
}
private function next() : void
{
/** @var Array_ $array */
$array = $this->args[$this->pointer]->value;
if ($array->items !== []) {
++$this->pointer;
}
}
}

View File

@ -0,0 +1,179 @@
<?php
declare (strict_types=1);
namespace Rector\DowngradePhp56\Rector\CallLike;
use PhpParser\Node;
use PhpParser\Node\Arg;
use PhpParser\Node\Expr;
use PhpParser\Node\Expr\Array_;
use PhpParser\Node\Expr\ArrayItem;
use PhpParser\Node\Expr\CallLike;
use PhpParser\Node\Expr\ClassConstFetch;
use PhpParser\Node\Expr\FuncCall;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Expr\New_;
use PhpParser\Node\Expr\StaticCall;
use PhpParser\Node\Identifier;
use PhpParser\Node\Name;
use PhpParser\Node\Scalar\String_;
use Rector\Core\Rector\AbstractRector;
use Rector\DowngradePhp56\NodeManipulator\ArgManipulator;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
use RectorPrefix20211113\Webmozart\Assert\Assert;
/**
* @changelog https://wiki.php.net/rfc/argument_unpacking
*
* @see \Rector\Tests\DowngradePhp56\Rector\CallLike\DowngradeArgumentUnpackingRector\DowngradeArgumentUnpackingRectorTest
*/
final class DowngradeArgumentUnpackingRector extends \Rector\Core\Rector\AbstractRector
{
/**
* @var \Rector\DowngradePhp56\NodeManipulator\ArgManipulator
*/
private $argManipulator;
public function __construct(\Rector\DowngradePhp56\NodeManipulator\ArgManipulator $argManipulator)
{
$this->argManipulator = $argManipulator;
}
public function getRuleDefinition() : \Symplify\RuleDocGenerator\ValueObject\RuleDefinition
{
return new \Symplify\RuleDocGenerator\ValueObject\RuleDefinition('Replace argument unpacking by call_user_func_array()', [new \Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample(<<<'CODE_SAMPLE'
class SomeClass
{
public function run(array $items)
{
some_function(...$items);
}
}
CODE_SAMPLE
, <<<'CODE_SAMPLE'
class SomeClass
{
public function run(array $items)
{
call_user_func_array('some_function', $items);
}
}
CODE_SAMPLE
)]);
}
/**
* @return array<class-string<Node>>
*/
public function getNodeTypes() : array
{
return [\PhpParser\Node\Expr\CallLike::class];
}
/**
* @param CallLike $node
*/
public function refactor(\PhpParser\Node $node) : ?\PhpParser\Node
{
$args = $node->getArgs();
if ($this->shouldSkip($args)) {
return null;
}
if ($node instanceof \PhpParser\Node\Expr\FuncCall) {
return $this->createCallUserFuncArrayFuncCall($this->funcCallToCallbackArg($node), $args);
}
if ($node instanceof \PhpParser\Node\Expr\MethodCall) {
return $this->createCallUserFuncArrayFuncCall($this->methodCallToCallbackArg($node), $args);
}
if ($node instanceof \PhpParser\Node\Expr\New_) {
return $this->createReflectionInstantiation($node, $args);
}
if ($node instanceof \PhpParser\Node\Expr\StaticCall) {
return $this->createCallUserFuncArrayFuncCall($this->staticCallToCallbackArg($node), $args);
}
return null;
}
/**
* @param Arg[] $args
*/
private function shouldSkip(array $args) : bool
{
return !$this->argManipulator->hasUnpackedArg($args);
}
private function funcCallToCallbackArg(\PhpParser\Node\Expr\FuncCall $funcCall) : \PhpParser\Node\Arg
{
$callback = $funcCall->name instanceof \PhpParser\Node\Name ? new \PhpParser\Node\Scalar\String_($funcCall->name->toString()) : $funcCall->name;
return new \PhpParser\Node\Arg($callback);
}
private function methodCallToCallbackArg(\PhpParser\Node\Expr\MethodCall $methodCall) : \PhpParser\Node\Arg
{
$object = $methodCall->var;
$method = $methodCall->name instanceof \PhpParser\Node\Identifier ? new \PhpParser\Node\Scalar\String_($methodCall->name->toString()) : $methodCall->name;
$array = new \PhpParser\Node\Expr\Array_([new \PhpParser\Node\Expr\ArrayItem($object), new \PhpParser\Node\Expr\ArrayItem($method)]);
return new \PhpParser\Node\Arg($array);
}
private function staticCallToCallbackArg(\PhpParser\Node\Expr\StaticCall $staticCall) : \PhpParser\Node\Arg
{
if ($staticCall->class instanceof \PhpParser\Node\Name) {
$class = $staticCall->class->isSpecialClassName() ? new \PhpParser\Node\Scalar\String_($staticCall->class->toString()) : new \PhpParser\Node\Expr\ClassConstFetch($staticCall->class, 'class');
} else {
$class = $staticCall->class;
}
$method = $staticCall->name instanceof \PhpParser\Node\Identifier ? new \PhpParser\Node\Scalar\String_($staticCall->name->toString()) : $staticCall->name;
$array = new \PhpParser\Node\Expr\Array_([new \PhpParser\Node\Expr\ArrayItem($class), new \PhpParser\Node\Expr\ArrayItem($method)]);
return new \PhpParser\Node\Arg($array);
}
/**
* @param Arg[] $args
*/
private function createCallUserFuncArrayFuncCall(\PhpParser\Node\Arg $arg, array $args) : \PhpParser\Node\Expr\FuncCall
{
return new \PhpParser\Node\Expr\FuncCall(new \PhpParser\Node\Name('call_user_func_array'), [$arg, $this->mergeArgs($args)]);
}
/**
* @param Arg[] $args
*/
private function mergeArgs(array $args) : \PhpParser\Node\Arg
{
$unpackedArgs = $this->argManipulator->unpack($args);
if (\count($unpackedArgs) === 1) {
return $unpackedArgs[0];
}
return new \PhpParser\Node\Arg(new \PhpParser\Node\Expr\FuncCall(new \PhpParser\Node\Name('array_merge'), $unpackedArgs));
}
/**
* @param Arg[] $args
*/
private function createReflectionInstantiation(\PhpParser\Node\Expr\New_ $new, array $args) : ?\PhpParser\Node\Expr
{
if ($this->argManipulator->canBeInlined($args)) {
$unpackedArgs = $this->argManipulator->unpack($args);
\RectorPrefix20211113\Webmozart\Assert\Assert::minCount($unpackedArgs, 1);
/** @var Array_ $array */
$array = $unpackedArgs[0]->value;
$arrayItems = \array_filter($array->items);
$new->args = \array_map(function (\PhpParser\Node\Expr\ArrayItem $item) : Arg {
return new \PhpParser\Node\Arg($item->value);
}, $arrayItems);
return $new;
}
if ($new->class instanceof \PhpParser\Node\Name) {
switch (\strtolower($new->class->toString())) {
case 'self':
$class = new \PhpParser\Node\Expr\FuncCall(new \PhpParser\Node\Name('get_class'));
break;
case 'static':
$class = new \PhpParser\Node\Expr\FuncCall(new \PhpParser\Node\Name('get_called_class'));
break;
case 'parent':
$class = new \PhpParser\Node\Expr\FuncCall(new \PhpParser\Node\Name('get_parent_class'));
break;
default:
$class = new \PhpParser\Node\Expr\ClassConstFetch($new->class, 'class');
break;
}
} elseif ($new->class instanceof \PhpParser\Node\Expr) {
$class = $new->class;
} else {
return null;
}
$newReflection = new \PhpParser\Node\Expr\New_(new \PhpParser\Node\Name('\\ReflectionClass'), [new \PhpParser\Node\Arg($class)]);
return new \PhpParser\Node\Expr\MethodCall($newReflection, 'newInstanceArgs', [$this->mergeArgs($args)]);
}
}

View File

@ -16,11 +16,11 @@ final class VersionResolver
/**
* @var string
*/
public const PACKAGE_VERSION = '096817b1afcd893e6c95677ff74058fc0c9f1628';
public const PACKAGE_VERSION = '81e9cbab101d6ef15de00b2da39d3095d7ad64fb';
/**
* @var string
*/
public const RELEASE_DATE = '2021-11-13 08:27:35';
public const RELEASE_DATE = '2021-11-13 17:36:52';
public static function resolvePackageVersion() : string
{
$process = new \RectorPrefix20211113\Symfony\Component\Process\Process(['git', 'log', '--pretty="%H"', '-n1', 'HEAD'], __DIR__);

2
vendor/autoload.php vendored
View File

@ -4,4 +4,4 @@
require_once __DIR__ . '/composer/autoload_real.php';
return ComposerAutoloaderInit69387b451e53fa05cffe87da5ea4f662::getLoader();
return ComposerAutoloaderInitba17b363b6d15060ff4e10e823b02404::getLoader();

View File

@ -1799,6 +1799,9 @@ return array(
'Rector\\DowngradePhp54\\Rector\\FunctionLike\\DowngradeCallableTypeDeclarationRector' => $baseDir . '/rules/DowngradePhp54/Rector/FunctionLike/DowngradeCallableTypeDeclarationRector.php',
'Rector\\DowngradePhp54\\Rector\\LNumber\\DowngradeBinaryNotationRector' => $baseDir . '/rules/DowngradePhp54/Rector/LNumber/DowngradeBinaryNotationRector.php',
'Rector\\DowngradePhp55\\Rector\\ClassConstFetch\\DowngradeClassConstantToStringRector' => $baseDir . '/rules/DowngradePhp55/Rector/ClassConstFetch/DowngradeClassConstantToStringRector.php',
'Rector\\DowngradePhp56\\NodeManipulator\\ArgManipulator' => $baseDir . '/rules/DowngradePhp56/NodeManipulator/ArgManipulator.php',
'Rector\\DowngradePhp56\\NodeManipulator\\UnpackedArgList' => $baseDir . '/rules/DowngradePhp56/NodeManipulator/UnpackedArgList.php',
'Rector\\DowngradePhp56\\Rector\\CallLike\\DowngradeArgumentUnpackingRector' => $baseDir . '/rules/DowngradePhp56/Rector/CallLike/DowngradeArgumentUnpackingRector.php',
'Rector\\DowngradePhp56\\Rector\\Pow\\DowngradeExponentialAssignmentOperatorRector' => $baseDir . '/rules/DowngradePhp56/Rector/Pow/DowngradeExponentialAssignmentOperatorRector.php',
'Rector\\DowngradePhp56\\Rector\\Pow\\DowngradeExponentialOperatorRector' => $baseDir . '/rules/DowngradePhp56/Rector/Pow/DowngradeExponentialOperatorRector.php',
'Rector\\DowngradePhp70\\NodeFactory\\ClassFromAnonymousFactory' => $baseDir . '/rules/DowngradePhp70/NodeFactory/ClassFromAnonymousFactory.php',

View File

@ -2,7 +2,7 @@
// autoload_real.php @generated by Composer
class ComposerAutoloaderInit69387b451e53fa05cffe87da5ea4f662
class ComposerAutoloaderInitba17b363b6d15060ff4e10e823b02404
{
private static $loader;
@ -22,15 +22,15 @@ class ComposerAutoloaderInit69387b451e53fa05cffe87da5ea4f662
return self::$loader;
}
spl_autoload_register(array('ComposerAutoloaderInit69387b451e53fa05cffe87da5ea4f662', 'loadClassLoader'), true, true);
spl_autoload_register(array('ComposerAutoloaderInitba17b363b6d15060ff4e10e823b02404', 'loadClassLoader'), true, true);
self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(\dirname(__FILE__)));
spl_autoload_unregister(array('ComposerAutoloaderInit69387b451e53fa05cffe87da5ea4f662', 'loadClassLoader'));
spl_autoload_unregister(array('ComposerAutoloaderInitba17b363b6d15060ff4e10e823b02404', 'loadClassLoader'));
$useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
if ($useStaticLoader) {
require __DIR__ . '/autoload_static.php';
call_user_func(\Composer\Autoload\ComposerStaticInit69387b451e53fa05cffe87da5ea4f662::getInitializer($loader));
call_user_func(\Composer\Autoload\ComposerStaticInitba17b363b6d15060ff4e10e823b02404::getInitializer($loader));
} else {
$classMap = require __DIR__ . '/autoload_classmap.php';
if ($classMap) {
@ -42,19 +42,19 @@ class ComposerAutoloaderInit69387b451e53fa05cffe87da5ea4f662
$loader->register(true);
if ($useStaticLoader) {
$includeFiles = Composer\Autoload\ComposerStaticInit69387b451e53fa05cffe87da5ea4f662::$files;
$includeFiles = Composer\Autoload\ComposerStaticInitba17b363b6d15060ff4e10e823b02404::$files;
} else {
$includeFiles = require __DIR__ . '/autoload_files.php';
}
foreach ($includeFiles as $fileIdentifier => $file) {
composerRequire69387b451e53fa05cffe87da5ea4f662($fileIdentifier, $file);
composerRequireba17b363b6d15060ff4e10e823b02404($fileIdentifier, $file);
}
return $loader;
}
}
function composerRequire69387b451e53fa05cffe87da5ea4f662($fileIdentifier, $file)
function composerRequireba17b363b6d15060ff4e10e823b02404($fileIdentifier, $file)
{
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
require $file;

View File

@ -4,7 +4,7 @@
namespace Composer\Autoload;
class ComposerStaticInit69387b451e53fa05cffe87da5ea4f662
class ComposerStaticInitba17b363b6d15060ff4e10e823b02404
{
public static $files = array (
'a4a119a56e50fbb293281d9a48007e0e' => __DIR__ . '/..' . '/symfony/polyfill-php80/bootstrap.php',
@ -2129,6 +2129,9 @@ class ComposerStaticInit69387b451e53fa05cffe87da5ea4f662
'Rector\\DowngradePhp54\\Rector\\FunctionLike\\DowngradeCallableTypeDeclarationRector' => __DIR__ . '/../..' . '/rules/DowngradePhp54/Rector/FunctionLike/DowngradeCallableTypeDeclarationRector.php',
'Rector\\DowngradePhp54\\Rector\\LNumber\\DowngradeBinaryNotationRector' => __DIR__ . '/../..' . '/rules/DowngradePhp54/Rector/LNumber/DowngradeBinaryNotationRector.php',
'Rector\\DowngradePhp55\\Rector\\ClassConstFetch\\DowngradeClassConstantToStringRector' => __DIR__ . '/../..' . '/rules/DowngradePhp55/Rector/ClassConstFetch/DowngradeClassConstantToStringRector.php',
'Rector\\DowngradePhp56\\NodeManipulator\\ArgManipulator' => __DIR__ . '/../..' . '/rules/DowngradePhp56/NodeManipulator/ArgManipulator.php',
'Rector\\DowngradePhp56\\NodeManipulator\\UnpackedArgList' => __DIR__ . '/../..' . '/rules/DowngradePhp56/NodeManipulator/UnpackedArgList.php',
'Rector\\DowngradePhp56\\Rector\\CallLike\\DowngradeArgumentUnpackingRector' => __DIR__ . '/../..' . '/rules/DowngradePhp56/Rector/CallLike/DowngradeArgumentUnpackingRector.php',
'Rector\\DowngradePhp56\\Rector\\Pow\\DowngradeExponentialAssignmentOperatorRector' => __DIR__ . '/../..' . '/rules/DowngradePhp56/Rector/Pow/DowngradeExponentialAssignmentOperatorRector.php',
'Rector\\DowngradePhp56\\Rector\\Pow\\DowngradeExponentialOperatorRector' => __DIR__ . '/../..' . '/rules/DowngradePhp56/Rector/Pow/DowngradeExponentialOperatorRector.php',
'Rector\\DowngradePhp70\\NodeFactory\\ClassFromAnonymousFactory' => __DIR__ . '/../..' . '/rules/DowngradePhp70/NodeFactory/ClassFromAnonymousFactory.php',
@ -3537,9 +3540,9 @@ class ComposerStaticInit69387b451e53fa05cffe87da5ea4f662
public static function getInitializer(ClassLoader $loader)
{
return \Closure::bind(function () use ($loader) {
$loader->prefixLengthsPsr4 = ComposerStaticInit69387b451e53fa05cffe87da5ea4f662::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInit69387b451e53fa05cffe87da5ea4f662::$prefixDirsPsr4;
$loader->classMap = ComposerStaticInit69387b451e53fa05cffe87da5ea4f662::$classMap;
$loader->prefixLengthsPsr4 = ComposerStaticInitba17b363b6d15060ff4e10e823b02404::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInitba17b363b6d15060ff4e10e823b02404::$prefixDirsPsr4;
$loader->classMap = ComposerStaticInitba17b363b6d15060ff4e10e823b02404::$classMap;
}, null, ClassLoader::class);
}

View File

@ -12,8 +12,8 @@ if (!class_exists('GenerateChangelogCommand', false) && !interface_exists('Gener
if (!class_exists('AutoloadIncluder', false) && !interface_exists('AutoloadIncluder', false) && !trait_exists('AutoloadIncluder', false)) {
spl_autoload_call('RectorPrefix20211113\AutoloadIncluder');
}
if (!class_exists('ComposerAutoloaderInit69387b451e53fa05cffe87da5ea4f662', false) && !interface_exists('ComposerAutoloaderInit69387b451e53fa05cffe87da5ea4f662', false) && !trait_exists('ComposerAutoloaderInit69387b451e53fa05cffe87da5ea4f662', false)) {
spl_autoload_call('RectorPrefix20211113\ComposerAutoloaderInit69387b451e53fa05cffe87da5ea4f662');
if (!class_exists('ComposerAutoloaderInitba17b363b6d15060ff4e10e823b02404', false) && !interface_exists('ComposerAutoloaderInitba17b363b6d15060ff4e10e823b02404', false) && !trait_exists('ComposerAutoloaderInitba17b363b6d15060ff4e10e823b02404', false)) {
spl_autoload_call('RectorPrefix20211113\ComposerAutoloaderInitba17b363b6d15060ff4e10e823b02404');
}
if (!class_exists('Helmich\TypoScriptParser\Parser\AST\Statement', false) && !interface_exists('Helmich\TypoScriptParser\Parser\AST\Statement', false) && !trait_exists('Helmich\TypoScriptParser\Parser\AST\Statement', false)) {
spl_autoload_call('RectorPrefix20211113\Helmich\TypoScriptParser\Parser\AST\Statement');
@ -3309,9 +3309,9 @@ if (!function_exists('print_node')) {
return \RectorPrefix20211113\print_node(...func_get_args());
}
}
if (!function_exists('composerRequire69387b451e53fa05cffe87da5ea4f662')) {
function composerRequire69387b451e53fa05cffe87da5ea4f662() {
return \RectorPrefix20211113\composerRequire69387b451e53fa05cffe87da5ea4f662(...func_get_args());
if (!function_exists('composerRequireba17b363b6d15060ff4e10e823b02404')) {
function composerRequireba17b363b6d15060ff4e10e823b02404() {
return \RectorPrefix20211113\composerRequireba17b363b6d15060ff4e10e823b02404(...func_get_args());
}
}
if (!function_exists('parseArgs')) {