mirror of
https://github.com/rectorphp/rector.git
synced 2024-06-11 05:32:23 +00:00
add ReplaceVariableByPropertyFetchRector
This commit is contained in:
parent
af5cc5beb2
commit
ade19f6a7d
|
@ -1,2 +1,3 @@
|
|||
services:
|
||||
Rector\Rector\Architecture\DependencyInjection\ActionInjectionToConstructorInjectionRector: ~
|
||||
Rector\Rector\Architecture\DependencyInjection\ReplaceVariableByPropertyFetchRector: ~
|
|
@ -0,0 +1,29 @@
|
|||
<?php declare(strict_types=1);
|
||||
|
||||
namespace Rector\Configuration\Rector\Architecture\DependencyInjection;
|
||||
|
||||
use Rector\Builder\Class_\VariableInfo;
|
||||
|
||||
final class VariablesToPropertyFetchCollection
|
||||
{
|
||||
/**
|
||||
* @var VariableInfo[]
|
||||
*/
|
||||
private $variableInfos = [];
|
||||
|
||||
/**
|
||||
* @param string[] $types
|
||||
*/
|
||||
public function addVariableInfo(VariableInfo $variableInfo): void
|
||||
{
|
||||
$this->variableInfos[] = $variableInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return VariableInfo[]
|
||||
*/
|
||||
public function getVariableInfos(): array
|
||||
{
|
||||
return $this->variableInfos;
|
||||
}
|
||||
}
|
|
@ -7,9 +7,11 @@ use PhpParser\Node;
|
|||
use PhpParser\Node\Param;
|
||||
use PhpParser\Node\Stmt\Class_;
|
||||
use PhpParser\Node\Stmt\ClassMethod;
|
||||
use Rector\Builder\Class_\VariableInfo;
|
||||
use Rector\Builder\Class_\VariableInfoFactory;
|
||||
use Rector\Builder\ConstructorMethodBuilder;
|
||||
use Rector\Builder\PropertyBuilder;
|
||||
use Rector\Configuration\Rector\Architecture\DependencyInjection\VariablesToPropertyFetchCollection;
|
||||
use Rector\Rector\AbstractRector;
|
||||
use Rector\RectorDefinition\CodeSample;
|
||||
use Rector\RectorDefinition\RectorDefinition;
|
||||
|
@ -30,15 +32,21 @@ final class ActionInjectionToConstructorInjectionRector extends AbstractRector
|
|||
* @var VariableInfoFactory
|
||||
*/
|
||||
private $variableInfoFactory;
|
||||
/**
|
||||
* @var VariablesToPropertyFetchCollection
|
||||
*/
|
||||
private $variablesToPropertyFetchCollection;
|
||||
|
||||
public function __construct(
|
||||
PropertyBuilder $propertyBuilder,
|
||||
ConstructorMethodBuilder $constructorMethodBuilder,
|
||||
VariableInfoFactory $variableInfoFactory
|
||||
VariableInfoFactory $variableInfoFactory,
|
||||
VariablesToPropertyFetchCollection $variablesToPropertyFetchCollection
|
||||
) {
|
||||
$this->propertyBuilder = $propertyBuilder;
|
||||
$this->constructorMethodBuilder = $constructorMethodBuilder;
|
||||
$this->variableInfoFactory = $variableInfoFactory;
|
||||
$this->variablesToPropertyFetchCollection = $variablesToPropertyFetchCollection;
|
||||
}
|
||||
|
||||
public function isCandidate(Node $node): bool
|
||||
|
@ -109,10 +117,14 @@ CODE_SAMPLE
|
|||
continue;
|
||||
}
|
||||
|
||||
$this->addConstructorDependencyToClassNode($classNode, $paramNode->var->name, [(string) $paramNode->type]);
|
||||
$variableInfo = $this->variableInfoFactory->createFromNameAndTypes($paramNode->var->name, [(string) $paramNode->type]);
|
||||
|
||||
$this->addConstructorDependencyToClassNode($classNode, $variableInfo);
|
||||
|
||||
// remove arguments
|
||||
unset($classMethodNode->params[$key]);
|
||||
|
||||
$this->variablesToPropertyFetchCollection->addVariableInfo($variableInfo);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -136,13 +148,8 @@ CODE_SAMPLE
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[] $variablesTypes
|
||||
*/
|
||||
private function addConstructorDependencyToClassNode(Class_ $classNode, string $variableName, array $variablesTypes): void
|
||||
private function addConstructorDependencyToClassNode(Class_ $classNode, VariableInfo $variableInfo): void
|
||||
{
|
||||
$variableInfo = $this->variableInfoFactory->createFromNameAndTypes($variableName, $variablesTypes);
|
||||
|
||||
// add property
|
||||
$this->propertyBuilder->addPropertyToClass($classNode, $variableInfo);
|
||||
|
||||
|
|
|
@ -0,0 +1,106 @@
|
|||
<?php declare(strict_types=1);
|
||||
|
||||
namespace Rector\Rector\Architecture\DependencyInjection;
|
||||
|
||||
use Nette\Utils\Strings;
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Expr\PropertyFetch;
|
||||
use PhpParser\Node\Expr\Variable;
|
||||
use PhpParser\Node\Stmt\ClassMethod;
|
||||
use Rector\Builder\Class_\VariableInfo;
|
||||
use Rector\Configuration\Rector\Architecture\DependencyInjection\VariablesToPropertyFetchCollection;
|
||||
use Rector\Node\Attribute;
|
||||
use Rector\Rector\AbstractRector;
|
||||
use Rector\RectorDefinition\CodeSample;
|
||||
use Rector\RectorDefinition\RectorDefinition;
|
||||
|
||||
final class ReplaceVariableByPropertyFetchRector extends AbstractRector
|
||||
{
|
||||
/**
|
||||
* @var VariablesToPropertyFetchCollection
|
||||
*/
|
||||
private $variablesToPropertyFetchCollection;
|
||||
|
||||
/**
|
||||
* @var VariableInfo|null
|
||||
*/
|
||||
private $activeVariableInfo;
|
||||
|
||||
public function __construct(VariablesToPropertyFetchCollection $variablesToPropertyFetchCollection)
|
||||
{
|
||||
$this->variablesToPropertyFetchCollection = $variablesToPropertyFetchCollection;
|
||||
}
|
||||
|
||||
public function getDefinition(): RectorDefinition
|
||||
{
|
||||
return new RectorDefinition('Turns variable to property fetch, as follow up to action injection variable to property change', [
|
||||
new CodeSample(
|
||||
<<<'CODE_SAMPLE'
|
||||
final class SomeController
|
||||
{
|
||||
public function default()
|
||||
{
|
||||
$products = $productRepository->fetchAll();
|
||||
}
|
||||
}
|
||||
CODE_SAMPLE
|
||||
,
|
||||
<<<'CODE_SAMPLE'
|
||||
final class SomeController
|
||||
{
|
||||
public function default()
|
||||
{
|
||||
$products = $this->productRepository->fetchAll();
|
||||
}
|
||||
}
|
||||
CODE_SAMPLE
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
||||
public function isCandidate(Node $node): bool
|
||||
{
|
||||
$this->activeVariableInfo = null;
|
||||
|
||||
if (! $node instanceof Variable) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (! Strings::endsWith((string) $node->getAttribute(Attribute::CLASS_NAME), 'Controller')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/** @var ClassMethod|null $methodNode */
|
||||
$methodNode = $node->getAttribute(Attribute::METHOD_NODE);
|
||||
if ($methodNode === null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// is probably in controller action
|
||||
if (! $methodNode->isPublic()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach ($this->variablesToPropertyFetchCollection->getVariableInfos() as $variableInfo) {
|
||||
if ($node->name !== $variableInfo->getName()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($node->getAttribute(Attribute::TYPES) === $variableInfo->getTypes()) {
|
||||
$this->activeVariableInfo = $variableInfo;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Variable $variableNode
|
||||
*/
|
||||
public function refactor(Node $variableNode): ?Node
|
||||
{
|
||||
// @todo NodeFactory
|
||||
return new PropertyFetch(new Variable('this'), $this->activeVariableInfo->getName());
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user