Updated Rector to commit 0af705fb570340cb0e4fbc0b9e897b09bd172f5c

0af705fb57 debug
This commit is contained in:
Tomas Votruba 2023-06-06 16:41:24 +00:00
parent 84532f58cf
commit 075297ce56
29 changed files with 141 additions and 331 deletions

View File

@ -28,9 +28,7 @@ final class ContextAnalyzer
}
public function isInLoop(Node $node) : bool
{
$item0Unpacked = ControlStructure::LOOP_NODES;
$item1Unpacked = self::BREAK_NODES;
$firstParent = $this->betterNodeFinder->findParentByTypes($node, \array_merge($item0Unpacked, $item1Unpacked));
$firstParent = $this->betterNodeFinder->findParentByTypes($node, \array_merge(ControlStructure::LOOP_NODES, self::BREAK_NODES));
if (!$firstParent instanceof Node) {
return \false;
}
@ -53,8 +51,7 @@ final class ContextAnalyzer
*/
public function isInIf(Node $node) : bool
{
$item1Unpacked = self::BREAK_NODES;
$previousNode = $this->betterNodeFinder->findParentByTypes($node, \array_merge([If_::class], $item1Unpacked));
$previousNode = $this->betterNodeFinder->findParentByTypes($node, \array_merge([If_::class], self::BREAK_NODES));
if (!$previousNode instanceof Node) {
return \false;
}

View File

@ -45,8 +45,7 @@ final class NullableTypeMapper implements PhpDocTypeMapperInterface
if ($typeNode->type instanceof IdentifierTypeNode) {
$type = $this->identifierTypeMapper->mapToPHPStanType($typeNode->type, $node, $nameScope);
if ($type instanceof UnionType) {
$item1Unpacked = $type->getTypes();
return new UnionType(\array_merge([new NullType()], $item1Unpacked));
return new UnionType(\array_merge([new NullType()], $type->getTypes()));
}
return new UnionType([new NullType(), $type]);
}

View File

@ -110,9 +110,7 @@ CODE_SAMPLE
return null;
}
if ($value instanceof Array_) {
$item0Unpacked = $array->items;
$item1Unpacked = $value->items;
$array->items = \array_merge($item0Unpacked, $item1Unpacked);
$array->items = \array_merge($array->items, $value->items);
continue;
}
$value = $this->resolveValue($value);

View File

@ -46,8 +46,7 @@ final class RenameClassCallbackHandler extends NodeVisitorAbstract
*/
public function addOldToNewClassCallbacks(array $oldToNewClassCallbacks) : void
{
$item0Unpacked = $this->oldToNewClassCallbacks;
$this->oldToNewClassCallbacks = \array_merge($item0Unpacked, $oldToNewClassCallbacks);
$this->oldToNewClassCallbacks = \array_merge($this->oldToNewClassCallbacks, $oldToNewClassCallbacks);
}
/**
* @return array<string, string>

View File

@ -403,7 +403,6 @@ final class ClassRenamer
*/
private function resolveOldToNewClassCallbacks(Node $node, array $oldToNewClasses) : array
{
$item1Unpacked = $this->renameClassCallbackHandler->getOldToNewClassesFromNode($node);
return \array_merge($oldToNewClasses, $item1Unpacked);
return \array_merge($oldToNewClasses, $this->renameClassCallbackHandler->getOldToNewClassesFromNode($node));
}
}

View File

@ -93,8 +93,7 @@ CODE_SAMPLE
if ($hasReturn) {
return \true;
}
$item1Unpacked = ControlStructure::CONDITIONAL_NODE_SCOPE_TYPES;
$hasNotNeverNodes = $this->betterNodeFinder->hasInstancesOfInFunctionLikeScoped($node, \array_merge([Yield_::class], $item1Unpacked));
$hasNotNeverNodes = $this->betterNodeFinder->hasInstancesOfInFunctionLikeScoped($node, \array_merge([Yield_::class], ControlStructure::CONDITIONAL_NODE_SCOPE_TYPES));
if ($hasNotNeverNodes) {
return \true;
}

View File

@ -19,12 +19,12 @@ final class VersionResolver
* @api
* @var string
*/
public const PACKAGE_VERSION = 'b852d706e3c13bc862a91acac245b313db357450';
public const PACKAGE_VERSION = '0af705fb570340cb0e4fbc0b9e897b09bd172f5c';
/**
* @api
* @var string
*/
public const RELEASE_DATE = '2023-06-06 14:15:56';
public const RELEASE_DATE = '2023-06-06 18:36:26';
/**
* @var int
*/

View File

