StatementGlue added

This commit is contained in:
TomasVotruba 2017-08-06 23:24:58 +02:00
parent 5d7c589533
commit d818014477
5 changed files with 105 additions and 58 deletions

View File

@ -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;
}
}

View File

@ -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

View File

@ -0,0 +1,63 @@
<?php declare(strict_types=1);
namespace Rector\Builder;
use Nette\Utils\Arrays;
use PhpParser\Node;
use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Property;
use PhpParser\Node\Stmt\TraitUse;
final class StatementGlue
{
/**
* @param ClassMethod|Property $node
*/
public function addAsFirstMethod(Class_ $classNode, Node $node): void
{
foreach ($classNode->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
]);
}
}

View File

@ -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)
]);
}

View File

@ -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'
);
}
}