mirror of
https://github.com/rectorphp/rector.git
synced 2024-07-31 22:00:23 +00:00
[DowngradePhp72] Allow empty config on DowngradeParameterTypeWideningRector (#1451)
* [DowngradePhp72] Allow empty config on DowngradeParameterTypeWideningRector * [ci-review] Rector Rectify * fix * early check on empty unsafeTypesToMethods * added back removed fixture * final touch: eol Co-authored-by: GitHub Action <action@github.com>
This commit is contained in:
parent
8d6eb87e99
commit
4681067be5
@ -30,10 +30,8 @@ return static function (ContainerConfigurator $containerConfigurator): void {
|
||||
|
||||
$services->set(DowngradeParameterTypeWideningRector::class)
|
||||
->configure([
|
||||
DowngradeParameterTypeWideningRector::UNSAFE_TYPES_TO_METHODS => [
|
||||
LoaderInterface::class => ['load'],
|
||||
Loader::class => ['import']
|
||||
],
|
||||
LoaderInterface::class => ['load'],
|
||||
Loader::class => ['import'],
|
||||
]);
|
||||
};
|
||||
|
||||
|
@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Tests\DowngradePhp72\Rector\ClassMethod\DowngradeParameterTypeWideningRector;
|
||||
|
||||
use Iterator;
|
||||
use Rector\Testing\PHPUnit\AbstractRectorTestCase;
|
||||
use Symplify\SmartFileSystem\SmartFileInfo;
|
||||
|
||||
final class EmptyConfigTest extends AbstractRectorTestCase
|
||||
{
|
||||
/**
|
||||
* @requires PHP 7.2
|
||||
* @dataProvider provideData()
|
||||
*/
|
||||
public function test(SmartFileInfo $fileInfo): void
|
||||
{
|
||||
$this->doTestFileInfo($fileInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Iterator<SmartFileInfo>
|
||||
*/
|
||||
public function provideData(): Iterator
|
||||
{
|
||||
return $this->yieldFilesFromDirectory(__DIR__ . '/FixtureEmptyConfig');
|
||||
}
|
||||
|
||||
public function provideConfigFilePath(): string
|
||||
{
|
||||
return __DIR__ . '/config/empty_config.php';
|
||||
}
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
namespace Rector\Tests\DowngradePhp72\Rector\ClassMethod\DowngradeParameterTypeWideningRector\FixtureEmptyConfig;
|
||||
|
||||
class SomeClass
|
||||
{
|
||||
public function hello(string $world = 'world') {
|
||||
printf('Hello %s', $world);
|
||||
}
|
||||
}
|
||||
|
||||
class SomeOtherClassUsingAnAnonymousClass
|
||||
{
|
||||
public function doSomething(): void
|
||||
{
|
||||
$class = new class () extends SomeClass {
|
||||
public function hello(string $world = 'world') {
|
||||
printf('Hi %s', $world);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\Tests\DowngradePhp72\Rector\ClassMethod\DowngradeParameterTypeWideningRector\FixtureEmptyConfig;
|
||||
|
||||
class SomeClass
|
||||
{
|
||||
/**
|
||||
* @param string $world
|
||||
*/
|
||||
public function hello($world = 'world') {
|
||||
printf('Hello %s', $world);
|
||||
}
|
||||
}
|
||||
|
||||
class SomeOtherClassUsingAnAnonymousClass
|
||||
{
|
||||
public function doSomething(): void
|
||||
{
|
||||
$class = new class () extends SomeClass {
|
||||
/**
|
||||
* @param string $world
|
||||
*/
|
||||
public function hello($world = 'world') {
|
||||
printf('Hi %s', $world);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
namespace Rector\Tests\DowngradePhp72\Rector\ClassMethod\DowngradeParameterTypeWideningRector\FixtureEmptyConfig;
|
||||
|
||||
interface SomeInterface
|
||||
{
|
||||
public function hello(string $world = 'world');
|
||||
}
|
||||
|
||||
class SomeClass2
|
||||
{
|
||||
public function doSomething(): void
|
||||
{
|
||||
$class = new class (function () {
|
||||
return $this->doSomethingElse();
|
||||
}) implements SomeInterface {
|
||||
public function hello(string $world = 'world') {
|
||||
printf('Hi %s', $world);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public function doSomethingElse(): void
|
||||
{
|
||||
print('Hello again');
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\Tests\DowngradePhp72\Rector\ClassMethod\DowngradeParameterTypeWideningRector\FixtureEmptyConfig;
|
||||
|
||||
interface SomeInterface
|
||||
{
|
||||
/**
|
||||
* @param string $world
|
||||
*/
|
||||
public function hello($world = 'world');
|
||||
}
|
||||
|
||||
class SomeClass2
|
||||
{
|
||||
public function doSomething(): void
|
||||
{
|
||||
$class = new class (function () {
|
||||
return $this->doSomethingElse();
|
||||
}) implements SomeInterface {
|
||||
/**
|
||||
* @param string $world
|
||||
*/
|
||||
public function hello($world = 'world') {
|
||||
printf('Hi %s', $world);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public function doSomethingElse(): void
|
||||
{
|
||||
print('Hello again');
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
namespace Rector\Tests\DowngradePhp72\Rector\ClassMethod\DowngradeParameterTypeWideningRector\FixtureEmptyConfig;
|
||||
|
||||
interface SomeInterface2
|
||||
{
|
||||
public function test(\SplFileInfo $file);
|
||||
}
|
||||
|
||||
abstract class SomeAbstractClass implements SomeInterface2
|
||||
{
|
||||
public function test2(\SplFileInfo $file, string $world = 'world') {
|
||||
printf('Hello %s', $world);
|
||||
}
|
||||
}
|
||||
|
||||
return new class extends SomeAbstractClass {
|
||||
public function test(\SplFileInfo $file) {
|
||||
$this->test2($file);
|
||||
}
|
||||
};
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\Tests\DowngradePhp72\Rector\ClassMethod\DowngradeParameterTypeWideningRector\FixtureEmptyConfig;
|
||||
|
||||
interface SomeInterface2
|
||||
{
|
||||
/**
|
||||
* @param \SplFileInfo $file
|
||||
*/
|
||||
public function test($file);
|
||||
}
|
||||
|
||||
abstract class SomeAbstractClass implements SomeInterface2
|
||||
{
|
||||
/**
|
||||
* @param \SplFileInfo $file
|
||||
* @param string $world
|
||||
*/
|
||||
public function test2($file, $world = 'world') {
|
||||
printf('Hello %s', $world);
|
||||
}
|
||||
}
|
||||
|
||||
return new class extends SomeAbstractClass {
|
||||
/**
|
||||
* @param \SplFileInfo $file
|
||||
*/
|
||||
public function test($file) {
|
||||
$this->test2($file);
|
||||
}
|
||||
};
|
||||
|
||||
?>
|
@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
namespace Rector\Tests\DowngradePhp72\Rector\ClassMethod\DowngradeParameterTypeWideningRector\FixtureEmptyConfig;
|
||||
|
||||
interface SomeContainerInterface
|
||||
{
|
||||
public function has(string $id);
|
||||
}
|
||||
|
||||
final class SomeContainerBuilder extends SomeUniqueContainer
|
||||
{
|
||||
public function has($id)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
class SomeUniqueContainer implements SomeContainerInterface
|
||||
{
|
||||
public function has($id)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\Tests\DowngradePhp72\Rector\ClassMethod\DowngradeParameterTypeWideningRector\FixtureEmptyConfig;
|
||||
|
||||
interface SomeContainerInterface
|
||||
{
|
||||
/**
|
||||
* @param string $id
|
||||
*/
|
||||
public function has($id);
|
||||
}
|
||||
|
||||
final class SomeContainerBuilder extends SomeUniqueContainer
|
||||
{
|
||||
public function has($id)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
class SomeUniqueContainer implements SomeContainerInterface
|
||||
{
|
||||
public function has($id)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
namespace Rector\Tests\DowngradePhp72\Rector\ClassMethod\DowngradeParameterTypeWideningRector\FixtureEmptyConfig;
|
||||
|
||||
interface A
|
||||
{
|
||||
public function test(array $input);
|
||||
}
|
||||
|
||||
class B implements A
|
||||
{
|
||||
public function test($input)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
final class MostChild implements A
|
||||
{
|
||||
public function test(array $input)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\Tests\DowngradePhp72\Rector\ClassMethod\DowngradeParameterTypeWideningRector\FixtureEmptyConfig;
|
||||
|
||||
interface A
|
||||
{
|
||||
/**
|
||||
* @param mixed[] $input
|
||||
*/
|
||||
public function test($input);
|
||||
}
|
||||
|
||||
class B implements A
|
||||
{
|
||||
public function test($input)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
final class MostChild implements A
|
||||
{
|
||||
/**
|
||||
* @param mixed[] $input
|
||||
*/
|
||||
public function test($input)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
namespace Rector\Tests\DowngradePhp72\Rector\ClassMethod\DowngradeParameterTypeWideningRector\FixtureEmptyConfig;
|
||||
|
||||
use Rector\Tests\DowngradePhp72\Rector\ClassMethod\DowngradeParameterTypeWideningRector\Source\AnotherContainerInterface;
|
||||
|
||||
final class YetAnotherContainer implements AnotherContainerInterface
|
||||
{
|
||||
use AnotherServiceLocatorTrait;
|
||||
}
|
||||
|
||||
trait AnotherServiceLocatorTrait
|
||||
{
|
||||
public function get(string $name)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\Tests\DowngradePhp72\Rector\ClassMethod\DowngradeParameterTypeWideningRector\FixtureEmptyConfig;
|
||||
|
||||
use Rector\Tests\DowngradePhp72\Rector\ClassMethod\DowngradeParameterTypeWideningRector\Source\AnotherContainerInterface;
|
||||
|
||||
final class YetAnotherContainer implements AnotherContainerInterface
|
||||
{
|
||||
use AnotherServiceLocatorTrait;
|
||||
}
|
||||
|
||||
trait AnotherServiceLocatorTrait
|
||||
{
|
||||
/**
|
||||
* @param string $name
|
||||
*/
|
||||
public function get($name)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
namespace Rector\Tests\DowngradePhp72\Rector\ClassMethod\DowngradeParameterTypeWideningRector\FixtureEmptyConfig;
|
||||
|
||||
abstract class ParentClass implements \SplObserver
|
||||
{
|
||||
public function update(\SplSubject $subject): void
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
class IndirectImplementsNativeInterface extends ParentClass
|
||||
{
|
||||
public function update($subject): void
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\Tests\DowngradePhp72\Rector\ClassMethod\DowngradeParameterTypeWideningRector\FixtureEmptyConfig;
|
||||
|
||||
abstract class ParentClass implements \SplObserver
|
||||
{
|
||||
/**
|
||||
* @param \SplSubject $subject
|
||||
*/
|
||||
public function update($subject): void
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
class IndirectImplementsNativeInterface extends ParentClass
|
||||
{
|
||||
public function update($subject): void
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
namespace Rector\Tests\DowngradePhp72\Rector\ClassMethod\DowngradeParameterTypeWideningRector\FixtureEmptyConfig;
|
||||
|
||||
interface WhateverInterface
|
||||
{
|
||||
public function test(string $input);
|
||||
}
|
||||
|
||||
abstract class AbstractSomeAncestorClass implements WhateverInterface
|
||||
{
|
||||
}
|
||||
|
||||
class SomeChildClass extends AbstractSomeAncestorClass
|
||||
{
|
||||
public function test($input) // type omitted for $input
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\Tests\DowngradePhp72\Rector\ClassMethod\DowngradeParameterTypeWideningRector\FixtureEmptyConfig;
|
||||
|
||||
interface WhateverInterface
|
||||
{
|
||||
/**
|
||||
* @param string $input
|
||||
*/
|
||||
public function test($input);
|
||||
}
|
||||
|
||||
abstract class AbstractSomeAncestorClass implements WhateverInterface
|
||||
{
|
||||
}
|
||||
|
||||
class SomeChildClass extends AbstractSomeAncestorClass
|
||||
{
|
||||
public function test($input) // type omitted for $input
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
namespace Rector\Tests\DowngradePhp72\Rector\ClassMethod\DowngradeParameterTypeWideningRector\FixtureEmptyConfig;
|
||||
|
||||
interface SomeAskingInterfaceWithNullable
|
||||
{
|
||||
public function ask(?callable $callable = null);
|
||||
}
|
||||
|
||||
final class AskForMore implements SomeAskingInterfaceWithNullable
|
||||
{
|
||||
public function ask($callable = null)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\Tests\DowngradePhp72\Rector\ClassMethod\DowngradeParameterTypeWideningRector\FixtureEmptyConfig;
|
||||
|
||||
interface SomeAskingInterfaceWithNullable
|
||||
{
|
||||
/**
|
||||
* @param callable|null $callable
|
||||
*/
|
||||
public function ask($callable = null);
|
||||
}
|
||||
|
||||
final class AskForMore implements SomeAskingInterfaceWithNullable
|
||||
{
|
||||
public function ask($callable = null)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
@ -12,9 +12,7 @@ return static function (ContainerConfigurator $containerConfigurator): void {
|
||||
|
||||
$services->set(DowngradeParameterTypeWideningRector::class)
|
||||
->configure([
|
||||
DowngradeParameterTypeWideningRector::UNSAFE_TYPES_TO_METHODS => [
|
||||
ContainerInterface::class => ['set', 'get', 'has', 'initialized'],
|
||||
SomeContainerInterface::class => ['set', 'has'],
|
||||
],
|
||||
ContainerInterface::class => ['set', 'get', 'has', 'initialized'],
|
||||
SomeContainerInterface::class => ['set', 'has'],
|
||||
]);
|
||||
};
|
||||
|
@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Rector\DowngradePhp72\Rector\ClassMethod\DowngradeParameterTypeWideningRector;
|
||||
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
|
||||
|
||||
return static function (ContainerConfigurator $containerConfigurator): void {
|
||||
$services = $containerConfigurator->services();
|
||||
$services->set(DowngradeParameterTypeWideningRector::class);
|
||||
};
|
@ -9,7 +9,7 @@ use PhpParser\Node\Param;
|
||||
use PhpParser\Node\Stmt\ClassLike;
|
||||
use PhpParser\Node\Stmt\ClassMethod;
|
||||
use PHPStan\Reflection\ClassReflection;
|
||||
use Rector\Core\Contract\Rector\ConfigurableRectorInterface;
|
||||
use Rector\Core\Contract\Rector\AllowEmptyConfigurableRectorInterface;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Rector\Core\Reflection\ReflectionResolver;
|
||||
use Rector\DowngradePhp72\NodeAnalyzer\BuiltInMethodAnalyzer;
|
||||
@ -27,13 +27,8 @@ use Webmozart\Assert\Assert;
|
||||
*
|
||||
* @see \Rector\Tests\DowngradePhp72\Rector\ClassMethod\DowngradeParameterTypeWideningRector\DowngradeParameterTypeWideningRectorTest
|
||||
*/
|
||||
final class DowngradeParameterTypeWideningRector extends AbstractRector implements ConfigurableRectorInterface
|
||||
final class DowngradeParameterTypeWideningRector extends AbstractRector implements AllowEmptyConfigurableRectorInterface
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
final public const UNSAFE_TYPES_TO_METHODS = 'unsafe_types_to_methods';
|
||||
|
||||
/**
|
||||
* @var array<string, string[]>
|
||||
*/
|
||||
@ -85,7 +80,8 @@ final class SomeClass implements SomeInterface
|
||||
CODE_SAMPLE
|
||||
,
|
||||
[
|
||||
self::UNSAFE_TYPES_TO_METHODS => [],
|
||||
'ContainerInterface' => ['set', 'get', 'has', 'initialized'],
|
||||
'SomeContainerInterface' => ['set', 'has'],
|
||||
]
|
||||
),
|
||||
]);
|
||||
@ -128,8 +124,8 @@ CODE_SAMPLE
|
||||
*/
|
||||
public function configure(array $configuration): void
|
||||
{
|
||||
$unsafeTypesToMethods = $configuration[self::UNSAFE_TYPES_TO_METHODS] ?? [];
|
||||
Assert::isArray($unsafeTypesToMethods);
|
||||
$unsafeTypesToMethods = $configuration;
|
||||
|
||||
foreach ($unsafeTypesToMethods as $key => $value) {
|
||||
Assert::string($key);
|
||||
Assert::allString($value);
|
||||
@ -212,6 +208,10 @@ CODE_SAMPLE
|
||||
|
||||
private function isSafeType(ClassReflection $classReflection, ClassMethod $classMethod): bool
|
||||
{
|
||||
if ($this->unsafeTypesToMethods === []) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$classReflectionName = $classReflection->getName();
|
||||
foreach ($this->unsafeTypesToMethods as $unsafeType => $unsafeMethods) {
|
||||
if (! $this->isNames($classMethod, $unsafeMethods)) {
|
||||
|
Loading…
Reference in New Issue
Block a user