decouple AbstractToConstructorInjectionRector

This commit is contained in:
TomasVotruba 2018-03-03 20:32:21 +01:00
parent 4b10b1a7f4
commit 54245f1948
3 changed files with 83 additions and 146 deletions

View File

@ -0,0 +1,81 @@
<?php declare(strict_types=1);
namespace Rector\Rector\Contrib\Symfony\FrameworkBundle;
use PhpParser\Node;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Scalar\String_;
use Rector\Builder\Class_\ClassPropertyCollector;
use Rector\Contract\Bridge\ServiceTypeForNameProviderInterface;
use Rector\Naming\PropertyNaming;
use Rector\Node\Attribute;
use Rector\Node\PropertyFetchNodeFactory;
use Rector\NodeAnalyzer\MethodCallAnalyzer;
use Rector\Rector\AbstractRector;
abstract class AbstractToConstructorInjectionRector extends AbstractRector
{
/**
* @var PropertyNaming
*/
protected $propertyNaming;
/**
* @var ClassPropertyCollector
*/
protected $classPropertyCollector;
/**
* @var PropertyFetchNodeFactory
*/
protected $propertyFetchNodeFactory;
/**
* @var ServiceTypeForNameProviderInterface
*/
protected $serviceTypeForNameProvider;
/**
* @var MethodCallAnalyzer
*/
protected $methodCallAnalyzer;
public function __construct(
PropertyNaming $propertyNaming,
ClassPropertyCollector $classPropertyCollector,
PropertyFetchNodeFactory $propertyFetchNodeFactory,
ServiceTypeForNameProviderInterface $serviceTypeForNameProvider,
MethodCallAnalyzer $methodCallAnalyzer
) {
$this->propertyNaming = $propertyNaming;
$this->classPropertyCollector = $classPropertyCollector;
$this->propertyFetchNodeFactory = $propertyFetchNodeFactory;
$this->serviceTypeForNameProvider = $serviceTypeForNameProvider;
$this->methodCallAnalyzer = $methodCallAnalyzer;
}
/**
* @param MethodCall $methodCallNode
*/
public function refactor(Node $methodCallNode): ?Node
{
/** @var String_ $stringArgument */
$stringArgument = $methodCallNode->args[0]->value;
$serviceName = $stringArgument->value;
$serviceType = $this->serviceTypeForNameProvider->provideTypeForName($serviceName);
if ($serviceType === null) {
return null;
}
$propertyName = $this->propertyNaming->typeToName($serviceType);
$this->classPropertyCollector->addPropertyForClass(
(string) $methodCallNode->getAttribute(Attribute::CLASS_NAME),
[$serviceType],
$propertyName
);
return $this->propertyFetchNodeFactory->createLocalWithPropertyName($propertyName);
}
}

View File

