Skip to content

Commit

Permalink
[Php80] Handle crash Property ReflectionEnum::$betterReflectionClass …
Browse files Browse the repository at this point in the history
…does not exist on AddParamBasedOnParentClassMethodRector on Enum usage (#4758)

* [Php80] Handle crash Property ReflectionEnum::$betterReflectionClass does not exist on AddParamBasedOnParentClassMethodRector on Enum usage

* Fixed 🎉

* Fixed 🎉

* [ci-review] Rector Rectify

* [ci-review] Rector Rectify

* clean up comment

---------

Co-authored-by: GitHub Action <actions@github.com>
  • Loading branch information
samsonasik and actions-user committed Aug 10, 2023
1 parent e9ff73f commit 0bdace5
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 36 deletions.
15 changes: 3 additions & 12 deletions packages/VendorLocker/ParentClassMethodTypeOverrideGuard.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,11 @@
namespace Rector\VendorLocker;

use PhpParser\Node\Stmt\ClassMethod;
use PHPStan\BetterReflection\Reflection\ReflectionClass;
use PHPStan\Reflection\ClassReflection;
use PHPStan\Reflection\MethodReflection;
use PHPStan\Type\Type;
use Rector\Core\Reflection\ClassReflectionAnalyzer;
use Rector\Core\Reflection\ReflectionResolver;
use Rector\Core\Util\Reflection\PrivatesAccessor;
use Rector\NodeNameResolver\NodeNameResolver;
use Rector\NodeTypeResolver\TypeComparator\TypeComparator;
use Rector\StaticTypeMapper\StaticTypeMapper;
Expand All @@ -23,7 +22,7 @@ public function __construct(
private readonly ReflectionResolver $reflectionResolver,
private readonly TypeComparator $typeComparator,
private readonly StaticTypeMapper $staticTypeMapper,
private readonly PrivatesAccessor $privatesAccessor,
private readonly ClassReflectionAnalyzer $classReflectionAnalyzer
) {
}

Expand Down Expand Up @@ -102,14 +101,6 @@ private function resolveParentClassMethod(ClassMethod $classMethod): ?MethodRefl

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'
);
/** @var ReflectionClass $betterReflectionClass */
$parentClassName = $betterReflectionClass->getParentClassName();
return $parentClassName !== null;
return $this->classReflectionAnalyzer->resolveParentClassName($classReflection) !== null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

namespace Rector\Tests\Php80\Rector\ClassMethod\AddParamBasedOnParentClassMethodRector\Fixture;

enum SkipEnum: string
{
case EN = 'en';

public static function ui(): array
{
return [
self::EN,
];
}

public static function dynamicContent(): array
{
return self::cases();
}
}
15 changes: 3 additions & 12 deletions rules/Privatization/Guard/ParentPropertyLookupGuard.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,13 @@
use PhpParser\Node\Stmt;
use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\Property;
use PHPStan\BetterReflection\Reflection\ReflectionClass;
use PHPStan\Reflection\ClassReflection;
use Rector\Core\Enum\ObjectReference;
use Rector\Core\NodeAnalyzer\PropertyFetchAnalyzer;
use Rector\Core\NodeManipulator\PropertyManipulator;
use Rector\Core\PhpParser\AstResolver;
use Rector\Core\PhpParser\Node\BetterNodeFinder;
use Rector\Core\Util\Reflection\PrivatesAccessor;
use Rector\Core\Reflection\ClassReflectionAnalyzer;
use Rector\NodeNameResolver\NodeNameResolver;

final class ParentPropertyLookupGuard
Expand All @@ -29,7 +28,7 @@ public function __construct(
private readonly PropertyFetchAnalyzer $propertyFetchAnalyzer,
private readonly AstResolver $astResolver,
private readonly PropertyManipulator $propertyManipulator,
private readonly PrivatesAccessor $privatesAccessor
private readonly ClassReflectionAnalyzer $classReflectionAnalyzer
) {
}

Expand All @@ -48,15 +47,7 @@ public function isLegal(Property $property, ?ClassReflection $classReflection):
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'
);
/** @var ReflectionClass $betterReflectionClass */
$parentClassName = $betterReflectionClass->getParentClassName();

$parentClassName = $this->classReflectionAnalyzer->resolveParentClassName($classReflection);
if ($parentClassName === null) {
return true;
}
Expand Down
15 changes: 3 additions & 12 deletions src/PhpParser/Node/Value/ValueResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
use PhpParser\Node\Scalar\MagicConst\Dir;
use PhpParser\Node\Scalar\MagicConst\File;
use PHPStan\Analyser\Scope;
use PHPStan\BetterReflection\Reflection\ReflectionClass;
use PHPStan\Reflection\ClassReflection;
use PHPStan\Reflection\ReflectionProvider;
use PHPStan\Type\Constant\ConstantArrayType;
Expand All @@ -24,8 +23,8 @@
use Rector\Core\Exception\ShouldNotHappenException;
use Rector\Core\NodeAnalyzer\ConstFetchAnalyzer;
use Rector\Core\Provider\CurrentFileProvider;
use Rector\Core\Reflection\ClassReflectionAnalyzer;
use Rector\Core\Reflection\ReflectionResolver;
use Rector\Core\Util\Reflection\PrivatesAccessor;
use Rector\NodeNameResolver\NodeNameResolver;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\NodeTypeResolver\NodeTypeResolver;
Expand All @@ -46,7 +45,7 @@ public function __construct(
private readonly ReflectionProvider $reflectionProvider,
private readonly CurrentFileProvider $currentFileProvider,
private readonly ReflectionResolver $reflectionResolver,
private readonly PrivatesAccessor $privatesAccessor
private readonly ClassReflectionAnalyzer $classReflectionAnalyzer
) {
}

Expand Down Expand Up @@ -334,16 +333,8 @@ private function resolveClassFromSelfStaticParent(ClassConstFetch $classConstFet
);
}

// 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'
);
/** @var ReflectionClass $betterReflectionClass */
$parentClassName = $betterReflectionClass->getParentClassName();

$parentClassName = $this->classReflectionAnalyzer->resolveParentClassName($classReflection);
if ($parentClassName === null) {
throw new ShouldNotHappenException();
}
Expand Down
32 changes: 32 additions & 0 deletions src/Reflection/ClassReflectionAnalyzer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

declare(strict_types=1);

namespace Rector\Core\Reflection;

use ReflectionEnum;
use PHPStan\Reflection\ClassReflection;
use Rector\Core\Util\Reflection\PrivatesAccessor;
use PHPStan\BetterReflection\Reflection\ReflectionClass;

final class ClassReflectionAnalyzer
{
public function __construct(private readonly PrivatesAccessor $privatesAccessor)
{
}

public function resolveParentClassName(ClassReflection $classReflection): ?string
{
$nativeReflection = $classReflection->getNativeReflection();
if ($nativeReflection instanceof ReflectionEnum) {
return null;
}

$betterReflectionClass = $this->privatesAccessor->getPrivateProperty(
$nativeReflection,
'betterReflectionClass'
);
/** @var ReflectionClass $betterReflectionClass */
return $betterReflectionClass->getParentClassName();
}
}

0 comments on commit 0bdace5

Please sign in to comment.