mirror of
https://github.com/rectorphp/rector.git
synced 2024-06-01 17:00:51 +00:00
[DX] Add MethodVisibility value object (#4028)
This commit is contained in:
parent
4553ae9579
commit
c2cfdaeacd
36
.github/workflows/test_with_doctrine.yaml
vendored
36
.github/workflows/test_with_doctrine.yaml
vendored
|
@ -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
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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'),
|
||||
]),
|
||||
]]);
|
||||
};
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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']]
|
||||
]]);
|
||||
|
|
|
@ -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,
|
||||
],
|
||||
]]);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
45
rules/generic/src/ValueObject/MethodVisibility.php
Normal file
45
rules/generic/src/ValueObject/MethodVisibility.php
Normal 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;
|
||||
}
|
||||
}
|
|
@ -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'),
|
||||
],
|
||||
],
|
||||
];
|
||||
|
|
Loading…
Reference in New Issue
Block a user