[Doctrine] Add GetUuidMethodCall to GetId

This commit is contained in:
Tomas Votruba 2019-09-21 13:32:35 +02:00
parent ca8cfe10ba
commit fabbfacd1a
11 changed files with 256 additions and 42 deletions

View File

@ -1,2 +1,3 @@
services:
Rector\Doctrine\Rector\MethodCall\ChangeSetIdToUuidValueRector: ~
Rector\Doctrine\Rector\MethodCall\ChangeGetUuidMethodCallToGetIdRector: ~

View File

@ -0,0 +1,116 @@
<?php declare(strict_types=1);
namespace Rector\Doctrine\Rector\MethodCall;
use PhpParser\Node;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Identifier;
use PHPStan\Type\ObjectType;
use Rector\Rector\AbstractRector;
use Rector\RectorDefinition\CodeSample;
use Rector\RectorDefinition\RectorDefinition;
/**
* @see \Rector\Doctrine\Tests\Rector\MethodCall\ChangeGetUuidMethodCallToGetIdRector\ChangeGetUuidMethodCallToGetIdRectorTest
*/
final class ChangeGetUuidMethodCallToGetIdRector extends AbstractRector
{
public function getDefinition(): RectorDefinition
{
return new RectorDefinition('Change getUuid() method call to getId()', [
new CodeSample(
<<<'PHP'
use Doctrine\ORM\Mapping as ORM;
use Ramsey\Uuid\Uuid;
use Ramsey\Uuid\UuidInterface;
class SomeClass
{
public function run()
{
$buildingFirst = new Building();
return $buildingFirst->getUuid()->toString();
}
}
/**
* @ORM\Entity
*/
class UuidEntity
{
private $uuid;
public function getUuid(): UuidInterface
{
return $this->uuid;
}
}
PHP
,
<<<'PHP'
use Doctrine\ORM\Mapping as ORM;
use Ramsey\Uuid\Uuid;
use Ramsey\Uuid\UuidInterface;
class SomeClass
{
public function run()
{
$buildingFirst = new Building();
return $buildingFirst->getId()->toString();
}
}
/**
* @ORM\Entity
*/
class UuidEntity
{
private $uuid;
public function getUuid(): UuidInterface
{
return $this->uuid;
}
}
PHP
),
]);
}
/**
* @return string[]
*/
public function getNodeTypes(): array
{
return [MethodCall::class];
}
/**
* @param MethodCall $node
*/
public function refactor(Node $node): ?Node
{
if ($this->shouldSkip($node)) {
return null;
}
$node->name = new Identifier('getId');
return $node;
}
private function shouldSkip(Node\Expr\MethodCall $methodCall): bool
{
if (! $this->isName($methodCall->name, 'getUuid')) {
return true;
}
$methodVarObjectType = $this->getObjectType($methodCall->var);
if (! $methodVarObjectType instanceof ObjectType) {
return true;
}
return ! $this->isDoctrineEntityClass($methodVarObjectType->getClassName());
}
}

View File

@ -4,11 +4,6 @@ namespace Rector\Doctrine\ValueObject;
final class DoctrineClass
{
/**
* @var string
*/
public const RAMSEY_UUID_INTERFACE = 'Ramsey\Uuid\UuidInterface';
/**
* @var string
*/
@ -33,4 +28,9 @@ final class DoctrineClass
* @var string
*/
public const RAMSEY_UUID = 'Ramsey\Uuid\Uuid';
/**
* @var string
*/
public const RAMSEY_UUID_INTERFACE = 'Ramsey\Uuid\UuidInterface';
}

View File

@ -0,0 +1,30 @@
<?php declare(strict_types=1);
namespace Rector\Doctrine\Tests\Rector\MethodCall\ChangeGetUuidMethodCallToGetIdRector;
use Rector\Doctrine\Rector\MethodCall\ChangeGetUuidMethodCallToGetIdRector;
use Rector\Testing\PHPUnit\AbstractRectorTestCase;
final class ChangeGetUuidMethodCallToGetIdRectorTest extends AbstractRectorTestCase
{
/**
* @dataProvider provideDataForTest()
*/
public function test(string $file): void
{
$this->doTestFile($file);
}
/**
* @return string[]
*/
public function provideDataForTest(): iterable
{
yield [__DIR__ . '/Fixture/fixture.php.inc'];
}
protected function getRectorClass(): string
{
return ChangeGetUuidMethodCallToGetIdRector::class;
}
}

View File

@ -0,0 +1,35 @@
<?php
namespace Rector\Doctrine\Tests\Rector\MethodCall\ChangeGetUuidMethodCallToGetIdRector\Fixture;
use Rector\Doctrine\Tests\Rector\MethodCall\ChangeGetUuidMethodCallToGetIdRector\Source\Car;
class SomeClass
{
public function run()
{
$car = new Car();
return $car->getUuid()->toString();
}
}
?>
-----
<?php
namespace Rector\Doctrine\Tests\Rector\MethodCall\ChangeGetUuidMethodCallToGetIdRector\Fixture;
use Rector\Doctrine\Tests\Rector\MethodCall\ChangeGetUuidMethodCallToGetIdRector\Source\Car;
class SomeClass
{
public function run()
{
$car = new Car();
return $car->getId()->toString();
}
}
?>

