2020-05-03 23:40:28 +02:00
|
|
|
<?php
|
|
|
|
|
|
|
|
declare(strict_types=1);
|
|
|
|
|
|
|
|
namespace Rector\Order;
|
|
|
|
|
2021-03-21 19:41:17 +01:00
|
|
|
use PhpParser\Node;
|
2020-08-07 18:23:40 +02:00
|
|
|
use PhpParser\Node\Stmt\ClassLike;
|
2020-08-09 19:21:31 +02:00
|
|
|
use Rector\NodeNameResolver\NodeNameResolver;
|
2020-05-03 23:40:28 +02:00
|
|
|
|
2020-09-01 19:56:30 +02:00
|
|
|
/**
|
2021-03-12 23:20:25 +01:00
|
|
|
* @see \Rector\Tests\Order\StmtOrderTest
|
2020-09-01 19:56:30 +02:00
|
|
|
*/
|
2020-05-03 23:40:28 +02:00
|
|
|
final class StmtOrder
|
|
|
|
{
|
|
|
|
/**
|
2020-08-09 19:21:31 +02:00
|
|
|
* @var NodeNameResolver
|
|
|
|
*/
|
|
|
|
private $nodeNameResolver;
|
|
|
|
|
|
|
|
public function __construct(NodeNameResolver $nodeNameResolver)
|
|
|
|
{
|
|
|
|
$this->nodeNameResolver = $nodeNameResolver;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2020-08-11 12:59:04 +02:00
|
|
|
* @param array<int, string> $desiredStmtOrder
|
|
|
|
* @param array<int, string> $currentStmtOrder
|
|
|
|
* @return array<int, int>
|
2020-05-03 23:40:28 +02:00
|
|
|
*/
|
|
|
|
public function createOldToNewKeys(array $desiredStmtOrder, array $currentStmtOrder): array
|
|
|
|
{
|
|
|
|
$newKeys = [];
|
2021-03-05 17:55:40 +07:00
|
|
|
foreach ($desiredStmtOrder as $singleDesiredStmtOrder) {
|
2020-05-03 23:40:28 +02:00
|
|
|
foreach ($currentStmtOrder as $currentKey => $classMethodName) {
|
2021-03-05 17:55:40 +07:00
|
|
|
if ($classMethodName === $singleDesiredStmtOrder) {
|
2020-05-03 23:40:28 +02:00
|
|
|
$newKeys[] = $currentKey;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
$oldKeys = array_values($newKeys);
|
|
|
|
sort($oldKeys);
|
|
|
|
|
2020-08-11 12:59:04 +02:00
|
|
|
/** @var array<int, int> $oldToNewKeys */
|
|
|
|
$oldToNewKeys = array_combine($oldKeys, $newKeys);
|
|
|
|
|
|
|
|
return $oldToNewKeys;
|
2020-05-03 23:40:28 +02:00
|
|
|
}
|
|
|
|
|
2020-08-09 19:21:31 +02:00
|
|
|
/**
|
2020-08-11 12:59:04 +02:00
|
|
|
* @param array<int, int> $oldToNewKeys
|
2020-08-09 19:21:31 +02:00
|
|
|
*/
|
2021-03-14 14:11:24 +01:00
|
|
|
public function reorderClassStmtsByOldToNewKeys(ClassLike $classLike, array $oldToNewKeys): void
|
2020-05-03 23:40:28 +02:00
|
|
|
{
|
2020-05-04 01:42:56 +02:00
|
|
|
$reorderedStmts = [];
|
|
|
|
|
2020-12-25 01:22:45 +01:00
|
|
|
$stmtCount = count($classLike->stmts);
|
2020-05-04 01:42:56 +02:00
|
|
|
|
2020-08-07 18:23:40 +02:00
|
|
|
foreach ($classLike->stmts as $key => $stmt) {
|
2020-05-04 01:42:56 +02:00
|
|
|
if (! array_key_exists($key, $oldToNewKeys)) {
|
|
|
|
$reorderedStmts[$key] = $stmt;
|
2020-05-03 23:40:28 +02:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
// reorder here
|
|
|
|
$newKey = $oldToNewKeys[$key];
|
2020-05-04 01:42:56 +02:00
|
|
|
|
2020-08-07 18:23:40 +02:00
|
|
|
$reorderedStmts[$key] = $classLike->stmts[$newKey];
|
2020-05-04 01:42:56 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
for ($i = 0; $i < $stmtCount; ++$i) {
|
|
|
|
if (! array_key_exists($i, $reorderedStmts)) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2020-08-07 18:23:40 +02:00
|
|
|
$classLike->stmts[$i] = $reorderedStmts[$i];
|
2020-05-03 23:40:28 +02:00
|
|
|
}
|
|
|
|
}
|
2020-08-08 00:21:17 +02:00
|
|
|
|
|
|
|
/**
|
2021-03-21 19:41:17 +01:00
|
|
|
* @param class-string<Node> $type
|
2021-01-20 00:29:52 +01:00
|
|
|
* @return array<int, string>
|
2020-08-08 00:21:17 +02:00
|
|
|
*/
|
2020-08-09 19:21:31 +02:00
|
|
|
public function getStmtsOfTypeOrder(ClassLike $classLike, string $type): array
|
2020-08-08 00:21:17 +02:00
|
|
|
{
|
2020-08-09 19:21:31 +02:00
|
|
|
$stmtsByPosition = [];
|
|
|
|
foreach ($classLike->stmts as $position => $classStmt) {
|
|
|
|
if (! is_a($classStmt, $type)) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
$name = $this->nodeNameResolver->getName($classStmt);
|
|
|
|
if ($name === null) {
|
|
|
|
continue;
|
|
|
|
}
|
2020-08-08 00:21:17 +02:00
|
|
|
|
2020-08-09 19:21:31 +02:00
|
|
|
$stmtsByPosition[$position] = $name;
|
2020-08-08 00:21:17 +02:00
|
|
|
}
|
|
|
|
|
2020-08-09 19:21:31 +02:00
|
|
|
return $stmtsByPosition;
|
2020-08-08 00:21:17 +02:00
|
|
|
}
|
2020-05-03 23:40:28 +02:00
|
|
|
}
|