mirror of
https://github.com/rectorphp/rector.git
synced 2024-06-01 17:00:51 +00:00
Merge branch 'master' into phpstan-fixes
This commit is contained in:
commit
6f397bade5
3
ecs.yaml
3
ecs.yaml
|
@ -75,6 +75,9 @@ parameters:
|
|||
|
||||
# @todo resolve!!!
|
||||
Symplify\CodingStandard\Sniffs\CleanCode\CognitiveComplexitySniff:
|
||||
- 'src/NodeContainer/NodeCollector/ParsedFunctionLikeNodesByType.php'
|
||||
- 'src/NodeContainer/NodeCollector/ParsedFunctionLikeNodeCollector.php'
|
||||
- 'packages/solid/src/Rector/ClassConst/PrivatizeLocalClassConstantRector.php'
|
||||
- 'packages/type-declaration/src/TypeInferer/PropertyTypeInferer/ConstructorPropertyTypeInferer.php'
|
||||
- 'packages/node-type-resolver/src/PhpDoc/NodeAnalyzer/DocBlockManipulator.php'
|
||||
- 'packages/minimal-scope/src/Rector/Class_/ChangeLocalPropertyToVariableRector.php'
|
||||
|
|
|
@ -9,7 +9,7 @@ use PhpParser\Node\Stmt\Property;
|
|||
use PHPStan\Type\ObjectType;
|
||||
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo;
|
||||
use Rector\BetterPhpDocParser\PhpDocNode\JMS\SerializerTypeTagValueNode;
|
||||
use Rector\Core\NodeContainer\ParsedNodesByType;
|
||||
use Rector\Core\NodeContainer\NodeCollector\ParsedNodeCollector;
|
||||
use Rector\Core\PhpParser\Node\Resolver\NameResolver;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
use Rector\NodeTypeResolver\NodeTypeResolver;
|
||||
|
@ -26,23 +26,23 @@ final class ClassAnalyzer
|
|||
*/
|
||||
private $nameResolver;
|
||||
|
||||
/**
|
||||
* @var ParsedNodesByType
|
||||
*/
|
||||
private $parsedNodesByType;
|
||||
|
||||
/**
|
||||
* @var NodeTypeResolver
|
||||
*/
|
||||
private $nodeTypeResolver;
|
||||
|
||||
/**
|
||||
* @var ParsedNodeCollector
|
||||
*/
|
||||
private $parsedNodeCollector;
|
||||
|
||||
public function __construct(
|
||||
NameResolver $nameResolver,
|
||||
ParsedNodesByType $parsedNodesByType,
|
||||
ParsedNodeCollector $parsedNodeCollector,
|
||||
NodeTypeResolver $nodeTypeResolver
|
||||
) {
|
||||
$this->nameResolver = $nameResolver;
|
||||
$this->parsedNodesByType = $parsedNodesByType;
|
||||
$this->parsedNodeCollector = $parsedNodeCollector;
|
||||
$this->nodeTypeResolver = $nodeTypeResolver;
|
||||
}
|
||||
|
||||
|
@ -81,7 +81,7 @@ final class ClassAnalyzer
|
|||
|
||||
// awesome!
|
||||
// is it services or value object?
|
||||
$paramTypeClass = $this->parsedNodesByType->findClass($paramType->getClassName());
|
||||
$paramTypeClass = $this->parsedNodeCollector->findClass($paramType->getClassName());
|
||||
if ($paramTypeClass === null) {
|
||||
// not sure :/
|
||||
continue;
|
||||
|
|
|
@ -21,7 +21,6 @@ use PhpParser\Node\Stmt\Expression;
|
|||
use PhpParser\Node\Stmt\Return_;
|
||||
use PHPStan\Type\ObjectType;
|
||||
use Rector\Core\Exception\ShouldNotHappenException;
|
||||
use Rector\Core\NodeContainer\ParsedNodesByType;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Rector\Core\RectorDefinition\CodeSample;
|
||||
use Rector\Core\RectorDefinition\RectorDefinition;
|
||||
|
@ -36,16 +35,6 @@ use Rector\NodeTypeResolver\Node\AttributeKey;
|
|||
*/
|
||||
final class CallableThisArrayToAnonymousFunctionRector extends AbstractRector
|
||||
{
|
||||
/**
|
||||
* @var ParsedNodesByType
|
||||
*/
|
||||
private $parsedNodesByType;
|
||||
|
||||
public function __construct(ParsedNodesByType $parsedNodesByType)
|
||||
{
|
||||
$this->parsedNodesByType = $parsedNodesByType;
|
||||
}
|
||||
|
||||
public function getDefinition(): RectorDefinition
|
||||
{
|
||||
return new RectorDefinition('Convert [$this, "method"] to proper anonymous function', [
|
||||
|
@ -158,7 +147,7 @@ PHP
|
|||
$objectType = $this->getObjectType($objectExpr);
|
||||
|
||||
if ($objectType instanceof ObjectType) {
|
||||
$class = $this->parsedNodesByType->findClass($objectType->getClassName());
|
||||
$class = $this->classLikeParsedNodesFinder->findClass($objectType->getClassName());
|
||||
|
||||
if ($class === null) {
|
||||
return null;
|
||||
|
|
|
@ -15,7 +15,6 @@ use PhpParser\Node\Stmt\ClassMethod;
|
|||
use PhpParser\Node\Stmt\Expression;
|
||||
use PhpParser\Node\Stmt\Return_;
|
||||
use Rector\Core\Exception\ShouldNotHappenException;
|
||||
use Rector\Core\NodeContainer\ParsedNodesByType;
|
||||
use Rector\Core\PhpParser\Node\Value\ValueResolver;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Rector\Core\RectorDefinition\CodeSample;
|
||||
|
@ -29,19 +28,13 @@ use ReflectionMethod;
|
|||
*/
|
||||
final class RemoveDelegatingParentCallRector extends AbstractRector
|
||||
{
|
||||
/**
|
||||
* @var ParsedNodesByType
|
||||
*/
|
||||
private $parsedNodesByType;
|
||||
|
||||
/**
|
||||
* @var ValueResolver
|
||||
*/
|
||||
private $valueResolver;
|
||||
|
||||
public function __construct(ParsedNodesByType $parsedNodesByType, ValueResolver $valueResolver)
|
||||
public function __construct(ValueResolver $valueResolver)
|
||||
{
|
||||
$this->parsedNodesByType = $parsedNodesByType;
|
||||
$this->valueResolver = $valueResolver;
|
||||
}
|
||||
|
||||
|
@ -229,7 +222,7 @@ PHP
|
|||
|
||||
/** @var string $methodName */
|
||||
$methodName = $this->getName($staticCall);
|
||||
$parentClassMethod = $this->parsedNodesByType->findMethod($methodName, $parentClassName);
|
||||
$parentClassMethod = $this->functionLikeParsedNodesFinder->findMethod($methodName, $parentClassName);
|
||||
if ($parentClassMethod !== null) {
|
||||
if ($parentClassMethod->isProtected() && $classMethod->isPublic()) {
|
||||
return true;
|
||||
|
|
|
@ -9,7 +9,6 @@ use PhpParser\Node\Stmt\Class_;
|
|||
use PhpParser\Node\Stmt\ClassMethod;
|
||||
use PhpParser\Node\Stmt\Interface_;
|
||||
use PhpParser\Node\Stmt\Trait_;
|
||||
use Rector\Core\NodeContainer\ParsedNodesByType;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Rector\Core\RectorDefinition\CodeSample;
|
||||
use Rector\Core\RectorDefinition\RectorDefinition;
|
||||
|
@ -20,16 +19,6 @@ use Rector\NodeTypeResolver\Node\AttributeKey;
|
|||
*/
|
||||
final class RemoveUnusedPrivateMethodRector extends AbstractRector
|
||||
{
|
||||
/**
|
||||
* @var ParsedNodesByType
|
||||
*/
|
||||
private $parsedNodesByType;
|
||||
|
||||
public function __construct(ParsedNodesByType $parsedNodesByType)
|
||||
{
|
||||
$this->parsedNodesByType = $parsedNodesByType;
|
||||
}
|
||||
|
||||
public function getDefinition(): RectorDefinition
|
||||
{
|
||||
return new RectorDefinition('Remove unused private method', [
|
||||
|
@ -79,7 +68,7 @@ PHP
|
|||
return null;
|
||||
}
|
||||
|
||||
$classMethodCalls = $this->parsedNodesByType->findClassMethodCalls($node);
|
||||
$classMethodCalls = $this->functionLikeParsedNodesFinder->findClassMethodCalls($node);
|
||||
if ($classMethodCalls !== []) {
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -11,7 +11,6 @@ use PhpParser\Node\Expr\New_;
|
|||
use PhpParser\Node\Expr\PropertyFetch;
|
||||
use PhpParser\Node\Stmt\Class_;
|
||||
use PhpParser\Node\Stmt\Property;
|
||||
use Rector\Core\NodeContainer\ParsedNodesByType;
|
||||
use Rector\Core\PhpParser\Node\Manipulator\ClassManipulator;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Rector\Core\RectorDefinition\CodeSample;
|
||||
|
@ -31,11 +30,6 @@ final class RemoveUnusedDoctrineEntityMethodAndPropertyRector extends AbstractRe
|
|||
*/
|
||||
private $collectionByPropertyName = [];
|
||||
|
||||
/**
|
||||
* @var ParsedNodesByType
|
||||
*/
|
||||
private $parsedNodesByType;
|
||||
|
||||
/**
|
||||
* @var ClassUnusedPrivateClassMethodResolver
|
||||
*/
|
||||
|
@ -52,12 +46,10 @@ final class RemoveUnusedDoctrineEntityMethodAndPropertyRector extends AbstractRe
|
|||
private $doctrineEntityManipulator;
|
||||
|
||||
public function __construct(
|
||||
ParsedNodesByType $parsedNodesByType,
|
||||
ClassUnusedPrivateClassMethodResolver $classUnusedPrivateClassMethodResolver,
|
||||
ClassManipulator $classManipulator,
|
||||
DoctrineEntityManipulator $doctrineEntityManipulator
|
||||
) {
|
||||
$this->parsedNodesByType = $parsedNodesByType;
|
||||
$this->classUnusedPrivateClassMethodResolver = $classUnusedPrivateClassMethodResolver;
|
||||
$this->classManipulator = $classManipulator;
|
||||
$this->doctrineEntityManipulator = $doctrineEntityManipulator;
|
||||
|
@ -265,7 +257,7 @@ PHP
|
|||
}
|
||||
|
||||
// get the class property and remove "mappedBy/inversedBy" from annotation
|
||||
$relatedEntityClass = $this->parsedNodesByType->findClass($targetEntity);
|
||||
$relatedEntityClass = $this->classLikeParsedNodesFinder->findClass($targetEntity);
|
||||
if (! $relatedEntityClass instanceof Class_) {
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -11,7 +11,6 @@ use PhpParser\Node\Expr\FuncCall;
|
|||
use PhpParser\Node\Expr\MethodCall;
|
||||
use PhpParser\Node\Expr\StaticCall;
|
||||
use PhpParser\Node\FunctionLike;
|
||||
use Rector\Core\NodeContainer\ParsedNodesByType;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Rector\Core\RectorDefinition\CodeSample;
|
||||
use Rector\Core\RectorDefinition\RectorDefinition;
|
||||
|
@ -23,16 +22,6 @@ use ReflectionFunction;
|
|||
*/
|
||||
final class RemoveDefaultArgumentValueRector extends AbstractRector
|
||||
{
|
||||
/**
|
||||
* @var ParsedNodesByType
|
||||
*/
|
||||
private $parsedNodesByType;
|
||||
|
||||
public function __construct(ParsedNodesByType $parsedNodesByType)
|
||||
{
|
||||
$this->parsedNodesByType = $parsedNodesByType;
|
||||
}
|
||||
|
||||
public function getDefinition(): RectorDefinition
|
||||
{
|
||||
return new RectorDefinition('Remove argument value, if it is the same as default value', [
|
||||
|
@ -159,7 +148,7 @@ PHP
|
|||
return [];
|
||||
}
|
||||
|
||||
$classMethodNode = $this->parsedNodesByType->findMethod($nodeName, $className);
|
||||
$classMethodNode = $this->functionLikeParsedNodesFinder->findMethod($nodeName, $className);
|
||||
if ($classMethodNode !== null) {
|
||||
return $this->resolveDefaultParamValuesFromFunctionLike($classMethodNode);
|
||||
}
|
||||
|
@ -207,7 +196,7 @@ PHP
|
|||
*/
|
||||
private function resolveFuncCallDefaultParamValues(string $nodeName): array
|
||||
{
|
||||
$functionNode = $this->parsedNodesByType->findFunction($nodeName);
|
||||
$functionNode = $this->functionLikeParsedNodesFinder->findFunction($nodeName);
|
||||
if ($functionNode !== null) {
|
||||
return $this->resolveDefaultParamValuesFromFunctionLike($functionNode);
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ namespace Rector\DeadCode\UnusedNodeResolver;
|
|||
|
||||
use Nette\Utils\Strings;
|
||||
use PhpParser\Node\Stmt\Class_;
|
||||
use Rector\Core\NodeContainer\ParsedNodesByType;
|
||||
use Rector\Core\NodeContainer\NodeFinder\FunctionLikeParsedNodesFinder;
|
||||
use Rector\Core\PhpParser\Node\Manipulator\ClassManipulator;
|
||||
use Rector\Core\PhpParser\Node\Resolver\NameResolver;
|
||||
use ReflectionMethod;
|
||||
|
@ -18,24 +18,24 @@ final class ClassUnusedPrivateClassMethodResolver
|
|||
*/
|
||||
private $nameResolver;
|
||||
|
||||
/**
|
||||
* @var ParsedNodesByType
|
||||
*/
|
||||
private $parsedNodesByType;
|
||||
|
||||
/**
|
||||
* @var ClassManipulator
|
||||
*/
|
||||
private $classManipulator;
|
||||
|
||||
/**
|
||||
* @var FunctionLikeParsedNodesFinder
|
||||
*/
|
||||
private $functionLikeParsedNodesFinder;
|
||||
|
||||
public function __construct(
|
||||
NameResolver $nameResolver,
|
||||
ParsedNodesByType $parsedNodesByType,
|
||||
ClassManipulator $classManipulator
|
||||
ClassManipulator $classManipulator,
|
||||
FunctionLikeParsedNodesFinder $functionLikeParsedNodesFinder
|
||||
) {
|
||||
$this->nameResolver = $nameResolver;
|
||||
$this->parsedNodesByType = $parsedNodesByType;
|
||||
$this->classManipulator = $classManipulator;
|
||||
$this->functionLikeParsedNodesFinder = $functionLikeParsedNodesFinder;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -45,7 +45,8 @@ final class ClassUnusedPrivateClassMethodResolver
|
|||
{
|
||||
/** @var string $className */
|
||||
$className = $this->nameResolver->getName($class);
|
||||
$classMethodCalls = $this->parsedNodesByType->findMethodCallsOnClass($className);
|
||||
|
||||
$classMethodCalls = $this->functionLikeParsedNodesFinder->findMethodCallsOnClass($className);
|
||||
|
||||
$usedMethodNames = array_keys($classMethodCalls);
|
||||
$classPublicMethodNames = $this->classManipulator->getPublicMethodNames($class);
|
||||
|
|
|
@ -13,7 +13,7 @@ use PhpParser\Node\NullableType;
|
|||
use PhpParser\Node\Param;
|
||||
use PhpParser\Node\Stmt\Class_;
|
||||
use Rector\Core\Exception\NotImplementedException;
|
||||
use Rector\Core\NodeContainer\ParsedNodesByType;
|
||||
use Rector\Core\NodeContainer\NodeCollector\ParsedNodeCollector;
|
||||
use Rector\Core\PhpParser\Node\Resolver\NameResolver;
|
||||
use Rector\Core\Testing\PHPUnit\PHPUnitEnvironment;
|
||||
|
||||
|
@ -30,14 +30,14 @@ final class UnusedClassResolver
|
|||
private $nameResolver;
|
||||
|
||||
/**
|
||||
* @var ParsedNodesByType
|
||||
* @var ParsedNodeCollector
|
||||
*/
|
||||
private $parsedNodesByType;
|
||||
private $parsedNodeCollector;
|
||||
|
||||
public function __construct(NameResolver $nameResolver, ParsedNodesByType $parsedNodesByType)
|
||||
public function __construct(NameResolver $nameResolver, ParsedNodeCollector $parsedNodeCollector)
|
||||
{
|
||||
$this->nameResolver = $nameResolver;
|
||||
$this->parsedNodesByType = $parsedNodesByType;
|
||||
$this->parsedNodeCollector = $parsedNodeCollector;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -90,7 +90,7 @@ final class UnusedClassResolver
|
|||
$classNames = [];
|
||||
|
||||
/** @var Param[] $paramNodes */
|
||||
$paramNodes = $this->parsedNodesByType->getNodesByType(Param::class);
|
||||
$paramNodes = $this->parsedNodeCollector->getNodesByType(Param::class);
|
||||
foreach ($paramNodes as $paramNode) {
|
||||
if ($paramNode->type === null) {
|
||||
continue;
|
||||
|
@ -124,7 +124,7 @@ final class UnusedClassResolver
|
|||
$classNames = [];
|
||||
|
||||
/** @var New_[] $newNodes */
|
||||
$newNodes = $this->parsedNodesByType->getNodesByType(New_::class);
|
||||
$newNodes = $this->parsedNodeCollector->getNodesByType(New_::class);
|
||||
foreach ($newNodes as $newNode) {
|
||||
$newNodeClassName = $this->nameResolver->getName($newNode->class);
|
||||
if (! is_string($newNodeClassName)) {
|
||||
|
@ -145,7 +145,7 @@ final class UnusedClassResolver
|
|||
$classNames = [];
|
||||
|
||||
/** @var StaticCall[] $staticCallNodes */
|
||||
$staticCallNodes = $this->parsedNodesByType->getNodesByType(StaticCall::class);
|
||||
$staticCallNodes = $this->parsedNodeCollector->getNodesByType(StaticCall::class);
|
||||
foreach ($staticCallNodes as $staticCallNode) {
|
||||
$staticClassName = $this->nameResolver->getName($staticCallNode->class);
|
||||
if (! is_string($staticClassName)) {
|
||||
|
@ -163,7 +163,7 @@ final class UnusedClassResolver
|
|||
private function getClassConstantFetchNames(): array
|
||||
{
|
||||
/** @var ClassConstFetch[] $classConstFetches */
|
||||
$classConstFetches = $this->parsedNodesByType->getNodesByType(ClassConstFetch::class);
|
||||
$classConstFetches = $this->parsedNodeCollector->getNodesByType(ClassConstFetch::class);
|
||||
|
||||
$classNames = [];
|
||||
foreach ($classConstFetches as $classConstFetch) {
|
||||
|
|
|
@ -14,7 +14,7 @@ use Rector\BetterPhpDocParser\PhpDocNode\Doctrine\Class_\EntityTagValueNode;
|
|||
use Rector\BetterPhpDocParser\PhpDocNode\Doctrine\Property_\ColumnTagValueNode;
|
||||
use Rector\BetterPhpDocParser\PhpDocNode\Doctrine\Property_\IdTagValueNode;
|
||||
use Rector\Core\Exception\ShouldNotHappenException;
|
||||
use Rector\Core\NodeContainer\ParsedNodesByType;
|
||||
use Rector\Core\NodeContainer\NodeCollector\ParsedNodeCollector;
|
||||
use Rector\NodeTypeResolver\ClassExistenceStaticHelper;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
use ReflectionClass;
|
||||
|
@ -22,13 +22,13 @@ use ReflectionClass;
|
|||
final class DoctrineDocBlockResolver
|
||||
{
|
||||
/**
|
||||
* @var ParsedNodesByType
|
||||
* @var ParsedNodeCollector
|
||||
*/
|
||||
private $parsedNodesByType;
|
||||
private $parsedNodeCollector;
|
||||
|
||||
public function __construct(ParsedNodesByType $parsedNodesByType)
|
||||
public function __construct(ParsedNodeCollector $parsedNodeCollector)
|
||||
{
|
||||
$this->parsedNodesByType = $parsedNodesByType;
|
||||
$this->parsedNodeCollector = $parsedNodeCollector;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -47,7 +47,7 @@ final class DoctrineDocBlockResolver
|
|||
|
||||
if (is_string($class)) {
|
||||
if (ClassExistenceStaticHelper::doesClassLikeExist($class)) {
|
||||
$classNode = $this->parsedNodesByType->findClass($class);
|
||||
$classNode = $this->parsedNodeCollector->findClass($class);
|
||||
if ($classNode !== null) {
|
||||
return $this->isDoctrineEntityClass($classNode);
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ use PhpParser\Node\Stmt\Property;
|
|||
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo;
|
||||
use Rector\BetterPhpDocParser\PhpDocNode\Doctrine\Property_\ColumnTagValueNode;
|
||||
use Rector\BetterPhpDocParser\PhpDocNode\Doctrine\Property_\IdTagValueNode;
|
||||
use Rector\Core\NodeContainer\ParsedNodesByType;
|
||||
use Rector\Core\NodeContainer\NodeCollector\ParsedNodeCollector;
|
||||
use Rector\Core\PhpParser\Node\Manipulator\ClassManipulator;
|
||||
use Rector\Core\PhpParser\Node\Resolver\NameResolver;
|
||||
use Rector\Doctrine\PhpDocParser\DoctrineDocBlockResolver;
|
||||
|
@ -24,9 +24,9 @@ final class EntityWithMissingUuidProvider
|
|||
private $entitiesWithMissingUuidProperty = [];
|
||||
|
||||
/**
|
||||
* @var ParsedNodesByType
|
||||
* @var ParsedNodeCollector
|
||||
*/
|
||||
private $parsedNodesByType;
|
||||
private $parsedNodeCollector;
|
||||
|
||||
/**
|
||||
* @var DoctrineDocBlockResolver
|
||||
|
@ -44,12 +44,12 @@ final class EntityWithMissingUuidProvider
|
|||
private $nameResolver;
|
||||
|
||||
public function __construct(
|
||||
ParsedNodesByType $parsedNodesByType,
|
||||
ParsedNodeCollector $parsedNodeCollector,
|
||||
DoctrineDocBlockResolver $doctrineDocBlockResolver,
|
||||
ClassManipulator $classManipulator,
|
||||
NameResolver $nameResolver
|
||||
) {
|
||||
$this->parsedNodesByType = $parsedNodesByType;
|
||||
$this->parsedNodeCollector = $parsedNodeCollector;
|
||||
$this->doctrineDocBlockResolver = $doctrineDocBlockResolver;
|
||||
$this->classManipulator = $classManipulator;
|
||||
$this->nameResolver = $nameResolver;
|
||||
|
@ -65,7 +65,7 @@ final class EntityWithMissingUuidProvider
|
|||
}
|
||||
|
||||
$entitiesWithMissingUuidProperty = [];
|
||||
foreach ($this->parsedNodesByType->getClasses() as $class) {
|
||||
foreach ($this->parsedNodeCollector->getClasses() as $class) {
|
||||
if (! $this->doctrineDocBlockResolver->isDoctrineEntityClassWithIdProperty($class)) {
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -13,7 +13,6 @@ use PhpParser\Node\Stmt\Expression;
|
|||
use PHPStan\Type\ObjectType;
|
||||
use PHPStan\Type\StringType;
|
||||
use Ramsey\Uuid\Uuid;
|
||||
use Rector\Core\NodeContainer\ParsedNodesByType;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Rector\Core\RectorDefinition\CodeSample;
|
||||
use Rector\Core\RectorDefinition\RectorDefinition;
|
||||
|
@ -27,21 +26,13 @@ use Rector\NodeTypeResolver\Node\AttributeKey;
|
|||
*/
|
||||
final class ChangeSetIdToUuidValueRector extends AbstractRector
|
||||
{
|
||||
/**
|
||||
* @var ParsedNodesByType
|
||||
*/
|
||||
private $parsedNodesByType;
|
||||
|
||||
/**
|
||||
* @var DoctrineEntityManipulator
|
||||
*/
|
||||
private $doctrineEntityManipulator;
|
||||
|
||||
public function __construct(
|
||||
ParsedNodesByType $parsedNodesByType,
|
||||
DoctrineEntityManipulator $doctrineEntityManipulator
|
||||
) {
|
||||
$this->parsedNodesByType = $parsedNodesByType;
|
||||
public function __construct(DoctrineEntityManipulator $doctrineEntityManipulator)
|
||||
{
|
||||
$this->doctrineEntityManipulator = $doctrineEntityManipulator;
|
||||
}
|
||||
|
||||
|
@ -123,7 +114,7 @@ PHP
|
|||
// B. is the value constant reference?
|
||||
$argumentValue = $node->args[0]->value;
|
||||
if ($argumentValue instanceof ClassConstFetch) {
|
||||
$classConst = $this->parsedNodesByType->findClassConstantByClassConstFetch($argumentValue);
|
||||
$classConst = $this->parsedNodeCollector->findClassConstantByClassConstFetch($argumentValue);
|
||||
if ($classConst === null) {
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -13,7 +13,6 @@ use PhpParser\Node\Name\FullyQualified;
|
|||
use PhpParser\Node\Scalar\String_;
|
||||
use PhpParser\Node\Stmt\ClassMethod;
|
||||
use PhpParser\Node\Stmt\Return_;
|
||||
use Rector\Core\NodeContainer\ParsedNodesByType;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Rector\Core\RectorDefinition\CodeSample;
|
||||
use Rector\Core\RectorDefinition\RectorDefinition;
|
||||
|
@ -40,15 +39,9 @@ final class RenameEventNamesInEventSubscriberRector extends AbstractRector
|
|||
*/
|
||||
private $symfonyClassConstWithAliases = [];
|
||||
|
||||
/**
|
||||
* @var ParsedNodesByType
|
||||
*/
|
||||
private $parsedNodesByType;
|
||||
|
||||
public function __construct(EventInfosFactory $eventInfosFactory, ParsedNodesByType $parsedNodesByType)
|
||||
public function __construct(EventInfosFactory $eventInfosFactory)
|
||||
{
|
||||
$this->symfonyClassConstWithAliases = $eventInfosFactory->create();
|
||||
$this->parsedNodesByType = $parsedNodesByType;
|
||||
}
|
||||
|
||||
public function getDefinition(): RectorDefinition
|
||||
|
@ -184,7 +177,7 @@ PHP
|
|||
|
||||
private function processMethodArgument(string $class, string $method, EventInfo $eventInfo): void
|
||||
{
|
||||
$classMethodNode = $this->parsedNodesByType->findMethod($method, $class);
|
||||
$classMethodNode = $this->functionLikeParsedNodesFinder->findMethod($method, $class);
|
||||
if ($classMethodNode === null) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -15,7 +15,6 @@ use PhpParser\Node\Stmt\Class_;
|
|||
use PhpParser\Node\Stmt\ClassMethod;
|
||||
use PHPStan\Type\ObjectType;
|
||||
use Rector\BetterPhpDocParser\PhpDocNode\Symfony\SymfonyRouteTagValueNode;
|
||||
use Rector\Core\NodeContainer\ParsedNodesByType;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Rector\Core\RectorDefinition\CodeSample;
|
||||
use Rector\Core\RectorDefinition\RectorDefinition;
|
||||
|
@ -35,11 +34,6 @@ use ReflectionMethod;
|
|||
*/
|
||||
final class RouterListToControllerAnnotationsRector extends AbstractRector
|
||||
{
|
||||
/**
|
||||
* @var ParsedNodesByType
|
||||
*/
|
||||
private $parsedNodesByType;
|
||||
|
||||
/**
|
||||
* @var RouteInfoFactory
|
||||
*/
|
||||
|
@ -56,12 +50,10 @@ final class RouterListToControllerAnnotationsRector extends AbstractRector
|
|||
private $implicitToExplicitRoutingAnnotationDecorator;
|
||||
|
||||
public function __construct(
|
||||
ParsedNodesByType $parsedNodesByType,
|
||||
RouteInfoFactory $routeInfoFactory,
|
||||
ReturnTypeInferer $returnTypeInferer,
|
||||
ImplicitToExplicitRoutingAnnotationDecorator $implicitToExplicitRoutingAnnotationDecorator
|
||||
) {
|
||||
$this->parsedNodesByType = $parsedNodesByType;
|
||||
$this->routeInfoFactory = $routeInfoFactory;
|
||||
$this->returnTypeInferer = $returnTypeInferer;
|
||||
$this->implicitToExplicitRoutingAnnotationDecorator = $implicitToExplicitRoutingAnnotationDecorator;
|
||||
|
@ -236,7 +228,7 @@ PHP
|
|||
|
||||
private function resolveControllerClassMethod(RouteInfo $routeInfo): ?ClassMethod
|
||||
{
|
||||
$classNode = $this->parsedNodesByType->findClass($routeInfo->getClass());
|
||||
$classNode = $this->classLikeParsedNodesFinder->findClass($routeInfo->getClass());
|
||||
if ($classNode === null) {
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ use PhpParser\Node\Expr\ClassConstFetch;
|
|||
use PhpParser\Node\Expr\New_;
|
||||
use PhpParser\Node\Expr\StaticCall;
|
||||
use PhpParser\Node\Scalar\String_;
|
||||
use Rector\Core\NodeContainer\ParsedNodesByType;
|
||||
use Rector\Core\NodeContainer\NodeCollector\ParsedNodeCollector;
|
||||
use Rector\Core\PhpParser\Node\Resolver\NameResolver;
|
||||
use Rector\Core\PhpParser\Node\Value\ValueResolver;
|
||||
use Rector\NetteToSymfony\ValueObject\RouteInfo;
|
||||
|
@ -28,18 +28,18 @@ final class RouteInfoFactory
|
|||
private $valueResolver;
|
||||
|
||||
/**
|
||||
* @var ParsedNodesByType
|
||||
* @var ParsedNodeCollector
|
||||
*/
|
||||
private $parsedNodesByType;
|
||||
private $parsedNodeCollector;
|
||||
|
||||
public function __construct(
|
||||
NameResolver $nameResolver,
|
||||
ValueResolver $valueResolver,
|
||||
ParsedNodesByType $parsedNodesByType
|
||||
ParsedNodeCollector $parsedNodeCollector
|
||||
) {
|
||||
$this->nameResolver = $nameResolver;
|
||||
$this->valueResolver = $valueResolver;
|
||||
$this->parsedNodesByType = $parsedNodesByType;
|
||||
$this->parsedNodeCollector = $parsedNodeCollector;
|
||||
}
|
||||
|
||||
public function createFromNode(Node $node): ?RouteInfo
|
||||
|
@ -127,9 +127,9 @@ final class RouteInfoFactory
|
|||
// detect class by controller name?
|
||||
// foreach all instance and try to match a name $controller . 'Presenter/Controller'
|
||||
|
||||
$classNode = $this->parsedNodesByType->findByShortName($controller . 'Presenter');
|
||||
$classNode = $this->parsedNodeCollector->findByShortName($controller . 'Presenter');
|
||||
if ($classNode === null) {
|
||||
$classNode = $this->parsedNodesByType->findByShortName($controller . 'Controller');
|
||||
$classNode = $this->parsedNodeCollector->findByShortName($controller . 'Controller');
|
||||
}
|
||||
|
||||
// unable to find here
|
||||
|
|
|
@ -31,7 +31,7 @@ use PHPStan\Type\TypeWithClassName;
|
|||
use PHPStan\Type\UnionType;
|
||||
use Rector\BetterPhpDocParser\PhpDocParser\BetterPhpDocParser;
|
||||
use Rector\Core\Exception\ShouldNotHappenException;
|
||||
use Rector\Core\NodeContainer\ParsedNodesByType;
|
||||
use Rector\Core\NodeContainer\NodeCollector\ParsedNodeCollector;
|
||||
use Rector\Core\PhpParser\Node\Resolver\NameResolver;
|
||||
use Rector\NodeTypeResolver\Contract\PerNodeTypeResolver\PerNodeTypeResolverInterface;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
|
@ -74,9 +74,9 @@ final class NodeTypeResolver
|
|||
private $objectTypeSpecifier;
|
||||
|
||||
/**
|
||||
* @var ParsedNodesByType
|
||||
* @var ParsedNodeCollector
|
||||
*/
|
||||
private $parsedNodesByType;
|
||||
private $parsedNodeCollector;
|
||||
|
||||
/**
|
||||
* @var BetterPhpDocParser
|
||||
|
@ -99,7 +99,7 @@ final class NodeTypeResolver
|
|||
public function __construct(
|
||||
BetterPhpDocParser $betterPhpDocParser,
|
||||
NameResolver $nameResolver,
|
||||
ParsedNodesByType $parsedNodesByType,
|
||||
ParsedNodeCollector $parsedNodeCollector,
|
||||
ClassReflectionTypesResolver $classReflectionTypesResolver,
|
||||
ReflectionProvider $reflectionProvider,
|
||||
TypeFactory $typeFactory,
|
||||
|
@ -117,7 +117,7 @@ final class NodeTypeResolver
|
|||
$this->reflectionProvider = $reflectionProvider;
|
||||
$this->typeFactory = $typeFactory;
|
||||
$this->objectTypeSpecifier = $objectTypeSpecifier;
|
||||
$this->parsedNodesByType = $parsedNodesByType;
|
||||
$this->parsedNodeCollector = $parsedNodeCollector;
|
||||
$this->betterPhpDocParser = $betterPhpDocParser;
|
||||
$this->staticTypeMapper = $staticTypeMapper;
|
||||
}
|
||||
|
@ -455,7 +455,7 @@ final class NodeTypeResolver
|
|||
return null;
|
||||
}
|
||||
|
||||
if ($this->parsedNodesByType->findClass($varObjectType->getClassName()) !== null) {
|
||||
if ($this->parsedNodeCollector->findClass($varObjectType->getClassName()) !== null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -6,18 +6,27 @@ namespace Rector\NodeTypeResolver\NodeVisitor;
|
|||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\NodeVisitorAbstract;
|
||||
use Rector\Core\NodeContainer\ParsedNodesByType;
|
||||
use Rector\Core\NodeContainer\NodeCollector\ParsedFunctionLikeNodeCollector;
|
||||
use Rector\Core\NodeContainer\NodeCollector\ParsedNodeCollector;
|
||||
|
||||
final class NodeCollectorNodeVisitor extends NodeVisitorAbstract
|
||||
{
|
||||
/**
|
||||
* @var ParsedNodesByType
|
||||
* @var ParsedFunctionLikeNodeCollector
|
||||
*/
|
||||
private $parsedNodesByType;
|
||||
private $parsedFunctionLikeNodeCollector;
|
||||
|
||||
public function __construct(ParsedNodesByType $parsedNodesByType)
|
||||
{
|
||||
$this->parsedNodesByType = $parsedNodesByType;
|
||||
/**
|
||||
* @var ParsedNodeCollector
|
||||
*/
|
||||
private $parsedNodeCollector;
|
||||
|
||||
public function __construct(
|
||||
ParsedNodeCollector $parsedNodeCollector,
|
||||
ParsedFunctionLikeNodeCollector $parsedFunctionLikeNodeCollector
|
||||
) {
|
||||
$this->parsedFunctionLikeNodeCollector = $parsedFunctionLikeNodeCollector;
|
||||
$this->parsedNodeCollector = $parsedNodeCollector;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -25,10 +34,10 @@ final class NodeCollectorNodeVisitor extends NodeVisitorAbstract
|
|||
*/
|
||||
public function enterNode(Node $node)
|
||||
{
|
||||
if (! $this->parsedNodesByType->isCollectableNode($node)) {
|
||||
return;
|
||||
if ($this->parsedNodeCollector->isCollectableNode($node)) {
|
||||
$this->parsedNodeCollector->collect($node);
|
||||
}
|
||||
|
||||
$this->parsedNodesByType->collect($node);
|
||||
$this->parsedFunctionLikeNodeCollector->collect($node);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@ use PhpParser\Node;
|
|||
use PhpParser\Node\Expr\MethodCall;
|
||||
use PhpParser\Node\Expr\Variable;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Rector\Core\NodeContainer\ParsedNodesByType;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Rector\Core\RectorDefinition\CodeSample;
|
||||
use Rector\Core\RectorDefinition\RectorDefinition;
|
||||
|
@ -20,16 +19,6 @@ use Rector\NodeTypeResolver\Node\AttributeKey;
|
|||
*/
|
||||
final class ThisCallOnStaticMethodToStaticCallRector extends AbstractRector
|
||||
{
|
||||
/**
|
||||
* @var ParsedNodesByType
|
||||
*/
|
||||
private $parsedNodesByType;
|
||||
|
||||
public function __construct(ParsedNodesByType $parsedNodesByType)
|
||||
{
|
||||
$this->parsedNodesByType = $parsedNodesByType;
|
||||
}
|
||||
|
||||
public function getDefinition(): RectorDefinition
|
||||
{
|
||||
return new RectorDefinition('Changes $this->call() to static method to static call', [
|
||||
|
@ -100,7 +89,7 @@ PHP
|
|||
return null;
|
||||
}
|
||||
|
||||
$isStaticMethod = $this->parsedNodesByType->isStaticMethod($methodName, $className);
|
||||
$isStaticMethod = $this->functionLikeParsedNodesFinder->isStaticMethod($methodName, $className);
|
||||
if (! $isStaticMethod) {
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -10,7 +10,6 @@ use PhpParser\Node\Expr\New_;
|
|||
use PhpParser\Node\Expr\PropertyFetch;
|
||||
use PhpParser\Node\Expr\StaticCall;
|
||||
use PHPStan\Type\ObjectType;
|
||||
use Rector\Core\NodeContainer\ParsedNodesByType;
|
||||
use Rector\Core\PhpParser\Node\Manipulator\ClassMethodManipulator;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Rector\Core\RectorDefinition\CodeSample;
|
||||
|
@ -27,21 +26,13 @@ use ReflectionClass;
|
|||
*/
|
||||
final class StaticCallOnNonStaticToInstanceCallRector extends AbstractRector
|
||||
{
|
||||
/**
|
||||
* @var ParsedNodesByType
|
||||
*/
|
||||
private $parsedNodesByType;
|
||||
|
||||
/**
|
||||
* @var ClassMethodManipulator
|
||||
*/
|
||||
private $classMethodManipulator;
|
||||
|
||||
public function __construct(
|
||||
ParsedNodesByType $parsedNodesByType,
|
||||
ClassMethodManipulator $classMethodManipulator
|
||||
) {
|
||||
$this->parsedNodesByType = $parsedNodesByType;
|
||||
public function __construct(ClassMethodManipulator $classMethodManipulator)
|
||||
{
|
||||
$this->classMethodManipulator = $classMethodManipulator;
|
||||
}
|
||||
|
||||
|
@ -106,7 +97,7 @@ PHP
|
|||
return null;
|
||||
}
|
||||
|
||||
$isStaticMethod = $this->parsedNodesByType->isStaticMethod($methodName, $className);
|
||||
$isStaticMethod = $this->functionLikeParsedNodesFinder->isStaticMethod($methodName, $className);
|
||||
if ($isStaticMethod) {
|
||||
return null;
|
||||
}
|
||||
|
@ -131,7 +122,7 @@ PHP
|
|||
}
|
||||
|
||||
// can we add static to method?
|
||||
$classMethodNode = $this->parsedNodesByType->findMethod($methodName, $className);
|
||||
$classMethodNode = $this->functionLikeParsedNodesFinder->findMethod($methodName, $className);
|
||||
if ($classMethodNode === null) {
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -13,13 +13,11 @@ use PhpParser\Node\Stmt\Class_;
|
|||
use PHPStan\Type\ObjectType;
|
||||
use Rector\Core\Exception\ShouldNotHappenException;
|
||||
use Rector\Core\Naming\PropertyNaming;
|
||||
use Rector\Core\NodeContainer\ParsedNodesByType;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Rector\Core\RectorDefinition\CodeSample;
|
||||
use Rector\Core\RectorDefinition\RectorDefinition;
|
||||
use Rector\PHPStan\Type\FullyQualifiedObjectType;
|
||||
use Rector\RemovingStatic\StaticTypesInClassResolver;
|
||||
use Symplify\PackageBuilder\Reflection\PrivatesAccessor;
|
||||
|
||||
/**
|
||||
* Depends on @see PassFactoryToUniqueObjectRector
|
||||
|
@ -48,36 +46,22 @@ final class NewUniqueObjectToEntityFactoryRector extends AbstractRector
|
|||
*/
|
||||
private $propertyNaming;
|
||||
|
||||
/**
|
||||
* @var ParsedNodesByType
|
||||
*/
|
||||
private $parsedNodesByType;
|
||||
|
||||
/**
|
||||
* @var StaticTypesInClassResolver
|
||||
*/
|
||||
private $staticTypesInClassResolver;
|
||||
|
||||
/**
|
||||
* @var PrivatesAccessor
|
||||
*/
|
||||
private $privatesAccessor;
|
||||
|
||||
/**
|
||||
* @param string[] $typesToServices
|
||||
*/
|
||||
public function __construct(
|
||||
PropertyNaming $propertyNaming,
|
||||
ParsedNodesByType $parsedNodesByType,
|
||||
StaticTypesInClassResolver $staticTypesInClassResolver,
|
||||
PrivatesAccessor $privatesAccessor,
|
||||
array $typesToServices = []
|
||||
) {
|
||||
$this->typesToServices = $typesToServices;
|
||||
$this->propertyNaming = $propertyNaming;
|
||||
$this->parsedNodesByType = $parsedNodesByType;
|
||||
$this->staticTypesInClassResolver = $staticTypesInClassResolver;
|
||||
$this->privatesAccessor = $privatesAccessor;
|
||||
}
|
||||
|
||||
public function getDefinition(): RectorDefinition
|
||||
|
@ -188,7 +172,7 @@ PHP
|
|||
}
|
||||
|
||||
// temporary
|
||||
$classes = $this->privatesAccessor->getPrivateProperty($this->parsedNodesByType, 'classes');
|
||||
$classes = $this->parsedNodeCollector->getClasses();
|
||||
if ($classes === []) {
|
||||
return [];
|
||||
}
|
||||
|
|
|
@ -7,3 +7,4 @@ services:
|
|||
resource: '../src'
|
||||
exclude:
|
||||
- '../src/Rector/**/*Rector.php'
|
||||
- '../src/ValueObject/*'
|
||||
|
|
|
@ -8,7 +8,7 @@ use PhpParser\Node\Expr\ClassConstFetch;
|
|||
use PHPStan\Type\ObjectType;
|
||||
use PHPStan\Type\Type;
|
||||
use PHPStan\Type\TypeUtils;
|
||||
use Rector\Core\NodeContainer\ParsedNodesByType;
|
||||
use Rector\Core\NodeContainer\NodeCollector\ParsedNodeCollector;
|
||||
use Rector\Core\PhpParser\Node\Resolver\NameResolver;
|
||||
use Rector\Core\Testing\PHPUnit\PHPUnitEnvironment;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
|
@ -21,11 +21,6 @@ final class ClassConstantFetchAnalyzer
|
|||
*/
|
||||
private $classConstantFetchByClassAndName = [];
|
||||
|
||||
/**
|
||||
* @var ParsedNodesByType
|
||||
*/
|
||||
private $parsedNodesByType;
|
||||
|
||||
/**
|
||||
* @var NameResolver
|
||||
*/
|
||||
|
@ -36,14 +31,19 @@ final class ClassConstantFetchAnalyzer
|
|||
*/
|
||||
private $nodeTypeResolver;
|
||||
|
||||
/**
|
||||
* @var ParsedNodeCollector
|
||||
*/
|
||||
private $parsedNodeCollector;
|
||||
|
||||
public function __construct(
|
||||
ParsedNodesByType $parsedNodesByType,
|
||||
NodeTypeResolver $nodeTypeResolver,
|
||||
NameResolver $nameResolver
|
||||
NameResolver $nameResolver,
|
||||
ParsedNodeCollector $parsedNodeCollector
|
||||
) {
|
||||
$this->parsedNodesByType = $parsedNodesByType;
|
||||
$this->nodeTypeResolver = $nodeTypeResolver;
|
||||
$this->nameResolver = $nameResolver;
|
||||
$this->parsedNodeCollector = $parsedNodeCollector;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -56,7 +56,7 @@ final class ClassConstantFetchAnalyzer
|
|||
return $this->classConstantFetchByClassAndName;
|
||||
}
|
||||
|
||||
$classConstFetches = $this->parsedNodesByType->getNodesByType(ClassConstFetch::class);
|
||||
$classConstFetches = $this->parsedNodeCollector->getNodesByType(ClassConstFetch::class);
|
||||
foreach ($classConstFetches as $classConstantFetch) {
|
||||
$this->addClassConstantFetch($classConstantFetch);
|
||||
}
|
||||
|
@ -99,7 +99,7 @@ final class ClassConstantFetchAnalyzer
|
|||
$classNames = TypeUtils::getDirectClassNames($type);
|
||||
|
||||
foreach ($classNames as $className) {
|
||||
$classOrInterface = $this->parsedNodesByType->findClassOrInterface($className);
|
||||
$classOrInterface = $this->parsedNodeCollector->findClassOrInterface($className);
|
||||
if ($classOrInterface === null) {
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\SOLID\NodeFinder;
|
||||
|
||||
use PhpParser\Node\Stmt\ClassConst;
|
||||
use Rector\Core\NodeContainer\NodeCollector\ParsedNodeCollector;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
|
||||
final class ParentClassConstantNodeFinder
|
||||
{
|
||||
/**
|
||||
* @var ParsedNodeCollector
|
||||
*/
|
||||
private $parsedNodeCollector;
|
||||
|
||||
public function __construct(ParsedNodeCollector $parsedNodeCollector)
|
||||
{
|
||||
$this->parsedNodeCollector = $parsedNodeCollector;
|
||||
}
|
||||
|
||||
public function find(string $class, string $constant): ?ClassConst
|
||||
{
|
||||
$classNode = $this->parsedNodeCollector->findClass($class);
|
||||
if ($classNode === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/** @var string|null $parentClassName */
|
||||
$parentClassName = $classNode->getAttribute(AttributeKey::PARENT_CLASS_NAME);
|
||||
if ($parentClassName === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $this->parsedNodeCollector->findClassConstant($parentClassName, $constant);
|
||||
}
|
||||
}
|
|
@ -6,12 +6,15 @@ namespace Rector\SOLID\Rector\ClassConst;
|
|||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Stmt\ClassConst;
|
||||
use Rector\Core\NodeContainer\ParsedNodesByType;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Rector\Core\RectorDefinition\CodeSample;
|
||||
use Rector\Core\RectorDefinition\RectorDefinition;
|
||||
use Rector\Core\ValueObject\PhpVersionFeature;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
use Rector\SOLID\Analyzer\ClassConstantFetchAnalyzer;
|
||||
use Rector\SOLID\NodeFinder\ParentClassConstantNodeFinder;
|
||||
use Rector\SOLID\Reflection\ParentConstantReflectionResolver;
|
||||
use Rector\SOLID\ValueObject\ConstantVisibility;
|
||||
|
||||
/**
|
||||
* @see \Rector\SOLID\Tests\Rector\ClassConst\PrivatizeLocalClassConstantRector\PrivatizeLocalClassConstantRectorTest
|
||||
|
@ -23,22 +26,29 @@ final class PrivatizeLocalClassConstantRector extends AbstractRector
|
|||
*/
|
||||
public const HAS_NEW_ACCESS_LEVEL = 'has_new_access_level';
|
||||
|
||||
/**
|
||||
* @var ParsedNodesByType
|
||||
*/
|
||||
private $parsedNodesByType;
|
||||
|
||||
/**
|
||||
* @var ClassConstantFetchAnalyzer
|
||||
*/
|
||||
private $classConstantFetchAnalyzer;
|
||||
|
||||
/**
|
||||
* @var ParentConstantReflectionResolver
|
||||
*/
|
||||
private $parentConstantReflectionResolver;
|
||||
|
||||
/**
|
||||
* @var ParentClassConstantNodeFinder
|
||||
*/
|
||||
private $parentClassConstantNodeFinder;
|
||||
|
||||
public function __construct(
|
||||
ParsedNodesByType $parsedNodesByType,
|
||||
ClassConstantFetchAnalyzer $classConstantFetchAnalyzer
|
||||
ClassConstantFetchAnalyzer $classConstantFetchAnalyzer,
|
||||
ParentConstantReflectionResolver $parentConstantReflectionResolver,
|
||||
ParentClassConstantNodeFinder $parentClassConstantNodeFinder
|
||||
) {
|
||||
$this->parsedNodesByType = $parsedNodesByType;
|
||||
$this->classConstantFetchAnalyzer = $classConstantFetchAnalyzer;
|
||||
$this->parentConstantReflectionResolver = $parentConstantReflectionResolver;
|
||||
$this->parentClassConstantNodeFinder = $parentClassConstantNodeFinder;
|
||||
}
|
||||
|
||||
public function getDefinition(): RectorDefinition
|
||||
|
@ -96,29 +106,25 @@ PHP
|
|||
$class = $node->getAttribute(AttributeKey::CLASS_NAME);
|
||||
|
||||
// 0. constants declared in interfaces have to be public
|
||||
if ($this->parsedNodesByType->findInterface($class) !== null) {
|
||||
if ($this->classLikeParsedNodesFinder->findInterface($class) !== null) {
|
||||
$this->makePublic($node);
|
||||
return $node;
|
||||
}
|
||||
|
||||
/** @var string $constant */
|
||||
$constant = $this->getName($node);
|
||||
$parentConstIsProtected = false;
|
||||
|
||||
$parentClassConstant = $this->findParentClassConstant($class, $constant);
|
||||
if ($parentClassConstant !== null) {
|
||||
// The parent's constant is public, so this one must become public too
|
||||
if ($parentClassConstant->isPublic()) {
|
||||
$this->makePublic($node);
|
||||
return $node;
|
||||
}
|
||||
$parentClassConstantVisibility = $this->findParentClassConstantAndRefactorIfPossible($class, $constant);
|
||||
|
||||
$parentConstIsProtected = $parentClassConstant->isProtected();
|
||||
// The parent's constant is public, so this one must become public too
|
||||
if ($parentClassConstantVisibility !== null && $parentClassConstantVisibility->isPublic()) {
|
||||
$this->makePublic($node);
|
||||
return $node;
|
||||
}
|
||||
|
||||
$useClasses = $this->findClassConstantFetches($class, $constant);
|
||||
|
||||
return $this->changeConstantVisibility($node, $useClasses, $parentConstIsProtected, $class);
|
||||
return $this->changeConstantVisibility($node, $useClasses, $parentClassConstantVisibility, $class);
|
||||
}
|
||||
|
||||
private function shouldSkip(ClassConst $classConst): bool
|
||||
|
@ -127,33 +133,39 @@ PHP
|
|||
return true;
|
||||
}
|
||||
|
||||
if (! $this->isAtLeastPhpVersion('7.1')) {
|
||||
if (! $this->isAtLeastPhpVersion(PhpVersionFeature::CONSTANT_VISIBILITY)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return count($classConst->consts) !== 1;
|
||||
}
|
||||
|
||||
private function findParentClassConstant(string $class, string $constant): ?ClassConst
|
||||
private function findParentClassConstantAndRefactorIfPossible(string $class, string $constant): ?ConstantVisibility
|
||||
{
|
||||
$classNode = $this->parsedNodesByType->findClass($class);
|
||||
if ($classNode !== null && $classNode->hasAttribute(AttributeKey::PARENT_CLASS_NAME)) {
|
||||
/** @var string $parentClassName */
|
||||
$parentClassName = $classNode->getAttribute(AttributeKey::PARENT_CLASS_NAME);
|
||||
if ($parentClassName !== '') {
|
||||
$parentClassConstant = $this->parsedNodesByType->findClassConstant($parentClassName, $constant);
|
||||
if ($parentClassConstant !== null) {
|
||||
// Make sure the parent's constant has been refactored
|
||||
$this->refactor($parentClassConstant);
|
||||
$parentClassConstant = $this->parentClassConstantNodeFinder->find($class, $constant);
|
||||
|
||||
return $parentClassConstant;
|
||||
}
|
||||
// If the constant isn't declared in the parent, it might be declared in the parent's parent
|
||||
return $this->findParentClassConstant($parentClassName, $constant);
|
||||
}
|
||||
if ($parentClassConstant !== null) {
|
||||
// Make sure the parent's constant has been refactored
|
||||
$this->refactor($parentClassConstant);
|
||||
|
||||
return new ConstantVisibility(
|
||||
$parentClassConstant->isPublic(),
|
||||
$parentClassConstant->isProtected(),
|
||||
$parentClassConstant->isPrivate()
|
||||
);
|
||||
// If the constant isn't declared in the parent, it might be declared in the parent's parent
|
||||
}
|
||||
|
||||
return null;
|
||||
$parentClassConstantReflection = $this->parentConstantReflectionResolver->resolve($class, $constant);
|
||||
if ($parentClassConstantReflection === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new ConstantVisibility(
|
||||
$parentClassConstantReflection->isPublic(),
|
||||
$parentClassConstantReflection->isProtected(),
|
||||
$parentClassConstantReflection->isPrivate()
|
||||
);
|
||||
}
|
||||
|
||||
private function findClassConstantFetches(string $className, string $constantName): ?array
|
||||
|
@ -169,18 +181,18 @@ PHP
|
|||
private function changeConstantVisibility(
|
||||
ClassConst $classConst,
|
||||
?array $useClasses,
|
||||
bool $parentConstIsProtected,
|
||||
?ConstantVisibility $constantVisibility,
|
||||
string $class
|
||||
): Node {
|
||||
// 1. is actually never used (@todo use in "dead-code" set)
|
||||
if ($useClasses === null) {
|
||||
$this->makePrivateOrWeaker($classConst, $parentConstIsProtected);
|
||||
$this->makePrivateOrWeaker($classConst, $constantVisibility);
|
||||
return $classConst;
|
||||
}
|
||||
|
||||
// 2. is only local use? → private
|
||||
if ($useClasses === [$class]) {
|
||||
$this->makePrivateOrWeaker($classConst, $parentConstIsProtected);
|
||||
$this->makePrivateOrWeaker($classConst, $constantVisibility);
|
||||
return $classConst;
|
||||
}
|
||||
|
||||
|
@ -194,11 +206,13 @@ PHP
|
|||
return $classConst;
|
||||
}
|
||||
|
||||
private function makePrivateOrWeaker(ClassConst $classConst, bool $protectedRequired): void
|
||||
private function makePrivateOrWeaker(ClassConst $classConst, ?ConstantVisibility $parentConstantVisibility): void
|
||||
{
|
||||
if ($protectedRequired) {
|
||||
if ($parentConstantVisibility !== null && $parentConstantVisibility->isProtected()) {
|
||||
$this->makeProtected($classConst);
|
||||
} else {
|
||||
} elseif ($parentConstantVisibility !== null && $parentConstantVisibility->isPrivate() && ! $parentConstantVisibility->isProtected()) {
|
||||
$this->makePrivate($classConst);
|
||||
} elseif ($parentConstantVisibility === null) {
|
||||
$this->makePrivate($classConst);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,6 @@ namespace Rector\SOLID\Rector\Class_;
|
|||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Stmt\Class_;
|
||||
use Rector\Core\NodeContainer\ParsedNodesByType;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Rector\Core\RectorDefinition\CodeSample;
|
||||
use Rector\Core\RectorDefinition\RectorDefinition;
|
||||
|
@ -16,16 +15,6 @@ use Rector\Core\RectorDefinition\RectorDefinition;
|
|||
*/
|
||||
final class MakeUnusedClassesWithChildrenAbstractRector extends AbstractRector
|
||||
{
|
||||
/**
|
||||
* @var ParsedNodesByType
|
||||
*/
|
||||
private $parsedNodesByType;
|
||||
|
||||
public function __construct(ParsedNodesByType $parsedNodesByType)
|
||||
{
|
||||
$this->parsedNodesByType = $parsedNodesByType;
|
||||
}
|
||||
|
||||
public function getDefinition(): RectorDefinition
|
||||
{
|
||||
return new RectorDefinition('Classes that have no children nor are used, should have abstract', [
|
||||
|
@ -72,12 +61,12 @@ PHP
|
|||
}
|
||||
|
||||
// 1. is in static call?
|
||||
if ($this->parsedNodesByType->findMethodCallsOnClass($className) !== []) {
|
||||
if ($this->functionLikeParsedNodesFinder->findMethodCallsOnClass($className) !== []) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// 2. is in new?
|
||||
if ($this->parsedNodesByType->findNewNodesByClass($className) !== []) {
|
||||
if ($this->parsedNodeCollector->findNewNodesByClass($className) !== []) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\SOLID\Reflection;
|
||||
|
||||
use ReflectionClass;
|
||||
use ReflectionClassConstant;
|
||||
|
||||
final class ParentConstantReflectionResolver
|
||||
{
|
||||
public function resolve(string $class, string $constant): ?ReflectionClassConstant
|
||||
{
|
||||
$reflectionClass = (new ReflectionClass($class));
|
||||
$parentReflectionClass = $reflectionClass->getParentClass();
|
||||
|
||||
while ($parentReflectionClass !== false) {
|
||||
if ($parentReflectionClass->hasConstant($constant)) {
|
||||
return $parentReflectionClass->getReflectionConstant($constant);
|
||||
}
|
||||
|
||||
$parentReflectionClass = $parentReflectionClass->getParentClass();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
45
packages/solid/src/ValueObject/ConstantVisibility.php
Normal file
45
packages/solid/src/ValueObject/ConstantVisibility.php
Normal file
|
@ -0,0 +1,45 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\SOLID\ValueObject;
|
||||
|
||||
final class ConstantVisibility
|
||||
{
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $isPublic = false;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $isProtected = false;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $isPrivate = false;
|
||||
|
||||
public function __construct(bool $isPublic, bool $isProtected, bool $isPrivate)
|
||||
{
|
||||
$this->isPublic = $isPublic;
|
||||
$this->isProtected = $isProtected;
|
||||
$this->isPrivate = $isPrivate;
|
||||
}
|
||||
|
||||
public function isPublic(): bool
|
||||
{
|
||||
return $this->isPublic;
|
||||
}
|
||||
|
||||
public function isProtected(): bool
|
||||
{
|
||||
return $this->isProtected;
|
||||
}
|
||||
|
||||
public function isPrivate(): bool
|
||||
{
|
||||
return $this->isPrivate;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\SOLID\Tests\Rector\ClassConst\PrivatizeLocalClassConstantRector\Fixture;
|
||||
|
||||
use Rector\SOLID\Tests\Rector\ClassConst\PrivatizeLocalClassConstantRector\Source\SomeProtectedParentClass;
|
||||
|
||||
class SkipParentClassProtected extends SomeProtectedParentClass
|
||||
{
|
||||
protected const SOME_CONST = 'changed_value';
|
||||
}
|
|
@ -18,24 +18,11 @@ final class PrivatizeLocalClassConstantRectorTest extends AbstractRectorTestCase
|
|||
$this->doTestFile($file);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideDataProtected()
|
||||
*/
|
||||
public function testProtected(string $file): void
|
||||
{
|
||||
$this->doTestFile($file);
|
||||
}
|
||||
|
||||
public function provideData(): Iterator
|
||||
{
|
||||
return $this->yieldFilesFromDirectory(__DIR__ . '/Fixture');
|
||||
}
|
||||
|
||||
public function provideDataProtected(): Iterator
|
||||
{
|
||||
return $this->yieldFilesFromDirectory(__DIR__ . '/Fixture');
|
||||
}
|
||||
|
||||
protected function getRectorClass(): string
|
||||
{
|
||||
return PrivatizeLocalClassConstantRector::class;
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\SOLID\Tests\Rector\ClassConst\PrivatizeLocalClassConstantRector\Source;
|
||||
|
||||
abstract class SomeProtectedParentClass
|
||||
{
|
||||
protected const SOME_CONST = '...';
|
||||
}
|
|
@ -22,7 +22,6 @@ use PhpParser\Node\Scalar\String_;
|
|||
use PhpParser\Node\Stmt\Class_;
|
||||
use PhpParser\Node\Stmt\ClassMethod;
|
||||
use PhpParser\Node\Stmt\Expression;
|
||||
use Rector\Core\NodeContainer\ParsedNodesByType;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Rector\Core\RectorDefinition\CodeSample;
|
||||
use Rector\Core\RectorDefinition\RectorDefinition;
|
||||
|
@ -42,16 +41,6 @@ use Symfony\Component\OptionsResolver\OptionsResolver;
|
|||
*/
|
||||
final class FormTypeInstanceToClassConstRector extends AbstractRector
|
||||
{
|
||||
/**
|
||||
* @var ParsedNodesByType
|
||||
*/
|
||||
private $parsedNodesByType;
|
||||
|
||||
public function __construct(ParsedNodesByType $parsedNodesByType)
|
||||
{
|
||||
$this->parsedNodesByType = $parsedNodesByType;
|
||||
}
|
||||
|
||||
public function getDefinition(): RectorDefinition
|
||||
{
|
||||
return new RectorDefinition(
|
||||
|
@ -180,7 +169,7 @@ PHP
|
|||
$methodCall->args[$optionsPosition] = new Arg($optionsArrayNode);
|
||||
}
|
||||
|
||||
$formTypeClassNode = $this->parsedNodesByType->findClass($className);
|
||||
$formTypeClassNode = $this->classLikeParsedNodesFinder->findClass($className);
|
||||
if ($formTypeClassNode === null) {
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -11,7 +11,6 @@ use PhpParser\Node\Expr\StaticCall;
|
|||
use PhpParser\Node\Stmt\ClassMethod;
|
||||
use PHPStan\Type\MixedType;
|
||||
use PHPStan\Type\Type;
|
||||
use Rector\Core\NodeContainer\ParsedNodesByType;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Rector\Core\RectorDefinition\CodeSample;
|
||||
use Rector\Core\RectorDefinition\RectorDefinition;
|
||||
|
@ -24,19 +23,13 @@ use Rector\NodeTypeResolver\PHPStan\Type\TypeFactory;
|
|||
*/
|
||||
final class AddMethodCallBasedParamTypeRector extends AbstractRector
|
||||
{
|
||||
/**
|
||||
* @var ParsedNodesByType
|
||||
*/
|
||||
private $parsedNodesByType;
|
||||
|
||||
/**
|
||||
* @var TypeFactory
|
||||
*/
|
||||
private $typeFactory;
|
||||
|
||||
public function __construct(ParsedNodesByType $parsedNodesByType, TypeFactory $typeFactory)
|
||||
public function __construct(TypeFactory $typeFactory)
|
||||
{
|
||||
$this->parsedNodesByType = $parsedNodesByType;
|
||||
$this->typeFactory = $typeFactory;
|
||||
}
|
||||
|
||||
|
@ -98,7 +91,7 @@ PHP
|
|||
*/
|
||||
public function refactor(Node $node): ?Node
|
||||
{
|
||||
$classMethodCalls = $this->parsedNodesByType->findClassMethodCalls($node);
|
||||
$classMethodCalls = $this->functionLikeParsedNodesFinder->findClassMethodCalls($node);
|
||||
|
||||
$classParameterTypes = $this->getCallTypesByPosition($classMethodCalls);
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ use PHPStan\Type\MixedType;
|
|||
use PHPStan\Type\ObjectType;
|
||||
use PHPStan\Type\StaticType;
|
||||
use PHPStan\Type\Type;
|
||||
use Rector\Core\NodeContainer\ParsedNodesByType;
|
||||
use Rector\Core\NodeContainer\NodeCollector\ParsedNodeCollector;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Rector\NodeTypeResolver\PhpDoc\NodeAnalyzer\DocBlockManipulator;
|
||||
use Rector\PHPStan\Type\SelfObjectType;
|
||||
|
@ -41,9 +41,9 @@ abstract class AbstractTypeDeclarationRector extends AbstractRector
|
|||
protected $docBlockManipulator;
|
||||
|
||||
/**
|
||||
* @var ParsedNodesByType
|
||||
* @var ParsedNodeCollector
|
||||
*/
|
||||
protected $parsedNodesByType;
|
||||
protected $parsedNodeCollector;
|
||||
|
||||
/**
|
||||
* @var PhpParserTypeAnalyzer
|
||||
|
@ -60,12 +60,12 @@ abstract class AbstractTypeDeclarationRector extends AbstractRector
|
|||
*/
|
||||
public function autowireAbstractTypeDeclarationRector(
|
||||
DocBlockManipulator $docBlockManipulator,
|
||||
ParsedNodesByType $parsedNodesByType,
|
||||
ParsedNodeCollector $parsedNodeCollector,
|
||||
PhpParserTypeAnalyzer $phpParserTypeAnalyzer,
|
||||
VendorLockResolver $vendorLockResolver
|
||||
): void {
|
||||
$this->docBlockManipulator = $docBlockManipulator;
|
||||
$this->parsedNodesByType = $parsedNodesByType;
|
||||
$this->parsedNodeCollector = $parsedNodeCollector;
|
||||
$this->phpParserTypeAnalyzer = $phpParserTypeAnalyzer;
|
||||
$this->vendorLockResolver = $vendorLockResolver;
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ use PHPStan\Type\MixedType;
|
|||
use PHPStan\Type\ObjectType;
|
||||
use PHPStan\Type\Type;
|
||||
use Rector\Core\Php\PhpVersionProvider;
|
||||
use Rector\Core\ValueObject\PhpVersionFeature;
|
||||
use Rector\TypeDeclaration\Contract\TypeInferer\ReturnTypeInfererInterface;
|
||||
use Rector\TypeDeclaration\TypeInferer\AbstractTypeInferer;
|
||||
|
||||
|
@ -51,7 +52,7 @@ final class YieldNodesReturnTypeInferer extends AbstractTypeInferer implements R
|
|||
$types[] = new ArrayType(new MixedType(), $yieldValueStaticType);
|
||||
}
|
||||
|
||||
if ($this->phpVersionProvider->isAtLeast('7.1')) {
|
||||
if ($this->phpVersionProvider->isAtLeast(PhpVersionFeature::ITERABLE_TYPE)) {
|
||||
// @see https://www.php.net/manual/en/language.types.iterable.php
|
||||
$types[] = new IterableType(new MixedType(), new MixedType());
|
||||
} else {
|
||||
|
|
|
@ -12,7 +12,7 @@ use PhpParser\Node\Stmt\Interface_;
|
|||
use PhpParser\Node\Stmt\Property;
|
||||
use PhpParser\Node\Stmt\PropertyProperty;
|
||||
use Rector\Core\Exception\ShouldNotHappenException;
|
||||
use Rector\Core\NodeContainer\ParsedNodesByType;
|
||||
use Rector\Core\NodeContainer\NodeCollector\ParsedNodeCollector;
|
||||
use Rector\Core\PhpParser\Node\Manipulator\ClassManipulator;
|
||||
use Rector\Core\PhpParser\Node\Resolver\NameResolver;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
|
@ -25,23 +25,23 @@ final class VendorLockResolver
|
|||
*/
|
||||
private $nameResolver;
|
||||
|
||||
/**
|
||||
* @var ParsedNodesByType
|
||||
*/
|
||||
private $parsedNodesByType;
|
||||
|
||||
/**
|
||||
* @var ClassManipulator
|
||||
*/
|
||||
private $classManipulator;
|
||||
|
||||
/**
|
||||
* @var ParsedNodeCollector
|
||||
*/
|
||||
private $parsedNodeCollector;
|
||||
|
||||
public function __construct(
|
||||
NameResolver $nameResolver,
|
||||
ParsedNodesByType $parsedNodesByType,
|
||||
ParsedNodeCollector $parsedNodeCollector,
|
||||
ClassManipulator $classManipulator
|
||||
) {
|
||||
$this->nameResolver = $nameResolver;
|
||||
$this->parsedNodesByType = $parsedNodesByType;
|
||||
$this->parsedNodeCollector = $parsedNodeCollector;
|
||||
$this->classManipulator = $classManipulator;
|
||||
}
|
||||
|
||||
|
@ -66,7 +66,7 @@ final class VendorLockResolver
|
|||
$parentClassName = $classMethod->getAttribute(AttributeKey::PARENT_CLASS_NAME);
|
||||
|
||||
if ($parentClassName !== null) {
|
||||
$parentClassNode = $this->parsedNodesByType->findClass($parentClassName);
|
||||
$parentClassNode = $this->parsedNodeCollector->findClass($parentClassName);
|
||||
if ($parentClassNode !== null) {
|
||||
$parentMethodNode = $parentClassNode->getMethod($methodName);
|
||||
// @todo validate type is conflicting
|
||||
|
@ -95,7 +95,7 @@ final class VendorLockResolver
|
|||
|
||||
$interfaceNames = $this->classManipulator->getClassLikeNodeParentInterfaceNames($classNode);
|
||||
foreach ($interfaceNames as $interfaceName) {
|
||||
$interface = $this->parsedNodesByType->findInterface($interfaceName);
|
||||
$interface = $this->parsedNodeCollector->findInterface($interfaceName);
|
||||
// parent class method in local scope → it's ok
|
||||
// @todo validate type is conflicting
|
||||
if ($interface !== null && $interface->getMethod($methodName) !== null) {
|
||||
|
@ -133,7 +133,7 @@ final class VendorLockResolver
|
|||
$parentClassName = $classMethod->getAttribute(AttributeKey::PARENT_CLASS_NAME);
|
||||
|
||||
if ($parentClassName !== null) {
|
||||
$parentClassNode = $this->parsedNodesByType->findClass($parentClassName);
|
||||
$parentClassNode = $this->parsedNodeCollector->findClass($parentClassName);
|
||||
if ($parentClassNode !== null) {
|
||||
$parentMethodNode = $parentClassNode->getMethod($methodName);
|
||||
// @todo validate type is conflicting
|
||||
|
@ -161,7 +161,7 @@ final class VendorLockResolver
|
|||
|
||||
$interfaceNames = $this->classManipulator->getClassLikeNodeParentInterfaceNames($classNode);
|
||||
foreach ($interfaceNames as $interfaceName) {
|
||||
$interface = $this->parsedNodesByType->findInterface($interfaceName);
|
||||
$interface = $this->parsedNodeCollector->findInterface($interfaceName);
|
||||
// parent class method in local scope → it's ok
|
||||
// @todo validate type is conflicting
|
||||
if ($interface !== null && $interface->getMethod($methodName) !== null) {
|
||||
|
@ -199,7 +199,7 @@ final class VendorLockResolver
|
|||
$parentClassName = $classNode->getAttribute(AttributeKey::PARENT_CLASS_NAME);
|
||||
|
||||
if ($parentClassName !== null) {
|
||||
$parentClassNode = $this->parsedNodesByType->findClass($parentClassName);
|
||||
$parentClassNode = $this->parsedNodeCollector->findClass($parentClassName);
|
||||
if ($parentClassNode !== null) {
|
||||
$parentPropertyNode = $this->getProperty($parentClassNode, $propertyName);
|
||||
// @todo validate type is conflicting
|
||||
|
|
13
phpstan.neon
13
phpstan.neon
|
@ -9,7 +9,7 @@ parameters:
|
|||
level: max
|
||||
|
||||
# to allow installing with various phsptan versions without reporting old errors here
|
||||
# reportUnmatchedIgnoredErrors: false
|
||||
reportUnmatchedIgnoredErrors: false
|
||||
|
||||
autoload_directories:
|
||||
- stubs
|
||||
|
@ -225,9 +225,9 @@ parameters:
|
|||
- '#Parameter \#1 \$str of function preg_quote expects string, int\|string given#'
|
||||
|
||||
- '#Parameter \#1 \$node of method Rector\\Core\\PhpParser\\Node\\Commander\\NodeAddingCommander\:\:wrapToExpression\(\) expects PhpParser\\Node\\Expr\|PhpParser\\Node\\Stmt, PhpParser\\Node given#'
|
||||
- '#Method Rector\\Core\\NodeContainer\\ParsedNodesByType\:\:findTrait\(\) should return PhpParser\\Node\\Stmt\\Trait_\|null but returns PhpParser\\Node\|null#'
|
||||
- '#Method Rector\\Core\\NodeContainer\\ParsedNodesByType\:\:findInterface\(\) should return PhpParser\\Node\\Stmt\\Interface_\|null but returns PhpParser\\Node\|null#'
|
||||
- '#Method Rector\\Core\\NodeContainer\\ParsedNodesByType\:\:findFunction\(\) should return PhpParser\\Node\\Stmt\\Function_\|null but returns PhpParser\\Node\|null#'
|
||||
- '#Method Rector\\Core\\NodeContainer\\NodeCollector\\ParsedNodesByType\:\:findTrait\(\) should return PhpParser\\Node\\Stmt\\Trait_\|null but returns PhpParser\\Node\|null#'
|
||||
- '#Method Rector\\Core\\NodeContainer\\NodeCollector\\ParsedNodesByType\:\:findInterface\(\) should return PhpParser\\Node\\Stmt\\Interface_\|null but returns PhpParser\\Node\|null#'
|
||||
- '#Method Rector\\Core\\NodeContainer\\NodeCollector\\ParsedNodesByType\:\:findFunction\(\) should return PhpParser\\Node\\Stmt\\Function_\|null but returns PhpParser\\Node\|null#'
|
||||
- '#Parameter \#2 \$propertyName of method Rector\\TypeDeclaration\\TypeInferer\\PropertyTypeInferer\\SingleMethodAssignedNodePropertyTypeInferer\:\:resolveAssignedNodeToProperty\(\) expects string, string\|null given#'
|
||||
- '#Parameter \#1 \$sprintfFuncCall of method Rector\\Core\\PhpParser\\NodeTransformer\:\:transformSprintfToArray\(\) expects PhpParser\\Node\\Expr\\FuncCall, PhpParser\\Node given#'
|
||||
- '#Parameter \#1 \$nodes of method Rector\\CodeQuality\\Rector\\Array_\\CallableThisArrayToAnonymousFunctionRector\:\:hasClassMethodReturn\(\) expects array<PhpParser\\Node\\Stmt\\Return_\>, array<PhpParser\\Node\> given#'
|
||||
|
@ -235,3 +235,8 @@ parameters:
|
|||
- '#PHPDoc tag @return with type iterable<object\> is not subtype of native type array#'
|
||||
- '#Method Rector\\BetterPhpDocParser\\AnnotationReader\\NodeAnnotationReader\:\:createClassReflectionFromNode\(\) return type with generic class ReflectionClass does not specify its types\: T#'
|
||||
- '#Method Rector\\FileSystemRector\\Rector\\AbstractFileSystemRector\:\:wrapToArg\(\) should return array<PhpParser\\Node\\Arg\> but returns array<PhpParser\\Node\\Arg\|PhpParser\\Node\\Expr\>#'
|
||||
- '#Method Rector\\SOLID\\Rector\\ClassConst\\PrivatizeLocalClassConstantRector\:\:resolveParentClassConstantReflection\(\) should return ReflectionClassConstant\|null but returns ReflectionClassConstant\|false#'
|
||||
- '#PHPDoc tag @var for variable \$parentClass contains generic class ReflectionClass but does not specify its types\: T#'
|
||||
- '#Method Rector\\SOLID\\Reflection\\ParentConstantReflectionResolver\:\:(.*?)\(\) should return ReflectionClassConstant\|null but returns ReflectionClassConstant\|false#'
|
||||
|
||||
- '#Method Rector\\Core\\NodeContainer\\NodeCollector\\ParsedFunctionLikeNodesByType\:\:findFunction\(\) should return PhpParser\\Node\\Stmt\\Function_\|null but returns PhpParser\\Node\|null#'
|
||||
|
|
|
@ -53,9 +53,9 @@ services:
|
|||
Rector\PhpDoc\PhpDocClassRenamer: Rector\Core\PhpDoc\PhpDocClassRenamer
|
||||
Rector\Util\RectorStrings: Rector\Core\Util\RectorStrings
|
||||
Rector\HttpKernel\RectorKernel: Rector\Core\HttpKernel\RectorKernel
|
||||
Rector\NodeContainer\FunctionLikeParsedNodesFinder: Rector\Core\NodeContainer\FunctionLikeParsedNodesFinder
|
||||
Rector\NodeContainer\FunctionLikeParsedNodesFinder: Rector\Core\NodeContainer\NodeFinder\FunctionLikeParsedNodesFinder
|
||||
Rector\NodeContainer\ClassLikeParsedNodesFinder: Rector\Core\NodeContainer\ClassLikeParsedNodesFinder
|
||||
Rector\NodeContainer\ParsedNodesByType: Rector\Core\NodeContainer\ParsedNodesByType
|
||||
Rector\NodeContainer\ParsedNodesByType: Rector\Core\NodeContainer\NodeCollector\ParsedNodesByType
|
||||
Rector\FileSystem\FileGuard: Rector\Core\FileSystem\FileGuard
|
||||
Rector\FileSystem\FilesystemTweaker: Rector\Core\FileSystem\FilesystemTweaker
|
||||
Rector\FileSystem\FilesFinder: Rector\Core\FileSystem\FilesFinder
|
||||
|
|
|
@ -1,77 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Core\NodeContainer;
|
||||
|
||||
use PhpParser\Node\Expr\MethodCall;
|
||||
use PhpParser\Node\Expr\StaticCall;
|
||||
use PhpParser\Node\Stmt\ClassMethod;
|
||||
use PHPStan\Type\TypeUtils;
|
||||
use Rector\Core\PhpParser\Node\Resolver\NameResolver;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
use Rector\NodeTypeResolver\NodeTypeResolver;
|
||||
|
||||
final class FunctionLikeParsedNodesFinder
|
||||
{
|
||||
/**
|
||||
* @var ParsedNodesByType
|
||||
*/
|
||||
private $parsedNodesByType;
|
||||
|
||||
/**
|
||||
* @var NameResolver
|
||||
*/
|
||||
private $nameResolver;
|
||||
|
||||
/**
|
||||
* @var NodeTypeResolver
|
||||
*/
|
||||
private $nodeTypeResolver;
|
||||
|
||||
public function __construct(
|
||||
ParsedNodesByType $parsedNodesByType,
|
||||
NameResolver $nameResolver,
|
||||
NodeTypeResolver $nodeTypeResolver
|
||||
) {
|
||||
$this->parsedNodesByType = $parsedNodesByType;
|
||||
$this->nameResolver = $nameResolver;
|
||||
$this->nodeTypeResolver = $nodeTypeResolver;
|
||||
}
|
||||
|
||||
public function findClassMethodByMethodCall(MethodCall $methodCall): ?ClassMethod
|
||||
{
|
||||
/** @var string|null $className */
|
||||
$className = $methodCall->getAttribute(AttributeKey::CLASS_NAME);
|
||||
if ($className === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$methodName = $this->nameResolver->getName($methodCall->name);
|
||||
if ($methodName === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $this->parsedNodesByType->findMethod($methodName, $className);
|
||||
}
|
||||
|
||||
public function findClassMethodByStaticCall(StaticCall $staticCall): ?ClassMethod
|
||||
{
|
||||
$methodName = $this->nameResolver->getName($staticCall->name);
|
||||
if ($methodName === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$objectType = $this->nodeTypeResolver->resolve($staticCall->class);
|
||||
|
||||
$classNames = TypeUtils::getDirectClassNames($objectType);
|
||||
foreach ($classNames as $className) {
|
||||
$foundMethod = $this->parsedNodesByType->findMethod($methodName, $className);
|
||||
if ($foundMethod !== null) {
|
||||
return $foundMethod;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,290 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Core\NodeContainer\NodeCollector;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Expr\Array_;
|
||||
use PhpParser\Node\Expr\ClassConstFetch;
|
||||
use PhpParser\Node\Expr\MethodCall;
|
||||
use PhpParser\Node\Expr\StaticCall;
|
||||
use PhpParser\Node\Expr\Variable;
|
||||
use PhpParser\Node\Param;
|
||||
use PhpParser\Node\Scalar\String_;
|
||||
use PhpParser\Node\Stmt\ClassMethod;
|
||||
use PhpParser\Node\Stmt\Function_;
|
||||
use PHPStan\Type\MixedType;
|
||||
use PHPStan\Type\ObjectType;
|
||||
use PHPStan\Type\Type;
|
||||
use PHPStan\Type\UnionType;
|
||||
use Rector\Core\PhpParser\Node\Resolver\NameResolver;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
use Rector\NodeTypeResolver\NodeTypeResolver;
|
||||
|
||||
/**
|
||||
* All parsed nodes grouped type
|
||||
*/
|
||||
final class ParsedFunctionLikeNodeCollector
|
||||
{
|
||||
/**
|
||||
* @var ClassMethod[][]
|
||||
*/
|
||||
private $methodsByType = [];
|
||||
|
||||
/**
|
||||
* @var Function_[]
|
||||
*/
|
||||
private $functionsByName = [];
|
||||
|
||||
/**
|
||||
* @var MethodCall[][][]|StaticCall[][][]
|
||||
*/
|
||||
private $methodsCallsByTypeAndMethod = [];
|
||||
|
||||
/**
|
||||
* E.g. [$this, 'someLocalMethod']
|
||||
* @var Array_[][][]
|
||||
*/
|
||||
private $arrayCallablesByTypeAndMethod = [];
|
||||
|
||||
/**
|
||||
* @var NameResolver
|
||||
*/
|
||||
private $nameResolver;
|
||||
|
||||
/**
|
||||
* @var NodeTypeResolver
|
||||
*/
|
||||
private $nodeTypeResolver;
|
||||
|
||||
public function __construct(NameResolver $nameResolver)
|
||||
{
|
||||
$this->nameResolver = $nameResolver;
|
||||
}
|
||||
|
||||
/**
|
||||
* To prevent circular reference
|
||||
* @required
|
||||
*/
|
||||
public function autowireParsedNodesByType(NodeTypeResolver $nodeTypeResolver): void
|
||||
{
|
||||
$this->nodeTypeResolver = $nodeTypeResolver;
|
||||
}
|
||||
|
||||
public function collect(Node $node): void
|
||||
{
|
||||
if ($node instanceof ClassMethod) {
|
||||
$this->addMethod($node);
|
||||
return;
|
||||
}
|
||||
|
||||
// array callable - [$this, 'someCall']
|
||||
if ($node instanceof Array_) {
|
||||
$arrayCallableClassAndMethod = $this->matchArrayCallableClassAndMethod($node);
|
||||
if ($arrayCallableClassAndMethod === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
[$className, $methodName] = $arrayCallableClassAndMethod;
|
||||
if (! method_exists($className, $methodName)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->arrayCallablesByTypeAndMethod[$className][$methodName][] = $node;
|
||||
return;
|
||||
}
|
||||
|
||||
if ($node instanceof MethodCall || $node instanceof StaticCall) {
|
||||
$this->addCall($node);
|
||||
}
|
||||
|
||||
if ($node instanceof Function_) {
|
||||
$functionName = $this->nameResolver->getName($node);
|
||||
if ($functionName === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->functionsByName[$functionName] = $node;
|
||||
}
|
||||
}
|
||||
|
||||
public function findFunction(string $name): ?Function_
|
||||
{
|
||||
return $this->functionsByName[$name] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return MethodCall[][]|StaticCall[][]
|
||||
*/
|
||||
public function findMethodCallsOnClass(string $className): array
|
||||
{
|
||||
return $this->methodsCallsByTypeAndMethod[$className] ?? [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return MethodCall[]|StaticCall[]|Array_[]
|
||||
*/
|
||||
public function findByClassAndMethod(string $className, string $methodName): array
|
||||
{
|
||||
return $this->methodsCallsByTypeAndMethod[$className][$methodName] ?? $this->arrayCallablesByTypeAndMethod[$className][$methodName] ?? [];
|
||||
}
|
||||
|
||||
public function findMethod(string $className, string $methodName): ?ClassMethod
|
||||
{
|
||||
if (isset($this->methodsByType[$className][$methodName])) {
|
||||
return $this->methodsByType[$className][$methodName];
|
||||
}
|
||||
|
||||
$parentClass = $className;
|
||||
while ($parentClass = get_parent_class($parentClass)) {
|
||||
if (isset($this->methodsByType[$parentClass][$methodName])) {
|
||||
return $this->methodsByType[$parentClass][$methodName];
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private function addMethod(ClassMethod $classMethod): void
|
||||
{
|
||||
$className = $classMethod->getAttribute(AttributeKey::CLASS_NAME);
|
||||
if ($className === null) { // anonymous
|
||||
return;
|
||||
}
|
||||
|
||||
$methodName = $this->nameResolver->getName($classMethod);
|
||||
$this->methodsByType[$className][$methodName] = $classMethod;
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo decouple to NodeAnalyzer
|
||||
* Matches array like: "[$this, 'methodName']" → ['ClassName', 'methodName']
|
||||
* @return string[]|null
|
||||
*/
|
||||
private function matchArrayCallableClassAndMethod(Array_ $array): ?array
|
||||
{
|
||||
if (count($array->items) !== 2) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($array->items[0] === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// $this, self, static, FQN
|
||||
if (! $this->isThisVariable($array->items[0]->value)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($array->items[1] === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (! $array->items[1]->value instanceof String_) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/** @var String_ $string */
|
||||
$string = $array->items[1]->value;
|
||||
|
||||
$methodName = $string->value;
|
||||
$className = $array->getAttribute(AttributeKey::CLASS_NAME);
|
||||
|
||||
if ($className === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return [$className, $methodName];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param MethodCall|StaticCall $node
|
||||
*/
|
||||
private function addCall(Node $node): void
|
||||
{
|
||||
// one node can be of multiple-class types
|
||||
if ($node instanceof MethodCall) {
|
||||
if ($node->var instanceof MethodCall) {
|
||||
$classType = $this->resolveNodeClassTypes($node);
|
||||
} else {
|
||||
$classType = $this->resolveNodeClassTypes($node->var);
|
||||
}
|
||||
} else {
|
||||
$classType = $this->resolveNodeClassTypes($node->class);
|
||||
}
|
||||
|
||||
$methodName = $this->nameResolver->getName($node);
|
||||
if ($classType instanceof MixedType) { // anonymous
|
||||
return;
|
||||
}
|
||||
|
||||
if ($methodName === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($classType instanceof ObjectType) {
|
||||
$this->methodsCallsByTypeAndMethod[$classType->getClassName()][$methodName][] = $node;
|
||||
}
|
||||
|
||||
if ($classType instanceof UnionType) {
|
||||
foreach ($classType->getTypes() as $unionedType) {
|
||||
if (! $unionedType instanceof ObjectType) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->methodsCallsByTypeAndMethod[$unionedType->getClassName()][$methodName][] = $node;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function isThisVariable(Node $node): bool
|
||||
{
|
||||
// $this
|
||||
if ($node instanceof Variable && $this->nameResolver->isName($node, 'this')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($node instanceof ClassConstFetch) {
|
||||
if (! $this->nameResolver->isName($node->name, 'class')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// self::class, static::class
|
||||
if ($this->nameResolver->isNames($node->class, ['self', 'static'])) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/** @var string|null $className */
|
||||
$className = $node->getAttribute(AttributeKey::CLASS_NAME);
|
||||
|
||||
if ($className === null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->nameResolver->isName($node->class, $className);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private function resolveNodeClassTypes(Node $node): Type
|
||||
{
|
||||
if ($node instanceof MethodCall && $node->var instanceof Variable && $node->var->name === 'this') {
|
||||
/** @var string|null $className */
|
||||
$className = $node->getAttribute(AttributeKey::CLASS_NAME);
|
||||
|
||||
if ($className) {
|
||||
return new ObjectType($className);
|
||||
}
|
||||
|
||||
return new MixedType();
|
||||
}
|
||||
|
||||
if ($node instanceof MethodCall) {
|
||||
return $this->nodeTypeResolver->resolve($node->var);
|
||||
}
|
||||
|
||||
return $this->nodeTypeResolver->resolve($node);
|
||||
}
|
||||
}
|
287
src/NodeContainer/NodeCollector/ParsedNodeCollector.php
Normal file
287
src/NodeContainer/NodeCollector/ParsedNodeCollector.php
Normal file
|
@ -0,0 +1,287 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Core\NodeContainer\NodeCollector;
|
||||
|
||||
use Nette\Utils\Strings;
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Expr\Array_;
|
||||
use PhpParser\Node\Expr\ClassConstFetch;
|
||||
use PhpParser\Node\Expr\MethodCall;
|
||||
use PhpParser\Node\Expr\New_;
|
||||
use PhpParser\Node\Expr\StaticCall;
|
||||
use PhpParser\Node\Param;
|
||||
use PhpParser\Node\Stmt\Class_;
|
||||
use PhpParser\Node\Stmt\ClassConst;
|
||||
use PhpParser\Node\Stmt\ClassLike;
|
||||
use PhpParser\Node\Stmt\ClassMethod;
|
||||
use PhpParser\Node\Stmt\Interface_;
|
||||
use PhpParser\Node\Stmt\Trait_;
|
||||
use Rector\Core\Exception\NotImplementedException;
|
||||
use Rector\Core\Exception\ShouldNotHappenException;
|
||||
use Rector\Core\PhpParser\Node\Resolver\NameResolver;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
|
||||
/**
|
||||
* All parsed nodes grouped type
|
||||
*/
|
||||
final class ParsedNodeCollector
|
||||
{
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
private $collectableNodeTypes = [
|
||||
Class_::class,
|
||||
Interface_::class,
|
||||
ClassConst::class,
|
||||
ClassConstFetch::class,
|
||||
Trait_::class,
|
||||
ClassMethod::class,
|
||||
// simply collected
|
||||
New_::class,
|
||||
StaticCall::class,
|
||||
MethodCall::class,
|
||||
// for array callable - [$this, 'someCall']
|
||||
Array_::class,
|
||||
// for unused classes
|
||||
Param::class,
|
||||
];
|
||||
|
||||
/**
|
||||
* @var Class_[]
|
||||
*/
|
||||
private $classes = [];
|
||||
|
||||
/**
|
||||
* @var ClassConst[][]
|
||||
*/
|
||||
private $constantsByType = [];
|
||||
|
||||
/**
|
||||
* @var Node[][]
|
||||
*/
|
||||
private $simpleParsedNodesByType = [];
|
||||
|
||||
/**
|
||||
* @var NameResolver
|
||||
*/
|
||||
private $nameResolver;
|
||||
|
||||
/**
|
||||
* @var Interface_[]
|
||||
*/
|
||||
private $interfaces = [];
|
||||
|
||||
/**
|
||||
* @var Trait_[]
|
||||
*/
|
||||
private $traits = [];
|
||||
|
||||
public function __construct(NameResolver $nameResolver)
|
||||
{
|
||||
$this->nameResolver = $nameResolver;
|
||||
}
|
||||
|
||||
/**
|
||||
* @template T of object
|
||||
* @param class-string<T> $type
|
||||
* @return Node[]|iterable<T>
|
||||
*/
|
||||
public function getNodesByType(string $type): array
|
||||
{
|
||||
return $this->simpleParsedNodesByType[$type] ?? [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Interface_[]
|
||||
*/
|
||||
public function getInterfaces(): array
|
||||
{
|
||||
return $this->interfaces;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Class_[]
|
||||
*/
|
||||
public function getClasses(): array
|
||||
{
|
||||
return $this->classes;
|
||||
}
|
||||
|
||||
public function findClass(string $name): ?Class_
|
||||
{
|
||||
return $this->classes[$name] ?? null;
|
||||
}
|
||||
|
||||
public function findInterface(string $name): ?Interface_
|
||||
{
|
||||
return $this->interfaces[$name] ?? null;
|
||||
}
|
||||
|
||||
public function findTrait(string $name): ?Trait_
|
||||
{
|
||||
return $this->traits[$name] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Guessing the nearest neighboor.
|
||||
* Used e.g. for "XController"
|
||||
*/
|
||||
public function findByShortName(string $shortName): ?Class_
|
||||
{
|
||||
foreach ($this->classes as $className => $classNode) {
|
||||
if (Strings::endsWith($className, '\\' . $shortName)) {
|
||||
return $classNode;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Class_|Interface_|null
|
||||
*/
|
||||
public function findClassOrInterface(string $type): ?ClassLike
|
||||
{
|
||||
$class = $this->findClass($type);
|
||||
if ($class !== null) {
|
||||
return $class;
|
||||
}
|
||||
|
||||
return $this->findInterface($type);
|
||||
}
|
||||
|
||||
public function findClassConstant(string $className, string $constantName): ?ClassConst
|
||||
{
|
||||
if (Strings::contains($constantName, '\\')) {
|
||||
throw new ShouldNotHappenException(sprintf('Switched arguments in "%s"', __METHOD__));
|
||||
}
|
||||
|
||||
return $this->constantsByType[$className][$constantName] ?? null;
|
||||
}
|
||||
|
||||
public function isCollectableNode(Node $node): bool
|
||||
{
|
||||
foreach ($this->collectableNodeTypes as $collectableNodeType) {
|
||||
if (is_a($node, $collectableNodeType, true)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function collect(Node $node): void
|
||||
{
|
||||
$nodeClass = get_class($node);
|
||||
|
||||
if ($node instanceof Class_) {
|
||||
$this->addClass($node);
|
||||
return;
|
||||
}
|
||||
|
||||
if ($node instanceof Interface_ || $node instanceof Trait_) {
|
||||
$name = $this->nameResolver->getName($node);
|
||||
if ($name === null) {
|
||||
throw new ShouldNotHappenException();
|
||||
}
|
||||
|
||||
if ($node instanceof Interface_) {
|
||||
$this->interfaces[$name] = $node;
|
||||
} elseif ($node instanceof Trait_) {
|
||||
$this->traits[$name] = $node;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ($node instanceof ClassConst) {
|
||||
$this->addClassConstant($node);
|
||||
return;
|
||||
}
|
||||
|
||||
// simple collect
|
||||
$this->simpleParsedNodesByType[$nodeClass][] = $node;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return New_[]
|
||||
*/
|
||||
public function findNewNodesByClass(string $className): array
|
||||
{
|
||||
$newNodesByClass = [];
|
||||
|
||||
/** @var New_[] $news */
|
||||
$news = $this->getNodesByType(New_::class);
|
||||
|
||||
foreach ($news as $new) {
|
||||
if (! $this->nameResolver->isName($new->class, $className)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$newNodesByClass[] = $new;
|
||||
}
|
||||
|
||||
return $newNodesByClass;
|
||||
}
|
||||
|
||||
public function findClassConstantByClassConstFetch(ClassConstFetch $classConstFetch): ?ClassConst
|
||||
{
|
||||
$class = $this->nameResolver->getName($classConstFetch->class);
|
||||
|
||||
if ($class === 'self') {
|
||||
/** @var string|null $class */
|
||||
$class = $classConstFetch->getAttribute(AttributeKey::CLASS_NAME);
|
||||
} elseif ($class === 'parent') {
|
||||
/** @var string|null $class */
|
||||
$class = $classConstFetch->getAttribute(AttributeKey::PARENT_CLASS_NAME);
|
||||
}
|
||||
|
||||
if ($class === null) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/** @var string $constantName */
|
||||
$constantName = $this->nameResolver->getName($classConstFetch->name);
|
||||
|
||||
return $this->findClassConstant($class, $constantName);
|
||||
}
|
||||
|
||||
private function addClass(Class_ $classNode): void
|
||||
{
|
||||
if ($this->isClassAnonymous($classNode)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$className = $classNode->getAttribute(AttributeKey::CLASS_NAME);
|
||||
if ($className === null) {
|
||||
throw new ShouldNotHappenException();
|
||||
}
|
||||
|
||||
$this->classes[$className] = $classNode;
|
||||
}
|
||||
|
||||
private function addClassConstant(ClassConst $classConst): void
|
||||
{
|
||||
$className = $classConst->getAttribute(AttributeKey::CLASS_NAME);
|
||||
if ($className === null) {
|
||||
// anonymous class constant
|
||||
return;
|
||||
}
|
||||
|
||||
$constantName = $this->nameResolver->getName($classConst);
|
||||
|
||||
$this->constantsByType[$className][$constantName] = $classConst;
|
||||
}
|
||||
|
||||
private function isClassAnonymous(Class_ $classNode): bool
|
||||
{
|
||||
if ($classNode->isAnonymous() || $classNode->name === null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// PHPStan polution
|
||||
return Strings::startsWith($classNode->name->toString(), 'AnonymousClass');
|
||||
}
|
||||
}
|
|
@ -2,31 +2,32 @@
|
|||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Core\NodeContainer;
|
||||
namespace Rector\Core\NodeContainer\NodeFinder;
|
||||
|
||||
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\Core\NodeContainer\NodeCollector\ParsedNodeCollector;
|
||||
use Rector\Core\PhpParser\Node\Resolver\NameResolver;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
|
||||
final class ClassLikeParsedNodesFinder
|
||||
{
|
||||
/**
|
||||
* @var ParsedNodesByType
|
||||
* @var ParsedNodeCollector
|
||||
*/
|
||||
private $parsedNodesByType;
|
||||
private $parsedNodeCollector;
|
||||
|
||||
/**
|
||||
* @var NameResolver
|
||||
*/
|
||||
private $nameResolver;
|
||||
|
||||
public function __construct(ParsedNodesByType $parsedNodesByType, NameResolver $nameResolver)
|
||||
public function __construct(ParsedNodeCollector $parsedNodeCollector, NameResolver $nameResolver)
|
||||
{
|
||||
$this->parsedNodesByType = $parsedNodesByType;
|
||||
$this->parsedNodeCollector = $parsedNodeCollector;
|
||||
$this->nameResolver = $nameResolver;
|
||||
}
|
||||
|
||||
|
@ -37,7 +38,7 @@ final class ClassLikeParsedNodesFinder
|
|||
{
|
||||
$childrenClasses = [];
|
||||
|
||||
foreach ($this->parsedNodesByType->getClasses() as $classNode) {
|
||||
foreach ($this->parsedNodeCollector->getClasses() as $classNode) {
|
||||
$currentClassName = $classNode->getAttribute(AttributeKey::CLASS_NAME);
|
||||
if (! $this->isChildOrEqualClassLike($class, $currentClassName)) {
|
||||
continue;
|
||||
|
@ -56,7 +57,7 @@ final class ClassLikeParsedNodesFinder
|
|||
{
|
||||
$classNodes = [];
|
||||
|
||||
foreach ($this->parsedNodesByType->getClasses() as $className => $classNode) {
|
||||
foreach ($this->parsedNodeCollector->getClasses() as $className => $classNode) {
|
||||
if (! Strings::endsWith($className, $suffix)) {
|
||||
continue;
|
||||
}
|
||||
|
@ -86,7 +87,7 @@ final class ClassLikeParsedNodesFinder
|
|||
continue;
|
||||
}
|
||||
|
||||
$foundTrait = $this->parsedNodesByType->findTrait($traitName);
|
||||
$foundTrait = $this->parsedNodeCollector->findTrait($traitName);
|
||||
if ($foundTrait !== null) {
|
||||
$traits[] = $foundTrait;
|
||||
}
|
||||
|
@ -111,7 +112,7 @@ final class ClassLikeParsedNodesFinder
|
|||
{
|
||||
$implementerInterfaces = [];
|
||||
|
||||
foreach ($this->parsedNodesByType->getInterfaces() as $interfaceNode) {
|
||||
foreach ($this->parsedNodeCollector->getInterfaces() as $interfaceNode) {
|
||||
$className = $interfaceNode->getAttribute(AttributeKey::CLASS_NAME);
|
||||
|
||||
if (! $this->isChildOrEqualClassLike($interface, $className)) {
|
||||
|
@ -124,6 +125,16 @@ final class ClassLikeParsedNodesFinder
|
|||
return $implementerInterfaces;
|
||||
}
|
||||
|
||||
public function findInterface(string $class): ?Interface_
|
||||
{
|
||||
return $this->parsedNodeCollector->findInterface($class);
|
||||
}
|
||||
|
||||
public function findClass(string $name): ?Class_
|
||||
{
|
||||
return $this->parsedNodeCollector->findClass($name);
|
||||
}
|
||||
|
||||
private function isChildOrEqualClassLike(string $desiredClass, ?string $currentClassName): bool
|
||||
{
|
||||
if ($currentClassName === null) {
|
153
src/NodeContainer/NodeFinder/FunctionLikeParsedNodesFinder.php
Normal file
153
src/NodeContainer/NodeFinder/FunctionLikeParsedNodesFinder.php
Normal file
|
@ -0,0 +1,153 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Core\NodeContainer\NodeFinder;
|
||||
|
||||
use Nette\Utils\Strings;
|
||||
use PhpParser\Node\Expr\Array_;
|
||||
use PhpParser\Node\Expr\MethodCall;
|
||||
use PhpParser\Node\Expr\StaticCall;
|
||||
use PhpParser\Node\Stmt\ClassMethod;
|
||||
use PhpParser\Node\Stmt\Function_;
|
||||
use PHPStan\Type\TypeUtils;
|
||||
use Rector\Core\NodeContainer\NodeCollector\ParsedFunctionLikeNodeCollector;
|
||||
use Rector\Core\PhpParser\Node\Resolver\NameResolver;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
use Rector\NodeTypeResolver\NodeTypeResolver;
|
||||
use ReflectionClass;
|
||||
|
||||
final class FunctionLikeParsedNodesFinder
|
||||
{
|
||||
/**
|
||||
* @var NameResolver
|
||||
*/
|
||||
private $nameResolver;
|
||||
|
||||
/**
|
||||
* @var NodeTypeResolver
|
||||
*/
|
||||
private $nodeTypeResolver;
|
||||
|
||||
/**
|
||||
* @var ParsedFunctionLikeNodeCollector
|
||||
*/
|
||||
private $parsedFunctionLikeNodeCollector;
|
||||
|
||||
public function __construct(
|
||||
NameResolver $nameResolver,
|
||||
NodeTypeResolver $nodeTypeResolver,
|
||||
ParsedFunctionLikeNodeCollector $parsedFunctionLikeNodeCollector
|
||||
) {
|
||||
$this->nameResolver = $nameResolver;
|
||||
$this->nodeTypeResolver = $nodeTypeResolver;
|
||||
$this->parsedFunctionLikeNodeCollector = $parsedFunctionLikeNodeCollector;
|
||||
}
|
||||
|
||||
public function findClassMethodByMethodCall(MethodCall $methodCall): ?ClassMethod
|
||||
{
|
||||
/** @var string|null $className */
|
||||
$className = $methodCall->getAttribute(AttributeKey::CLASS_NAME);
|
||||
if ($className === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$methodName = $this->nameResolver->getName($methodCall->name);
|
||||
if ($methodName === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $this->findMethod($methodName, $className);
|
||||
}
|
||||
|
||||
public function findClassMethodByStaticCall(StaticCall $staticCall): ?ClassMethod
|
||||
{
|
||||
$methodName = $this->nameResolver->getName($staticCall->name);
|
||||
if ($methodName === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$objectType = $this->nodeTypeResolver->resolve($staticCall->class);
|
||||
|
||||
$classNames = TypeUtils::getDirectClassNames($objectType);
|
||||
foreach ($classNames as $className) {
|
||||
$foundMethod = $this->findMethod($methodName, $className);
|
||||
if ($foundMethod !== null) {
|
||||
return $foundMethod;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function findFunction(string $name): ?Function_
|
||||
{
|
||||
return $this->parsedFunctionLikeNodeCollector->findFunction($name);
|
||||
}
|
||||
|
||||
public function findMethod(string $methodName, string $className): ?ClassMethod
|
||||
{
|
||||
return $this->parsedFunctionLikeNodeCollector->findMethod($className, $methodName);
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo deocpule
|
||||
*/
|
||||
public function isStaticMethod(string $methodName, string $className): bool
|
||||
{
|
||||
$methodNode = $this->findMethod($methodName, $className);
|
||||
if ($methodNode !== null) {
|
||||
return $methodNode->isStatic();
|
||||
}
|
||||
|
||||
// could be static in doc type magic
|
||||
// @see https://regex101.com/r/tlvfTB/1
|
||||
if (class_exists($className) || trait_exists($className)) {
|
||||
$reflectionClass = new ReflectionClass($className);
|
||||
if (Strings::match(
|
||||
(string) $reflectionClass->getDocComment(),
|
||||
'#@method\s*static\s*(.*?)\b' . $methodName . '\b#'
|
||||
)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// probably magic method → we don't know
|
||||
if (! method_exists($className, $methodName)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$methodReflection = $reflectionClass->getMethod($methodName);
|
||||
return $methodReflection->isStatic();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return MethodCall[]|StaticCall[]|Array_[]
|
||||
*/
|
||||
public function findClassMethodCalls(ClassMethod $classMethod): array
|
||||
{
|
||||
/** @var string|null $className */
|
||||
$className = $classMethod->getAttribute(AttributeKey::CLASS_NAME);
|
||||
if ($className === null) { // anonymous
|
||||
return [];
|
||||
}
|
||||
|
||||
/** @var string|null $methodName */
|
||||
$methodName = $this->nameResolver->getName($classMethod);
|
||||
if ($methodName === null) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return $this->parsedFunctionLikeNodeCollector->findByClassAndMethod($className, $methodName);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return MethodCall[][]|StaticCall[][]
|
||||
*/
|
||||
public function findMethodCallsOnClass(string $className): array
|
||||
{
|
||||
return $this->parsedFunctionLikeNodeCollector->findMethodCallsOnClass($className);
|
||||
}
|
||||
}
|
|
@ -1,555 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Core\NodeContainer;
|
||||
|
||||
use Nette\Utils\Strings;
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Expr\Array_;
|
||||
use PhpParser\Node\Expr\ClassConstFetch;
|
||||
use PhpParser\Node\Expr\MethodCall;
|
||||
use PhpParser\Node\Expr\New_;
|
||||
use PhpParser\Node\Expr\StaticCall;
|
||||
use PhpParser\Node\Expr\Variable;
|
||||
use PhpParser\Node\Param;
|
||||
use PhpParser\Node\Scalar\String_;
|
||||
use PhpParser\Node\Stmt\Class_;
|
||||
use PhpParser\Node\Stmt\ClassConst;
|
||||
use PhpParser\Node\Stmt\ClassLike;
|
||||
use PhpParser\Node\Stmt\ClassMethod;
|
||||
use PhpParser\Node\Stmt\Function_;
|
||||
use PhpParser\Node\Stmt\Interface_;
|
||||
use PhpParser\Node\Stmt\Trait_;
|
||||
use PHPStan\Type\MixedType;
|
||||
use PHPStan\Type\ObjectType;
|
||||
use PHPStan\Type\Type;
|
||||
use PHPStan\Type\UnionType;
|
||||
use Rector\Core\Exception\NotImplementedException;
|
||||
use Rector\Core\Exception\ShouldNotHappenException;
|
||||
use Rector\Core\PhpParser\Node\Resolver\NameResolver;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
use Rector\NodeTypeResolver\NodeTypeResolver;
|
||||
use ReflectionClass;
|
||||
|
||||
/**
|
||||
* All parsed nodes grouped type
|
||||
*/
|
||||
final class ParsedNodesByType
|
||||
{
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
private $collectableNodeTypes = [
|
||||
Class_::class,
|
||||
Interface_::class,
|
||||
ClassConst::class,
|
||||
ClassConstFetch::class,
|
||||
Trait_::class,
|
||||
ClassMethod::class,
|
||||
Function_::class,
|
||||
// simply collected
|
||||
New_::class,
|
||||
StaticCall::class,
|
||||
MethodCall::class,
|
||||
// for array callable - [$this, 'someCall']
|
||||
Array_::class,
|
||||
// for unused classes
|
||||
Param::class,
|
||||
];
|
||||
|
||||
/**
|
||||
* @var Class_[]
|
||||
*/
|
||||
private $classes = [];
|
||||
|
||||
/**
|
||||
* @var ClassConst[][]
|
||||
*/
|
||||
private $constantsByType = [];
|
||||
|
||||
/**
|
||||
* @var ClassMethod[][]
|
||||
*/
|
||||
private $methodsByType = [];
|
||||
|
||||
/**
|
||||
* @var Node[][]
|
||||
*/
|
||||
private $simpleParsedNodesByType = [];
|
||||
|
||||
/**
|
||||
* @var MethodCall[][][]|StaticCall[][][]
|
||||
*/
|
||||
private $methodsCallsByTypeAndMethod = [];
|
||||
|
||||
/**
|
||||
* E.g. [$this, 'someLocalMethod']
|
||||
* @var Array_[][][]
|
||||
*/
|
||||
private $arrayCallablesByTypeAndMethod = [];
|
||||
|
||||
/**
|
||||
* @var NameResolver
|
||||
*/
|
||||
private $nameResolver;
|
||||
|
||||
/**
|
||||
* @var NodeTypeResolver
|
||||
*/
|
||||
private $nodeTypeResolver;
|
||||
|
||||
public function __construct(NameResolver $nameResolver)
|
||||
{
|
||||
$this->nameResolver = $nameResolver;
|
||||
}
|
||||
|
||||
/**
|
||||
* @template T of object
|
||||
* @param class-string<T> $type
|
||||
* @return Node[]|iterable<T>
|
||||
*/
|
||||
public function getNodesByType(string $type): array
|
||||
{
|
||||
return $this->simpleParsedNodesByType[$type] ?? [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Interface_[]
|
||||
*/
|
||||
public function getInterfaces(): array
|
||||
{
|
||||
return $this->simpleParsedNodesByType[Interface_::class] ?? [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Class_[]
|
||||
*/
|
||||
public function getClasses(): array
|
||||
{
|
||||
return $this->classes;
|
||||
}
|
||||
|
||||
/**
|
||||
* To prevent circular reference
|
||||
* @required
|
||||
*/
|
||||
public function autowireParsedNodesByType(NodeTypeResolver $nodeTypeResolver): void
|
||||
{
|
||||
$this->nodeTypeResolver = $nodeTypeResolver;
|
||||
}
|
||||
|
||||
public function findClass(string $name): ?Class_
|
||||
{
|
||||
return $this->classes[$name] ?? null;
|
||||
}
|
||||
|
||||
public function findInterface(string $name): ?Interface_
|
||||
{
|
||||
return $this->simpleParsedNodesByType[Interface_::class][$name] ?? null;
|
||||
}
|
||||
|
||||
public function findTrait(string $name): ?Trait_
|
||||
{
|
||||
return $this->simpleParsedNodesByType[Trait_::class][$name] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Guessing the nearest neighboor.
|
||||
* Used e.g. for "XController"
|
||||
*/
|
||||
public function findByShortName(string $shortName): ?Class_
|
||||
{
|
||||
foreach ($this->classes as $className => $classNode) {
|
||||
if (Strings::endsWith($className, '\\' . $shortName)) {
|
||||
return $classNode;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Class_|Interface_|null
|
||||
*/
|
||||
public function findClassOrInterface(string $type): ?ClassLike
|
||||
{
|
||||
$class = $this->findClass($type);
|
||||
if ($class !== null) {
|
||||
return $class;
|
||||
}
|
||||
|
||||
return $this->findInterface($type);
|
||||
}
|
||||
|
||||
public function findClassConstant(string $className, string $constantName): ?ClassConst
|
||||
{
|
||||
if (Strings::contains($constantName, '\\')) {
|
||||
throw new ShouldNotHappenException(sprintf('Switched arguments in "%s"', __METHOD__));
|
||||
}
|
||||
|
||||
return $this->constantsByType[$className][$constantName] ?? null;
|
||||
}
|
||||
|
||||
public function findFunction(string $name): ?Function_
|
||||
{
|
||||
return $this->simpleParsedNodesByType[Function_::class][$name] ?? null;
|
||||
}
|
||||
|
||||
public function findMethod(string $methodName, string $className): ?ClassMethod
|
||||
{
|
||||
if (isset($this->methodsByType[$className][$methodName])) {
|
||||
return $this->methodsByType[$className][$methodName];
|
||||
}
|
||||
|
||||
$parentClass = $className;
|
||||
while ($parentClass = get_parent_class($parentClass)) {
|
||||
if (isset($this->methodsByType[$parentClass][$methodName])) {
|
||||
return $this->methodsByType[$parentClass][$methodName];
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function isStaticMethod(string $methodName, string $className): bool
|
||||
{
|
||||
$methodNode = $this->findMethod($methodName, $className);
|
||||
if ($methodNode !== null) {
|
||||
return $methodNode->isStatic();
|
||||
}
|
||||
|
||||
// could be static in doc type magic
|
||||
// @see https://regex101.com/r/tlvfTB/1
|
||||
if (class_exists($className) || trait_exists($className)) {
|
||||
$reflectionClass = new ReflectionClass($className);
|
||||
if (Strings::match(
|
||||
(string) $reflectionClass->getDocComment(),
|
||||
'#@method\s*static\s*(.*?)\b' . $methodName . '\b#'
|
||||
)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// probably magic method → we don't know
|
||||
if (! method_exists($className, $methodName)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$methodReflection = $reflectionClass->getMethod($methodName);
|
||||
return $methodReflection->isStatic();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function isCollectableNode(Node $node): bool
|
||||
{
|
||||
foreach ($this->collectableNodeTypes as $collectableNodeType) {
|
||||
if (is_a($node, $collectableNodeType, true)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function collect(Node $node): void
|
||||
{
|
||||
$nodeClass = get_class($node);
|
||||
|
||||
if ($node instanceof Class_) {
|
||||
$this->addClass($node);
|
||||
return;
|
||||
}
|
||||
|
||||
if ($node instanceof Interface_ || $node instanceof Trait_ || $node instanceof Function_) {
|
||||
$name = $this->nameResolver->getName($node);
|
||||
if ($name === null) {
|
||||
throw new ShouldNotHappenException();
|
||||
}
|
||||
|
||||
$this->simpleParsedNodesByType[$nodeClass][$name] = $node;
|
||||
return;
|
||||
}
|
||||
|
||||
if ($node instanceof ClassConst) {
|
||||
$this->addClassConstant($node);
|
||||
return;
|
||||
}
|
||||
|
||||
if ($node instanceof ClassMethod) {
|
||||
$this->addMethod($node);
|
||||
return;
|
||||
}
|
||||
|
||||
// array callable - [$this, 'someCall']
|
||||
if ($node instanceof Array_) {
|
||||
$arrayCallableClassAndMethod = $this->matchArrayCallableClassAndMethod($node);
|
||||
if ($arrayCallableClassAndMethod === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
[$className, $methodName] = $arrayCallableClassAndMethod;
|
||||
if (! method_exists($className, $methodName)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->arrayCallablesByTypeAndMethod[$className][$methodName][] = $node;
|
||||
return;
|
||||
}
|
||||
|
||||
if ($node instanceof MethodCall || $node instanceof StaticCall) {
|
||||
$this->addCall($node);
|
||||
}
|
||||
|
||||
// simple collect
|
||||
$this->simpleParsedNodesByType[$nodeClass][] = $node;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return MethodCall[]|StaticCall[]|Array_[]
|
||||
*/
|
||||
public function findClassMethodCalls(ClassMethod $classMethod): array
|
||||
{
|
||||
$className = $classMethod->getAttribute(AttributeKey::CLASS_NAME);
|
||||
if ($className === null) { // anonymous
|
||||
return [];
|
||||
}
|
||||
|
||||
$methodName = $this->nameResolver->getName($classMethod);
|
||||
if ($methodName === null) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return $this->methodsCallsByTypeAndMethod[$className][$methodName] ?? $this->arrayCallablesByTypeAndMethod[$className][$methodName] ?? [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return MethodCall[][]|StaticCall[][]
|
||||
*/
|
||||
public function findMethodCallsOnClass(string $className): array
|
||||
{
|
||||
return $this->methodsCallsByTypeAndMethod[$className] ?? [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return New_[]
|
||||
*/
|
||||
public function findNewNodesByClass(string $className): array
|
||||
{
|
||||
$newNodesByClass = [];
|
||||
|
||||
/** @var New_[] $news */
|
||||
$news = $this->getNodesByType(New_::class);
|
||||
|
||||
foreach ($news as $new) {
|
||||
if (! $this->nameResolver->isName($new->class, $className)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$newNodesByClass[] = $new;
|
||||
}
|
||||
|
||||
return $newNodesByClass;
|
||||
}
|
||||
|
||||
public function findClassConstantByClassConstFetch(ClassConstFetch $classConstFetch): ?ClassConst
|
||||
{
|
||||
$class = $this->nameResolver->getName($classConstFetch->class);
|
||||
|
||||
if ($class === 'self') {
|
||||
/** @var string|null $class */
|
||||
$class = $classConstFetch->getAttribute(AttributeKey::CLASS_NAME);
|
||||
} elseif ($class === 'parent') {
|
||||
/** @var string|null $class */
|
||||
$class = $classConstFetch->getAttribute(AttributeKey::PARENT_CLASS_NAME);
|
||||
}
|
||||
|
||||
if ($class === null) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/** @var string $constantName */
|
||||
$constantName = $this->nameResolver->getName($classConstFetch->name);
|
||||
|
||||
return $this->findClassConstant($class, $constantName);
|
||||
}
|
||||
|
||||
private function addClass(Class_ $classNode): void
|
||||
{
|
||||
if ($this->isClassAnonymous($classNode)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$className = $classNode->getAttribute(AttributeKey::CLASS_NAME);
|
||||
if ($className === null) {
|
||||
throw new ShouldNotHappenException();
|
||||
}
|
||||
|
||||
$this->classes[$className] = $classNode;
|
||||
}
|
||||
|
||||
private function addClassConstant(ClassConst $classConst): void
|
||||
{
|
||||
$className = $classConst->getAttribute(AttributeKey::CLASS_NAME);
|
||||
if ($className === null) {
|
||||
// anonymous class constant
|
||||
return;
|
||||
}
|
||||
|
||||
$constantName = $this->nameResolver->getName($classConst);
|
||||
|
||||
$this->constantsByType[$className][$constantName] = $classConst;
|
||||
}
|
||||
|
||||
private function addMethod(ClassMethod $classMethod): void
|
||||
{
|
||||
$className = $classMethod->getAttribute(AttributeKey::CLASS_NAME);
|
||||
if ($className === null) { // anonymous
|
||||
return;
|
||||
}
|
||||
|
||||
$methodName = $this->nameResolver->getName($classMethod);
|
||||
$this->methodsByType[$className][$methodName] = $classMethod;
|
||||
}
|
||||
|
||||
/**
|
||||
* Matches array like: "[$this, 'methodName']" → ['ClassName', 'methodName']
|
||||
* @return string[]|null
|
||||
*/
|
||||
private function matchArrayCallableClassAndMethod(Array_ $array): ?array
|
||||
{
|
||||
if (count($array->items) !== 2) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($array->items[0] === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// $this, self, static, FQN
|
||||
if (! $this->isThisVariable($array->items[0]->value)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($array->items[1] === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (! $array->items[1]->value instanceof String_) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/** @var String_ $string */
|
||||
$string = $array->items[1]->value;
|
||||
|
||||
$methodName = $string->value;
|
||||
$className = $array->getAttribute(AttributeKey::CLASS_NAME);
|
||||
|
||||
if ($className === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return [$className, $methodName];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param MethodCall|StaticCall $node
|
||||
*/
|
||||
private function addCall(Node $node): void
|
||||
{
|
||||
// one node can be of multiple-class types
|
||||
if ($node instanceof MethodCall) {
|
||||
if ($node->var instanceof MethodCall) {
|
||||
$classType = $this->resolveNodeClassTypes($node);
|
||||
} else {
|
||||
$classType = $this->resolveNodeClassTypes($node->var);
|
||||
}
|
||||
} else {
|
||||
$classType = $this->resolveNodeClassTypes($node->class);
|
||||
}
|
||||
|
||||
$methodName = $this->nameResolver->getName($node);
|
||||
if ($classType instanceof MixedType) { // anonymous
|
||||
return;
|
||||
}
|
||||
|
||||
if ($methodName === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($classType instanceof ObjectType) {
|
||||
$this->methodsCallsByTypeAndMethod[$classType->getClassName()][$methodName][] = $node;
|
||||
}
|
||||
|
||||
if ($classType instanceof UnionType) {
|
||||
foreach ($classType->getTypes() as $unionedType) {
|
||||
if (! $unionedType instanceof ObjectType) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->methodsCallsByTypeAndMethod[$unionedType->getClassName()][$methodName][] = $node;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function isClassAnonymous(Class_ $classNode): bool
|
||||
{
|
||||
if ($classNode->isAnonymous() || $classNode->name === null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// PHPStan polution
|
||||
return Strings::startsWith($classNode->name->toString(), 'AnonymousClass');
|
||||
}
|
||||
|
||||
private function isThisVariable(Node $node): bool
|
||||
{
|
||||
// $this
|
||||
if ($node instanceof Variable && $this->nameResolver->isName($node, 'this')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($node instanceof ClassConstFetch) {
|
||||
if (! $this->nameResolver->isName($node->name, 'class')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// self::class, static::class
|
||||
if ($this->nameResolver->isNames($node->class, ['self', 'static'])) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/** @var string|null $className */
|
||||
$className = $node->getAttribute(AttributeKey::CLASS_NAME);
|
||||
|
||||
if ($className === null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->nameResolver->isName($node->class, $className);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private function resolveNodeClassTypes(Node $node): Type
|
||||
{
|
||||
if ($node instanceof MethodCall && $node->var instanceof Variable && $node->var->name === 'this') {
|
||||
/** @var string|null $className */
|
||||
$className = $node->getAttribute(AttributeKey::CLASS_NAME);
|
||||
|
||||
if ($className) {
|
||||
return new ObjectType($className);
|
||||
}
|
||||
|
||||
return new MixedType();
|
||||
}
|
||||
|
||||
if ($node instanceof MethodCall) {
|
||||
return $this->nodeTypeResolver->resolve($node->var);
|
||||
}
|
||||
|
||||
return $this->nodeTypeResolver->resolve($node);
|
||||
}
|
||||
}
|
|
@ -13,7 +13,7 @@ use PhpParser\Node\Expr\FuncCall;
|
|||
use PhpParser\Node\Expr\StaticCall;
|
||||
use PhpParser\Node\Expr\Variable;
|
||||
use PhpParser\Node\Scalar\String_;
|
||||
use Rector\Core\NodeContainer\ParsedNodesByType;
|
||||
use Rector\Core\NodeContainer\NodeCollector\ParsedNodeCollector;
|
||||
use Rector\Core\PhpParser\Node\BetterNodeFinder;
|
||||
use Rector\Core\PhpParser\Node\Resolver\NameResolver;
|
||||
use Rector\Core\PhpParser\Printer\BetterStandardPrinter;
|
||||
|
@ -57,11 +57,6 @@ final class RegexPatternArgumentManipulator
|
|||
*/
|
||||
private $nameResolver;
|
||||
|
||||
/**
|
||||
* @var ParsedNodesByType
|
||||
*/
|
||||
private $parsedNodesByType;
|
||||
|
||||
/**
|
||||
* @var BetterNodeFinder
|
||||
*/
|
||||
|
@ -72,16 +67,21 @@ final class RegexPatternArgumentManipulator
|
|||
*/
|
||||
private $betterStandardPrinter;
|
||||
|
||||
/**
|
||||
* @var ParsedNodeCollector
|
||||
*/
|
||||
private $parsedNodeCollector;
|
||||
|
||||
public function __construct(
|
||||
NodeTypeResolver $nodeTypeResolver,
|
||||
NameResolver $nameResolver,
|
||||
ParsedNodesByType $parsedNodesByType,
|
||||
ParsedNodeCollector $parsedNodeCollector,
|
||||
BetterNodeFinder $betterNodeFinder,
|
||||
BetterStandardPrinter $betterStandardPrinter
|
||||
) {
|
||||
$this->nodeTypeResolver = $nodeTypeResolver;
|
||||
$this->nameResolver = $nameResolver;
|
||||
$this->parsedNodesByType = $parsedNodesByType;
|
||||
$this->parsedNodeCollector = $parsedNodeCollector;
|
||||
$this->betterNodeFinder = $betterNodeFinder;
|
||||
$this->betterStandardPrinter = $betterStandardPrinter;
|
||||
}
|
||||
|
@ -204,7 +204,7 @@ final class RegexPatternArgumentManipulator
|
|||
*/
|
||||
private function resolveClassConstFetchValue(ClassConstFetch $classConstFetch): array
|
||||
{
|
||||
$classConstNode = $this->parsedNodesByType->findClassConstantByClassConstFetch($classConstFetch);
|
||||
$classConstNode = $this->parsedNodeCollector->findClassConstantByClassConstFetch($classConstFetch);
|
||||
if ($classConstNode === null) {
|
||||
return [];
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ declare(strict_types=1);
|
|||
namespace Rector\Core\Php;
|
||||
|
||||
use Nette\Utils\Strings;
|
||||
use Rector\Core\ValueObject\PhpVersionFeature;
|
||||
|
||||
final class TypeAnalyzer
|
||||
{
|
||||
|
@ -30,7 +31,7 @@ final class TypeAnalyzer
|
|||
|
||||
public function __construct(PhpVersionProvider $phpVersionProvider)
|
||||
{
|
||||
if ($phpVersionProvider->isAtLeast('7.2')) {
|
||||
if ($phpVersionProvider->isAtLeast(PhpVersionFeature::OBJECT_TYPE)) {
|
||||
$this->phpSupportedTypes[] = 'object';
|
||||
}
|
||||
}
|
||||
|
@ -78,9 +79,4 @@ final class TypeAnalyzer
|
|||
|
||||
return $type;
|
||||
}
|
||||
|
||||
public function isPhpSupported(string $type): bool
|
||||
{
|
||||
return in_array($type, $this->phpSupportedTypes, true);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,19 +7,14 @@ namespace Rector\Core\PhpParser\Node\Manipulator;
|
|||
use PhpParser\Node\Stmt\Class_;
|
||||
use PhpParser\Node\Stmt\ClassMethod;
|
||||
use PhpParser\Node\Stmt\Expression;
|
||||
use Rector\Core\NodeContainer\ClassLikeParsedNodesFinder;
|
||||
use Rector\Core\NodeContainer\ParsedNodesByType;
|
||||
use Rector\Core\NodeContainer\NodeCollector\ParsedNodeCollector;
|
||||
use Rector\Core\NodeContainer\NodeFinder\ClassLikeParsedNodesFinder;
|
||||
use Rector\Core\PhpParser\Node\NodeFactory;
|
||||
use Rector\Core\PhpParser\Node\Resolver\NameResolver;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
|
||||
final class ChildAndParentClassManipulator
|
||||
{
|
||||
/**
|
||||
* @var ParsedNodesByType
|
||||
*/
|
||||
private $parsedNodesByType;
|
||||
|
||||
/**
|
||||
* @var NodeFactory
|
||||
*/
|
||||
|
@ -35,16 +30,21 @@ final class ChildAndParentClassManipulator
|
|||
*/
|
||||
private $classLikeParsedNodesFinder;
|
||||
|
||||
/**
|
||||
* @var ParsedNodeCollector
|
||||
*/
|
||||
private $parsedNodeCollector;
|
||||
|
||||
public function __construct(
|
||||
ParsedNodesByType $parsedNodesByType,
|
||||
ParsedNodeCollector $parsedNodeCollector,
|
||||
NodeFactory $nodeFactory,
|
||||
NameResolver $nameResolver,
|
||||
ClassLikeParsedNodesFinder $classLikeParsedNodesFinder
|
||||
) {
|
||||
$this->parsedNodesByType = $parsedNodesByType;
|
||||
$this->nodeFactory = $nodeFactory;
|
||||
$this->nameResolver = $nameResolver;
|
||||
$this->classLikeParsedNodesFinder = $classLikeParsedNodesFinder;
|
||||
$this->parsedNodeCollector = $parsedNodeCollector;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -59,7 +59,7 @@ final class ChildAndParentClassManipulator
|
|||
}
|
||||
|
||||
// not in analyzed scope, nothing we can do
|
||||
$parentClassNode = $this->parsedNodesByType->findClass($parentClassName);
|
||||
$parentClassNode = $this->parsedNodeCollector->findClass($parentClassName);
|
||||
if ($parentClassNode !== null) {
|
||||
$this->completeParentConstructorBasedOnParentNode($parentClassNode, $classMethod);
|
||||
return;
|
||||
|
@ -142,7 +142,7 @@ final class ChildAndParentClassManipulator
|
|||
return null;
|
||||
}
|
||||
|
||||
$classNode = $this->parsedNodesByType->findClass($parentClassName);
|
||||
$classNode = $this->parsedNodeCollector->findClass($parentClassName);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
|
|
@ -8,7 +8,7 @@ use PhpParser\Node;
|
|||
use PhpParser\Node\Expr\ClassConstFetch;
|
||||
use PhpParser\Node\Stmt\Class_;
|
||||
use PhpParser\Node\Stmt\ClassConst;
|
||||
use Rector\Core\NodeContainer\ParsedNodesByType;
|
||||
use Rector\Core\NodeContainer\NodeCollector\ParsedNodeCollector;
|
||||
use Rector\Core\PhpParser\Node\BetterNodeFinder;
|
||||
use Rector\Core\PhpParser\Node\Resolver\NameResolver;
|
||||
use Rector\Core\PhpParser\Printer\BetterStandardPrinter;
|
||||
|
@ -32,9 +32,9 @@ final class ClassConstManipulator
|
|||
private $betterStandardPrinter;
|
||||
|
||||
/**
|
||||
* @var ParsedNodesByType
|
||||
* @var ParsedNodeCollector
|
||||
*/
|
||||
private $parsedNodesByType;
|
||||
private $parsedNodeCollector;
|
||||
|
||||
/**
|
||||
* @var ClassManipulator
|
||||
|
@ -45,13 +45,13 @@ final class ClassConstManipulator
|
|||
NameResolver $nameResolver,
|
||||
BetterNodeFinder $betterNodeFinder,
|
||||
BetterStandardPrinter $betterStandardPrinter,
|
||||
ParsedNodesByType $parsedNodesByType,
|
||||
ParsedNodeCollector $parsedNodeCollector,
|
||||
ClassManipulator $classManipulator
|
||||
) {
|
||||
$this->nameResolver = $nameResolver;
|
||||
$this->betterNodeFinder = $betterNodeFinder;
|
||||
$this->betterStandardPrinter = $betterStandardPrinter;
|
||||
$this->parsedNodesByType = $parsedNodesByType;
|
||||
$this->parsedNodeCollector = $parsedNodeCollector;
|
||||
$this->classManipulator = $classManipulator;
|
||||
}
|
||||
|
||||
|
@ -68,7 +68,7 @@ final class ClassConstManipulator
|
|||
|
||||
$searchInNodes = [$classNode];
|
||||
foreach ($this->classManipulator->getUsedTraits($classNode) as $trait) {
|
||||
$trait = $this->parsedNodesByType->findTrait((string) $trait);
|
||||
$trait = $this->parsedNodeCollector->findTrait((string) $trait);
|
||||
if ($trait === null) {
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ use PhpParser\Node\Stmt\PropertyProperty;
|
|||
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo;
|
||||
use Rector\BetterPhpDocParser\PhpDocNode\JMS\SerializerTypeTagValueNode;
|
||||
use Rector\Core\Exception\ShouldNotHappenException;
|
||||
use Rector\Core\NodeContainer\ClassLikeParsedNodesFinder;
|
||||
use Rector\Core\NodeContainer\NodeFinder\ClassLikeParsedNodesFinder;
|
||||
use Rector\Core\PhpParser\Node\BetterNodeFinder;
|
||||
use Rector\Core\PhpParser\Node\Resolver\NameResolver;
|
||||
use Rector\Core\PhpParser\Printer\BetterStandardPrinter;
|
||||
|
|
|
@ -14,7 +14,7 @@ use PhpParser\Node\Scalar\MagicConst\File;
|
|||
use PHPStan\Type\Constant\ConstantArrayType;
|
||||
use PHPStan\Type\ConstantScalarType;
|
||||
use Rector\Core\Exception\ShouldNotHappenException;
|
||||
use Rector\Core\NodeContainer\ParsedNodesByType;
|
||||
use Rector\Core\NodeContainer\NodeCollector\ParsedNodeCollector;
|
||||
use Rector\Core\PhpParser\Node\Resolver\NameResolver;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
use Rector\NodeTypeResolver\NodeTypeResolver;
|
||||
|
@ -36,9 +36,9 @@ final class ValueResolver
|
|||
private $constExprEvaluator;
|
||||
|
||||
/**
|
||||
* @var ParsedNodesByType
|
||||
* @var ParsedNodeCollector
|
||||
*/
|
||||
private $parsedNodesByType;
|
||||
private $parsedNodeCollector;
|
||||
|
||||
/**
|
||||
* @var NodeTypeResolver
|
||||
|
@ -48,10 +48,10 @@ final class ValueResolver
|
|||
public function __construct(
|
||||
NameResolver $nameResolver,
|
||||
NodeTypeResolver $nodeTypeResolver,
|
||||
ParsedNodesByType $parsedNodesByType
|
||||
ParsedNodeCollector $parsedNodeCollector
|
||||
) {
|
||||
$this->nameResolver = $nameResolver;
|
||||
$this->parsedNodesByType = $parsedNodesByType;
|
||||
$this->parsedNodeCollector = $parsedNodeCollector;
|
||||
$this->nodeTypeResolver = $nodeTypeResolver;
|
||||
}
|
||||
|
||||
|
@ -192,7 +192,7 @@ final class ValueResolver
|
|||
return $class;
|
||||
}
|
||||
|
||||
$classConstNode = $this->parsedNodesByType->findClassConstant($class, $constant);
|
||||
$classConstNode = $this->parsedNodeCollector->findClassConstant($class, $constant);
|
||||
|
||||
if ($classConstNode === null) {
|
||||
// fallback to the name
|
||||
|
|
|
@ -15,15 +15,12 @@ use PhpParser\Node\Stmt\Expression;
|
|||
use PhpParser\NodeVisitorAbstract;
|
||||
use PHPStan\Analyser\Scope;
|
||||
use Rector\BetterPhpDocParser\Printer\PhpDocInfoPrinter;
|
||||
use Rector\CodingStyle\Rector\ClassMethod\NewlineBeforeNewAssignSetRector;
|
||||
use Rector\CodingStyle\Rector\Namespace_\ImportFullyQualifiedNamesRector;
|
||||
use Rector\Core\Commander\CommanderCollector;
|
||||
use Rector\Core\Contract\PhpParser\Node\CommanderInterface;
|
||||
use Rector\Core\Contract\Rector\PhpRectorInterface;
|
||||
use Rector\DeadCode\Rector\FunctionLike\RemoveCodeAfterReturnRector;
|
||||
use Rector\Core\Exclusion\ExclusionManager;
|
||||
use Rector\Core\NodeContainer\ClassLikeParsedNodesFinder;
|
||||
use Rector\Core\NodeContainer\FunctionLikeParsedNodesFinder;
|
||||
use Rector\Core\NodeContainer\NodeFinder\ClassLikeParsedNodesFinder;
|
||||
use Rector\Core\NodeContainer\NodeFinder\FunctionLikeParsedNodesFinder;
|
||||
use Rector\NodeTypeResolver\FileSystem\CurrentFileInfoProvider;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
use Rector\NodeTypeResolver\PhpDoc\NodeAnalyzer\DocBlockManipulator;
|
||||
|
@ -83,15 +80,6 @@ abstract class AbstractRector extends NodeVisitorAbstract implements PhpRectorIn
|
|||
*/
|
||||
protected $staticTypeMapper;
|
||||
|
||||
/**
|
||||
* @var ClassLikeParsedNodesFinder
|
||||
*/
|
||||
protected $classLikeParsedNodesFinder;
|
||||
/**
|
||||
* @var FunctionLikeParsedNodesFinder
|
||||
*/
|
||||
protected $functionLikeParsedNodesFinder;
|
||||
|
||||
/**
|
||||
* Run once in the every end of one processed file
|
||||
*/
|
||||
|
@ -111,9 +99,7 @@ abstract class AbstractRector extends NodeVisitorAbstract implements PhpRectorIn
|
|||
CurrentFileInfoProvider $currentFileInfoProvider,
|
||||
PhpDocInfoPrinter $phpDocInfoPrinter,
|
||||
DocBlockManipulator $docBlockManipulator,
|
||||
StaticTypeMapper $staticTypeMapper,
|
||||
ClassLikeParsedNodesFinder $classLikeParsedNodesFinder,
|
||||
FunctionLikeParsedNodesFinder $functionLikeParsedNodesFinder
|
||||
StaticTypeMapper $staticTypeMapper
|
||||
): void {
|
||||
$this->symfonyStyle = $symfonyStyle;
|
||||
$this->phpVersionProvider = $phpVersionProvider;
|
||||
|
@ -124,8 +110,6 @@ abstract class AbstractRector extends NodeVisitorAbstract implements PhpRectorIn
|
|||
$this->phpDocInfoPrinter = $phpDocInfoPrinter;
|
||||
$this->docBlockManipulator = $docBlockManipulator;
|
||||
$this->staticTypeMapper = $staticTypeMapper;
|
||||
$this->classLikeParsedNodesFinder = $classLikeParsedNodesFinder;
|
||||
$this->functionLikeParsedNodesFinder = $functionLikeParsedNodesFinder;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -23,6 +23,7 @@ trait AbstractRectorTrait
|
|||
use ValueResolverTrait;
|
||||
use CallableNodeTraverserTrait;
|
||||
use ComplexRemovalTrait;
|
||||
use NodeCollectorTrait;
|
||||
|
||||
protected function isNonAnonymousClass(?Node $node): bool
|
||||
{
|
||||
|
|
|
@ -40,7 +40,8 @@ use PhpParser\Node\Stmt\Expression;
|
|||
use PhpParser\Node\Stmt\Property;
|
||||
use PhpParser\Node\Stmt\PropertyProperty;
|
||||
use Rector\Core\Exception\ShouldNotHappenException;
|
||||
use Rector\Core\NodeContainer\ParsedNodesByType;
|
||||
use Rector\Core\NodeContainer\NodeCollector\ParsedNodeCollector;
|
||||
use Rector\Core\NodeContainer\NodeFinder\FunctionLikeParsedNodesFinder;
|
||||
use Rector\Core\PhpParser\Node\Commander\NodeRemovingCommander;
|
||||
use Rector\Core\PhpParser\Node\Manipulator\PropertyManipulator;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
|
@ -50,25 +51,27 @@ use Rector\NodeTypeResolver\Node\AttributeKey;
|
|||
*/
|
||||
trait ComplexRemovalTrait
|
||||
{
|
||||
/**
|
||||
* @var ParsedNodeCollector
|
||||
*/
|
||||
protected $parsedNodeCollector;
|
||||
|
||||
/**
|
||||
* @var PropertyManipulator
|
||||
*/
|
||||
private $propertyManipulator;
|
||||
|
||||
/**
|
||||
* @var ParsedNodesByType
|
||||
*/
|
||||
private $parsedNodesByType;
|
||||
|
||||
/**
|
||||
* @required
|
||||
*/
|
||||
public function autowireComplextRemovalTrait(
|
||||
PropertyManipulator $propertyManipulator,
|
||||
ParsedNodesByType $parsedNodesByType
|
||||
ParsedNodeCollector $parsedNodeCollector,
|
||||
FunctionLikeParsedNodesFinder $functionLikeParsedNodesFinder
|
||||
): void {
|
||||
$this->parsedNodesByType = $parsedNodesByType;
|
||||
$this->parsedNodeCollector = $parsedNodeCollector;
|
||||
$this->propertyManipulator = $propertyManipulator;
|
||||
$this->functionLikeParsedNodesFinder = $functionLikeParsedNodesFinder;
|
||||
}
|
||||
|
||||
abstract protected function removeNode(Node $node): void;
|
||||
|
@ -77,7 +80,7 @@ trait ComplexRemovalTrait
|
|||
{
|
||||
$this->removeNode($classMethod);
|
||||
|
||||
$classMethodCalls = $this->parsedNodesByType->findClassMethodCalls($classMethod);
|
||||
$classMethodCalls = $this->functionLikeParsedNodesFinder->findClassMethodCalls($classMethod);
|
||||
foreach ($classMethodCalls as $classMethodCall) {
|
||||
if ($classMethodCall instanceof Array_) {
|
||||
continue;
|
||||
|
|
36
src/Rector/AbstractRector/NodeCollectorTrait.php
Normal file
36
src/Rector/AbstractRector/NodeCollectorTrait.php
Normal file
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Core\Rector\AbstractRector;
|
||||
|
||||
use Rector\Core\NodeContainer\NodeFinder\ClassLikeParsedNodesFinder;
|
||||
use Rector\Core\NodeContainer\NodeFinder\FunctionLikeParsedNodesFinder;
|
||||
|
||||
/**
|
||||
* This could be part of @see AbstractRector, but decopuling to trait
|
||||
* makes clear what code has 1 purpose.
|
||||
*/
|
||||
trait NodeCollectorTrait
|
||||
{
|
||||
/**
|
||||
* @var ClassLikeParsedNodesFinder
|
||||
*/
|
||||
protected $classLikeParsedNodesFinder;
|
||||
|
||||
/**
|
||||
* @var FunctionLikeParsedNodesFinder
|
||||
*/
|
||||
protected $functionLikeParsedNodesFinder;
|
||||
|
||||
/**
|
||||
* @required
|
||||
*/
|
||||
public function autowireNodeCollectorTrait(
|
||||
ClassLikeParsedNodesFinder $classLikeParsedNodesFinder,
|
||||
FunctionLikeParsedNodesFinder $functionLikeParsedNodesFinder
|
||||
): void {
|
||||
$this->classLikeParsedNodesFinder = $classLikeParsedNodesFinder;
|
||||
$this->functionLikeParsedNodesFinder = $functionLikeParsedNodesFinder;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user