View File

@ -0,0 +1,19 @@
<?php declare(strict_types=1);
namespace Rector\Doctrine\Tests\Rector\MethodCall\ChangeGetUuidMethodCallToGetIdRector\Source;
use Doctrine\ORM\Mapping as ORM;
use Ramsey\Uuid\UuidInterface;
/**
* @ORM\Entity
*/
class Car
{
private $uuid;
public function getUuid(): UuidInterface
{
return $this->uuid;
}
}

View File

@ -2,13 +2,10 @@
namespace Rector\Php\Tests\Rector\FuncCall\RegexDashEscapeRector\Fixture;
use Nette\Utils\Strings;
class ConstPattern
{
const COMPAT_PATTERN = '#[-\w()]#';
const NON_COMPAT_PATTERN = '#[\w-()]#';
const EXTERNAL_NON_COMPAT_PATTERN = '#[\w-()]#';
public function run()
{
@ -17,27 +14,16 @@ class ConstPattern
}
}
class AnotherClass
{
public function run()
{
Strings::match('...', ConstPattern::EXTERNAL_NON_COMPAT_PATTERN);
}
}
?>
-----
<?php
namespace Rector\Php\Tests\Rector\FuncCall\RegexDashEscapeRector\Fixture;
use Nette\Utils\Strings;
class ConstPattern
{
const COMPAT_PATTERN = '#[-\w()]#';
const NON_COMPAT_PATTERN = '#[\w\-()]#';
const EXTERNAL_NON_COMPAT_PATTERN = '#[\w-()]#';
public function run()
{
@ -46,12 +32,4 @@ class ConstPattern
}
}
class AnotherClass
{
public function run()
{
Strings::match('...', ConstPattern::EXTERNAL_NON_COMPAT_PATTERN);
}
}
?>

View File

@ -0,0 +1,41 @@
<?php
namespace Rector\Php\Tests\Rector\FuncCall\RegexDashEscapeRector\Fixture;
use Nette\Utils\Strings;
class ExternalConstPattern
{
const EXTERNAL_NON_COMPAT_PATTERN = '#[\w-()]#';
}
class AnotherExternalClass
{
public function run()
{
Strings::match('...', ExternalConstPattern::EXTERNAL_NON_COMPAT_PATTERN);
}
}
?>
-----
<?php
namespace Rector\Php\Tests\Rector\FuncCall\RegexDashEscapeRector\Fixture;
use Nette\Utils\Strings;
class ExternalConstPattern
{
const EXTERNAL_NON_COMPAT_PATTERN = '#[\w\-()]#';
}
class AnotherExternalClass
{
public function run()
{
Strings::match('...', ExternalConstPattern::EXTERNAL_NON_COMPAT_PATTERN);
}
}
?>

View File

@ -23,6 +23,7 @@ final class RegexDashEscapeRectorTest extends AbstractRectorTestCase
yield [__DIR__ . '/Fixture/fixture.php.inc'];
yield [__DIR__ . '/Fixture/method_call.php.inc'];
yield [__DIR__ . '/Fixture/const.php.inc'];
yield [__DIR__ . '/Fixture/external_const.php.inc'];
yield [__DIR__ . '/Fixture/variable.php.inc'];
yield [__DIR__ . '/Fixture/multiple_variables.php.inc'];
}

View File

@ -460,10 +460,14 @@ final class ParsedNodesByType
public function findClassConstantByClassConstFetch(ClassConstFetch $classConstFetch): ?ClassConst
{
$class = null;
if ($this->nameResolver->isName($classConstFetch->class, 'self')) {
$class = $this->nameResolver->getName($classConstFetch->class);
if ($class === 'self') {
/** @var string|null $class */
$class = $classConstFetch->getAttribute(AttributeKey::CLASS_NAME);
} elseif ($class === 'parent') {
/** @var string|null $class */
$class = $classConstFetch->getAttribute(AttributeKey::PARENT_CLASS_NAME);
}
if ($class === null) {
@ -472,6 +476,7 @@ final class ParsedNodesByType
/** @var string $constantName */
$constantName = $this->nameResolver->getName($classConstFetch->name);
return $this->findClassConstant($class, $constantName);
}

View File

@ -202,19 +202,7 @@ final class RegexPatternArgumentManipulator
*/
private function resolveClassConstFetchValue(ClassConstFetch $classConstFetch): array
{
$className = $classConstFetch->getAttribute(AttributeKey::CLASS_NAME);
if (! is_string($className)) {
return [];
}
$constantName = $this->nameResolver->getName($classConstFetch->name);
if ($constantName === null) {
return [];
}
$classConstNode = $this->parsedNodesByType->findClassConstant($className, $constantName);
$classConstNode = $this->parsedNodesByType->findClassConstantByClassConstFetch($classConstFetch);
if ($classConstNode === null) {
return [];
}