Passed
Pull Request — master (#405)
by Kirill
08:21 queued 04:03
created

AttributeReader::getParameterMetadata()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 2
eloc 3
c 2
b 0
f 0
nc 2
nop 2
dl 0
loc 6
rs 10
1
<?php
2
3
/**
4
 * This file is part of Spiral Framework package.
5
 *
6
 * For the full copyright and license information, please view the LICENSE
7
 * file that was distributed with this source code.
8
 */
9
10
declare(strict_types=1);
11
12
namespace Spiral\Attributes\Internal;
13
14
use Spiral\Attributes\Exception\SemanticAttributeException;
15
use Spiral\Attributes\Internal\Instantiator\Facade;
16
use Spiral\Attributes\Internal\Instantiator\InstantiatorInterface;
17
use Spiral\Attributes\Reader;
18
19
/**
20
 * @internal AttributeReader is an internal library class, please do not use it in your code.
21
 * @psalm-internal Spiral\Attributes
22
 */
23
abstract class AttributeReader extends Reader
24
{
25
    /**
26
     * @var ContextRenderer
27
     */
28
    protected $renderer;
29
    /**
30
     * @var InstantiatorInterface
31
     */
32
    private $instantiator;
33
34
    /**
35
     * @param InstantiatorInterface|null $instantiator
36
     */
37
    public function __construct(InstantiatorInterface $instantiator = null)
38
    {
39
        $this->instantiator = $instantiator ?? new Facade($this);
40
        $this->renderer = new ContextRenderer();
41
    }
42
43
    /**
44
     * {@inheritDoc}
45
     * @throws \Throwable
46
     */
47
    public function getClassMetadata(\ReflectionClass $class, string $name = null): iterable
48
    {
49
        $attributes = $this->getClassAttributes($class, $name);
50
51
        foreach ($attributes as $attribute => $arguments) {
52
            yield $this->instantiator->instantiate($attribute, $arguments, $class);
53
        }
54
    }
55
56
    /**
57
     * {@inheritDoc}
58
     * @throws \Throwable
59
     */
60
    public function getFunctionMetadata(\ReflectionFunctionAbstract $function, string $name = null): iterable
61
    {
62
        $attributes = $this->getFunctionAttributes($function, $name);
63
64
        foreach ($attributes as $attribute => $arguments) {
65
            yield $this->instantiator->instantiate($attribute, $arguments, $function);
66
        }
67
    }
68
69
    /**
70
     * {@inheritDoc}
71
     * @throws \Throwable
72
     */
73
    public function getPropertyMetadata(\ReflectionProperty $property, string $name = null): iterable
74
    {
75
        $attributes = $this->getPropertyAttributes($property, $name);
76
77
        foreach ($attributes as $attribute => $arguments) {
78
            yield $this->instantiator->instantiate($attribute, $arguments, $property);
79
        }
80
    }
81
82
    /**
83
     * {@inheritDoc}
84
     * @throws \Throwable
85
     */
86
    public function getConstantMetadata(\ReflectionClassConstant $constant, string $name = null): iterable
87
    {
88
        $attributes = $this->getConstantAttributes($constant, $name);
89
90
        foreach ($attributes as $attribute => $arguments) {
91
            yield $this->instantiator->instantiate($attribute, $arguments, $constant);
92
        }
93
    }
94
95
    /**
96
     * {@inheritDoc}
97
     * @throws \Throwable
98
     */
99
    public function getParameterMetadata(\ReflectionParameter $parameter, string $name = null): iterable
100
    {
101
        $attributes = $this->getParameterAttributes($parameter, $name);
102
103
        foreach ($attributes as $attribute => $arguments) {
104
            yield $this->instantiator->instantiate($attribute, $arguments, $parameter);
105
        }
106
    }
107
108
    /**
109
     * @param string $class
110
     * @param \Reflector $context
111
     */
112
    protected function assertClassExists(string $class, \Reflector $context): void
113
    {
114
        if (!\class_exists($class)) {
115
            $message = \vsprintf('The metadata class "%s" in %s was not found', [
116
                $class,
117
                $this->renderer->render($context),
118
            ]);
119
120
            throw new SemanticAttributeException($message);
121
        }
122
    }
123
124
    /**
125
     * @param \ReflectionClass $class
126
     * @param string|null $name
127
     * @return iterable<\ReflectionClass, array>
128
     */
129
    abstract protected function getClassAttributes(\ReflectionClass $class, ?string $name): iterable;
130
131
    /**
132
     * @param \ReflectionFunctionAbstract $function
133
     * @param string|null $name
134
     * @return iterable<\ReflectionClass, array>
135
     */
136
    abstract protected function getFunctionAttributes(\ReflectionFunctionAbstract $function, ?string $name): iterable;
137
138
    /**
139
     * @param \ReflectionProperty $property
140
     * @param string|null $name
141
     * @return iterable<\ReflectionClass, array>
142
     */
143
    abstract protected function getPropertyAttributes(\ReflectionProperty $property, ?string $name): iterable;
144
145
    /**
146
     * @param \ReflectionClassConstant $const
147
     * @param string|null $name
148
     * @return iterable<\ReflectionClass, array>
149
     */
150
    abstract protected function getConstantAttributes(\ReflectionClassConstant $const, ?string $name): iterable;
151
152
    /**
153
     * @param \ReflectionParameter $param
154
     * @param string|null $name
155
     * @return iterable<\ReflectionClass, array>
156
     */
157
    abstract protected function getParameterAttributes(\ReflectionParameter $param, ?string $name): iterable;
158
}
159