Updated Rector to commit 9f9b29c741

9f9b29c741 [DowngradePhp54] Add DowngradeThisInClosureRector (#1995)
This commit is contained in:
Tomas Votruba 2022-04-02 15:46:27 +00:00
parent c0fda8c76d
commit d7c212ece1
9 changed files with 226 additions and 22 deletions

View File

@ -7,6 +7,7 @@ use Rector\Core\Configuration\Option;
use Rector\Core\ValueObject\PhpVersion;
use Rector\DowngradePhp54\Rector\Array_\ShortArrayToLongArrayRector;
use Rector\DowngradePhp54\Rector\Closure\DowngradeStaticClosureRector;
use Rector\DowngradePhp54\Rector\Closure\DowngradeThisInClosureRector;
use Rector\DowngradePhp54\Rector\FuncCall\DowngradeIndirectCallByArrayRector;
use Rector\DowngradePhp54\Rector\FunctionLike\DowngradeCallableTypeDeclarationRector;
use Rector\DowngradePhp54\Rector\LNumber\DowngradeBinaryNotationRector;
@ -22,4 +23,5 @@ return static function (\Symfony\Component\DependencyInjection\Loader\Configurat
$services->set(\Rector\DowngradePhp54\Rector\FunctionLike\DowngradeCallableTypeDeclarationRector::class);
$services->set(\Rector\DowngradePhp54\Rector\LNumber\DowngradeBinaryNotationRector::class);
$services->set(\Rector\DowngradePhp54\Rector\MethodCall\DowngradeInstanceMethodCallRector::class);
$services->set(\Rector\DowngradePhp54\Rector\Closure\DowngradeThisInClosureRector::class);
};

View File

@ -1,4 +1,4 @@
# 506 Rules Overview
# 508 Rules Overview
<br>
@ -20,7 +20,7 @@
- [DowngradePhp53](#downgradephp53) (1)
- [DowngradePhp54](#downgradephp54) (6)
- [DowngradePhp54](#downgradephp54) (7)
- [DowngradePhp55](#downgradephp55) (4)
@ -38,7 +38,7 @@
- [DowngradePhp80](#downgradephp80) (28)
- [DowngradePhp81](#downgradephp81) (8)
- [DowngradePhp81](#downgradephp81) (9)
- [EarlyReturn](#earlyreturn) (11)
@ -3916,6 +3916,33 @@ Remove static from closure
<br>
### DowngradeThisInClosureRector
Downgrade `$this->` inside Closure to use assigned `$self` = `$this` before Closure
- class: [`Rector\DowngradePhp54\Rector\Closure\DowngradeThisInClosureRector`](../rules/DowngradePhp54/Rector/Closure/DowngradeThisInClosureRector.php)
```diff
class SomeClass
{
public $property = 'test';
public function run()
{
- $function = function () {
- echo $this->property;
+ $self = $this;
+ $function = function () use ($self) {
+ echo $self->property;
};
$function();
}
}
```
<br>
### ShortArrayToLongArrayRector
Replace short arrays by long arrays
@ -5826,6 +5853,35 @@ Removes union type property type definition, adding `@var` annotations instead.
## DowngradePhp81
### DowngradeArrayIsListRector
Replace `array_is_list()` function
- class: [`Rector\DowngradePhp81\Rector\FuncCall\DowngradeArrayIsListRector`](../rules/DowngradePhp81/Rector/FuncCall/DowngradeArrayIsListRector.php)
```diff
-array_is_list([1 => 'apple', 'orange']);
+$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;
+};
+$arrayIsList([1 => 'apple', 'orange']);
```
<br>
### DowngradeArraySpreadStringKeyRector
Replace array spread with string key to array_merge function

View File

@ -0,0 +1,144 @@
<?php
declare (strict_types=1);
namespace Rector\DowngradePhp54\Rector\Closure;
use PhpParser\Node;
use PhpParser\Node\Expr\Assign;
use PhpParser\Node\Expr\Closure;
use PhpParser\Node\Expr\ClosureUse;
use PhpParser\Node\Expr\PropertyFetch;
use PhpParser\Node\Expr\Variable;
use PhpParser\Node\FunctionLike;
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Expression;
use PhpParser\Node\Stmt\Function_;
use PHPStan\Reflection\Php\PhpPropertyReflection;
use Rector\Core\Rector\AbstractRector;
use Rector\Core\Reflection\ReflectionResolver;
use Rector\Naming\Naming\VariableNaming;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* @changelog https://wiki.php.net/rfc/closures/object-extension
*
* @see \Rector\Tests\DowngradePhp54\Rector\Closure\DowngradeThisInClosureRector\DowngradeThisInClosureRectorTest
*/
final class DowngradeThisInClosureRector extends \Rector\Core\Rector\AbstractRector
{
/**
* @readonly
* @var \Rector\Naming\Naming\VariableNaming
*/
private $variableNaming;
/**
* @readonly
* @var \Rector\Core\Reflection\ReflectionResolver
*/
private $reflectionResolver;
public function __construct(\Rector\Naming\Naming\VariableNaming $variableNaming, \Rector\Core\Reflection\ReflectionResolver $reflectionResolver)
{
$this->variableNaming = $variableNaming;
$this->reflectionResolver = $reflectionResolver;
}
public function getRuleDefinition() : \Symplify\RuleDocGenerator\ValueObject\RuleDefinition
{
return new \Symplify\RuleDocGenerator\ValueObject\RuleDefinition('Downgrade $this-> inside Closure to use assigned $self = $this before Closure', [new \Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample(<<<'CODE_SAMPLE'
class SomeClass
{
public $property = 'test';
public function run()
{
$function = function () {
echo $this->property;
};
$function();
}
}
CODE_SAMPLE
, <<<'CODE_SAMPLE'
class SomeClass
{
public $property = 'test';
public function run()
{
$self = $this;
$function = function () use ($self) {
echo $self->property;
};
$function();
}
}
CODE_SAMPLE
)]);
}
/**
* @return array<class-string<Node>>
*/
public function getNodeTypes() : array
{
return [\PhpParser\Node\Expr\Closure::class];
}
/**
* @param Closure $node
*/
public function refactor(\PhpParser\Node $node) : ?\PhpParser\Node
{
$closureParentFunctionLike = $this->betterNodeFinder->findParentByTypes($node, [\PhpParser\Node\Stmt\ClassMethod::class, \PhpParser\Node\Stmt\Function_::class]);
/** @var PropertyFetch[] $propertyFetches */
$propertyFetches = $this->resolvePropertyFetches($node, $closureParentFunctionLike);
if ($propertyFetches === []) {
return null;
}
$scope = $node->getAttribute(\Rector\NodeTypeResolver\Node\AttributeKey::SCOPE);
$selfVariable = new \PhpParser\Node\Expr\Variable($this->variableNaming->createCountedValueName('self', $scope));
$expression = new \PhpParser\Node\Stmt\Expression(new \PhpParser\Node\Expr\Assign($selfVariable, new \PhpParser\Node\Expr\Variable('this')));
$currentStmt = $node->getAttribute(\Rector\NodeTypeResolver\Node\AttributeKey::CURRENT_STATEMENT);
$this->nodesToAddCollector->addNodeBeforeNode($expression, $currentStmt);
$this->traverseNodesWithCallable($node, function (\PhpParser\Node $subNode) use($selfVariable) : ?Closure {
if (!$subNode instanceof \PhpParser\Node\Expr\Closure) {
return null;
}
$subNode->uses = \array_merge($subNode->uses, [new \PhpParser\Node\Expr\ClosureUse($selfVariable)]);
return $subNode;
});
foreach ($propertyFetches as $propertyFetch) {
$propertyFetch->var = $selfVariable;
}
return $node;
}
/**
* @return PropertyFetch[]
*/
private function resolvePropertyFetches(\PhpParser\Node\Expr\Closure $node, ?\PhpParser\Node\FunctionLike $closureParentFunctionLike) : array
{
/** @var PropertyFetch[] $propertyFetches */
$propertyFetches = $this->betterNodeFinder->find($node->stmts, function (\PhpParser\Node $subNode) use($closureParentFunctionLike) : bool {
// multiple deep Closure may access $this, unless its parent is not Closure
$parent = $this->betterNodeFinder->findParentByTypes($subNode, [\PhpParser\Node\Stmt\ClassMethod::class, \PhpParser\Node\Stmt\Function_::class]);
if ($parent instanceof \PhpParser\Node\FunctionLike && $parent !== $closureParentFunctionLike) {
return \false;
}
if (!$subNode instanceof \PhpParser\Node\Expr\PropertyFetch) {
return \false;
}
if (!$subNode->var instanceof \PhpParser\Node\Expr\Variable) {
return \false;
}
if (!$this->nodeNameResolver->isName($subNode->var, 'this')) {
return \false;
}
$phpPropertyReflection = $this->reflectionResolver->resolvePropertyReflectionFromPropertyFetch($subNode);
if (!$phpPropertyReflection instanceof \PHPStan\Reflection\Php\PhpPropertyReflection) {
return \false;
}
return $phpPropertyReflection->isPublic();
});
return $propertyFetches;
}
}

View File

@ -16,11 +16,11 @@ final class VersionResolver
/**
* @var string
*/
public const PACKAGE_VERSION = 'e077d7c3fb9cc4204857a80d587f23a75ddf6665';
public const PACKAGE_VERSION = '9f9b29c7418647f260c99f0b6bdeebc2fee0af6f';
/**
* @var string
*/
public const RELEASE_DATE = '2022-04-02 15:09:17';
public const RELEASE_DATE = '2022-04-02 17:40:58';
public static function resolvePackageVersion() : string
{
$process = new \RectorPrefix20220402\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 ComposerAutoloaderInitb2a46d0a1fd67da06f14f31687db4f9d::getLoader();
return ComposerAutoloaderInitb8f7e4dcb1ceef2c51ff1c33837960b4::getLoader();

View File

@ -1955,6 +1955,7 @@ return array(
'Rector\\DowngradePhp53\\Rector\\Dir\\DirConstToFileConstRector' => $baseDir . '/rules/DowngradePhp53/Rector/Dir/DirConstToFileConstRector.php',
'Rector\\DowngradePhp54\\Rector\\Array_\\ShortArrayToLongArrayRector' => $baseDir . '/rules/DowngradePhp54/Rector/Array_/ShortArrayToLongArrayRector.php',
'Rector\\DowngradePhp54\\Rector\\Closure\\DowngradeStaticClosureRector' => $baseDir . '/rules/DowngradePhp54/Rector/Closure/DowngradeStaticClosureRector.php',
'Rector\\DowngradePhp54\\Rector\\Closure\\DowngradeThisInClosureRector' => $baseDir . '/rules/DowngradePhp54/Rector/Closure/DowngradeThisInClosureRector.php',
'Rector\\DowngradePhp54\\Rector\\FuncCall\\DowngradeIndirectCallByArrayRector' => $baseDir . '/rules/DowngradePhp54/Rector/FuncCall/DowngradeIndirectCallByArrayRector.php',
'Rector\\DowngradePhp54\\Rector\\FunctionLike\\DowngradeCallableTypeDeclarationRector' => $baseDir . '/rules/DowngradePhp54/Rector/FunctionLike/DowngradeCallableTypeDeclarationRector.php',
'Rector\\DowngradePhp54\\Rector\\LNumber\\DowngradeBinaryNotationRector' => $baseDir . '/rules/DowngradePhp54/Rector/LNumber/DowngradeBinaryNotationRector.php',

View File

@ -2,7 +2,7 @@
// autoload_real.php @generated by Composer
class ComposerAutoloaderInitb2a46d0a1fd67da06f14f31687db4f9d
class ComposerAutoloaderInitb8f7e4dcb1ceef2c51ff1c33837960b4
{
private static $loader;
@ -22,19 +22,19 @@ class ComposerAutoloaderInitb2a46d0a1fd67da06f14f31687db4f9d
return self::$loader;
}
spl_autoload_register(array('ComposerAutoloaderInitb2a46d0a1fd67da06f14f31687db4f9d', 'loadClassLoader'), true, true);
spl_autoload_register(array('ComposerAutoloaderInitb8f7e4dcb1ceef2c51ff1c33837960b4', 'loadClassLoader'), true, true);
self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__));
spl_autoload_unregister(array('ComposerAutoloaderInitb2a46d0a1fd67da06f14f31687db4f9d', 'loadClassLoader'));
spl_autoload_unregister(array('ComposerAutoloaderInitb8f7e4dcb1ceef2c51ff1c33837960b4', 'loadClassLoader'));
require __DIR__ . '/autoload_static.php';
\Composer\Autoload\ComposerStaticInitb2a46d0a1fd67da06f14f31687db4f9d::getInitializer($loader)();
\Composer\Autoload\ComposerStaticInitb8f7e4dcb1ceef2c51ff1c33837960b4::getInitializer($loader)();
$loader->setClassMapAuthoritative(true);
$loader->register(true);
$includeFiles = \Composer\Autoload\ComposerStaticInitb2a46d0a1fd67da06f14f31687db4f9d::$files;
$includeFiles = \Composer\Autoload\ComposerStaticInitb8f7e4dcb1ceef2c51ff1c33837960b4::$files;
foreach ($includeFiles as $fileIdentifier => $file) {
composerRequireb2a46d0a1fd67da06f14f31687db4f9d($fileIdentifier, $file);
composerRequireb8f7e4dcb1ceef2c51ff1c33837960b4($fileIdentifier, $file);
}
return $loader;
@ -46,7 +46,7 @@ class ComposerAutoloaderInitb2a46d0a1fd67da06f14f31687db4f9d
* @param string $file
* @return void
*/
function composerRequireb2a46d0a1fd67da06f14f31687db4f9d($fileIdentifier, $file)
function composerRequireb8f7e4dcb1ceef2c51ff1c33837960b4($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 ComposerStaticInitb2a46d0a1fd67da06f14f31687db4f9d
class ComposerStaticInitb8f7e4dcb1ceef2c51ff1c33837960b4
{
public static $files = array (
'320cde22f66dd4f5d3fd621d3e88b98f' => __DIR__ . '/..' . '/symfony/polyfill-ctype/bootstrap.php',
@ -2324,6 +2324,7 @@ class ComposerStaticInitb2a46d0a1fd67da06f14f31687db4f9d
'Rector\\DowngradePhp53\\Rector\\Dir\\DirConstToFileConstRector' => __DIR__ . '/../..' . '/rules/DowngradePhp53/Rector/Dir/DirConstToFileConstRector.php',
'Rector\\DowngradePhp54\\Rector\\Array_\\ShortArrayToLongArrayRector' => __DIR__ . '/../..' . '/rules/DowngradePhp54/Rector/Array_/ShortArrayToLongArrayRector.php',
'Rector\\DowngradePhp54\\Rector\\Closure\\DowngradeStaticClosureRector' => __DIR__ . '/../..' . '/rules/DowngradePhp54/Rector/Closure/DowngradeStaticClosureRector.php',
'Rector\\DowngradePhp54\\Rector\\Closure\\DowngradeThisInClosureRector' => __DIR__ . '/../..' . '/rules/DowngradePhp54/Rector/Closure/DowngradeThisInClosureRector.php',
'Rector\\DowngradePhp54\\Rector\\FuncCall\\DowngradeIndirectCallByArrayRector' => __DIR__ . '/../..' . '/rules/DowngradePhp54/Rector/FuncCall/DowngradeIndirectCallByArrayRector.php',
'Rector\\DowngradePhp54\\Rector\\FunctionLike\\DowngradeCallableTypeDeclarationRector' => __DIR__ . '/../..' . '/rules/DowngradePhp54/Rector/FunctionLike/DowngradeCallableTypeDeclarationRector.php',
'Rector\\DowngradePhp54\\Rector\\LNumber\\DowngradeBinaryNotationRector' => __DIR__ . '/../..' . '/rules/DowngradePhp54/Rector/LNumber/DowngradeBinaryNotationRector.php',
@ -3839,9 +3840,9 @@ class ComposerStaticInitb2a46d0a1fd67da06f14f31687db4f9d
public static function getInitializer(ClassLoader $loader)
{
return \Closure::bind(function () use ($loader) {
$loader->prefixLengthsPsr4 = ComposerStaticInitb2a46d0a1fd67da06f14f31687db4f9d::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInitb2a46d0a1fd67da06f14f31687db4f9d::$prefixDirsPsr4;
$loader->classMap = ComposerStaticInitb2a46d0a1fd67da06f14f31687db4f9d::$classMap;
$loader->prefixLengthsPsr4 = ComposerStaticInitb8f7e4dcb1ceef2c51ff1c33837960b4::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInitb8f7e4dcb1ceef2c51ff1c33837960b4::$prefixDirsPsr4;
$loader->classMap = ComposerStaticInitb8f7e4dcb1ceef2c51ff1c33837960b4::$classMap;
}, null, ClassLoader::class);
}

View File

@ -9,8 +9,8 @@ $loader = require_once __DIR__.'/autoload.php';
if (!class_exists('AutoloadIncluder', false) && !interface_exists('AutoloadIncluder', false) && !trait_exists('AutoloadIncluder', false)) {
spl_autoload_call('RectorPrefix20220402\AutoloadIncluder');
}
if (!class_exists('ComposerAutoloaderInitb2a46d0a1fd67da06f14f31687db4f9d', false) && !interface_exists('ComposerAutoloaderInitb2a46d0a1fd67da06f14f31687db4f9d', false) && !trait_exists('ComposerAutoloaderInitb2a46d0a1fd67da06f14f31687db4f9d', false)) {
spl_autoload_call('RectorPrefix20220402\ComposerAutoloaderInitb2a46d0a1fd67da06f14f31687db4f9d');
if (!class_exists('ComposerAutoloaderInitb8f7e4dcb1ceef2c51ff1c33837960b4', false) && !interface_exists('ComposerAutoloaderInitb8f7e4dcb1ceef2c51ff1c33837960b4', false) && !trait_exists('ComposerAutoloaderInitb8f7e4dcb1ceef2c51ff1c33837960b4', false)) {
spl_autoload_call('RectorPrefix20220402\ComposerAutoloaderInitb8f7e4dcb1ceef2c51ff1c33837960b4');
}
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('RectorPrefix20220402\Helmich\TypoScriptParser\Parser\AST\Statement');
@ -59,9 +59,9 @@ if (!function_exists('print_node')) {
return \RectorPrefix20220402\print_node(...func_get_args());
}
}
if (!function_exists('composerRequireb2a46d0a1fd67da06f14f31687db4f9d')) {
function composerRequireb2a46d0a1fd67da06f14f31687db4f9d() {
return \RectorPrefix20220402\composerRequireb2a46d0a1fd67da06f14f31687db4f9d(...func_get_args());
if (!function_exists('composerRequireb8f7e4dcb1ceef2c51ff1c33837960b4')) {
function composerRequireb8f7e4dcb1ceef2c51ff1c33837960b4() {
return \RectorPrefix20220402\composerRequireb8f7e4dcb1ceef2c51ff1c33837960b4(...func_get_args());
}
}
if (!function_exists('scanPath')) {