3 declare(strict_types=1);
5 namespace CuyZ\Valinor\Definition\Repository\Reflection;
7 use CuyZ\Valinor\Definition\PropertyDefinition;
8 use CuyZ\Valinor\Definition\Repository\AttributesRepository;
9 use CuyZ\Valinor\Type\Type;
10 use CuyZ\Valinor\Type\Types\NullType;
11 use CuyZ\Valinor\Type\Types\UnresolvableType;
12 use CuyZ\Valinor\Utility\Reflection\Reflection;
13 use ReflectionProperty;
16 final class ReflectionPropertyDefinitionBuilder
18 public function __construct(private AttributesRepository $attributesRepository) {}
20 public function for(ReflectionProperty $reflection, ReflectionTypeResolver $typeResolver): PropertyDefinition
22 $name = $reflection->name;
23 $signature = Reflection::signature($reflection);
24 $type = $typeResolver->resolveType($reflection);
25 $hasDefaultValue = $this->hasDefaultValue($reflection, $type);
26 $defaultValue = $reflection->getDefaultValue();
27 $isPublic = $reflection->isPublic();
28 $attributes = $this->attributesRepository->for($reflection);
31 && ! $type instanceof UnresolvableType
32 && ! $type->accepts($defaultValue)
34 $type = UnresolvableType::forInvalidPropertyDefaultValue($signature, $type, $defaultValue);
37 return new PropertyDefinition(
48 private function hasDefaultValue(ReflectionProperty $reflection, Type $type): bool
50 if ($reflection->hasType()) {
51 return $reflection->hasDefaultValue();
54 return $reflection->getDeclaringClass()->getDefaultProperties()[$reflection->name] !== null
55 || NullType::get()->matches($type);