2017-10-06 11:57:21 +00:00
|
|
|
<?php declare(strict_types=1);
|
|
|
|
|
|
|
|
namespace Rector\Rector\Dynamic;
|
|
|
|
|
|
|
|
use PhpParser\Node;
|
|
|
|
use PhpParser\Node\Expr\MethodCall;
|
|
|
|
use PhpParser\Node\Expr\StaticCall;
|
|
|
|
use PhpParser\Node\Name;
|
2017-10-20 16:16:52 +00:00
|
|
|
use Rector\NodeAnalyzer\MethodCallAnalyzer;
|
2017-10-20 16:23:59 +00:00
|
|
|
use Rector\NodeAnalyzer\StaticMethodCallAnalyzer;
|
2017-10-06 11:57:21 +00:00
|
|
|
use Rector\Rector\AbstractRector;
|
|
|
|
|
|
|
|
final class MethodNameReplacerRector extends AbstractRector
|
|
|
|
{
|
|
|
|
/**
|
|
|
|
* class => [
|
|
|
|
* oldMethod => newMethod
|
|
|
|
* ]
|
|
|
|
*
|
2017-10-20 15:54:20 +00:00
|
|
|
* or (typically for static calls):
|
|
|
|
*
|
|
|
|
* class => [
|
|
|
|
* oldMethod => [
|
|
|
|
* newClass, newMethod
|
|
|
|
* ]
|
|
|
|
* ]
|
|
|
|
*
|
2017-10-06 11:57:21 +00:00
|
|
|
* @var string[][]
|
|
|
|
*/
|
|
|
|
private $perClassOldToNewMethods = [];
|
|
|
|
|
2017-10-06 12:07:13 +00:00
|
|
|
/**
|
|
|
|
* @var string|null
|
|
|
|
*/
|
|
|
|
private $activeType;
|
|
|
|
|
2017-10-20 16:16:52 +00:00
|
|
|
/**
|
|
|
|
* @var MethodCallAnalyzer
|
|
|
|
*/
|
|
|
|
private $methodCallAnalyzer;
|
2017-10-20 16:25:47 +00:00
|
|
|
|
2017-10-20 16:23:59 +00:00
|
|
|
/**
|
|
|
|
* @var StaticMethodCallAnalyzer
|
|
|
|
*/
|
|
|
|
private $staticMethodCallAnalyzer;
|
2017-10-20 16:16:52 +00:00
|
|
|
|
2017-10-06 11:57:21 +00:00
|
|
|
/**
|
|
|
|
* @param string[][]
|
|
|
|
*/
|
2017-10-20 16:23:59 +00:00
|
|
|
public function __construct(
|
|
|
|
array $perClassOldToNewMethods,
|
|
|
|
MethodCallAnalyzer $methodCallAnalyzer,
|
|
|
|
StaticMethodCallAnalyzer $staticMethodCallAnalyzer
|
|
|
|
) {
|
2017-10-06 11:57:21 +00:00
|
|
|
$this->perClassOldToNewMethods = $perClassOldToNewMethods;
|
2017-10-20 16:16:52 +00:00
|
|
|
$this->methodCallAnalyzer = $methodCallAnalyzer;
|
2017-10-20 16:23:59 +00:00
|
|
|
$this->staticMethodCallAnalyzer = $staticMethodCallAnalyzer;
|
2017-10-06 11:57:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public function isCandidate(Node $node): bool
|
|
|
|
{
|
|
|
|
$this->activeType = null;
|
|
|
|
|
2017-10-20 16:33:21 +00:00
|
|
|
$matchedType = $this->methodCallAnalyzer->matchTypes($node, $this->getClasses());
|
2017-10-20 16:59:24 +00:00
|
|
|
if ($matchedType) {
|
2017-10-20 16:16:52 +00:00
|
|
|
$this->activeType = $matchedType;
|
|
|
|
|
2017-10-06 11:57:21 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2017-10-20 16:33:21 +00:00
|
|
|
$matchedType = $this->staticMethodCallAnalyzer->matchTypes($node, $this->getClasses());
|
2017-10-20 16:59:24 +00:00
|
|
|
if ($matchedType) {
|
2017-10-20 16:16:52 +00:00
|
|
|
$this->activeType = $matchedType;
|
|
|
|
|
2017-10-06 11:57:21 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param StaticCall|MethodCall $node
|
|
|
|
*/
|
|
|
|
public function refactor(Node $node): ?Node
|
|
|
|
{
|
|
|
|
$oldToNewMethods = $this->perClassOldToNewMethods[$this->activeType];
|
|
|
|
|
2017-10-20 15:57:24 +00:00
|
|
|
$methodName = $node->name->name;
|
|
|
|
|
2017-10-20 16:59:24 +00:00
|
|
|
if (! isset($oldToNewMethods[$methodName])) {
|
|
|
|
return $node;
|
|
|
|
}
|
|
|
|
|
2017-10-20 15:54:20 +00:00
|
|
|
if ($this->isClassRename($oldToNewMethods)) {
|
2017-10-20 15:57:24 +00:00
|
|
|
[$newClass, $newMethod] = $oldToNewMethods[$methodName];
|
|
|
|
|
|
|
|
$node->class = new Name($newClass);
|
|
|
|
$node->name->name = $newMethod;
|
2017-10-06 11:57:21 +00:00
|
|
|
|
2017-10-20 16:59:24 +00:00
|
|
|
return $node;
|
|
|
|
}
|
|
|
|
|
|
|
|
// is only method rename
|
|
|
|
foreach ($oldToNewMethods as $oldMethod => $newMethod) {
|
|
|
|
if ($methodName !== $oldMethod) {
|
|
|
|
continue;
|
2017-10-20 15:54:20 +00:00
|
|
|
}
|
2017-10-20 16:59:24 +00:00
|
|
|
|
|
|
|
$node->name->name = $newMethod;
|
2017-10-06 11:57:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return $node;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return string[]
|
|
|
|
*/
|
|
|
|
private function getClasses(): array
|
|
|
|
{
|
|
|
|
return array_keys($this->perClassOldToNewMethods);
|
|
|
|
}
|
2017-10-20 15:54:20 +00:00
|
|
|
|
2017-10-20 16:16:52 +00:00
|
|
|
/**
|
|
|
|
* @param mixed[] $oldToNewMethods
|
|
|
|
*/
|
2017-10-20 15:54:20 +00:00
|
|
|
private function isClassRename(array $oldToNewMethods): bool
|
|
|
|
{
|
|
|
|
$firstMethodConfiguration = current($oldToNewMethods);
|
|
|
|
|
|
|
|
return is_array($firstMethodConfiguration);
|
|
|
|
}
|
2017-10-06 11:57:21 +00:00
|
|
|
}
|