Updated Rector to commit f8221e3e21c487f2d18707f7b979ef6607204826

f8221e3e21 [CodeQuality] Fix CompactToVariablesRector to resolve values when the compact() is called (#2627)
This commit is contained in:
Tomas Votruba 2022-07-03 20:44:15 +00:00
parent b682e0bcdf
commit 175fded020
9 changed files with 37 additions and 167 deletions

View File

@ -1,29 +0,0 @@
<?php
declare (strict_types=1);
namespace Rector\CodeQuality\NodeAnalyzer;
use PhpParser\Node\Expr\Array_;
use PhpParser\Node\Expr\ArrayItem;
use PhpParser\Node\Expr\Variable;
use PhpParser\Node\Scalar\String_;
final class ArrayCompacter
{
public function compactStringToVariableArray(Array_ $array) : void
{
foreach ($array->items as $arrayItem) {
if (!$arrayItem instanceof ArrayItem) {
continue;
}
if ($arrayItem->key !== null) {
continue;
}
if (!$arrayItem->value instanceof String_) {
continue;
}
$variableName = $arrayItem->value->value;
$arrayItem->key = new String_($variableName);
$arrayItem->value = new Variable($variableName);
}
}
}

View File

@ -1,50 +0,0 @@
<?php
declare (strict_types=1);
namespace Rector\CodeQuality\NodeAnalyzer;
use PhpParser\Node\Expr\Array_;
use PhpParser\Node\Expr\ArrayItem;
use PhpParser\Node\Scalar\String_;
use PHPStan\Analyser\Scope;
final class ArrayItemsAnalyzer
{
public function hasArrayExclusiveDefinedVariableNames(Array_ $array, Scope $scope) : bool
{
foreach ($array->items as $arrayItem) {
$variableName = $this->resolveStringValue($arrayItem);
if ($variableName === null) {
continue;
}
// the variable must not be defined here
if ($scope->hasVariableType($variableName)->no()) {
return \false;
}
}
return \true;
}
public function hasArrayExclusiveUndefinedVariableNames(Array_ $array, Scope $scope) : bool
{
foreach ($array->items as $arrayItem) {
$variableName = $this->resolveStringValue($arrayItem);
if ($variableName === null) {
continue;
}
// the variable must not be defined here
if ($scope->hasVariableType($variableName)->yes()) {
return \false;
}
}
return \true;
}
private function resolveStringValue(?ArrayItem $arrayItem) : ?string
{
if (!$arrayItem instanceof ArrayItem) {
return null;
}
if (!$arrayItem->value instanceof String_) {
return null;
}
return $arrayItem->value->value;
}
}

View File

@ -4,25 +4,22 @@ declare (strict_types=1);
namespace Rector\CodeQuality\Rector\FuncCall;
use PhpParser\Node;
use PhpParser\Node\Arg;
use PhpParser\Node\Expr;
use PhpParser\Node\Expr\Array_;
use PhpParser\Node\Expr\Assign;
use PhpParser\Node\Expr\ArrayItem;
use PhpParser\Node\Expr\FuncCall;
use PhpParser\Node\Stmt;
use PHPStan\Analyser\Scope;
use PhpParser\Node\Expr\Variable;
use PhpParser\Node\Scalar\String_;
use PHPStan\Type\Constant\ConstantArrayType;
use PHPStan\Type\Constant\ConstantStringType;
use PHPStan\Type\MixedType;
use Rector\CodeQuality\CompactConverter;
use Rector\CodeQuality\NodeAnalyzer\ArrayCompacter;
use Rector\CodeQuality\NodeAnalyzer\ArrayItemsAnalyzer;
use Rector\Core\Rector\AbstractRector;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* @changelog https://stackoverflow.com/a/16319909/1348344
* @changelog https://3v4l.org/8GJEs
*
* @see \Rector\Tests\CodeQuality\Rector\FuncCall\CompactToVariablesRector\CompactToVariablesRectorTest
*/
final class CompactToVariablesRector extends AbstractRector
@ -32,21 +29,9 @@ final class CompactToVariablesRector extends AbstractRector
* @var \Rector\CodeQuality\CompactConverter
*/
private $compactConverter;
/**
* @readonly
* @var \Rector\CodeQuality\NodeAnalyzer\ArrayItemsAnalyzer
*/
private $arrayItemsAnalyzer;
/**
* @readonly
* @var \Rector\CodeQuality\NodeAnalyzer\ArrayCompacter
*/
private $arrayCompacter;
public function __construct(CompactConverter $compactConverter, ArrayItemsAnalyzer $arrayItemsAnalyzer, ArrayCompacter $arrayCompacter)
public function __construct(CompactConverter $compactConverter)
{
$this->compactConverter = $compactConverter;
$this->arrayItemsAnalyzer = $arrayItemsAnalyzer;
$this->arrayCompacter = $arrayCompacter;
}
public function getRuleDefinition() : RuleDefinition
{
@ -94,8 +79,7 @@ CODE_SAMPLE
if ($this->compactConverter->hasAllArgumentsNamed($node)) {
return $this->compactConverter->convertToArray($node);
}
/** @var Arg $firstArg */
$firstArg = $node->args[0];
$firstArg = $node->getArgs()[0];
$firstValue = $firstArg->value;
$firstValueStaticType = $this->getType($firstValue);
if (!$firstValueStaticType instanceof ConstantArrayType) {
@ -104,49 +88,19 @@ CODE_SAMPLE
if ($firstValueStaticType->getItemType() instanceof MixedType) {
return null;
}
return $this->refactorAssignArray($firstValue, $node);
return $this->refactorAssignArray($firstValueStaticType);
}
private function refactorAssignedArray(Assign $assign, FuncCall $funcCall, Expr $expr) : ?Expr
private function refactorAssignArray(ConstantArrayType $constantArrayType) : ?Array_
{
if (!$assign->expr instanceof Array_) {
return null;
}
$array = $assign->expr;
$assignScope = $assign->getAttribute(AttributeKey::SCOPE);
if (!$assignScope instanceof Scope) {
return null;
}
$currentStmt = $this->betterNodeFinder->resolveCurrentStatement($funcCall);
if (!$currentStmt instanceof Stmt) {
return null;
}
$isCompactOfUndefinedVariables = $this->arrayItemsAnalyzer->hasArrayExclusiveDefinedVariableNames($array, $assignScope);
if ($isCompactOfUndefinedVariables) {
$funcCallScope = $funcCall->getAttribute(AttributeKey::SCOPE);
if (!$funcCallScope instanceof Scope) {
$arrayItems = [];
foreach ($constantArrayType->getValueTypes() as $valueType) {
if (!$valueType instanceof ConstantStringType) {
return null;
}
$isCompactOfDefinedVariables = $this->arrayItemsAnalyzer->hasArrayExclusiveUndefinedVariableNames($array, $funcCallScope);
if ($isCompactOfDefinedVariables) {
$this->arrayCompacter->compactStringToVariableArray($array);
return $expr;
}
$variableName = $valueType->getValue();
$variable = new Variable($variableName);
$arrayItems[] = new ArrayItem($variable, new String_($variableName));
}
$this->removeNode($assign);
$this->arrayCompacter->compactStringToVariableArray($array);
/** @var Arg $firstArg */
$firstArg = $funcCall->args[0];
$assignVariable = $firstArg->value;
$preAssign = new Assign($assignVariable, $array);
$this->nodesToAddCollector->addNodeBeforeNode($preAssign, $currentStmt);
return $expr;
}
private function refactorAssignArray(Expr $expr, FuncCall $funcCall) : ?Expr
{
$previousAssign = $this->betterNodeFinder->findPreviousAssignToExpr($expr);
if (!$previousAssign instanceof Assign) {
return null;
}
return $this->refactorAssignedArray($previousAssign, $funcCall, $expr);
return new Array_($arrayItems);
}
}

View File

@ -44,10 +44,10 @@ final class NewlineAfterStatementRector extends AbstractRector
return new RuleDefinition('Add new line after statements to tidify code', [new CodeSample(<<<'CODE_SAMPLE'
class SomeClass
{
public function test()
public function first()
{
}
public function test2()
public function second()
{
}
}
@ -55,11 +55,11 @@ CODE_SAMPLE
, <<<'CODE_SAMPLE'
class SomeClass
{
public function test()
public function first()
{
}
public function test2()
public function second()
{
}
}
@ -75,8 +75,9 @@ CODE_SAMPLE
}
/**
* @param Stmt $node
* @return Stmt[]|null
*/
public function refactor(Node $node) : ?Node
public function refactor(Node $node) : ?array
{
if (!\in_array(\get_class($node), self::STMTS_TO_HAVE_NEXT_NEWLINE, \true)) {
return null;
@ -108,9 +109,7 @@ CODE_SAMPLE
return null;
}
}
// @todo refactor to direct return of array
$this->nodesToAddCollector->addNodeAfterNode(new Nop(), $node);
return $node;
return [$node, new Nop()];
}
/**
* @param Comment[]|null $comments

View File

@ -17,12 +17,12 @@ final class VersionResolver
* @api
* @var string
*/
public const PACKAGE_VERSION = '646d1888a42854bfa2af3b7537b0e1efbeccaf0a';
public const PACKAGE_VERSION = 'f8221e3e21c487f2d18707f7b979ef6607204826';
/**
* @api
* @var string
*/
public const RELEASE_DATE = '2022-07-03 22:30:07';
public const RELEASE_DATE = '2022-07-03 22:37:10';
/**
* @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 ComposerAutoloaderInit4bb373ad1f6850d6aeb06d893643ee00::getLoader();
return ComposerAutoloaderInitcdd6065f6f3d900461c5946dc02fec48::getLoader();

View File

@ -1319,8 +1319,6 @@ return array(
'Rector\\ChangesReporting\\ValueObjectFactory\\FileDiffFactory' => $baseDir . '/packages/ChangesReporting/ValueObjectFactory/FileDiffFactory.php',
'Rector\\ChangesReporting\\ValueObject\\RectorWithLineChange' => $baseDir . '/packages/ChangesReporting/ValueObject/RectorWithLineChange.php',
'Rector\\CodeQuality\\CompactConverter' => $baseDir . '/rules/CodeQuality/CompactConverter.php',
'Rector\\CodeQuality\\NodeAnalyzer\\ArrayCompacter' => $baseDir . '/rules/CodeQuality/NodeAnalyzer/ArrayCompacter.php',
'Rector\\CodeQuality\\NodeAnalyzer\\ArrayItemsAnalyzer' => $baseDir . '/rules/CodeQuality/NodeAnalyzer/ArrayItemsAnalyzer.php',
'Rector\\CodeQuality\\NodeAnalyzer\\ClassLikeAnalyzer' => $baseDir . '/rules/CodeQuality/NodeAnalyzer/ClassLikeAnalyzer.php',
'Rector\\CodeQuality\\NodeAnalyzer\\ConstructorPropertyDefaultExprResolver' => $baseDir . '/rules/CodeQuality/NodeAnalyzer/ConstructorPropertyDefaultExprResolver.php',
'Rector\\CodeQuality\\NodeAnalyzer\\ForAnalyzer' => $baseDir . '/rules/CodeQuality/NodeAnalyzer/ForAnalyzer.php',

View File

@ -2,7 +2,7 @@
// autoload_real.php @generated by Composer
class ComposerAutoloaderInit4bb373ad1f6850d6aeb06d893643ee00
class ComposerAutoloaderInitcdd6065f6f3d900461c5946dc02fec48
{
private static $loader;
@ -22,19 +22,19 @@ class ComposerAutoloaderInit4bb373ad1f6850d6aeb06d893643ee00
return self::$loader;
}
spl_autoload_register(array('ComposerAutoloaderInit4bb373ad1f6850d6aeb06d893643ee00', 'loadClassLoader'), true, true);
spl_autoload_register(array('ComposerAutoloaderInitcdd6065f6f3d900461c5946dc02fec48', 'loadClassLoader'), true, true);
self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__));
spl_autoload_unregister(array('ComposerAutoloaderInit4bb373ad1f6850d6aeb06d893643ee00', 'loadClassLoader'));
spl_autoload_unregister(array('ComposerAutoloaderInitcdd6065f6f3d900461c5946dc02fec48', 'loadClassLoader'));
require __DIR__ . '/autoload_static.php';
call_user_func(\Composer\Autoload\ComposerStaticInit4bb373ad1f6850d6aeb06d893643ee00::getInitializer($loader));
call_user_func(\Composer\Autoload\ComposerStaticInitcdd6065f6f3d900461c5946dc02fec48::getInitializer($loader));
$loader->setClassMapAuthoritative(true);
$loader->register(true);
$includeFiles = \Composer\Autoload\ComposerStaticInit4bb373ad1f6850d6aeb06d893643ee00::$files;
$includeFiles = \Composer\Autoload\ComposerStaticInitcdd6065f6f3d900461c5946dc02fec48::$files;
foreach ($includeFiles as $fileIdentifier => $file) {
composerRequire4bb373ad1f6850d6aeb06d893643ee00($fileIdentifier, $file);
composerRequirecdd6065f6f3d900461c5946dc02fec48($fileIdentifier, $file);
}
return $loader;
@ -46,7 +46,7 @@ class ComposerAutoloaderInit4bb373ad1f6850d6aeb06d893643ee00
* @param string $file
* @return void
*/
function composerRequire4bb373ad1f6850d6aeb06d893643ee00($fileIdentifier, $file)
function composerRequirecdd6065f6f3d900461c5946dc02fec48($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 ComposerStaticInit4bb373ad1f6850d6aeb06d893643ee00
class ComposerStaticInitcdd6065f6f3d900461c5946dc02fec48
{
public static $files = array (
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php',
@ -1626,8 +1626,6 @@ class ComposerStaticInit4bb373ad1f6850d6aeb06d893643ee00
'Rector\\ChangesReporting\\ValueObjectFactory\\FileDiffFactory' => __DIR__ . '/../..' . '/packages/ChangesReporting/ValueObjectFactory/FileDiffFactory.php',
'Rector\\ChangesReporting\\ValueObject\\RectorWithLineChange' => __DIR__ . '/../..' . '/packages/ChangesReporting/ValueObject/RectorWithLineChange.php',
'Rector\\CodeQuality\\CompactConverter' => __DIR__ . '/../..' . '/rules/CodeQuality/CompactConverter.php',
'Rector\\CodeQuality\\NodeAnalyzer\\ArrayCompacter' => __DIR__ . '/../..' . '/rules/CodeQuality/NodeAnalyzer/ArrayCompacter.php',
'Rector\\CodeQuality\\NodeAnalyzer\\ArrayItemsAnalyzer' => __DIR__ . '/../..' . '/rules/CodeQuality/NodeAnalyzer/ArrayItemsAnalyzer.php',
'Rector\\CodeQuality\\NodeAnalyzer\\ClassLikeAnalyzer' => __DIR__ . '/../..' . '/rules/CodeQuality/NodeAnalyzer/ClassLikeAnalyzer.php',
'Rector\\CodeQuality\\NodeAnalyzer\\ConstructorPropertyDefaultExprResolver' => __DIR__ . '/../..' . '/rules/CodeQuality/NodeAnalyzer/ConstructorPropertyDefaultExprResolver.php',
'Rector\\CodeQuality\\NodeAnalyzer\\ForAnalyzer' => __DIR__ . '/../..' . '/rules/CodeQuality/NodeAnalyzer/ForAnalyzer.php',
@ -3412,9 +3410,9 @@ class ComposerStaticInit4bb373ad1f6850d6aeb06d893643ee00
public static function getInitializer(ClassLoader $loader)
{
return \Closure::bind(function () use ($loader) {
$loader->prefixLengthsPsr4 = ComposerStaticInit4bb373ad1f6850d6aeb06d893643ee00::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInit4bb373ad1f6850d6aeb06d893643ee00::$prefixDirsPsr4;
$loader->classMap = ComposerStaticInit4bb373ad1f6850d6aeb06d893643ee00::$classMap;
$loader->prefixLengthsPsr4 = ComposerStaticInitcdd6065f6f3d900461c5946dc02fec48::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInitcdd6065f6f3d900461c5946dc02fec48::$prefixDirsPsr4;
$loader->classMap = ComposerStaticInitcdd6065f6f3d900461c5946dc02fec48::$classMap;
}, null, ClassLoader::class);
}