mirror of
https://github.com/rectorphp/rector.git
synced 2025-01-17 13:28:18 +01:00
Updated Rector to commit 912d0b7ecc78aae4cbc2f3df7992fab9b5c63014
912d0b7ecc
[PhpParser] Remove regex check single line spaces before <?php on FileProcessor (#6525)
This commit is contained in:
parent
cce6781c15
commit
f4499090a2
4
vendor/composer/autoload_classmap.php
vendored
4
vendor/composer/autoload_classmap.php
vendored
@ -2237,8 +2237,12 @@ return array(
|
||||
'Rector\\Symfony\\DataProvider\\ServiceMapProvider' => $vendorDir . '/rector/rector-symfony/src/DataProvider/ServiceMapProvider.php',
|
||||
'Rector\\Symfony\\DataProvider\\ServiceNameToTypeUniqueProvider' => $vendorDir . '/rector/rector-symfony/src/DataProvider/ServiceNameToTypeUniqueProvider.php',
|
||||
'Rector\\Symfony\\DependencyInjection\\NodeDecorator\\CommandConstructorDecorator' => $vendorDir . '/rector/rector-symfony/rules/DependencyInjection/NodeDecorator/CommandConstructorDecorator.php',
|
||||
'Rector\\Symfony\\DependencyInjection\\NodeFactory\\AutowireClassMethodFactory' => $vendorDir . '/rector/rector-symfony/rules/DependencyInjection/NodeFactory/AutowireClassMethodFactory.php',
|
||||
'Rector\\Symfony\\DependencyInjection\\Rector\\Class_\\CommandGetByTypeToConstructorInjectionRector' => $vendorDir . '/rector/rector-symfony/rules/DependencyInjection/Rector/Class_/CommandGetByTypeToConstructorInjectionRector.php',
|
||||
'Rector\\Symfony\\DependencyInjection\\Rector\\Class_\\ControllerGetByTypeToConstructorInjectionRector' => $vendorDir . '/rector/rector-symfony/rules/DependencyInjection/Rector/Class_/ControllerGetByTypeToConstructorInjectionRector.php',
|
||||
'Rector\\Symfony\\DependencyInjection\\Rector\\Class_\\GetBySymfonyStringToConstructorInjectionRector' => $vendorDir . '/rector/rector-symfony/rules/DependencyInjection/Rector/Class_/GetBySymfonyStringToConstructorInjectionRector.php',
|
||||
'Rector\\Symfony\\DependencyInjection\\Rector\\Trait_\\TraitGetByTypeToInjectRector' => $vendorDir . '/rector/rector-symfony/rules/DependencyInjection/Rector/Trait_/TraitGetByTypeToInjectRector.php',
|
||||
'Rector\\Symfony\\DependencyInjection\\ThisGetTypeMatcher' => $vendorDir . '/rector/rector-symfony/rules/DependencyInjection/ThisGetTypeMatcher.php',
|
||||
'Rector\\Symfony\\DowngradeSymfony70\\Rector\\Class_\\DowngradeSymfonyCommandAttributeRector' => $vendorDir . '/rector/rector-symfony/rules/DowngradeSymfony70/Rector/Class_/DowngradeSymfonyCommandAttributeRector.php',
|
||||
'Rector\\Symfony\\Enum\\SensioAttribute' => $vendorDir . '/rector/rector-symfony/src/Enum/SensioAttribute.php',
|
||||
'Rector\\Symfony\\Enum\\SymfonyAnnotation' => $vendorDir . '/rector/rector-symfony/src/Enum/SymfonyAnnotation.php',
|
||||
|
4
vendor/composer/autoload_static.php
vendored
4
vendor/composer/autoload_static.php
vendored
@ -2456,8 +2456,12 @@ class ComposerStaticInitc12d7e0a7ec6f5f877903ca571cd9ab7
|
||||
'Rector\\Symfony\\DataProvider\\ServiceMapProvider' => __DIR__ . '/..' . '/rector/rector-symfony/src/DataProvider/ServiceMapProvider.php',
|
||||
'Rector\\Symfony\\DataProvider\\ServiceNameToTypeUniqueProvider' => __DIR__ . '/..' . '/rector/rector-symfony/src/DataProvider/ServiceNameToTypeUniqueProvider.php',
|
||||
'Rector\\Symfony\\DependencyInjection\\NodeDecorator\\CommandConstructorDecorator' => __DIR__ . '/..' . '/rector/rector-symfony/rules/DependencyInjection/NodeDecorator/CommandConstructorDecorator.php',
|
||||
'Rector\\Symfony\\DependencyInjection\\NodeFactory\\AutowireClassMethodFactory' => __DIR__ . '/..' . '/rector/rector-symfony/rules/DependencyInjection/NodeFactory/AutowireClassMethodFactory.php',
|
||||
'Rector\\Symfony\\DependencyInjection\\Rector\\Class_\\CommandGetByTypeToConstructorInjectionRector' => __DIR__ . '/..' . '/rector/rector-symfony/rules/DependencyInjection/Rector/Class_/CommandGetByTypeToConstructorInjectionRector.php',
|
||||
'Rector\\Symfony\\DependencyInjection\\Rector\\Class_\\ControllerGetByTypeToConstructorInjectionRector' => __DIR__ . '/..' . '/rector/rector-symfony/rules/DependencyInjection/Rector/Class_/ControllerGetByTypeToConstructorInjectionRector.php',
|
||||
'Rector\\Symfony\\DependencyInjection\\Rector\\Class_\\GetBySymfonyStringToConstructorInjectionRector' => __DIR__ . '/..' . '/rector/rector-symfony/rules/DependencyInjection/Rector/Class_/GetBySymfonyStringToConstructorInjectionRector.php',
|
||||
'Rector\\Symfony\\DependencyInjection\\Rector\\Trait_\\TraitGetByTypeToInjectRector' => __DIR__ . '/..' . '/rector/rector-symfony/rules/DependencyInjection/Rector/Trait_/TraitGetByTypeToInjectRector.php',
|
||||
'Rector\\Symfony\\DependencyInjection\\ThisGetTypeMatcher' => __DIR__ . '/..' . '/rector/rector-symfony/rules/DependencyInjection/ThisGetTypeMatcher.php',
|
||||
'Rector\\Symfony\\DowngradeSymfony70\\Rector\\Class_\\DowngradeSymfonyCommandAttributeRector' => __DIR__ . '/..' . '/rector/rector-symfony/rules/DowngradeSymfony70/Rector/Class_/DowngradeSymfonyCommandAttributeRector.php',
|
||||
'Rector\\Symfony\\Enum\\SensioAttribute' => __DIR__ . '/..' . '/rector/rector-symfony/src/Enum/SensioAttribute.php',
|
||||
'Rector\\Symfony\\Enum\\SymfonyAnnotation' => __DIR__ . '/..' . '/rector/rector-symfony/src/Enum/SymfonyAnnotation.php',
|
||||
|
8
vendor/composer/installed.json
vendored
8
vendor/composer/installed.json
vendored
@ -1868,12 +1868,12 @@
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https:\/\/github.com\/rectorphp\/rector-symfony.git",
|
||||
"reference": "617b3aff39d3ae14e5ea24ad5150fb4d0fc4a05e"
|
||||
"reference": "1138f045e2a27f9b069a3e512a04e6d49e04a596"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https:\/\/api.github.com\/repos\/rectorphp\/rector-symfony\/zipball\/617b3aff39d3ae14e5ea24ad5150fb4d0fc4a05e",
|
||||
"reference": "617b3aff39d3ae14e5ea24ad5150fb4d0fc4a05e",
|
||||
"url": "https:\/\/api.github.com\/repos\/rectorphp\/rector-symfony\/zipball\/1138f045e2a27f9b069a3e512a04e6d49e04a596",
|
||||
"reference": "1138f045e2a27f9b069a3e512a04e6d49e04a596",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -1898,7 +1898,7 @@
|
||||
"tomasvotruba\/class-leak": "^1.0",
|
||||
"tracy\/tracy": "^2.10"
|
||||
},
|
||||
"time": "2024-12-01T14:07:35+00:00",
|
||||
"time": "2024-12-01T16:51:24+00:00",
|
||||
"default-branch": true,
|
||||
"type": "rector-extension",
|
||||
"extra": {
|
||||
|
2
vendor/composer/installed.php
vendored
2
vendor/composer/installed.php
vendored
File diff suppressed because one or more lines are too long
@ -9,7 +9,7 @@ namespace Rector\RectorInstaller;
|
||||
*/
|
||||
final class GeneratedConfig
|
||||
{
|
||||
public const EXTENSIONS = array('rector/rector-doctrine' => array('install_path' => '/home/runner/work/rector-src/rector-src/rector-build/vendor/rector/rector-doctrine', 'relative_install_path' => '../../rector-doctrine', 'extra' => NULL, 'version' => 'dev-main 02ae401'), 'rector/rector-downgrade-php' => array('install_path' => '/home/runner/work/rector-src/rector-src/rector-build/vendor/rector/rector-downgrade-php', 'relative_install_path' => '../../rector-downgrade-php', 'extra' => NULL, 'version' => 'dev-main 7bb52fb'), 'rector/rector-phpunit' => array('install_path' => '/home/runner/work/rector-src/rector-src/rector-build/vendor/rector/rector-phpunit', 'relative_install_path' => '../../rector-phpunit', 'extra' => NULL, 'version' => 'dev-main a506b2c'), 'rector/rector-symfony' => array('install_path' => '/home/runner/work/rector-src/rector-src/rector-build/vendor/rector/rector-symfony', 'relative_install_path' => '../../rector-symfony', 'extra' => NULL, 'version' => 'dev-main 617b3af'));
|
||||
public const EXTENSIONS = array('rector/rector-doctrine' => array('install_path' => '/home/runner/work/rector-src/rector-src/rector-build/vendor/rector/rector-doctrine', 'relative_install_path' => '../../rector-doctrine', 'extra' => NULL, 'version' => 'dev-main 02ae401'), 'rector/rector-downgrade-php' => array('install_path' => '/home/runner/work/rector-src/rector-src/rector-build/vendor/rector/rector-downgrade-php', 'relative_install_path' => '../../rector-downgrade-php', 'extra' => NULL, 'version' => 'dev-main 7bb52fb'), 'rector/rector-phpunit' => array('install_path' => '/home/runner/work/rector-src/rector-src/rector-build/vendor/rector/rector-phpunit', 'relative_install_path' => '../../rector-phpunit', 'extra' => NULL, 'version' => 'dev-main a506b2c'), 'rector/rector-symfony' => array('install_path' => '/home/runner/work/rector-src/rector-src/rector-build/vendor/rector/rector-symfony', 'relative_install_path' => '../../rector-symfony', 'extra' => NULL, 'version' => 'dev-main 1138f04'));
|
||||
private function __construct()
|
||||
{
|
||||
}
|
||||
|
@ -4,16 +4,20 @@ declare (strict_types=1);
|
||||
namespace RectorPrefix202412;
|
||||
|
||||
use Rector\Config\RectorConfig;
|
||||
use Rector\Symfony\DependencyInjection\Rector\Class_\CommandGetByTypeToConstructorInjectionRector;
|
||||
use Rector\Symfony\DependencyInjection\Rector\Class_\ControllerGetByTypeToConstructorInjectionRector;
|
||||
use Rector\Symfony\DependencyInjection\Rector\Class_\GetBySymfonyStringToConstructorInjectionRector;
|
||||
use Rector\Symfony\DependencyInjection\Rector\Trait_\TraitGetByTypeToInjectRector;
|
||||
use Rector\Symfony\Symfony28\Rector\MethodCall\GetToConstructorInjectionRector;
|
||||
use Rector\Symfony\Symfony34\Rector\Closure\ContainerGetNameToTypeInTestsRector;
|
||||
use Rector\Symfony\Symfony42\Rector\MethodCall\ContainerGetToConstructorInjectionRector;
|
||||
return static function (RectorConfig $rectorConfig) : void {
|
||||
$rectorConfig->rules([
|
||||
// modern step-by-step narrow approach
|
||||
\Rector\Symfony\DependencyInjection\Rector\Class_\ControllerGetByTypeToConstructorInjectionRector::class,
|
||||
\Rector\Symfony\DependencyInjection\Rector\Class_\CommandGetByTypeToConstructorInjectionRector::class,
|
||||
ControllerGetByTypeToConstructorInjectionRector::class,
|
||||
CommandGetByTypeToConstructorInjectionRector::class,
|
||||
GetBySymfonyStringToConstructorInjectionRector::class,
|
||||
TraitGetByTypeToInjectRector::class,
|
||||
// legacy rules that require container fetch
|
||||
ContainerGetToConstructorInjectionRector::class,
|
||||
ContainerGetNameToTypeInTestsRector::class,
|
||||
GetToConstructorInjectionRector::class,
|
||||
]);
|
||||
|
@ -16,7 +16,6 @@ use Rector\Removing\ValueObject\ArgumentRemover;
|
||||
use Rector\Renaming\Rector\MethodCall\RenameMethodRector;
|
||||
use Rector\Renaming\Rector\Name\RenameClassRector;
|
||||
use Rector\Renaming\ValueObject\MethodCallRename;
|
||||
use Rector\Symfony\Symfony42\Rector\MethodCall\ContainerGetToConstructorInjectionRector;
|
||||
use Rector\Symfony\Symfony42\Rector\New_\RootNodeTreeBuilderRector;
|
||||
use Rector\Symfony\Symfony42\Rector\New_\StringToArrayArgumentProcessRector;
|
||||
use Rector\Transform\Rector\ClassMethod\WrapReturnRector;
|
||||
@ -39,11 +38,11 @@ return static function (RectorConfig $rectorConfig) : void {
|
||||
'Symfony\\Bundle\\FrameworkBundle\\Command\\ContainerAwareCommand' => 'Symfony\\Component\\Console\\Command\\Command',
|
||||
'Symfony\\Component\\Translation\\TranslatorInterface' => 'Symfony\\Contracts\\Translation\\TranslatorInterface',
|
||||
]);
|
||||
# related to "Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand" deprecation, @see https://github.com/rectorphp/rector/issues/1629
|
||||
$rectorConfig->rule(ContainerGetToConstructorInjectionRector::class);
|
||||
$rectorConfig->rules([
|
||||
# https://symfony.com/blog/new-in-symfony-4-2-important-deprecations
|
||||
$rectorConfig->rule(StringToArrayArgumentProcessRector::class);
|
||||
$rectorConfig->rule(RootNodeTreeBuilderRector::class);
|
||||
StringToArrayArgumentProcessRector::class,
|
||||
RootNodeTreeBuilderRector::class,
|
||||
]);
|
||||
$rectorConfig->ruleWithConfiguration(ArgumentAdderRector::class, [new ArgumentAdder('Symfony\\Component\\DomCrawler\\Crawler', 'children', 0, null, null, null, ArgumentAddingScope::SCOPE_METHOD_CALL), new ArgumentAdder('Symfony\\Component\\Finder\\Finder', 'sortByName', 0, null, \false, null, ArgumentAddingScope::SCOPE_METHOD_CALL), new ArgumentAdder('Symfony\\Bridge\\Monolog\\Processor\\DebugProcessor', 'getLogs', 0, null, null, null, ArgumentAddingScope::SCOPE_METHOD_CALL), new ArgumentAdder('Symfony\\Bridge\\Monolog\\Processor\\DebugProcessor', 'countErrors', 0, 'default_value', null, null, ArgumentAddingScope::SCOPE_METHOD_CALL), new ArgumentAdder('Symfony\\Bridge\\Monolog\\Logger', 'getLogs', 0, 'default_value', null, null, ArgumentAddingScope::SCOPE_METHOD_CALL), new ArgumentAdder('Symfony\\Bridge\\Monolog\\Logger', 'countErrors', 0, 'default_value', null, null, ArgumentAddingScope::SCOPE_METHOD_CALL), new ArgumentAdder('Symfony\\Component\\Serializer\\Normalizer', 'handleCircularReference', 1, null, null, null, ArgumentAddingScope::SCOPE_METHOD_CALL), new ArgumentAdder('Symfony\\Component\\Serializer\\Normalizer', 'handleCircularReference', 2, null, null, null, ArgumentAddingScope::SCOPE_METHOD_CALL)]);
|
||||
$rectorConfig->ruleWithConfiguration(RenameMethodRector::class, [new MethodCallRename('Symfony\\Component\\Cache\\CacheItem', 'getPreviousTags', 'getMetadata'), new MethodCallRename('Symfony\\Component\\Form\\AbstractTypeExtension', 'getExtendedType', 'getExtendedTypes')]);
|
||||
$iterableType = new IterableType(new MixedType(), new MixedType());
|
||||
|
@ -13,6 +13,9 @@ use Rector\NodeTypeResolver\NodeTypeResolver;
|
||||
use Rector\ValueObject\MethodName;
|
||||
final class CommandConstructorDecorator
|
||||
{
|
||||
/**
|
||||
* @readonly
|
||||
*/
|
||||
private NodeTypeResolver $nodeTypeResolver;
|
||||
public function __construct(NodeTypeResolver $nodeTypeResolver)
|
||||
{
|
||||
|
@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
declare (strict_types=1);
|
||||
namespace Rector\Symfony\DependencyInjection\NodeFactory;
|
||||
|
||||
use PhpParser\Comment\Doc;
|
||||
use PhpParser\Modifiers;
|
||||
use PhpParser\Node\Expr\Assign;
|
||||
use PhpParser\Node\Expr\PropertyFetch;
|
||||
use PhpParser\Node\Expr\Variable;
|
||||
use PhpParser\Node\Identifier;
|
||||
use PhpParser\Node\Name\FullyQualified;
|
||||
use PhpParser\Node\Param;
|
||||
use PhpParser\Node\Stmt\ClassMethod;
|
||||
use PhpParser\Node\Stmt\Expression;
|
||||
use PhpParser\Node\Stmt\Trait_;
|
||||
use PHPStan\Type\ObjectType;
|
||||
use Rector\Exception\ShouldNotHappenException;
|
||||
use Rector\NodeNameResolver\NodeNameResolver;
|
||||
use Rector\PostRector\ValueObject\PropertyMetadata;
|
||||
final class AutowireClassMethodFactory
|
||||
{
|
||||
/**
|
||||
* @readonly
|
||||
*/
|
||||
private NodeNameResolver $nodeNameResolver;
|
||||
public function __construct(NodeNameResolver $nodeNameResolver)
|
||||
{
|
||||
$this->nodeNameResolver = $nodeNameResolver;
|
||||
}
|
||||
/**
|
||||
* @param PropertyMetadata[] $propertyMetadatas
|
||||
*/
|
||||
public function create(Trait_ $trait, array $propertyMetadatas) : ClassMethod
|
||||
{
|
||||
$traitName = $this->nodeNameResolver->getShortName($trait);
|
||||
$autowireClassMethod = new ClassMethod('autowire' . $traitName);
|
||||
$autowireClassMethod->flags |= Modifiers::PUBLIC;
|
||||
$autowireClassMethod->returnType = new Identifier('void');
|
||||
$autowireClassMethod->setDocComment(new Doc("/**\n * @required\n */"));
|
||||
foreach ($propertyMetadatas as $propertyMetadata) {
|
||||
$param = $this->createAutowiredParam($propertyMetadata);
|
||||
$autowireClassMethod->params[] = $param;
|
||||
$createPropertyAssign = new Assign(new PropertyFetch(new Variable('this'), new Identifier($propertyMetadata->getName())), new Variable($propertyMetadata->getName()));
|
||||
$autowireClassMethod->stmts[] = new Expression($createPropertyAssign);
|
||||
}
|
||||
return $autowireClassMethod;
|
||||
}
|
||||
private function createAutowiredParam(PropertyMetadata $propertyMetadata) : Param
|
||||
{
|
||||
$param = new Param(new Variable($propertyMetadata->getName()));
|
||||
$objectType = $propertyMetadata->getType();
|
||||
if (!$objectType instanceof ObjectType) {
|
||||
throw new ShouldNotHappenException();
|
||||
}
|
||||
$param->type = new FullyQualified($objectType->getClassName());
|
||||
return $param;
|
||||
}
|
||||
}
|
@ -4,7 +4,6 @@ declare (strict_types=1);
|
||||
namespace Rector\Symfony\DependencyInjection\Rector\Class_;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Expr\ClassConstFetch;
|
||||
use PhpParser\Node\Expr\MethodCall;
|
||||
use PhpParser\Node\Stmt\Class_;
|
||||
use PHPStan\Reflection\ClassReflection;
|
||||
@ -15,6 +14,7 @@ use Rector\PostRector\ValueObject\PropertyMetadata;
|
||||
use Rector\Rector\AbstractRector;
|
||||
use Rector\StaticTypeMapper\ValueObject\Type\FullyQualifiedObjectType;
|
||||
use Rector\Symfony\DependencyInjection\NodeDecorator\CommandConstructorDecorator;
|
||||
use Rector\Symfony\DependencyInjection\ThisGetTypeMatcher;
|
||||
use Rector\Symfony\Enum\SymfonyClass;
|
||||
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
|
||||
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||
@ -35,11 +35,16 @@ final class CommandGetByTypeToConstructorInjectionRector extends AbstractRector
|
||||
* @readonly
|
||||
*/
|
||||
private CommandConstructorDecorator $commandConstructorDecorator;
|
||||
public function __construct(ClassDependencyManipulator $classDependencyManipulator, PropertyNaming $propertyNaming, CommandConstructorDecorator $commandConstructorDecorator)
|
||||
/**
|
||||
* @readonly
|
||||
*/
|
||||
private ThisGetTypeMatcher $thisGetTypeMatcher;
|
||||
public function __construct(ClassDependencyManipulator $classDependencyManipulator, PropertyNaming $propertyNaming, CommandConstructorDecorator $commandConstructorDecorator, ThisGetTypeMatcher $thisGetTypeMatcher)
|
||||
{
|
||||
$this->classDependencyManipulator = $classDependencyManipulator;
|
||||
$this->propertyNaming = $propertyNaming;
|
||||
$this->commandConstructorDecorator = $commandConstructorDecorator;
|
||||
$this->thisGetTypeMatcher = $thisGetTypeMatcher;
|
||||
}
|
||||
public function getRuleDefinition() : RuleDefinition
|
||||
{
|
||||
@ -91,27 +96,7 @@ CODE_SAMPLE
|
||||
if (!$node instanceof MethodCall) {
|
||||
return null;
|
||||
}
|
||||
if ($node->isFirstClassCallable()) {
|
||||
return null;
|
||||
}
|
||||
if (!$this->isName($node->name, 'get')) {
|
||||
return null;
|
||||
}
|
||||
if (!$this->isName($node->var, 'this')) {
|
||||
return null;
|
||||
}
|
||||
if (\count($node->getArgs()) !== 1) {
|
||||
return null;
|
||||
}
|
||||
$firstArg = $node->getArgs()[0];
|
||||
if (!$firstArg->value instanceof ClassConstFetch) {
|
||||
return null;
|
||||
}
|
||||
// must be class const fetch
|
||||
if (!$this->isName($firstArg->value->name, 'class')) {
|
||||
return null;
|
||||
}
|
||||
$className = $this->getName($firstArg->value->class);
|
||||
$className = $this->thisGetTypeMatcher->match($node);
|
||||
if (!\is_string($className)) {
|
||||
return null;
|
||||
}
|
||||
|
@ -4,7 +4,6 @@ declare (strict_types=1);
|
||||
namespace Rector\Symfony\DependencyInjection\Rector\Class_;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Expr\ClassConstFetch;
|
||||
use PhpParser\Node\Expr\MethodCall;
|
||||
use PhpParser\Node\Stmt\Class_;
|
||||
use PHPStan\Reflection\ClassReflection;
|
||||
@ -14,6 +13,7 @@ use Rector\PHPStan\ScopeFetcher;
|
||||
use Rector\PostRector\ValueObject\PropertyMetadata;
|
||||
use Rector\Rector\AbstractRector;
|
||||
use Rector\StaticTypeMapper\ValueObject\Type\FullyQualifiedObjectType;
|
||||
use Rector\Symfony\DependencyInjection\ThisGetTypeMatcher;
|
||||
use Rector\Symfony\Enum\SymfonyClass;
|
||||
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
|
||||
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||
@ -30,10 +30,15 @@ final class ControllerGetByTypeToConstructorInjectionRector extends AbstractRect
|
||||
* @readonly
|
||||
*/
|
||||
private PropertyNaming $propertyNaming;
|
||||
public function __construct(ClassDependencyManipulator $classDependencyManipulator, PropertyNaming $propertyNaming)
|
||||
/**
|
||||
* @readonly
|
||||
*/
|
||||
private ThisGetTypeMatcher $thisGetTypeMatcher;
|
||||
public function __construct(ClassDependencyManipulator $classDependencyManipulator, PropertyNaming $propertyNaming, ThisGetTypeMatcher $thisGetTypeMatcher)
|
||||
{
|
||||
$this->classDependencyManipulator = $classDependencyManipulator;
|
||||
$this->propertyNaming = $propertyNaming;
|
||||
$this->thisGetTypeMatcher = $thisGetTypeMatcher;
|
||||
}
|
||||
public function getRuleDefinition() : RuleDefinition
|
||||
{
|
||||
@ -85,27 +90,7 @@ CODE_SAMPLE
|
||||
if (!$node instanceof MethodCall) {
|
||||
return null;
|
||||
}
|
||||
if ($node->isFirstClassCallable()) {
|
||||
return null;
|
||||
}
|
||||
if (!$this->isName($node->name, 'get')) {
|
||||
return null;
|
||||
}
|
||||
if (!$this->isName($node->var, 'this')) {
|
||||
return null;
|
||||
}
|
||||
if (\count($node->getArgs()) !== 1) {
|
||||
return null;
|
||||
}
|
||||
$firstArg = $node->getArgs()[0];
|
||||
if (!$firstArg->value instanceof ClassConstFetch) {
|
||||
return null;
|
||||
}
|
||||
// must be class const fetch
|
||||
if (!$this->isName($firstArg->value->name, 'class')) {
|
||||
return null;
|
||||
}
|
||||
$className = $this->getName($firstArg->value->class);
|
||||
$className = $this->thisGetTypeMatcher->match($node);
|
||||
if (!\is_string($className)) {
|
||||
return null;
|
||||
}
|
||||
|
@ -0,0 +1,129 @@
|
||||
<?php
|
||||
|
||||
declare (strict_types=1);
|
||||
namespace Rector\Symfony\DependencyInjection\Rector\Class_;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Expr\MethodCall;
|
||||
use PhpParser\Node\Stmt\Class_;
|
||||
use PHPStan\Reflection\ClassReflection;
|
||||
use Rector\Naming\Naming\PropertyNaming;
|
||||
use Rector\NodeManipulator\ClassDependencyManipulator;
|
||||
use Rector\PHPStan\ScopeFetcher;
|
||||
use Rector\PostRector\ValueObject\PropertyMetadata;
|
||||
use Rector\Rector\AbstractRector;
|
||||
use Rector\StaticTypeMapper\ValueObject\Type\FullyQualifiedObjectType;
|
||||
use Rector\Symfony\DependencyInjection\ThisGetTypeMatcher;
|
||||
use Rector\Symfony\Enum\SymfonyClass;
|
||||
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
|
||||
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||
/**
|
||||
* @see \Rector\Symfony\Tests\DependencyInjection\Rector\Class_\GetBySymfonyStringToConstructorInjectionRector\GetBySymfonyStringToConstructorInjectionRectorTest
|
||||
*/
|
||||
final class GetBySymfonyStringToConstructorInjectionRector extends AbstractRector
|
||||
{
|
||||
/**
|
||||
* @readonly
|
||||
*/
|
||||
private ClassDependencyManipulator $classDependencyManipulator;
|
||||
/**
|
||||
* @readonly
|
||||
*/
|
||||
private ThisGetTypeMatcher $thisGetTypeMatcher;
|
||||
/**
|
||||
* @readonly
|
||||
*/
|
||||
private PropertyNaming $propertyNaming;
|
||||
/**
|
||||
* @var array<string, string>
|
||||
*/
|
||||
private const SYMFONY_NAME_TO_TYPE_MAP = ['validator' => SymfonyClass::VALIDATOR_INTERFACE, 'event_dispatcher' => SymfonyClass::EVENT_DISPATCHER_INTERFACE, 'logger' => SymfonyClass::LOGGER_INTERFACE, 'jms_serializer' => SymfonyClass::SERIALIZER_INTERFACE];
|
||||
public function __construct(ClassDependencyManipulator $classDependencyManipulator, ThisGetTypeMatcher $thisGetTypeMatcher, PropertyNaming $propertyNaming)
|
||||
{
|
||||
$this->classDependencyManipulator = $classDependencyManipulator;
|
||||
$this->thisGetTypeMatcher = $thisGetTypeMatcher;
|
||||
$this->propertyNaming = $propertyNaming;
|
||||
}
|
||||
public function getRuleDefinition() : RuleDefinition
|
||||
{
|
||||
return new RuleDefinition('Converts typical Symfony services like $this->get("validator") in commands/controllers to constructor injection (step 3/x)', [new CodeSample(<<<'CODE_SAMPLE'
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
|
||||
|
||||
final class SomeController extends Controller
|
||||
{
|
||||
public function someMethod()
|
||||
{
|
||||
$someType = $this->get('validator');
|
||||
}
|
||||
}
|
||||
CODE_SAMPLE
|
||||
, <<<'CODE_SAMPLE'
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
|
||||
use Symfony\Component\Validator\Validator\ValidatorInterface;
|
||||
|
||||
final class SomeController extends Controller
|
||||
{
|
||||
public function __construct(private ValidatorInterface $validator)
|
||||
|
||||
public function someMethod()
|
||||
{
|
||||
$someType = $this->validator;
|
||||
}
|
||||
}
|
||||
CODE_SAMPLE
|
||||
)]);
|
||||
}
|
||||
/**
|
||||
* @return array<class-string<Node>>
|
||||
*/
|
||||
public function getNodeTypes() : array
|
||||
{
|
||||
return [Class_::class];
|
||||
}
|
||||
/**
|
||||
* @param Class_ $node
|
||||
*/
|
||||
public function refactor(Node $node) : ?Node
|
||||
{
|
||||
if ($this->shouldSkipClass($node)) {
|
||||
return null;
|
||||
}
|
||||
$propertyMetadatas = [];
|
||||
$this->traverseNodesWithCallable($node, function (Node $node) use(&$propertyMetadatas) : ?Node {
|
||||
if (!$node instanceof MethodCall) {
|
||||
return null;
|
||||
}
|
||||
$serviceName = $this->thisGetTypeMatcher->matchString($node);
|
||||
if (!\is_string($serviceName)) {
|
||||
return null;
|
||||
}
|
||||
$serviceType = self::SYMFONY_NAME_TO_TYPE_MAP[$serviceName] ?? null;
|
||||
if ($serviceType === null) {
|
||||
return null;
|
||||
}
|
||||
$propertyName = $this->propertyNaming->fqnToVariableName($serviceType);
|
||||
$propertyMetadata = new PropertyMetadata($propertyName, new FullyQualifiedObjectType($serviceType));
|
||||
$propertyMetadatas[] = $propertyMetadata;
|
||||
return $this->nodeFactory->createPropertyFetch('this', $propertyMetadata->getName());
|
||||
});
|
||||
if ($propertyMetadatas === []) {
|
||||
return null;
|
||||
}
|
||||
foreach ($propertyMetadatas as $propertyMetadata) {
|
||||
$this->classDependencyManipulator->addConstructorDependency($node, $propertyMetadata);
|
||||
}
|
||||
return $node;
|
||||
}
|
||||
private function shouldSkipClass(Class_ $class) : bool
|
||||
{
|
||||
$scope = ScopeFetcher::fetch($class);
|
||||
$classReflection = $scope->getClassReflection();
|
||||
if (!$classReflection instanceof ClassReflection) {
|
||||
return \true;
|
||||
}
|
||||
if ($classReflection->isSubclassOf(SymfonyClass::CONTAINER_AWARE_COMMAND)) {
|
||||
return \false;
|
||||
}
|
||||
return !$classReflection->isSubclassOf(SymfonyClass::CONTROLLER);
|
||||
}
|
||||
}
|
@ -0,0 +1,132 @@
|
||||
<?php
|
||||
|
||||
declare (strict_types=1);
|
||||
namespace Rector\Symfony\DependencyInjection\Rector\Trait_;
|
||||
|
||||
use PhpParser\Modifiers;
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Expr\MethodCall;
|
||||
use PhpParser\Node\Name\FullyQualified;
|
||||
use PhpParser\Node\Param;
|
||||
use PhpParser\Node\PropertyItem;
|
||||
use PhpParser\Node\Stmt\Property;
|
||||
use PhpParser\Node\Stmt\Trait_;
|
||||
use PHPStan\Type\ObjectType;
|
||||
use Rector\Exception\ShouldNotHappenException;
|
||||
use Rector\Naming\Naming\PropertyNaming;
|
||||
use Rector\PostRector\ValueObject\PropertyMetadata;
|
||||
use Rector\Rector\AbstractRector;
|
||||
use Rector\StaticTypeMapper\ValueObject\Type\FullyQualifiedObjectType;
|
||||
use Rector\Symfony\DependencyInjection\NodeFactory\AutowireClassMethodFactory;
|
||||
use Rector\Symfony\DependencyInjection\ThisGetTypeMatcher;
|
||||
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
|
||||
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||
/**
|
||||
* @see \Rector\Symfony\Tests\DependencyInjection\Rector\Trait_\TraitGetByTypeToInjectRector\TraitGetByTypeToInjectRectorTest
|
||||
*/
|
||||
final class TraitGetByTypeToInjectRector extends AbstractRector
|
||||
{
|
||||
/**
|
||||
* @readonly
|
||||
*/
|
||||
private PropertyNaming $propertyNaming;
|
||||
/**
|
||||
* @readonly
|
||||
*/
|
||||
private ThisGetTypeMatcher $thisGetTypeMatcher;
|
||||
/**
|
||||
* @readonly
|
||||
*/
|
||||
private AutowireClassMethodFactory $autowireClassMethodFactory;
|
||||
public function __construct(PropertyNaming $propertyNaming, ThisGetTypeMatcher $thisGetTypeMatcher, AutowireClassMethodFactory $autowireClassMethodFactory)
|
||||
{
|
||||
$this->propertyNaming = $propertyNaming;
|
||||
$this->thisGetTypeMatcher = $thisGetTypeMatcher;
|
||||
$this->autowireClassMethodFactory = $autowireClassMethodFactory;
|
||||
}
|
||||
public function getRuleDefinition() : RuleDefinition
|
||||
{
|
||||
return new RuleDefinition('From `$this->get(SomeType::class)` in traits, to autowired method with @required', [new CodeSample(<<<'CODE_SAMPLE'
|
||||
// must be used in old Controller class
|
||||
trait SomeInjects
|
||||
{
|
||||
public function someMethod()
|
||||
{
|
||||
return $this->get(SomeType::class);
|
||||
}
|
||||
}
|
||||
CODE_SAMPLE
|
||||
, <<<'CODE_SAMPLE'
|
||||
trait SomeInjects
|
||||
{
|
||||
private SomeType $someType;
|
||||
|
||||
/**
|
||||
* @required
|
||||
*/
|
||||
public function autowireSomeInjects(SomeType $someType): void
|
||||
{
|
||||
$this->someType = $someType;
|
||||
}
|
||||
|
||||
public function someMethod()
|
||||
{
|
||||
return $this->someType;
|
||||
}
|
||||
}
|
||||
CODE_SAMPLE
|
||||
)]);
|
||||
}
|
||||
/**
|
||||
* @return array<class-string<Node>>
|
||||
*/
|
||||
public function getNodeTypes() : array
|
||||
{
|
||||
return [Trait_::class];
|
||||
}
|
||||
/**
|
||||
* @param Trait_ $node
|
||||
*/
|
||||
public function refactor(Node $node) : ?Node
|
||||
{
|
||||
$propertyMetadatas = [];
|
||||
$this->traverseNodesWithCallable($node, function (Node $node) use(&$propertyMetadatas) : ?Node {
|
||||
if (!$node instanceof MethodCall) {
|
||||
return null;
|
||||
}
|
||||
$className = $this->thisGetTypeMatcher->match($node);
|
||||
if (!\is_string($className)) {
|
||||
return null;
|
||||
}
|
||||
$propertyName = $this->propertyNaming->fqnToVariableName($className);
|
||||
$propertyMetadata = new PropertyMetadata($propertyName, new FullyQualifiedObjectType($className));
|
||||
$propertyMetadatas[] = $propertyMetadata;
|
||||
return $this->nodeFactory->createPropertyFetch('this', $propertyMetadata->getName());
|
||||
});
|
||||
if ($propertyMetadatas === []) {
|
||||
return null;
|
||||
}
|
||||
// create local properties
|
||||
$autowiredProperties = $this->createAutowiredProperties($propertyMetadatas);
|
||||
$autowireClassMethod = $this->autowireClassMethodFactory->create($node, $propertyMetadatas);
|
||||
$node->stmts = \array_merge($autowiredProperties, [$autowireClassMethod], $node->stmts);
|
||||
return $node;
|
||||
}
|
||||
/**
|
||||
* @param PropertyMetadata[] $propertyMetadatas
|
||||
* @return Property[]
|
||||
*/
|
||||
private function createAutowiredProperties(array $propertyMetadatas) : array
|
||||
{
|
||||
$autowiredProperties = [];
|
||||
foreach ($propertyMetadatas as $propertyMetadata) {
|
||||
$propertyType = $propertyMetadata->getType();
|
||||
if (!$propertyType instanceof ObjectType) {
|
||||
throw new ShouldNotHappenException();
|
||||
}
|
||||
// create property
|
||||
$autowiredProperties[] = new Property(Modifiers::PRIVATE, [new PropertyItem($propertyMetadata->getName())], [], new FullyQualified($propertyType->getClassName()));
|
||||
}
|
||||
return $autowiredProperties;
|
||||
}
|
||||
}
|
70
vendor/rector/rector-symfony/rules/DependencyInjection/ThisGetTypeMatcher.php
vendored
Normal file
70
vendor/rector/rector-symfony/rules/DependencyInjection/ThisGetTypeMatcher.php
vendored
Normal file
@ -0,0 +1,70 @@
|
||||
<?php
|
||||
|
||||
declare (strict_types=1);
|
||||
namespace Rector\Symfony\DependencyInjection;
|
||||
|
||||
use PhpParser\Node\Expr;
|
||||
use PhpParser\Node\Expr\ClassConstFetch;
|
||||
use PhpParser\Node\Expr\MethodCall;
|
||||
use PhpParser\Node\Expr\PropertyFetch;
|
||||
use PhpParser\Node\Expr\Variable;
|
||||
use PhpParser\Node\Scalar\String_;
|
||||
use Rector\NodeNameResolver\NodeNameResolver;
|
||||
final class ThisGetTypeMatcher
|
||||
{
|
||||
/**
|
||||
* @readonly
|
||||
*/
|
||||
private NodeNameResolver $nodeNameResolver;
|
||||
public function __construct(NodeNameResolver $nodeNameResolver)
|
||||
{
|
||||
$this->nodeNameResolver = $nodeNameResolver;
|
||||
}
|
||||
public function matchString(MethodCall $methodCall) : ?string
|
||||
{
|
||||
$getExpr = $this->matchGetExpr($methodCall);
|
||||
if (!$getExpr instanceof String_) {
|
||||
return null;
|
||||
}
|
||||
return $getExpr->value;
|
||||
}
|
||||
public function match(MethodCall $methodCall) : ?string
|
||||
{
|
||||
$getExpr = $this->matchGetExpr($methodCall);
|
||||
if (!$getExpr instanceof ClassConstFetch) {
|
||||
return null;
|
||||
}
|
||||
// must be class const fetch
|
||||
if (!$this->nodeNameResolver->isName($getExpr->name, 'class')) {
|
||||
return null;
|
||||
}
|
||||
return $this->nodeNameResolver->getName($getExpr->class);
|
||||
}
|
||||
private function isValidContainerCall(MethodCall $methodCall) : bool
|
||||
{
|
||||
if ($methodCall->var instanceof MethodCall && $this->nodeNameResolver->isName($methodCall->var->name, 'getContainer')) {
|
||||
return \true;
|
||||
}
|
||||
if ($methodCall->var instanceof Variable && $this->nodeNameResolver->isName($methodCall->var, 'this')) {
|
||||
return \true;
|
||||
}
|
||||
return $methodCall->var instanceof PropertyFetch && $this->nodeNameResolver->isName($methodCall->var->var, 'this') && $this->nodeNameResolver->isName($methodCall->var->name, 'container');
|
||||
}
|
||||
private function matchGetExpr(MethodCall $methodCall) : ?Expr
|
||||
{
|
||||
if ($methodCall->isFirstClassCallable()) {
|
||||
return null;
|
||||
}
|
||||
if (!$this->nodeNameResolver->isName($methodCall->name, 'get')) {
|
||||
return null;
|
||||
}
|
||||
if (!$this->isValidContainerCall($methodCall)) {
|
||||
return null;
|
||||
}
|
||||
if (\count($methodCall->getArgs()) !== 1) {
|
||||
return null;
|
||||
}
|
||||
$firstArg = $methodCall->getArgs()[0];
|
||||
return $firstArg->value;
|
||||
}
|
||||
}
|
@ -8,6 +8,7 @@ use PhpParser\Node\Expr\ClassConstFetch;
|
||||
use PhpParser\Node\Expr\MethodCall;
|
||||
use PhpParser\Node\Stmt\Class_;
|
||||
use PHPStan\Type\ObjectType;
|
||||
use Rector\Configuration\Deprecation\Contract\DeprecatedInterface;
|
||||
use Rector\NodeManipulator\ClassDependencyManipulator;
|
||||
use Rector\PHPUnit\NodeAnalyzer\TestsNodeAnalyzer;
|
||||
use Rector\PostRector\ValueObject\PropertyMetadata;
|
||||
@ -19,9 +20,9 @@ use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||
/**
|
||||
* Ref: https://github.com/symfony/symfony/blob/master/UPGRADE-4.0.md#console
|
||||
*
|
||||
* @see \Rector\Symfony\Tests\Symfony42\Rector\MethodCall\ContainerGetToConstructorInjectionRector\ContainerGetToConstructorInjectionRectorTest
|
||||
* @deprecated This rule is deprecated as too vague and causing too many changes. Use more granular @see \Rector\Symfony\Set\SymfonySetList::SYMFONY_CONSTRUCTOR_INJECTION instead
|
||||
*/
|
||||
final class ContainerGetToConstructorInjectionRector extends AbstractRector
|
||||
final class ContainerGetToConstructorInjectionRector extends AbstractRector implements DeprecatedInterface
|
||||
{
|
||||
/**
|
||||
* @readonly
|
||||
|
@ -34,7 +34,10 @@ final class ConvertRenderTemplateShortNotationToBundleSyntaxRector extends Abstr
|
||||
public function getRuleDefinition() : RuleDefinition
|
||||
{
|
||||
return new RuleDefinition('Change Twig template short name to bundle syntax in render calls from controllers', [new CodeSample(<<<'CODE_SAMPLE'
|
||||
class BaseController extends Controller {
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
|
||||
|
||||
class BaseController extends Controller
|
||||
{
|
||||
function indexAction()
|
||||
{
|
||||
$this->render('appBundle:Landing\Main:index.html.twig');
|
||||
@ -42,7 +45,10 @@ class BaseController extends Controller {
|
||||
}
|
||||
CODE_SAMPLE
|
||||
, <<<'CODE_SAMPLE'
|
||||
class BaseController extends Controller {
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
|
||||
|
||||
class BaseController extends Controller
|
||||
{
|
||||
function indexAction()
|
||||
{
|
||||
$this->render('@app/Landing/Main/index.html.twig');
|
||||
|
@ -21,4 +21,20 @@ final class SymfonyClass
|
||||
* @var string
|
||||
*/
|
||||
public const CONTAINER_AWARE_COMMAND = 'Symfony\\Bundle\\FrameworkBundle\\Command\\ContainerAwareCommand';
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public const EVENT_DISPATCHER_INTERFACE = 'Symfony\\Contracts\\EventDispatcher\\EventDispatcherInterface';
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public const VALIDATOR_INTERFACE = 'Symfony\\Component\\Validator\\Validator\\ValidatorInterface';
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public const LOGGER_INTERFACE = 'Psr\\Log\\LoggerInterface';
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public const SERIALIZER_INTERFACE = 'JMS\\Serializer\\SerializerInterface';
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user