This commit is contained in:
TomasVotruba 2017-08-08 02:30:29 +02:00
parent 7d5a1250eb
commit 70bb18f099
14 changed files with 60 additions and 85 deletions

View File

@ -11,9 +11,7 @@ final class ClassPropertyCollector
public function addPropertyForClass(string $class, string $propertyType, string $propertyName): void public function addPropertyForClass(string $class, string $propertyType, string $propertyName): void
{ {
$this->classProperties[$class] = [ $this->classProperties[$class][$propertyType] = $propertyName;
$propertyType => $propertyName,
];
} }
/** /**

View File

@ -1,6 +1,6 @@
<?php declare(strict_types=1); <?php declare(strict_types=1);
namespace Rector\NodeVisitor\DependencyInjection\NamedServicesToConstructor; namespace Rector\NodeVisitor\DependencyInjection;
use PhpParser\Node; use PhpParser\Node;
use PhpParser\Node\Stmt\Class_; use PhpParser\Node\Stmt\Class_;
@ -8,7 +8,6 @@ use PhpParser\NodeVisitorAbstract;
use Rector\Builder\Class_\ClassPropertyCollector; use Rector\Builder\Class_\ClassPropertyCollector;
use Rector\Builder\ConstructorMethodBuilder; use Rector\Builder\ConstructorMethodBuilder;
use Rector\Builder\PropertyBuilder; use Rector\Builder\PropertyBuilder;
use Rector\NodeTraverser\TokenSwitcher;
/** /**
* Add new propertis to class and to contructor. * Add new propertis to class and to contructor.
@ -30,21 +29,14 @@ final class AddPropertiesToClassNodeVisitor extends NodeVisitorAbstract
*/ */
private $newClassPropertyCollector; private $newClassPropertyCollector;
/**
* @var TokenSwitcher
*/
private $tokenSwitcher;
public function __construct( public function __construct(
ConstructorMethodBuilder $constructorMethodBuilder, ConstructorMethodBuilder $constructorMethodBuilder,
PropertyBuilder $propertyBuilder, PropertyBuilder $propertyBuilder,
ClassPropertyCollector $newClassPropertyCollector, ClassPropertyCollector $newClassPropertyCollector
TokenSwitcher $tokenSwitcher
) { ) {
$this->constructorMethodBuilder = $constructorMethodBuilder; $this->constructorMethodBuilder = $constructorMethodBuilder;
$this->propertyBuilder = $propertyBuilder; $this->propertyBuilder = $propertyBuilder;
$this->newClassPropertyCollector = $newClassPropertyCollector; $this->newClassPropertyCollector = $newClassPropertyCollector;
$this->tokenSwitcher = $tokenSwitcher;
} }
/** /**
@ -53,24 +45,24 @@ final class AddPropertiesToClassNodeVisitor extends NodeVisitorAbstract
*/ */
public function afterTraverse(array $nodes): array public function afterTraverse(array $nodes): array
{ {
foreach ($nodes as $node) { foreach ($nodes as $key => $node) {
if ($node instanceof Class_) { if ($node instanceof Class_) {
$this->reconstruct($node, (string) $node->name); $nodes[$key] = $this->reconstruct($node, (string) $node->name);
break;
} }
} }
return $nodes; return $nodes;
} }
private function reconstruct(Class_ $classNode, string $className): void private function reconstruct(Class_ $classNode, string $className): Class_
{ {
$propertiesForClass = $this->newClassPropertyCollector->getPropertiesforClass($className); $propertiesForClass = $this->newClassPropertyCollector->getPropertiesforClass($className);
foreach ($propertiesForClass as $propertyType => $propertyName) { foreach ($propertiesForClass as $propertyType => $propertyName) {
$this->tokenSwitcher->enable();
$this->constructorMethodBuilder->addPropertyAssignToClass($classNode, $propertyType, $propertyName); $this->constructorMethodBuilder->addPropertyAssignToClass($classNode, $propertyType, $propertyName);
$this->propertyBuilder->addPropertyToClass($classNode, $propertyType, $propertyName); $this->propertyBuilder->addPropertyToClass($classNode, $propertyType, $propertyName);
} }
return $classNode;
} }
} }

View File

@ -1,15 +1,17 @@
<?php declare(strict_types=1); <?php declare(strict_types=1);
namespace Rector\NodeVisitor\DependencyInjection; namespace Rector\NodeVisitor\DependencyInjection\InjectAnnotationToConstructor;
use PhpCsFixer\DocBlock\DocBlock; use PhpCsFixer\DocBlock\DocBlock;
use PhpParser\Comment\Doc; use PhpParser\Comment\Doc;
use PhpParser\Node; use PhpParser\Node;
use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\Property; use PhpParser\Node\Stmt\Property;
use PhpParser\NodeVisitorAbstract; use PhpParser\NodeVisitorAbstract;
use Rector\Builder\Class_\ClassPropertyCollector;
use Rector\NodeTraverser\TokenSwitcher; use Rector\NodeTraverser\TokenSwitcher;
final class InjectAnnotationToConstructorRector extends NodeVisitorAbstract final class PropertyRector extends NodeVisitorAbstract
{ {
/** /**
* @var string * @var string
@ -21,19 +23,36 @@ final class InjectAnnotationToConstructorRector extends NodeVisitorAbstract
*/ */
private $tokenSwitcher; private $tokenSwitcher;
// /** /**
// * @var ConstructorMethodBuilder * @var ClassPropertyCollector
// */ */
// private $constructorMethodBuilder; private $classPropertyCollector;
//
// public function __construct(ConstructorMethodBuilder $constructorMethodBuilder)
// {
// $this->constructorMethodBuilder = $constructorMethodBuilder;
// }
public function __construct(TokenSwitcher $tokenSwitcher) /**
* @var string
*/
private $className;
public function __construct(TokenSwitcher $tokenSwitcher, ClassPropertyCollector $classPropertyCollector)
{ {
$this->tokenSwitcher = $tokenSwitcher; $this->tokenSwitcher = $tokenSwitcher;
$this->classPropertyCollector = $classPropertyCollector;
}
/**
* @param Node[] $nodes
* @return null|array
*/
public function beforeTraverse(array $nodes): ?array
{
dump('1');
foreach ($nodes as $node) {
if ($node instanceof Class_) {
$this->className = (string) $node->name;
}
}
return null;
} }
public function enterNode(Node $node): ?Node public function enterNode(Node $node): ?Node
@ -42,6 +61,8 @@ final class InjectAnnotationToConstructorRector extends NodeVisitorAbstract
return null; return null;
} }
dump('2');
return $this->reconstructProperty($node); return $this->reconstructProperty($node);
} }
@ -59,43 +80,14 @@ final class InjectAnnotationToConstructorRector extends NodeVisitorAbstract
return true; return true;
} }
// private function reconstruct(Class_ $classNode): Node
// {
// dump($classNode);
// die;
//
// foreach ($classNode->stmts as $classElementStatement) {
// if (! $classElementStatement instanceof Property) {
// continue;
// }
//
// $propertyNode = $classElementStatement;
//
// $propertyDocBlock = $this->createDocBlockFromNode($propertyNode);
// $injectAnnotations = $propertyDocBlock->getAnnotationsOfType(self::ANNOTATION_INJECT);
// if (! $injectAnnotations) {
// continue;
// }
//
// $this->removeInjectAnnotationFromProperty($propertyNode, $propertyDocBlock);
// $this->makePropertyPrivate($propertyNode);
//
// $propertyType = $propertyDocBlock->getAnnotationsOfType('var')[0]
// ->getTypes()[0];
// $propertyName = (string) $propertyNode->props[0]->name;
//
// $this->constructorMethodBuilder->addPropertyAssignToClass($classNode, $propertyType, $propertyName);
// }
//
// return $classNode;
// }
private function reconstructProperty($propertyNode): Property private function reconstructProperty($propertyNode): Property
{ {
$propertyDocBlock = $this->createDocBlockFromNode($propertyNode); $propertyDocBlock = $this->createDocBlockFromNode($propertyNode);
$propertyNode = $this->removeInjectAnnotationFromProperty($propertyNode, $propertyDocBlock); $propertyNode = $this->removeInjectAnnotationFromProperty($propertyNode, $propertyDocBlock);
// $propertyNode->flags = Class_::MODIFIER_PRIVATE; $propertyNode->flags = Class_::MODIFIER_PRIVATE;
$this->addPropertyToCollector($propertyNode, $propertyDocBlock);
return $propertyNode; return $propertyNode;
} }
@ -115,7 +107,6 @@ final class InjectAnnotationToConstructorRector extends NodeVisitorAbstract
private function removeInjectAnnotationFromProperty(Property $propertyNode, DocBlock $propertyDocBlock): Property private function removeInjectAnnotationFromProperty(Property $propertyNode, DocBlock $propertyDocBlock): Property
{ {
$injectAnnotations = $propertyDocBlock->getAnnotationsOfType(self::ANNOTATION_INJECT); $injectAnnotations = $propertyDocBlock->getAnnotationsOfType(self::ANNOTATION_INJECT);
foreach ($injectAnnotations as $injectAnnotation) { foreach ($injectAnnotations as $injectAnnotation) {
$injectAnnotation->remove(); $injectAnnotation->remove();
} }
@ -124,4 +115,14 @@ final class InjectAnnotationToConstructorRector extends NodeVisitorAbstract
return $propertyNode; return $propertyNode;
} }
private function addPropertyToCollector(Property $propertyNode, DocBlock $propertyDocBlock): void
{
$propertyType = $propertyDocBlock->getAnnotationsOfType('var')[0]
->getTypes()[0];
$propertyName = (string)$propertyNode->props[0]->name;
$this->classPropertyCollector->addPropertyForClass($this->className, $propertyType, $propertyName);
}
} }

View File

@ -13,7 +13,7 @@ use PhpParser\NodeVisitorAbstract;
use Rector\Builder\Class_\ClassPropertyCollector; use Rector\Builder\Class_\ClassPropertyCollector;
use Rector\Builder\Kernel\ServiceFromKernelResolver; use Rector\Builder\Kernel\ServiceFromKernelResolver;
use Rector\Builder\Naming\NameResolver; use Rector\Builder\Naming\NameResolver;
use Rector\Tests\NodeVisitor\DependencyInjection\NamedServicesToConstructorReconstructor\Source\LocalKernel; use Rector\Tests\NodeVisitor\DependencyInjection\NamedServicesToConstructorRector\Source\LocalKernel;
/** /**
* Converts all: * Converts all:
@ -22,7 +22,7 @@ use Rector\Tests\NodeVisitor\DependencyInjection\NamedServicesToConstructorRecon
* into: * into:
* $this->someService # where "someService" is type of the service * $this->someService # where "someService" is type of the service
*/ */
final class GetterToPropertyNodeVisitor extends NodeVisitorAbstract final class GetterToPropertyRector extends NodeVisitorAbstract
{ {
/** /**
* @var string * @var string
@ -69,25 +69,10 @@ final class GetterToPropertyNodeVisitor extends NodeVisitorAbstract
return null; return null;
} }
/** public function enterNode(Node $node): ?Node
* Return value semantics:
* * null
* => $node stays as-is
* * NodeTraverser::DONT_TRAVERSE_CHILDREN
* => Children of $node are not traversed. $node stays as-is
* * NodeTraverser::STOP_TRAVERSAL
* => Traversal is aborted. $node stays as-is
* * otherwise
* => $node is set to the return value.
*
* @return null|int|Node
*/
public function enterNode(Node $node)
{ {
if ($this->isCandidate($node)) { if ($this->isCandidate($node)) {
$this->reconstruct($node); return $this->reconstruct($node);
return $node;
} }
return null; return null;

View File

@ -6,7 +6,6 @@ class ClassWithInjects
* @var stdClass * @var stdClass
*/ */
private $property; private $property;
/** /**
* @var DateTimeInterface * @var DateTimeInterface
*/ */

View File

@ -1,6 +1,6 @@
<?php declare(strict_types=1); <?php declare(strict_types=1);
namespace Rector\Tests\NodeVisitor\DependencyInjection\NamedServicesToConstructorReconstructor\Source; namespace Rector\Tests\NodeVisitor\DependencyInjection\NamedServicesToConstructorRector\Source;
use Symfony\Component\Config\Loader\LoaderInterface; use Symfony\Component\Config\Loader\LoaderInterface;
use Symfony\Component\HttpKernel\Bundle\BundleInterface; use Symfony\Component\HttpKernel\Bundle\BundleInterface;

View File

@ -1,6 +1,6 @@
<?php declare(strict_types=1); <?php declare(strict_types=1);
namespace Rector\Tests\NodeVisitor\DependencyInjection\NamedServicesToConstructorReconstructor; namespace Rector\Tests\NodeVisitor\DependencyInjection\NamedServicesToConstructorRector;
use Rector\Testing\PHPUnit\AbstractReconstructorTestCase; use Rector\Testing\PHPUnit\AbstractReconstructorTestCase;