@ -3,15 +3,7 @@
namespace Rector\Rector\Contrib\Symfony\FrameworkBundle;
use PhpParser\Node;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Scalar\String_;
use Rector\Builder\Class_\ClassPropertyCollector;
use Rector\Contract\Bridge\ServiceTypeForNameProviderInterface;
use Rector\Naming\PropertyNaming;
use Rector\Node\Attribute;
use Rector\Node\PropertyFetchNodeFactory;
use Rector\NodeAnalyzer\MethodCallAnalyzer;
use Rector\Rector\AbstractRector;
/**
* Ref: https://github.com/symfony/symfony/blob/master/UPGRADE-4.0.md#console
@ -36,33 +28,8 @@ use Rector\Rector\AbstractRector;
* $this->someService
* }
*/
final class ContainerGetToConstructorInjectionRector extends AbstractRector
final class ContainerGetToConstructorInjectionRector extends AbstractToConstructorInjectionRector
{
/**
* @var ClassPropertyCollector
*/
private $classPropertyCollector;
/**
* @var PropertyNaming
*/
private $propertyNaming;
/**
* @var PropertyFetchNodeFactory
*/
private $propertyFetchNodeFactory;
/**
* @var ServiceTypeForNameProviderInterface
*/
private $serviceTypeForNameProvider;
/**
* @var MethodCallAnalyzer
*/
private $methodCallAnalyzer;
/**
* @var string[]
*/
@ -71,20 +38,6 @@ final class ContainerGetToConstructorInjectionRector extends AbstractRector
'Symfony\Bundle\FrameworkBundle\Controller\Controller',
];
public function __construct(
ClassPropertyCollector $classPropertyCollector,
PropertyNaming $propertyNaming,
PropertyFetchNodeFactory $propertyFetchNodeFactory,
ServiceTypeForNameProviderInterface $serviceTypeForNameProvider,
MethodCallAnalyzer $methodCallAnalyzer
) {
$this->classPropertyCollector = $classPropertyCollector;
$this->propertyNaming = $propertyNaming;
$this->propertyFetchNodeFactory = $propertyFetchNodeFactory;
$this->serviceTypeForNameProvider = $serviceTypeForNameProvider;
$this->methodCallAnalyzer = $methodCallAnalyzer;
}
public function isCandidate(Node $node): bool
{
if (! $this->methodCallAnalyzer->isTypeAndMethod(
@ -99,29 +52,4 @@ final class ContainerGetToConstructorInjectionRector extends AbstractRector
return in_array($parentClassName, $this->containerAwareParentTypes, true);
}
/**
* @param MethodCall $methodCallNode
*/
public function refactor(Node $methodCallNode): ?Node
{
/** @var String_ $serviceNameArgument */
$serviceNameArgument = $methodCallNode->args[0]->value;
$serviceName = $serviceNameArgument->value;
$serviceType = $this->serviceTypeForNameProvider->provideTypeForName($serviceName);
if ($serviceType === null) {
return null;
}
$propertyName = $this->propertyNaming->typeToName($serviceType);
$this->classPropertyCollector->addPropertyForClass(
(string) $methodCallNode->getAttribute(Attribute::CLASS_NAME),
[$serviceType],
$propertyName
);
return $this->propertyFetchNodeFactory->createLocalWithPropertyName($propertyName);
}
}

View File

@ -4,14 +4,6 @@ namespace Rector\Rector\Contrib\Symfony\FrameworkBundle;
use PhpParser\Node;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Scalar\String_;
use Rector\Builder\Class_\ClassPropertyCollector;
use Rector\Contract\Bridge\ServiceTypeForNameProviderInterface;
use Rector\Naming\PropertyNaming;
use Rector\Node\Attribute;
use Rector\Node\PropertyFetchNodeFactory;
use Rector\NodeAnalyzer\MethodCallAnalyzer;
use Rector\Rector\AbstractRector;
/**
* Before:
@ -20,47 +12,8 @@ use Rector\Rector\AbstractRector;
* After:
* - $this->someService # where "someService" is type of the service
*/
final class GetToConstructorInjectionRector extends AbstractRector
final class GetToConstructorInjectionRector extends AbstractToConstructorInjectionRector
{
/**
* @var PropertyNaming
*/
private $propertyNaming;
/**
* @var ClassPropertyCollector
*/
private $classPropertyCollector;
/**
* @var PropertyFetchNodeFactory
*/
private $propertyFetchNodeFactory;
/**
* @var ServiceTypeForNameProviderInterface
*/
private $serviceTypeForNameProvider;
/**
* @var MethodCallAnalyzer
*/
private $methodCallAnalyzer;
public function __construct(
PropertyNaming $propertyNaming,
ClassPropertyCollector $classPropertyCollector,
PropertyFetchNodeFactory $propertyFetchNodeFactory,
ServiceTypeForNameProviderInterface $serviceTypeForNameProvider,
MethodCallAnalyzer $methodCallAnalyzer
) {
$this->propertyNaming = $propertyNaming;
$this->classPropertyCollector = $classPropertyCollector;
$this->propertyFetchNodeFactory = $propertyFetchNodeFactory;
$this->serviceTypeForNameProvider = $serviceTypeForNameProvider;
$this->methodCallAnalyzer = $methodCallAnalyzer;
}
public function isCandidate(Node $node): bool
{
if (! $node instanceof MethodCall) {
@ -73,29 +26,4 @@ final class GetToConstructorInjectionRector extends AbstractRector
'get'
);
}
/**
* @param MethodCall $methodCallNode
*/
public function refactor(Node $methodCallNode): ?Node
{
/** @var String_ $stringArgument */
$stringArgument = $methodCallNode->args[0]->value;
$serviceName = $stringArgument->value;
$serviceType = $this->serviceTypeForNameProvider->provideTypeForName($serviceName);
if ($serviceType === null) {
return null;
}
$propertyName = $this->propertyNaming->typeToName($serviceType);
$this->classPropertyCollector->addPropertyForClass(
(string) $methodCallNode->getAttribute(Attribute::CLASS_NAME),
[$serviceType],
$propertyName
);
return $this->propertyFetchNodeFactory->createLocalWithPropertyName($propertyName);
}
}