mirror of
https://github.com/rectorphp/rector.git
synced 2025-03-11 02:49:42 +01:00
[Injection] Add StaticCallToAnotherServiceConstructorInjectionRector
This commit is contained in:
parent
407e0c4d33
commit
9c08060925
@ -145,7 +145,8 @@
|
||||
"Rector\\NetteCodeQuality\\": "rules/nette-code-quality/src",
|
||||
"Rector\\Decomplex\\": "rules/decomplex/src",
|
||||
"Rector\\Downgrade\\": "rules/downgrade/src",
|
||||
"Rector\\SymfonyPhpConfig\\": "rules/symfony-php-config/src"
|
||||
"Rector\\SymfonyPhpConfig\\": "rules/symfony-php-config/src",
|
||||
"Rector\\Injection\\": "rules/injection/src"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
@ -225,7 +226,8 @@
|
||||
"Rector\\NetteCodeQuality\\Tests\\": "rules/nette-code-quality/tests",
|
||||
"Rector\\Decomplex\\Tests\\": "rules/decomplex/tests",
|
||||
"Rector\\Downgrade\\Tests\\": "rules/downgrade/tests",
|
||||
"Rector\\SymfonyPhpConfig\\Tests\\": "rules/symfony-php-config/tests"
|
||||
"Rector\\SymfonyPhpConfig\\Tests\\": "rules/symfony-php-config/tests",
|
||||
"Rector\\Injection\\Tests\\": "rules/injection/tests"
|
||||
},
|
||||
"classmap": [
|
||||
"rules/cakephp/tests/Rector/Name/ImplicitShortClassNameUseStatementRector/Source",
|
||||
|
@ -39,7 +39,7 @@ final class ConfigurationFactory
|
||||
$extraFileContent = isset($rectorRecipe['extra_file_content']) ? $this->normalizeCode(
|
||||
$rectorRecipe['extra_file_content']
|
||||
) : null;
|
||||
$set = $this->setResolver->resolveSetByName($rectorRecipe['set']);
|
||||
$set = $rectorRecipe['set'] ? $this->setResolver->resolveSetByName($rectorRecipe['set']) : null;
|
||||
|
||||
return new Configuration(
|
||||
$rectorRecipe['package'],
|
||||
|
@ -0,0 +1,126 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Injection\Rector\StaticCall;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Expr\MethodCall;
|
||||
use PhpParser\Node\Expr\StaticCall;
|
||||
use PhpParser\Node\Stmt\Class_;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Rector\Core\RectorDefinition\ConfiguredCodeSample;
|
||||
use Rector\Core\RectorDefinition\RectorDefinition;
|
||||
use Rector\Injection\ValueObject\StaticCallToMethodCall;
|
||||
use Rector\Naming\Naming\PropertyNaming;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
use Rector\PHPStan\Type\FullyQualifiedObjectType;
|
||||
|
||||
/**
|
||||
* @see \Rector\Injection\Tests\Rector\StaticCall\StaticCallToAnotherServiceConstructorInjectionRector\StaticCallToAnotherServiceConstructorInjectionRectorTest
|
||||
*/
|
||||
final class StaticCallToAnotherServiceConstructorInjectionRector extends AbstractRector
|
||||
{
|
||||
/**
|
||||
* @var StaticCallToMethodCall[]
|
||||
*/
|
||||
private $staticCallsToMethodCalls;
|
||||
|
||||
/**
|
||||
* @var PropertyNaming
|
||||
*/
|
||||
private $propertyNaming;
|
||||
|
||||
/**
|
||||
* @param StaticCallToMethodCall[] $staticCallsToMethodCalls
|
||||
*/
|
||||
public function __construct(array $staticCallsToMethodCalls, PropertyNaming $propertyNaming)
|
||||
{
|
||||
$this->staticCallsToMethodCalls = $staticCallsToMethodCalls;
|
||||
$this->propertyNaming = $propertyNaming;
|
||||
}
|
||||
|
||||
public function getDefinition(): RectorDefinition
|
||||
{
|
||||
return new RectorDefinition('Change static call to service method via constructor injection', [
|
||||
new ConfiguredCodeSample(
|
||||
<<<'PHP'
|
||||
use Nette\Utils\FileSystem;
|
||||
|
||||
class SomeClass
|
||||
{
|
||||
public function run()
|
||||
{
|
||||
return FileSystem::write('file', 'content');
|
||||
}
|
||||
}
|
||||
PHP
|
||||
,
|
||||
<<<'PHP'
|
||||
use Symplify\SmartFileSystem\SmartFileSystem;
|
||||
|
||||
class SomeClass
|
||||
{
|
||||
/**
|
||||
* @var SmartFileSystem
|
||||
*/
|
||||
private $smartFileSystem;
|
||||
public function __construct(SmartFileSystem $smartFileSystem)
|
||||
{
|
||||
$this->smartFileSystem = $smartFileSystem;
|
||||
}
|
||||
public function run()
|
||||
{
|
||||
return $this->smartFileSystem->dumpFile('file', 'content');
|
||||
}
|
||||
}
|
||||
PHP
|
||||
, [
|
||||
'$staticCallsToMethodCalls' => [
|
||||
new StaticCallToMethodCall(
|
||||
'Nette\Utils\FileSystem',
|
||||
'write',
|
||||
'Symplify\SmartFileSystem\SmartFileSystem',
|
||||
'dumpFile'
|
||||
),
|
||||
],
|
||||
]),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function getNodeTypes(): array
|
||||
{
|
||||
return [StaticCall::class];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param StaticCall $node
|
||||
*/
|
||||
public function refactor(Node $node): ?Node
|
||||
{
|
||||
$class = $node->getAttribute(AttributeKey::CLASS_NODE);
|
||||
if (! $class instanceof Class_) {
|
||||
return null;
|
||||
}
|
||||
|
||||
foreach ($this->staticCallsToMethodCalls as $staticCallsToMethodCall) {
|
||||
if (! $staticCallsToMethodCall->matchStaticCall($node)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$serviceObjectType = new FullyQualifiedObjectType($staticCallsToMethodCall->getClassType());
|
||||
|
||||
$propertyName = $this->propertyNaming->fqnToVariableName($serviceObjectType);
|
||||
$this->addPropertyToClass($class, $serviceObjectType, $propertyName);
|
||||
|
||||
$propertyFetchNode = $this->createPropertyFetch('this', $propertyName);
|
||||
|
||||
return new MethodCall($propertyFetchNode, $staticCallsToMethodCall->getMethodName(), $node->args);
|
||||
}
|
||||
|
||||
return $node;
|
||||
}
|
||||
}
|
69
rules/injection/src/ValueObject/StaticCallToMethodCall.php
Normal file
69
rules/injection/src/ValueObject/StaticCallToMethodCall.php
Normal file
@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Injection\ValueObject;
|
||||
|
||||
use PhpParser\Node\Expr\StaticCall;
|
||||
use PhpParser\Node\Identifier;
|
||||
use PhpParser\Node\Name;
|
||||
|
||||
final class StaticCallToMethodCall
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $staticClass;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $staticMethod;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $classType;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $methodName;
|
||||
|
||||
public function __construct(string $staticClass, string $staticMethod, string $classType, string $methodName)
|
||||
{
|
||||
$this->staticClass = $staticClass;
|
||||
$this->staticMethod = $staticMethod;
|
||||
$this->classType = $classType;
|
||||
$this->methodName = $methodName;
|
||||
}
|
||||
|
||||
public function getClassType(): string
|
||||
{
|
||||
return $this->classType;
|
||||
}
|
||||
|
||||
public function getMethodName(): string
|
||||
{
|
||||
return $this->methodName;
|
||||
}
|
||||
|
||||
public function matchStaticCall(StaticCall $staticCall): bool
|
||||
{
|
||||
if (! $staticCall->class instanceof Name) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$staticCallClassName = $staticCall->class->toString();
|
||||
if ($staticCallClassName !== $this->staticClass) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (! $staticCall->name instanceof Identifier) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$staticCallMethodName = $staticCall->name->toString();
|
||||
return $staticCallMethodName === $this->staticMethod;
|
||||
}
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace Rector\Injection\Tests\Rector\StaticCall\StaticCallToAnotherServiceConstructorInjectionRector\Fixture;
|
||||
|
||||
use Nette\Utils\FileSystem;
|
||||
|
||||
class SomeClass
|
||||
{
|
||||
public function run()
|
||||
{
|
||||
return FileSystem::write('file', 'content');
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\Injection\Tests\Rector\StaticCall\StaticCallToAnotherServiceConstructorInjectionRector\Fixture;
|
||||
|
||||
use Nette\Utils\FileSystem;
|
||||
|
||||
class SomeClass
|
||||
{
|
||||
private \Symplify\SmartFileSystem\SmartFileSystem $smartFileSystem;
|
||||
public function __construct(\Symplify\SmartFileSystem\SmartFileSystem $smartFileSystem)
|
||||
{
|
||||
$this->smartFileSystem = $smartFileSystem;
|
||||
}
|
||||
public function run()
|
||||
{
|
||||
return $this->smartFileSystem->dumpFile('file', 'content');
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Injection\Tests\Rector\StaticCall\StaticCallToAnotherServiceConstructorInjectionRector;
|
||||
|
||||
use Iterator;
|
||||
use Rector\Core\Testing\PHPUnit\AbstractRectorTestCase;
|
||||
use Rector\Injection\Rector\StaticCall\StaticCallToAnotherServiceConstructorInjectionRector;
|
||||
use Rector\Injection\ValueObject\StaticCallToMethodCall;
|
||||
use Symplify\SmartFileSystem\SmartFileInfo;
|
||||
|
||||
final class StaticCallToAnotherServiceConstructorInjectionRectorTest extends AbstractRectorTestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider provideData()
|
||||
*/
|
||||
public function test(SmartFileInfo $fileInfo): void
|
||||
{
|
||||
$this->doTestFileInfo($fileInfo);
|
||||
}
|
||||
|
||||
public function provideData(): Iterator
|
||||
{
|
||||
return $this->yieldFilesFromDirectory(__DIR__ . '/Fixture');
|
||||
}
|
||||
|
||||
protected function getRectorsWithConfiguration(): array
|
||||
{
|
||||
$configuration = [
|
||||
new StaticCallToMethodCall(
|
||||
'Nette\Utils\FileSystem',
|
||||
'write',
|
||||
'Symplify\SmartFileSystem\SmartFileSystem',
|
||||
'dumpFile'
|
||||
),
|
||||
];
|
||||
|
||||
return [
|
||||
StaticCallToAnotherServiceConstructorInjectionRector::class => [
|
||||
'$staticCallsToMethodCalls' => $configuration,
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user