Updated Rector to commit 3cef752763be750ea221c5c5eb1681d27398a3d5

3cef752763 Skip classes without final and exception as possibly invoke child implement in AddVoidReturnTypeWhereNoReturnRector (#5381)
This commit is contained in:
Tomas Votruba 2023-12-23 15:28:34 +00:00
parent 78b306c557
commit a4aba10ad7
5 changed files with 59 additions and 23 deletions

View File

@ -8,10 +8,10 @@ use PhpParser\Node\Expr\Closure;
use PhpParser\Node\Identifier;
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Function_;
use PHPStan\Reflection\ClassReflection;
use PhpParser\Node\Stmt\Throw_;
use Rector\Core\NodeAnalyzer\MagicClassMethodAnalyzer;
use Rector\Core\Rector\AbstractRector;
use Rector\Core\Reflection\ReflectionResolver;
use Rector\Core\Reflection\ClassModifierChecker;
use Rector\Core\ValueObject\PhpVersionFeature;
use Rector\TypeDeclaration\TypeInferer\SilentVoidResolver;
use Rector\VendorLocker\NodeVendorLocker\ClassMethodReturnVendorLockResolver;
@ -33,22 +33,22 @@ final class AddVoidReturnTypeWhereNoReturnRector extends AbstractRector implemen
* @var \Rector\VendorLocker\NodeVendorLocker\ClassMethodReturnVendorLockResolver
*/
private $classMethodReturnVendorLockResolver;
/**
* @readonly
* @var \Rector\Core\Reflection\ReflectionResolver
*/
private $reflectionResolver;
/**
* @readonly
* @var \Rector\Core\NodeAnalyzer\MagicClassMethodAnalyzer
*/
private $magicClassMethodAnalyzer;
public function __construct(SilentVoidResolver $silentVoidResolver, ClassMethodReturnVendorLockResolver $classMethodReturnVendorLockResolver, ReflectionResolver $reflectionResolver, MagicClassMethodAnalyzer $magicClassMethodAnalyzer)
/**
* @readonly
* @var \Rector\Core\Reflection\ClassModifierChecker
*/
private $classModifierChecker;
public function __construct(SilentVoidResolver $silentVoidResolver, ClassMethodReturnVendorLockResolver $classMethodReturnVendorLockResolver, MagicClassMethodAnalyzer $magicClassMethodAnalyzer, ClassModifierChecker $classModifierChecker)
{
$this->silentVoidResolver = $silentVoidResolver;
$this->classMethodReturnVendorLockResolver = $classMethodReturnVendorLockResolver;
$this->reflectionResolver = $reflectionResolver;
$this->magicClassMethodAnalyzer = $magicClassMethodAnalyzer;
$this->classModifierChecker = $classModifierChecker;
}
public function getRuleDefinition() : RuleDefinition
{
@ -119,25 +119,24 @@ CODE_SAMPLE
if ($functionLike->isAbstract()) {
return \true;
}
// is not final and has only exception? possibly implemented by child
if ($this->isNotFinalAndHasExceptionOnly($functionLike)) {
return \true;
}
if ($functionLike->isProtected()) {
return !$this->isInsideFinalClass($functionLike);
return !$this->classModifierChecker->isInsideFinalClass($functionLike);
}
return $this->isInsideAbstractClass($functionLike) && $functionLike->getStmts() === [];
return $this->classModifierChecker->isInsideAbstractClass($functionLike) && $functionLike->getStmts() === [];
}
private function isInsideFinalClass(ClassMethod $classMethod) : bool
private function isNotFinalAndHasExceptionOnly(ClassMethod $classMethod) : bool
{
$classReflection = $this->reflectionResolver->resolveClassReflection($classMethod);
if (!$classReflection instanceof ClassReflection) {
if ($this->classModifierChecker->isInsideFinalClass($classMethod)) {
return \false;
}
return $classReflection->isFinalByKeyword();
}
private function isInsideAbstractClass(ClassMethod $classMethod) : bool
{
$classReflection = $this->reflectionResolver->resolveClassReflection($classMethod);
if (!$classReflection instanceof ClassReflection) {
if (\count((array) $classMethod->stmts) !== 1) {
return \false;
}
return $classReflection->isAbstract();
$onlyStmt = $classMethod->stmts[0] ?? null;
return $onlyStmt instanceof Throw_;
}
}

View File

@ -19,12 +19,12 @@ final class VersionResolver
* @api
* @var string
*/
public const PACKAGE_VERSION = '5259090faea9e744c79da1115ad299d31b649bb1';
public const PACKAGE_VERSION = '3cef752763be750ea221c5c5eb1681d27398a3d5';
/**
* @api
* @var string
*/
public const RELEASE_DATE = '2023-12-23 14:01:33';
public const RELEASE_DATE = '2023-12-23 15:26:18';
/**
* @var int
*/

View File

@ -0,0 +1,35 @@
<?php
declare (strict_types=1);
namespace Rector\Core\Reflection;
use PhpParser\Node;
use PHPStan\Reflection\ClassReflection;
final class ClassModifierChecker
{
/**
* @readonly
* @var \Rector\Core\Reflection\ReflectionResolver
*/
private $reflectionResolver;
public function __construct(\Rector\Core\Reflection\ReflectionResolver $reflectionResolver)
{
$this->reflectionResolver = $reflectionResolver;
}
public function isInsideFinalClass(Node $node) : bool
{
$classReflection = $this->reflectionResolver->resolveClassReflection($node);
if (!$classReflection instanceof ClassReflection) {
return \false;
}
return $classReflection->isFinalByKeyword();
}
public function isInsideAbstractClass(Node $node) : bool
{
$classReflection = $this->reflectionResolver->resolveClassReflection($node);
if (!$classReflection instanceof ClassReflection) {
return \false;
}
return $classReflection->isAbstract();
}
}

View File

@ -1277,6 +1277,7 @@ return array(
'Rector\\Core\\Rector\\AbstractCollectorRector' => $baseDir . '/src/Rector/AbstractCollectorRector.php',
'Rector\\Core\\Rector\\AbstractRector' => $baseDir . '/src/Rector/AbstractRector.php',
'Rector\\Core\\Rector\\AbstractScopeAwareRector' => $baseDir . '/src/Rector/AbstractScopeAwareRector.php',
'Rector\\Core\\Reflection\\ClassModifierChecker' => $baseDir . '/src/Reflection/ClassModifierChecker.php',
'Rector\\Core\\Reflection\\ClassReflectionAnalyzer' => $baseDir . '/src/Reflection/ClassReflectionAnalyzer.php',
'Rector\\Core\\Reflection\\MethodReflectionResolver' => $baseDir . '/src/Reflection/MethodReflectionResolver.php',
'Rector\\Core\\Reflection\\ReflectionResolver' => $baseDir . '/src/Reflection/ReflectionResolver.php',

View File

@ -1495,6 +1495,7 @@ class ComposerStaticInit8339caf294dd12447c06647e5d0dc118
'Rector\\Core\\Rector\\AbstractCollectorRector' => __DIR__ . '/../..' . '/src/Rector/AbstractCollectorRector.php',
'Rector\\Core\\Rector\\AbstractRector' => __DIR__ . '/../..' . '/src/Rector/AbstractRector.php',
'Rector\\Core\\Rector\\AbstractScopeAwareRector' => __DIR__ . '/../..' . '/src/Rector/AbstractScopeAwareRector.php',
'Rector\\Core\\Reflection\\ClassModifierChecker' => __DIR__ . '/../..' . '/src/Reflection/ClassModifierChecker.php',
'Rector\\Core\\Reflection\\ClassReflectionAnalyzer' => __DIR__ . '/../..' . '/src/Reflection/ClassReflectionAnalyzer.php',
'Rector\\Core\\Reflection\\MethodReflectionResolver' => __DIR__ . '/../..' . '/src/Reflection/MethodReflectionResolver.php',
'Rector\\Core\\Reflection\\ReflectionResolver' => __DIR__ . '/../..' . '/src/Reflection/ReflectionResolver.php',