@ -23,9 +23,8 @@ final class RenamedClassesDataCollector
*/
public function addOldToNewClasses(array $oldToNewClasses) : void
{
$item0Unpacked = $this->oldToNewClasses;
/** @var array<string, string> $oldToNewClasses */
$oldToNewClasses = \array_merge($item0Unpacked, $oldToNewClasses);
$oldToNewClasses = \array_merge($this->oldToNewClasses, $oldToNewClasses);
$this->oldToNewClasses = $oldToNewClasses;
}
/**

View File

@ -105,10 +105,8 @@ CODE_SAMPLE
*/
private function getRenameClasses() : array
{
$item0Unpacked = $this->renameClasses;
$item1Unpacked = $this->renamedClassesDataCollector->getOldToNewClasses();
/** @var array<string, string> $renameClasses */
$renameClasses = \array_merge($item0Unpacked, $item1Unpacked);
$renameClasses = \array_merge($this->renameClasses, $this->renamedClassesDataCollector->getOldToNewClasses());
return $renameClasses;
}
private function createOldClassRegex(string $oldClass) : string

2
vendor/autoload.php vendored
View File

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

View File

@ -2,7 +2,7 @@
// autoload_real.php @generated by Composer
class ComposerAutoloaderInit1a4e23b0816d75b635bfde4cbb4fbdef
class ComposerAutoloaderInit676759b8e47d3081b47cdf1707b8a0d7
{
private static $loader;
@ -22,17 +22,17 @@ class ComposerAutoloaderInit1a4e23b0816d75b635bfde4cbb4fbdef
return self::$loader;
}
spl_autoload_register(array('ComposerAutoloaderInit1a4e23b0816d75b635bfde4cbb4fbdef', 'loadClassLoader'), true, true);
spl_autoload_register(array('ComposerAutoloaderInit676759b8e47d3081b47cdf1707b8a0d7', 'loadClassLoader'), true, true);
self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__));
spl_autoload_unregister(array('ComposerAutoloaderInit1a4e23b0816d75b635bfde4cbb4fbdef', 'loadClassLoader'));
spl_autoload_unregister(array('ComposerAutoloaderInit676759b8e47d3081b47cdf1707b8a0d7', 'loadClassLoader'));
require __DIR__ . '/autoload_static.php';
call_user_func(\Composer\Autoload\ComposerStaticInit1a4e23b0816d75b635bfde4cbb4fbdef::getInitializer($loader));
call_user_func(\Composer\Autoload\ComposerStaticInit676759b8e47d3081b47cdf1707b8a0d7::getInitializer($loader));
$loader->setClassMapAuthoritative(true);
$loader->register(true);
$filesToLoad = \Composer\Autoload\ComposerStaticInit1a4e23b0816d75b635bfde4cbb4fbdef::$files;
$filesToLoad = \Composer\Autoload\ComposerStaticInit676759b8e47d3081b47cdf1707b8a0d7::$files;
$requireFile = \Closure::bind(static function ($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 ComposerStaticInit1a4e23b0816d75b635bfde4cbb4fbdef
class ComposerStaticInit676759b8e47d3081b47cdf1707b8a0d7
{
public static $files = array (
'ad155f8f1cf0d418fe49e248db8c661b' => __DIR__ . '/..' . '/react/promise/src/functions_include.php',
@ -3042,9 +3042,9 @@ class ComposerStaticInit1a4e23b0816d75b635bfde4cbb4fbdef
public static function getInitializer(ClassLoader $loader)
{
return \Closure::bind(function () use ($loader) {
$loader->prefixLengthsPsr4 = ComposerStaticInit1a4e23b0816d75b635bfde4cbb4fbdef::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInit1a4e23b0816d75b635bfde4cbb4fbdef::$prefixDirsPsr4;
$loader->classMap = ComposerStaticInit1a4e23b0816d75b635bfde4cbb4fbdef::$classMap;
$loader->prefixLengthsPsr4 = ComposerStaticInit676759b8e47d3081b47cdf1707b8a0d7::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInit676759b8e47d3081b47cdf1707b8a0d7::$prefixDirsPsr4;
$loader->classMap = ComposerStaticInit676759b8e47d3081b47cdf1707b8a0d7::$classMap;
}, null, ClassLoader::class);
}

View File

@ -1917,12 +1917,12 @@
"source": {
"type": "git",
"url": "https:\/\/github.com\/rectorphp\/rector-downgrade-php.git",
"reference": "2ca5c9497ac5ca0fe1f7e863bf7ffbe8804eed39"
"reference": "392f969e8166ba3329193e761bb0a35069d39deb"
},
"dist": {
"type": "zip",
"url": "https:\/\/api.github.com\/repos\/rectorphp\/rector-downgrade-php\/zipball\/2ca5c9497ac5ca0fe1f7e863bf7ffbe8804eed39",
"reference": "2ca5c9497ac5ca0fe1f7e863bf7ffbe8804eed39",
"url": "https:\/\/api.github.com\/repos\/rectorphp\/rector-downgrade-php\/zipball\/392f969e8166ba3329193e761bb0a35069d39deb",
"reference": "392f969e8166ba3329193e761bb0a35069d39deb",
"shasum": ""
},
"require": {
@ -1946,7 +1946,7 @@
"tomasvotruba\/type-coverage": "^0.2",
"tomasvotruba\/unused-public": "^0.1"
},
"time": "2023-06-06T14:49:13+00:00",
"time": "2023-06-06T16:14:50+00:00",
"default-branch": true,
"type": "rector-extension",
"extra": {

File diff suppressed because one or more lines are too long

View File

@ -198,23 +198,7 @@ class Arrays
*/
public static function isList($value) : bool
{
$arrayIsList = function (array $array) : bool {
if (\function_exists('array_is_list')) {
return \array_is_list($array);
}
if ($array === []) {
return \true;
}
$current_key = 0;
foreach ($array as $key => $noop) {
if ($key !== $current_key) {
return \false;
}
++$current_key;
}
return \true;
};
return is_array($value) && (\PHP_VERSION_ID < 80100 ? !$value || \array_keys($value) === \range(0, count($value) - 1) : $arrayIsList($value));
return is_array($value) && (\PHP_VERSION_ID < 80100 ? !$value || \array_keys($value) === \range(0, count($value) - 1) : \array_is_list($value));
}
/**
* Reformats table to associative tree. Path looks like 'field|field[]field->field=field'.

View File

@ -9,7 +9,7 @@ namespace Rector\RectorInstaller;
*/
final class GeneratedConfig
{
public const EXTENSIONS = array('rector/rector-doctrine' => array('install_path' => '/home/runner/work/rector-src/rector-src/vendor/rector/rector-doctrine', 'relative_install_path' => '../../rector-doctrine', 'extra' => array('includes' => array(0 => 'config/config.php')), 'version' => 'dev-main 08503e7'), 'rector/rector-downgrade-php' => array('install_path' => '/home/runner/work/rector-src/rector-src/vendor/rector/rector-downgrade-php', 'relative_install_path' => '../../rector-downgrade-php', 'extra' => array('includes' => array(0 => 'config/config.php')), 'version' => 'dev-main 2ca5c94'), 'rector/rector-phpunit' => array('install_path' => '/home/runner/work/rector-src/rector-src/vendor/rector/rector-phpunit', 'relative_install_path' => '../../rector-phpunit', 'extra' => array('includes' => array(0 => 'config/config.php')), 'version' => 'dev-main 134c91c'), 'rector/rector-symfony' => array('install_path' => '/home/runner/work/rector-src/rector-src/vendor/rector/rector-symfony', 'relative_install_path' => '../../rector-symfony', 'extra' => array('includes' => array(0 => 'config/config.php')), 'version' => 'dev-main 36d3cb5'));
public const EXTENSIONS = array('rector/rector-doctrine' => array('install_path' => '/home/runner/work/rector-src/rector-src/vendor/rector/rector-doctrine', 'relative_install_path' => '../../rector-doctrine', 'extra' => array('includes' => array(0 => 'config/config.php')), 'version' => 'dev-main 08503e7'), 'rector/rector-downgrade-php' => array('install_path' => '/home/runner/work/rector-src/rector-src/vendor/rector/rector-downgrade-php', 'relative_install_path' => '../../rector-downgrade-php', 'extra' => array('includes' => array(0 => 'config/config.php')), 'version' => 'dev-main 392f969'), 'rector/rector-phpunit' => array('install_path' => '/home/runner/work/rector-src/rector-src/vendor/rector/rector-phpunit', 'relative_install_path' => '../../rector-phpunit', 'extra' => array('includes' => array(0 => 'config/config.php')), 'version' => 'dev-main 134c91c'), 'rector/rector-symfony' => array('install_path' => '/home/runner/work/rector-src/rector-src/vendor/rector/rector-symfony', 'relative_install_path' => '../../rector-symfony', 'extra' => array('includes' => array(0 => 'config/config.php')), 'version' => 'dev-main 36d3cb5'));
private function __construct()
{
}

View File

@ -10,9 +10,11 @@ use PhpParser\Node\Expr\ArrayItem;
use PhpParser\Node\Expr\FuncCall;
use PhpParser\Node\Name;
use PhpParser\Node\Scalar\String_;
use PhpParser\Node\Stmt;
use PhpParser\Node\Stmt\Expression;
use PhpParser\Node\Stmt\If_;
use PhpParser\Node\Stmt\Return_;
use Rector\Core\Rector\AbstractRector;
use Rector\PostRector\Collector\NodesToAddCollector;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
@ -20,22 +22,6 @@ use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
*/
final class DowngradeSessionStartArrayOptionsRector extends AbstractRector
{
/**
* @readonly
* @var \Rector\PostRector\Collector\NodesToAddCollector
*/
private $nodesToAddCollector;
public function __construct(NodesToAddCollector $nodesToAddCollector)
{
$this->nodesToAddCollector = $nodesToAddCollector;
}
/**
* @return array<class-string<Node>>
*/
public function getNodeTypes() : array
{
return [FuncCall::class];
}
public function getRuleDefinition() : RuleDefinition
{
return new RuleDefinition('Move array option of session_start($options) to before statement\'s ini_set()', [new CodeSample(<<<'CODE_SAMPLE'
@ -50,36 +36,49 @@ CODE_SAMPLE
)]);
}
/**
* @param FuncCall $node
* @return array<class-string<Node>>
*/
public function refactor(Node $node) : ?Node
public function getNodeTypes() : array
{
if ($this->shouldSkip($node)) {
return null;
}
$args = $node->getArgs();
if (!isset($args[0])) {
return null;
}
/** @var Array_ $options */
$options = $args[0]->value;
foreach ($options->items as $option) {
if (!$option instanceof ArrayItem) {
return null;
return [Expression::class, Return_::class, If_::class];
}
/**
* @param Expression|Return_|If_ $node
* @return Stmt[]|null
*/
public function refactor(Node $node) : ?array
{
$funcCalls = $this->betterNodeFinder->findInstanceOf($node, FuncCall::class);
$nodesToReturn = [];
foreach ($funcCalls as $funcCall) {
if ($this->shouldSkip($funcCall)) {
continue;
}
if (!$option->key instanceof String_) {
return null;
$firstArg = $funcCall->getArgs()[0] ?? null;
if (!$firstArg instanceof Arg) {
continue;
}
if (!$this->valueResolver->isTrueOrFalse($option->value) && !$option->value instanceof String_) {
return null;
/** @var Array_ $options */
$options = $firstArg->value;
foreach ($options->items as $option) {
if (!$option instanceof ArrayItem) {
continue;
}
if (!$option->key instanceof String_) {
continue;
}
if (!$this->valueResolver->isTrueOrFalse($option->value) && !$option->value instanceof String_) {
continue;
}
$initSetFuncCall = $this->createInitSetFuncCall($option, $option->key);
unset($funcCall->args[0]);
$nodesToReturn[] = new Expression($initSetFuncCall);
}
$sessionKey = new String_('session.' . $option->key->value);
$funcName = new Name('ini_set');
$iniSet = new FuncCall($funcName, [new Arg($sessionKey), new Arg($option->value)]);
$this->nodesToAddCollector->addNodeBeforeNode(new Expression($iniSet), $node);
}
unset($node->args[0]);
return $node;
if ($nodesToReturn !== []) {
return \array_merge($nodesToReturn, [$node]);
}
return null;
}
private function shouldSkip(FuncCall $funcCall) : bool
{
@ -92,4 +91,10 @@ CODE_SAMPLE
}
return !$args[0]->value instanceof Array_;
}
private function createInitSetFuncCall(ArrayItem $arrayItem, String_ $string) : FuncCall
{
$sessionKey = new String_('session.' . $string->value);
$funcName = new Name('ini_set');
return new FuncCall($funcName, [new Arg($sessionKey), new Arg($arrayItem->value)]);
}
}

View File

@ -59,8 +59,7 @@ CODE_SAMPLE
}
$methodCall = $this->createBindToCall($node);
$args = $node->getArgs();
$item1Unpacked = \array_slice($args, 1);
$args = \array_merge([new Arg($methodCall)], $item1Unpacked);
$args = \array_merge([new Arg($methodCall)], \array_slice($args, 1));
return new FuncCall(new Name('call_user_func'), $args);
}
private function shouldSkip(MethodCall $methodCall) : bool

View File

@ -8,14 +8,15 @@ use PhpParser\Node\Expr\Assign;
use PhpParser\Node\Expr\Closure;
use PhpParser\Node\Expr\FuncCall;
use PhpParser\Node\Expr\Variable;
use PhpParser\Node\Stmt;
use PhpParser\Node\Stmt\Expression;
use PhpParser\Node\Stmt\Return_;
use PHPStan\Analyser\Scope;
use Rector\Core\Exception\ShouldNotHappenException;
use Rector\Core\PhpParser\Parser\InlineCodeParser;
use Rector\Core\Rector\AbstractScopeAwareRector;
use Rector\DowngradePhp72\NodeAnalyzer\FunctionExistsFunCallAnalyzer;
use Rector\Naming\Naming\VariableNaming;
use Rector\PostRector\Collector\NodesToAddCollector;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
@ -44,17 +45,11 @@ final class DowngradeStreamIsattyRector extends AbstractScopeAwareRector
* @var \Rector\Naming\Naming\VariableNaming
*/
private $variableNaming;
/**
* @readonly
* @var \Rector\PostRector\Collector\NodesToAddCollector
*/
private $nodesToAddCollector;
public function __construct(InlineCodeParser $inlineCodeParser, FunctionExistsFunCallAnalyzer $functionExistsFunCallAnalyzer, VariableNaming $variableNaming, NodesToAddCollector $nodesToAddCollector)
public function __construct(InlineCodeParser $inlineCodeParser, FunctionExistsFunCallAnalyzer $functionExistsFunCallAnalyzer, VariableNaming $variableNaming)
{
$this->inlineCodeParser = $inlineCodeParser;
$this->functionExistsFunCallAnalyzer = $functionExistsFunCallAnalyzer;
$this->variableNaming = $variableNaming;
$this->nodesToAddCollector = $nodesToAddCollector;
}
public function getRuleDefinition() : RuleDefinition
{
@ -102,25 +97,30 @@ CODE_SAMPLE
*/
public function getNodeTypes() : array
{
return [FuncCall::class];
return [Expression::class, Return_::class];
}
/**
* @param FuncCall $node
* @param Expression|Stmt\Return_ $node
* @return Stmt[]
*/
public function refactorWithScope(Node $node, Scope $scope) : ?Node
public function refactorWithScope(Node $node, Scope $scope) : ?array
{
if (!$this->isName($node, 'stream_isatty')) {
return null;
/** @var FuncCall[] $funcCalls */
$funcCalls = $this->betterNodeFinder->findInstanceOf($node, FuncCall::class);
foreach ($funcCalls as $funcCall) {
if (!$this->isName($funcCall, 'stream_isatty')) {
continue;
}
if ($this->functionExistsFunCallAnalyzer->detect($funcCall, 'stream_isatty')) {
continue;
}
$function = $this->createClosure();
$variable = new Variable($this->variableNaming->createCountedValueName('streamIsatty', $scope));
$assign = new Assign($variable, $function);
$funcCall->name = $variable;
return [new Expression($assign), $node];
}
if ($this->functionExistsFunCallAnalyzer->detect($node, 'stream_isatty')) {
return null;
}
$function = $this->createClosure();
$variable = new Variable($this->variableNaming->createCountedValueName('streamIsatty', $scope));
$assign = new Assign($variable, $function);
$this->nodesToAddCollector->addNodeBeforeNode($assign, $node);
$args = $node->getArgs();
return new FuncCall($variable, $args);
return null;
}
private function createClosure() : Closure
{

View File

@ -88,8 +88,7 @@ CODE_SAMPLE
public function refactor(Node $node)
{
if ($node instanceof If_ || $node instanceof ElseIf_) {
$item1Unpacked = $node->stmts;
$scopeStmt = \array_merge([$node->cond], $item1Unpacked);
$scopeStmt = \array_merge([$node->cond], $node->stmts);
} elseif ($node instanceof Else_) {
$scopeStmt = $node->stmts;
} else {

View File

@ -77,8 +77,13 @@ class SomeClass
public function runWithIterable()
{
$item0Unpacked = new ArrayIterator(['durian', 'kiwi']);
$fruits = array_merge(['banana', 'orange'], is_array($item0Unpacked) ? $item0Unpacked : iterator_to_array($item0Unpacked), ['watermelon']);
$fruits = array_merge(
['banana', 'orange'],
is_array(new ArrayIterator(['durian', 'kiwi'])) ?
new ArrayIterator(['durian', 'kiwi']) :
iterator_to_array(new ArrayIterator(['durian', 'kiwi'])),
['watermelon']
);
}
}
CODE_SAMPLE
@ -102,14 +107,8 @@ CODE_SAMPLE
if (!$this->arraySpreadAnalyzer->isArrayWithUnpack($node)) {
return null;
}
$shouldIncrement = (bool) $this->betterNodeFinder->findFirstNext($node, function (Node $subNode) : bool {
if (!$subNode instanceof Array_) {
return \false;
}
return $this->arraySpreadAnalyzer->isArrayWithUnpack($subNode);
});
/** @var MutatingScope $scope */
return $this->arrayMergeFromArraySpreadFactory->createFromArray($node, $scope, $this->file, $shouldIncrement);
return $this->arrayMergeFromArraySpreadFactory->createFromArray($node, $scope, $this->file);
}
private function refactorUnderClassConst(ClassConst $classConst) : ?ClassConst
{

View File

@ -7,7 +7,6 @@ use PhpParser\Node;
use PhpParser\Node\Arg;
use PhpParser\Node\Expr\Array_;
use PhpParser\Node\Expr\ArrayItem;
use PhpParser\Node\Expr\Assign;
use PhpParser\Node\Expr\FuncCall;
use PhpParser\Node\Expr\Ternary;
use PhpParser\Node\Expr\Variable;
@ -19,40 +18,12 @@ use PHPStan\Type\IterableType;
use PHPStan\Type\ObjectType;
use PHPStan\Type\Type;
use Rector\Core\Exception\ShouldNotHappenException;
use Rector\Core\PhpParser\Node\BetterNodeFinder;
use Rector\Core\ValueObject\Application\File;
use Rector\DowngradePhp81\NodeAnalyzer\ArraySpreadAnalyzer;
use Rector\Naming\Naming\VariableNaming;
use Rector\NodeNameResolver\NodeNameResolver;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\PostRector\Collector\NodesToAddCollector;
final class ArrayMergeFromArraySpreadFactory
{
/**
* @var bool
*/
private $shouldIncrement = \false;
/**
* Handle different result in CI
*
* @var array<string, int>
*/
private $lastPositionCurrentFile = [];
/**
* @readonly
* @var \Rector\Naming\Naming\VariableNaming
*/
private $variableNaming;
/**
* @readonly
* @var \Rector\Core\PhpParser\Node\BetterNodeFinder
*/
private $betterNodeFinder;
/**
* @readonly
* @var \Rector\PostRector\Collector\NodesToAddCollector
*/
private $nodesToAddCollector;
/**
* @readonly
* @var \Rector\NodeNameResolver\NodeNameResolver
@ -63,30 +34,17 @@ final class ArrayMergeFromArraySpreadFactory
* @var \Rector\DowngradePhp81\NodeAnalyzer\ArraySpreadAnalyzer
*/
private $arraySpreadAnalyzer;
public function __construct(VariableNaming $variableNaming, BetterNodeFinder $betterNodeFinder, NodesToAddCollector $nodesToAddCollector, NodeNameResolver $nodeNameResolver, ArraySpreadAnalyzer $arraySpreadAnalyzer)
public function __construct(NodeNameResolver $nodeNameResolver, ArraySpreadAnalyzer $arraySpreadAnalyzer)
{
$this->variableNaming = $variableNaming;
$this->betterNodeFinder = $betterNodeFinder;
$this->nodesToAddCollector = $nodesToAddCollector;
$this->nodeNameResolver = $nodeNameResolver;
$this->arraySpreadAnalyzer = $arraySpreadAnalyzer;
}
public function createFromArray(Array_ $array, MutatingScope $mutatingScope, File $file, ?bool $shouldIncrement = null) : ?Node
public function createFromArray(Array_ $array, MutatingScope $mutatingScope, File $file) : ?Node
{
if (!$this->arraySpreadAnalyzer->isArrayWithUnpack($array)) {
return null;
}
if ($shouldIncrement !== null) {
$this->shouldIncrement = $shouldIncrement;
} else {
$this->shouldIncrement = (bool) $this->betterNodeFinder->findFirstNext($array, function (Node $subNode) : bool {
if (!$subNode instanceof Array_) {
return \false;
}
return $this->arraySpreadAnalyzer->isArrayWithUnpack($subNode);
});
}
$newArrayItems = $this->disolveArrayItems($array, $mutatingScope, $file);
$newArrayItems = $this->disolveArrayItems($array);
return $this->createArrayMergeFuncCall($newArrayItems, $mutatingScope);
}
/**
@ -97,17 +55,12 @@ final class ArrayMergeFromArraySpreadFactory
* to be added once the next spread is found, or at the end
* @return ArrayItem[]
*/
private function disolveArrayItems(Array_ $array, MutatingScope $mutatingScope, File $file) : array
private function disolveArrayItems(Array_ $array) : array
{
$newItems = [];
$accumulatedItems = [];
foreach ($array->items as $position => $item) {
foreach ($array->items as $item) {
if ($item instanceof ArrayItem && $item->unpack) {
// Spread operator found
if (!$item->value instanceof Variable) {
// If it is a not variable, transform it to a variable
$item->value = $this->createVariableFromNonVariable($array, $item, $position, $mutatingScope, $file);
}
if ($accumulatedItems !== []) {
// If previous items were in the new array, add them first
$newItems[] = $this->createArrayItemFromArray($accumulatedItems);
@ -142,31 +95,6 @@ final class ArrayMergeFromArraySpreadFactory
}, $arrayItems);
return new FuncCall(new Name('array_merge'), $args);
}
/**
* If it is a variable, we add it directly
* Otherwise it could be a function, method, ternary, traversable, etc
* We must then first extract it into a variable,
* as to invoke it only once and avoid potential bugs,
* such as a method executing some side-effect
*/
private function createVariableFromNonVariable(Array_ $array, ArrayItem $arrayItem, int $position, MutatingScope $mutatingScope, File $file) : Variable
{
// The variable name will be item0Unpacked, item1Unpacked, etc,
// depending on their position.
// The number can't be at the end of the var name, or it would
// conflict with the counter (for if that name is already taken)
$filePath = $file->getFilePath();
$position = $this->lastPositionCurrentFile[$filePath] ?? $position;
$variableName = $this->variableNaming->resolveFromNodeWithScopeCountAndFallbackName($array, $mutatingScope, 'item' . $position . 'Unpacked');
if ($this->shouldIncrement) {
$this->lastPositionCurrentFile[$filePath] = ++$position;
}
// Assign the value to the variable, and replace the element with the variable
$newVariable = new Variable($variableName);
$newVariableAssign = new Assign($newVariable, $arrayItem->value);
$this->nodesToAddCollector->addNodeBeforeNode($newVariableAssign, $array);
return $newVariable;
}
/**
* @param array<ArrayItem|null> $items
*/

View File

@ -8,6 +8,7 @@ use PhpParser\Node\Expr\Assign;
use PhpParser\Node\Expr\Closure;
use PhpParser\Node\Expr\FuncCall;
use PhpParser\Node\Expr\Variable;
use PhpParser\Node\Stmt;
use PhpParser\Node\Stmt\Expression;
use PHPStan\Analyser\Scope;
use Rector\Core\Exception\ShouldNotHappenException;
@ -15,7 +16,6 @@ use Rector\Core\PhpParser\Parser\InlineCodeParser;
use Rector\Core\Rector\AbstractScopeAwareRector;
use Rector\DowngradePhp72\NodeAnalyzer\FunctionExistsFunCallAnalyzer;
use Rector\Naming\Naming\VariableNaming;
use Rector\PostRector\Collector\NodesToAddCollector;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
@ -44,17 +44,11 @@ final class DowngradeArrayIsListRector extends AbstractScopeAwareRector
* @var \Rector\Naming\Naming\VariableNaming
*/
private $variableNaming;
/**
* @readonly
* @var \Rector\PostRector\Collector\NodesToAddCollector
*/
private $nodesToAddCollector;
public function __construct(InlineCodeParser $inlineCodeParser, FunctionExistsFunCallAnalyzer $functionExistsFunCallAnalyzer, VariableNaming $variableNaming, NodesToAddCollector $nodesToAddCollector)
public function __construct(InlineCodeParser $inlineCodeParser, FunctionExistsFunCallAnalyzer $functionExistsFunCallAnalyzer, VariableNaming $variableNaming)
{
$this->inlineCodeParser = $inlineCodeParser;
$this->functionExistsFunCallAnalyzer = $functionExistsFunCallAnalyzer;
$this->variableNaming = $variableNaming;
$this->nodesToAddCollector = $nodesToAddCollector;
}
public function getRuleDefinition() : RuleDefinition
{
@ -66,9 +60,11 @@ $arrayIsList = function (array $array) : bool {
if (function_exists('array_is_list')) {
return array_is_list($array);
}
if ($array === []) {
return true;
}
$current_key = 0;
foreach ($array as $key => $noop) {
if ($key !== $current_key) {
@ -76,6 +72,7 @@ $arrayIsList = function (array $array) : bool {
}
++$current_key;
}
return true;
};
$arrayIsList([1 => 'apple', 'orange']);
@ -87,22 +84,30 @@ CODE_SAMPLE
*/
public function getNodeTypes() : array
{
return [FuncCall::class];
return [Expression::class];
}
/**
* @param FuncCall $node
* @param Expression $node
* @return Stmt[]|null
*/
public function refactorWithScope(Node $node, Scope $scope) : ?FuncCall
public function refactorWithScope(Node $node, Scope $scope) : ?array
{
if ($this->shouldSkip($node)) {
/** @var FuncCall[] $funcCalls */
$funcCalls = $this->betterNodeFinder->findInstanceOf($node, FuncCall::class);
if ($funcCalls === []) {
return null;
}
$variable = new Variable($this->variableNaming->createCountedValueName('arrayIsList', $scope));
$function = $this->createClosure();
$expression = new Expression(new Assign($variable, $function));
$this->nodesToAddCollector->addNodeBeforeNode($expression, $node);
$args = $node->getArgs();
return new FuncCall($variable, $args);
foreach ($funcCalls as $funcCall) {
if ($this->shouldSkip($funcCall)) {
continue;
}
$variable = new Variable($this->variableNaming->createCountedValueName('arrayIsList', $scope));
$function = $this->createClosure();
$expression = new Expression(new Assign($variable, $function));
$funcCall->name = $variable;
return [$expression, $node];
}
return null;
}
private function createClosure() : Closure
{

View File

@ -39,8 +39,7 @@ final class FormTypeStringToTypeProvider
private function getNameToTypeMap() : array
{
$customServiceFormTypeByAlias = $this->provideCustomServiceFormTypeByAliasFromContainerXml();
$item0Unpacked = self::SYMFONY_CORE_NAME_TO_TYPE_MAP;
return \array_merge($item0Unpacked, $customServiceFormTypeByAlias);
return \array_merge(self::SYMFONY_CORE_NAME_TO_TYPE_MAP, $customServiceFormTypeByAlias);
}
/**
* @return array<string, string>

View File

@ -168,23 +168,7 @@ class YamlReferenceDumper
}
private function writeArray(array $array, int $depth) : void
{
$arrayIsList = function (array $array) : bool {
if (\function_exists('array_is_list')) {
return \array_is_list($array);
}
if ($array === []) {
return \true;
}
$current_key = 0;
foreach ($array as $key => $noop) {
if ($key !== $current_key) {
return \false;
}
++$current_key;
}
return \true;
};
$isIndexed = $arrayIsList($array);
$isIndexed = \array_is_list($array);
foreach ($array as $key => $value) {
if (\is_array($value)) {
$val = '';

View File

@ -186,23 +186,7 @@ class PrototypedArrayNode extends ArrayNode
return $value;
}
$value = $this->remapXml($value);
$arrayIsList = function (array $array) : bool {
if (\function_exists('array_is_list')) {
return \array_is_list($array);
}
if ($array === []) {
return \true;
}
$current_key = 0;
foreach ($array as $key => $noop) {
if ($key !== $current_key) {
return \false;
}
++$current_key;
}
return \true;
};
$isList = $arrayIsList($value);
$isList = \array_is_list($value);
$normalized = [];
foreach ($value as $k => $v) {
if (null !== $this->keyAttribute && \is_array($v)) {
@ -264,23 +248,7 @@ class PrototypedArrayNode extends ArrayNode
if (\false === $leftSide || !$this->performDeepMerging) {
return $rightSide;
}
$arrayIsList = function (array $array) : bool {
if (\function_exists('array_is_list')) {
return \array_is_list($array);
}
if ($array === []) {
return \true;
}
$current_key = 0;
foreach ($array as $key => $noop) {
if ($key !== $current_key) {
return \false;
}
++$current_key;
}
return \true;
};
$isList = $arrayIsList($rightSide);
$isList = \array_is_list($rightSide);
foreach ($rightSide as $k => $v) {
// prototype, and key is irrelevant there are no named keys, append the element
if (null === $this->keyAttribute && $isList) {

View File

@ -94,23 +94,7 @@ class ResolveNamedArgumentsPass extends AbstractRecursivePass
}
if ($resolvedArguments !== $call[1]) {
\ksort($resolvedArguments);
$arrayIsList = function (array $array) : bool {
if (\function_exists('array_is_list')) {
return \array_is_list($array);
}
if ($array === []) {
return \true;
}
$current_key = 0;
foreach ($array as $key => $noop) {
if ($key !== $current_key) {
return \false;
}
++$current_key;
}
return \true;
};
if (!$value->isAutowired() && !$arrayIsList($resolvedArguments)) {
if (!$value->isAutowired() && !\array_is_list($resolvedArguments)) {
\ksort($resolvedKeys);
$resolvedArguments = \array_combine($resolvedKeys, $resolvedArguments);
}

View File

@ -881,23 +881,7 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
if (null !== $id && $definition->isShared() && (isset($this->services[$id]) || isset($this->privates[$id])) && ($tryProxy || !$definition->isLazy())) {
return $this->services[$id] ?? $this->privates[$id];
}
$arrayIsList = function (array $array) : bool {
if (\function_exists('array_is_list')) {
return \array_is_list($array);
}
if ($array === []) {
return \true;
}
$current_key = 0;
foreach ($array as $key => $noop) {
if ($key !== $current_key) {
return \false;
}
++$current_key;
}
return \true;
};
if (!$arrayIsList($arguments)) {
if (!\array_is_list($arguments)) {
$arguments = \array_combine(\array_map(function ($k) {
return \preg_replace('/^.*\\$/', '', $k);
}, \array_keys($arguments)), $arguments);

View File

@ -229,23 +229,7 @@ class XmlDumper extends Dumper
}
private function convertParameters(array $parameters, string $type, \DOMElement $parent, string $keyAttribute = 'key')
{
$arrayIsList = function (array $array) : bool {
if (\function_exists('array_is_list')) {
return \array_is_list($array);
}
if ($array === []) {
return \true;
}
$current_key = 0;
foreach ($array as $key => $noop) {
if ($key !== $current_key) {
return \false;
}
++$current_key;
}
return \true;
};
$withKeys = !$arrayIsList($parameters);
$withKeys = !\array_is_list($parameters);
foreach ($parameters as $key => $value) {
$element = $this->document->createElement($type);
if ($withKeys) {