[DX] Add MethodVisibility value object (#4028)

This commit is contained in:
Tomas Votruba 2020-08-25 21:19:12 +02:00 committed by GitHub
parent 4553ae9579
commit c2cfdaeacd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 106 additions and 111 deletions

View File

@ -1,36 +0,0 @@
name: Test With Doctrine
on:
pull_request: null
push:
branches:
- master
jobs:
test_with_doctrine:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: shivammathur/setup-php@v1
with:
php-version: 7.4
coverage: none
- name: Clone doctrine/orm and install safe dependencies
run: |
# cannot install dev deps (--no-dev), because doctrine/orm might inherit from them in different version
composer install --no-progress --no-dev --ansi
# loads autoload-dev packages as well, there are utils that might be used later
git clone https://github.com/doctrine/orm.git --depth 1
# older version have breaking "object" type
composer require doctrine/cache:^1.10 -d orm --no-update
# remove phsptan config to prevent rector loading configs
rm phpstan.neon
# do not intall doctrine/orm phpstan, it conflicts with Retor's one
composer install -d orm --no-dev
- run: |
bin/rector process orm/lib --config ci/config/rector-doctrine.php --autoload-file orm/vendor/autoload.php

View File

@ -7,6 +7,7 @@ use Rector\Generic\Rector\Assign\PropertyToMethodRector;
use Rector\Generic\Rector\ClassMethod\ChangeMethodVisibilityRector;
use Rector\Generic\Rector\ClassMethod\NormalToFluentRector;
use Rector\Generic\Rector\PropertyFetch\RenamePropertyRector;
use Rector\Generic\ValueObject\MethodVisibility;
use Rector\Renaming\Rector\MethodCall\RenameMethodRector;
use Rector\Renaming\Rector\Name\RenameClassRector;
use Rector\Renaming\ValueObject\MethodCallRename;
@ -314,14 +315,10 @@ return static function (ContainerConfigurator $containerConfigurator): void {
$services->set(ChangeMethodVisibilityRector::class)
->call('configure', [[
ChangeMethodVisibilityRector::METHOD_TO_VISIBILITY_BY_CLASS => [
'Cake\Mailer\MailerAwareTrait' => [
'getMailer' => 'protected',
],
'Cake\View\CellTrait' => [
'cell' => 'protected',
],
],
ChangeMethodVisibilityRector::METHOD_VISIBILITIES => inline_value_objects([
new MethodVisibility('Cake\Mailer\MailerAwareTrait', 'getMailer', 'protected'),
new MethodVisibility('Cake\View\CellTrait', 'cell', 'protected'),
]),
]]);
$services->set(RenameClassRector::class)

View File

@ -3,6 +3,7 @@
declare(strict_types=1);
use Rector\Generic\Rector\ClassMethod\ChangeMethodVisibilityRector;
use Rector\Generic\ValueObject\MethodVisibility;
use Rector\NetteToSymfony\Rector\MethodCall\WrapTransParameterNameRector;
use Rector\Renaming\Rector\MethodCall\RenameMethodRector;
use Rector\Renaming\Rector\Name\RenameClassRector;
@ -15,11 +16,9 @@ return static function (ContainerConfigurator $containerConfigurator): void {
$services->set(ChangeMethodVisibilityRector::class)
->call('configure', [[
ChangeMethodVisibilityRector::METHOD_TO_VISIBILITY_BY_CLASS => [
'Kdyby\Events\Subscriber' => [
'getSubscribedEvents' => 'static',
],
],
ChangeMethodVisibilityRector::METHOD_VISIBILITIES => inline_value_objects([
new MethodVisibility('Kdyby\Events\Subscriber', 'getSubscribedEvents', 'static'),
]),
]]);
$services->set(RenameMethodRector::class)

View File

@ -3,6 +3,7 @@
declare(strict_types=1);
use Rector\Generic\Rector\ClassMethod\ChangeMethodVisibilityRector;
use Rector\Generic\ValueObject\MethodVisibility;
use Rector\Renaming\Rector\MethodCall\RenameMethodRector;
use Rector\Renaming\ValueObject\MethodCallRename;
use function Rector\SymfonyPhpConfig\inline_value_objects;
@ -31,16 +32,10 @@ return static function (ContainerConfigurator $containerConfigurator): void {
$services->set(ChangeMethodVisibilityRector::class)
->call('configure', [[
ChangeMethodVisibilityRector::METHOD_TO_VISIBILITY_BY_CLASS => [
'Illuminate\Routing\Router' => [
'addRoute' => 'public',
],
'Illuminate\Contracts\Auth\Access\Gate' => [
'raw' => 'public',
],
'Illuminate\Database\Grammar' => [
'getDateFormat' => 'public',
],
],
ChangeMethodVisibilityRector::METHOD_VISIBILITIES => inline_value_objects([
new MethodVisibility('Illuminate\Routing\Router', 'addRoute', 'public'),
new MethodVisibility('Illuminate\Contracts\Auth\Access\Gate', 'raw', 'public'),
new MethodVisibility('Illuminate\Database\Grammar', 'getDateFormat', 'public'),
]),
]]);
};

View File

@ -5,6 +5,7 @@ declare(strict_types=1);
use Rector\Generic\Rector\ClassMethod\ArgumentAdderRector;
use Rector\Generic\Rector\ClassMethod\ArgumentRemoverRector;
use Rector\Generic\Rector\ClassMethod\ChangeMethodVisibilityRector;
use Rector\Generic\ValueObject\MethodVisibility;
use Rector\Generic\ValueObject\RemovedArgument;
use Rector\Laravel\Rector\StaticCall\Redirect301ToPermanentRedirectRector;
use function Rector\SymfonyPhpConfig\inline_value_objects;
@ -17,14 +18,10 @@ return static function (ContainerConfigurator $containerConfigurator): void {
$services->set(ChangeMethodVisibilityRector::class)
->call('configure', [[
ChangeMethodVisibilityRector::METHOD_TO_VISIBILITY_BY_CLASS => [
'Illuminate\Routing\Router' => [
'addRoute' => 'public',
],
'Illuminate\Contracts\Auth\Access\Gate' => [
'raw' => 'public',
],
],
ChangeMethodVisibilityRector::METHOD_VISIBILITIES => inline_value_objects([
new MethodVisibility('Illuminate\Routing\Router', 'addRoute', 'public'),
new MethodVisibility('Illuminate\Contracts\Auth\Access\Gate', 'raw', 'public'),
]),
]]);
$services->set(ArgumentAdderRector::class)

View File

@ -5,6 +5,7 @@ declare(strict_types=1);
use Rector\Generic\Rector\ClassMethod\ArgumentAdderRector;
use Rector\Generic\Rector\ClassMethod\ChangeMethodVisibilityRector;
use Rector\Generic\Rector\Expression\MethodCallToReturnRector;
use Rector\Generic\ValueObject\MethodVisibility;
use Rector\Renaming\Rector\MethodCall\RenameMethodRector;
use Rector\Renaming\Rector\Name\RenameClassRector;
use Rector\Renaming\Rector\StaticCall\RenameStaticMethodRector;
@ -77,12 +78,9 @@ return static function (ContainerConfigurator $containerConfigurator): void {
$services->set(ChangeMethodVisibilityRector::class)
->call('configure', [[
ChangeMethodVisibilityRector::METHOD_TO_VISIBILITY_BY_CLASS => [
'Illuminate\Foundation\Http\FormRequest' => [
# https://github.com/laravel/framework/commit/e47e91417ab22e6af001db1dcbe75b87db218c1d
'validationData' => 'public',
],
],
ChangeMethodVisibilityRector::METHOD_VISIBILITIES => inline_value_objects([
new MethodVisibility('Illuminate\Foundation\Http\FormRequest', 'validationData', 'public'),
]),
]]);
$services->set(ArgumentAdderRector::class)

View File

@ -5,12 +5,14 @@ declare(strict_types=1);
use Rector\Generic\Rector\ClassMethod\AddReturnTypeDeclarationRector;
use Rector\Generic\Rector\ClassMethod\ArgumentAdderRector;
use Rector\Generic\Rector\ClassMethod\ArgumentDefaultValueReplacerRector;
use Rector\Generic\Rector\ClassMethod\ArgumentRemoverRector;
use Rector\Generic\Rector\ClassMethod\ChangeMethodVisibilityRector;
use Rector\Generic\Rector\ClassMethod\WrapReturnRector;
use Rector\Generic\Rector\New_\NewToStaticCallRector;
use Rector\Generic\ValueObject\MethodReturnType;
use Rector\Generic\ValueObject\MethodVisibility;
use Rector\Generic\ValueObject\RemovedArgument;
use Rector\Generic\ValueObject\TypeMethodWrap;
use Rector\Renaming\Rector\MethodCall\RenameMethodRector;
@ -144,11 +146,9 @@ return static function (ContainerConfigurator $containerConfigurator): void {
$services->set(ChangeMethodVisibilityRector::class)
->call('configure', [[
ChangeMethodVisibilityRector::METHOD_TO_VISIBILITY_BY_CLASS => [
'Symfony\Component\Form\AbstractTypeExtension' => [
'getExtendedTypes' => 'static',
],
],
ChangeMethodVisibilityRector::METHOD_VISIBILITIES => inline_value_objects([
new MethodVisibility('Symfony\Component\Form\AbstractTypeExtension', 'getExtendedTypes', 'static'),
]),
]]);
$services->set(WrapReturnRector::class)

View File

@ -4995,7 +4995,7 @@ return function (ContainerConfigurator $containerConfigurator) : void {
$services = $containerConfigurator->services();
$services->set(ChangeMethodVisibilityRector::class)
->call('configure', [[
ChangeMethodVisibilityRector::METHOD_TO_VISIBILITY_BY_CLASS => [
ChangeMethodVisibilityRector::METHOD_VISIBILITIES => [
'FrameworkClass' => [
'someMethod' => 'protected']]
]]);

View File

@ -3,7 +3,7 @@
declare(strict_types=1);
use Rector\Core\Configuration\Option;
use Rector\Generic\ValueObject\RemovedArgument;
use Rector\Generic\ValueObject\MethodVisibility;
use Rector\SymfonyPhpConfig\Rector\ArrayItem\ReplaceArrayWithObjectRector;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
@ -13,7 +13,7 @@ return static function (ContainerConfigurator $containerConfigurator): void {
$services->set(ReplaceArrayWithObjectRector::class)
->call('configure', [[
ReplaceArrayWithObjectRector::CONSTANT_NAMES_TO_VALUE_OBJECTS => [
'Rector\Generic\Rector\ClassMethod\ArgumentRemoverRector::REMOVED_ARGUMENTS' => RemovedArgument::class,
'Rector\Generic\Rector\ClassMethod\ChangeMethodVisibilityRector::METHOD_VISIBILITIES' => MethodVisibility::class,
],
]]);

View File

@ -10,7 +10,9 @@ use Rector\Core\Contract\Rector\ConfigurableRectorInterface;
use Rector\Core\Rector\AbstractRector;
use Rector\Core\RectorDefinition\ConfiguredCodeSample;
use Rector\Core\RectorDefinition\RectorDefinition;
use Rector\Generic\ValueObject\MethodVisibility;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Webmozart\Assert\Assert;
/**
* @see \Rector\Generic\Tests\Rector\ClassMethod\ChangeMethodVisibilityRector\ChangeMethodVisibilityRectorTest
@ -20,12 +22,12 @@ final class ChangeMethodVisibilityRector extends AbstractRector implements Confi
/**
* @var string
*/
public const METHOD_TO_VISIBILITY_BY_CLASS = 'method_to_visibility_by_class';
public const METHOD_VISIBILITIES = 'method_visibilities';
/**
* @var string[][] { class => [ method name => visibility ] }
* @var MethodVisibility[]
*/
private $methodToVisibilityByClass = [];
private $methodVisibilities = [];
public function getDefinition(): RectorDefinition
{
@ -65,10 +67,8 @@ class MyClass extends FrameworkClass
PHP
,
[
self::METHOD_TO_VISIBILITY_BY_CLASS => [
'FrameworkClass' => [
'someMethod' => 'protected',
],
self::METHOD_VISIBILITIES => [
new MethodVisibility('FrameworkClass', 'someMethod', 'protected'),
],
]
)]
@ -94,28 +94,29 @@ PHP
}
$nodeParentClassName = $node->getAttribute(AttributeKey::PARENT_CLASS_NAME);
if (! isset($this->methodToVisibilityByClass[$nodeParentClassName])) {
return null;
}
$methodName = $this->getName($node);
if ($methodName === null) {
return null;
}
if (! isset($this->methodToVisibilityByClass[$nodeParentClassName][$methodName])) {
return null;
foreach ($this->methodVisibilities as $methodVisibility) {
if ($methodVisibility->getClass() !== $nodeParentClassName) {
continue;
}
if (! $this->isName($node, $methodVisibility->getMethod())) {
continue;
}
$this->changeNodeVisibility($node, $methodVisibility->getVisibility());
return $node;
}
$nodeParentClassName = $node->getAttribute(AttributeKey::PARENT_CLASS_NAME);
$visibility = $this->methodToVisibilityByClass[$nodeParentClassName][$methodName];
$this->changeNodeVisibility($node, $visibility);
return $node;
}
public function configure(array $configuration): void
{
$this->methodToVisibilityByClass = $configuration[self::METHOD_TO_VISIBILITY_BY_CLASS] ?? [];
$methodVisibilities = $configuration[self::METHOD_VISIBILITIES] ?? [];
Assert::allIsInstanceOf($methodVisibilities, MethodVisibility::class);
$this->methodVisibilities = $methodVisibilities;
}
}

View File

@ -0,0 +1,45 @@
<?php
declare(strict_types=1);
namespace Rector\Generic\ValueObject;
final class MethodVisibility
{
/**
* @var string
*/
private $class;
/**
* @var string
*/
private $method;
/**
* @var string
*/
private $visibility;
public function __construct(string $class, string $method, string $visibility)
{
$this->class = $class;
$this->method = $method;
$this->visibility = $visibility;
}
public function getClass(): string
{
return $this->class;
}
public function getMethod(): string
{
return $this->method;
}
public function getVisibility(): string
{
return $this->visibility;
}
}

View File

@ -8,6 +8,7 @@ use Iterator;
use Rector\Core\Testing\PHPUnit\AbstractRectorTestCase;
use Rector\Generic\Rector\ClassMethod\ChangeMethodVisibilityRector;
use Rector\Generic\Tests\Rector\ClassMethod\ChangeMethodVisibilityRector\Source\ParentObject;
use Rector\Generic\ValueObject\MethodVisibility;
use Symplify\SmartFileSystem\SmartFileInfo;
final class ChangeMethodVisibilityRectorTest extends AbstractRectorTestCase
@ -32,13 +33,11 @@ final class ChangeMethodVisibilityRectorTest extends AbstractRectorTestCase
{
return [
ChangeMethodVisibilityRector::class => [
ChangeMethodVisibilityRector::METHOD_TO_VISIBILITY_BY_CLASS => [
ParentObject::class => [
'toBePublicMethod' => 'public',
'toBeProtectedMethod' => 'protected',
'toBePrivateMethod' => 'private',
'toBePublicStaticMethod' => 'public',
],
ChangeMethodVisibilityRector::METHOD_VISIBILITIES => [
new MethodVisibility(ParentObject::class, 'toBePublicMethod', 'public'),
new MethodVisibility(ParentObject::class, 'toBeProtectedMethod', 'protected'),
new MethodVisibility(ParentObject::class, 'toBePrivateMethod', 'private'),
new MethodVisibility(ParentObject::class, 'toBePublicStaticMethod', 'public'),
],
],
];