mirror of https://github.com/rectorphp/rector.git
Decopule ChildClassMethodDecorator, and DependencyClassMethodDecorator (#600)
This commit is contained in:
parent
c2acf79190
commit
45766e1d95
|
@ -24,11 +24,11 @@
|
|||
"phpstan/phpstan-phpunit": "^0.12.21",
|
||||
"rector/extension-installer": "^0.11.0",
|
||||
"rector/rector-cakephp": "^0.11.3",
|
||||
"rector/rector-doctrine": "^0.11.13",
|
||||
"rector/rector-laravel": "^0.11.4",
|
||||
"rector/rector-nette": "^0.11.16",
|
||||
"rector/rector-phpunit": "^0.11.6",
|
||||
"rector/rector-symfony": "^0.11.12",
|
||||
"rector/rector-doctrine": "^0.11.15",
|
||||
"rector/rector-laravel": "^0.11.5",
|
||||
"rector/rector-nette": "^0.11.21",
|
||||
"rector/rector-phpunit": "^0.11.7",
|
||||
"rector/rector-symfony": "^0.11.16",
|
||||
"rector/rector-phpoffice": "^0.11.2",
|
||||
"sebastian/diff": "^4.0.4",
|
||||
"ssch/typo3-rector": "^0.11.22",
|
||||
|
|
|
@ -1,92 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\NodeCollector\NodeCollector;
|
||||
|
||||
use PhpParser\Node\Stmt\Class_;
|
||||
use PHPStan\Reflection\ReflectionProvider;
|
||||
use Rector\Core\Exception\ShouldNotHappenException;
|
||||
use Rector\Core\NodeAnalyzer\ClassAnalyzer;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
|
||||
/**
|
||||
* This service contains all the parsed nodes. E.g. all the functions, method call, classes, static calls etc. It's
|
||||
* useful in case of context analysis, e.g. find all the usage of class method to detect, if the method is used.
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
final class NodeRepository
|
||||
{
|
||||
/**
|
||||
* @deprecated Not reliable, as only works with so-far parsed classes
|
||||
* @var Class_[]
|
||||
*/
|
||||
private array $classes = [];
|
||||
|
||||
public function __construct(
|
||||
private ClassAnalyzer $classAnalyzer,
|
||||
private ReflectionProvider $reflectionProvider,
|
||||
) {
|
||||
}
|
||||
|
||||
public function collectClass(Class_ $class): void
|
||||
{
|
||||
if ($this->classAnalyzer->isAnonymousClass($class)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$className = $class->getAttribute(AttributeKey::CLASS_NAME);
|
||||
if ($className === null) {
|
||||
throw new ShouldNotHappenException();
|
||||
}
|
||||
|
||||
$this->classes[$className] = $class;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param class-string $className
|
||||
* @return Class_[]
|
||||
* @deprecated Use static reflection instead
|
||||
*/
|
||||
public function findChildrenOfClass(string $className): array
|
||||
{
|
||||
$childrenClasses = [];
|
||||
|
||||
// @todo refactor to reflection
|
||||
foreach ($this->classes as $class) {
|
||||
$currentClassName = $class->getAttribute(AttributeKey::CLASS_NAME);
|
||||
if ($currentClassName === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (! $this->isChildOrEqualClassLike($className, $currentClassName)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$childrenClasses[] = $class;
|
||||
}
|
||||
|
||||
return $childrenClasses;
|
||||
}
|
||||
|
||||
private function isChildOrEqualClassLike(string $desiredClass, string $currentClassName): bool
|
||||
{
|
||||
if (! $this->reflectionProvider->hasClass($desiredClass)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (! $this->reflectionProvider->hasClass($currentClassName)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$desiredClassReflection = $this->reflectionProvider->getClass($desiredClass);
|
||||
$currentClassReflection = $this->reflectionProvider->getClass($currentClassName);
|
||||
|
||||
if (! $currentClassReflection->isSubclassOf($desiredClassReflection->getName())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $currentClassName !== $desiredClass;
|
||||
}
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\NodeCollector\NodeVisitor;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Stmt\Class_;
|
||||
use PhpParser\NodeVisitorAbstract;
|
||||
use Rector\NodeCollector\NodeCollector\NodeRepository;
|
||||
|
||||
final class NodeCollectorNodeVisitor extends NodeVisitorAbstract
|
||||
{
|
||||
public function __construct(
|
||||
private NodeRepository $nodeRepository,
|
||||
) {
|
||||
}
|
||||
|
||||
public function enterNode(Node $node)
|
||||
{
|
||||
if ($node instanceof Class_) {
|
||||
$this->nodeRepository->collectClass($node);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -10,7 +10,6 @@ use PhpParser\NodeVisitor\CloningVisitor;
|
|||
use PhpParser\NodeVisitor\NameResolver;
|
||||
use PhpParser\NodeVisitor\NodeConnectingVisitor;
|
||||
use Rector\Core\ValueObject\Application\File;
|
||||
use Rector\NodeCollector\NodeVisitor\NodeCollectorNodeVisitor;
|
||||
use Rector\NodeTypeResolver\NodeVisitor\FileNodeVisitor;
|
||||
use Rector\NodeTypeResolver\NodeVisitor\FunctionLikeParamArgPositionNodeVisitor;
|
||||
use Rector\NodeTypeResolver\NodeVisitor\FunctionMethodAndClassNodeVisitor;
|
||||
|
@ -24,7 +23,6 @@ final class NodeScopeAndMetadataDecorator
|
|||
private CloningVisitor $cloningVisitor,
|
||||
private FunctionMethodAndClassNodeVisitor $functionMethodAndClassNodeVisitor,
|
||||
private NamespaceNodeVisitor $namespaceNodeVisitor,
|
||||
private NodeCollectorNodeVisitor $nodeCollectorNodeVisitor,
|
||||
private PHPStanNodeScopeResolver $phpStanNodeScopeResolver,
|
||||
private StatementNodeVisitor $statementNodeVisitor,
|
||||
private NodeConnectingVisitor $nodeConnectingVisitor,
|
||||
|
@ -78,7 +76,6 @@ final class NodeScopeAndMetadataDecorator
|
|||
// this split is needed, so nodes have names, classes and namespaces
|
||||
$nodeTraverser = new NodeTraverser();
|
||||
$nodeTraverser->addVisitor($this->statementNodeVisitor);
|
||||
$nodeTraverser->addVisitor($this->nodeCollectorNodeVisitor);
|
||||
|
||||
return $nodeTraverser->traverse($nodes);
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ use PHPStan\Analyser\Scope;
|
|||
use PHPStan\Reflection\ClassReflection;
|
||||
use PHPStan\Type\Type;
|
||||
use Rector\Core\NodeAnalyzer\PropertyPresenceChecker;
|
||||
use Rector\Core\NodeManipulator\Dependency\DependencyClassMethodDecorator;
|
||||
use Rector\Core\Php\PhpVersionProvider;
|
||||
use Rector\Core\PhpParser\Node\NodeFactory;
|
||||
use Rector\Core\ValueObject\MethodName;
|
||||
|
@ -29,7 +30,6 @@ use Rector\TypeDeclaration\NodeAnalyzer\AutowiredClassMethodOrPropertyAnalyzer;
|
|||
final class ClassDependencyManipulator
|
||||
{
|
||||
public function __construct(
|
||||
private ChildAndParentClassManipulator $childAndParentClassManipulator,
|
||||
private ClassInsertManipulator $classInsertManipulator,
|
||||
private ClassMethodAssignManipulator $classMethodAssignManipulator,
|
||||
private NodeFactory $nodeFactory,
|
||||
|
@ -38,7 +38,8 @@ final class ClassDependencyManipulator
|
|||
private PropertyPresenceChecker $propertyPresenceChecker,
|
||||
private NodeNameResolver $nodeNameResolver,
|
||||
private NodesToRemoveCollector $nodesToRemoveCollector,
|
||||
private AutowiredClassMethodOrPropertyAnalyzer $autowiredClassMethodOrPropertyAnalyzer
|
||||
private AutowiredClassMethodOrPropertyAnalyzer $autowiredClassMethodOrPropertyAnalyzer,
|
||||
private DependencyClassMethodDecorator $dependencyClassMethodDecorator
|
||||
) {
|
||||
}
|
||||
|
||||
|
@ -97,8 +98,11 @@ final class ClassDependencyManipulator
|
|||
/** @var Scope $scope */
|
||||
$scope = $class->getAttribute(AttributeKey::SCOPE);
|
||||
|
||||
$this->childAndParentClassManipulator->completeParentConstructor($class, $constructorMethod, $scope);
|
||||
$this->childAndParentClassManipulator->completeChildConstructors($class, $constructorMethod);
|
||||
$this->dependencyClassMethodDecorator->decorateConstructorWithParentDependencies(
|
||||
$class,
|
||||
$constructorMethod,
|
||||
$scope
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -162,8 +166,11 @@ final class ClassDependencyManipulator
|
|||
/** @var Scope $scope */
|
||||
$scope = $class->getAttribute(AttributeKey::SCOPE);
|
||||
|
||||
$this->childAndParentClassManipulator->completeParentConstructor($class, $constructClassMethod, $scope);
|
||||
$this->childAndParentClassManipulator->completeChildConstructors($class, $constructClassMethod);
|
||||
$this->dependencyClassMethodDecorator->decorateConstructorWithParentDependencies(
|
||||
$class,
|
||||
$constructClassMethod,
|
||||
$scope
|
||||
);
|
||||
}
|
||||
|
||||
private function hasClassParentClassMethod(Class_ $class, string $methodName): bool
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Core\NodeManipulator;
|
||||
namespace Rector\Core\NodeManipulator\Dependency;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Param;
|
||||
|
@ -15,16 +15,14 @@ use Rector\Core\NodeAnalyzer\PromotedPropertyParamCleaner;
|
|||
use Rector\Core\PhpParser\AstResolver;
|
||||
use Rector\Core\PhpParser\Node\NodeFactory;
|
||||
use Rector\Core\ValueObject\MethodName;
|
||||
use Rector\NodeCollector\NodeCollector\NodeRepository;
|
||||
use Rector\NodeNameResolver\NodeNameResolver;
|
||||
use Symplify\Astral\NodeTraverser\SimpleCallableNodeTraverser;
|
||||
|
||||
final class ChildAndParentClassManipulator
|
||||
final class DependencyClassMethodDecorator
|
||||
{
|
||||
public function __construct(
|
||||
private NodeFactory $nodeFactory,
|
||||
private NodeNameResolver $nodeNameResolver,
|
||||
private NodeRepository $nodeRepository,
|
||||
private PromotedPropertyParamCleaner $promotedPropertyParamCleaner,
|
||||
private ReflectionProvider $reflectionProvider,
|
||||
private AstResolver $astResolver,
|
||||
|
@ -35,8 +33,11 @@ final class ChildAndParentClassManipulator
|
|||
/**
|
||||
* Add "parent::__construct(X, Y, Z)" where needed
|
||||
*/
|
||||
public function completeParentConstructor(Class_ $class, ClassMethod $classMethod, Scope $scope): void
|
||||
{
|
||||
public function decorateConstructorWithParentDependencies(
|
||||
Class_ $class,
|
||||
ClassMethod $classMethod,
|
||||
Scope $scope
|
||||
): void {
|
||||
$className = $this->nodeNameResolver->getName($class);
|
||||
if ($className === null) {
|
||||
return;
|
||||
|
@ -68,38 +69,6 @@ final class ChildAndParentClassManipulator
|
|||
}
|
||||
}
|
||||
|
||||
public function completeChildConstructors(Class_ $class, ClassMethod $constructorClassMethod): void
|
||||
{
|
||||
$className = $this->nodeNameResolver->getName($class);
|
||||
if ($className === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
$childClasses = $this->nodeRepository->findChildrenOfClass($className);
|
||||
|
||||
foreach ($childClasses as $childClass) {
|
||||
$childConstructorClassMethod = $childClass->getMethod(MethodName::CONSTRUCT);
|
||||
if (! $childConstructorClassMethod instanceof ClassMethod) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// replicate parent parameters
|
||||
$childConstructorClassMethod->params = array_merge(
|
||||
$constructorClassMethod->params,
|
||||
$childConstructorClassMethod->params
|
||||
);
|
||||
|
||||
$parentConstructCallNode = $this->nodeFactory->createParentConstructWithParams(
|
||||
$constructorClassMethod->params
|
||||
);
|
||||
|
||||
$childConstructorClassMethod->stmts = array_merge(
|
||||
[new Expression($parentConstructCallNode)],
|
||||
(array) $childConstructorClassMethod->stmts
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private function completeParentConstructorBasedOnParentNode(
|
||||
ClassMethod $classMethod,
|
||||
ClassMethod $parentClassMethod
|
|
@ -37,7 +37,6 @@ use Rector\Core\PhpParser\Printer\BetterStandardPrinter;
|
|||
use Rector\Core\Provider\CurrentFileProvider;
|
||||
use Rector\Core\Validation\InfiniteLoopValidator;
|
||||
use Rector\Core\ValueObject\Application\File;
|
||||
use Rector\NodeCollector\NodeCollector\NodeRepository;
|
||||
use Rector\NodeNameResolver\NodeNameResolver;
|
||||
use Rector\NodeRemoval\NodeRemover;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
|
@ -94,8 +93,6 @@ abstract class AbstractRector extends NodeVisitorAbstract implements PhpRectorIn
|
|||
|
||||
protected ValueResolver $valueResolver;
|
||||
|
||||
protected NodeRepository $nodeRepository;
|
||||
|
||||
protected BetterNodeFinder $betterNodeFinder;
|
||||
|
||||
protected NodeRemover $nodeRemover;
|
||||
|
@ -161,7 +158,6 @@ abstract class AbstractRector extends NodeVisitorAbstract implements PhpRectorIn
|
|||
CurrentNodeProvider $currentNodeProvider,
|
||||
Skipper $skipper,
|
||||
ValueResolver $valueResolver,
|
||||
NodeRepository $nodeRepository,
|
||||
BetterNodeFinder $betterNodeFinder,
|
||||
NodeComparator $nodeComparator,
|
||||
CurrentFileProvider $currentFileProvider,
|
||||
|
@ -189,7 +185,6 @@ abstract class AbstractRector extends NodeVisitorAbstract implements PhpRectorIn
|
|||
$this->currentNodeProvider = $currentNodeProvider;
|
||||
$this->skipper = $skipper;
|
||||
$this->valueResolver = $valueResolver;
|
||||
$this->nodeRepository = $nodeRepository;
|
||||
$this->betterNodeFinder = $betterNodeFinder;
|
||||
$this->nodeComparator = $nodeComparator;
|
||||
$this->currentFileProvider = $currentFileProvider;
|
||||
|
|
Loading…
Reference in New Issue