consolidate AbstractRectorTrait (#5464)

Co-authored-by: kaizen-ci <info@kaizen-ci.org>
This commit is contained in:
Tomas Votruba 2021-02-08 22:00:45 +01:00 committed by GitHub
parent 1757e83cdc
commit 50f6adf47e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
55 changed files with 765 additions and 737 deletions

View File

@ -26,7 +26,7 @@ It's a tool that [we develop](https://getrector.org/) and share for free, so any
## Open-Source First
Rector **instantly upgrades and refactors the PHP code of your application**.
It supports all versions of PHP from 5.2 and major open-source projects:
It supports all versions of PHP from 5.3 and major open-source projects:
<br>

View File

@ -31,7 +31,3 @@ parameters:
# broken in PHPStan https://github.com/rectorphp/rector/runs/1305002460#step:5:56
- ../../utils/phpstan-extensions/*
- ../../packages/testing/src/PHPUnit/*.php
ignoreErrors:
# trait in trait call
- '#Call to an undefined method Rector\\PostRector\\Rector\\AbstractPostRector\:\:isObjectType\(\)#'

View File

@ -16,6 +16,7 @@ use PhpParser\Node\Expr\New_;
use PhpParser\Node\Expr\PropertyFetch;
use PhpParser\Node\Expr\StaticCall;
use PhpParser\Node\Expr\Variable;
use PhpParser\Node\Param;
use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\ClassConst;
use PhpParser\Node\Stmt\ClassLike;
@ -555,6 +556,69 @@ final class NodeRepository
return $class->getProperty($propertyName);
}
/**
* @return Class_[]
*/
public function getClasses(): array
{
return $this->parsedNodeCollector->getClasses();
}
/**
* @return New_[]
*/
public function findNewsByClass(string $className): array
{
return $this->parsedNodeCollector->findNewsByClass($className);
}
public function findClassConstant(string $className, string $constantName): ?ClassConst
{
return $this->parsedNodeCollector->findClassConstant($className, $constantName);
}
public function findTrait(string $name): ?Trait_
{
return $this->parsedNodeCollector->findTrait($name);
}
public function findByShortName(string $shortName): ?Class_
{
return $this->parsedNodeCollector->findByShortName($shortName);
}
/**
* @return Param[]
*/
public function getParams(): array
{
return $this->parsedNodeCollector->getParams();
}
/**
* @return New_[]
*/
public function getNews(): array
{
return $this->parsedNodeCollector->getNews();
}
/**
* @return StaticCall[]
*/
public function getStaticCalls(): array
{
return $this->parsedNodeCollector->getStaticCalls();
}
/**
* @return ClassConstFetch[]
*/
public function getClassConstFetches(): array
{
return $this->parsedNodeCollector->getClassConstFetches();
}
private function addMethod(ClassMethod $classMethod): void
{
$className = $classMethod->getAttribute(AttributeKey::CLASS_NAME);

View File

@ -25,6 +25,8 @@ use Rector\NodeTypeResolver\Node\AttributeKey;
/**
* All parsed nodes grouped type
* @see https://phpstan.org/blog/generics-in-php-using-phpdocs
*
* @internal To be used only in NodeRepository
*/
final class ParsedNodeCollector
{

View File

@ -23,7 +23,7 @@ use PHPStan\Type\Type;
use PHPStan\Type\TypeWithClassName;
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo;
use Rector\Core\PhpParser\Node\BetterNodeFinder;
use Rector\NodeCollector\NodeCollector\ParsedNodeCollector;
use Rector\NodeCollector\NodeCollector\NodeRepository;
use Rector\NodeNameResolver\NodeNameResolver;
use Rector\NodeTypeResolver\Contract\NodeTypeResolverInterface;
use Rector\NodeTypeResolver\Node\AttributeKey;
@ -37,11 +37,6 @@ use Symplify\SmartFileSystem\SmartFileSystem;
*/
final class PropertyFetchTypeResolver implements NodeTypeResolverInterface
{
/**
* @var ParsedNodeCollector
*/
private $parsedNodeCollector;
/**
* @var NodeTypeResolver
*/
@ -77,22 +72,27 @@ final class PropertyFetchTypeResolver implements NodeTypeResolverInterface
*/
private $parser;
/**
* @var NodeRepository
*/
private $nodeRepository;
public function __construct(
NodeNameResolver $nodeNameResolver,
ParsedNodeCollector $parsedNodeCollector,
StaticTypeMapper $staticTypeMapper,
TraitNodeScopeCollector $traitNodeScopeCollector,
SmartFileSystem $smartFileSystem,
BetterNodeFinder $betterNodeFinder,
Parser $parser
Parser $parser,
NodeRepository $nodeRepository
) {
$this->parsedNodeCollector = $parsedNodeCollector;
$this->nodeNameResolver = $nodeNameResolver;
$this->staticTypeMapper = $staticTypeMapper;
$this->traitNodeScopeCollector = $traitNodeScopeCollector;
$this->betterNodeFinder = $betterNodeFinder;
$this->smartFileSystem = $smartFileSystem;
$this->parser = $parser;
$this->nodeRepository = $nodeRepository;
}
/**
@ -157,7 +157,7 @@ final class PropertyFetchTypeResolver implements NodeTypeResolverInterface
return new MixedType();
}
$class = $this->parsedNodeCollector->findClass($varObjectType->getClassName());
$class = $this->nodeRepository->findClass($varObjectType->getClassName());
if ($class !== null) {
return new MixedType();
}

View File

@ -1,14 +0,0 @@
<?php
declare(strict_types=1);
namespace Rector\PostRector\Rector;
use PhpParser\NodeVisitorAbstract;
use Rector\Core\Rector\AbstractRector\NameResolverTrait;
use Rector\PostRector\Contract\Rector\PostRectorInterface;
abstract class AbstractPostRector extends NodeVisitorAbstract implements PostRectorInterface
{
use NameResolverTrait;
}

View File

@ -5,10 +5,12 @@ declare(strict_types=1);
namespace Rector\PostRector\Rector;
use PhpParser\Node;
use PhpParser\NodeVisitorAbstract;
use Rector\PostRector\Contract\Rector\PostRectorInterface;
use Rector\PSR4\Collector\RenamedClassesCollector;
use Rector\Renaming\NodeManipulator\ClassRenamer;
final class ClassRenamingPostRector extends AbstractPostRector
final class ClassRenamingPostRector extends NodeVisitorAbstract implements PostRectorInterface
{
/**
* @var RenamedClassesCollector

View File

@ -6,14 +6,17 @@ namespace Rector\PostRector\Rector;
use PhpParser\Node;
use PhpParser\Node\Name;
use PhpParser\NodeVisitorAbstract;
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory;
use Rector\CodingStyle\ClassNameImport\ClassNameImportSkipper;
use Rector\CodingStyle\Node\NameImporter;
use Rector\Core\Configuration\Option;
use Rector\NodeNameResolver\NodeNameResolver;
use Rector\NodeTypeResolver\PhpDoc\NodeAnalyzer\DocBlockNameImporter;
use Rector\PostRector\Contract\Rector\PostRectorInterface;
use Symplify\PackageBuilder\Parameter\ParameterProvider;
final class NameImportingPostRector extends AbstractPostRector
final class NameImportingPostRector extends NodeVisitorAbstract implements PostRectorInterface
{
/**
* @var ParameterProvider
@ -40,18 +43,25 @@ final class NameImportingPostRector extends AbstractPostRector
*/
private $phpDocInfoFactory;
/**
* @var NodeNameResolver
*/
private $nodeNameResolver;
public function __construct(
ParameterProvider $parameterProvider,
NameImporter $nameImporter,
DocBlockNameImporter $docBlockNameImporter,
ClassNameImportSkipper $classNameImportSkipper,
PhpDocInfoFactory $phpDocInfoFactory
PhpDocInfoFactory $phpDocInfoFactory,
NodeNameResolver $nodeNameResolver
) {
$this->parameterProvider = $parameterProvider;
$this->nameImporter = $nameImporter;
$this->docBlockNameImporter = $docBlockNameImporter;
$this->classNameImportSkipper = $classNameImportSkipper;
$this->phpDocInfoFactory = $phpDocInfoFactory;
$this->nodeNameResolver = $nodeNameResolver;
}
public function enterNode(Node $node): ?Node
@ -87,7 +97,7 @@ final class NameImportingPostRector extends AbstractPostRector
return $name;
}
$importName = $this->getName($name);
$importName = $this->nodeNameResolver->getName($name);
if (! is_callable($importName)) {
return $this->nameImporter->importName($name);

View File

@ -5,7 +5,9 @@ declare(strict_types=1);
namespace Rector\PostRector\Rector;
use PhpParser\Node;
use PhpParser\NodeVisitorAbstract;
use Rector\PostRector\Collector\NodesToAddCollector;
use Rector\PostRector\Contract\Rector\PostRectorInterface;
/**
* This class collects all to-be-added expresssions (= 1 line in code)
@ -18,7 +20,7 @@ use Rector\PostRector\Collector\NodesToAddCollector;
* - $this->someCall();
* - $value = this->someNewCall(); // added expression
*/
final class NodeAddingPostRector extends AbstractPostRector
final class NodeAddingPostRector extends NodeVisitorAbstract implements PostRectorInterface
{
/**
* @var NodesToAddCollector

View File

@ -8,11 +8,14 @@ use PhpParser\Node;
use PhpParser\Node\Expr\BinaryOp;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\NodeTraverser;
use PhpParser\NodeVisitorAbstract;
use Rector\Core\PhpParser\Node\NodeFactory;
use Rector\NodeNameResolver\NodeNameResolver;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\PostRector\Collector\NodesToRemoveCollector;
use Rector\PostRector\Contract\Rector\PostRectorInterface;
final class NodeRemovingPostRector extends AbstractPostRector
final class NodeRemovingPostRector extends NodeVisitorAbstract implements PostRectorInterface
{
/**
* @var NodesToRemoveCollector
@ -24,10 +27,19 @@ final class NodeRemovingPostRector extends AbstractPostRector
*/
private $nodeFactory;
public function __construct(NodeFactory $nodeFactory, NodesToRemoveCollector $nodesToRemoveCollector)
{
/**
* @var NodeNameResolver
*/
private $nodeNameResolver;
public function __construct(
NodeFactory $nodeFactory,
NodeNameResolver $nodeNameResolver,
NodesToRemoveCollector $nodesToRemoveCollector
) {
$this->nodesToRemoveCollector = $nodesToRemoveCollector;
$this->nodeFactory = $nodeFactory;
$this->nodeNameResolver = $nodeNameResolver;
}
public function getPriority(): int
@ -58,7 +70,7 @@ final class NodeRemovingPostRector extends AbstractPostRector
$this->nodesToRemoveCollector->unset($key);
$methodName = $this->getName($node->name);
$methodName = $this->nodeNameResolver->getName($node->name);
/** @var MethodCall $nestedMethodCall */
$nestedMethodCall = $node->var;
@ -109,7 +121,7 @@ final class NodeRemovingPostRector extends AbstractPostRector
return false;
}
$methodName = $this->getName($mainMethodCall->name);
$methodName = $this->nodeNameResolver->getName($mainMethodCall->name);
return $methodName !== null;
}

View File

@ -5,9 +5,11 @@ declare(strict_types=1);
namespace Rector\PostRector\Rector;
use PhpParser\Node;
use PhpParser\NodeVisitorAbstract;
use Rector\PostRector\Collector\NodesToReplaceCollector;
use Rector\PostRector\Contract\Rector\PostRectorInterface;
final class NodeToReplacePostRector extends AbstractPostRector
final class NodeToReplacePostRector extends NodeVisitorAbstract implements PostRectorInterface
{
/**
* @var NodesToReplaceCollector

View File

@ -6,15 +6,17 @@ namespace Rector\PostRector\Rector;
use PhpParser\Node;
use PhpParser\Node\Stmt\Class_;
use PhpParser\NodeVisitorAbstract;
use Rector\Core\NodeManipulator\ClassDependencyManipulator;
use Rector\Core\NodeManipulator\ClassInsertManipulator;
use Rector\PostRector\Collector\PropertyToAddCollector;
use Rector\PostRector\Contract\Rector\PostRectorInterface;
use Rector\PostRector\NodeAnalyzer\NetteInjectDetector;
/**
* Adds new private properties to class + to constructor
*/
final class PropertyAddingPostRector extends AbstractPostRector
final class PropertyAddingPostRector extends NodeVisitorAbstract implements PostRectorInterface
{
/**
* @var ClassDependencyManipulator

View File

@ -8,6 +8,7 @@ use Nette\Utils\Strings;
use PhpParser\Node;
use PhpParser\Node\Stmt;
use PhpParser\Node\Stmt\Namespace_;
use PhpParser\NodeVisitorAbstract;
use Rector\CodingStyle\Application\UseImportsAdder;
use Rector\CodingStyle\Application\UseImportsRemover;
use Rector\Core\PhpParser\Node\BetterNodeFinder;
@ -15,10 +16,11 @@ use Rector\Core\PhpParser\Node\CustomNode\FileWithoutNamespace;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\NodeTypeResolver\PHPStan\Type\TypeFactory;
use Rector\PostRector\Collector\UseNodesToAddCollector;
use Rector\PostRector\Contract\Rector\PostRectorInterface;
use Rector\StaticTypeMapper\ValueObject\Type\FullyQualifiedObjectType;
use Symplify\SmartFileSystem\SmartFileInfo;
final class UseAddingPostRector extends AbstractPostRector
final class UseAddingPostRector extends NodeVisitorAbstract implements PostRectorInterface
{
/**
* @var UseImportsAdder

View File

@ -9,17 +9,12 @@ use PhpParser\Node\Stmt\ClassLike;
use PhpParser\Node\Stmt\Interface_;
use Rector\Core\NodeManipulator\ClassManipulator;
use Rector\FamilyTree\Reflection\FamilyRelationsAnalyzer;
use Rector\NodeCollector\NodeCollector\ParsedNodeCollector;
use Rector\NodeCollector\NodeCollector\NodeRepository;
use Rector\NodeNameResolver\NodeNameResolver;
use Rector\NodeTypeResolver\Node\AttributeKey;
abstract class AbstractNodeVendorLockResolver
{
/**
* @var ParsedNodeCollector
*/
protected $parsedNodeCollector;
/**
* @var ClassManipulator
*/
@ -30,6 +25,11 @@ abstract class AbstractNodeVendorLockResolver
*/
protected $nodeNameResolver;
/**
* @var NodeRepository
*/
protected $nodeRepository;
/**
* @var FamilyRelationsAnalyzer
*/
@ -39,12 +39,12 @@ abstract class AbstractNodeVendorLockResolver
* @required
*/
public function autowireAbstractNodeVendorLockResolver(
ParsedNodeCollector $parsedNodeCollector,
NodeRepository $nodeRepository,
ClassManipulator $classManipulator,
NodeNameResolver $nodeNameResolver,
FamilyRelationsAnalyzer $familyRelationsAnalyzer
): void {
$this->parsedNodeCollector = $parsedNodeCollector;
$this->nodeRepository = $nodeRepository;
$this->classManipulator = $classManipulator;
$this->nodeNameResolver = $nodeNameResolver;
$this->familyRelationsAnalyzer = $familyRelationsAnalyzer;

View File

@ -44,7 +44,7 @@ final class ClassMethodParamVendorLockResolver extends AbstractNodeVendorLockRes
private function isParentClassVendorLocking(int $paramPosition, string $parentClassName, string $methodName): ?bool
{
$parentClass = $this->parsedNodeCollector->findClass($parentClassName);
$parentClass = $this->nodeRepository->findClass($parentClassName);
if ($parentClass !== null) {
$parentClassMethod = $parentClass->getMethod($methodName);
// parent class method in local scope → it's ok

View File

@ -42,7 +42,7 @@ final class ClassMethodReturnVendorLockResolver extends AbstractNodeVendorLockRe
private function isVendorLockedByParentClass(string $parentClassName, string $methodName): bool
{
$parentClass = $this->parsedNodeCollector->findClass($parentClassName);
$parentClass = $this->nodeRepository->findClass($parentClassName);
if ($parentClass !== null) {
$parentClassMethod = $parentClass->getMethod($methodName);
// validate type is conflicting

View File

@ -240,7 +240,6 @@ parameters:
- rules/type-declaration/src/Rector/FunctionLike/ReturnTypeDeclarationRector.php # 82
# trait in trait call
- '#Call to an undefined method Rector\\PostRector\\Rector\\AbstractPostRector\:\:isObjectType\(\)#'
- '#Parameter \#1 \$expr of class PhpParser\\Node\\Stmt\\Expression constructor expects PhpParser\\Node\\Expr, PhpParser\\Node\\Expr\|PhpParser\\Node\\Stmt given#'
-

View File

@ -10,7 +10,7 @@ use PHPStan\Type\ObjectType;
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory;
use Rector\BetterPhpDocParser\ValueObject\PhpDocNode\JMS\SerializerTypeTagValueNode;
use Rector\Core\ValueObject\MethodName;
use Rector\NodeCollector\NodeCollector\ParsedNodeCollector;
use Rector\NodeCollector\NodeCollector\NodeRepository;
use Rector\NodeNameResolver\NodeNameResolver;
use Rector\NodeTypeResolver\NodeTypeResolver;
@ -31,26 +31,26 @@ final class ClassAnalyzer
*/
private $nodeTypeResolver;
/**
* @var ParsedNodeCollector
*/
private $parsedNodeCollector;
/**
* @var PhpDocInfoFactory
*/
private $phpDocInfoFactory;
/**
* @var NodeRepository
*/
private $nodeRepository;
public function __construct(
NodeNameResolver $nodeNameResolver,
NodeTypeResolver $nodeTypeResolver,
ParsedNodeCollector $parsedNodeCollector,
PhpDocInfoFactory $phpDocInfoFactory
PhpDocInfoFactory $phpDocInfoFactory,
NodeRepository $nodeRepository
) {
$this->nodeNameResolver = $nodeNameResolver;
$this->parsedNodeCollector = $parsedNodeCollector;
$this->nodeTypeResolver = $nodeTypeResolver;
$this->phpDocInfoFactory = $phpDocInfoFactory;
$this->nodeRepository = $nodeRepository;
}
public function isValueObjectClass(Class_ $class): bool
@ -81,7 +81,7 @@ final class ClassAnalyzer
// awesome!
// is it services or value object?
$paramTypeClass = $this->parsedNodeCollector->findClass($paramType->getClassName());
$paramTypeClass = $this->nodeRepository->findClass($paramType->getClassName());
if (! $paramTypeClass instanceof Class_) {
// not sure :/
continue;

View File

@ -26,7 +26,6 @@ use Rector\Core\Rector\AbstractRector;
use Rector\Core\ValueObject\MethodName;
use Rector\Core\ValueObject\PhpVersionFeature;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\NodeTypeResolver\NodeTypeResolver;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
@ -42,19 +41,13 @@ final class DateTimeToDateTimeInterfaceRector extends AbstractRector
'add', 'modify', MethodName::SET_STATE, 'setDate', 'setISODate', 'setTime', 'setTimestamp', 'setTimezone', 'sub',
];
/**
* @var NodeTypeResolver
*/
private $nodeTypeResolver;
/**
* @var PhpDocTypeChanger
*/
private $phpDocTypeChanger;
public function __construct(NodeTypeResolver $nodeTypeResolver, PhpDocTypeChanger $phpDocTypeChanger)
public function __construct(PhpDocTypeChanger $phpDocTypeChanger)
{
$this->nodeTypeResolver = $nodeTypeResolver;
$this->phpDocTypeChanger = $phpDocTypeChanger;
}

View File

@ -123,7 +123,7 @@ CODE_SAMPLE
private function shouldSkipClass(Class_ $class): bool
{
if (! $this->isNonAnonymousClass($class)) {
if ($this->classNodeAnalyzer->isAnonymousClass($class)) {
return true;
}

View File

@ -24,6 +24,8 @@ use PHPStan\Type\BooleanType;
use PHPStan\Type\FloatType;
use PHPStan\Type\IntegerType;
use Rector\Core\Rector\AbstractRector;
use Rector\NodeTypeResolver\TypeAnalyzer\ArrayTypeAnalyzer;
use Rector\NodeTypeResolver\TypeAnalyzer\StringTypeAnalyzer;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
@ -35,6 +37,22 @@ use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
*/
final class ExplicitBoolCompareRector extends AbstractRector
{
/**
* @var StringTypeAnalyzer
*/
private $stringTypeAnalyzer;
/**
* @var ArrayTypeAnalyzer
*/
private $arrayTypeAnalyzer;
public function __construct(StringTypeAnalyzer $stringTypeAnalyzer, ArrayTypeAnalyzer $arrayTypeAnalyzer)
{
$this->stringTypeAnalyzer = $stringTypeAnalyzer;
$this->arrayTypeAnalyzer = $arrayTypeAnalyzer;
}
public function getRuleDefinition(): RuleDefinition
{
return new RuleDefinition('Make if conditions more explicit', [
@ -118,11 +136,11 @@ CODE_SAMPLE
return $this->resolveCount($isNegated, $expr);
}
if ($this->isArrayType($expr)) {
if ($this->arrayTypeAnalyzer->isArrayType($expr)) {
return $this->resolveArray($isNegated, $expr);
}
if ($this->isStringOrUnionStringOnlyType($expr)) {
if ($this->stringTypeAnalyzer->isStringOrUnionStringOnlyType($expr)) {
return $this->resolveString($isNegated, $expr);
}
@ -134,7 +152,7 @@ CODE_SAMPLE
return $this->resolveFloat($isNegated, $expr);
}
if ($this->isNullableObjectType($expr)) {
if ($this->nodeTypeResolver->isNullableObjectType($expr)) {
return $this->resolveNullable($isNegated, $expr);
}

View File

@ -9,6 +9,7 @@ use PhpParser\Node\Arg;
use PhpParser\Node\Expr\FuncCall;
use PhpParser\Node\Scalar\String_;
use Rector\Core\Rector\AbstractRector;
use Rector\NodeTypeResolver\TypeAnalyzer\StringTypeAnalyzer;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
@ -19,6 +20,16 @@ use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
*/
final class ConsistentImplodeRector extends AbstractRector
{
/**
* @var StringTypeAnalyzer
*/
private $stringTypeAnalyzer;
public function __construct(StringTypeAnalyzer $stringTypeAnalyzer)
{
$this->stringTypeAnalyzer = $stringTypeAnalyzer;
}
public function getRuleDefinition(): RuleDefinition
{
return new RuleDefinition(
@ -85,7 +96,9 @@ CODE_SAMPLE
return null;
}
if (count($node->args) === 2 && $this->isStringOrUnionStringOnlyType($node->args[1]->value)) {
if (count($node->args) === 2 && $this->stringTypeAnalyzer->isStringOrUnionStringOnlyType(
$node->args[1]->value
)) {
$node->args = array_reverse($node->args);
}

View File

@ -8,6 +8,7 @@ use PhpParser\Node;
use PhpParser\Node\Stmt\Expression;
use PhpParser\Node\Stmt\Nop;
use Rector\Core\Rector\AbstractRector;
use Rector\DeadCode\NodeManipulator\LivingCodeManipulator;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
@ -17,6 +18,16 @@ use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
*/
final class RemoveDeadStmtRector extends AbstractRector
{
/**
* @var LivingCodeManipulator
*/
private $livingCodeManipulator;
public function __construct(LivingCodeManipulator $livingCodeManipulator)
{
$this->livingCodeManipulator = $livingCodeManipulator;
}
public function getRuleDefinition(): RuleDefinition
{
return new RuleDefinition('Removes dead code statements', [

View File

@ -17,6 +17,7 @@ use Rector\Core\PhpParser\NodeFinder\PropertyFetchFinder;
use Rector\Core\Rector\AbstractRector;
use Rector\Core\ValueObject\MethodName;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\Removing\NodeManipulator\ComplexNodeRemover;
use Rector\VendorLocker\VendorLockResolver;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
@ -43,14 +44,21 @@ final class RemoveSetterOnlyPropertyAndMethodCallRector extends AbstractRector
*/
private $propertyFetchFinder;
/**
* @var ComplexNodeRemover
*/
private $complexNodeRemover;
public function __construct(
PropertyManipulator $propertyManipulator,
VendorLockResolver $vendorLockResolver,
PropertyFetchFinder $propertyFetchFinder
PropertyFetchFinder $propertyFetchFinder,
ComplexNodeRemover $complexNodeRemover
) {
$this->propertyManipulator = $propertyManipulator;
$this->vendorLockResolver = $vendorLockResolver;
$this->propertyFetchFinder = $propertyFetchFinder;
$this->complexNodeRemover = $complexNodeRemover;
}
public function getRuleDefinition(): RuleDefinition
@ -120,7 +128,7 @@ CODE_SAMPLE
$vendorLockedClassMethodNames = $this->getVendorLockedClassMethodNames($classMethodsToCheck);
$this->removePropertyAndUsages($node, $vendorLockedClassMethodNames);
$this->complexNodeRemover->removePropertyAndUsages($node, $vendorLockedClassMethodNames);
/** @var ClassMethod $method */
foreach ($classMethodsToCheck as $method) {
@ -133,7 +141,7 @@ CODE_SAMPLE
continue;
}
$this->removeClassMethodAndUsages($method);
$this->complexNodeRemover->removeClassMethodAndUsages($method);
}
return $node;

View File

@ -12,6 +12,7 @@ use PhpParser\Node\Stmt\Trait_;
use Rector\Core\NodeManipulator\PropertyManipulator;
use Rector\Core\Rector\AbstractRector;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\Removing\NodeManipulator\ComplexNodeRemover;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
@ -25,9 +26,15 @@ final class RemoveUnusedPrivatePropertyRector extends AbstractRector
*/
private $propertyManipulator;
public function __construct(PropertyManipulator $propertyManipulator)
/**
* @var ComplexNodeRemover
*/
private $complexNodeRemover;
public function __construct(PropertyManipulator $propertyManipulator, ComplexNodeRemover $complexNodeRemover)
{
$this->propertyManipulator = $propertyManipulator;
$this->complexNodeRemover = $complexNodeRemover;
}
public function getRuleDefinition(): RuleDefinition
@ -71,7 +78,7 @@ CODE_SAMPLE
return null;
}
$this->removePropertyAndUsages($node);
$this->complexNodeRemover->removePropertyAndUsages($node);
return $node;
}

View File

@ -10,7 +10,7 @@ use PhpParser\Node\NullableType;
use PhpParser\Node\Param;
use PhpParser\Node\Stmt\Class_;
use Rector\Core\Exception\NotImplementedYetException;
use Rector\NodeCollector\NodeCollector\ParsedNodeCollector;
use Rector\NodeCollector\NodeCollector\NodeRepository;
use Rector\NodeNameResolver\NodeNameResolver;
use Rector\Testing\PHPUnit\StaticPHPUnitEnvironment;
@ -27,14 +27,14 @@ final class UnusedClassResolver
private $nodeNameResolver;
/**
* @var ParsedNodeCollector
* @var NodeRepository
*/
private $parsedNodeCollector;
private $nodeRepository;
public function __construct(NodeNameResolver $nodeNameResolver, ParsedNodeCollector $parsedNodeCollector)
public function __construct(NodeNameResolver $nodeNameResolver, NodeRepository $nodeRepository)
{
$this->nodeNameResolver = $nodeNameResolver;
$this->parsedNodeCollector = $parsedNodeCollector;
$this->nodeRepository = $nodeRepository;
}
public function isClassWithoutInterfaceAndNotController(Class_ $class): bool
@ -89,7 +89,7 @@ final class UnusedClassResolver
{
$classNames = [];
foreach ($this->parsedNodeCollector->getParams() as $param) {
foreach ($this->nodeRepository->getParams() as $param) {
if ($param->type === null) {
continue;
}
@ -121,7 +121,7 @@ final class UnusedClassResolver
{
$classNames = [];
foreach ($this->parsedNodeCollector->getNews() as $newNode) {
foreach ($this->nodeRepository->getNews() as $newNode) {
$newClassName = $this->nodeNameResolver->getName($newNode->class);
if (! is_string($newClassName)) {
continue;
@ -140,7 +140,7 @@ final class UnusedClassResolver
{
$classNames = [];
foreach ($this->parsedNodeCollector->getStaticCalls() as $staticCallNode) {
foreach ($this->nodeRepository->getStaticCalls() as $staticCallNode) {
$staticClassName = $this->nodeNameResolver->getName($staticCallNode->class);
if (! is_string($staticClassName)) {
continue;
@ -156,7 +156,7 @@ final class UnusedClassResolver
*/
private function getClassConstantFetchNames(): array
{
$classConstFetches = $this->parsedNodeCollector->getClassConstFetches();
$classConstFetches = $this->nodeRepository->getClassConstFetches();
$classNames = [];
foreach ($classConstFetches as $classConstFetch) {

View File

@ -16,6 +16,7 @@ use PhpParser\Node\Stmt\ClassLike;
use Rector\Core\Exception\ShouldNotHappenException;
use Rector\Core\Rector\AbstractRector;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\NodeTypeResolver\TypeAnalyzer\ArrayTypeAnalyzer;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
@ -26,7 +27,17 @@ use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
final class ChangeSetParametersArrayToArrayCollectionRector extends AbstractRector
{
/**
* @return string[]
* @var ArrayTypeAnalyzer
*/
private $arrayTypeAnalyzer;
public function __construct(ArrayTypeAnalyzer $arrayTypeAnalyzer)
{
$this->arrayTypeAnalyzer = $arrayTypeAnalyzer;
}
/**
* @return array<class-string<Node>>
*/
public function getNodeTypes(): array
{
@ -47,7 +58,7 @@ final class ChangeSetParametersArrayToArrayCollectionRector extends AbstractRect
return null;
}
$firstArgument = $methodArguments[0];
if (! $this->isArrayType($firstArgument->value)) {
if (! $this->arrayTypeAnalyzer->isArrayType($firstArgument->value)) {
return null;
}

View File

@ -14,7 +14,7 @@ use Rector\BetterPhpDocParser\ValueObject\PhpDocNode\Doctrine\Class_\EmbeddableT
use Rector\BetterPhpDocParser\ValueObject\PhpDocNode\Doctrine\Class_\EntityTagValueNode;
use Rector\BetterPhpDocParser\ValueObject\PhpDocNode\Doctrine\Property_\IdTagValueNode;
use Rector\Core\Exception\ShouldNotHappenException;
use Rector\NodeCollector\NodeCollector\ParsedNodeCollector;
use Rector\NodeCollector\NodeCollector\NodeRepository;
use Rector\NodeTypeResolver\ClassExistenceStaticHelper;
use Rector\NodeTypeResolver\Node\AttributeKey;
use ReflectionClass;
@ -27,20 +27,20 @@ final class DoctrineDocBlockResolver
*/
private const ORM_ENTITY_EMBEDDABLE_SHORT_ANNOTATION_REGEX = '#@ORM\\\\(Entity|Embeddable)#';
/**
* @var ParsedNodeCollector
*/
private $parsedNodeCollector;
/**
* @var PhpDocInfoFactory
*/
private $phpDocInfoFactory;
public function __construct(ParsedNodeCollector $parsedNodeCollector, PhpDocInfoFactory $phpDocInfoFactory)
/**
* @var NodeRepository
*/
private $nodeRepository;
public function __construct(NodeRepository $nodeRepository, PhpDocInfoFactory $phpDocInfoFactory)
{
$this->parsedNodeCollector = $parsedNodeCollector;
$this->phpDocInfoFactory = $phpDocInfoFactory;
$this->nodeRepository = $nodeRepository;
}
/**
@ -109,7 +109,7 @@ final class DoctrineDocBlockResolver
return false;
}
$classNode = $this->parsedNodeCollector->findClass($class);
$classNode = $this->nodeRepository->findClass($class);
if ($classNode !== null) {
return $this->isDoctrineEntityClass($classNode);
}

View File

@ -11,7 +11,7 @@ use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory;
use Rector\BetterPhpDocParser\ValueObject\PhpDocNode\Doctrine\Property_\ColumnTagValueNode;
use Rector\BetterPhpDocParser\ValueObject\PhpDocNode\Doctrine\Property_\IdTagValueNode;
use Rector\Doctrine\PhpDocParser\DoctrineDocBlockResolver;
use Rector\NodeCollector\NodeCollector\ParsedNodeCollector;
use Rector\NodeCollector\NodeCollector\NodeRepository;
use Rector\NodeNameResolver\NodeNameResolver;
final class EntityWithMissingUuidProvider
@ -27,11 +27,6 @@ final class EntityWithMissingUuidProvider
*/
private $entitiesWithMissingUuidProperty = [];
/**
* @var ParsedNodeCollector
*/
private $parsedNodeCollector;
/**
* @var DoctrineDocBlockResolver
*/
@ -47,16 +42,21 @@ final class EntityWithMissingUuidProvider
*/
private $phpDocInfoFactory;
/**
* @var NodeRepository
*/
private $nodeRepository;
public function __construct(
DoctrineDocBlockResolver $doctrineDocBlockResolver,
NodeNameResolver $nodeNameResolver,
ParsedNodeCollector $parsedNodeCollector,
PhpDocInfoFactory $phpDocInfoFactory
PhpDocInfoFactory $phpDocInfoFactory,
NodeRepository $nodeRepository
) {
$this->parsedNodeCollector = $parsedNodeCollector;
$this->doctrineDocBlockResolver = $doctrineDocBlockResolver;
$this->nodeNameResolver = $nodeNameResolver;
$this->phpDocInfoFactory = $phpDocInfoFactory;
$this->nodeRepository = $nodeRepository;
}
/**
@ -69,7 +69,7 @@ final class EntityWithMissingUuidProvider
}
$entitiesWithMissingUuidProperty = [];
foreach ($this->parsedNodeCollector->getClasses() as $class) {
foreach ($this->nodeRepository->getClasses() as $class) {
if (! $this->doctrineDocBlockResolver->isDoctrineEntityClassWithIdProperty($class)) {
continue;
}

View File

@ -15,7 +15,6 @@ use PhpParser\Node\Scalar\LNumber;
use PhpParser\Node\Stmt\ClassConst;
use Rector\Core\Rector\AbstractRector;
use Rector\Laravel\ValueObject\TypeToTimeMethodAndPosition;
use Rector\NodeCollector\NodeCollector\ParsedNodeCollector;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
@ -52,10 +51,8 @@ final class MinutesToSecondsInCacheRector extends AbstractRector
*/
private $typeToTimeMethodsAndPositions = [];
public function __construct(ParsedNodeCollector $parsedNodeCollector)
public function __construct()
{
$this->parsedNodeCollector = $parsedNodeCollector;
$this->typeToTimeMethodsAndPositions = [
new TypeToTimeMethodAndPosition('Illuminate\Support\Facades\Cache', self::PUT, 2),
new TypeToTimeMethodAndPosition('Illuminate\Contracts\Cache\Repository', self::PUT, 2),

View File

@ -95,7 +95,7 @@ CODE_SAMPLE
*/
public function refactor(Node $node): ?Node
{
if (! $this->isPropertyBoolean($node)) {
if (! $this->nodeTypeResolver->isPropertyBoolean($node)) {
return null;
}

View File

@ -13,7 +13,7 @@ use PhpParser\Node\Scalar\String_;
use PhpParser\Node\Stmt\Class_;
use Rector\Core\PhpParser\Node\Value\ValueResolver;
use Rector\NetteToSymfony\ValueObject\RouteInfo;
use Rector\NodeCollector\NodeCollector\ParsedNodeCollector;
use Rector\NodeCollector\NodeCollector\NodeRepository;
use Rector\NodeNameResolver\NodeNameResolver;
final class RouteInfoFactory
@ -29,18 +29,18 @@ final class RouteInfoFactory
private $valueResolver;
/**
* @var ParsedNodeCollector
* @var NodeRepository
*/
private $parsedNodeCollector;
private $nodeRepository;
public function __construct(
NodeNameResolver $nodeNameResolver,
ParsedNodeCollector $parsedNodeCollector,
NodeRepository $nodeRepository,
ValueResolver $valueResolver
) {
$this->nodeNameResolver = $nodeNameResolver;
$this->valueResolver = $valueResolver;
$this->parsedNodeCollector = $parsedNodeCollector;
$this->nodeRepository = $nodeRepository;
}
public function createFromNode(Node $node): ?RouteInfo
@ -163,17 +163,17 @@ final class RouteInfoFactory
// detect class by controller name?
// foreach all instance and try to match a name $controller . 'Presenter/Controller'
$classNode = $this->parsedNodeCollector->findByShortName($controller . 'Presenter');
if (! $classNode instanceof Class_) {
$classNode = $this->parsedNodeCollector->findByShortName($controller . 'Controller');
$class = $this->nodeRepository->findByShortName($controller . 'Presenter');
if (! $class instanceof Class_) {
$class = $this->nodeRepository->findByShortName($controller . 'Controller');
}
// unable to find here
if (! $classNode instanceof Class_) {
if (! $class instanceof Class_) {
return null;
}
$controllerClass = $this->nodeNameResolver->getName($classNode);
$controllerClass = $this->nodeNameResolver->getName($class);
if ($controllerClass === null) {
return null;
}

View File

@ -22,6 +22,7 @@ use PHPStan\Type\NullType;
use Rector\Core\Rector\AbstractRector;
use Rector\Core\ValueObject\PhpVersionFeature;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\NodeTypeResolver\TypeAnalyzer\CountableTypeAnalyzer;
use Rector\Php71\NodeAnalyzer\CountableAnalyzer;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
@ -38,13 +39,19 @@ final class CountOnNullRector extends AbstractRector
*/
private const ALREADY_CHANGED_ON_COUNT = 'already_changed_on_count';
/**
* @var CountableTypeAnalyzer
*/
private $countableTypeAnalyzer;
/**
* @var CountableAnalyzer
*/
private $countableAnalyzer;
public function __construct(CountableAnalyzer $countableAnalyzer)
public function __construct(CountableTypeAnalyzer $countableTypeAnalyzer, CountableAnalyzer $countableAnalyzer)
{
$this->countableTypeAnalyzer = $countableTypeAnalyzer;
$this->countableAnalyzer = $countableAnalyzer;
}
@ -84,7 +91,7 @@ CODE_SAMPLE
}
$countedNode = $node->args[0]->value;
if ($this->isCountableType($countedNode)) {
if ($this->countableTypeAnalyzer->isCountableType($countedNode)) {
return null;
}
@ -98,7 +105,7 @@ CODE_SAMPLE
return $this->castToArray($countedNode, $node);
}
if ($this->isNullableArrayType($countedNode)) {
if ($this->nodeTypeResolver->isNullableArrayType($countedNode)) {
return $this->castToArray($countedNode, $node);
}

View File

@ -9,6 +9,7 @@ use PhpParser\Node\Expr\ConstFetch;
use PhpParser\Node\Expr\FuncCall;
use PhpParser\Node\Scalar\String_;
use Rector\Core\Rector\AbstractRector;
use Rector\NodeTypeResolver\TypeAnalyzer\StringTypeAnalyzer;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
@ -18,6 +19,16 @@ use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
*/
final class StringifyDefineRector extends AbstractRector
{
/**
* @var StringTypeAnalyzer
*/
private $stringTypeAnalyzer;
public function __construct(StringTypeAnalyzer $stringTypeAnalyzer)
{
$this->stringTypeAnalyzer = $stringTypeAnalyzer;
}
public function getRuleDefinition(): RuleDefinition
{
return new RuleDefinition('Make first argument of define() string', [
@ -64,7 +75,7 @@ CODE_SAMPLE
return null;
}
if ($this->isStringOrUnionStringOnlyType($node->args[0]->value)) {
if ($this->stringTypeAnalyzer->isStringOrUnionStringOnlyType($node->args[0]->value)) {
return null;
}

View File

@ -18,6 +18,7 @@ use PHPStan\Type\IntegerType;
use PHPStan\Type\Type;
use Rector\Core\Rector\AbstractRector;
use Rector\Core\ValueObject\PhpVersionFeature;
use Rector\NodeTypeResolver\TypeAnalyzer\ArrayTypeAnalyzer;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
@ -28,6 +29,16 @@ use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
*/
final class ArraySpreadInsteadOfArrayMergeRector extends AbstractRector
{
/**
* @var ArrayTypeAnalyzer
*/
private $arrayTypeAnalyzer;
public function __construct(ArrayTypeAnalyzer $arrayTypeAnalyzer)
{
$this->arrayTypeAnalyzer = $arrayTypeAnalyzer;
}
public function getRuleDefinition(): RuleDefinition
{
return new RuleDefinition(
@ -116,7 +127,7 @@ CODE_SAMPLE
private function shouldSkipArrayForInvalidTypeOrKeys(Expr $expr): bool
{
// we have no idea what it is → cannot change it
if (! $this->isArrayType($expr)) {
if (! $this->arrayTypeAnalyzer->isArrayType($expr)) {
return true;
}

View File

@ -6,24 +6,24 @@ namespace Rector\Privatization\NodeFinder;
use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\ClassConst;
use Rector\NodeCollector\NodeCollector\ParsedNodeCollector;
use Rector\NodeCollector\NodeCollector\NodeRepository;
use Rector\NodeTypeResolver\Node\AttributeKey;
final class ParentClassConstantNodeFinder
{
/**
* @var ParsedNodeCollector
* @var NodeRepository
*/
private $parsedNodeCollector;
private $nodeRepository;
public function __construct(ParsedNodeCollector $parsedNodeCollector)
public function __construct(NodeRepository $nodeRepository)
{
$this->parsedNodeCollector = $parsedNodeCollector;
$this->nodeRepository = $nodeRepository;
}
public function find(string $class, string $constant): ?ClassConst
{
$classNode = $this->parsedNodeCollector->findClass($class);
$classNode = $this->nodeRepository->findClass($class);
if (! $classNode instanceof Class_) {
return null;
}
@ -34,6 +34,6 @@ final class ParentClassConstantNodeFinder
return null;
}
return $this->parsedNodeCollector->findClassConstant($parentClassName, $constant);
return $this->nodeRepository->findClassConstant($parentClassName, $constant);
}
}

View File

@ -68,7 +68,7 @@ CODE_SAMPLE
if ($nodeRepositoryFindMethodCallsOnClass !== []) {
return null;
}
$parsedNodeCollectorFindNewsByClass = $this->parsedNodeCollector->findNewsByClass($className);
$parsedNodeCollectorFindNewsByClass = $this->nodeRepository->findNewsByClass($className);
// 2. is in new?
if ($parsedNodeCollectorFindNewsByClass !== []) {

View File

@ -31,7 +31,7 @@ final class NewUniqueObjectToEntityFactoryRector extends AbstractRector implemen
* @api
* @var string
*/
public const TYPES_TO_SERVICES = '$typesToServices';
public const TYPES_TO_SERVICES = 'types_to_services';
/**
* @var string
@ -190,7 +190,7 @@ CODE_SAMPLE
}
// temporary
$classes = $this->parsedNodeCollector->getClasses();
$classes = $this->nodeRepository->getClasses();
if ($classes === []) {
return [];
}

View File

@ -0,0 +1,17 @@
<?php
declare(strict_types=1);
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
return static function (ContainerConfigurator $containerConfigurator): void {
$services = $containerConfigurator->services();
$services->defaults()
->public()
->autowire()
->autoconfigure();
$services->load('Rector\Removing\\', __DIR__ . '/../src')
->exclude([__DIR__ . '/../src/Rector', __DIR__ . '/../src/ValueObject']);
};

View File

@ -2,7 +2,7 @@
declare(strict_types=1);
namespace Rector\Core\Rector\AbstractRector;
namespace Rector\Removing\NodeManipulator;
use PhpParser\Node;
use PhpParser\Node\Expr;
@ -13,42 +13,23 @@ use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Property;
use Rector\Core\Exception\ShouldNotHappenException;
use Rector\Core\NodeManipulator\PropertyManipulator;
use Rector\Core\PhpParser\Node\BetterNodeFinder;
use Rector\Core\PhpParser\NodeFinder\PropertyFetchFinder;
use Rector\Core\PhpParser\Printer\BetterStandardPrinter;
use Rector\Core\ValueObject\MethodName;
use Rector\DeadCode\NodeManipulator\LivingCodeManipulator;
use Rector\NodeCollector\NodeCollector\ParsedNodeCollector;
use Rector\NodeNameResolver\NodeNameResolver;
use Rector\NodeRemoval\AssignRemover;
use Rector\NodeRemoval\ClassMethodRemover;
use Rector\NodeRemoval\NodeRemover;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\PostRector\Collector\NodesToRemoveCollector;
/**
* Located in another trait
* @property NodesToRemoveCollector $nodesToRemoveCollector
*/
trait ComplexRemovalTrait
final class ComplexNodeRemover
{
/**
* @var ParsedNodeCollector
*/
protected $parsedNodeCollector;
/**
* @var LivingCodeManipulator
*/
protected $livingCodeManipulator;
/**
* @var BetterStandardPrinter
*/
protected $betterStandardPrinter;
/**
* @var PropertyManipulator
*/
private $propertyManipulator;
private $betterStandardPrinter;
/**
* @var ClassMethodRemover
@ -66,27 +47,46 @@ trait ComplexRemovalTrait
private $propertyFetchFinder;
/**
* @required
* @var NodeNameResolver
*/
public function autowireComplexRemovalTrait(
PropertyManipulator $propertyManipulator,
ParsedNodeCollector $parsedNodeCollector,
LivingCodeManipulator $livingCodeManipulator,
private $nodeNameResolver;
/**
* @var BetterNodeFinder
*/
private $betterNodeFinder;
/**
* @var NodeRemover
*/
private $nodeRemover;
/**
* @var NodesToRemoveCollector
*/
private $nodesToRemoveCollector;
public function __construct(
BetterStandardPrinter $betterStandardPrinter,
ClassMethodRemover $classMethodRemover,
AssignRemover $assignRemover,
PropertyFetchFinder $propertyFetchFinder
): void {
$this->parsedNodeCollector = $parsedNodeCollector;
$this->propertyManipulator = $propertyManipulator;
$this->livingCodeManipulator = $livingCodeManipulator;
PropertyFetchFinder $propertyFetchFinder,
NodeNameResolver $nodeNameResolver,
BetterNodeFinder $betterNodeFinder,
NodeRemover $nodeRemover,
NodesToRemoveCollector $nodesToRemoveCollector
) {
$this->betterStandardPrinter = $betterStandardPrinter;
$this->classMethodRemover = $classMethodRemover;
$this->assignRemover = $assignRemover;
$this->propertyFetchFinder = $propertyFetchFinder;
$this->nodeNameResolver = $nodeNameResolver;
$this->betterNodeFinder = $betterNodeFinder;
$this->nodeRemover = $nodeRemover;
$this->nodesToRemoveCollector = $nodesToRemoveCollector;
}
protected function removeClassMethodAndUsages(ClassMethod $classMethod): void
public function removeClassMethodAndUsages(ClassMethod $classMethod): void
{
$this->classMethodRemover->removeClassMethodAndUsages($classMethod);
}
@ -94,7 +94,7 @@ trait ComplexRemovalTrait
/**
* @param string[] $classMethodNamesToSkip
*/
protected function removePropertyAndUsages(Property $property, array $classMethodNamesToSkip = []): void
public function removePropertyAndUsages(Property $property, array $classMethodNamesToSkip = []): void
{
$shouldKeepProperty = false;
@ -120,7 +120,7 @@ trait ComplexRemovalTrait
// remove __construct param
/** @var Property $property */
$this->removeNode($property);
$this->nodeRemover->removeNode($property);
foreach ($property->props as $prop) {
if (! $this->nodesToRemoveCollector->isNodeRemoved($prop)) {
@ -129,7 +129,7 @@ trait ComplexRemovalTrait
}
}
$this->removeNode($property);
$this->nodeRemover->removeNode($property);
}
/**
@ -143,7 +143,7 @@ trait ComplexRemovalTrait
return false;
}
$classMethodName = $this->getName($classMethodNode);
$classMethodName = $this->nodeNameResolver->getName($classMethodNode);
return in_array($classMethodName, $classMethodNamesToSkip, true);
}
@ -191,7 +191,7 @@ trait ComplexRemovalTrait
return $this->betterStandardPrinter->areNodesEqual($param->var, $node);
});
if ($variable === null) {
if (! $variable instanceof Node) {
continue;
}
@ -203,7 +203,7 @@ trait ComplexRemovalTrait
continue;
}
$this->removeNode($param);
$this->nodeRemover->removeNode($param);
}
}

View File

@ -76,7 +76,7 @@ CODE_SAMPLE
return null;
}
$this->removeFinal($node);
$this->visibilityManipulator->removeFinal($node);
return $node;
}

View File

@ -22,6 +22,7 @@ use PhpParser\NodeTraverser;
use PHPStan\Type\ArrayType;
use PHPStan\Type\Constant\ConstantArrayType;
use PHPStan\Type\MixedType;
use PHPStan\Type\TypeWithClassName;
use Rector\BetterPhpDocParser\ValueObject\PhpDocNode\Sensio\SensioTemplateTagValueNode;
use Rector\Core\Rector\AbstractRector;
use Rector\Sensio\NodeFactory\ThisRenderFactory;
@ -222,6 +223,20 @@ CODE_SAMPLE
return $this->isReturnOfObjectType($lastReturn, self::RESPONSE_CLASS);
}
private function isReturnOfObjectType(Return_ $return, string $objectType): bool
{
if ($return->expr === null) {
return false;
}
$returnType = $this->getStaticType($return->expr);
if (! $returnType instanceof TypeWithClassName) {
return false;
}
return is_a($returnType->getClassName(), $objectType, true);
}
private function refactorReturn(
Return_ $return,
ClassMethod $classMethod,

View File

@ -11,6 +11,7 @@ use PhpParser\Node\Expr\FuncCall;
use PhpParser\Node\Expr\MethodCall;
use PHPStan\Type\ObjectType;
use Rector\Core\Rector\AbstractRector;
use Rector\NodeTypeResolver\TypeAnalyzer\StringTypeAnalyzer;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
@ -20,6 +21,16 @@ use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
*/
final class MakeDispatchFirstArgumentEventRector extends AbstractRector
{
/**
* @var StringTypeAnalyzer
*/
private $stringTypeAnalyzer;
public function __construct(StringTypeAnalyzer $stringTypeAnalyzer)
{
$this->stringTypeAnalyzer = $stringTypeAnalyzer;
}
public function getRuleDefinition(): RuleDefinition
{
return new RuleDefinition(
@ -72,7 +83,7 @@ CODE_SAMPLE
}
$firstArgumentValue = $node->args[0]->value;
if ($this->isStringOrUnionStringOnlyType($firstArgumentValue)) {
if ($this->stringTypeAnalyzer->isStringOrUnionStringOnlyType($firstArgumentValue)) {
return $this->refactorStringArgument($node);
}

View File

@ -16,6 +16,7 @@ use Rector\Core\Rector\AbstractRector;
use Rector\Naming\Naming\PropertyNaming;
use Rector\Naming\ValueObject\ExpectedName;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\NodeTypeResolver\TypeAnalyzer\ArrayTypeAnalyzer;
use Rector\StaticTypeMapper\ValueObject\Type\FullyQualifiedObjectType;
use Rector\Transform\ValueObject\ArgumentFuncCallToMethodCall;
use Rector\Transform\ValueObject\ArrayFuncCallToMethodCall;
@ -53,9 +54,15 @@ final class ArgumentFuncCallToMethodCallRector extends AbstractRector implements
*/
private $propertyNaming;
public function __construct(PropertyNaming $propertyNaming)
/**
* @var ArrayTypeAnalyzer
*/
private $arrayTypeAnalyzer;
public function __construct(ArrayTypeAnalyzer $arrayTypeAnalyzer, PropertyNaming $propertyNaming)
{
$this->propertyNaming = $propertyNaming;
$this->arrayTypeAnalyzer = $arrayTypeAnalyzer;
}
public function getRuleDefinition(): RuleDefinition
@ -268,11 +275,15 @@ CODE_SAMPLE
return $propertyFetch;
}
if ($arrayFuncCallToMethodCall->getArrayMethod() && $this->isArrayType($funcCall->args[0]->value)) {
if ($arrayFuncCallToMethodCall->getArrayMethod() && $this->arrayTypeAnalyzer->isArrayType(
$funcCall->args[0]->value
)) {
return new MethodCall($propertyFetch, $arrayFuncCallToMethodCall->getArrayMethod(), $funcCall->args);
}
if ($arrayFuncCallToMethodCall->getNonArrayMethod() && ! $this->isArrayType($funcCall->args[0]->value)) {
if ($arrayFuncCallToMethodCall->getNonArrayMethod() && ! $this->arrayTypeAnalyzer->isArrayType(
$funcCall->args[0]->value
)) {
return new MethodCall($propertyFetch, $arrayFuncCallToMethodCall->getNonArrayMethod(), $funcCall->args);
}

View File

@ -143,7 +143,7 @@ CODE_SAMPLE
return null;
}
if (! $this->isNonAnonymousClass($classLike)) {
if ($this->classNodeAnalyzer->isAnonymousClass($classLike)) {
return null;
}

View File

@ -11,7 +11,6 @@ use Rector\Core\NodeAnalyzer\PromotedPropertyParamCleaner;
use Rector\Core\PhpParser\Node\NodeFactory;
use Rector\Core\ValueObject\MethodName;
use Rector\NodeCollector\NodeCollector\NodeRepository;
use Rector\NodeCollector\NodeCollector\ParsedNodeCollector;
use Rector\NodeNameResolver\NodeNameResolver;
use Rector\NodeTypeResolver\Node\AttributeKey;
@ -27,11 +26,6 @@ final class ChildAndParentClassManipulator
*/
private $nodeNameResolver;
/**
* @var ParsedNodeCollector
*/
private $parsedNodeCollector;
/**
* @var NodeRepository
*/
@ -45,13 +39,11 @@ final class ChildAndParentClassManipulator
public function __construct(
NodeFactory $nodeFactory,
NodeNameResolver $nodeNameResolver,
ParsedNodeCollector $parsedNodeCollector,
NodeRepository $nodeRepository,
PromotedPropertyParamCleaner $promotedPropertyParamCleaner
) {
$this->nodeFactory = $nodeFactory;
$this->nodeNameResolver = $nodeNameResolver;
$this->parsedNodeCollector = $parsedNodeCollector;
$this->nodeRepository = $nodeRepository;
$this->promotedPropertyParamCleaner = $promotedPropertyParamCleaner;
}
@ -68,7 +60,7 @@ final class ChildAndParentClassManipulator
}
// not in analyzed scope, nothing we can do
$parentClassNode = $this->parsedNodeCollector->findClass($parentClassName);
$parentClassNode = $this->nodeRepository->findClass($parentClassName);
if ($parentClassNode !== null) {
$this->completeParentConstructorBasedOnParentNode($parentClassNode, $classMethod);
return;
@ -144,7 +136,7 @@ final class ChildAndParentClassManipulator
return null;
}
$class = $this->parsedNodeCollector->findClass($parentClassName);
$class = $this->nodeRepository->findClass($parentClassName);
}
return null;

View File

@ -11,7 +11,7 @@ use PhpParser\Node\Stmt\ClassConst;
use PhpParser\Node\Stmt\Trait_;
use Rector\Core\PhpParser\Node\BetterNodeFinder;
use Rector\Core\PhpParser\Printer\BetterStandardPrinter;
use Rector\NodeCollector\NodeCollector\ParsedNodeCollector;
use Rector\NodeCollector\NodeCollector\NodeRepository;
use Rector\NodeNameResolver\NodeNameResolver;
use Rector\NodeTypeResolver\Node\AttributeKey;
@ -32,28 +32,28 @@ final class ClassConstManipulator
*/
private $betterStandardPrinter;
/**
* @var ParsedNodeCollector
*/
private $parsedNodeCollector;
/**
* @var ClassManipulator
*/
private $classManipulator;
/**
* @var NodeRepository
*/
private $nodeRepository;
public function __construct(
BetterNodeFinder $betterNodeFinder,
BetterStandardPrinter $betterStandardPrinter,
ClassManipulator $classManipulator,
NodeNameResolver $nodeNameResolver,
ParsedNodeCollector $parsedNodeCollector
NodeRepository $nodeRepository
) {
$this->nodeNameResolver = $nodeNameResolver;
$this->betterNodeFinder = $betterNodeFinder;
$this->betterStandardPrinter = $betterStandardPrinter;
$this->parsedNodeCollector = $parsedNodeCollector;
$this->classManipulator = $classManipulator;
$this->nodeRepository = $nodeRepository;
}
/**
@ -70,7 +70,7 @@ final class ClassConstManipulator
$usedTraitNames = $this->classManipulator->getUsedTraits($classLike);
foreach ($usedTraitNames as $name) {
$name = $this->parsedNodeCollector->findTrait((string) $name);
$name = $this->nodeRepository->findTrait((string) $name);
if (! $name instanceof Trait_) {
continue;
}

View File

@ -136,6 +136,11 @@ final class VisibilityManipulator
$this->replaceVisibilityFlag($node, Visibility::PRIVATE);
}
public function removeFinal(Class_ $class): void
{
$class->flags -= Class_::MODIFIER_FINAL;
}
/**
* @param Class_|ClassMethod|Property|ClassConst $node
*/

View File

@ -17,7 +17,7 @@ use PhpParser\Node\Stmt\ClassConst;
use PhpParser\Node\Stmt\ClassMethod;
use Rector\Core\PhpParser\Node\BetterNodeFinder;
use Rector\Core\PhpParser\Printer\BetterStandardPrinter;
use Rector\NodeCollector\NodeCollector\ParsedNodeCollector;
use Rector\NodeCollector\NodeCollector\NodeRepository;
use Rector\NodeNameResolver\NodeNameResolver;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\NodeTypeResolver\NodeTypeResolver;
@ -25,7 +25,7 @@ use Rector\NodeTypeResolver\NodeTypeResolver;
final class RegexPatternArgumentManipulator
{
/**
* @var int[]
* @var array<string, int>
*/
private const FUNCTIONS_WITH_PATTERNS_TO_ARGUMENT_POSITION = [
'preg_match' => 0,
@ -70,22 +70,22 @@ final class RegexPatternArgumentManipulator
private $betterStandardPrinter;
/**
* @var ParsedNodeCollector
* @var NodeRepository
*/
private $parsedNodeCollector;
private $nodeRepository;
public function __construct(
BetterNodeFinder $betterNodeFinder,
BetterStandardPrinter $betterStandardPrinter,
NodeNameResolver $nodeNameResolver,
NodeTypeResolver $nodeTypeResolver,
ParsedNodeCollector $parsedNodeCollector
NodeRepository $nodeRepository
) {
$this->nodeTypeResolver = $nodeTypeResolver;
$this->nodeNameResolver = $nodeNameResolver;
$this->parsedNodeCollector = $parsedNodeCollector;
$this->betterNodeFinder = $betterNodeFinder;
$this->betterStandardPrinter = $betterStandardPrinter;
$this->nodeRepository = $nodeRepository;
}
/**
@ -206,7 +206,7 @@ final class RegexPatternArgumentManipulator
*/
private function resolveClassConstFetchValue(ClassConstFetch $classConstFetch): array
{
$classConstNode = $this->parsedNodeCollector->findClassConstByClassConstFetch($classConstFetch);
$classConstNode = $this->nodeRepository->findClassConstByClassConstFetch($classConstFetch);
if (! $classConstNode instanceof ClassConst) {
return [];
}

View File

@ -13,12 +13,10 @@ use PhpParser\Node\Expr\ClassConstFetch;
use PhpParser\Node\Expr\ConstFetch;
use PhpParser\Node\Scalar\MagicConst\Dir;
use PhpParser\Node\Scalar\MagicConst\File;
use PhpParser\Node\Stmt\ClassConst;
use PHPStan\Type\Constant\ConstantArrayType;
use PHPStan\Type\ConstantScalarType;
use Rector\Core\Exception\ShouldNotHappenException;
use Rector\Core\NodeAnalyzer\ConstFetchAnalyzer;
use Rector\NodeCollector\NodeCollector\ParsedNodeCollector;
use Rector\NodeNameResolver\NodeNameResolver;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\NodeTypeResolver\NodeTypeResolver;
@ -39,11 +37,6 @@ final class ValueResolver
*/
private $constExprEvaluator;
/**
* @var ParsedNodeCollector
*/
private $parsedNodeCollector;
/**
* @var NodeTypeResolver
*/
@ -57,11 +50,9 @@ final class ValueResolver
public function __construct(
NodeNameResolver $nodeNameResolver,
NodeTypeResolver $nodeTypeResolver,
ParsedNodeCollector $parsedNodeCollector,
ConstFetchAnalyzer $constFetchAnalyzer
) {
$this->nodeNameResolver = $nodeNameResolver;
$this->parsedNodeCollector = $parsedNodeCollector;
$this->nodeTypeResolver = $nodeTypeResolver;
$this->constFetchAnalyzer = $constFetchAnalyzer;
}
@ -268,13 +259,12 @@ final class ValueResolver
return $class;
}
$classConstNode = $this->parsedNodeCollector->findClassConstant($class, $constant);
if (! $classConstNode instanceof ClassConst) {
// fallback to the name
return $class . '::' . $constant;
$classConstantReference = $class . '::' . $constant;
if (defined($classConstantReference)) {
return constant($classConstantReference);
}
return $this->constExprEvaluator->evaluateDirectly($classConstNode->consts[0]->value);
// fallback to constant reference itself, to avoid fatal error
return $classConstantReference;
}
}

View File

@ -4,39 +4,349 @@ declare(strict_types=1);
namespace Rector\Core\Rector\AbstractRector;
use Nette\Utils\Strings;
use PhpParser\Node;
use PhpParser\Node\Expr;
use PhpParser\Node\Expr\ClassConstFetch;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Expr\StaticCall;
use PhpParser\Node\Expr\Variable;
use PhpParser\Node\Identifier;
use PhpParser\Node\Name;
use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\ClassLike;
use PhpParser\Node\Stmt\ClassMethod;
use PHPStan\Type\ObjectType;
use PHPStan\Type\Type;
use Rector\ChangesReporting\Rector\AbstractRector\NotifyingRemovingNodeTrait;
use Rector\CodingStyle\Naming\ClassNaming;
use Rector\Core\PhpParser\Printer\BetterStandardPrinter;
use Rector\NodeNameResolver\NodeNameResolver;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\NodeTypeResolver\NodeTypeResolver;
use Rector\PHPStanStaticTypeMapper\Utils\TypeUnwrapper;
use Rector\PostRector\Rector\AbstractRector\NodeCommandersTrait;
use Symplify\Astral\NodeTraverser\SimpleCallableNodeTraverser;
trait AbstractRectorTrait
{
use RemovedAndAddedFilesTrait;
use NodeTypeResolverTrait;
use NameResolverTrait;
use BetterStandardPrinterTrait;
use NodeCommandersTrait;
use SimpleCallableNodeTraverserTrait;
use ComplexRemovalTrait;
use NotifyingRemovingNodeTrait;
protected function isNonAnonymousClass(Node $node): bool
{
if (! $node instanceof Class_) {
return false;
}
/**
* @var NodeNameResolver
*/
protected $nodeNameResolver;
$name = $this->getName($node);
if ($name === null) {
return false;
}
/**
* @var TypeUnwrapper
*/
protected $typeUnwrapper;
return ! Strings::contains($name, 'AnonymousClass');
/**
* @var NodeTypeResolver
*/
protected $nodeTypeResolver;
/**
* @var BetterStandardPrinter
*/
protected $betterStandardPrinter;
/**
* @var ClassNaming
*/
private $classNaming;
/**
* @var SimpleCallableNodeTraverser
*/
private $simpleCallableNodeTraverser;
/**
* @required
*/
public function autowireAbstractRectorTrait(
BetterStandardPrinter $betterStandardPrinter,
NodeNameResolver $nodeNameResolver,
ClassNaming $classNaming,
NodeTypeResolver $nodeTypeResolver,
TypeUnwrapper $typeUnwrapper,
SimpleCallableNodeTraverser $simpleCallableNodeTraverser
): void {
$this->betterStandardPrinter = $betterStandardPrinter;
$this->nodeNameResolver = $nodeNameResolver;
$this->classNaming = $classNaming;
$this->nodeTypeResolver = $nodeTypeResolver;
$this->typeUnwrapper = $typeUnwrapper;
$this->simpleCallableNodeTraverser = $simpleCallableNodeTraverser;
}
protected function removeFinal(Class_ $class): void
protected function isName(Node $node, string $name): bool
{
$class->flags -= Class_::MODIFIER_FINAL;
return $this->nodeNameResolver->isName($node, $name);
}
protected function areNamesEqual(Node $firstNode, Node $secondNode): bool
{
return $this->nodeNameResolver->areNamesEqual($firstNode, $secondNode);
}
/**
* @param string[] $names
*/
protected function isNames(Node $node, array $names): bool
{
return $this->nodeNameResolver->isNames($node, $names);
}
protected function getName(Node $node): ?string
{
return $this->nodeNameResolver->getName($node);
}
/**
* @param string|Name|Identifier|ClassLike $name
*/
protected function getShortName($name): string
{
return $this->classNaming->getShortName($name);
}
protected function isLocalPropertyFetchNamed(Node $node, string $name): bool
{
return $this->nodeNameResolver->isLocalPropertyFetchNamed($node, $name);
}
protected function isLocalMethodCallNamed(Node $node, string $name): bool
{
return $this->nodeNameResolver->isLocalMethodCallNamed($node, $name);
}
/**
* @param string[] $names
*/
protected function isLocalMethodCallsNamed(Node $node, array $names): bool
{
return $this->nodeNameResolver->isLocalMethodCallsNamed($node, $names);
}
protected function isFuncCallName(Node $node, string $name): bool
{
return $this->nodeNameResolver->isFuncCallName($node, $name);
}
/**
* Detects "SomeClass::class"
*/
protected function isClassConstReference(Node $node, string $className): bool
{
if (! $node instanceof ClassConstFetch) {
return false;
}
if (! $this->isName($node->name, 'class')) {
return false;
}
return $this->isName($node->class, $className);
}
protected function isStaticCallNamed(Node $node, string $className, string $methodName): bool
{
if (! $node instanceof StaticCall) {
return false;
}
// handles (new Some())->...
if ($node->class instanceof Expr) {
if (! $this->isObjectType($node->class, $className)) {
return false;
}
} elseif (! $this->isName($node->class, $className)) {
return false;
}
return $this->isName($node->name, $methodName);
}
/**
* @param string[] $names
*/
protected function isFuncCallNames(Node $node, array $names): bool
{
return $this->nodeNameResolver->isFuncCallNames($node, $names);
}
/**
* @param string[] $methodNames
*/
protected function isStaticCallsNamed(Node $node, string $className, array $methodNames): bool
{
foreach ($methodNames as $methodName) {
if ($this->isStaticCallNamed($node, $className, $methodName)) {
return true;
}
}
return false;
}
protected function isMethodCall(Node $node, string $variableName, string $methodName): bool
{
if (! $node instanceof MethodCall) {
return false;
}
if ($node->var instanceof MethodCall) {
return false;
}
if ($node->var instanceof StaticCall) {
return false;
}
if (! $this->isName($node->var, $variableName)) {
return false;
}
return $this->isName($node->name, $methodName);
}
protected function isVariableName(Node $node, string $name): bool
{
if (! $node instanceof Variable) {
return false;
}
return $this->isName($node, $name);
}
protected function isInClassNamed(Node $node, string $desiredClassName): bool
{
$className = $node->getAttribute(AttributeKey::CLASS_NAME);
if ($className === null) {
return false;
}
return is_a($className, $desiredClassName, true);
}
/**
* @param string[] $desiredClassNames
*/
protected function isInClassesNamed(Node $node, array $desiredClassNames): bool
{
foreach ($desiredClassNames as $desiredClassName) {
if ($this->isInClassNamed($node, $desiredClassName)) {
return true;
}
}
return false;
}
/**
* @param ObjectType|string $type
*/
protected function isObjectType(Node $node, $type): bool
{
return $this->nodeTypeResolver->isObjectType($node, $type);
}
/**
* @param string[]|ObjectType[] $requiredTypes
*/
protected function isObjectTypes(Node $node, array $requiredTypes): bool
{
return $this->nodeTypeResolver->isObjectTypes($node, $requiredTypes);
}
/**
* @param Type[] $desiredTypes
*/
protected function isSameObjectTypes(ObjectType $objectType, array $desiredTypes): bool
{
foreach ($desiredTypes as $abstractClassConstructorParamType) {
if ($abstractClassConstructorParamType->equals($objectType)) {
return true;
}
}
return false;
}
protected function isNumberType(Node $node): bool
{
return $this->nodeTypeResolver->isNumberType($node);
}
protected function isStaticType(Node $node, string $staticTypeClass): bool
{
return $this->nodeTypeResolver->isStaticType($node, $staticTypeClass);
}
protected function getStaticType(Node $node): Type
{
return $this->nodeTypeResolver->getStaticType($node);
}
protected function isNullableType(Node $node): bool
{
return $this->nodeTypeResolver->isNullableType($node);
}
protected function getObjectType(Node $node): Type
{
return $this->nodeTypeResolver->resolve($node);
}
/**
* @param MethodCall|StaticCall|ClassMethod $node
*/
protected function isMethodStaticCallOrClassMethodObjectType(Node $node, string $type): bool
{
if ($node instanceof MethodCall) {
// method call is variable return
return $this->isObjectType($node->var, $type);
}
if ($node instanceof StaticCall) {
return $this->isObjectType($node->class, $type);
}
$classLike = $node->getAttribute(AttributeKey::CLASS_NODE);
if (! $classLike instanceof Class_) {
return false;
}
return $this->isObjectType($classLike, $type);
}
/**
* @param Node|Node[] $nodes
*/
protected function traverseNodesWithCallable($nodes, callable $callable): void
{
$this->simpleCallableNodeTraverser->traverseNodesWithCallable($nodes, $callable);
}
/**
* @param Node|Node[]|null $node
*/
protected function print($node): string
{
return $this->betterStandardPrinter->print($node);
}
/**
* Removes all comments from both nodes
*
* @param Node|Node[]|null $firstNode
* @param Node|Node[]|null $secondNode
*/
protected function areNodesEqual($firstNode, $secondNode): bool
{
return $this->betterStandardPrinter->areNodesEqual($firstNode, $secondNode);
}
}

View File

@ -1,47 +0,0 @@
<?php
declare(strict_types=1);
namespace Rector\Core\Rector\AbstractRector;
use PhpParser\Node;
use Rector\Core\PhpParser\Printer\BetterStandardPrinter;
/**
* This could be part of @see AbstractRector, but decopuling to trait
* makes clear what code has 1 purpose.
*/
trait BetterStandardPrinterTrait
{
/**
* @var BetterStandardPrinter
*/
protected $betterStandardPrinter;
/**
* @required
*/
public function autowireBetterStandardPrinterTrait(BetterStandardPrinter $betterStandardPrinter): void
{
$this->betterStandardPrinter = $betterStandardPrinter;
}
/**
* @param Node|Node[]|null $node
*/
public function print($node): string
{
return $this->betterStandardPrinter->print($node);
}
/**
* Removes all comments from both nodes
*
* @param Node|Node[]|null $firstNode
* @param Node|Node[]|null $secondNode
*/
protected function areNodesEqual($firstNode, $secondNode): bool
{
return $this->betterStandardPrinter->areNodesEqual($firstNode, $secondNode);
}
}

View File

@ -1,208 +0,0 @@
<?php
declare(strict_types=1);
namespace Rector\Core\Rector\AbstractRector;
use PhpParser\Node;
use PhpParser\Node\Expr;
use PhpParser\Node\Expr\ClassConstFetch;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Expr\StaticCall;
use PhpParser\Node\Expr\Variable;
use PhpParser\Node\Identifier;
use PhpParser\Node\Name;
use PhpParser\Node\Stmt\ClassLike;
use Rector\CodingStyle\Naming\ClassNaming;
use Rector\NodeNameResolver\NodeNameResolver;
use Rector\NodeTypeResolver\Node\AttributeKey;
/**
* This could be part of @see AbstractRector, but decopuling to trait
* makes clear what code has 1 purpose.
*/
trait NameResolverTrait
{
/**
* @var NodeNameResolver
*/
protected $nodeNameResolver;
/**
* @var ClassNaming
*/
private $classNaming;
/**
* @required
*/
public function autowireNameResolverTrait(NodeNameResolver $nodeNameResolver, ClassNaming $classNaming): void
{
$this->nodeNameResolver = $nodeNameResolver;
$this->classNaming = $classNaming;
}
public function isName(Node $node, string $name): bool
{
return $this->nodeNameResolver->isName($node, $name);
}
public function areNamesEqual(Node $firstNode, Node $secondNode): bool
{
return $this->nodeNameResolver->areNamesEqual($firstNode, $secondNode);
}
/**
* @param string[] $names
*/
public function isNames(Node $node, array $names): bool
{
return $this->nodeNameResolver->isNames($node, $names);
}
public function getName(Node $node): ?string
{
return $this->nodeNameResolver->getName($node);
}
/**
* @param string|Name|Identifier|ClassLike $name
*/
protected function getShortName($name): string
{
return $this->classNaming->getShortName($name);
}
protected function isLocalPropertyFetchNamed(Node $node, string $name): bool
{
return $this->nodeNameResolver->isLocalPropertyFetchNamed($node, $name);
}
protected function isLocalMethodCallNamed(Node $node, string $name): bool
{
return $this->nodeNameResolver->isLocalMethodCallNamed($node, $name);
}
/**
* @param string[] $names
*/
protected function isLocalMethodCallsNamed(Node $node, array $names): bool
{
return $this->nodeNameResolver->isLocalMethodCallsNamed($node, $names);
}
protected function isFuncCallName(Node $node, string $name): bool
{
return $this->nodeNameResolver->isFuncCallName($node, $name);
}
/**
* Detects "SomeClass::class"
*/
protected function isClassConstReference(Node $node, string $className): bool
{
if (! $node instanceof ClassConstFetch) {
return false;
}
if (! $this->isName($node->name, 'class')) {
return false;
}
return $this->isName($node->class, $className);
}
protected function isStaticCallNamed(Node $node, string $className, string $methodName): bool
{
if (! $node instanceof StaticCall) {
return false;
}
// handles (new Some())->...
if ($node->class instanceof Expr) {
if (! $this->isObjectType($node->class, $className)) {
return false;
}
} elseif (! $this->isName($node->class, $className)) {
return false;
}
return $this->isName($node->name, $methodName);
}
/**
* @param string[] $names
*/
protected function isFuncCallNames(Node $node, array $names): bool
{
return $this->nodeNameResolver->isFuncCallNames($node, $names);
}
/**
* @param string[] $methodNames
*/
protected function isStaticCallsNamed(Node $node, string $className, array $methodNames): bool
{
foreach ($methodNames as $methodName) {
if ($this->isStaticCallNamed($node, $className, $methodName)) {
return true;
}
}
return false;
}
protected function isMethodCall(Node $node, string $variableName, string $methodName): bool
{
if (! $node instanceof MethodCall) {
return false;
}
if ($node->var instanceof MethodCall) {
return false;
}
if ($node->var instanceof StaticCall) {
return false;
}
if (! $this->isName($node->var, $variableName)) {
return false;
}
return $this->isName($node->name, $methodName);
}
protected function isVariableName(Node $node, string $name): bool
{
if (! $node instanceof Variable) {
return false;
}
return $this->isName($node, $name);
}
protected function isInClassNamed(Node $node, string $desiredClassName): bool
{
$className = $node->getAttribute(AttributeKey::CLASS_NAME);
if ($className === null) {
return false;
}
return is_a($className, $desiredClassName, true);
}
/**
* @param string[] $desiredClassNames
*/
protected function isInClassesNamed(Node $node, array $desiredClassNames): bool
{
foreach ($desiredClassNames as $desiredClassName) {
if ($this->isInClassNamed($node, $desiredClassName)) {
return true;
}
}
return false;
}
}

View File

@ -1,197 +0,0 @@
<?php
declare(strict_types=1);
namespace Rector\Core\Rector\AbstractRector;
use PhpParser\Node;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Expr\StaticCall;
use PhpParser\Node\Expr\Variable;
use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Property;
use PhpParser\Node\Stmt\Return_;
use PHPStan\Type\ObjectType;
use PHPStan\Type\Type;
use PHPStan\Type\TypeWithClassName;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\NodeTypeResolver\NodeTypeResolver;
use Rector\NodeTypeResolver\TypeAnalyzer\ArrayTypeAnalyzer;
use Rector\NodeTypeResolver\TypeAnalyzer\CountableTypeAnalyzer;
use Rector\NodeTypeResolver\TypeAnalyzer\StringTypeAnalyzer;
use Rector\PHPStanStaticTypeMapper\Utils\TypeUnwrapper;
/**
* This could be part of @see AbstractRector, but decopuling to trait
* makes clear what code has 1 purpose.
*/
trait NodeTypeResolverTrait
{
/**
* @var TypeUnwrapper
*/
protected $typeUnwrapper;
/**
* @var NodeTypeResolver
*/
private $nodeTypeResolver;
/**
* @var ArrayTypeAnalyzer
*/
private $arrayTypeAnalyzer;
/**
* @var CountableTypeAnalyzer
*/
private $countableTypeAnalyzer;
/**
* @var StringTypeAnalyzer
*/
private $stringTypeAnalyzer;
/**
* @required
*/
public function autowireNodeTypeResolverTrait(
NodeTypeResolver $nodeTypeResolver,
ArrayTypeAnalyzer $arrayTypeAnalyzer,
CountableTypeAnalyzer $countableTypeAnalyzer,
StringTypeAnalyzer $stringTypeAnalyzer,
TypeUnwrapper $typeUnwrapper
): void {
$this->nodeTypeResolver = $nodeTypeResolver;
$this->arrayTypeAnalyzer = $arrayTypeAnalyzer;
$this->countableTypeAnalyzer = $countableTypeAnalyzer;
$this->stringTypeAnalyzer = $stringTypeAnalyzer;
$this->typeUnwrapper = $typeUnwrapper;
}
public function isPropertyBoolean(Property $property): bool
{
return $this->nodeTypeResolver->isPropertyBoolean($property);
}
/**
* @param ObjectType|string $type
*/
protected function isObjectType(Node $node, $type): bool
{
return $this->nodeTypeResolver->isObjectType($node, $type);
}
/**
* @param string[]|ObjectType[] $requiredTypes
*/
protected function isObjectTypes(Node $node, array $requiredTypes): bool
{
return $this->nodeTypeResolver->isObjectTypes($node, $requiredTypes);
}
protected function isReturnOfObjectType(Return_ $return, string $objectType): bool
{
if ($return->expr === null) {
return false;
}
$returnType = $this->getStaticType($return->expr);
if (! $returnType instanceof TypeWithClassName) {
return false;
}
return is_a($returnType->getClassName(), $objectType, true);
}
/**
* @param Type[] $desiredTypes
*/
protected function isSameObjectTypes(ObjectType $objectType, array $desiredTypes): bool
{
foreach ($desiredTypes as $abstractClassConstructorParamType) {
if ($abstractClassConstructorParamType->equals($objectType)) {
return true;
}
}
return false;
}
protected function isStringOrUnionStringOnlyType(Node $node): bool
{
return $this->stringTypeAnalyzer->isStringOrUnionStringOnlyType($node);
}
protected function isNumberType(Node $node): bool
{
return $this->nodeTypeResolver->isNumberType($node);
}
protected function isStaticType(Node $node, string $staticTypeClass): bool
{
return $this->nodeTypeResolver->isStaticType($node, $staticTypeClass);
}
protected function getStaticType(Node $node): Type
{
return $this->nodeTypeResolver->getStaticType($node);
}
protected function isNullableType(Node $node): bool
{
return $this->nodeTypeResolver->isNullableType($node);
}
protected function isNullableObjectType(Node $node): bool
{
return $this->nodeTypeResolver->isNullableObjectType($node);
}
protected function isNullableArrayType(Node $node): bool
{
return $this->nodeTypeResolver->isNullableArrayType($node);
}
protected function isCountableType(Node $node): bool
{
return $this->countableTypeAnalyzer->isCountableType($node);
}
protected function isArrayType(Node $node): bool
{
return $this->arrayTypeAnalyzer->isArrayType($node);
}
protected function getObjectType(Node $node): Type
{
return $this->nodeTypeResolver->resolve($node);
}
/**
* @param MethodCall|StaticCall|ClassMethod $node
*/
protected function isMethodStaticCallOrClassMethodObjectType(Node $node, string $type): bool
{
if ($node instanceof MethodCall) {
// method call is variable return
return $this->isObjectType($node->var, $type);
}
if ($node instanceof StaticCall) {
return $this->isObjectType($node->class, $type);
}
if ($node instanceof ClassMethod) {
$classLike = $node->getAttribute(AttributeKey::CLASS_NODE);
if (! $classLike instanceof Class_) {
return false;
}
return $this->isObjectType($classLike, $type);
}
return false;
}
}

View File

@ -1,37 +0,0 @@
<?php
declare(strict_types=1);
namespace Rector\Core\Rector\AbstractRector;
use PhpParser\Node;
use Symplify\Astral\NodeTraverser\SimpleCallableNodeTraverser;
/**
* This could be part of @see AbstractRector, but decopuling to trait
* makes clear what code has 1 purpose.
*/
trait SimpleCallableNodeTraverserTrait
{
/**
* @var SimpleCallableNodeTraverser
*/
private $simpleCallableNodeTraverser;
/**
* @required
*/
public function autowireSimpleCallableNodeTraverserTrait(
SimpleCallableNodeTraverser $simpleCallableNodeTraverser
): void {
$this->simpleCallableNodeTraverser = $simpleCallableNodeTraverser;
}
/**
* @param Node|Node[] $nodes
*/
public function traverseNodesWithCallable($nodes, callable $callable): void
{
$this->simpleCallableNodeTraverser->traverseNodesWithCallable($nodes, $callable);
}
}