forked from doctrine/annotations
/
AnnotationMetadata.php
124 lines (100 loc) · 2.77 KB
/
AnnotationMetadata.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
<?php
declare(strict_types=1);
namespace Doctrine\Annotations\Metadata;
use Doctrine\Annotations\Parser\Scope;
use ReflectionClass;
use ReflectionMethod;
use ReflectionProperty;
use function array_combine;
use function array_filter;
use function array_map;
use function array_values;
final class AnnotationMetadata
{
/** @var string */
private $name;
/** @var AnnotationTarget */
private $target;
/** @var bool */
private $hasConstructor;
/** @var PropertyMetadata[] */
private $properties;
/** @var PropertyMetadata|null */
private $defaultProperty;
/**
* TODO: Validate input
*
* @param PropertyMetadata[] $properties
*/
public function __construct(
string $name,
AnnotationTarget $target,
bool $hasConstructor,
array $properties = []
) {
$this->name = $name;
$this->target = $target;
$this->hasConstructor = $hasConstructor;
$this->properties = array_combine(
array_map(static function (PropertyMetadata $property) : string {
return $property->getName();
}, $properties),
$properties
);
$this->defaultProperty = array_values(array_filter($properties, static function (PropertyMetadata $property) : bool {
return $property->isDefault();
}))[0] ?? null;
}
public function getName() : string
{
return $this->name;
}
public function getTarget() : AnnotationTarget
{
return $this->target;
}
public function hasConstructor() : bool
{
return $this->hasConstructor;
}
/**
* @return PropertyMetadata[]
*/
public function getProperties() : array
{
return $this->properties;
}
public function getDefaultProperty() : ?PropertyMetadata
{
return $this->defaultProperty;
}
/**
* @return true
*
* @throws InvalidTarget
*/
public function validateTarget(Scope $scope) : bool
{
$target = $this->getTarget();
if ($target->all()) {
return true;
}
if ($scope->isNested()) {
if (! $target->annotation()) {
throw InvalidTarget::annotation($this);
}
return true;
}
$subject = $scope->getSubject();
if ($subject instanceof ReflectionClass && ! $target->class()) {
throw InvalidTarget::class($this);
}
if ($subject instanceof ReflectionProperty && ! $target->property()) {
throw InvalidTarget::property($this);
}
if ($subject instanceof ReflectionMethod && ! $target->method()) {
throw InvalidTarget::method($this);
}
return true;
}
}