2017-11-18 15:20:10 +00:00
|
|
|
<?php declare(strict_types=1);
|
|
|
|
|
|
|
|
namespace Rector\Rector\Dynamic;
|
|
|
|
|
|
|
|
use PhpParser\Node;
|
2017-11-18 15:48:20 +00:00
|
|
|
use PhpParser\Node\Expr\Assign;
|
2017-11-18 15:20:10 +00:00
|
|
|
use PhpParser\Node\Expr\MethodCall;
|
|
|
|
use PhpParser\Node\Expr\PropertyFetch;
|
2017-12-10 00:13:25 +00:00
|
|
|
use PhpParser\Node\Identifier;
|
2017-12-27 16:26:02 +00:00
|
|
|
use Rector\Node\NodeFactory;
|
2017-11-18 15:20:10 +00:00
|
|
|
use Rector\NodeAnalyzer\PropertyFetchAnalyzer;
|
|
|
|
use Rector\Rector\AbstractRector;
|
|
|
|
|
2017-11-18 15:48:20 +00:00
|
|
|
/**
|
|
|
|
* Example - from:
|
|
|
|
* - $result = $object->property;
|
|
|
|
* - $object->property = $value;
|
|
|
|
*
|
|
|
|
* To
|
|
|
|
* - $result = $object->getProperty();
|
|
|
|
* - $object->setProperty($value);
|
|
|
|
*/
|
2017-11-18 15:20:10 +00:00
|
|
|
final class PropertyToMethodRector extends AbstractRector
|
|
|
|
{
|
|
|
|
/**
|
|
|
|
* class => [
|
|
|
|
* property => [getMethod, setMethod]
|
|
|
|
* ]
|
|
|
|
*
|
|
|
|
* @var string[][][]
|
|
|
|
*/
|
|
|
|
private $perClassPropertyToMethods = [];
|
|
|
|
|
|
|
|
/**
|
2017-11-18 15:48:20 +00:00
|
|
|
* @var string
|
2017-11-18 15:20:10 +00:00
|
|
|
*/
|
2017-11-18 15:48:20 +00:00
|
|
|
private $activeMethod;
|
2017-11-18 15:20:10 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @var PropertyFetchAnalyzer
|
|
|
|
*/
|
|
|
|
private $propertyFetchAnalyzer;
|
|
|
|
|
2017-12-27 16:26:02 +00:00
|
|
|
/**
|
|
|
|
* @var NodeFactory
|
|
|
|
*/
|
|
|
|
private $nodeFactory;
|
|
|
|
|
2017-11-18 15:20:10 +00:00
|
|
|
/**
|
2017-12-09 20:58:33 +00:00
|
|
|
* @param string[][][] $perClassOldToNewProperties
|
2017-11-18 15:20:10 +00:00
|
|
|
*/
|
2017-12-27 16:26:02 +00:00
|
|
|
public function __construct(
|
|
|
|
array $perClassOldToNewProperties,
|
|
|
|
PropertyFetchAnalyzer $propertyFetchAnalyzer,
|
|
|
|
NodeFactory $nodeFactory
|
|
|
|
) {
|
2017-11-18 15:20:10 +00:00
|
|
|
$this->perClassPropertyToMethods = $perClassOldToNewProperties;
|
|
|
|
$this->propertyFetchAnalyzer = $propertyFetchAnalyzer;
|
2017-12-27 16:26:02 +00:00
|
|
|
$this->nodeFactory = $nodeFactory;
|
2017-11-18 15:20:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public function isCandidate(Node $node): bool
|
|
|
|
{
|
2017-11-18 15:48:20 +00:00
|
|
|
if (! $node instanceof Assign) {
|
2017-11-18 15:20:10 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2017-11-18 15:48:20 +00:00
|
|
|
// setter
|
|
|
|
if ($node->var instanceof PropertyFetch) {
|
|
|
|
return $this->processPropertyFetchCandidate($node->var, 'set');
|
|
|
|
}
|
2017-11-18 15:20:10 +00:00
|
|
|
|
2017-11-18 15:48:20 +00:00
|
|
|
// getter
|
|
|
|
if ($node->expr instanceof PropertyFetch) {
|
|
|
|
return $this->processPropertyFetchCandidate($node->expr, 'get');
|
2017-11-18 15:20:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2017-11-18 15:48:20 +00:00
|
|
|
* @param Assign $assignNode
|
2017-11-18 15:20:10 +00:00
|
|
|
*/
|
2017-11-18 15:48:20 +00:00
|
|
|
public function refactor(Node $assignNode): ?Node
|
2017-11-18 15:20:10 +00:00
|
|
|
{
|
2017-11-18 15:48:20 +00:00
|
|
|
// setter
|
|
|
|
if ($assignNode->var instanceof PropertyFetch) {
|
2017-12-27 16:26:02 +00:00
|
|
|
$args = $this->nodeFactory->createArgs([
|
|
|
|
$assignNode->expr,
|
|
|
|
]);
|
2017-11-18 15:48:20 +00:00
|
|
|
|
|
|
|
return new MethodCall($assignNode->var->var, $this->activeMethod, $args);
|
|
|
|
}
|
|
|
|
|
|
|
|
// getter
|
|
|
|
if ($assignNode->expr instanceof PropertyFetch) {
|
|
|
|
$assignNode->expr = new MethodCall($assignNode->expr->var, $this->activeMethod);
|
|
|
|
}
|
|
|
|
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
private function processPropertyFetchCandidate(PropertyFetch $propertyFetchNode, string $type): bool
|
|
|
|
{
|
|
|
|
foreach ($this->perClassPropertyToMethods as $class => $propertyToMethods) {
|
|
|
|
$properties = array_keys($propertyToMethods);
|
|
|
|
if ($this->propertyFetchAnalyzer->isTypeAndProperties($propertyFetchNode, $class, $properties)) {
|
2017-12-10 00:13:25 +00:00
|
|
|
/** @var Identifier $identifierNode */
|
|
|
|
$identifierNode = $propertyFetchNode->name;
|
|
|
|
|
|
|
|
$this->activeMethod = $propertyToMethods[$identifierNode->toString()][$type];
|
2017-11-18 15:48:20 +00:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
2017-11-18 15:20:10 +00:00
|
|
|
}
|
|
|
|
}
|