Skip to content

Commit

Permalink
replace ClassReflection with ReflectionProvider, use unprefixed Bette…
Browse files Browse the repository at this point in the history
…rReflection namespace
  • Loading branch information
TomasVotruba committed Feb 25, 2021
1 parent d470af7 commit ad3c3dc
Show file tree
Hide file tree
Showing 82 changed files with 970 additions and 800 deletions.
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
"nette/utils": "^3.2",
"nikic/php-parser": "^4.10.4",
"phpstan/phpdoc-parser": "^0.4.9",
"phpstan/phpstan": "^0.12.76",
"phpstan/phpstan": "dev-master",
"phpstan/phpstan-phpunit": "^0.12.17",
"psr/simple-cache": "^1.0",
"sebastian/diff": "^4.0.4",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Property;
use PHPStan\Reflection\ClassReflection;
use PHPStan\Reflection\Php\PhpPropertyReflection;
use PHPStan\Reflection\ReflectionProvider;
use Rector\Core\Exception\ShouldNotHappenException;
use Rector\DoctrineAnnotationGenerated\PhpDocNode\ConstantReferenceIdentifierRestorer;
use Rector\NodeNameResolver\NodeNameResolver;
use Rector\NodeTypeResolver\Node\AttributeKey;
use ReflectionMethod;
use ReflectionProperty;
use Symplify\PackageBuilder\Reflection\PrivatesAccessor;
use Throwable;

final class NodeAnnotationReader
Expand Down Expand Up @@ -48,23 +48,16 @@ final class NodeAnnotationReader
*/
private $reflectionProvider;

/**
* @var PrivatesAccessor
*/
private $privatesAccessor;

public function __construct(
ConstantReferenceIdentifierRestorer $constantReferenceIdentifierRestorer,
NodeNameResolver $nodeNameResolver,
Reader $reader,
ReflectionProvider $reflectionProvider,
PrivatesAccessor $privatesAccessor
ReflectionProvider $reflectionProvider
) {
$this->reader = $reader;
$this->nodeNameResolver = $nodeNameResolver;
$this->constantReferenceIdentifierRestorer = $constantReferenceIdentifierRestorer;
$this->reflectionProvider = $reflectionProvider;
$this->privatesAccessor = $privatesAccessor;
}

public function readAnnotation(Node $node, string $annotationClass): ?object
Expand Down Expand Up @@ -213,9 +206,9 @@ private function getNativePropertyReflection(Property $property): ?ReflectionPro
$classReflection = $this->reflectionProvider->getClass($className);
$propertyScope = $property->getAttribute(AttributeKey::SCOPE);
$propertyReflection = $classReflection->getProperty($propertyName, $propertyScope);

