Updated Rector to commit eaaecc39d7

eaaecc39d7 Remove PREVIOUS_STATEMENT from StatementNodeVisitor (#2146)
This commit is contained in:
Tomas Votruba 2022-04-24 16:25:18 +00:00
parent 671dde4094
commit 348b2f0e8d
24 changed files with 508 additions and 458 deletions

View File

@ -96,7 +96,7 @@ return static function (\Rector\Config\RectorConfig $rectorConfig) : void {
$services->set(\PHPStan\Analyser\ScopeFactory::class)->factory([\RectorPrefix20220424\Symfony\Component\DependencyInjection\Loader\Configurator\service(\Rector\NodeTypeResolver\DependencyInjection\PHPStanServicesFactory::class), 'createScopeFactory']);
$services->set(\PHPStan\PhpDoc\TypeNodeResolver::class)->factory([\RectorPrefix20220424\Symfony\Component\DependencyInjection\Loader\Configurator\service(\Rector\NodeTypeResolver\DependencyInjection\PHPStanServicesFactory::class), 'createTypeNodeResolver']);
$services->set(\Rector\NodeTypeResolver\Reflection\BetterReflection\SourceLocatorProvider\DynamicSourceLocatorProvider::class)->factory([\RectorPrefix20220424\Symfony\Component\DependencyInjection\Loader\Configurator\service(\Rector\NodeTypeResolver\DependencyInjection\PHPStanServicesFactory::class), 'createDynamicSourceLocatorProvider']);
$services->set(\RectorPrefix20220424\Idiosyncratic\EditorConfig\EditorConfig::class);
$services->set(\RectorPrefix20220424\Ergebnis\Json\Printer\Printer::class);
$services->alias(\RectorPrefix20220424\Ergebnis\Json\Printer\PrinterInterface::class, \RectorPrefix20220424\Ergebnis\Json\Printer\Printer::class);
$services->set(\RectorPrefix20220424\Idiosyncratic\EditorConfig\EditorConfig::class);
};

View File

@ -9,19 +9,6 @@ use PhpParser\NodeVisitorAbstract;
use Rector\NodeTypeResolver\Node\AttributeKey;
final class StatementNodeVisitor extends \PhpParser\NodeVisitorAbstract
{
/**
* @var \PhpParser\Node\Stmt|null
*/
private $previousStmt;
/**
* @param Node[] $nodes
* @return Node[]|null
*/
public function beforeTraverse(array $nodes) : ?array
{
$this->previousStmt = null;
return null;
}
public function enterNode(\PhpParser\Node $node) : ?\PhpParser\Node
{
$parent = $node->getAttribute(\Rector\NodeTypeResolver\Node\AttributeKey::PARENT_NODE);
@ -29,24 +16,22 @@ final class StatementNodeVisitor extends \PhpParser\NodeVisitorAbstract
if (!$node instanceof \PhpParser\Node\Stmt) {
return null;
}
$node->setAttribute(\Rector\NodeTypeResolver\Node\AttributeKey::PREVIOUS_STATEMENT, $this->previousStmt);
$node->setAttribute(\Rector\NodeTypeResolver\Node\AttributeKey::CURRENT_STATEMENT, $node);
$this->previousStmt = $node;
}
if (\property_exists($node, 'stmts')) {
$previous = $node;
foreach ((array) $node->stmts as $stmt) {
/** @var Stmt $stmt */
$stmt->setAttribute(\Rector\NodeTypeResolver\Node\AttributeKey::PREVIOUS_STATEMENT, $previous);
$stmt->setAttribute(\Rector\NodeTypeResolver\Node\AttributeKey::CURRENT_STATEMENT, $stmt);
$previous = $stmt;
}
}
$currentStmt = $node->getAttribute(\Rector\NodeTypeResolver\Node\AttributeKey::CURRENT_STATEMENT);
if ($parent instanceof \PhpParser\Node && !$currentStmt instanceof \PhpParser\Node) {
$node->setAttribute(\Rector\NodeTypeResolver\Node\AttributeKey::PREVIOUS_STATEMENT, $parent->getAttribute(\Rector\NodeTypeResolver\Node\AttributeKey::PREVIOUS_STATEMENT));
$node->setAttribute(\Rector\NodeTypeResolver\Node\AttributeKey::CURRENT_STATEMENT, $parent->getAttribute(\Rector\NodeTypeResolver\Node\AttributeKey::CURRENT_STATEMENT));
if (!$parent instanceof \PhpParser\Node) {
return null;
}
if ($currentStmt instanceof \PhpParser\Node) {
return null;
}
$node->setAttribute(\Rector\NodeTypeResolver\Node\AttributeKey::CURRENT_STATEMENT, $parent->getAttribute(\Rector\NodeTypeResolver\Node\AttributeKey::CURRENT_STATEMENT));
return null;
}
}

View File

@ -16,11 +16,11 @@ final class VersionResolver
/**
* @var string
*/
public const PACKAGE_VERSION = '1084889b30d96eb1545be3758fd2e2464ca4cece';
public const PACKAGE_VERSION = 'eaaecc39d7077b49ad2b36a93e7dd21b2f25453c';
/**
* @var string
*/
public const RELEASE_DATE = '2022-04-24 22:21:16';
public const RELEASE_DATE = '2022-04-24 16:19:51';
/**
* @var string
*/

View File

@ -49,7 +49,7 @@ abstract class AbstractRector extends \PhpParser\NodeVisitorAbstract implements
/**
* @var string[]
*/
private const ATTRIBUTES_TO_MIRROR = [\Rector\NodeTypeResolver\Node\AttributeKey::USE_NODES, \Rector\NodeTypeResolver\Node\AttributeKey::SCOPE, \Rector\NodeTypeResolver\Node\AttributeKey::RESOLVED_NAME, \Rector\NodeTypeResolver\Node\AttributeKey::PARENT_NODE, \Rector\NodeTypeResolver\Node\AttributeKey::CURRENT_STATEMENT, \Rector\NodeTypeResolver\Node\AttributeKey::PREVIOUS_STATEMENT];
private const ATTRIBUTES_TO_MIRROR = [\Rector\NodeTypeResolver\Node\AttributeKey::USE_NODES, \Rector\NodeTypeResolver\Node\AttributeKey::SCOPE, \Rector\NodeTypeResolver\Node\AttributeKey::RESOLVED_NAME, \Rector\NodeTypeResolver\Node\AttributeKey::PARENT_NODE, \Rector\NodeTypeResolver\Node\AttributeKey::CURRENT_STATEMENT];
/**
* @var string
*/

2
vendor/autoload.php vendored
View File

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

View File

@ -2905,6 +2905,7 @@ return array(
'Rector\\Symfony\\NodeAnalyzer\\RouteRequiredParamNameToTypesResolver' => $vendorDir . '/rector/rector-symfony/src/NodeAnalyzer/RouteRequiredParamNameToTypesResolver.php',
'Rector\\Symfony\\NodeAnalyzer\\ServiceTypeMethodCallResolver' => $vendorDir . '/rector/rector-symfony/src/NodeAnalyzer/ServiceTypeMethodCallResolver.php',
'Rector\\Symfony\\NodeAnalyzer\\SymfonyControllerFilter' => $vendorDir . '/rector/rector-symfony/src/NodeAnalyzer/SymfonyControllerFilter.php',
'Rector\\Symfony\\NodeAnalyzer\\SymfonyTestCaseAnalyzer' => $vendorDir . '/rector/rector-symfony/src/NodeAnalyzer/SymfonyTestCaseAnalyzer.php',
'Rector\\Symfony\\NodeFactory\\Annotations\\DoctrineAnnotationFromNewFactory' => $vendorDir . '/rector/rector-symfony/src/NodeFactory/Annotations/DoctrineAnnotationFromNewFactory.php',
'Rector\\Symfony\\NodeFactory\\Annotations\\DoctrineAnnotationKeyToValuesResolver' => $vendorDir . '/rector/rector-symfony/src/NodeFactory/Annotations/DoctrineAnnotationKeyToValuesResolver.php',
'Rector\\Symfony\\NodeFactory\\ArrayFromCompactFactory' => $vendorDir . '/rector/rector-symfony/src/NodeFactory/ArrayFromCompactFactory.php',
@ -2963,12 +2964,14 @@ return array(
'Rector\\Symfony\\Rector\\MethodCall\\ReadOnlyOptionToAttributeRector' => $vendorDir . '/rector/rector-symfony/src/Rector/MethodCall/ReadOnlyOptionToAttributeRector.php',
'Rector\\Symfony\\Rector\\MethodCall\\RedirectToRouteRector' => $vendorDir . '/rector/rector-symfony/src/Rector/MethodCall/RedirectToRouteRector.php',
'Rector\\Symfony\\Rector\\MethodCall\\ReflectionExtractorEnableMagicCallExtractorRector' => $vendorDir . '/rector/rector-symfony/src/Rector/MethodCall/ReflectionExtractorEnableMagicCallExtractorRector.php',
'Rector\\Symfony\\Rector\\MethodCall\\SimplifyWebTestCaseAssertionsRector' => $vendorDir . '/rector/rector-symfony/src/Rector/MethodCall/SimplifyWebTestCaseAssertionsRector.php',
'Rector\\Symfony\\Rector\\MethodCall\\StringFormTypeToClassRector' => $vendorDir . '/rector/rector-symfony/src/Rector/MethodCall/StringFormTypeToClassRector.php',
'Rector\\Symfony\\Rector\\MethodCall\\SwiftCreateMessageToNewEmailRector' => $vendorDir . '/rector/rector-symfony/src/Rector/MethodCall/SwiftCreateMessageToNewEmailRector.php',
'Rector\\Symfony\\Rector\\MethodCall\\SwiftSetBodyToHtmlPlainMethodCallRector' => $vendorDir . '/rector/rector-symfony/src/Rector/MethodCall/SwiftSetBodyToHtmlPlainMethodCallRector.php',
'Rector\\Symfony\\Rector\\MethodCall\\ValidatorBuilderEnableAnnotationMappingRector' => $vendorDir . '/rector/rector-symfony/src/Rector/MethodCall/ValidatorBuilderEnableAnnotationMappingRector.php',
'Rector\\Symfony\\Rector\\MethodCall\\VarDumperTestTraitMethodArgsRector' => $vendorDir . '/rector/rector-symfony/src/Rector/MethodCall/VarDumperTestTraitMethodArgsRector.php',
'Rector\\Symfony\\Rector\\MethodCall\\WebTestCaseAssertIsSuccessfulRector' => $vendorDir . '/rector/rector-symfony/src/Rector/MethodCall/WebTestCaseAssertIsSuccessfulRector.php',
'Rector\\Symfony\\Rector\\MethodCall\\WebTestCaseAssertResponseCodeRector' => $vendorDir . '/rector/rector-symfony/src/Rector/MethodCall/WebTestCaseAssertResponseCodeRector.php',
'Rector\\Symfony\\Rector\\MethodCall\\WebTestCaseAssertSelectorTextContainsRector' => $vendorDir . '/rector/rector-symfony/src/Rector/MethodCall/WebTestCaseAssertSelectorTextContainsRector.php',
'Rector\\Symfony\\Rector\\New_\\PropertyAccessorCreationBooleanToFlagsRector' => $vendorDir . '/rector/rector-symfony/src/Rector/New_/PropertyAccessorCreationBooleanToFlagsRector.php',
'Rector\\Symfony\\Rector\\New_\\PropertyPathMapperToDataMapperRector' => $vendorDir . '/rector/rector-symfony/src/Rector/New_/PropertyPathMapperToDataMapperRector.php',
'Rector\\Symfony\\Rector\\New_\\RootNodeTreeBuilderRector' => $vendorDir . '/rector/rector-symfony/src/Rector/New_/RootNodeTreeBuilderRector.php',

View File

@ -2,7 +2,7 @@
// autoload_real.php @generated by Composer
class ComposerAutoloaderInit388c70bb548765b1670bb03171cf794b
class ComposerAutoloaderInit19fcad7dd58e192ff8d5197742f295d9
{
private static $loader;
@ -22,19 +22,19 @@ class ComposerAutoloaderInit388c70bb548765b1670bb03171cf794b
return self::$loader;
}
spl_autoload_register(array('ComposerAutoloaderInit388c70bb548765b1670bb03171cf794b', 'loadClassLoader'), true, true);
spl_autoload_register(array('ComposerAutoloaderInit19fcad7dd58e192ff8d5197742f295d9', 'loadClassLoader'), true, true);
self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__));
spl_autoload_unregister(array('ComposerAutoloaderInit388c70bb548765b1670bb03171cf794b', 'loadClassLoader'));
spl_autoload_unregister(array('ComposerAutoloaderInit19fcad7dd58e192ff8d5197742f295d9', 'loadClassLoader'));
require __DIR__ . '/autoload_static.php';
call_user_func(\Composer\Autoload\ComposerStaticInit388c70bb548765b1670bb03171cf794b::getInitializer($loader));
call_user_func(\Composer\Autoload\ComposerStaticInit19fcad7dd58e192ff8d5197742f295d9::getInitializer($loader));
$loader->setClassMapAuthoritative(true);
$loader->register(true);
$includeFiles = \Composer\Autoload\ComposerStaticInit388c70bb548765b1670bb03171cf794b::$files;
$includeFiles = \Composer\Autoload\ComposerStaticInit19fcad7dd58e192ff8d5197742f295d9::$files;
foreach ($includeFiles as $fileIdentifier => $file) {
composerRequire388c70bb548765b1670bb03171cf794b($fileIdentifier, $file);
composerRequire19fcad7dd58e192ff8d5197742f295d9($fileIdentifier, $file);
}
return $loader;
@ -46,7 +46,7 @@ class ComposerAutoloaderInit388c70bb548765b1670bb03171cf794b
* @param string $file
* @return void
*/
function composerRequire388c70bb548765b1670bb03171cf794b($fileIdentifier, $file)
function composerRequire19fcad7dd58e192ff8d5197742f295d9($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 ComposerStaticInit388c70bb548765b1670bb03171cf794b
class ComposerStaticInit19fcad7dd58e192ff8d5197742f295d9
{
public static $files = array (
'320cde22f66dd4f5d3fd621d3e88b98f' => __DIR__ . '/..' . '/symfony/polyfill-ctype/bootstrap.php',
@ -3274,6 +3274,7 @@ class ComposerStaticInit388c70bb548765b1670bb03171cf794b
'Rector\\Symfony\\NodeAnalyzer\\RouteRequiredParamNameToTypesResolver' => __DIR__ . '/..' . '/rector/rector-symfony/src/NodeAnalyzer/RouteRequiredParamNameToTypesResolver.php',
'Rector\\Symfony\\NodeAnalyzer\\ServiceTypeMethodCallResolver' => __DIR__ . '/..' . '/rector/rector-symfony/src/NodeAnalyzer/ServiceTypeMethodCallResolver.php',
'Rector\\Symfony\\NodeAnalyzer\\SymfonyControllerFilter' => __DIR__ . '/..' . '/rector/rector-symfony/src/NodeAnalyzer/SymfonyControllerFilter.php',
'Rector\\Symfony\\NodeAnalyzer\\SymfonyTestCaseAnalyzer' => __DIR__ . '/..' . '/rector/rector-symfony/src/NodeAnalyzer/SymfonyTestCaseAnalyzer.php',
'Rector\\Symfony\\NodeFactory\\Annotations\\DoctrineAnnotationFromNewFactory' => __DIR__ . '/..' . '/rector/rector-symfony/src/NodeFactory/Annotations/DoctrineAnnotationFromNewFactory.php',
'Rector\\Symfony\\NodeFactory\\Annotations\\DoctrineAnnotationKeyToValuesResolver' => __DIR__ . '/..' . '/rector/rector-symfony/src/NodeFactory/Annotations/DoctrineAnnotationKeyToValuesResolver.php',
'Rector\\Symfony\\NodeFactory\\ArrayFromCompactFactory' => __DIR__ . '/..' . '/rector/rector-symfony/src/NodeFactory/ArrayFromCompactFactory.php',
@ -3332,12 +3333,14 @@ class ComposerStaticInit388c70bb548765b1670bb03171cf794b
'Rector\\Symfony\\Rector\\MethodCall\\ReadOnlyOptionToAttributeRector' => __DIR__ . '/..' . '/rector/rector-symfony/src/Rector/MethodCall/ReadOnlyOptionToAttributeRector.php',
'Rector\\Symfony\\Rector\\MethodCall\\RedirectToRouteRector' => __DIR__ . '/..' . '/rector/rector-symfony/src/Rector/MethodCall/RedirectToRouteRector.php',
'Rector\\Symfony\\Rector\\MethodCall\\ReflectionExtractorEnableMagicCallExtractorRector' => __DIR__ . '/..' . '/rector/rector-symfony/src/Rector/MethodCall/ReflectionExtractorEnableMagicCallExtractorRector.php',
'Rector\\Symfony\\Rector\\MethodCall\\SimplifyWebTestCaseAssertionsRector' => __DIR__ . '/..' . '/rector/rector-symfony/src/Rector/MethodCall/SimplifyWebTestCaseAssertionsRector.php',
'Rector\\Symfony\\Rector\\MethodCall\\StringFormTypeToClassRector' => __DIR__ . '/..' . '/rector/rector-symfony/src/Rector/MethodCall/StringFormTypeToClassRector.php',
'Rector\\Symfony\\Rector\\MethodCall\\SwiftCreateMessageToNewEmailRector' => __DIR__ . '/..' . '/rector/rector-symfony/src/Rector/MethodCall/SwiftCreateMessageToNewEmailRector.php',
'Rector\\Symfony\\Rector\\MethodCall\\SwiftSetBodyToHtmlPlainMethodCallRector' => __DIR__ . '/..' . '/rector/rector-symfony/src/Rector/MethodCall/SwiftSetBodyToHtmlPlainMethodCallRector.php',
'Rector\\Symfony\\Rector\\MethodCall\\ValidatorBuilderEnableAnnotationMappingRector' => __DIR__ . '/..' . '/rector/rector-symfony/src/Rector/MethodCall/ValidatorBuilderEnableAnnotationMappingRector.php',
'Rector\\Symfony\\Rector\\MethodCall\\VarDumperTestTraitMethodArgsRector' => __DIR__ . '/..' . '/rector/rector-symfony/src/Rector/MethodCall/VarDumperTestTraitMethodArgsRector.php',
'Rector\\Symfony\\Rector\\MethodCall\\WebTestCaseAssertIsSuccessfulRector' => __DIR__ . '/..' . '/rector/rector-symfony/src/Rector/MethodCall/WebTestCaseAssertIsSuccessfulRector.php',
'Rector\\Symfony\\Rector\\MethodCall\\WebTestCaseAssertResponseCodeRector' => __DIR__ . '/..' . '/rector/rector-symfony/src/Rector/MethodCall/WebTestCaseAssertResponseCodeRector.php',
'Rector\\Symfony\\Rector\\MethodCall\\WebTestCaseAssertSelectorTextContainsRector' => __DIR__ . '/..' . '/rector/rector-symfony/src/Rector/MethodCall/WebTestCaseAssertSelectorTextContainsRector.php',
'Rector\\Symfony\\Rector\\New_\\PropertyAccessorCreationBooleanToFlagsRector' => __DIR__ . '/..' . '/rector/rector-symfony/src/Rector/New_/PropertyAccessorCreationBooleanToFlagsRector.php',
'Rector\\Symfony\\Rector\\New_\\PropertyPathMapperToDataMapperRector' => __DIR__ . '/..' . '/rector/rector-symfony/src/Rector/New_/PropertyPathMapperToDataMapperRector.php',
'Rector\\Symfony\\Rector\\New_\\RootNodeTreeBuilderRector' => __DIR__ . '/..' . '/rector/rector-symfony/src/Rector/New_/RootNodeTreeBuilderRector.php',
@ -3867,9 +3870,9 @@ class ComposerStaticInit388c70bb548765b1670bb03171cf794b
public static function getInitializer(ClassLoader $loader)
{
return \Closure::bind(function () use ($loader) {
$loader->prefixLengthsPsr4 = ComposerStaticInit388c70bb548765b1670bb03171cf794b::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInit388c70bb548765b1670bb03171cf794b::$prefixDirsPsr4;
$loader->classMap = ComposerStaticInit388c70bb548765b1670bb03171cf794b::$classMap;
$loader->prefixLengthsPsr4 = ComposerStaticInit19fcad7dd58e192ff8d5197742f295d9::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInit19fcad7dd58e192ff8d5197742f295d9::$prefixDirsPsr4;
$loader->classMap = ComposerStaticInit19fcad7dd58e192ff8d5197742f295d9::$classMap;
}, null, ClassLoader::class);
}

View File

@ -2415,12 +2415,12 @@
"source": {
"type": "git",
"url": "https:\/\/github.com\/rectorphp\/rector-nette.git",
"reference": "0b5a94c5611aa3130b6dc0cce4028f7ad0184923"
"reference": "3a6ed85d0f99efed313152341a43625988320a02"
},
"dist": {
"type": "zip",
"url": "https:\/\/api.github.com\/repos\/rectorphp\/rector-nette\/zipball\/0b5a94c5611aa3130b6dc0cce4028f7ad0184923",
"reference": "0b5a94c5611aa3130b6dc0cce4028f7ad0184923",
"url": "https:\/\/api.github.com\/repos\/rectorphp\/rector-nette\/zipball\/3a6ed85d0f99efed313152341a43625988320a02",
"reference": "3a6ed85d0f99efed313152341a43625988320a02",
"shasum": ""
},
"require": {
@ -2452,7 +2452,7 @@
"symplify\/rule-doc-generator": "^10.2",
"symplify\/vendor-patches": "^10.2"
},
"time": "2022-04-20T19:02:05+00:00",
"time": "2022-04-24T16:13:34+00:00",
"default-branch": true,
"type": "rector-extension",
"extra": {
@ -2481,7 +2481,7 @@
],
"description": "Rector upgrades rules for Nette Framework",
"support": {
"source": "https:\/\/github.com\/rectorphp\/rector-nette\/tree\/0.11.58"
"source": "https:\/\/github.com\/rectorphp\/rector-nette\/tree\/main"
},
"install-path": "..\/rector\/rector-nette"
},
@ -2627,12 +2627,12 @@
"source": {
"type": "git",
"url": "https:\/\/github.com\/rectorphp\/rector-symfony.git",
"reference": "9694784aefad71ab3336fdec06045627aeb25b87"
"reference": "00b95515f1a06ba7e2910fca81d2dbf18522820f"
},
"dist": {
"type": "zip",
"url": "https:\/\/api.github.com\/repos\/rectorphp\/rector-symfony\/zipball\/9694784aefad71ab3336fdec06045627aeb25b87",
"reference": "9694784aefad71ab3336fdec06045627aeb25b87",
"url": "https:\/\/api.github.com\/repos\/rectorphp\/rector-symfony\/zipball\/00b95515f1a06ba7e2910fca81d2dbf18522820f",
"reference": "00b95515f1a06ba7e2910fca81d2dbf18522820f",
"shasum": ""
},
"require": {
@ -2650,7 +2650,7 @@
"phpstan\/phpstan-webmozart-assert": "^1.0",
"phpunit\/phpunit": "^9.5",
"rector\/phpstan-rules": "^0.4.4",
"rector\/rector-src": "dev-main",
"rector\/rector-src": "dev-main#9c97822",
"symfony\/security-core": "^5.4",
"symfony\/security-http": "^5.4",
"symplify\/easy-coding-standard": "^10.0",
@ -2660,7 +2660,7 @@
"symplify\/rule-doc-generator": "^10.0",
"symplify\/vendor-patches": "^10.0"
},
"time": "2022-04-23T12:07:09+00:00",
"time": "2022-04-24T15:55:08+00:00",
"default-branch": true,
"type": "rector-extension",
"extra": {

File diff suppressed because one or more lines are too long

View File

@ -9,7 +9,7 @@ namespace Rector\RectorInstaller;
*/
final class GeneratedConfig
{
public const EXTENSIONS = array('rector/rector-cakephp' => array('install_path' => '/home/runner/work/rector-src/rector-src/vendor/rector/rector-cakephp', 'relative_install_path' => '../../rector-cakephp', 'extra' => array('includes' => array(0 => 'config/config.php')), 'version' => 'dev-main dc4fbb8'), '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 3f5c267'), 'rector/rector-generator' => array('install_path' => '/home/runner/work/rector-src/rector-src/vendor/rector/rector-generator', 'relative_install_path' => '../../rector-generator', 'extra' => array('includes' => array(0 => 'config/config.php')), 'version' => 'dev-main 5d945fb'), 'rector/rector-laravel' => array('install_path' => '/home/runner/work/rector-src/rector-src/vendor/rector/rector-laravel', 'relative_install_path' => '../../rector-laravel', 'extra' => array('includes' => array(0 => 'config/config.php')), 'version' => 'dev-main b794171'), 'rector/rector-nette' => array('install_path' => '/home/runner/work/rector-src/rector-src/vendor/rector/rector-nette', 'relative_install_path' => '../../rector-nette', 'extra' => array('includes' => array(0 => 'config/config.php')), 'version' => 'dev-main 0b5a94c'), 'rector/rector-phpoffice' => array('install_path' => '/home/runner/work/rector-src/rector-src/vendor/rector/rector-phpoffice', 'relative_install_path' => '../../rector-phpoffice', 'extra' => array('includes' => array(0 => 'config/config.php')), 'version' => 'dev-main 01fa90c'), '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 a9d0d93'), '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 9694784'), 'ssch/typo3-rector' => array('install_path' => '/home/runner/work/rector-src/rector-src/vendor/ssch/typo3-rector', 'relative_install_path' => '../../../ssch/typo3-rector', 'extra' => array('includes' => array(0 => 'config/config.php')), 'version' => 'dev-main ca364be'));
public const EXTENSIONS = array('rector/rector-cakephp' => array('install_path' => '/home/runner/work/rector-src/rector-src/vendor/rector/rector-cakephp', 'relative_install_path' => '../../rector-cakephp', 'extra' => array('includes' => array(0 => 'config/config.php')), 'version' => 'dev-main dc4fbb8'), '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 3f5c267'), 'rector/rector-generator' => array('install_path' => '/home/runner/work/rector-src/rector-src/vendor/rector/rector-generator', 'relative_install_path' => '../../rector-generator', 'extra' => array('includes' => array(0 => 'config/config.php')), 'version' => 'dev-main 5d945fb'), 'rector/rector-laravel' => array('install_path' => '/home/runner/work/rector-src/rector-src/vendor/rector/rector-laravel', 'relative_install_path' => '../../rector-laravel', 'extra' => array('includes' => array(0 => 'config/config.php')), 'version' => 'dev-main b794171'), 'rector/rector-nette' => array('install_path' => '/home/runner/work/rector-src/rector-src/vendor/rector/rector-nette', 'relative_install_path' => '../../rector-nette', 'extra' => array('includes' => array(0 => 'config/config.php')), 'version' => 'dev-main 3a6ed85'), 'rector/rector-phpoffice' => array('install_path' => '/home/runner/work/rector-src/rector-src/vendor/rector/rector-phpoffice', 'relative_install_path' => '../../rector-phpoffice', 'extra' => array('includes' => array(0 => 'config/config.php')), 'version' => 'dev-main 01fa90c'), '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 a9d0d93'), '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 00b9551'), 'ssch/typo3-rector' => array('install_path' => '/home/runner/work/rector-src/rector-src/vendor/ssch/typo3-rector', 'relative_install_path' => '../../../ssch/typo3-rector', 'extra' => array('includes' => array(0 => 'config/config.php')), 'version' => 'dev-main ca364be'));
private function __construct()
{
}

