Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
use PhpParser\Node\Param;
use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\ClassMethod;
use Rector\NodeContainer\ParsedNodesByType;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\PhpParser\Node\Manipulator\ClassManipulator;
use Rector\PhpParser\Node\Manipulator\ClassMethodManipulator;
Expand All @@ -32,11 +31,6 @@ final class RemoveUnusedParameterRector extends AbstractRector
*/
private $classMethodManipulator;

/**
* @var ParsedNodesByType
*/
private $parsedNodesByType;

/**
* @var string[]
*/
Expand All @@ -59,12 +53,10 @@ final class RemoveUnusedParameterRector extends AbstractRector

public function __construct(
ClassManipulator $classManipulator,
ClassMethodManipulator $classMethodManipulator,
ParsedNodesByType $parsedNodesByType
ClassMethodManipulator $classMethodManipulator
) {
$this->classManipulator = $classManipulator;
$this->classMethodManipulator = $classMethodManipulator;
$this->parsedNodesByType = $parsedNodesByType;
}

public function getDefinition(): RectorDefinition
Expand Down Expand Up @@ -130,7 +122,7 @@ public function refactor(Node $node): ?Node
return null;
}

$childrenOfClass = $this->parsedNodesByType->findChildrenOfClass($class);
$childrenOfClass = $this->classLikeParsedNodesFinder->findChildrenOfClass($class);
$unusedParameters = $this->getUnusedParameters($node, $methodName, $childrenOfClass);

