recursivity check
parent
6537a2db81
commit
94f5bcb2a1
@ -0,0 +1,74 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Kartierung\Analyze;
|
||||
|
||||
use Kartierung\Analyze\Exception\InvalidEntity;
|
||||
use Kartierung\Attribute\ListOf;
|
||||
use ReflectionClass;
|
||||
use ReflectionException;
|
||||
|
||||
readonly class RecursionCheck
|
||||
{
|
||||
/**
|
||||
* @param class-string<object> $fqcn
|
||||
*/
|
||||
public function __construct(
|
||||
private string $fqcn
|
||||
) {}
|
||||
|
||||
public function check(): void
|
||||
{
|
||||
/** @var list<class-string<object>> $seenClasses */
|
||||
$seenClasses = [$this->fqcn];
|
||||
$toProcess = [...$this->declaredListTypes($this->fqcn)];
|
||||
|
||||
while (!empty($toProcess)) {
|
||||
$current = array_pop($toProcess);
|
||||
|
||||
try {
|
||||
// is there a better workaround?
|
||||
new ReflectionClass($current);
|
||||
|
||||
if (in_array($current, $seenClasses)) {
|
||||
throw new InvalidEntity(
|
||||
"Entity $this->fqcn declares a recursive mapping. This is not supported."
|
||||
);
|
||||
}
|
||||
|
||||
$seenClasses[] = $current;
|
||||
} catch (ReflectionException) {
|
||||
// $current does not reference a class, skip
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param class-string<object> $fqcn
|
||||
* @return list<class-string<object>>
|
||||
*/
|
||||
private function declaredListTypes(string $fqcn): array
|
||||
{
|
||||
$params = (new ReflectionClass($fqcn))->getConstructor()?->getParameters();
|
||||
|
||||
if ($params === null) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$result = [];
|
||||
|
||||
foreach ($params as $param) {
|
||||
$listAttr = $param->getAttributes(ListOf::class);
|
||||
if (empty($listAttr)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/** @var ListOf $inst */
|
||||
$inst = $listAttr[0]->newInstance();
|
||||
$result[] = $inst->entitiyFqcn;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Kartierung\Analyze;
|
||||
|
||||
use Kartierung\Attribute\Id;
|
||||
use Kartierung\Attribute\ListOf;
|
||||
|
||||
class EntityWithInfiniteRecursion
|
||||
{
|
||||
public function __construct(
|
||||
#[Id]
|
||||
public int $id,
|
||||
#[ListOf(self::class)]
|
||||
public array $children
|
||||
) {}
|
||||
}
|
||||
Loading…
Reference in New Issue