mirror of https://github.com/rectorphp/rector.git
Updated Rector to commit 493e4f89c9f9a033668301cd4eee4df7e77df0cb
493e4f89c9
Skip code changes on unresolvable/unknown classes (#4619)
This commit is contained in:
parent
60a90b19ce
commit
4cf14d6438
|
@ -0,0 +1,8 @@
|
|||
<?php
|
||||
|
||||
declare (strict_types=1);
|
||||
namespace Rector\VendorLocker\Exception;
|
||||
|
||||
final class UnresolvableClassException extends \Exception
|
||||
{
|
||||
}
|
|
@ -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) {
|
||||
|
|
|
@ -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');
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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');
|
||||
|
|
|
@ -22,4 +22,4 @@ if (PHP_VERSION_ID < 50600) {
|
|||
|
||||
require_once __DIR__ . '/composer/autoload_real.php';
|
||||
|
||||
return ComposerAutoloaderIniteb2977d07722edfb3f92b84a842954d4::getLoader();
|
||||
return ComposerAutoloaderInitd60879e03e03619f65217abab90852fe::getLoader();
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue