From af3c92b3d51a8f374692105a4069533a245df295 Mon Sep 17 00:00:00 2001 From: TomasVotruba Date: Tue, 31 Mar 2020 20:23:21 +0200 Subject: [PATCH] move property adding to PostRector --- .../src/Collector/PropertyToAddCollector.php | 98 +++++++++ .../AbstractRector/NodeCommandersTrait.php | 17 +- .../src/Rector/PropertyAddingPostRector.php | 95 +++++++++ .../Commander/PropertyAddingCommander.php | 190 ------------------ 4 files changed, 201 insertions(+), 199 deletions(-) create mode 100644 packages/post-rector/src/Collector/PropertyToAddCollector.php create mode 100644 packages/post-rector/src/Rector/PropertyAddingPostRector.php delete mode 100644 src/PhpParser/Node/Commander/PropertyAddingCommander.php diff --git a/packages/post-rector/src/Collector/PropertyToAddCollector.php b/packages/post-rector/src/Collector/PropertyToAddCollector.php new file mode 100644 index 000000000000..e3a604d4b5cc --- /dev/null +++ b/packages/post-rector/src/Collector/PropertyToAddCollector.php @@ -0,0 +1,98 @@ +nodeNameResolver = $nodeNameResolver; + } + + public function isActive(): bool + { + if (count($this->propertiesByClass) > 0) { + return true; + } + + if (count($this->propertiesWithoutConstructorByClass) > 0) { + return true; + } + + return count($this->constantsByClass) > 0; + } + + public function addPropertyToClass(string $propertyName, ?Type $propertyType, Class_ $class): void + { + $this->propertiesByClass[spl_object_hash($class)][$propertyName] = $propertyType; + } + + public function addConstantToClass(Class_ $class, ClassConst $classConst): void + { + $constantName = $this->nodeNameResolver->getName($classConst); + $this->constantsByClass[spl_object_hash($class)][$constantName] = $classConst; + } + + public function addPropertyWithoutConstructorToClass( + string $propertyName, + ?Type $propertyType, + Class_ $classNode + ): void { + $this->propertiesWithoutConstructorByClass[spl_object_hash($classNode)][$propertyName] = $propertyType; + } + + /** + * @var ClassConst[] + */ + public function getConstantsByClass(Class_ $class): array + { + $classHash = spl_object_hash($class); + return $this->constantsByClass[$classHash] ?? []; + } + + /** + * @var Type[]|null[] + */ + public function getPropertiesByClass(Class_ $class): array + { + $classHash = spl_object_hash($class); + return $this->propertiesByClass[$classHash] ?? []; + } + + /** + * @var Type[]|null[] + */ + public function getPropertiesWithoutConstructorByClass(Class_ $class): array + { + $classHash = spl_object_hash($class); + return $this->propertiesWithoutConstructorByClass[$classHash] ?? []; + } +} diff --git a/packages/post-rector/src/Rector/AbstractRector/NodeCommandersTrait.php b/packages/post-rector/src/Rector/AbstractRector/NodeCommandersTrait.php index 940d624fd84e..8870f191cdc4 100644 --- a/packages/post-rector/src/Rector/AbstractRector/NodeCommandersTrait.php +++ b/packages/post-rector/src/Rector/AbstractRector/NodeCommandersTrait.php @@ -14,10 +14,10 @@ use Rector\ChangesReporting\Collector\RectorChangeCollector; use Rector\Core\PhpParser\Node\Commander\NodeAddingCommander; use Rector\Core\PhpParser\Node\Commander\NodeReplacingCommander; -use Rector\Core\PhpParser\Node\Commander\PropertyAddingCommander; use Rector\PHPStan\Type\AliasedObjectType; use Rector\PHPStan\Type\FullyQualifiedObjectType; use Rector\PostRector\Collector\NodesToRemoveCollector; +use Rector\PostRector\Collector\PropertyToAddCollector; use Rector\PostRector\Collector\UseNodesToAddCollector; /** @@ -42,9 +42,9 @@ trait NodeCommandersTrait private $nodeAddingCommander; /** - * @var PropertyAddingCommander + * @var PropertyToAddCollector */ - private $propertyAddingCommander; + private $propertyToAddCollector; /** * @var NodeReplacingCommander @@ -62,14 +62,14 @@ trait NodeCommandersTrait public function autowireNodeCommandersTrait( NodesToRemoveCollector $nodesToRemoveCollector, NodeAddingCommander $nodeAddingCommander, - PropertyAddingCommander $propertyAddingCommander, + PropertyToAddCollector $propertyToAddCollector, UseNodesToAddCollector $useNodesToAddCollector, NodeReplacingCommander $nodeReplacingCommander, RectorChangeCollector $rectorChangeCollector ): void { $this->nodesToRemoveCollector = $nodesToRemoveCollector; $this->nodeAddingCommander = $nodeAddingCommander; - $this->propertyAddingCommander = $propertyAddingCommander; + $this->propertyToAddCollector = $propertyToAddCollector; $this->useNodesToAddCollector = $useNodesToAddCollector; $this->nodeReplacingCommander = $nodeReplacingCommander; $this->rectorChangeCollector = $rectorChangeCollector; @@ -101,13 +101,13 @@ protected function addNodeBeforeNode(Node $newNode, Node $positionNode): void protected function addPropertyToClass(Class_ $class, ?Type $propertyType, string $propertyName): void { - $this->propertyAddingCommander->addPropertyToClass($propertyName, $propertyType, $class); + $this->propertyToAddCollector->addPropertyToClass($propertyName, $propertyType, $class); $this->rectorChangeCollector->notifyNodeFileInfo($class); } protected function addConstantToClass(Class_ $class, ClassConst $classConst): void { - $this->propertyAddingCommander->addConstantToClass($class, $classConst); + $this->propertyToAddCollector->addConstantToClass($class, $classConst); $this->rectorChangeCollector->notifyNodeFileInfo($class); } @@ -116,8 +116,7 @@ protected function addPropertyWithoutConstructorToClass( ?Type $propertyType, string $propertyName ): void { - $this->propertyAddingCommander->addPropertyWithoutConstructorToClass($propertyName, $propertyType, $classNode); - + $this->propertyToAddCollector->addPropertyWithoutConstructorToClass($propertyName, $propertyType, $classNode); $this->rectorChangeCollector->notifyNodeFileInfo($classNode); } diff --git a/packages/post-rector/src/Rector/PropertyAddingPostRector.php b/packages/post-rector/src/Rector/PropertyAddingPostRector.php new file mode 100644 index 000000000000..7cc51d17851f --- /dev/null +++ b/packages/post-rector/src/Rector/PropertyAddingPostRector.php @@ -0,0 +1,95 @@ +classDependencyManipulator = $classDependencyManipulator; + $this->classInsertManipulator = $classInsertManipulator; + $this->propertyToAddCollector = $propertyToAddCollector; + } + + public function getPriority(): int + { + return 900; + } + + public function refactor(Node $node): ?Node + { + if (! $node instanceof Class_ || $node->isAnonymous()) { + return null; + } + + $this->addConstants($node); + $this->addProperties($node); + $this->addPropertiesWithoutConstructor($node); + + return $node; + } + + public function getDefinition(): RectorDefinition + { + return new RectorDefinition('Post Rector that adds properties'); + } + + private function addConstants(Class_ $class): void + { + $constants = $this->propertyToAddCollector->getConstantsByClass($class); + + foreach ($constants as $constantName => $nodeConst) { + $this->classInsertManipulator->addConstantToClass($class, $constantName, $nodeConst); + } + } + + private function addProperties(Class_ $class): void + { + $properties = $this->propertyToAddCollector->getPropertiesByClass($class); + + foreach ($properties as $propertyName => $propertyType) { + $this->classDependencyManipulator->addConstructorDependency($class, $propertyName, $propertyType); + } + } + + private function addPropertiesWithoutConstructor(Class_ $class): void + { + $propertiesWithoutConstructor = $this->propertyToAddCollector->getPropertiesWithoutConstructorByClass( + $class + ); + + foreach ($propertiesWithoutConstructor as $propertyName => $propertyType) { + $this->classInsertManipulator->addPropertyToClass($class, $propertyName, $propertyType); + } + } +} diff --git a/src/PhpParser/Node/Commander/PropertyAddingCommander.php b/src/PhpParser/Node/Commander/PropertyAddingCommander.php deleted file mode 100644 index 8b3c82c9df64..000000000000 --- a/src/PhpParser/Node/Commander/PropertyAddingCommander.php +++ /dev/null @@ -1,190 +0,0 @@ -nodeNameResolver = $nodeNameResolver; - $this->classDependencyManipulator = $classDependencyManipulator; - $this->classInsertManipulator = $classInsertManipulator; - } - - public function addPropertyToClass(string $propertyName, ?Type $propertyType, Class_ $classNode): void - { - $this->propertiesByClass[spl_object_hash($classNode)][$propertyName] = $propertyType; - } - - public function addConstantToClass(Class_ $class, ClassConst $classConst): void - { - $constantName = $this->nodeNameResolver->getName($classConst); - $this->constantsByClass[spl_object_hash($class)][$constantName] = $classConst; - } - - public function addPropertyWithoutConstructorToClass( - string $propertyName, - ?Type $propertyType, - Class_ $classNode - ): void { - $this->propertiesWithoutConstructorByClass[spl_object_hash($classNode)][$propertyName] = $propertyType; - } - - /** - * @param Node[] $nodes - * @return Node[] - */ - public function traverseNodes(array $nodes): array - { - $nodeTraverser = new NodeTraverser(); - $nodeTraverser->addVisitor($this->createNodeVisitor()); - - // new nodes to remove are always per traverse - $this->propertiesByClass = []; - $this->constantsByClass = []; - - return $nodeTraverser->traverse($nodes); - } - - public function isActive(): bool - { - return count($this->propertiesByClass) > 0 || count($this->propertiesWithoutConstructorByClass) > 0 || count( - $this->constantsByClass - ) > 0; - } - - public function getPriority(): int - { - return 900; - } - - private function createNodeVisitor(): NodeVisitor - { - return new class($this->classInsertManipulator, $this->classDependencyManipulator, $this->propertiesByClass, $this->propertiesWithoutConstructorByClass, $this->constantsByClass) extends NodeVisitorAbstract { - /** - * @var Type[][]|null[][] - */ - private $propertiesByClass = []; - - /** - * @var Type[][]|null[][] - */ - private $propertiesWithoutConstructorByClass = []; - - /** - * @var ClassInsertManipulator - */ - private $classInsertManipulator; - - /** - * @var ClassConst[][] - */ - private $constantsByClass = []; - - /** - * @var ClassDependencyManipulator - */ - private $classDependencyManipulator; - - /** - * @param Type[][]|null[][] $propertiesByClass - * @param Type[][]|null[][] $propertiesWithoutConstructorByClass - * @param ClassConst[][] $constantsByClass - */ - public function __construct( - ClassInsertManipulator $classInsertManipulator, - ClassDependencyManipulator $classDependencyManipulator, - array $propertiesByClass, - array $propertiesWithoutConstructorByClass, - array $constantsByClass - ) { - $this->classInsertManipulator = $classInsertManipulator; - $this->classDependencyManipulator = $classDependencyManipulator; - $this->propertiesByClass = $propertiesByClass; - $this->propertiesWithoutConstructorByClass = $propertiesWithoutConstructorByClass; - $this->constantsByClass = $constantsByClass; - } - - public function enterNode(Node $node): ?Node - { - if (! $node instanceof Class_ || $node->isAnonymous()) { - return null; - } - - return $this->processClassNode($node); - } - - private function processClassNode(Class_ $class): Class_ - { - $classHash = spl_object_hash($class); - - $classConstants = $this->constantsByClass[$classHash] ?? []; - foreach ($classConstants as $constantName => $classConst) { - $this->classInsertManipulator->addConstantToClass($class, $constantName, $classConst); - } - - $classProperties = $this->propertiesByClass[$classHash] ?? []; - foreach ($classProperties as $propertyName => $propertyType) { - $this->classDependencyManipulator->addConstructorDependency($class, $propertyName, $propertyType); - } - - $classPropertiesWithoutConstructor = $this->propertiesWithoutConstructorByClass[$classHash] ?? []; - foreach ($classPropertiesWithoutConstructor as $propertyName => $propertyType) { - $this->classInsertManipulator->addPropertyToClass($class, $propertyName, $propertyType); - } - - return $class; - } - }; - } -}