foreach ($childrenOfClass as $childClassNode) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ private function addSymfonyRouteShortTagNodeWithUse(

private function completeImplicitRoutes(): void
{
$presenterClasses = $this->parsedNodesByType->findClassesBySuffix('Presenter');
$presenterClasses = $this->classLikeParsedNodesFinder->findClassesBySuffix('Presenter');

foreach ($presenterClasses as $presenterClass) {
foreach ($presenterClass->getMethods() as $classMethod) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

use PhpParser\Node;
use PhpParser\Node\Stmt\Class_;
use Rector\NodeContainer\ParsedNodesByType;
use Rector\Rector\AbstractRector;
use Rector\RectorDefinition\CodeSample;
use Rector\RectorDefinition\RectorDefinition;
Expand All @@ -16,16 +15,6 @@
*/
final class FinalizeClassesWithoutChildrenRector extends AbstractRector
{
/**
* @var ParsedNodesByType
*/
private $parsedNodesByType;

public function __construct(ParsedNodesByType $parsedNodesByType)
{
$this->parsedNodesByType = $parsedNodesByType;
}

public function getDefinition(): RectorDefinition
{
return new RectorDefinition('Finalize every class that has no children', [
Expand Down Expand Up @@ -84,7 +73,7 @@ public function refactor(Node $node): ?Node

/** @var string $class */
$class = $this->getName($node);
if ($this->parsedNodesByType->hasClassChildren($class)) {
if ($this->classLikeParsedNodesFinder->hasClassChildren($class)) {
return null;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ public function refactor(Node $node): ?Node
}

// 3. does it have any children
if ($this->parsedNodesByType->findChildrenOfClass($className) === []) {
if ($this->classLikeParsedNodesFinder->findChildrenOfClass($className) === []) {
return null;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -202,12 +202,12 @@ private function populateChildren(Node $node, int $position, Type $paramType): v
return;
}

$childrenClassLikes = $this->parsedNodesByType->findClassesAndInterfacesByType($className);
$childrenClassLikes = $this->classLikeParsedNodesFinder->findClassesAndInterfacesByType($className);

// update their methods as well
foreach ($childrenClassLikes as $childClassLike) {
if ($childClassLike instanceof Class_) {
$usedTraits = $this->parsedNodesByType->findUsedTraitsInClass($childClassLike);
$usedTraits = $this->classLikeParsedNodesFinder->findUsedTraitsInClass($childClassLike);

foreach ($usedTraits as $trait) {
$this->addParamTypeToMethod($trait, $position, $node, $paramType);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -243,14 +243,14 @@ private function populateChildren(ClassMethod $classMethod, Type $returnType): v
throw new ShouldNotHappenException();
}

$childrenClassLikes = $this->parsedNodesByType->findChildrenOfClass($className);
$childrenClassLikes = $this->classLikeParsedNodesFinder->findChildrenOfClass($className);
if ($childrenClassLikes === []) {
return;
}

// update their methods as well
foreach ($childrenClassLikes as $childClassLike) {
$usedTraits = $this->parsedNodesByType->findUsedTraitsInClass($childClassLike);
$usedTraits = $this->classLikeParsedNodesFinder->findUsedTraitsInClass($childClassLike);
foreach ($usedTraits as $trait) {
$this->addReturnTypeToChildMethod($trait, $classMethod, $returnType);
}
Expand Down
143 changes: 143 additions & 0 deletions src/NodeContainer/ClassLikeParsedNodesFinder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
<?php

declare(strict_types=1);

namespace Rector\NodeContainer;

use Nette\Utils\Strings;
use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\ClassLike;
use PhpParser\Node\Stmt\Interface_;
use PhpParser\Node\Stmt\Trait_;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\PhpParser\Node\Resolver\NameResolver;

final class ClassLikeParsedNodesFinder
{
/**
* @var ParsedNodesByType
*/
private $parsedNodesByType;

/**
* @var NameResolver
*/
private $nameResolver;

public function __construct(ParsedNodesByType $parsedNodesByType, NameResolver $nameResolver)
{
$this->parsedNodesByType = $parsedNodesByType;
$this->nameResolver = $nameResolver;
}

/**
* @return Class_[]
*/
public function findChildrenOfClass(string $class): array
{
$childrenClasses = [];

foreach ($this->parsedNodesByType->getClasses() as $classNode) {
$currentClassName = $classNode->getAttribute(AttributeKey::CLASS_NAME);
if (! $this->isChildOrEqualClassLike($class, $currentClassName)) {
continue;
}

$childrenClasses[] = $classNode;
}

return $childrenClasses;
}

/**
* @return Class_[]
*/
public function findClassesBySuffix(string $suffix): array
{
$classNodes = [];

foreach ($this->parsedNodesByType->getClasses() as $className => $classNode) {
if (! Strings::endsWith($className, $suffix)) {
continue;
}

$classNodes[] = $classNode;
}

return $classNodes;
}

public function hasClassChildren(string $class): bool
{
return $this->findChildrenOfClass($class) !== [];
}

/**
* @return Trait_[]
*/
public function findUsedTraitsInClass(ClassLike $classLike): array
{
$traits = [];

foreach ($classLike->getTraitUses() as $traitUse) {
foreach ($traitUse->traits as $trait) {
$traitName = $this->nameResolver->getName($trait);
if ($traitName === null) {
continue;
}

$foundTrait = $this->parsedNodesByType->findTrait($traitName);
if ($foundTrait !== null) {
$traits[] = $foundTrait;
}
}
}

return $traits;
}

/**
* @return Class_[]|Interface_[]
*/
public function findClassesAndInterfacesByType(string $type): array
{
return array_merge($this->findChildrenOfClass($type), $this->findImplementersOfInterface($type));
}

/**
* @return Interface_[]
*/
public function findImplementersOfInterface(string $interface): array
{
$implementerInterfaces = [];

foreach ($this->parsedNodesByType->getInterfaces() as $interfaceNode) {
$className = $interfaceNode->getAttribute(AttributeKey::CLASS_NAME);

if (! $this->isChildOrEqualClassLike($interface, $className)) {
continue;
}

$implementerInterfaces[] = $interfaceNode;
}

return $implementerInterfaces;
}

private function isChildOrEqualClassLike(string $desiredClass, ?string $currentClassName): bool
{
if ($currentClassName === null) {
return false;
}

if (! is_a($currentClassName, $desiredClass, true)) {
return false;
}

if ($currentClassName === $desiredClass) {
return false;
}

return true;
}
}
Loading