View File

@ -9,6 +9,7 @@ use Rector\Set\ValueObject\LevelSetList;
use Rector\Set\ValueObject\SetList;
return static function (\Rector\Config\RectorConfig $rectorConfig) : void {
$rectorConfig->importNames();
$rectorConfig->parallel();
$rectorConfig->paths([__DIR__ . '/src', __DIR__ . '/tests']);
$rectorConfig->skip([
// for tests

View File

@ -4,16 +4,12 @@ declare (strict_types=1);
namespace Rector\Nette\NodeAnalyzer;
use PhpParser\Node;
use PhpParser\Node\Expr\Assign;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Expr\Variable;
use PhpParser\Node\FunctionLike;
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Expression;
use Rector\Core\PhpParser\Node\BetterNodeFinder;
use Rector\Defluent\NodeAnalyzer\FluentChainMethodCallNodeAnalyzer;
use Rector\NodeNameResolver\NodeNameResolver;
use Rector\NodeTypeResolver\Node\AttributeKey;
final class MethodCallManipulator
{
/**
@ -37,61 +33,6 @@ final class MethodCallManipulator
$this->nodeNameResolver = $nodeNameResolver;
$this->fluentChainMethodCallNodeAnalyzer = $fluentChainMethodCallNodeAnalyzer;
}
/**
* @return string[]
*/
public function findMethodCallNamesOnVariable(\PhpParser\Node\Expr\Variable $variable) : array
{
$methodCallsOnVariable = $this->findMethodCallsOnVariable($variable);
$methodCallNamesOnVariable = [];
foreach ($methodCallsOnVariable as $methodCallOnVariable) {
$methodName = $this->nodeNameResolver->getName($methodCallOnVariable->name);
if ($methodName === null) {
continue;
}
$methodCallNamesOnVariable[] = $methodName;
}
return \array_unique($methodCallNamesOnVariable);
}
/**
* @return MethodCall[]
*/
public function findMethodCallsIncludingChain(\PhpParser\Node\Expr\MethodCall $methodCall) : array
{
$chainMethodCalls = [];
// 1. collect method chain call
$currentMethodCallee = $methodCall->var;
while ($currentMethodCallee instanceof \PhpParser\Node\Expr\MethodCall) {
$chainMethodCalls[] = $currentMethodCallee;
$currentMethodCallee = $currentMethodCallee->var;
}
// 2. collect on-same-variable calls
$onVariableMethodCalls = [];
if ($currentMethodCallee instanceof \PhpParser\Node\Expr\Variable) {
$onVariableMethodCalls = $this->findMethodCallsOnVariable($currentMethodCallee);
}
$methodCalls = \array_merge($chainMethodCalls, $onVariableMethodCalls);
return $this->uniquateObjects($methodCalls);
}
public function findAssignToVariable(\PhpParser\Node\Expr\Variable $variable) : ?\PhpParser\Node\Expr\Assign
{
$parentNode = $variable->getAttribute(\Rector\NodeTypeResolver\Node\AttributeKey::PARENT_NODE);
if (!$parentNode instanceof \PhpParser\Node) {
return null;
}
$variableName = $this->nodeNameResolver->getName($variable);
if ($variableName === null) {
return null;
}
do {
$assign = $this->findAssignToVariableName($parentNode, $variableName);
if ($assign instanceof \PhpParser\Node\Expr\Assign) {
return $assign;
}
$parentNode = $this->resolvePreviousNodeInSameScope($parentNode);
} while ($parentNode instanceof \PhpParser\Node && !$parentNode instanceof \PhpParser\Node\FunctionLike);
return null;
}
/**
* @return MethodCall[]
*/
@ -117,53 +58,4 @@ final class MethodCallManipulator
return $this->nodeNameResolver->isName($callerNode, $variableName);
});
}
/**
* @see https://stackoverflow.com/a/4507991/1348344
* @param object[] $objects
* @return object[]
*
* @template T
* @phpstan-param array<T>|T[] $objects
* @phpstan-return array<T>|T[]
*/
private function uniquateObjects(array $objects) : array
{
$uniqueObjects = [];
foreach ($objects as $object) {
if (\in_array($object, $uniqueObjects, \true)) {
continue;
}
$uniqueObjects[] = $object;
}
// re-index
return \array_values($uniqueObjects);
}
private function findAssignToVariableName(\PhpParser\Node $node, string $variableName) : ?\PhpParser\Node
{
/** @var Assign[] $assigns */
$assigns = $this->betterNodeFinder->findInstanceOf($node, \PhpParser\Node\Expr\Assign::class);
foreach ($assigns as $assign) {
if (!$assign->var instanceof \PhpParser\Node\Expr\Variable) {
continue;
}
if (!$this->nodeNameResolver->isName($assign->var, $variableName)) {
continue;
}
return $assign;
}
return null;
}
private function resolvePreviousNodeInSameScope(\PhpParser\Node $parentNode) : ?\PhpParser\Node
{
$previousParentNode = $parentNode;
$parentNode = $parentNode->getAttribute(\Rector\NodeTypeResolver\Node\AttributeKey::PARENT_NODE);
if (!$parentNode instanceof \PhpParser\Node\FunctionLike) {
// is about to leave → try previous expression
$previousStatement = $previousParentNode->getAttribute(\Rector\NodeTypeResolver\Node\AttributeKey::PREVIOUS_STATEMENT);
if ($previousStatement instanceof \PhpParser\Node\Stmt\Expression) {
return $previousStatement->expr;
}
}
return $parentNode;
}
}

