Skip to content

Commit

Permalink
Updated Rector to commit 622e93f2aa7c4cdcfb8a32388d27ae43df95bb9a
Browse files Browse the repository at this point in the history
rectorphp/rector-src@622e93f [Php73] Remove next node attribute usage on ArrayKeyFirstLastRector (#3559)
  • Loading branch information
TomasVotruba committed Apr 3, 2023
1 parent f5640c1 commit a6db719
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 61 deletions.
127 changes: 78 additions & 49 deletions rules/Php73/Rector/FuncCall/ArrayKeyFirstLastRector.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@
use PhpParser\Node;
use PhpParser\Node\Expr\FuncCall;
use PhpParser\Node\Name;
use PhpParser\Node\Stmt;
use PhpParser\Node\Stmt\Expression;
use PHPStan\Reflection\ReflectionProvider;
use Rector\Core\Contract\PhpParser\Node\StmtsAwareInterface;
use Rector\Core\Rector\AbstractRector;
use Rector\Core\ValueObject\PhpVersionFeature;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\VersionBonding\Contract\MinPhpVersionInterface;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
Expand Down Expand Up @@ -68,80 +69,108 @@ public function getRuleDefinition() : RuleDefinition
*/
public function getNodeTypes() : array
{
return [FuncCall::class];
return [StmtsAwareInterface::class];
}
/**
* @param FuncCall $node
* @param StmtsAwareInterface $node
*/
public function refactor(Node $node) : ?Node
public function refactor(Node $node) : ?StmtsAwareInterface
{
if ($this->shouldSkip($node)) {
return null;
}
$nextExpression = $this->getNextExpression($node);
if (!$nextExpression instanceof Node) {
return $this->processArrayKeyFirstLast($node, \false);
}
public function provideMinPhpVersion() : int
{
return PhpVersionFeature::ARRAY_KEY_FIRST_LAST;
}
private function processArrayKeyFirstLast(StmtsAwareInterface $stmtsAware, bool $hasChanged, int $jumpToKey = 0) : ?StmtsAwareInterface
{
if ($stmtsAware->stmts === null) {
return null;
}
$resetOrEndFuncCall = $node;
$keyFuncCall = $this->betterNodeFinder->findFirst($nextExpression, function (Node $node) use($resetOrEndFuncCall) : bool {
if (!$node instanceof FuncCall) {
return \false;
\end($stmtsAware->stmts);
/** @var int $totalKeys */
$totalKeys = \key($stmtsAware->stmts);
for ($key = $jumpToKey; $key < $totalKeys; ++$key) {
if (!isset($stmtsAware->stmts[$key], $stmtsAware->stmts[$key + 1])) {
break;
}
if (!$this->isName($node, 'key')) {
return \false;
if (!$stmtsAware->stmts[$key] instanceof Expression) {
continue;
}
return $this->nodeComparator->areNodesEqual($resetOrEndFuncCall->args[0], $node->args[0]);
});
if (!$keyFuncCall instanceof FuncCall) {
return null;
/** @var Expression $stmt */
$stmt = $stmtsAware->stmts[$key];
if ($this->shouldSkip($stmt)) {
continue;
}
$nextStmt = $stmtsAware->stmts[$key + 1];
/** @var FuncCall $resetOrEndFuncCall */
$resetOrEndFuncCall = $stmt->expr;
$keyFuncCall = $this->resolveKeyFuncCall($nextStmt, $resetOrEndFuncCall);
if (!$keyFuncCall instanceof FuncCall) {
continue;
}
if ($this->hasPrevCallNext($stmtsAware, $key + 2, $totalKeys, $keyFuncCall)) {
continue;
}
$newName = self::PREVIOUS_TO_NEW_FUNCTIONS[$this->getName($stmt->expr)];
$keyFuncCall->name = new Name($newName);
unset($stmtsAware->stmts[$key]);
$hasChanged = \true;
return $this->processArrayKeyFirstLast($stmtsAware, $hasChanged, $key + 2);
}
if ($this->hasPrevCallNext($keyFuncCall)) {
return null;
if ($hasChanged) {
return $stmtsAware;
}
$newName = self::PREVIOUS_TO_NEW_FUNCTIONS[$this->getName($node)];
$keyFuncCall->name = new Name($newName);
$this->removeNode($node);
// change next node before remove, so it needs to return the Node
return $node;
}
public function provideMinPhpVersion() : int
{
return PhpVersionFeature::ARRAY_KEY_FIRST_LAST;
return null;
}
private function hasPrevCallNext(FuncCall $funcCall) : bool
private function resolveKeyFuncCall(Stmt $nextStmt, FuncCall $resetOrEndFuncCall) : ?FuncCall
{
return (bool) $this->betterNodeFinder->findFirstNext($funcCall, function (Node $subNode) use($funcCall) : bool {
/** @var FuncCall|null */
return $this->betterNodeFinder->findFirst($nextStmt, function (Node $subNode) use($resetOrEndFuncCall) : bool {
if (!$subNode instanceof FuncCall) {
return \false;
}
if (!$this->isName($subNode, 'prev')) {
if (!$this->isName($subNode, 'key')) {
return \false;
}
if ($subNode->isFirstClassCallable()) {
return $this->nodeComparator->areNodesEqual($resetOrEndFuncCall->args[0], $subNode->args[0]);
});
}
private function hasPrevCallNext(StmtsAwareInterface $stmtsAware, int $nextKey, int $totalKeys, FuncCall $funcCall) : bool
{
for ($key = $nextKey; $key <= $totalKeys; ++$key) {
if (!isset($stmtsAware->stmts[$key])) {
continue;
}
$hasPrevCallNext = (bool) $this->betterNodeFinder->findFirst($stmtsAware->stmts[$key], function (Node $subNode) use($funcCall) : bool {
if (!$subNode instanceof FuncCall) {
return \false;
}
if (!$this->isName($subNode, 'prev')) {
return \false;
}
if ($subNode->isFirstClassCallable()) {
return \true;
}
return $this->nodeComparator->areNodesEqual($subNode->args[0]->value, $funcCall->args[0]->value);
});
if ($hasPrevCallNext) {
return \true;
}
return $this->nodeComparator->areNodesEqual($subNode->args[0]->value, $funcCall->args[0]->value);
});
}
return \false;
}
private function shouldSkip(FuncCall $funcCall) : bool
private function shouldSkip(Expression $expression) : bool
{
if (!$this->isNames($funcCall, ['reset', 'end'])) {
if (!$expression->expr instanceof FuncCall) {
return \true;
}
if (!$this->isNames($expression->expr, ['reset', 'end'])) {
return \true;
}
if (!$this->reflectionProvider->hasFunction(new Name(self::ARRAY_KEY_FIRST), null)) {
return \true;
}
return !$this->reflectionProvider->hasFunction(new Name(self::ARRAY_KEY_LAST), null);
}
private function getNextExpression(FuncCall $funcCall) : ?Node
{
$currentStmt = $this->betterNodeFinder->resolveCurrentStatement($funcCall);
if (!$currentStmt instanceof Expression) {
return null;
}
if ($currentStmt->expr !== $funcCall) {
return null;
}
return $currentStmt->getAttribute(AttributeKey::NEXT_NODE);
}
}
4 changes: 2 additions & 2 deletions src/Application/VersionResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@ final class VersionResolver
* @api
* @var string
*/
public const PACKAGE_VERSION = '5e5681d9edbb438b5782b45fde6e88650aa3843f';
public const PACKAGE_VERSION = '622e93f2aa7c4cdcfb8a32388d27ae43df95bb9a';
/**
* @api
* @var string
*/
public const RELEASE_DATE = '2023-04-04 00:15:55';
public const RELEASE_DATE = '2023-04-04 01:22:06';
/**
* @var int
*/
Expand Down
2 changes: 1 addition & 1 deletion vendor/autoload.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,4 @@

require_once __DIR__ . '/composer/autoload_real.php';

return ComposerAutoloaderInit277ffbed55498b11c1ef07f9e681665e::getLoader();
return ComposerAutoloaderInitbf34321edf24c05d9f6b115e015e4c7f::getLoader();
10 changes: 5 additions & 5 deletions vendor/composer/autoload_real.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

// autoload_real.php @generated by Composer

class ComposerAutoloaderInit277ffbed55498b11c1ef07f9e681665e
class ComposerAutoloaderInitbf34321edf24c05d9f6b115e015e4c7f
{
private static $loader;

Expand All @@ -22,17 +22,17 @@ public static function getLoader()
return self::$loader;
}

spl_autoload_register(array('ComposerAutoloaderInit277ffbed55498b11c1ef07f9e681665e', 'loadClassLoader'), true, true);
spl_autoload_register(array('ComposerAutoloaderInitbf34321edf24c05d9f6b115e015e4c7f', 'loadClassLoader'), true, true);
self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__));
spl_autoload_unregister(array('ComposerAutoloaderInit277ffbed55498b11c1ef07f9e681665e', 'loadClassLoader'));
spl_autoload_unregister(array('ComposerAutoloaderInitbf34321edf24c05d9f6b115e015e4c7f', 'loadClassLoader'));

require __DIR__ . '/autoload_static.php';
call_user_func(\Composer\Autoload\ComposerStaticInit277ffbed55498b11c1ef07f9e681665e::getInitializer($loader));
call_user_func(\Composer\Autoload\ComposerStaticInitbf34321edf24c05d9f6b115e015e4c7f::getInitializer($loader));

$loader->setClassMapAuthoritative(true);
$loader->register(true);

$filesToLoad = \Composer\Autoload\ComposerStaticInit277ffbed55498b11c1ef07f9e681665e::$files;
$filesToLoad = \Composer\Autoload\ComposerStaticInitbf34321edf24c05d9f6b115e015e4c7f::$files;
$requireFile = \Closure::bind(static function ($fileIdentifier, $file) {
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
$GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
Expand Down
8 changes: 4 additions & 4 deletions vendor/composer/autoload_static.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

namespace Composer\Autoload;

class ComposerStaticInit277ffbed55498b11c1ef07f9e681665e
class ComposerStaticInitbf34321edf24c05d9f6b115e015e4c7f
{
public static $files = array (
'ad155f8f1cf0d418fe49e248db8c661b' => __DIR__ . '/..' . '/react/promise/src/functions_include.php',
Expand Down Expand Up @@ -3131,9 +3131,9 @@ class ComposerStaticInit277ffbed55498b11c1ef07f9e681665e
public static function getInitializer(ClassLoader $loader)
{
return \Closure::bind(function () use ($loader) {
$loader->prefixLengthsPsr4 = ComposerStaticInit277ffbed55498b11c1ef07f9e681665e::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInit277ffbed55498b11c1ef07f9e681665e::$prefixDirsPsr4;
$loader->classMap = ComposerStaticInit277ffbed55498b11c1ef07f9e681665e::$classMap;
$loader->prefixLengthsPsr4 = ComposerStaticInitbf34321edf24c05d9f6b115e015e4c7f::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInitbf34321edf24c05d9f6b115e015e4c7f::$prefixDirsPsr4;
$loader->classMap = ComposerStaticInitbf34321edf24c05d9f6b115e015e4c7f::$classMap;

}, null, ClassLoader::class);
}
Expand Down

0 comments on commit a6db719

Please sign in to comment.