rector/src/Rector/Dynamic/MethodNameReplacerRector.php

133 lines
3.1 KiB
PHP
Raw Normal View History

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;
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
* ]
*
* or (typically for static calls):
*
* class => [
* oldMethod => [
* newClass, newMethod
* ]
* ]
*
2017-10-06 11:57:21 +00:00
* @var string[][]
*/
private $perClassOldToNewMethods = [];
/**
* @var string|null
*/
private $activeType;
/**
* @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-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;
$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) {
$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) {
$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;
}
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 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);
}
/**
* @param mixed[] $oldToNewMethods
*/
private function isClassRename(array $oldToNewMethods): bool
{
$firstMethodConfiguration = current($oldToNewMethods);
return is_array($firstMethodConfiguration);
}
2017-10-06 11:57:21 +00:00
}