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; } }