From 478ce6413824e547bc8d97f0774134f0be82a892 Mon Sep 17 00:00:00 2001 From: TomasVotruba Date: Tue, 8 Aug 2017 18:17:40 +0200 Subject: [PATCH] fix it all --- easy-coding-standard.neon | 1 + src/Builder/PropertyBuilder.php | 20 +++++++++ src/NodeTraverser/NodeTraverserFactory.php | 20 ++++++++- .../AddPropertiesToClassNodeVisitor.php | 2 - .../PropertyRector.php | 2 + .../GetterToPropertyRector.php | 2 + .../Traverse/NodeConnectorNodeVisitor.php | 45 +++++++++++++++++++ .../Traverse/ParentConnectorNodeVisitor.php | 33 ++++++++++++++ src/Printer/FormatPerservingPrinter.php | 1 - .../correct/correct.php.inc | 2 - 10 files changed, 121 insertions(+), 7 deletions(-) create mode 100644 src/NodeVisitor/Traverse/NodeConnectorNodeVisitor.php create mode 100644 src/NodeVisitor/Traverse/ParentConnectorNodeVisitor.php diff --git a/easy-coding-standard.neon b/easy-coding-standard.neon index e7be08bf21c..b2daddc770e 100644 --- a/easy-coding-standard.neon +++ b/easy-coding-standard.neon @@ -41,6 +41,7 @@ checkers: # Namespaces - PhpCsFixer\Fixer\Import\OrderedImportsFixer + - PhpCsFixer\Fixer\Import\NoUnusedImportsFixer PhpCsFixer\Fixer\Operator\ConcatSpaceFixer: spacing: one diff --git a/src/Builder/PropertyBuilder.php b/src/Builder/PropertyBuilder.php index a0237e9b53a..68eeb6d13b2 100644 --- a/src/Builder/PropertyBuilder.php +++ b/src/Builder/PropertyBuilder.php @@ -27,6 +27,10 @@ final class PropertyBuilder public function addPropertyToClass(Class_ $classNode, string $propertyType, string $propertyName): void { + if ($this->doesPropertyAlreadyExist($classNode, $propertyName)) { + return; + } + $propertyNode = $this->buildPrivatePropertyNode($propertyType, $propertyName); $this->statementGlue->addAsFirstMethod($classNode, $propertyNode); @@ -49,4 +53,20 @@ final class PropertyBuilder . PHP_EOL . ' * @var ' . $propertyType . PHP_EOL . ' */'); } + + private function doesPropertyAlreadyExist(Class_ $classNode, string $propertyName): bool + { + foreach ($classNode->stmts as $inClassNode) { + if (! $inClassNode instanceof Property) { + continue; + } + + $classPropertyName = (string) $inClassNode->props[0]->name; + if ($classPropertyName === $propertyName) { + return true; + } + } + + return false; + } } diff --git a/src/NodeTraverser/NodeTraverserFactory.php b/src/NodeTraverser/NodeTraverserFactory.php index fcd2a082cf9..9ae2e29e10c 100644 --- a/src/NodeTraverser/NodeTraverserFactory.php +++ b/src/NodeTraverser/NodeTraverserFactory.php @@ -5,6 +5,8 @@ namespace Rector\NodeTraverser; use PhpParser\NodeTraverser; use PhpParser\NodeVisitor; use PhpParser\NodeVisitor\CloningVisitor; +use Rector\NodeVisitor\Traverse\NodeConnectorNodeVisitor; +use Rector\NodeVisitor\Traverse\ParentConnectorNodeVisitor; final class NodeTraverserFactory { @@ -13,6 +15,15 @@ final class NodeTraverserFactory */ private $nodeVisitors = []; + /** + * @var string[] + */ + private $priorityNodeVisitorClasses = [ + CloningVisitor::class, + ParentConnectorNodeVisitor::class, + NodeConnectorNodeVisitor::class + ]; + public function addNodeVisitor(NodeVisitor $nodeVisitor): void { $this->nodeVisitors[] = $nodeVisitor; @@ -22,10 +33,15 @@ final class NodeTraverserFactory { $nodeTraverser = new NodeTraverser; - // this one has priority - $nodeTraverser->addVisitor(new CloningVisitor); + foreach ($this->priorityNodeVisitorClasses as $priorityNodeVisitor) { + $nodeTraverser->addVisitor(new $priorityNodeVisitor); + } foreach ($this->nodeVisitors as $nodeVisitor) { + if (in_array(get_class($nodeVisitor), $this->priorityNodeVisitorClasses, true)) { + continue; + } + $nodeTraverser->addVisitor($nodeVisitor); } diff --git a/src/NodeVisitor/DependencyInjection/AddPropertiesToClassNodeVisitor.php b/src/NodeVisitor/DependencyInjection/AddPropertiesToClassNodeVisitor.php index c52b38091c1..1dd89f29c92 100644 --- a/src/NodeVisitor/DependencyInjection/AddPropertiesToClassNodeVisitor.php +++ b/src/NodeVisitor/DependencyInjection/AddPropertiesToClassNodeVisitor.php @@ -70,8 +70,6 @@ final class AddPropertiesToClassNodeVisitor extends NodeVisitorAbstract { $propertiesForClass = $this->newClassPropertyCollector->getPropertiesforClass($className); - dump($propertiesForClass); - foreach ($propertiesForClass as $propertyType => $propertyName) { $this->constructorMethodBuilder->addPropertyAssignToClass($classNode, $propertyType, $propertyName); $this->propertyBuilder->addPropertyToClass($classNode, $propertyType, $propertyName); diff --git a/src/NodeVisitor/DependencyInjection/InjectAnnotationToConstructor/PropertyRector.php b/src/NodeVisitor/DependencyInjection/InjectAnnotationToConstructor/PropertyRector.php index a8b6ed60b59..0d4e9bde0cd 100644 --- a/src/NodeVisitor/DependencyInjection/InjectAnnotationToConstructor/PropertyRector.php +++ b/src/NodeVisitor/DependencyInjection/InjectAnnotationToConstructor/PropertyRector.php @@ -45,6 +45,8 @@ final class PropertyRector extends NodeVisitorAbstract */ public function beforeTraverse(array $nodes): ?array { + $this->className = null; + foreach ($nodes as $node) { if ($node instanceof Class_) { $this->className = (string) $node->name; diff --git a/src/NodeVisitor/DependencyInjection/NamedServicesToConstructor/GetterToPropertyRector.php b/src/NodeVisitor/DependencyInjection/NamedServicesToConstructor/GetterToPropertyRector.php index 45e323be49e..2ede1dc2689 100644 --- a/src/NodeVisitor/DependencyInjection/NamedServicesToConstructor/GetterToPropertyRector.php +++ b/src/NodeVisitor/DependencyInjection/NamedServicesToConstructor/GetterToPropertyRector.php @@ -60,6 +60,8 @@ final class GetterToPropertyRector extends NodeVisitorAbstract */ public function beforeTraverse(array $nodes): ?array { + $this->className = null; + foreach ($nodes as $node) { if ($node instanceof Class_) { $this->className = (string) $node->name; diff --git a/src/NodeVisitor/Traverse/NodeConnectorNodeVisitor.php b/src/NodeVisitor/Traverse/NodeConnectorNodeVisitor.php new file mode 100644 index 00000000000..ce9b30d935e --- /dev/null +++ b/src/NodeVisitor/Traverse/NodeConnectorNodeVisitor.php @@ -0,0 +1,45 @@ +stack = []; + $this->prev = null; + } + + public function enterNode(Node $node): void + { + if (! empty($this->stack)) { + $node->setAttribute('parent', $this->stack[count($this->stack)-1]); + } + + if ($this->prev && $this->prev->getAttribute('parent') === $node->getAttribute('parent')) { + $node->setAttribute('prev', $this->prev); + $this->prev->setAttribute('next', $node); + } + + $this->stack[] = $node; + } + + public function leaveNode(Node $node): void + { + $this->prev = $node; + array_pop($this->stack); + } +} diff --git a/src/NodeVisitor/Traverse/ParentConnectorNodeVisitor.php b/src/NodeVisitor/Traverse/ParentConnectorNodeVisitor.php new file mode 100644 index 00000000000..e9dbc37750b --- /dev/null +++ b/src/NodeVisitor/Traverse/ParentConnectorNodeVisitor.php @@ -0,0 +1,33 @@ +stack = []; + } + + public function enterNode(Node $node): void + { + if (! empty($this->stack)) { + $node->setAttribute('parent', $this->stack[count($this->stack)-1]); + } + + $this->stack[] = $node; + } + + public function leaveNode(Node $node): void + { + array_pop($this->stack); + } +} diff --git a/src/Printer/FormatPerservingPrinter.php b/src/Printer/FormatPerservingPrinter.php index 8b046b22298..ca6a78676e3 100644 --- a/src/Printer/FormatPerservingPrinter.php +++ b/src/Printer/FormatPerservingPrinter.php @@ -4,7 +4,6 @@ namespace Rector\Printer; use PhpParser\PrettyPrinter\Standard; use SplFileInfo; -use Tracy\Debugger; final class FormatPerservingPrinter { diff --git a/tests/NodeVisitor/DependencyInjection/InjectAnnotationToConstructorRector/correct/correct.php.inc b/tests/NodeVisitor/DependencyInjection/InjectAnnotationToConstructorRector/correct/correct.php.inc index 57ec4a63833..19ed81e6394 100644 --- a/tests/NodeVisitor/DependencyInjection/InjectAnnotationToConstructorRector/correct/correct.php.inc +++ b/tests/NodeVisitor/DependencyInjection/InjectAnnotationToConstructorRector/correct/correct.php.inc @@ -6,12 +6,10 @@ class ClassWithInjects * @var stdClass */ private $property; - /** * @var DateTimeInterface */ private $otherProperty; - public function __construct(stdClass $property, DateTimeInterface $otherProperty) { $this->property = $property;