// @see https://github.com/phpstan/phpstan-src/commit/5fad625b7770b9c5beebb19ccc1a493839308fb4
return $this->privatesAccessor->getPrivateProperty($propertyReflection, 'reflection');
if ($propertyReflection instanceof PhpPropertyReflection) {
return $propertyReflection->getNativeReflection();
}
} catch (Throwable $throwable) {
// in case of PHPUnit property or just-added property
return null;
Expand Down
84 changes: 34 additions & 50 deletions packages/family-tree/src/NodeAnalyzer/ClassChildAnalyzer.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
namespace Rector\FamilyTree\NodeAnalyzer;

use PhpParser\Node\Stmt\Class_;
use PHPStan\Reflection\Php\PhpMethodReflection;
use PHPStan\Reflection\ReflectionProvider;
use Rector\NodeNameResolver\NodeNameResolver;
use Rector\NodeTypeResolver\Node\AttributeKey;
use ReflectionClass;
use ReflectionMethod;

final class ClassChildAnalyzer
{
Expand All @@ -17,31 +17,40 @@ final class ClassChildAnalyzer
*/
private $reflectionProvider;

public function __construct(ReflectionProvider $reflectionProvider)
/**
* @var NodeNameResolver
*/
private $nodeNameResolver;

public function __construct(ReflectionProvider $reflectionProvider, NodeNameResolver $nodeNameResolver)
{
$this->reflectionProvider = $reflectionProvider;
$this->nodeNameResolver = $nodeNameResolver;
}

public function hasChildClassConstructor(Class_ $class): bool
{
$childClasses = $this->getChildClasses($class);
$className = $this->nodeNameResolver->getName($class);
if ($className === null) {
return false;
}

foreach ($childClasses as $childClass) {
if (! $this->reflectionProvider->hasClass($childClass)) {
continue;
}
if (! $this->reflectionProvider->hasClass($className)) {
return false;
}

$reflectionClass = new ReflectionClass($childClass);
$constructorReflectionMethod = $reflectionClass->getConstructor();
if (! $constructorReflectionMethod instanceof ReflectionMethod) {
continue;
}
$classReflection = $this->reflectionProvider->getClass($className);

if ($constructorReflectionMethod->class !== $childClass) {
foreach ($classReflection->getAncestors() as $childClassReflection) {
$constructorReflectionMethod = $childClassReflection->getConstructor();
if (! $constructorReflectionMethod instanceof PhpMethodReflection) {
continue;
}

return true;
$methodDeclaringClassReflection = $constructorReflectionMethod->getDeclaringClass();
if ($methodDeclaringClassReflection->getName() === $childClassReflection->getName()) {
return true;
}
}

return false;
Expand All @@ -54,49 +63,24 @@ public function hasParentClassConstructor(Class_ $class): bool
return false;
}

/** @var string[] $classParents */
$classParents = (array) class_parents($className);

foreach ($classParents as $classParent) {
$parentReflectionClass = new ReflectionClass($classParent);
$constructMethodReflection = $parentReflectionClass->getConstructor();
if (! $constructMethodReflection instanceof ReflectionMethod) {
continue;
}

if ($constructMethodReflection->class !== $classParent) {
continue;
}

return true;
if (! $this->reflectionProvider->hasClass($className)) {
return false;
}

return false;
}

/**
* @return class-string[]
*/
private function getChildClasses(Class_ $class): array
{
$className = $class->getAttribute(AttributeKey::CLASS_NAME);
if ($className === null) {
return [];
}
$classReflection = $this->reflectionProvider->getClass($className);

$childClasses = [];
foreach (get_declared_classes() as $declaredClass) {
if (! is_a($declaredClass, $className, true)) {
foreach ($classReflection->getParents() as $parentClassReflections) {
$constructMethodReflection = $parentClassReflections->getConstructor();
if (! $constructMethodReflection instanceof PhpMethodReflection) {
continue;
}

if ($declaredClass === $className) {
continue;
$methodDeclaringMethodClass = $constructMethodReflection->getDeclaringClass();
if ($methodDeclaringMethodClass->getName() === $parentClassReflections->getName()) {
return true;
}

$childClasses[] = $declaredClass;
}

return $childClasses;
return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,10 @@ public function isPropertyFetchedInChildClass(Property $property): bool

$propertyName = $this->nodeNameResolver->getName($property);

$childrenClassNames = $this->familyRelationsAnalyzer->getChildrenOfClass($className);
foreach ($childrenClassNames as $childClassName) {
$childClass = $this->nodeRepository->findClass($childClassName);
if (! $childClass instanceof Class_) {
$childrenClassReflections = $this->familyRelationsAnalyzer->getChildrenOfClass($className);
foreach ($childrenClassReflections as $childClassReflection) {
$childClass = $this->nodeRepository->findClass($childClassReflection->getName());
if ($childClass === null) {
continue;
}

Expand Down
31 changes: 16 additions & 15 deletions packages/family-tree/src/Reflection/FamilyRelationsAnalyzer.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,28 @@

namespace Rector\FamilyTree\Reflection;

use PHPStan\Reflection\ClassReflection;
use PHPStan\Reflection\ReflectionProvider;

final class FamilyRelationsAnalyzer
{
/**
* @return class-string[]
* @var ReflectionProvider
*/
public function getChildrenOfClass(string $parentClass): array
{
$childrenClasses = [];
foreach (get_declared_classes() as $declaredClass) {
if ($declaredClass === $parentClass) {
continue;
}

if (! is_a($declaredClass, $parentClass, true)) {
continue;
}
private $reflectionProvider;

$childrenClasses[] = $declaredClass;
}
public function __construct(ReflectionProvider $reflectionProvider)
{
$this->reflectionProvider = $reflectionProvider;
}

return $childrenClasses;
/**
* @return ClassReflection[]
*/
public function getChildrenOfClass(string $className): array
{
$classReflection = $this->reflectionProvider->getClass($className);
return $classReflection->getAncestors();
}

public function isParentClass(string $class): bool
Expand Down
11 changes: 10 additions & 1 deletion packages/node-collector/src/NodeCollector/NodeRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -663,7 +663,16 @@ private function collectArray(Array_ $array): void
return;
}

if (! $arrayCallable->isExistingMethod()) {
if (! $this->reflectionProvider->hasClass($arrayCallable->getClass())) {
return;
}

$classReflection = $this->reflectionProvider->getClass($arrayCallable->getClass());
if ($classReflection->isClass()) {
return;
}

if (! $classReflection->hasMethod($arrayCallable->getMethod())) {
return;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@

use PhpParser\Node;
use PhpParser\Node\Expr\ClassConstFetch;
use PHPStan\Reflection\ReflectionProvider;
use PHPStan\Type\ObjectType;
use PHPStan\Type\Type;
use PHPStan\Type\TypeUtils;
use PHPStan\Type\UnionType;
use Rector\NodeNameResolver\NodeNameResolver;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\NodeTypeResolver\NodeTypeResolver;
use ReflectionClass;

final class ParsedClassConstFetchNodeCollector
{
Expand All @@ -32,9 +32,15 @@ final class ParsedClassConstFetchNodeCollector
*/
private $nodeTypeResolver;

public function __construct(NodeNameResolver $nodeNameResolver)
/**
* @var ReflectionProvider
*/
private $reflectionProvider;

public function __construct(NodeNameResolver $nodeNameResolver, ReflectionProvider $reflectionProvider)
{
$this->nodeNameResolver = $nodeNameResolver;
$this->reflectionProvider = $reflectionProvider;
}

/**
Expand Down Expand Up @@ -137,14 +143,16 @@ private function matchClassTypeThatContainsConstant(Type $type, string $constant
*/
private function getConstantsDefinedInClass(string $className): array
{
$reflectionClass = new ReflectionClass($className);
if (! $this->reflectionProvider->hasClass($className)) {
return [];
}

$constants = $reflectionClass->getConstants();
$classReflection = $this->reflectionProvider->getClass($className);
$nativeClassReflection = $classReflection->getNativeReflection();
$constants = $nativeClassReflection->getConstants();

$currentClassConstants = array_keys($constants);
$parentClassReflection = $reflectionClass->getParentClass();

if (! $parentClassReflection) {
if ($classReflection->getParentClass() !== false) {
return $currentClassConstants;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
use Rector\NodeNameResolver\NodeNameResolver;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\NodeTypeResolver\NodeTypeResolver;
use ReflectionMethod;

final class MethodReflectionProvider
{
Expand Down Expand Up @@ -70,7 +69,7 @@ public function provideParameterTypesFromMethodReflection(MethodReflection $meth
return $parameterTypes;
}

public function provideByMethodCall(MethodCall $methodCall): ?ReflectionMethod
public function provideByMethodCall(MethodCall $methodCall): ?MethodReflection
{
$className = $methodCall->getAttribute(AttributeKey::CLASS_NAME);
if (! is_string($className)) {
Expand All @@ -82,11 +81,16 @@ public function provideByMethodCall(MethodCall $methodCall): ?ReflectionMethod
return null;
}

if (! method_exists($className, $methodName)) {
if (! $this->reflectionProvider->hasClass($className)) {
return null;
}

return new ReflectionMethod($className, $methodName);
$classReflection = $this->reflectionProvider->getClass($className);
if (! $classReflection->hasMethod($methodName)) {
return null;
}

return $classReflection->getNativeMethod($methodName);
}

public function provideByClassAndMethodName(string $class, string $method, Scope $scope): ?MethodReflection
Expand Down Expand Up @@ -174,16 +178,24 @@ public function getParameterReflectionsFromMethodReflection(MethodReflection $me
public function provideParameterNamesByNew(New_ $new): array
{
$objectType = $this->nodeTypeResolver->resolve($new->class);

$classes = TypeUtils::getDirectClassNames($objectType);

$parameterNames = [];

foreach ($classes as $class) {
if (! method_exists($class, MethodName::CONSTRUCT)) {
if (! $this->reflectionProvider->hasClass($class)) {
continue;
}

$methodReflection = new ReflectionMethod($class, MethodName::CONSTRUCT);
$classReflection = $this->reflectionProvider->getClass($class);
if (! $classReflection->hasMethod(MethodName::CONSTRUCT)) {
continue;
}

$nativeClassReflection = $classReflection->getNativeReflection();
$methodReflection = $nativeClassReflection->getMethod(MethodName::CONSTRUCT);

foreach ($methodReflection->getParameters() as $reflectionParameter) {
$parameterNames[] = $reflectionParameter->name;
}
Expand Down
Loading

0 comments on commit ad3c3dc

Please sign in to comment.