From d81801447767228b814f17794f64a2d2f487c102 Mon Sep 17 00:00:00 2001 From: TomasVotruba Date: Sun, 6 Aug 2017 23:24:58 +0200 Subject: [PATCH] StatementGlue added --- src/Builder/ConstructorMethodBuilder.php | 28 +++------ src/Builder/PropertyBuilder.php | 41 +++--------- src/Builder/StatementGlue.php | 63 +++++++++++++++++++ ...eprecatedParentClassToTraitNodeVisitor.php | 23 ++++++- .../Test.php | 8 ++- 5 files changed, 105 insertions(+), 58 deletions(-) create mode 100644 src/Builder/StatementGlue.php diff --git a/src/Builder/ConstructorMethodBuilder.php b/src/Builder/ConstructorMethodBuilder.php index 1f4ddd8a6fe..e6e3660d1d1 100644 --- a/src/Builder/ConstructorMethodBuilder.php +++ b/src/Builder/ConstructorMethodBuilder.php @@ -2,7 +2,6 @@ namespace Rector\Builder; -use Nette\Utils\Arrays; use PhpParser\Builder\Method; use PhpParser\Builder\Param; use PhpParser\BuilderFactory; @@ -23,10 +22,16 @@ final class ConstructorMethodBuilder */ private $builderFactory; - public function __construct(Parser $parser, BuilderFactory $builderFactory) + /** + * @var StatementGlue + */ + private $statementGlue; + + public function __construct(Parser $parser, BuilderFactory $builderFactory, StatementGlue $statementGlue) { $this->parser = $parser; $this->builderFactory = $builderFactory; + $this->statementGlue = $statementGlue; } public function addPropertyAssignToClass(Class_ $classNode, string $propertyType, string $propertyName): void @@ -50,7 +55,7 @@ final class ConstructorMethodBuilder ->addParam($this->createParameter($propertyType, $propertyName)) ->addStmts($assign); - $this->addAsFirstMethod($classNode, $constructorMethod->getNode()); + $this->statementGlue->addAsFirstMethod($classNode, $constructorMethod->getNode()); } private function createParameter(string $propertyType, string $propertyName): Param @@ -70,21 +75,4 @@ final class ConstructorMethodBuilder $propertyName )); } - - private function addAsFirstMethod(Class_ $classNode, ClassMethod $constructorMethod): void - { - foreach ($classNode->stmts as $key => $classElementNode) { - if ($classElementNode instanceof ClassMethod) { - Arrays::insertBefore( - $classNode->stmts, - $key, - ['before_' . $key => $constructorMethod] - ); - - return; - } - } - - $classNode->stmts[] = $constructorMethod; - } } diff --git a/src/Builder/PropertyBuilder.php b/src/Builder/PropertyBuilder.php index f0f92634551..a0237e9b53a 100644 --- a/src/Builder/PropertyBuilder.php +++ b/src/Builder/PropertyBuilder.php @@ -2,11 +2,9 @@ namespace Rector\Builder; -use Nette\Utils\Arrays; use PhpParser\BuilderFactory; use PhpParser\Comment\Doc; use PhpParser\Node\Stmt\Class_; -use PhpParser\Node\Stmt\ClassMethod; use PhpParser\Node\Stmt\Property; final class PropertyBuilder @@ -16,45 +14,22 @@ final class PropertyBuilder */ private $builderFactory; - public function __construct(BuilderFactory $builderFactory) + /** + * @var StatementGlue + */ + private $statementGlue; + + public function __construct(BuilderFactory $builderFactory, StatementGlue $statementGlue) { $this->builderFactory = $builderFactory; + $this->statementGlue = $statementGlue; } public function addPropertyToClass(Class_ $classNode, string $propertyType, string $propertyName): void { $propertyNode = $this->buildPrivatePropertyNode($propertyType, $propertyName); - // add before first method - foreach ($classNode->stmts as $key => $classElementNode) { - if ($classElementNode instanceof ClassMethod) { - Arrays::insertBefore( - $classNode->stmts, - $key, - ['before_' . $key => $propertyNode] - ); - - return; - } - } - - // or after last property - $previousElement = null; - foreach ($classNode->stmts as $key => $classElementNode) { - if ($previousElement instanceof Property && ! $classElementNode instanceof Property) { - Arrays::insertBefore( - $classNode->stmts, - $key, - ['before_' . $key => $propertyNode] - ); - - return; - } - - $previousElement = $classElementNode; - } - - $classNode->stmts[] = $propertyNode; + $this->statementGlue->addAsFirstMethod($classNode, $propertyNode); } private function buildPrivatePropertyNode(string $propertyType, string $propertyName): Property diff --git a/src/Builder/StatementGlue.php b/src/Builder/StatementGlue.php new file mode 100644 index 00000000000..56979223555 --- /dev/null +++ b/src/Builder/StatementGlue.php @@ -0,0 +1,63 @@ +stmts as $key => $classElementNode) { + if ($classElementNode instanceof ClassMethod) { + $this->insertBefore($classNode, $node, $key); + + return; + } + } + + $previousElement = null; + foreach ($classNode->stmts as $key => $classElementNode) { + if ($previousElement instanceof Property && ! $classElementNode instanceof Property) { + $this->insertBefore($classNode, $node, $key); + + return; + } + + $previousElement = $classElementNode; + } + + $classNode->stmts[] = $node; + } + + public function addAsFirstTrait(Class_ $classNode, TraitUse $traitUse): void + { + foreach ($classNode->stmts as $key => $classElementNode) { + if ($classElementNode instanceof TraitUse) { + $this->insertBefore($classNode, $traitUse, $key); + + return; + } + } + + $classNode->stmts[] = $traitUse; + } + + /** + * @param int|string $key + */ + private function insertBefore(Class_ $classNode, Node $node, $key): void + { + Arrays::insertBefore($classNode->stmts, $key, [ + 'before_' . $key => $node + ]); + } +} diff --git a/src/NodeVisitor/UpgradeDeprecation/DeprecatedParentClassToTraitNodeVisitor.php b/src/NodeVisitor/UpgradeDeprecation/DeprecatedParentClassToTraitNodeVisitor.php index 2a4c9c214e1..2b791e3558d 100644 --- a/src/NodeVisitor/UpgradeDeprecation/DeprecatedParentClassToTraitNodeVisitor.php +++ b/src/NodeVisitor/UpgradeDeprecation/DeprecatedParentClassToTraitNodeVisitor.php @@ -8,12 +8,23 @@ use PhpParser\Node\Stmt\Class_; use PhpParser\Node\Stmt\TraitUse; use PhpParser\NodeTraverser; use PhpParser\NodeVisitorAbstract; +use Rector\Builder\StatementGlue; /** * Reflects @link https://doc.nette.org/en/2.4/migration-2-4#toc-nette-smartobject */ final class DeprecatedParentClassToTraitNodeVisitor extends NodeVisitorAbstract { + /** + * @var StatementGlue + */ + private $statementGlue; + + public function __construct(StatementGlue $statementGlue) + { + $this->statementGlue = $statementGlue; + } + public function getParentClassName(): string { return 'Nette\Object'; @@ -57,9 +68,15 @@ final class DeprecatedParentClassToTraitNodeVisitor extends NodeVisitorAbstract // remove parent class $classNode->extends = null; - // add new trait - $nameParts = explode('\\', $this->getTraitName()); - $classNode->stmts[] = new TraitUse([ + $traitUseNode = $this->createTraitUse($this->getTraitName()); + $this->statementGlue->addAsFirstTrait($classNode, $traitUseNode); + } + + private function createTraitUse(string $traitName): TraitUse + { + $nameParts = explode('\\', $traitName); + + return new TraitUse([ new FullyQualified($nameParts) ]); } diff --git a/tests/NodeVisitor/UpgradeDeprecation/DeprecatedParentClassToTraitNodeVisitor/Test.php b/tests/NodeVisitor/UpgradeDeprecation/DeprecatedParentClassToTraitNodeVisitor/Test.php index a7a8f29ac9a..1fbe121cd97 100644 --- a/tests/NodeVisitor/UpgradeDeprecation/DeprecatedParentClassToTraitNodeVisitor/Test.php +++ b/tests/NodeVisitor/UpgradeDeprecation/DeprecatedParentClassToTraitNodeVisitor/Test.php @@ -8,9 +8,13 @@ final class Test extends AbstractReconstructorTestCase { public function test(): void { + // $this->doTestFileMatchesExpectedContent( + // __DIR__ . '/wrong/wrong.php.inc', + // __DIR__ . '/correct/correct.php.inc' + // ); $this->doTestFileMatchesExpectedContent( - __DIR__ . '/wrong/wrong.php.inc', - __DIR__ . '/correct/correct.php.inc' + __DIR__ . '/wrong/wrong2.php.inc', + __DIR__ . '/correct/correct2.php.inc' ); } }