mirror of
https://github.com/rectorphp/rector.git
synced 2024-06-03 18:00:50 +00:00
Deprecate RemovingStatic rules as very narrow use case in generic rules (#1819)
This commit is contained in:
parent
9fe44263f9
commit
92d04a5547
|
@ -1,4 +1,4 @@
|
|||
# 524 Rules Overview
|
||||
# 520 Rules Overview
|
||||
|
||||
<br>
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
|||
|
||||
- [Autodiscovery](#autodiscovery) (4)
|
||||
|
||||
- [CodeQuality](#codequality) (70)
|
||||
- [CodeQuality](#codequality) (71)
|
||||
|
||||
- [CodingStyle](#codingstyle) (35)
|
||||
|
||||
|
@ -76,7 +76,7 @@
|
|||
|
||||
- [Php74](#php74) (15)
|
||||
|
||||
- [Php80](#php80) (18)
|
||||
- [Php80](#php80) (17)
|
||||
|
||||
- [Php81](#php81) (9)
|
||||
|
||||
|
@ -88,7 +88,7 @@
|
|||
|
||||
- [Removing](#removing) (6)
|
||||
|
||||
- [RemovingStatic](#removingstatic) (5)
|
||||
- [RemovingStatic](#removingstatic) (1)
|
||||
|
||||
- [Renaming](#renaming) (11)
|
||||
|
||||
|
@ -1127,6 +1127,24 @@ Change unsafe new `static()` to new `self()`
|
|||
|
||||
<br>
|
||||
|
||||
### OptionalParametersAfterRequiredRector
|
||||
|
||||
Move required parameters after optional ones
|
||||
|
||||
- class: [`Rector\CodeQuality\Rector\ClassMethod\OptionalParametersAfterRequiredRector`](../rules/CodeQuality/Rector/ClassMethod/OptionalParametersAfterRequiredRector.php)
|
||||
|
||||
```diff
|
||||
class SomeObject
|
||||
{
|
||||
- public function run($optional = 1, $required)
|
||||
+ public function run($required, $optional = 1)
|
||||
{
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
### RemoveAlwaysTrueConditionSetInConstructorRector
|
||||
|
||||
If conditions is always true, perform the content right away
|
||||
|
@ -8350,24 +8368,6 @@ Change ternary type resolve to `get_debug_type()`
|
|||
|
||||
<br>
|
||||
|
||||
### OptionalParametersAfterRequiredRector
|
||||
|
||||
Move required parameters after optional ones
|
||||
|
||||
- class: [`Rector\Php80\Rector\ClassMethod\OptionalParametersAfterRequiredRector`](../rules/Php80/Rector/ClassMethod/OptionalParametersAfterRequiredRector.php)
|
||||
|
||||
```diff
|
||||
class SomeObject
|
||||
{
|
||||
- public function run($optional = 1, $required)
|
||||
+ public function run($required, $optional = 1)
|
||||
{
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
### Php8ResourceReturnToObjectRector
|
||||
|
||||
Change `is_resource()` to instanceof Object
|
||||
|
@ -9566,108 +9566,6 @@ return static function (ContainerConfigurator $containerConfigurator): void {
|
|||
|
||||
## RemovingStatic
|
||||
|
||||
### DesiredClassTypeToDynamicRector
|
||||
|
||||
Change full static service, to dynamic one
|
||||
|
||||
- class: [`Rector\RemovingStatic\Rector\Class_\DesiredClassTypeToDynamicRector`](../rules/RemovingStatic/Rector/Class_/DesiredClassTypeToDynamicRector.php)
|
||||
|
||||
```diff
|
||||
class AnotherClass
|
||||
{
|
||||
+ /**
|
||||
+ * @var SomeClass
|
||||
+ */
|
||||
+ private $someClass;
|
||||
+
|
||||
+ public fuction __construct(SomeClass $someClass)
|
||||
+ {
|
||||
+ $this->someClass = $someClass;
|
||||
+ }
|
||||
+
|
||||
public function run()
|
||||
{
|
||||
SomeClass::someStatic();
|
||||
}
|
||||
}
|
||||
|
||||
class SomeClass
|
||||
{
|
||||
- public static function run()
|
||||
+ public function run()
|
||||
{
|
||||
- self::someStatic();
|
||||
+ $this->someStatic();
|
||||
}
|
||||
|
||||
- private static function someStatic()
|
||||
+ private function someStatic()
|
||||
{
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
### DesiredPropertyClassMethodTypeToDynamicRector
|
||||
|
||||
Change defined static properties and methods to dynamic
|
||||
|
||||
- class: [`Rector\RemovingStatic\Rector\Property\DesiredPropertyClassMethodTypeToDynamicRector`](../rules/RemovingStatic/Rector/Property/DesiredPropertyClassMethodTypeToDynamicRector.php)
|
||||
|
||||
```diff
|
||||
final class SomeClass
|
||||
{
|
||||
- public static $name;
|
||||
+ public $name;
|
||||
|
||||
- public static function go()
|
||||
+ public function go()
|
||||
{
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
### DesiredStaticCallTypeToDynamicRector
|
||||
|
||||
Change defined static service to dynamic one
|
||||
|
||||
- class: [`Rector\RemovingStatic\Rector\StaticCall\DesiredStaticCallTypeToDynamicRector`](../rules/RemovingStatic/Rector/StaticCall/DesiredStaticCallTypeToDynamicRector.php)
|
||||
|
||||
```diff
|
||||
final class SomeClass
|
||||
{
|
||||
public function run()
|
||||
{
|
||||
- SomeStaticMethod::someStatic();
|
||||
+ $this->someStaticMethod->someStatic();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
### DesiredStaticPropertyFetchTypeToDynamicRector
|
||||
|
||||
Change defined static service to dynamic one
|
||||
|
||||
- class: [`Rector\RemovingStatic\Rector\StaticPropertyFetch\DesiredStaticPropertyFetchTypeToDynamicRector`](../rules/RemovingStatic/Rector/StaticPropertyFetch/DesiredStaticPropertyFetchTypeToDynamicRector.php)
|
||||
|
||||
```diff
|
||||
final class SomeClass
|
||||
{
|
||||
public function run()
|
||||
{
|
||||
- SomeStaticMethod::$someStatic;
|
||||
+ $this->someStaticMethod->someStatic;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
### LocallyCalledStaticMethodToNonStaticRector
|
||||
|
||||
Change static method and local-only calls to non-static
|
||||
|
|
|
@ -2,15 +2,11 @@
|
|||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Rector\Core\Configuration\Option;
|
||||
use Rector\PSR4\Composer\PSR4NamespaceMatcher;
|
||||
use Rector\PSR4\Contract\PSR4AutoloadNamespaceMatcherInterface;
|
||||
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
|
||||
|
||||
return static function (ContainerConfigurator $containerConfigurator): void {
|
||||
$parameters = $containerConfigurator->parameters();
|
||||
$parameters->set(Option::TYPES_TO_REMOVE_STATIC_FROM, []);
|
||||
|
||||
$services = $containerConfigurator->services();
|
||||
|
||||
$services->defaults()
|
||||
|
@ -22,5 +18,11 @@ return static function (ContainerConfigurator $containerConfigurator): void {
|
|||
$services->alias(PSR4AutoloadNamespaceMatcherInterface::class, PSR4NamespaceMatcher::class);
|
||||
|
||||
$services->load('Rector\\', __DIR__ . '/../rules')
|
||||
->exclude([__DIR__ . '/../rules/*/{ValueObject,Rector,Contract,Exception,Enum}']);
|
||||
->exclude([
|
||||
__DIR__ . '/../rules/*/ValueObject/*',
|
||||
__DIR__ . '/../rules/*/Rector/*',
|
||||
__DIR__ . '/../rules/*/Contract/*',
|
||||
__DIR__ . '/../rules/*/Exception/*',
|
||||
__DIR__ . '/../rules/*/Enum/*',
|
||||
]);
|
||||
};
|
||||
|
|
|
@ -1,33 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Tests\RemovingStatic\Rector\Class_\DesiredClassTypeToDynamicRector;
|
||||
|
||||
use Iterator;
|
||||
use Rector\Testing\PHPUnit\AbstractRectorTestCase;
|
||||
use Symplify\SmartFileSystem\SmartFileInfo;
|
||||
|
||||
final class DesiredClassTypeToDynamicRectorTest extends AbstractRectorTestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider provideData()
|
||||
*/
|
||||
public function test(SmartFileInfo $fileInfo): void
|
||||
{
|
||||
$this->doTestFileInfo($fileInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Iterator<SmartFileInfo>
|
||||
*/
|
||||
public function provideData(): Iterator
|
||||
{
|
||||
return $this->yieldFilesFromDirectory(__DIR__ . '/Fixture');
|
||||
}
|
||||
|
||||
public function provideConfigFilePath(): string
|
||||
{
|
||||
return __DIR__ . '/config/some_config.php';
|
||||
}
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Tests\RemovingStatic\Rector\Class_\DesiredClassTypeToDynamicRector\Fixture;
|
||||
|
||||
use Rector\Tests\RemovingStatic\Rector\Class_\DesiredClassTypeToDynamicRector\Source\FirstStaticClass;
|
||||
|
||||
class AnotherClass
|
||||
{
|
||||
public function run()
|
||||
{
|
||||
FirstStaticClass::someStaticFunction();
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\Tests\RemovingStatic\Rector\Class_\DesiredClassTypeToDynamicRector\Fixture;
|
||||
|
||||
use Rector\Tests\RemovingStatic\Rector\Class_\DesiredClassTypeToDynamicRector\Source\FirstStaticClass;
|
||||
|
||||
class AnotherClass
|
||||
{
|
||||
public function __construct(private \Rector\Tests\RemovingStatic\Rector\Class_\DesiredClassTypeToDynamicRector\Source\FirstStaticClass $firstStaticClass)
|
||||
{
|
||||
}
|
||||
public function run()
|
||||
{
|
||||
FirstStaticClass::someStaticFunction();
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -1,12 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Tests\RemovingStatic\Rector\Class_\DesiredClassTypeToDynamicRector\Source;
|
||||
|
||||
final class FirstStaticClass
|
||||
{
|
||||
public static function someStaticFunction()
|
||||
{
|
||||
}
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Rector\Core\Configuration\Option;
|
||||
use Rector\RemovingStatic\Rector\Class_\DesiredClassTypeToDynamicRector;
|
||||
use Rector\Tests\RemovingStatic\Rector\Class_\DesiredClassTypeToDynamicRector\Source\FirstStaticClass;
|
||||
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
|
||||
|
||||
return static function (ContainerConfigurator $containerConfigurator): void {
|
||||
$parameters = $containerConfigurator->parameters();
|
||||
$parameters->set(Option::TYPES_TO_REMOVE_STATIC_FROM, [FirstStaticClass::class]);
|
||||
|
||||
$services = $containerConfigurator->services();
|
||||
$services->set(DesiredClassTypeToDynamicRector::class);
|
||||
};
|
|
@ -1,33 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Tests\RemovingStatic\Rector\Property\DesiredPropertyClassMethodTypeToDynamicRector;
|
||||
|
||||
use Iterator;
|
||||
use Rector\Testing\PHPUnit\AbstractRectorTestCase;
|
||||
use Symplify\SmartFileSystem\SmartFileInfo;
|
||||
|
||||
final class DesiredPropertyClassMethodTypeToDynamicRectorTest extends AbstractRectorTestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider provideData()
|
||||
*/
|
||||
public function test(SmartFileInfo $fileInfo): void
|
||||
{
|
||||
$this->doTestFileInfo($fileInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Iterator<SmartFileInfo>
|
||||
*/
|
||||
public function provideData(): Iterator
|
||||
{
|
||||
return $this->yieldFilesFromDirectory(__DIR__ . '/Fixture');
|
||||
}
|
||||
|
||||
public function provideConfigFilePath(): string
|
||||
{
|
||||
return __DIR__ . '/config/some_config.php';
|
||||
}
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Tests\RemovingStatic\Rector\Property\DesiredPropertyClassMethodTypeToDynamicRector\Fixture;
|
||||
|
||||
final class StaticProperty
|
||||
{
|
||||
public static $value;
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Tests\RemovingStatic\Rector\Property\DesiredPropertyClassMethodTypeToDynamicRector\Fixture;
|
||||
|
||||
final class StaticProperty
|
||||
{
|
||||
public $value;
|
||||
}
|
||||
|
||||
?>
|
|
@ -1,16 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Rector\Core\Configuration\Option;
|
||||
use Rector\RemovingStatic\Rector\Property\DesiredPropertyClassMethodTypeToDynamicRector;
|
||||
use Rector\Tests\RemovingStatic\Rector\Property\DesiredPropertyClassMethodTypeToDynamicRector\Fixture\StaticProperty;
|
||||
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
|
||||
|
||||
return static function (ContainerConfigurator $containerConfigurator): void {
|
||||
$parameters = $containerConfigurator->parameters();
|
||||
$parameters->set(Option::TYPES_TO_REMOVE_STATIC_FROM, [StaticProperty::class]);
|
||||
|
||||
$services = $containerConfigurator->services();
|
||||
$services->set(DesiredPropertyClassMethodTypeToDynamicRector::class);
|
||||
};
|
|
@ -1,33 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Tests\RemovingStatic\Rector\StaticCall\DesiredStaticCallTypeToDynamicRector;
|
||||
|
||||
use Iterator;
|
||||
use Rector\Testing\PHPUnit\AbstractRectorTestCase;
|
||||
use Symplify\SmartFileSystem\SmartFileInfo;
|
||||
|
||||
final class DesiredStaticCallTypeToDynamicRectorTest extends AbstractRectorTestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider provideData()
|
||||
*/
|
||||
public function test(SmartFileInfo $fileInfo): void
|
||||
{
|
||||
$this->doTestFileInfo($fileInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Iterator<SmartFileInfo>
|
||||
*/
|
||||
public function provideData(): Iterator
|
||||
{
|
||||
return $this->yieldFilesFromDirectory(__DIR__ . '/Fixture');
|
||||
}
|
||||
|
||||
public function provideConfigFilePath(): string
|
||||
{
|
||||
return __DIR__ . '/config/some_config.php';
|
||||
}
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Tests\RemovingStatic\Rector\StaticCall\DesiredStaticCallTypeToDynamicRector\Fixture;
|
||||
|
||||
use Rector\Tests\RemovingStatic\Rector\StaticCall\DesiredStaticCallTypeToDynamicRector\Source\SomeStaticMethod;
|
||||
|
||||
final class SomeStaticCall
|
||||
{
|
||||
public function run()
|
||||
{
|
||||
SomeStaticMethod::go();
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\Tests\RemovingStatic\Rector\StaticCall\DesiredStaticCallTypeToDynamicRector\Fixture;
|
||||
|
||||
use Rector\Tests\RemovingStatic\Rector\StaticCall\DesiredStaticCallTypeToDynamicRector\Source\SomeStaticMethod;
|
||||
|
||||
final class SomeStaticCall
|
||||
{
|
||||
public function run()
|
||||
{
|
||||
$this->someStaticMethod->go();
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -1,12 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Tests\RemovingStatic\Rector\StaticCall\DesiredStaticCallTypeToDynamicRector\Source;
|
||||
|
||||
final class SomeStaticMethod
|
||||
{
|
||||
public static function go()
|
||||
{
|
||||
}
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Rector\Core\Configuration\Option;
|
||||
use Rector\RemovingStatic\Rector\StaticCall\DesiredStaticCallTypeToDynamicRector;
|
||||
use Rector\Tests\RemovingStatic\Rector\StaticCall\DesiredStaticCallTypeToDynamicRector\Source\SomeStaticMethod;
|
||||
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
|
||||
|
||||
return static function (ContainerConfigurator $containerConfigurator): void {
|
||||
$parameters = $containerConfigurator->parameters();
|
||||
$parameters->set(Option::TYPES_TO_REMOVE_STATIC_FROM, [SomeStaticMethod::class]);
|
||||
|
||||
$services = $containerConfigurator->services();
|
||||
$services->set(DesiredStaticCallTypeToDynamicRector::class);
|
||||
};
|
|
@ -1,33 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Tests\RemovingStatic\Rector\StaticPropertyFetch\DesiredStaticPropertyFetchTypeToDynamicRector;
|
||||
|
||||
use Iterator;
|
||||
use Rector\Testing\PHPUnit\AbstractRectorTestCase;
|
||||
use Symplify\SmartFileSystem\SmartFileInfo;
|
||||
|
||||
final class DesiredStaticPropertyFetchTypeToDynamicRectorTest extends AbstractRectorTestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider provideData()
|
||||
*/
|
||||
public function test(SmartFileInfo $fileInfo): void
|
||||
{
|
||||
$this->doTestFileInfo($fileInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Iterator<SmartFileInfo>
|
||||
*/
|
||||
public function provideData(): Iterator
|
||||
{
|
||||
return $this->yieldFilesFromDirectory(__DIR__ . '/Fixture');
|
||||
}
|
||||
|
||||
public function provideConfigFilePath(): string
|
||||
{
|
||||
return __DIR__ . '/config/some_config.php';
|
||||
}
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Tests\RemovingStatic\Rector\StaticPropertyFetch\DesiredStaticPropertyFetchTypeToDynamicRector\Fixture;
|
||||
|
||||
use Rector\Tests\RemovingStatic\Rector\StaticPropertyFetch\DesiredStaticPropertyFetchTypeToDynamicRector\Source\SomeStaticType;
|
||||
|
||||
final class SomeStaticPropertyFetch
|
||||
{
|
||||
public function run()
|
||||
{
|
||||
return SomeStaticType::$someProperty;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Tests\RemovingStatic\Rector\StaticPropertyFetch\DesiredStaticPropertyFetchTypeToDynamicRector\Fixture;
|
||||
|
||||
use Rector\Tests\RemovingStatic\Rector\StaticPropertyFetch\DesiredStaticPropertyFetchTypeToDynamicRector\Source\SomeStaticType;
|
||||
|
||||
final class SomeStaticPropertyFetch
|
||||
{
|
||||
public function __construct(private \Rector\Tests\RemovingStatic\Rector\StaticPropertyFetch\DesiredStaticPropertyFetchTypeToDynamicRector\Source\SomeStaticType $someStaticType)
|
||||
{
|
||||
}
|
||||
public function run()
|
||||
{
|
||||
return $this->someStaticType->someProperty;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -1,10 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Tests\RemovingStatic\Rector\StaticPropertyFetch\DesiredStaticPropertyFetchTypeToDynamicRector\Source;
|
||||
|
||||
final class SomeStaticType
|
||||
{
|
||||
public static $someProperty;
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Rector\Core\Configuration\Option;
|
||||
use Rector\RemovingStatic\Rector\StaticPropertyFetch\DesiredStaticPropertyFetchTypeToDynamicRector;
|
||||
use Rector\Tests\RemovingStatic\Rector\StaticPropertyFetch\DesiredStaticPropertyFetchTypeToDynamicRector\Source\SomeStaticType;
|
||||
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
|
||||
|
||||
return static function (ContainerConfigurator $containerConfigurator): void {
|
||||
$parameters = $containerConfigurator->parameters();
|
||||
$parameters->set(Option::TYPES_TO_REMOVE_STATIC_FROM, [SomeStaticType::class]);
|
||||
|
||||
$services = $containerConfigurator->services();
|
||||
$services->set(DesiredStaticPropertyFetchTypeToDynamicRector::class);
|
||||
};
|
|
@ -1,53 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\RemovingStatic\NodeAnalyzer;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Expr\StaticCall;
|
||||
use PhpParser\Node\Stmt\Class_;
|
||||
use PhpParser\Node\Stmt\ClassMethod;
|
||||
use PHPStan\Type\ObjectType;
|
||||
use Rector\Core\PhpParser\Node\BetterNodeFinder;
|
||||
use Rector\Core\ValueObject\MethodName;
|
||||
use Rector\NodeTypeResolver\NodeTypeResolver;
|
||||
|
||||
final class StaticCallPresenceAnalyzer
|
||||
{
|
||||
public function __construct(
|
||||
private readonly BetterNodeFinder $betterNodeFinder,
|
||||
private readonly NodeTypeResolver $nodeTypeResolver
|
||||
) {
|
||||
}
|
||||
|
||||
public function hasMethodStaticCallOnType(ClassMethod $classMethod, ObjectType $objectType): bool
|
||||
{
|
||||
return (bool) $this->betterNodeFinder->findFirst(
|
||||
(array) $classMethod->stmts,
|
||||
function (Node $node) use ($objectType): bool {
|
||||
if (! $node instanceof StaticCall) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->nodeTypeResolver->isObjectType($node->class, $objectType);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
public function hasClassAnyMethodWithStaticCallOnType(Class_ $class, ObjectType $objectType): bool
|
||||
{
|
||||
foreach ($class->getMethods() as $classMethod) {
|
||||
// handled else where
|
||||
if ((string) $classMethod->name === MethodName::CONSTRUCT) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($this->hasMethodStaticCallOnType($classMethod, $objectType)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -1,190 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\RemovingStatic\Rector\Class_;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Expr\Variable;
|
||||
use PhpParser\Node\Name\FullyQualified;
|
||||
use PhpParser\Node\Param;
|
||||
use PhpParser\Node\Stmt\Class_;
|
||||
use PhpParser\Node\Stmt\ClassMethod;
|
||||
use PHPStan\Type\ObjectType;
|
||||
use Rector\Core\Configuration\Option;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Rector\Core\ValueObject\MethodName;
|
||||
use Rector\Naming\Naming\PropertyNaming;
|
||||
use Rector\PostRector\Collector\PropertyToAddCollector;
|
||||
use Rector\PostRector\ValueObject\PropertyMetadata;
|
||||
use Rector\RemovingStatic\NodeAnalyzer\StaticCallPresenceAnalyzer;
|
||||
use Symplify\PackageBuilder\Parameter\ParameterProvider;
|
||||
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
|
||||
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||
|
||||
/**
|
||||
* @see \Rector\Tests\RemovingStatic\Rector\Class_\DesiredClassTypeToDynamicRector\DesiredClassTypeToDynamicRectorTest
|
||||
*/
|
||||
final class DesiredClassTypeToDynamicRector extends AbstractRector
|
||||
{
|
||||
/**
|
||||
* @var ObjectType[]
|
||||
*/
|
||||
private array $staticObjectTypes = [];
|
||||
|
||||
public function __construct(
|
||||
private readonly PropertyNaming $propertyNaming,
|
||||
private readonly StaticCallPresenceAnalyzer $staticCallPresenceAnalyzer,
|
||||
private readonly PropertyToAddCollector $propertyToAddCollector,
|
||||
ParameterProvider $parameterProvider
|
||||
) {
|
||||
$typesToRemoveStaticFrom = $parameterProvider->provideArrayParameter(Option::TYPES_TO_REMOVE_STATIC_FROM);
|
||||
foreach ($typesToRemoveStaticFrom as $typeToRemoveStaticFrom) {
|
||||
$this->staticObjectTypes[] = new ObjectType($typeToRemoveStaticFrom);
|
||||
}
|
||||
}
|
||||
|
||||
public function getRuleDefinition(): RuleDefinition
|
||||
{
|
||||
return new RuleDefinition('Change full static service, to dynamic one', [
|
||||
new CodeSample(
|
||||
<<<'CODE_SAMPLE'
|
||||
class AnotherClass
|
||||
{
|
||||
public function run()
|
||||
{
|
||||
SomeClass::someStatic();
|
||||
}
|
||||
}
|
||||
|
||||
class SomeClass
|
||||
{
|
||||
public static function run()
|
||||
{
|
||||
self::someStatic();
|
||||
}
|
||||
|
||||
private static function someStatic()
|
||||
{
|
||||
}
|
||||
}
|
||||
CODE_SAMPLE
|
||||
,
|
||||
<<<'CODE_SAMPLE'
|
||||
class AnotherClass
|
||||
{
|
||||
/**
|
||||
* @var SomeClass
|
||||
*/
|
||||
private $someClass;
|
||||
|
||||
public fuction __construct(SomeClass $someClass)
|
||||
{
|
||||
$this->someClass = $someClass;
|
||||
}
|
||||
|
||||
public function run()
|
||||
{
|
||||
SomeClass::someStatic();
|
||||
}
|
||||
}
|
||||
|
||||
class SomeClass
|
||||
{
|
||||
public function run()
|
||||
{
|
||||
$this->someStatic();
|
||||
}
|
||||
|
||||
private function someStatic()
|
||||
{
|
||||
}
|
||||
}
|
||||
CODE_SAMPLE
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<class-string<Node>>
|
||||
*/
|
||||
public function getNodeTypes(): array
|
||||
{
|
||||
return [Class_::class];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Class_ $node
|
||||
*/
|
||||
public function refactor(Node $node): ?Node
|
||||
{
|
||||
foreach ($this->staticObjectTypes as $staticObjectType) {
|
||||
// do not any dependencies to class itself
|
||||
if ($this->isObjectType($node, $staticObjectType)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->completeDependencyToConstructorOnly($node, $staticObjectType);
|
||||
|
||||
if ($this->staticCallPresenceAnalyzer->hasClassAnyMethodWithStaticCallOnType($node, $staticObjectType)) {
|
||||
$propertyExpectedName = $this->propertyNaming->fqnToVariableName($staticObjectType);
|
||||
|
||||
$propertyMetadata = new PropertyMetadata(
|
||||
$propertyExpectedName,
|
||||
$staticObjectType,
|
||||
Class_::MODIFIER_PRIVATE
|
||||
);
|
||||
$this->propertyToAddCollector->addPropertyToClass($node, $propertyMetadata);
|
||||
|
||||
return $node;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private function completeDependencyToConstructorOnly(Class_ $class, ObjectType $objectType): void
|
||||
{
|
||||
$constructClassMethod = $class->getMethod(MethodName::CONSTRUCT);
|
||||
if (! $constructClassMethod instanceof ClassMethod) {
|
||||
return;
|
||||
}
|
||||
|
||||
$hasStaticCall = $this->staticCallPresenceAnalyzer->hasMethodStaticCallOnType(
|
||||
$constructClassMethod,
|
||||
$objectType
|
||||
);
|
||||
|
||||
if (! $hasStaticCall) {
|
||||
return;
|
||||
}
|
||||
|
||||
$propertyExpectedName = $this->propertyNaming->fqnToVariableName($objectType);
|
||||
|
||||
if ($this->isTypeAlreadyInParamMethod($constructClassMethod, $objectType)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$constructClassMethod->params[] = $this->createParam($propertyExpectedName, $objectType);
|
||||
}
|
||||
|
||||
private function isTypeAlreadyInParamMethod(ClassMethod $classMethod, ObjectType $objectType): bool
|
||||
{
|
||||
foreach ($classMethod->getParams() as $param) {
|
||||
if ($param->type === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($this->isName($param->type, $objectType->getClassName())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private function createParam(string $propertyName, ObjectType $objectType): Param
|
||||
{
|
||||
return new Param(new Variable($propertyName), null, new FullyQualified($objectType->getClassName()));
|
||||
}
|
||||
}
|
|
@ -1,109 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\RemovingStatic\Rector\Property;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Stmt\ClassMethod;
|
||||
use PhpParser\Node\Stmt\Property;
|
||||
use PHPStan\Analyser\Scope;
|
||||
use PHPStan\Reflection\ClassReflection;
|
||||
use PHPStan\Type\ObjectType;
|
||||
use Rector\Core\Configuration\Option;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
use Rector\Privatization\NodeManipulator\VisibilityManipulator;
|
||||
use Symplify\PackageBuilder\Parameter\ParameterProvider;
|
||||
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
|
||||
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||
|
||||
/**
|
||||
* @see \Rector\Tests\RemovingStatic\Rector\Property\DesiredPropertyClassMethodTypeToDynamicRector\DesiredPropertyClassMethodTypeToDynamicRectorTest
|
||||
*/
|
||||
final class DesiredPropertyClassMethodTypeToDynamicRector extends AbstractRector
|
||||
{
|
||||
/**
|
||||
* @var ObjectType[]
|
||||
*/
|
||||
private array $staticObjectTypes = [];
|
||||
|
||||
public function __construct(
|
||||
ParameterProvider $parameterProvider,
|
||||
private readonly VisibilityManipulator $visibilityManipulator,
|
||||
) {
|
||||
$typesToRemoveStaticFrom = $parameterProvider->provideArrayParameter(Option::TYPES_TO_REMOVE_STATIC_FROM);
|
||||
foreach ($typesToRemoveStaticFrom as $typeToRemoveStaticFrom) {
|
||||
$this->staticObjectTypes[] = new ObjectType($typeToRemoveStaticFrom);
|
||||
}
|
||||
}
|
||||
|
||||
public function getRuleDefinition(): RuleDefinition
|
||||
{
|
||||
return new RuleDefinition('Change defined static properties and methods to dynamic', [
|
||||
new CodeSample(
|
||||
<<<'CODE_SAMPLE'
|
||||
final class SomeClass
|
||||
{
|
||||
public static $name;
|
||||
|
||||
public static function go()
|
||||
{
|
||||
}
|
||||
}
|
||||
CODE_SAMPLE
|
||||
,
|
||||
<<<'CODE_SAMPLE'
|
||||
final class SomeClass
|
||||
{
|
||||
public $name;
|
||||
|
||||
public function go()
|
||||
{
|
||||
}
|
||||
}
|
||||
CODE_SAMPLE
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<class-string<Node>>
|
||||
*/
|
||||
public function getNodeTypes(): array
|
||||
{
|
||||
return [Property::class, ClassMethod::class];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Property|ClassMethod $node
|
||||
*/
|
||||
public function refactor(Node $node): ?Node
|
||||
{
|
||||
/** @var Scope $scope */
|
||||
$scope = $node->getAttribute(AttributeKey::SCOPE);
|
||||
|
||||
$classReflection = $scope->getClassReflection();
|
||||
if (! $classReflection instanceof ClassReflection) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$classObjectType = new ObjectType($classReflection->getName());
|
||||
|
||||
foreach ($this->staticObjectTypes as $staticObjectType) {
|
||||
if (! $staticObjectType->isSuperTypeOf($classObjectType)->yes()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (! $node->isStatic()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$this->visibilityManipulator->makeNonStatic($node);
|
||||
|
||||
return $node;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -1,116 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\RemovingStatic\Rector\StaticCall;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Expr\MethodCall;
|
||||
use PhpParser\Node\Expr\PropertyFetch;
|
||||
use PhpParser\Node\Expr\StaticCall;
|
||||
use PhpParser\Node\Expr\Variable;
|
||||
use PhpParser\Node\Stmt\ClassMethod;
|
||||
use PHPStan\Type\ObjectType;
|
||||
use Rector\Core\Configuration\Option;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Rector\Core\ValueObject\MethodName;
|
||||
use Rector\Naming\Naming\PropertyNaming;
|
||||
use Symplify\PackageBuilder\Parameter\ParameterProvider;
|
||||
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
|
||||
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||
|
||||
/**
|
||||
* @see \Rector\Tests\RemovingStatic\Rector\StaticCall\DesiredStaticCallTypeToDynamicRector\DesiredStaticCallTypeToDynamicRectorTest
|
||||
*/
|
||||
final class DesiredStaticCallTypeToDynamicRector extends AbstractRector
|
||||
{
|
||||
/**
|
||||
* @var ObjectType[]
|
||||
*/
|
||||
private array $staticObjectTypes = [];
|
||||
|
||||
public function __construct(
|
||||
private readonly PropertyNaming $propertyNaming,
|
||||
ParameterProvider $parameterProvider
|
||||
) {
|
||||
$typesToRemoveStaticFrom = $parameterProvider->provideArrayParameter(Option::TYPES_TO_REMOVE_STATIC_FROM);
|
||||
foreach ($typesToRemoveStaticFrom as $typeToRemoveStaticFrom) {
|
||||
$this->staticObjectTypes[] = new ObjectType($typeToRemoveStaticFrom);
|
||||
}
|
||||
}
|
||||
|
||||
public function getRuleDefinition(): RuleDefinition
|
||||
{
|
||||
return new RuleDefinition('Change defined static service to dynamic one', [
|
||||
new CodeSample(
|
||||
<<<'CODE_SAMPLE'
|
||||
final class SomeClass
|
||||
{
|
||||
public function run()
|
||||
{
|
||||
SomeStaticMethod::someStatic();
|
||||
}
|
||||
}
|
||||
CODE_SAMPLE
|
||||
,
|
||||
<<<'CODE_SAMPLE'
|
||||
final class SomeClass
|
||||
{
|
||||
public function run()
|
||||
{
|
||||
$this->someStaticMethod->someStatic();
|
||||
}
|
||||
}
|
||||
CODE_SAMPLE
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<class-string<Node>>
|
||||
*/
|
||||
public function getNodeTypes(): array
|
||||
{
|
||||
return [StaticCall::class];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param StaticCall $node
|
||||
*/
|
||||
public function refactor(Node $node): ?Node
|
||||
{
|
||||
foreach ($this->staticObjectTypes as $staticObjectType) {
|
||||
if (! $this->isObjectType($node->class, $staticObjectType)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// is the same class or external call?
|
||||
$className = $this->getName($node->class);
|
||||
if ($className === 'self') {
|
||||
return $this->createFromSelf($node);
|
||||
}
|
||||
|
||||
$propertyName = $this->propertyNaming->fqnToVariableName($staticObjectType);
|
||||
|
||||
$classMethod = $this->betterNodeFinder->findParentType($node, ClassMethod::class);
|
||||
if (! $classMethod instanceof ClassMethod) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($this->nodeNameResolver->isName($classMethod, MethodName::CONSTRUCT)) {
|
||||
$propertyFetch = new Variable($propertyName);
|
||||
} else {
|
||||
$propertyFetch = new PropertyFetch(new Variable('this'), $propertyName);
|
||||
}
|
||||
|
||||
return new MethodCall($propertyFetch, $node->name, $node->args);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private function createFromSelf(StaticCall $staticCall): MethodCall
|
||||
{
|
||||
return new MethodCall(new Variable('this'), $staticCall->name, $staticCall->args);
|
||||
}
|
||||
}
|
|
@ -1,125 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\RemovingStatic\Rector\StaticPropertyFetch;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Expr\PropertyFetch;
|
||||
use PhpParser\Node\Expr\StaticPropertyFetch;
|
||||
use PhpParser\Node\Expr\Variable;
|
||||
use PhpParser\Node\Stmt\Class_;
|
||||
use PHPStan\Analyser\Scope;
|
||||
use PHPStan\Reflection\ClassReflection;
|
||||
use PHPStan\Type\ObjectType;
|
||||
use Rector\Core\Configuration\Option;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Rector\Naming\Naming\PropertyNaming;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
use Rector\PostRector\Collector\PropertyToAddCollector;
|
||||
use Rector\PostRector\ValueObject\PropertyMetadata;
|
||||
use Symplify\PackageBuilder\Parameter\ParameterProvider;
|
||||
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
|
||||
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||
|
||||
/**
|
||||
* @see \Rector\Tests\RemovingStatic\Rector\StaticPropertyFetch\DesiredStaticPropertyFetchTypeToDynamicRector\DesiredStaticPropertyFetchTypeToDynamicRectorTest
|
||||
*/
|
||||
final class DesiredStaticPropertyFetchTypeToDynamicRector extends AbstractRector
|
||||
{
|
||||
/**
|
||||
* @var ObjectType[]
|
||||
*/
|
||||
private array $staticObjectTypes = [];
|
||||
|
||||
public function __construct(
|
||||
private readonly PropertyNaming $propertyNaming,
|
||||
private readonly PropertyToAddCollector $propertyToAddCollector,
|
||||
ParameterProvider $parameterProvider
|
||||
) {
|
||||
$typesToRemoveStaticFrom = $parameterProvider->provideArrayParameter(Option::TYPES_TO_REMOVE_STATIC_FROM);
|
||||
foreach ($typesToRemoveStaticFrom as $typeToRemoveStaticFrom) {
|
||||
$this->staticObjectTypes[] = new ObjectType($typeToRemoveStaticFrom);
|
||||
}
|
||||
}
|
||||
|
||||
public function getRuleDefinition(): RuleDefinition
|
||||
{
|
||||
return new RuleDefinition('Change defined static service to dynamic one', [
|
||||
new CodeSample(
|
||||
<<<'CODE_SAMPLE'
|
||||
final class SomeClass
|
||||
{
|
||||
public function run()
|
||||
{
|
||||
SomeStaticMethod::$someStatic;
|
||||
}
|
||||
}
|
||||
CODE_SAMPLE
|
||||
,
|
||||
<<<'CODE_SAMPLE'
|
||||
final class SomeClass
|
||||
{
|
||||
public function run()
|
||||
{
|
||||
$this->someStaticMethod->someStatic;
|
||||
}
|
||||
}
|
||||
CODE_SAMPLE
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<class-string<Node>>
|
||||
*/
|
||||
public function getNodeTypes(): array
|
||||
{
|
||||
return [StaticPropertyFetch::class];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param StaticPropertyFetch $node
|
||||
*/
|
||||
public function refactor(Node $node): ?Node
|
||||
{
|
||||
/** @var Scope $scope */
|
||||
$scope = $node->getAttribute(AttributeKey::SCOPE);
|
||||
|
||||
$classReflection = $scope->getClassReflection();
|
||||
if (! $classReflection instanceof ClassReflection) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$classObjectType = new ObjectType($classReflection->getName());
|
||||
|
||||
// A. remove local fetch
|
||||
foreach ($this->staticObjectTypes as $staticObjectType) {
|
||||
if (! $staticObjectType->isSuperTypeOf($classObjectType)->yes()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
return new PropertyFetch(new Variable('this'), $node->name);
|
||||
}
|
||||
|
||||
// B. external property fetch
|
||||
foreach ($this->staticObjectTypes as $staticObjectType) {
|
||||
if (! $this->isObjectType($node->class, $staticObjectType)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$propertyName = $this->propertyNaming->fqnToVariableName($staticObjectType);
|
||||
|
||||
/** @var Class_ $class */
|
||||
$class = $this->betterNodeFinder->findParentType($node, Class_::class);
|
||||
|
||||
$propertyMetadata = new PropertyMetadata($propertyName, $staticObjectType, Class_::MODIFIER_PRIVATE);
|
||||
$this->propertyToAddCollector->addPropertyToClass($class, $propertyMetadata);
|
||||
|
||||
$objectPropertyFetch = new PropertyFetch(new Variable('this'), $propertyName);
|
||||
return new PropertyFetch($objectPropertyFetch, $node->name);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -141,11 +141,6 @@ final class Option
|
|||
*/
|
||||
public const PHPSTAN_FOR_RECTOR_PATH = 'phpstan_for_rector_path';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public const TYPES_TO_REMOVE_STATIC_FROM = 'types_to_remove_static_from';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue
Block a user