802f242c9ddd217a8c2ca481bc5bb11772b3c542
[GitHub/WoltLab/WCF.git] /
1 <?php
2
3 declare(strict_types=1);
4
5 namespace CuyZ\Valinor\Definition\Repository\Reflection;
6
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;
14
15 /** @internal */
16 final class ReflectionPropertyDefinitionBuilder
17 {
18 public function __construct(private AttributesRepository $attributesRepository) {}
19
20 public function for(ReflectionProperty $reflection, ReflectionTypeResolver $typeResolver): PropertyDefinition
21 {
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);
29
30 if ($hasDefaultValue
31 && ! $type instanceof UnresolvableType
32 && ! $type->accepts($defaultValue)
33 ) {
34 $type = UnresolvableType::forInvalidPropertyDefaultValue($signature, $type, $defaultValue);
35 }
36
37 return new PropertyDefinition(
38 $name,
39 $signature,
40 $type,
41 $hasDefaultValue,
42 $defaultValue,
43 $isPublic,
44 $attributes
45 );
46 }
47
48 private function hasDefaultValue(ReflectionProperty $reflection, Type $type): bool
49 {
50 if ($reflection->hasType()) {
51 return $reflection->hasDefaultValue();
52 }
53
54 return $reflection->getDeclaringClass()->getDefaultProperties()[$reflection->name] !== null
55 || NullType::get()->matches($type);
56 }
57 }