mirror of
https://github.com/rectorphp/rector.git
synced 2024-06-05 10:50:48 +00:00
StatementGlue added
This commit is contained in:
parent
5d7c589533
commit
d818014477
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
namespace Rector\Builder;
|
namespace Rector\Builder;
|
||||||
|
|
||||||
use Nette\Utils\Arrays;
|
|
||||||
use PhpParser\Builder\Method;
|
use PhpParser\Builder\Method;
|
||||||
use PhpParser\Builder\Param;
|
use PhpParser\Builder\Param;
|
||||||
use PhpParser\BuilderFactory;
|
use PhpParser\BuilderFactory;
|
||||||
|
@ -23,10 +22,16 @@ final class ConstructorMethodBuilder
|
||||||
*/
|
*/
|
||||||
private $builderFactory;
|
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->parser = $parser;
|
||||||
$this->builderFactory = $builderFactory;
|
$this->builderFactory = $builderFactory;
|
||||||
|
$this->statementGlue = $statementGlue;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function addPropertyAssignToClass(Class_ $classNode, string $propertyType, string $propertyName): void
|
public function addPropertyAssignToClass(Class_ $classNode, string $propertyType, string $propertyName): void
|
||||||
|
@ -50,7 +55,7 @@ final class ConstructorMethodBuilder
|
||||||
->addParam($this->createParameter($propertyType, $propertyName))
|
->addParam($this->createParameter($propertyType, $propertyName))
|
||||||
->addStmts($assign);
|
->addStmts($assign);
|
||||||
|
|
||||||
$this->addAsFirstMethod($classNode, $constructorMethod->getNode());
|
$this->statementGlue->addAsFirstMethod($classNode, $constructorMethod->getNode());
|
||||||
}
|
}
|
||||||
|
|
||||||
private function createParameter(string $propertyType, string $propertyName): Param
|
private function createParameter(string $propertyType, string $propertyName): Param
|
||||||
|
@ -70,21 +75,4 @@ final class ConstructorMethodBuilder
|
||||||
$propertyName
|
$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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,11 +2,9 @@
|
||||||
|
|
||||||
namespace Rector\Builder;
|
namespace Rector\Builder;
|
||||||
|
|
||||||
use Nette\Utils\Arrays;
|
|
||||||
use PhpParser\BuilderFactory;
|
use PhpParser\BuilderFactory;
|
||||||
use PhpParser\Comment\Doc;
|
use PhpParser\Comment\Doc;
|
||||||
use PhpParser\Node\Stmt\Class_;
|
use PhpParser\Node\Stmt\Class_;
|
||||||
use PhpParser\Node\Stmt\ClassMethod;
|
|
||||||
use PhpParser\Node\Stmt\Property;
|
use PhpParser\Node\Stmt\Property;
|
||||||
|
|
||||||
final class PropertyBuilder
|
final class PropertyBuilder
|
||||||
|
@ -16,45 +14,22 @@ final class PropertyBuilder
|
||||||
*/
|
*/
|
||||||
private $builderFactory;
|
private $builderFactory;
|
||||||
|
|
||||||
public function __construct(BuilderFactory $builderFactory)
|
/**
|
||||||
|
* @var StatementGlue
|
||||||
|
*/
|
||||||
|
private $statementGlue;
|
||||||
|
|
||||||
|
public function __construct(BuilderFactory $builderFactory, StatementGlue $statementGlue)
|
||||||
{
|
{
|
||||||
$this->builderFactory = $builderFactory;
|
$this->builderFactory = $builderFactory;
|
||||||
|
$this->statementGlue = $statementGlue;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function addPropertyToClass(Class_ $classNode, string $propertyType, string $propertyName): void
|
public function addPropertyToClass(Class_ $classNode, string $propertyType, string $propertyName): void
|
||||||
{
|
{
|
||||||
$propertyNode = $this->buildPrivatePropertyNode($propertyType, $propertyName);
|
$propertyNode = $this->buildPrivatePropertyNode($propertyType, $propertyName);
|
||||||
|
|
||||||
// add before first method
|
$this->statementGlue->addAsFirstMethod($classNode, $propertyNode);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function buildPrivatePropertyNode(string $propertyType, string $propertyName): Property
|
private function buildPrivatePropertyNode(string $propertyType, string $propertyName): Property
|
||||||
|
|
63
src/Builder/StatementGlue.php
Normal file
63
src/Builder/StatementGlue.php
Normal 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
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,12 +8,23 @@ use PhpParser\Node\Stmt\Class_;
|
||||||
use PhpParser\Node\Stmt\TraitUse;
|
use PhpParser\Node\Stmt\TraitUse;
|
||||||
use PhpParser\NodeTraverser;
|
use PhpParser\NodeTraverser;
|
||||||
use PhpParser\NodeVisitorAbstract;
|
use PhpParser\NodeVisitorAbstract;
|
||||||
|
use Rector\Builder\StatementGlue;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reflects @link https://doc.nette.org/en/2.4/migration-2-4#toc-nette-smartobject
|
* Reflects @link https://doc.nette.org/en/2.4/migration-2-4#toc-nette-smartobject
|
||||||
*/
|
*/
|
||||||
final class DeprecatedParentClassToTraitNodeVisitor extends NodeVisitorAbstract
|
final class DeprecatedParentClassToTraitNodeVisitor extends NodeVisitorAbstract
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @var StatementGlue
|
||||||
|
*/
|
||||||
|
private $statementGlue;
|
||||||
|
|
||||||
|
public function __construct(StatementGlue $statementGlue)
|
||||||
|
{
|
||||||
|
$this->statementGlue = $statementGlue;
|
||||||
|
}
|
||||||
|
|
||||||
public function getParentClassName(): string
|
public function getParentClassName(): string
|
||||||
{
|
{
|
||||||
return 'Nette\Object';
|
return 'Nette\Object';
|
||||||
|
@ -57,9 +68,15 @@ final class DeprecatedParentClassToTraitNodeVisitor extends NodeVisitorAbstract
|
||||||
// remove parent class
|
// remove parent class
|
||||||
$classNode->extends = null;
|
$classNode->extends = null;
|
||||||
|
|
||||||
// add new trait
|
$traitUseNode = $this->createTraitUse($this->getTraitName());
|
||||||
$nameParts = explode('\\', $this->getTraitName());
|
$this->statementGlue->addAsFirstTrait($classNode, $traitUseNode);
|
||||||
$classNode->stmts[] = new TraitUse([
|
}
|
||||||
|
|
||||||
|
private function createTraitUse(string $traitName): TraitUse
|
||||||
|
{
|
||||||
|
$nameParts = explode('\\', $traitName);
|
||||||
|
|
||||||
|
return new TraitUse([
|
||||||
new FullyQualified($nameParts)
|
new FullyQualified($nameParts)
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,9 +8,13 @@ final class Test extends AbstractReconstructorTestCase
|
||||||
{
|
{
|
||||||
public function test(): void
|
public function test(): void
|
||||||
{
|
{
|
||||||
|
// $this->doTestFileMatchesExpectedContent(
|
||||||
|
// __DIR__ . '/wrong/wrong.php.inc',
|
||||||
|
// __DIR__ . '/correct/correct.php.inc'
|
||||||
|
// );
|
||||||
$this->doTestFileMatchesExpectedContent(
|
$this->doTestFileMatchesExpectedContent(
|
||||||
__DIR__ . '/wrong/wrong.php.inc',
|
__DIR__ . '/wrong/wrong2.php.inc',
|
||||||
__DIR__ . '/correct/correct.php.inc'
|
__DIR__ . '/correct/correct2.php.inc'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user