Last active
November 3, 2021 20:36
-
-
Save alexanderschnitzler/f664b458f2bc47833c7a55f93b5a363d to your computer and use it in GitHub Desktop.
InjectMethodToConstructorInjectionRector.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
declare(strict_types=1); | |
namespace FriendsOfTYPO3\Rector\TYPO3\Rector\Extbase; | |
use Rector\Core\Rector\AbstractRector; | |
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition; | |
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample; | |
use PhpParser\Node\Param; | |
use PhpParser\Node\Name\FullyQualified; | |
use PhpParser\Node; | |
use PhpParser\Node\Stmt\Class_; | |
use PHPStan\Type\ObjectType; | |
use Rector\Core\NodeManipulator\ClassDependencyManipulator; | |
use Rector\PostRector\ValueObject\PropertyMetadata; | |
final class InjectMethodToConstructorInjectionRector extends AbstractRector | |
{ | |
private $classDependencyManipulator; | |
public function __construct(ClassDependencyManipulator $classDependencyManipulator) { | |
$this->classDependencyManipulator = $classDependencyManipulator; | |
} | |
public function getRuleDefinition(): RuleDefinition | |
{ | |
return new RuleDefinition( | |
'', | |
[ | |
new CodeSample(<<<'CODE_SAMPLE' | |
namespace App\Service; | |
use \TYPO3\CMS\Core\Cache\CacheManager; | |
class Service | |
{ | |
private CacheManager $cacheManager; | |
public function injectCacheManager(CacheManager $cacheManager): void | |
{ | |
$this->cacheManager = $cacheManager; | |
} | |
} | |
CODE_SAMPLE, <<<'CODE_SAMPLE' | |
namespace App\Service; | |
use \TYPO3\CMS\Core\Cache\CacheManager; | |
class Service | |
{ | |
private CacheManager $cacheManager; | |
public function __construct(CacheManager $cacheManager) | |
{ | |
$this->cacheManager = $cacheManager; | |
} | |
} | |
CODE_SAMPLE | |
) | |
] | |
); | |
} | |
/** | |
* List of nodes this class checks, classes that implements \PhpParser\Node | |
* See beautiful map of all nodes https://github.com/rectorphp/rector/blob/master/docs/NodesOverview.md | |
* | |
* @return class-string[] | |
*/ | |
public function getNodeTypes(): array | |
{ | |
return [Class_::class]; | |
} | |
/** | |
* Process Node of matched type | |
*/ | |
public function refactor(Node $node): ?Node | |
{ | |
/** @var Class_ $node */ | |
if ($this->shouldSkip($node)) { | |
return null; | |
} | |
$injectMethods = array_filter($node->getMethods(), function ($classMethod) { | |
return strncmp((string)$classMethod->name, 'inject', 6) === 0; | |
}); | |
if ($injectMethods === []) { | |
return null; | |
} | |
foreach ($injectMethods as $injectMethod) { | |
$params = $injectMethod->getParams(); | |
if (empty($params)) { | |
continue; | |
} | |
reset($params); | |
/** @var Param $param */ | |
$param = current($params); | |
if (!$param->type instanceof FullyQualified) { | |
continue; | |
} | |
$this->classDependencyManipulator->addConstructorDependency( | |
$node, | |
new PropertyMetadata( | |
(string)$param->var->name, | |
new ObjectType((string)$param->type), | |
Class_::MODIFIER_PROTECTED | |
) | |
); | |
$this->removeNodeFromStatements($node, $injectMethod); | |
} | |
return $node; | |
} | |
private function shouldSkip(Class_ $class): bool | |
{ | |
return $class->getMethods() === []; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment