mirror of
https://github.com/rectorphp/rector.git
synced 2025-02-22 02:36:52 +01:00
99 lines
2.8 KiB
PHP
99 lines
2.8 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Rector\FamilyTree\NodeAnalyzer;
|
|
|
|
use PhpParser\Node;
|
|
use PhpParser\Node\Stmt\Class_;
|
|
use PhpParser\Node\Stmt\Property;
|
|
use PHPStan\Analyser\Scope;
|
|
use PHPStan\Reflection\ClassReflection;
|
|
use Rector\Core\Exception\ShouldNotHappenException;
|
|
use Rector\Core\PhpParser\Node\BetterNodeFinder;
|
|
use Rector\FamilyTree\Reflection\FamilyRelationsAnalyzer;
|
|
use Rector\NodeCollector\NodeCollector\NodeRepository;
|
|
use Rector\NodeNameResolver\NodeNameResolver;
|
|
use Rector\NodeTypeResolver\Node\AttributeKey;
|
|
|
|
final class PropertyUsageAnalyzer
|
|
{
|
|
/**
|
|
* @var NodeNameResolver
|
|
*/
|
|
private $nodeNameResolver;
|
|
|
|
/**
|
|
* @var BetterNodeFinder
|
|
*/
|
|
private $betterNodeFinder;
|
|
|
|
/**
|
|
* @var FamilyRelationsAnalyzer
|
|
*/
|
|
private $familyRelationsAnalyzer;
|
|
|
|
/**
|
|
* @var NodeRepository
|
|
*/
|
|
private $nodeRepository;
|
|
|
|
public function __construct(
|
|
BetterNodeFinder $betterNodeFinder,
|
|
FamilyRelationsAnalyzer $familyRelationsAnalyzer,
|
|
NodeNameResolver $nodeNameResolver,
|
|
NodeRepository $nodeRepository
|
|
) {
|
|
$this->nodeNameResolver = $nodeNameResolver;
|
|
$this->betterNodeFinder = $betterNodeFinder;
|
|
$this->familyRelationsAnalyzer = $familyRelationsAnalyzer;
|
|
$this->nodeRepository = $nodeRepository;
|
|
}
|
|
|
|
public function isPropertyFetchedInChildClass(Property $property): bool
|
|
{
|
|
$className = $property->getAttribute(AttributeKey::CLASS_NAME);
|
|
if ($className === null) {
|
|
return false;
|
|
}
|
|
|
|
$scope = $property->getAttribute(AttributeKey::SCOPE);
|
|
if (! $scope instanceof Scope) {
|
|
return false;
|
|
}
|
|
|
|
$classReflection = $scope->getClassReflection();
|
|
if (! $classReflection instanceof ClassReflection) {
|
|
throw new ShouldNotHappenException();
|
|
}
|
|
|
|
if ($classReflection->isClass() && $classReflection->isFinal()) {
|
|
return false;
|
|
}
|
|
|
|
$propertyName = $this->nodeNameResolver->getName($property);
|
|
|
|
$childrenClassReflections = $this->familyRelationsAnalyzer->getChildrenOfClassReflection($classReflection);
|
|
|
|
foreach ($childrenClassReflections as $childClassReflection) {
|
|
$childClass = $this->nodeRepository->findClass($childClassReflection->getName());
|
|
if (! $childClass instanceof Class_) {
|
|
continue;
|
|
}
|
|
|
|
$isPropertyFetched = (bool) $this->betterNodeFinder->findFirst(
|
|
$childClass->stmts,
|
|
function (Node $node) use ($propertyName): bool {
|
|
return $this->nodeNameResolver->isLocalPropertyFetchNamed($node, $propertyName);
|
|
}
|
|
);
|
|
|
|
if ($isPropertyFetched) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
}
|