diff --git a/easy-ci.php b/easy-ci.php index f444305eacf..0f2b4c802c5 100644 --- a/easy-ci.php +++ b/easy-ci.php @@ -2,7 +2,6 @@ declare(strict_types=1); -use PHPStan\PhpDocParser\Parser\TypeParser; use Rector\BetterPhpDocParser\Contract\PhpDocParser\PhpDocNodeDecoratorInterface; use Rector\BetterPhpDocParser\PhpDoc\ArrayItemNode; use Rector\CodingStyle\Contract\ClassNameImport\ClassNameImportSkipVoterInterface; @@ -29,7 +28,6 @@ use Rector\Testing\PHPUnit\AbstractTestCase; use Rector\TypeDeclaration\Contract\PHPStan\TypeWithClassTypeSpecifierInterface; use Symfony\Component\Console\Application; -use Symfony\Component\Console\Command\Command; use Symplify\EasyCI\Config\EasyCIConfig; return static function (EasyCIConfig $easyCiConfig): void { @@ -37,7 +35,6 @@ AttributeDecoratorInterface::class, ArrayItemNode::class, PhpDocNodeDecoratorInterface::class, - Command::class, Application::class, RectorInterface::class, TypeToCallReflectionResolverInterface::class, @@ -51,7 +48,6 @@ NodeTypeResolverInterface::class, ReadNodeAnalyzerInterface::class, SetListInterface::class, - TypeParser::class, RectorBetterReflectionSourceLocatorFactory::class, AbstractTestCase::class, PHPStanServicesFactory::class, diff --git a/packages/PostRector/Application/PostFileProcessor.php b/packages/PostRector/Application/PostFileProcessor.php index a29416df4d7..c97316fae06 100644 --- a/packages/PostRector/Application/PostFileProcessor.php +++ b/packages/PostRector/Application/PostFileProcessor.php @@ -13,7 +13,6 @@ use Rector\PostRector\Contract\Rector\PostRectorInterface; use Rector\PostRector\Rector\ClassRenamingPostRector; use Rector\PostRector\Rector\NameImportingPostRector; -use Rector\PostRector\Rector\PropertyAddingPostRector; use Rector\PostRector\Rector\UnusedImportRemovingPostRector; use Rector\PostRector\Rector\UseAddingPostRector; use Rector\Skipper\Skipper\Skipper; @@ -32,13 +31,10 @@ public function __construct( // set order here UseAddingPostRector $useAddingPostRector, NameImportingPostRector $nameImportingPostRector, - PropertyAddingPostRector $propertyAddingPostRector, ClassRenamingPostRector $classRenamingPostRector, UnusedImportRemovingPostRector $unusedImportRemovingPostRector, ) { $this->postRectors = [ - // priority: 900 - $propertyAddingPostRector, // priority: 650 $classRenamingPostRector, // priority: 600 diff --git a/packages/PostRector/Collector/PropertyToAddCollector.php b/packages/PostRector/Collector/PropertyToAddCollector.php deleted file mode 100644 index 3423f515946..00000000000 --- a/packages/PostRector/Collector/PropertyToAddCollector.php +++ /dev/null @@ -1,48 +0,0 @@ - - */ - private array $propertiesByClass = []; - - public function __construct( - private readonly RectorChangeCollector $rectorChangeCollector - ) { - } - - public function isActive(): bool - { - return $this->propertiesByClass !== []; - } - - public function addPropertyToClass(Class_ $class, PropertyMetadata $propertyMetadata): void - { - $uniqueHash = spl_object_hash($class); - $this->propertiesByClass[$uniqueHash][] = $propertyMetadata; - - $this->rectorChangeCollector->notifyNodeFileInfo($class); - } - - /** - * @return PropertyMetadata[] - */ - public function getPropertiesByClass(Class_ $class): array - { - $classHash = spl_object_hash($class); - return $this->propertiesByClass[$classHash] ?? []; - } -} diff --git a/packages/PostRector/Rector/PropertyAddingPostRector.php b/packages/PostRector/Rector/PropertyAddingPostRector.php deleted file mode 100644 index 3bdc88b5e9f..00000000000 --- a/packages/PostRector/Rector/PropertyAddingPostRector.php +++ /dev/null @@ -1,80 +0,0 @@ -classAnalyzer->isAnonymousClass($node)) { - return null; - } - - $this->addProperties($node); - - return $node; - } - - public function getRuleDefinition(): RuleDefinition - { - return new RuleDefinition( - 'Add dependency properties', - [ - new CodeSample( - <<<'CODE_SAMPLE' -class SomeClass -{ - public function run() - { - return $this->value; - } -} -CODE_SAMPLE - , - <<<'CODE_SAMPLE' -class SomeClass -{ - private $value; - public function run() - { - return $this->value; - } -} -CODE_SAMPLE - ), ] - ); - } - - private function addProperties(Class_ $class): void - { - $propertiesMetadatas = $this->propertyToAddCollector->getPropertiesByClass($class); - - foreach ($propertiesMetadatas as $propertyMetadata) { - $this->classDependencyManipulator->addConstructorDependency($class, $propertyMetadata); - } - } -} diff --git a/packages/PostRector/ValueObject/PropertyMetadata.php b/packages/PostRector/ValueObject/PropertyMetadata.php index 7aaa80e0e22..ea64a83cc23 100644 --- a/packages/PostRector/ValueObject/PropertyMetadata.php +++ b/packages/PostRector/ValueObject/PropertyMetadata.php @@ -4,6 +4,7 @@ namespace Rector\PostRector\ValueObject; +use PhpParser\Node\Stmt\Class_; use PHPStan\Type\Type; final class PropertyMetadata @@ -11,7 +12,7 @@ final class PropertyMetadata public function __construct( private readonly string $name, private readonly ?Type $type, - private readonly int $flags + private readonly int $flags = Class_::MODIFIER_PRIVATE, ) { } diff --git a/phpstan.neon b/phpstan.neon index 6ee93abca07..6648c73cb8a 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -43,9 +43,6 @@ parameters: # broken in PHPStan https://github.com/rectorphp/rector/runs/1305002460#step:5:56 - packages/Testing/PHPUnit/*.php - # demo rule - - tests/Issues/AliasedImportDouble/Rector/ClassMethod/AddAliasImportRector.php - # complex printer - '*tests/Rector/MethodCall/RenameMethodRector/**/SomeClass.php' # tests files @@ -54,8 +51,6 @@ parameters: - '*tests/*/Source/*' - '*tests/*/Source*' - '*tests/*/Fixture*' - # part of composer - - '*/tests/Rector/Psr4/MultipleClassFileToPsr4ClassesRector/Expected/Just*ExceptionWithoutNamespace.php' # tests - tests/DependencyInjection/config @@ -264,11 +259,6 @@ parameters: # impossible to validate json string is a class-string - '#Parameter \#1 \$rectorClass of class Rector\\ChangesReporting\\ValueObject\\RectorWithLineChange constructor expects class\-string\|Rector\\Core\\Contract\\Rector\\RectorInterface, string given#' - - - message: '#Only booleans are allowed in an if condition, array\|null given#' - paths: - - rules/Naming/Naming/PropertyNaming.php - # mapper re-use - '#Parameter \#1 \$type of method Rector\\PHPStanStaticTypeMapper\\TypeMapper\\ObjectWithoutClassTypeMapper\:\:mapToPhpParserNode\(\) expects PHPStan\\Type\\ObjectWithoutClassType, PHPStan\\Type\\Accessory\\Has(Property|Method)Type given#' @@ -329,7 +319,6 @@ parameters: # for config class reflection - src/Bootstrap/ExtensionConfigResolver.php - src/DependencyInjection/CompilerPass/AutowireArrayParameterCompilerPass.php - - src/DependencyInjection/Skipper/ParameterSkipper.php - src/DependencyInjection/DefinitionFinder.php - @@ -713,8 +702,6 @@ parameters: - '#Call to deprecated method findParentByTypes#' - '#Instantiation of deprecated class Rector\\Core\\DependencyInjection\\CompilerPass\\AutowireArrayParameterCompilerPass#' - # handle later - - '#Fetching class constant class of deprecated class Rector\\(.*?)#' - - '#has typehint with deprecated class Rector\\PostRector\\Collector\\PropertyToAddCollector#' + - '#Cognitive complexity for "Rector\\Transform\\Rector\\StaticCall\\StaticCallToMethodCallRector\:\:refactorWithScope\(\)" is 14, keep it under 11#' - '#Function "class_exists\(\)" cannot be used/left in the code\: use ReflectionProvider\->has\*\(\) instead#' diff --git a/rules/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector.php b/rules/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector.php index 0a9e0ab117f..cdaa285ae49 100644 --- a/rules/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector.php +++ b/rules/CodeQuality/Rector/Class_/CompleteDynamicPropertiesRector.php @@ -184,11 +184,8 @@ private function filterOutExistingProperties( continue; } - $propertyMetadata = new PropertyMetadata( - $propertyToComplete, - new ObjectType($className), - Class_::MODIFIER_PRIVATE - ); + $propertyMetadata = new PropertyMetadata($propertyToComplete, new ObjectType($className)); + $hasClassContextProperty = $this->propertyPresenceChecker->hasClassContextProperty( $class, $propertyMetadata diff --git a/rules/Transform/NodeAnalyzer/FuncCallStaticCallToMethodCallAnalyzer.php b/rules/Transform/NodeAnalyzer/FuncCallStaticCallToMethodCallAnalyzer.php index ef937f0445b..2b72b4f51c9 100644 --- a/rules/Transform/NodeAnalyzer/FuncCallStaticCallToMethodCallAnalyzer.php +++ b/rules/Transform/NodeAnalyzer/FuncCallStaticCallToMethodCallAnalyzer.php @@ -12,10 +12,10 @@ use PhpParser\Node\Stmt\ClassMethod; use PhpParser\Node\Stmt\Function_; use PHPStan\Type\ObjectType; +use Rector\Core\NodeManipulator\ClassDependencyManipulator; use Rector\Core\PhpParser\Node\NodeFactory; use Rector\Naming\Naming\PropertyNaming; use Rector\NodeNameResolver\NodeNameResolver; -use Rector\PostRector\Collector\PropertyToAddCollector; use Rector\PostRector\ValueObject\PropertyMetadata; use Rector\Transform\NodeFactory\PropertyFetchFactory; use Rector\Transform\NodeTypeAnalyzer\TypeProvidingExprFromClassResolver; @@ -28,7 +28,7 @@ public function __construct( private readonly NodeNameResolver $nodeNameResolver, private readonly NodeFactory $nodeFactory, private readonly PropertyFetchFactory $propertyFetchFactory, - private readonly PropertyToAddCollector $propertyToAddCollector + private readonly ClassDependencyManipulator $classDependencyManipulator, ) { } @@ -52,8 +52,10 @@ public function matchTypeProvidingExpr( } $propertyName = $this->propertyNaming->fqnToVariableName($objectType); - $propertyMetadata = new PropertyMetadata($propertyName, $objectType, Class_::MODIFIER_PRIVATE); - $this->propertyToAddCollector->addPropertyToClass($class, $propertyMetadata); + $this->classDependencyManipulator->addConstructorDependency( + $class, + new PropertyMetadata($propertyName, $objectType) + ); return $this->propertyFetchFactory->createFromType($objectType); } diff --git a/rules/Transform/Rector/StaticCall/StaticCallToMethodCallRector.php b/rules/Transform/Rector/StaticCall/StaticCallToMethodCallRector.php index 36e3ff19782..b483cbd28d8 100644 --- a/rules/Transform/Rector/StaticCall/StaticCallToMethodCallRector.php +++ b/rules/Transform/Rector/StaticCall/StaticCallToMethodCallRector.php @@ -10,7 +10,6 @@ use PhpParser\Node\Expr\StaticCall; use PhpParser\Node\Name\FullyQualified; use PhpParser\Node\Stmt\Class_; -use PhpParser\Node\Stmt\ClassMethod; use PHPStan\Analyser\Scope; use Rector\Core\Contract\Rector\ConfigurableRectorInterface; use Rector\Core\Exception\ShouldNotHappenException; @@ -91,53 +90,66 @@ public function run() */ public function getNodeTypes(): array { - return [StaticCall::class]; + return [Class_::class]; } /** - * @param StaticCall $node + * @param Class_ $node */ public function refactorWithScope(Node $node, Scope $scope): ?Node { - $classLike = $this->betterNodeFinder->findParentType($node, Class_::class); - if (! $classLike instanceof Class_) { - return null; - } - - $classMethod = $this->betterNodeFinder->findParentType($node, ClassMethod::class); - if (! $classMethod instanceof ClassMethod) { - return null; - } - - foreach ($this->staticCallsToMethodCalls as $staticCallToMethodCall) { - if (! $staticCallToMethodCall->isStaticCallMatch($node)) { - continue; - } - - if ($classMethod->isStatic()) { - return $this->refactorToInstanceCall($node, $staticCallToMethodCall); - } + $class = $node; + $hasChanged = false; - $expr = $this->funcCallStaticCallToMethodCallAnalyzer->matchTypeProvidingExpr( - $classLike, + foreach ($node->getMethods() as $classMethod) { + $this->traverseNodesWithCallable($classMethod, function (Node $node) use ( + $class, $classMethod, - $staticCallToMethodCall->getClassObjectType(), - ); - - if ($staticCallToMethodCall->getMethodName() === '*') { - $methodName = $this->getName($node->name); - } else { - $methodName = $staticCallToMethodCall->getMethodName(); - } - - if (! is_string($methodName)) { - throw new ShouldNotHappenException(); - } + &$hasChanged + ): null|MethodCall|StaticCall { + if (! $node instanceof StaticCall) { + return null; + } + + foreach ($this->staticCallsToMethodCalls as $staticCallToMethodCall) { + if (! $staticCallToMethodCall->isStaticCallMatch($node)) { + continue; + } + + if ($classMethod->isStatic()) { + return $this->refactorToInstanceCall($node, $staticCallToMethodCall); + } + + $expr = $this->funcCallStaticCallToMethodCallAnalyzer->matchTypeProvidingExpr( + $class, + $classMethod, + $staticCallToMethodCall->getClassObjectType(), + ); + + if ($staticCallToMethodCall->getMethodName() === '*') { + $methodName = $this->getName($node->name); + } else { + $methodName = $staticCallToMethodCall->getMethodName(); + } + + if (! is_string($methodName)) { + throw new ShouldNotHappenException(); + } + + $hasChanged = true; + + return new MethodCall($expr, $methodName, $node->args); + } + + return $node; + }); + } - return new MethodCall($expr, $methodName, $node->args); + if ($hasChanged) { + return $node; } - return $node; + return null; } /** @@ -155,6 +167,7 @@ private function refactorToInstanceCall( StaticCallToMethodCall $staticCallToMethodCall ): MethodCall { $new = new New_(new FullyQualified($staticCallToMethodCall->getClassType())); + return new MethodCall($new, $staticCallToMethodCall->getMethodName(), $staticCall->args); } } diff --git a/src/Kernel/RectorKernel.php b/src/Kernel/RectorKernel.php index 2c993382f44..0da9d981bd0 100644 --- a/src/Kernel/RectorKernel.php +++ b/src/Kernel/RectorKernel.php @@ -17,7 +17,7 @@ final class RectorKernel /** * @var string */ - private const CACHE_KEY = 'v77'; + private const CACHE_KEY = 'v79'; private ContainerInterface|null $container = null;