Updated Rector to commit 493e4f89c9f9a033668301cd4eee4df7e77df0cb

493e4f89c9 Skip code changes on unresolvable/unknown classes (#4619)
This commit is contained in:
Tomas Votruba 2023-08-07 10:55:35 +00:00
parent 60a90b19ce
commit 4cf14d6438
15 changed files with 79 additions and 25 deletions

View File

@ -0,0 +1,8 @@
<?php
declare (strict_types=1);
namespace Rector\VendorLocker\Exception;
final class UnresolvableClassException extends \Exception
{
}

View File

@ -7,10 +7,13 @@ use PhpParser\Node\Stmt\ClassMethod;
use PHPStan\Reflection\ClassReflection;
use PHPStan\Reflection\MethodReflection;
use PHPStan\Type\Type;
use Rector\Core\Exception\ShouldNotHappenException;
use Rector\Core\Reflection\ReflectionResolver;
use Rector\Core\Util\Reflection\PrivatesAccessor;
use Rector\NodeNameResolver\NodeNameResolver;
use Rector\NodeTypeResolver\TypeComparator\TypeComparator;
use Rector\StaticTypeMapper\StaticTypeMapper;
use Rector\VendorLocker\Exception\UnresolvableClassException;
final class ParentClassMethodTypeOverrideGuard
{
/**
@ -33,31 +36,62 @@ final class ParentClassMethodTypeOverrideGuard
* @var \Rector\StaticTypeMapper\StaticTypeMapper
*/
private $staticTypeMapper;
public function __construct(NodeNameResolver $nodeNameResolver, ReflectionResolver $reflectionResolver, TypeComparator $typeComparator, StaticTypeMapper $staticTypeMapper)
/**
* @readonly
* @var \Rector\Core\Util\Reflection\PrivatesAccessor
*/
private $privatesAccessor;
public function __construct(NodeNameResolver $nodeNameResolver, ReflectionResolver $reflectionResolver, TypeComparator $typeComparator, StaticTypeMapper $staticTypeMapper, PrivatesAccessor $privatesAccessor)
{
$this->nodeNameResolver = $nodeNameResolver;
$this->reflectionResolver = $reflectionResolver;
$this->typeComparator = $typeComparator;
$this->staticTypeMapper = $staticTypeMapper;
$this->privatesAccessor = $privatesAccessor;
}
public function hasParentClassMethod(ClassMethod $classMethod) : bool
public function hasParentClassMethod(ClassMethod $classMethod) : ?bool
{
return $this->getParentClassMethod($classMethod) instanceof MethodReflection;
try {
$parentClassMethod = $this->resolveParentClassMethod($classMethod);
return $parentClassMethod instanceof MethodReflection;
} catch (UnresolvableClassException $exception) {
// we don't know all involved parents.
return null;
}
}
public function getParentClassMethod(ClassMethod $classMethod) : ?MethodReflection
{
try {
$parentClassMethod = $this->resolveParentClassMethod($classMethod);
return $parentClassMethod;
} catch (UnresolvableClassException $exception) {
// we don't know all involved parents.
throw new ShouldNotHappenException('Unable to resolve involved class. You are likely missing hasParentClassMethod() before calling getParentClassMethod().');
}
}
/**
* @throws UnresolvableClassException
*/
private function resolveParentClassMethod(ClassMethod $classMethod) : ?MethodReflection
{
$classReflection = $this->reflectionResolver->resolveClassReflection($classMethod);
if (!$classReflection instanceof ClassReflection) {
return null;
// we can't resolve the class, so we don't know.
throw new UnresolvableClassException();
}
/** @var string $methodName */
$methodName = $this->nodeNameResolver->getName($classMethod);
$parentClassReflection = $classReflection->getParentClass();
while ($parentClassReflection instanceof ClassReflection) {
$currentClassReflection = $classReflection;
while ($this->hasClassParent($currentClassReflection)) {
$parentClassReflection = $currentClassReflection->getParentClass();
if (!$parentClassReflection instanceof ClassReflection) {
// per AST we have a parent class, but our reflection classes are not able to load its class definition/signature
throw new UnresolvableClassException();
}
if ($parentClassReflection->hasNativeMethod($methodName)) {
return $parentClassReflection->getNativeMethod($methodName);
}
$parentClassReflection = $parentClassReflection->getParentClass();
$currentClassReflection = $parentClassReflection;
}
foreach ($classReflection->getInterfaces() as $interfaceReflection) {
if (!$interfaceReflection->hasNativeMethod($methodName)) {
@ -67,6 +101,14 @@ final class ParentClassMethodTypeOverrideGuard
}
return null;
}
private function hasClassParent(ClassReflection $classReflection) : bool
{
// XXX rework this hack, after https://github.com/phpstan/phpstan-src/pull/2563 landed
$nativeReflection = $classReflection->getNativeReflection();
$betterReflectionClass = $this->privatesAccessor->getPrivateProperty($nativeReflection, 'betterReflectionClass');
$parentClassName = $this->privatesAccessor->getPrivateProperty($betterReflectionClass, 'parentClassName');
return $parentClassName !== null;
}
public function shouldSkipReturnTypeChange(ClassMethod $classMethod, Type $parentType) : bool
{
if ($classMethod->returnType === null) {

View File

@ -72,6 +72,7 @@ final class ParentPropertyLookupGuard
if ($this->propertyManipulator->isUsedByTrait($classReflection, $propertyName)) {
return \false;
}
// XXX rework this hack, after https://github.com/phpstan/phpstan-src/pull/2563 landed
$nativeReflection = $classReflection->getNativeReflection();
$betterReflectionClass = $this->privatesAccessor->getPrivateProperty($nativeReflection, 'betterReflectionClass');
$parentClassName = $this->privatesAccessor->getPrivateProperty($betterReflectionClass, 'parentClassName');

View File

@ -121,7 +121,7 @@ CODE_SAMPLE
if (!$paramType instanceof Node) {
continue;
}
if ($this->parentClassMethodTypeOverrideGuard->hasParentClassMethod($node)) {
if ($this->parentClassMethodTypeOverrideGuard->hasParentClassMethod($node) !== \false) {
return null;
}
$param->type = $paramType;

View File

@ -135,7 +135,7 @@ CODE_SAMPLE
if ($classMethod->params === []) {
return \true;
}
return $this->parentClassMethodTypeOverrideGuard->hasParentClassMethod($classMethod);
return $this->parentClassMethodTypeOverrideGuard->hasParentClassMethod($classMethod) !== \false;
}
/**
* @param \PhpParser\Node\Identifier|\PhpParser\Node\Name|\PhpParser\Node\NullableType|\PhpParser\Node\UnionType|\PhpParser\Node\ComplexType $paramType

View File

@ -177,7 +177,7 @@ CODE_SAMPLE
return \true;
}
if ($node instanceof ClassMethod) {
if ($this->parentClassMethodTypeOverrideGuard->hasParentClassMethod($node)) {
if ($this->parentClassMethodTypeOverrideGuard->hasParentClassMethod($node) !== \false) {
return \true;
}
if ($node->isMagic()) {

View File

@ -70,7 +70,7 @@ CODE_SAMPLE
public function refactor(Node $node) : ?Node
{
$hasChanged = \false;
if ($node instanceof ClassMethod && $this->parentClassMethodTypeOverrideGuard->hasParentClassMethod($node)) {
if ($node instanceof ClassMethod && $this->parentClassMethodTypeOverrideGuard->hasParentClassMethod($node) !== \false) {
return null;
}
foreach ($node->getParams() as $param) {

View File

@ -71,7 +71,7 @@ CODE_SAMPLE
*/
public function refactor(Node $node) : ?Node
{
if ($node instanceof ClassMethod && $this->parentClassMethodTypeOverrideGuard->hasParentClassMethod($node)) {
if ($node instanceof ClassMethod && $this->parentClassMethodTypeOverrideGuard->hasParentClassMethod($node) !== \false) {
return null;
}
$hasChanged = \false;

View File

@ -108,7 +108,7 @@ CODE_SAMPLE
if ($classMethod->isAbstract()) {
return null;
}
if ($this->parentClassMethodTypeOverrideGuard->hasParentClassMethod($classMethod)) {
if ($this->parentClassMethodTypeOverrideGuard->hasParentClassMethod($classMethod) !== \false) {
return null;
}
$originalParamType = $this->resolveParamOriginalType($param, $scope);

View File

@ -19,12 +19,12 @@ final class VersionResolver
* @api
* @var string
*/
public const PACKAGE_VERSION = '73112a253e40199adda14259717e4d8c630c97d1';
public const PACKAGE_VERSION = '493e4f89c9f9a033668301cd4eee4df7e77df0cb';
/**
* @api
* @var string
*/
public const RELEASE_DATE = '2023-08-07 16:58:34';
public const RELEASE_DATE = '2023-08-07 17:52:00';
/**
* @var int
*/

View File

@ -311,6 +311,7 @@ final class ValueResolver
if (!$classReflection->isClass()) {
throw new ShouldNotHappenException('Complete class parent node for to class const fetch, so "parent" references is resolvable to lookup parent class');
}
// XXX rework this hack, after https://github.com/phpstan/phpstan-src/pull/2563 landed
// ensure parent class name still resolved even not autoloaded
$nativeReflection = $classReflection->getNativeReflection();
$betterReflectionClass = $this->privatesAccessor->getPrivateProperty($nativeReflection, 'betterReflectionClass');

2
vendor/autoload.php vendored
View File

@ -22,4 +22,4 @@ if (PHP_VERSION_ID < 50600) {
require_once __DIR__ . '/composer/autoload_real.php';
return ComposerAutoloaderIniteb2977d07722edfb3f92b84a842954d4::getLoader();
return ComposerAutoloaderInitd60879e03e03619f65217abab90852fe::getLoader();

View File

@ -2725,6 +2725,7 @@ return array(
'Rector\\TypeDeclaration\\ValueObject\\AssignToVariable' => $baseDir . '/rules/TypeDeclaration/ValueObject/AssignToVariable.php',
'Rector\\TypeDeclaration\\ValueObject\\NestedArrayType' => $baseDir . '/rules/TypeDeclaration/ValueObject/NestedArrayType.php',
'Rector\\ValueObject\\ClassMethodWillChangeReturnType' => $vendorDir . '/rector/rector-downgrade-php/src/ValueObject/ClassMethodWillChangeReturnType.php',
'Rector\\VendorLocker\\Exception\\UnresolvableClassException' => $baseDir . '/packages/VendorLocker/Exception/UnresolvableClassException.php',
'Rector\\VendorLocker\\NodeVendorLocker\\ClassMethodParamVendorLockResolver' => $baseDir . '/packages/VendorLocker/NodeVendorLocker/ClassMethodParamVendorLockResolver.php',
'Rector\\VendorLocker\\NodeVendorLocker\\ClassMethodReturnTypeOverrideGuard' => $baseDir . '/packages/VendorLocker/NodeVendorLocker/ClassMethodReturnTypeOverrideGuard.php',
'Rector\\VendorLocker\\NodeVendorLocker\\ClassMethodReturnVendorLockResolver' => $baseDir . '/packages/VendorLocker/NodeVendorLocker/ClassMethodReturnVendorLockResolver.php',

View File

@ -2,7 +2,7 @@
// autoload_real.php @generated by Composer
class ComposerAutoloaderIniteb2977d07722edfb3f92b84a842954d4
class ComposerAutoloaderInitd60879e03e03619f65217abab90852fe
{
private static $loader;
@ -22,17 +22,17 @@ class ComposerAutoloaderIniteb2977d07722edfb3f92b84a842954d4
return self::$loader;
}
spl_autoload_register(array('ComposerAutoloaderIniteb2977d07722edfb3f92b84a842954d4', 'loadClassLoader'), true, true);
spl_autoload_register(array('ComposerAutoloaderInitd60879e03e03619f65217abab90852fe', 'loadClassLoader'), true, true);
self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__));
spl_autoload_unregister(array('ComposerAutoloaderIniteb2977d07722edfb3f92b84a842954d4', 'loadClassLoader'));
spl_autoload_unregister(array('ComposerAutoloaderInitd60879e03e03619f65217abab90852fe', 'loadClassLoader'));
require __DIR__ . '/autoload_static.php';
call_user_func(\Composer\Autoload\ComposerStaticIniteb2977d07722edfb3f92b84a842954d4::getInitializer($loader));
call_user_func(\Composer\Autoload\ComposerStaticInitd60879e03e03619f65217abab90852fe::getInitializer($loader));
$loader->setClassMapAuthoritative(true);
$loader->register(true);
$filesToLoad = \Composer\Autoload\ComposerStaticIniteb2977d07722edfb3f92b84a842954d4::$files;
$filesToLoad = \Composer\Autoload\ComposerStaticInitd60879e03e03619f65217abab90852fe::$files;
$requireFile = \Closure::bind(static function ($fileIdentifier, $file) {
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
$GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;

View File

@ -4,7 +4,7 @@
namespace Composer\Autoload;
class ComposerStaticIniteb2977d07722edfb3f92b84a842954d4
class ComposerStaticInitd60879e03e03619f65217abab90852fe
{
public static $files = array (
'ad155f8f1cf0d418fe49e248db8c661b' => __DIR__ . '/..' . '/react/promise/src/functions_include.php',
@ -2979,6 +2979,7 @@ class ComposerStaticIniteb2977d07722edfb3f92b84a842954d4
'Rector\\TypeDeclaration\\ValueObject\\AssignToVariable' => __DIR__ . '/../..' . '/rules/TypeDeclaration/ValueObject/AssignToVariable.php',
'Rector\\TypeDeclaration\\ValueObject\\NestedArrayType' => __DIR__ . '/../..' . '/rules/TypeDeclaration/ValueObject/NestedArrayType.php',
'Rector\\ValueObject\\ClassMethodWillChangeReturnType' => __DIR__ . '/..' . '/rector/rector-downgrade-php/src/ValueObject/ClassMethodWillChangeReturnType.php',
'Rector\\VendorLocker\\Exception\\UnresolvableClassException' => __DIR__ . '/../..' . '/packages/VendorLocker/Exception/UnresolvableClassException.php',
'Rector\\VendorLocker\\NodeVendorLocker\\ClassMethodParamVendorLockResolver' => __DIR__ . '/../..' . '/packages/VendorLocker/NodeVendorLocker/ClassMethodParamVendorLockResolver.php',
'Rector\\VendorLocker\\NodeVendorLocker\\ClassMethodReturnTypeOverrideGuard' => __DIR__ . '/../..' . '/packages/VendorLocker/NodeVendorLocker/ClassMethodReturnTypeOverrideGuard.php',
'Rector\\VendorLocker\\NodeVendorLocker\\ClassMethodReturnVendorLockResolver' => __DIR__ . '/../..' . '/packages/VendorLocker/NodeVendorLocker/ClassMethodReturnVendorLockResolver.php',
@ -3010,9 +3011,9 @@ class ComposerStaticIniteb2977d07722edfb3f92b84a842954d4
public static function getInitializer(ClassLoader $loader)
{
return \Closure::bind(function () use ($loader) {
$loader->prefixLengthsPsr4 = ComposerStaticIniteb2977d07722edfb3f92b84a842954d4::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticIniteb2977d07722edfb3f92b84a842954d4::$prefixDirsPsr4;
$loader->classMap = ComposerStaticIniteb2977d07722edfb3f92b84a842954d4::$classMap;
$loader->prefixLengthsPsr4 = ComposerStaticInitd60879e03e03619f65217abab90852fe::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInitd60879e03e03619f65217abab90852fe::$prefixDirsPsr4;
$loader->classMap = ComposerStaticInitd60879e03e03619f65217abab90852fe::$classMap;
}, null, ClassLoader::class);
}