View File

@ -84,7 +84,7 @@ CODE_SAMPLE
return null;
}
$checkRequirementsClassMethod = $node->getMethod('checkRequirements');
if ($checkRequirementsClassMethod === null) {
if (!$checkRequirementsClassMethod instanceof \PhpParser\Node\Stmt\ClassMethod) {
$checkRequirementsClassMethod = $this->checkRequirementsClassMethodFactory->create((array) $getUserClassMethod->stmts);
$this->classInsertManipulator->addAsFirstMethod($node, $checkRequirementsClassMethod);
} else {

View File

@ -11,7 +11,7 @@
"require-dev": {
"phpunit\/phpunit": "^9.5",
"phpstan\/phpstan": "^1.3",
"rector\/rector-src": "dev-main",
"rector\/rector-src": "dev-main#9c97822",
"symplify\/phpstan-rules": "^10.0",
"symfony\/security-core": "^5.4",
"symfony\/security-http": "^5.4",
@ -45,7 +45,7 @@
"check-cs": "vendor\/bin\/ecs check --ansi",
"fix-cs": "vendor\/bin\/ecs check --fix --ansi",
"docs": [
"vendor\/bin\/rule-doc-generator generate src --output-file docs\/rector_rules_overview.md --ansi --configure-method",
"vendor\/bin\/rule-doc-generator generate src --output-file docs\/rector_rules_overview.md --ansi",
"vendor\/bin\/ecs check-markdown docs\/rector_rules_overview.md --ansi --fix"
]
},

View File

@ -10,6 +10,6 @@ return static function (\Rector\Config\RectorConfig $rectorConfig) : void {
$services = $rectorConfig->services();
$services->defaults()->public()->autowire()->autoconfigure();
$services->load('Rector\\Symfony\\', __DIR__ . '/../src')->exclude([__DIR__ . '/../src/{Rector,ValueObject}']);
$services->set(\Rector\Core\NonPhpFile\Rector\RenameClassNonPhpRector::class);
$rectorConfig->rule(\Rector\Core\NonPhpFile\Rector\RenameClassNonPhpRector::class);
$services->set(\RectorPrefix20220424\Symplify\SmartFileSystem\SmartFileSystem::class);
};

View File

@ -12,11 +12,11 @@ use Rector\Renaming\Rector\MethodCall\RenameMethodRector;
use Rector\Renaming\Rector\Name\RenameClassRector;
use Rector\Renaming\ValueObject\MethodCallRename;
use Rector\Symfony\Rector\MethodCall\MakeDispatchFirstArgumentEventRector;
use Rector\Symfony\Rector\MethodCall\SimplifyWebTestCaseAssertionsRector;
use Rector\Symfony\Rector\MethodCall\WebTestCaseAssertResponseCodeRector;
# https://github.com/symfony/symfony/blob/4.4/UPGRADE-4.3.md
return static function (\Rector\Config\RectorConfig $rectorConfig) : void {
# https://symfony.com/blog/new-in-symfony-4-3-better-test-assertions
$rectorConfig->rule(\Rector\Symfony\Rector\MethodCall\SimplifyWebTestCaseAssertionsRector::class);
$rectorConfig->rule(\Rector\Symfony\Rector\MethodCall\WebTestCaseAssertResponseCodeRector::class);
$rectorConfig->ruleWithConfiguration(\Rector\Renaming\Rector\MethodCall\RenameMethodRector::class, [
new \Rector\Renaming\ValueObject\MethodCallRename('Symfony\\Component\\BrowserKit\\Response', 'getStatus', 'getStatusCode'),
new \Rector\Renaming\ValueObject\MethodCallRename('Symfony\\Component\\Security\\Http\\Firewall', 'handleRequest', 'callListeners'),

View File

@ -1,4 +1,4 @@
# 60 Rules Overview
# 62 Rules Overview
## ActionSuffixRemoverRector
@ -144,17 +144,11 @@ Change XML loader to YAML in Bundle Extension
- class: [`Rector\Symfony\Rector\Class_\ChangeFileLoaderInExtensionAndKernelRector`](../src/Rector/Class_/ChangeFileLoaderInExtensionAndKernelRector.php)
```php
use Rector\Config\RectorConfig;
use Rector\Symfony\Rector\Class_\ChangeFileLoaderInExtensionAndKernelRector;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
return static function (ContainerConfigurator $containerConfigurator): void {
$services = $containerConfigurator->services();
$services->set(ChangeFileLoaderInExtensionAndKernelRector::class)
->configure([
ChangeFileLoaderInExtensionAndKernelRector::FROM => 'xml',
ChangeFileLoaderInExtensionAndKernelRector::TO => 'yaml',
]);
return static function (RectorConfig $rectorConfig): void {
$rectorConfig->ruleWithConfiguration(ChangeFileLoaderInExtensionAndKernelRector::class, [Rector\Symfony\Rector\Class_\ChangeFileLoaderInExtensionAndKernelRector::FROM: 'xml', Rector\Symfony\Rector\Class_\ChangeFileLoaderInExtensionAndKernelRector::TO: 'yaml']);
};
```
@ -870,13 +864,15 @@ Complete strict param type declaration based on route annotation
## ParseFileRector
session > use_strict_mode is true by default and can be removed
Replaces deprecated `Yaml::parse()` of file argument with file contents
- class: [`Rector\Symfony\Rector\StaticCall\ParseFileRector`](../src/Rector/StaticCall/ParseFileRector.php)
```diff
-session > use_strict_mode: true
+session:
use Symfony\Component\Yaml\Yaml;
-$parsedFile = Yaml::parse('someFile.yml');
+$parsedFile = Yaml::parse(file_get_contents('someFile.yml'));
```
<br>
@ -1106,15 +1102,15 @@ Replace defined `service()` argument in Symfony PHP config
```php
use PhpParser\Node\Scalar\String_;
use Rector\Config\RectorConfig;
use Rector\Symfony\Rector\FuncCall\ReplaceServiceArgumentRector;
use Rector\Symfony\ValueObject\ReplaceServiceArgument;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
return static function (ContainerConfigurator $containerConfigurator): void {
$services = $containerConfigurator->services();
$services->set(ReplaceServiceArgumentRector::class)
->configure([new ReplaceServiceArgument('ContainerInterface', new String_('service_container', []))]);
return static function (RectorConfig $rectorConfig): void {
$rectorConfig->ruleWithConfiguration(
ReplaceServiceArgumentRector::class,
[new ReplaceServiceArgument('ContainerInterface', new String_('service_container', []))]
);
};
```
@ -1255,43 +1251,9 @@ Changes Twig_Function_Method to Twig_SimpleFunction calls in Twig_Extension.
<br>
## SimplifyWebTestCaseAssertionsRector
Simplify use of assertions in WebTestCase
- class: [`Rector\Symfony\Rector\MethodCall\SimplifyWebTestCaseAssertionsRector`](../src/Rector/MethodCall/SimplifyWebTestCaseAssertionsRector.php)
```diff
use PHPUnit\Framework\TestCase;
class SomeClass extends TestCase
{
public function test()
{
- $this->assertSame(200, $client->getResponse()->getStatusCode());
+ $this->assertResponseIsSuccessful();
}
public function testUrl()
{
- $this->assertSame(301, $client->getResponse()->getStatusCode());
- $this->assertSame('https://example.com', $client->getResponse()->headers->get('Location'));
+ $this->assertResponseRedirects('https://example.com', 301);
}
public function testContains()
{
- $this->assertContains('Hello World', $crawler->filter('h1')->text());
+ $this->assertSelectorTextContains('h1', 'Hello World');
}
}
```
<br>
## StringFormTypeToClassRector
Turns string Form Type references to their CONSTANT alternatives in FormTypes in Form in Symfony. To enable custom types, add link to your container XML dump in "$parameters->set(Option::SYMFONY_CONTAINER_XML_PATH_PARAMETER, ...);"
Turns string Form Type references to their CONSTANT alternatives in FormTypes in Form in Symfony. To enable custom types, add link to your container XML dump in "$rectorConfig->symfonyContainerXml(...)"
- class: [`Rector\Symfony\Rector\MethodCall\StringFormTypeToClassRector`](../src/Rector/MethodCall/StringFormTypeToClassRector.php)
@ -1409,3 +1371,72 @@ Adds a new `$filter` argument in `VarDumperTestTrait->assertDumpEquals()` and `V
```
<br>
## WebTestCaseAssertIsSuccessfulRector
Simplify use of assertions in WebTestCase
- class: [`Rector\Symfony\Rector\MethodCall\WebTestCaseAssertIsSuccessfulRector`](../src/Rector/MethodCall/WebTestCaseAssertIsSuccessfulRector.php)
```diff
use PHPUnit\Framework\TestCase;
class SomeClass extends TestCase
{
public function test()
{
- $this->assertSame(200, $this->client->getResponse()->getStatusCode());
+ $this->assertResponseIsSuccessful();
}
}
```
<br>
## WebTestCaseAssertResponseCodeRector
Simplify use of assertions in WebTestCase
- class: [`Rector\Symfony\Rector\MethodCall\WebTestCaseAssertResponseCodeRector`](../src/Rector/MethodCall/WebTestCaseAssertResponseCodeRector.php)
```diff
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
final class SomeClass extends WebTestCase
{
public function test()
{
- $response = self::getClient()->getResponse();
-
- $this->assertSame(301, $response->getStatusCode());
- $this->assertSame('https://example.com', $response->headers->get('Location'));
+ $this->assertResponseStatusCodeSame(301);
+ $this->assertResponseRedirects('https://example.com');
}
}
```
<br>
## WebTestCaseAssertSelectorTextContainsRector
Simplify use of assertions in WebTestCase to `assertSelectorTextContains()`
- class: [`Rector\Symfony\Rector\MethodCall\WebTestCaseAssertSelectorTextContainsRector`](../src/Rector/MethodCall/WebTestCaseAssertSelectorTextContainsRector.php)
```diff
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
use Symfony\Component\DomCrawler\Crawler;
final class SomeTest extends WebTestCase
{
public function testContains()
{
$crawler = new Symfony\Component\DomCrawler\Crawler();
- $this->assertContains('Hello World', $crawler->filter('h1')->text());
+ $this->assertSelectorTextContains('h1', 'Hello World');
}
}
```
<br>

View File

@ -0,0 +1,24 @@
<?php
declare (strict_types=1);
namespace Rector\Symfony\NodeAnalyzer;
use PhpParser\Node;
use PHPStan\Analyser\Scope;
use PHPStan\Reflection\ClassReflection;
use Rector\NodeTypeResolver\Node\AttributeKey;
final class SymfonyTestCaseAnalyzer
{
public function isInWebTestCase(\PhpParser\Node $node) : bool
{
$scope = $node->getAttribute(\Rector\NodeTypeResolver\Node\AttributeKey::SCOPE);
if (!$scope instanceof \PHPStan\Analyser\Scope) {
return \false;
}
$classReflection = $scope->getClassReflection();
if (!$classReflection instanceof \PHPStan\Reflection\ClassReflection) {
return \false;
}
return $classReflection->isSubclassOf('Symfony\\Bundle\\FrameworkBundle\\Test\\WebTestCase');
}
}

View File

@ -1,234 +0,0 @@
<?php
declare (strict_types=1);
namespace Rector\Symfony\Rector\MethodCall;
use PhpParser\Node;
use PhpParser\Node\Arg;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Expr\PropertyFetch;
use PhpParser\Node\Expr\Variable;
use PhpParser\Node\Scalar\LNumber;
use PhpParser\Node\Scalar\String_;
use PhpParser\Node\Stmt\Expression;
use PHPStan\Analyser\Scope;
use PHPStan\Reflection\ClassReflection;
use Rector\Core\Exception\ShouldNotHappenException;
use Rector\Core\Rector\AbstractRector;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* @see https://symfony.com/blog/new-in-symfony-4-3-better-test-assertions
* @see https://github.com/symfony/symfony/pull/30813/files
*
* @see \Rector\Symfony\Tests\Rector\MethodCall\SimplifyWebTestCaseAssertionsRector\SimplifyWebTestCaseAssertionsRectorTest
*/
final class SimplifyWebTestCaseAssertionsRector extends \Rector\Core\Rector\AbstractRector
{
/**
* @var string
*/
private const ASSERT_SAME = 'assertSame';
/**
* @var \PhpParser\Node\Expr\MethodCall|null
*/
private $getStatusCodeMethodCall;
public function getRuleDefinition() : \Symplify\RuleDocGenerator\ValueObject\RuleDefinition
{
return new \Symplify\RuleDocGenerator\ValueObject\RuleDefinition('Simplify use of assertions in WebTestCase', [new \Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample(<<<'CODE_SAMPLE'
use PHPUnit\Framework\TestCase;
class SomeClass extends TestCase
{
public function test()
{
$this->assertSame(200, $client->getResponse()->getStatusCode());
}
public function testUrl()
{
$this->assertSame(301, $client->getResponse()->getStatusCode());
$this->assertSame('https://example.com', $client->getResponse()->headers->get('Location'));
}
public function testContains()
{
$this->assertContains('Hello World', $crawler->filter('h1')->text());
}
}
CODE_SAMPLE
, <<<'CODE_SAMPLE'
use PHPUnit\Framework\TestCase;
class SomeClass extends TestCase
{
public function test()
{
$this->assertResponseIsSuccessful();
}
public function testUrl()
{
$this->assertResponseRedirects('https://example.com', 301);
}
public function testContains()
{
$this->assertSelectorTextContains('h1', 'Hello World');
}
}
CODE_SAMPLE
)]);
}
/**
* @return array<class-string<Node>>
*/
public function getNodeTypes() : array
{
return [\PhpParser\Node\Expr\MethodCall::class];
}
/**
* @param MethodCall $node
*/
public function refactor(\PhpParser\Node $node) : ?\PhpParser\Node
{
if (!$this->isInWebTestCase($node)) {
return null;
}
$clientGetResponseMethodCall = $this->nodeFactory->createMethodCall('client', 'getResponse');
$this->getStatusCodeMethodCall = $this->nodeFactory->createMethodCall($clientGetResponseMethodCall, 'getStatusCode');
// assertResponseIsSuccessful
$args = [];
$args[] = new \PhpParser\Node\Arg(new \PhpParser\Node\Scalar\LNumber(200));
$args[] = new \PhpParser\Node\Arg($this->getGetStatusCodeMethodCall());
$methodCall = $this->nodeFactory->createLocalMethodCall(self::ASSERT_SAME, $args);
if ($this->nodeComparator->areNodesEqual($node, $methodCall)) {
return $this->nodeFactory->createLocalMethodCall('assertResponseIsSuccessful');
}
// assertResponseStatusCodeSame
$newNode = $this->processAssertResponseStatusCodeSame($node);
if ($newNode !== null) {
return $newNode;
}
// assertSelectorTextContains
$args = $this->matchAssertContainsCrawlerArg($node);
if ($args !== null) {
return $this->nodeFactory->createLocalMethodCall('assertSelectorTextContains', $args);
}
return $this->processAssertResponseRedirects($node);
}
private function isInWebTestCase(\PhpParser\Node\Expr\MethodCall $methodCall) : bool
{
$scope = $methodCall->getAttribute(\Rector\NodeTypeResolver\Node\AttributeKey::SCOPE);
if (!$scope instanceof \PHPStan\Analyser\Scope) {
return \false;
}
$classReflection = $scope->getClassReflection();
if (!$classReflection instanceof \PHPStan\Reflection\ClassReflection) {
return \false;
}
return $classReflection->isSubclassOf('Symfony\\Bundle\\FrameworkBundle\\Test\\WebTestCase');
}
private function processAssertResponseStatusCodeSame(\PhpParser\Node\Expr\MethodCall $methodCall) : ?\PhpParser\Node\Expr\MethodCall
{
if (!$this->isName($methodCall->name, self::ASSERT_SAME)) {
return null;
}
$secondArg = $methodCall->args[1];
if (!$secondArg instanceof \PhpParser\Node\Arg) {
return null;
}
if (!$this->nodeComparator->areNodesEqual($secondArg->value, $this->getGetStatusCodeMethodCall())) {
return null;
}
$firstArg = $methodCall->args[0];
if (!$firstArg instanceof \PhpParser\Node\Arg) {
return null;
}
$statusCode = $this->valueResolver->getValue($firstArg->value);
// handled by another methods
if (\in_array($statusCode, [200, 301], \true)) {
return null;
}
return $this->nodeFactory->createLocalMethodCall('assertResponseStatusCodeSame', [$methodCall->args[0]]);
}
/**
* @return Arg[]|null
*/
private function matchAssertContainsCrawlerArg(\PhpParser\Node\Expr\MethodCall $methodCall) : ?array
{
if (!$this->isName($methodCall->name, 'assertContains')) {
return null;
}
$secondArg = $methodCall->args[1];
if (!$secondArg instanceof \PhpParser\Node\Arg) {
return null;
}
$comparedNode = $secondArg->value;
if (!$comparedNode instanceof \PhpParser\Node\Expr\MethodCall) {
return null;
}
if (!$comparedNode->var instanceof \PhpParser\Node\Expr\MethodCall) {
return null;
}
$comparedMethodCaller = $comparedNode->var;
if (!$comparedMethodCaller->var instanceof \PhpParser\Node\Expr\Variable) {
return null;
}
if (!$this->isName($comparedMethodCaller->var, 'crawler')) {
return null;
}
if (!$this->isName($comparedNode->name, 'text')) {
return null;
}
$args = [];
$args[] = $comparedNode->var->args[0];
$args[] = $methodCall->args[0];
/** @var Arg[] $args */
return $args;
}
private function processAssertResponseRedirects(\PhpParser\Node\Expr\MethodCall $methodCall) : ?\PhpParser\Node
{
/** @var Expression|null $previousStatement */
$previousStatement = $methodCall->getAttribute(\Rector\NodeTypeResolver\Node\AttributeKey::PREVIOUS_STATEMENT);
if (!$previousStatement instanceof \PhpParser\Node\Stmt\Expression) {
return null;
}
$previousNode = $previousStatement->expr;
if (!$previousNode instanceof \PhpParser\Node\Expr\MethodCall) {
return null;
}
$args = [];
$args[] = new \PhpParser\Node\Arg(new \PhpParser\Node\Scalar\LNumber(301));
$args[] = new \PhpParser\Node\Arg($this->getGetStatusCodeMethodCall());
$match = $this->nodeFactory->createLocalMethodCall(self::ASSERT_SAME, $args);
if ($this->nodeComparator->areNodesEqual($previousNode, $match)) {
$getResponseMethodCall = $this->nodeFactory->createMethodCall('client', 'getResponse');
$propertyFetch = new \PhpParser\Node\Expr\PropertyFetch($getResponseMethodCall, 'headers');
$clientGetLocation = $this->nodeFactory->createMethodCall($propertyFetch, 'get', [new \PhpParser\Node\Arg(new \PhpParser\Node\Scalar\String_('Location'))]);
if (!isset($methodCall->args[1])) {
return null;
}
$firstArg = $methodCall->args[1];
if (!$firstArg instanceof \PhpParser\Node\Arg) {
return null;
}
if ($this->nodeComparator->areNodesEqual($firstArg->value, $clientGetLocation)) {
$args = [];
$args[] = $methodCall->args[0];
$args[] = $previousNode->args[0];
$this->removeNode($previousNode);
return $this->nodeFactory->createLocalMethodCall('assertResponseRedirects', $args);
}
}
return null;
}
private function getGetStatusCodeMethodCall() : \PhpParser\Node\Expr\MethodCall
{
if ($this->getStatusCodeMethodCall === null) {
throw new \Rector\Core\Exception\ShouldNotHappenException();
}
return $this->getStatusCodeMethodCall;
}
}

View File

@ -0,0 +1,97 @@
<?php
declare (strict_types=1);
namespace Rector\Symfony\Rector\MethodCall;
use PhpParser\Node;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Expr\StaticCall;
use PhpParser\Node\Identifier;
use Rector\Core\Rector\AbstractRector;
use Rector\PHPUnit\NodeAnalyzer\TestsNodeAnalyzer;
use Rector\Symfony\NodeAnalyzer\SymfonyTestCaseAnalyzer;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* @changelog https://symfony.com/blog/new-in-symfony-4-3-better-test-assertions
* @changelog https://github.com/symfony/symfony/pull/30813
*
* @see \Rector\Symfony\Tests\Rector\MethodCall\WebTestCaseAssertIsSuccessfulRector\WebTestCaseAssertIsSuccessfulRectorTest
*/
final class WebTestCaseAssertIsSuccessfulRector extends \Rector\Core\Rector\AbstractRector
{
/**
* @readonly
* @var \Rector\Symfony\NodeAnalyzer\SymfonyTestCaseAnalyzer
*/
private $symfonyTestCaseAnalyzer;
/**
* @readonly
* @var \Rector\PHPUnit\NodeAnalyzer\TestsNodeAnalyzer
*/
private $testsNodeAnalyzer;
public function __construct(\Rector\Symfony\NodeAnalyzer\SymfonyTestCaseAnalyzer $symfonyTestCaseAnalyzer, \Rector\PHPUnit\NodeAnalyzer\TestsNodeAnalyzer $testsNodeAnalyzer)
{
$this->symfonyTestCaseAnalyzer = $symfonyTestCaseAnalyzer;
$this->testsNodeAnalyzer = $testsNodeAnalyzer;
}
public function getRuleDefinition() : \Symplify\RuleDocGenerator\ValueObject\RuleDefinition
{
return new \Symplify\RuleDocGenerator\ValueObject\RuleDefinition('Simplify use of assertions in WebTestCase', [new \Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample(<<<'CODE_SAMPLE'
use PHPUnit\Framework\TestCase;
class SomeClass extends TestCase
{
public function test()
{
$this->assertSame(200, $this->client->getResponse()->getStatusCode());
}
}
CODE_SAMPLE
, <<<'CODE_SAMPLE'
use PHPUnit\Framework\TestCase;
class SomeClass extends TestCase
{
public function test()
{
$this->assertResponseIsSuccessful();
}
}
CODE_SAMPLE
)]);
}
/**
* @return array<class-string<Node>>
*/
public function getNodeTypes() : array
{
return [\PhpParser\Node\Expr\MethodCall::class, \PhpParser\Node\Expr\StaticCall::class];
}
/**
* @param MethodCall|StaticCall $node
*/
public function refactor(\PhpParser\Node $node) : ?\PhpParser\Node
{
if (!$this->symfonyTestCaseAnalyzer->isInWebTestCase($node)) {
return null;
}
if (!$this->testsNodeAnalyzer->isAssertMethodCallName($node, 'assertSame')) {
return null;
}
$args = $node->getArgs();
if (!$this->valueResolver->isValue($args[0]->value, 200)) {
return null;
}
$secondArg = $args[1]->value;
if (!$secondArg instanceof \PhpParser\Node\Expr\MethodCall) {
return null;
}
if (!$this->isName($secondArg->name, 'getStatusCode')) {
return null;
}
$node->name = new \PhpParser\Node\Identifier('assertResponseIsSuccessful');
$node->args = [];
return $node;
}
}

View File

@ -0,0 +1,144 @@
<?php
declare (strict_types=1);
namespace Rector\Symfony\Rector\MethodCall;
use PhpParser\Node;
use PhpParser\Node\Expr;
use PhpParser\Node\Expr\MethodCall;
use Rector\Core\Rector\AbstractRector;
use Rector\PHPUnit\NodeAnalyzer\TestsNodeAnalyzer;
use Rector\Symfony\NodeAnalyzer\SymfonyTestCaseAnalyzer;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* @changelog https://symfony.com/blog/new-in-symfony-4-3-better-test-assertions
* @changelog https://github.com/symfony/symfony/pull/30813
*
* @see \Rector\Symfony\Tests\Rector\MethodCall\WebTestCaseAssertResponseCodeRector\WebTestCaseAssertResponseCodeRectorTest
*/
final class WebTestCaseAssertResponseCodeRector extends \Rector\Core\Rector\AbstractRector
{
/**
* @readonly
* @var \Rector\Symfony\NodeAnalyzer\SymfonyTestCaseAnalyzer
*/
private $symfonyTestCaseAnalyzer;
/**
* @readonly
* @var \Rector\PHPUnit\NodeAnalyzer\TestsNodeAnalyzer
*/
private $testsNodeAnalyzer;
public function __construct(\Rector\Symfony\NodeAnalyzer\SymfonyTestCaseAnalyzer $symfonyTestCaseAnalyzer, \Rector\PHPUnit\NodeAnalyzer\TestsNodeAnalyzer $testsNodeAnalyzer)
{
$this->symfonyTestCaseAnalyzer = $symfonyTestCaseAnalyzer;
$this->testsNodeAnalyzer = $testsNodeAnalyzer;
}
public function getRuleDefinition() : \Symplify\RuleDocGenerator\ValueObject\RuleDefinition
{
return new \Symplify\RuleDocGenerator\ValueObject\RuleDefinition('Simplify use of assertions in WebTestCase', [new \Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample(<<<'CODE_SAMPLE'
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
final class SomeClass extends WebTestCase
{
public function test()
{
$response = self::getClient()->getResponse();
$this->assertSame(301, $response->getStatusCode());
$this->assertSame('https://example.com', $response->headers->get('Location'));
}
}
CODE_SAMPLE
, <<<'CODE_SAMPLE'
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
final class SomeClass extends WebTestCase
{
public function test()
{
$this->assertResponseStatusCodeSame(301);
$this->assertResponseRedirects('https://example.com');
}
}
CODE_SAMPLE
)]);
}
/**
* @return array<class-string<Node>>
*/
public function getNodeTypes() : array
{
return [\PhpParser\Node\Expr\MethodCall::class];
}
/**
* @param MethodCall $node
*/
public function refactor(\PhpParser\Node $node) : ?\PhpParser\Node
{
if (!$this->symfonyTestCaseAnalyzer->isInWebTestCase($node)) {
return null;
}
// assertResponseStatusCodeSame
$newMethodCall = $this->processAssertResponseStatusCodeSame($node);
if ($newMethodCall !== null) {
return $newMethodCall;
}
return $this->processAssertResponseRedirects($node);
}
/**
* We look for: "$client->getResponse()->headers->get('Location')"
*/
public function isGetLocationMethodCall(\PhpParser\Node\Expr $expr) : bool
{
if (!$expr instanceof \PhpParser\Node\Expr\MethodCall) {
return \false;
}
if (!$this->isName($expr->name, 'get')) {
return \false;
}
$args = $expr->getArgs();
if ($args === []) {
return \false;
}
$firstArg = $args[0];
return $this->valueResolver->isValue($firstArg->value, 'Location');
}
private function processAssertResponseStatusCodeSame(\PhpParser\Node\Expr\MethodCall $methodCall) : ?\PhpParser\Node\Expr\MethodCall
{
if (!$this->isName($methodCall->name, 'assertSame')) {
return null;
}
$args = $methodCall->getArgs();
$secondArg = $args[1];
if (!$secondArg->value instanceof \PhpParser\Node\Expr\MethodCall) {
return null;
}
$nestedMethodCall = $secondArg->value;
if (!$this->nodeNameResolver->isName($nestedMethodCall->name, 'getStatusCode')) {
return null;
}
$statusCode = $this->valueResolver->getValue($args[0]->value);
if ($statusCode === null) {
return null;
}
// handled by another methods
if ($statusCode === 200) {
return null;
}
return $this->nodeFactory->createLocalMethodCall('assertResponseStatusCodeSame', [$methodCall->args[0]]);
}
private function processAssertResponseRedirects(\PhpParser\Node\Expr\MethodCall $methodCall) : ?\PhpParser\Node\Expr\MethodCall
{
if (!$this->testsNodeAnalyzer->isPHPUnitMethodCallNames($methodCall, ['assertSame'])) {
return null;
}
$args = $methodCall->getArgs();
$firstArgValue = $args[1]->value;
if (!$this->isGetLocationMethodCall($firstArgValue)) {
return null;
}
$expectedUrl = $args[0]->value;
return $this->nodeFactory->createLocalMethodCall('assertResponseRedirects', [$expectedUrl]);
}
}

View File

@ -0,0 +1,104 @@
<?php
declare (strict_types=1);
namespace Rector\Symfony\Rector\MethodCall;
use PhpParser\Node;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Expr\StaticCall;
use Rector\Core\Rector\AbstractRector;
use Rector\PHPUnit\NodeAnalyzer\TestsNodeAnalyzer;
use Rector\Symfony\NodeAnalyzer\SymfonyTestCaseAnalyzer;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* @changelog https://symfony.com/blog/new-in-symfony-4-3-better-test-assertions
* @changelog https://github.com/symfony/symfony/pull/30813
*
* @see \Rector\Symfony\Tests\Rector\MethodCall\WebTestCaseAssertSelectorTextContainsRector\WebTestCaseAssertSelectorTextContainsRectorTest
*/
final class WebTestCaseAssertSelectorTextContainsRector extends \Rector\Core\Rector\AbstractRector
{
/**
* @readonly
* @var \Rector\Symfony\NodeAnalyzer\SymfonyTestCaseAnalyzer
*/
private $symfonyTestCaseAnalyzer;
/**
* @readonly
* @var \Rector\PHPUnit\NodeAnalyzer\TestsNodeAnalyzer
*/
private $testsNodeAnalyzer;
public function __construct(\Rector\Symfony\NodeAnalyzer\SymfonyTestCaseAnalyzer $symfonyTestCaseAnalyzer, \Rector\PHPUnit\NodeAnalyzer\TestsNodeAnalyzer $testsNodeAnalyzer)
{
$this->symfonyTestCaseAnalyzer = $symfonyTestCaseAnalyzer;
$this->testsNodeAnalyzer = $testsNodeAnalyzer;
}
public function getRuleDefinition() : \Symplify\RuleDocGenerator\ValueObject\RuleDefinition
{
return new \Symplify\RuleDocGenerator\ValueObject\RuleDefinition('Simplify use of assertions in WebTestCase to assertSelectorTextContains()', [new \Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample(<<<'CODE_SAMPLE'
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
use Symfony\Component\DomCrawler\Crawler;
final class SomeTest extends WebTestCase
{
public function testContains()
{
$crawler = new Symfony\Component\DomCrawler\Crawler();
$this->assertContains('Hello World', $crawler->filter('h1')->text());
}
}
CODE_SAMPLE
, <<<'CODE_SAMPLE'
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
use Symfony\Component\DomCrawler\Crawler;
final class SomeTest extends WebTestCase
{
public function testContains()
{
$crawler = new Symfony\Component\DomCrawler\Crawler();
$this->assertSelectorTextContains('h1', 'Hello World');
}
}
CODE_SAMPLE
)]);
}
/**
* @return array<class-string<Node>>
*/
public function getNodeTypes() : array
{
return [\PhpParser\Node\Expr\MethodCall::class, \PhpParser\Node\Expr\StaticCall::class];
}
/**
* @param MethodCall|StaticCall $node
*/
public function refactor(\PhpParser\Node $node) : ?\PhpParser\Node
{
if (!$this->symfonyTestCaseAnalyzer->isInWebTestCase($node)) {
return null;
}
if (!$this->testsNodeAnalyzer->isAssertMethodCallName($node, 'assertContains')) {
return null;
}
$args = $node->getArgs();
$firstArgValue = $args[1]->value;
if (!$firstArgValue instanceof \PhpParser\Node\Expr\MethodCall) {
return null;
}
$methodCall = $firstArgValue;
if (!$this->isName($methodCall->name, 'text')) {
return null;
}
if (!$methodCall->var instanceof \PhpParser\Node\Expr\MethodCall) {
return null;
}
$nestedMethodCall = $methodCall->var;
if (!$this->isName($nestedMethodCall->name, 'filter')) {
return null;
}
$newArgs = [$nestedMethodCall->args[0], $args[0]];
return $this->nodeFactory->createLocalMethodCall('assertSelectorTextContains', $newArgs);
}
}

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('RectorPrefix20220424\AutoloadIncluder');
}
if (!class_exists('ComposerAutoloaderInit388c70bb548765b1670bb03171cf794b', false) && !interface_exists('ComposerAutoloaderInit388c70bb548765b1670bb03171cf794b', false) && !trait_exists('ComposerAutoloaderInit388c70bb548765b1670bb03171cf794b', false)) {
spl_autoload_call('RectorPrefix20220424\ComposerAutoloaderInit388c70bb548765b1670bb03171cf794b');
if (!class_exists('ComposerAutoloaderInit19fcad7dd58e192ff8d5197742f295d9', false) && !interface_exists('ComposerAutoloaderInit19fcad7dd58e192ff8d5197742f295d9', false) && !trait_exists('ComposerAutoloaderInit19fcad7dd58e192ff8d5197742f295d9', false)) {
spl_autoload_call('RectorPrefix20220424\ComposerAutoloaderInit19fcad7dd58e192ff8d5197742f295d9');
}
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('RectorPrefix20220424\Helmich\TypoScriptParser\Parser\AST\Statement');
@ -59,9 +59,9 @@ if (!function_exists('print_node')) {
return \RectorPrefix20220424\print_node(...func_get_args());
}
}
if (!function_exists('composerRequire388c70bb548765b1670bb03171cf794b')) {
function composerRequire388c70bb548765b1670bb03171cf794b() {
return \RectorPrefix20220424\composerRequire388c70bb548765b1670bb03171cf794b(...func_get_args());
if (!function_exists('composerRequire19fcad7dd58e192ff8d5197742f295d9')) {
function composerRequire19fcad7dd58e192ff8d5197742f295d9() {
return \RectorPrefix20220424\composerRequire19fcad7dd58e192ff8d5197742f295d9(...func_get_args());
}
}
if (!function_exists('scanPath')) {