Completed
Push — master ( 6366df...fbe022 )
by Kirill
23s queued 19s
created

ContextRenderer::render()   A

Complexity

Conditions 6
Paths 6

Size

Total Lines 20
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 6
eloc 13
c 1
b 0
f 0
nc 6
nop 1
dl 0
loc 20
rs 9.2222
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
/**
15
 * @internal Context is an internal library class, please do not use it in your code.
16
 * @psalm-internal Spiral\Attributes
17
 */
18
final class ContextRenderer
19
{
20
    /**
21
     * @var string
22
     */
23
    protected const FORMAT_CLASS = 'class %s';
24
25
    /**
26
     * @var string
27
     */
28
    protected const FORMAT_ANONYMOUS_CLASS = 'object(class@anonymous): %s(%d)';
29
30
    /**
31
     * @var string
32
     */
33
    protected const FORMAT_METHOD = 'method %s::%s()';
34
35
    /**
36
     * @var string
37
     */
38
    protected const FORMAT_PROPERTY = 'property %s::$%s';
39
40
    /**
41
     * @var string
42
     */
43
    protected const FORMAT_CONSTANT = 'constant %s::%s';
44
45
    /**
46
     * @var string
47
     */
48
    protected const FORMAT_FUNCTION = 'function %s()';
49
50
    /**
51
     * @var string
52
     */
53
    protected const FORMAT_ANONYMOUS_FUNCTION = 'object(Closure): %s(%d)';
54
55
    /**
56
     * @var string
57
     */
58
    protected const FORMAT_PARAMETER = 'parameter $%s of %s';
59
60
    /**
61
     * @param \Reflector|null $reflector
62
     * @return string
63
     */
64
    public function render(?\Reflector $reflector): string
65
    {
66
        switch (true) {
67
            case $reflector instanceof \ReflectionClass:
68
                return $this->renderClassContext($reflector);
69
70
            case $reflector instanceof \ReflectionFunctionAbstract:
71
                return $this->renderCallableContext($reflector);
72
73
            case $reflector instanceof \ReflectionProperty:
74
                return $this->renderPropertyContext($reflector);
75
76
            case $reflector instanceof \ReflectionClassConstant:
77
                return $this->renderConstantContext($reflector);
78
79
            case $reflector instanceof \ReflectionParameter:
80
                return $this->renderParameterContext($reflector);
81
82
            default:
83
                return '<unknown>';
84
        }
85
    }
86
87
    /**
88
     * @param \ReflectionClass $class
89
     * @return string
90
     */
91
    public function renderClassContext(\ReflectionClass $class): string
92
    {
93
        if ($class->isAnonymous()) {
94
            return \sprintf(self::FORMAT_ANONYMOUS_CLASS, $class->getFileName(), $class->getStartLine());
95
        }
96
97
        return \sprintf(self::FORMAT_CLASS, $class->getName());
98
    }
99
100
    /**
101
     * @param \ReflectionMethod $method
102
     * @return string
103
     */
104
    public function renderMethodContext(\ReflectionMethod $method): string
105
    {
106
        $class = $method->getDeclaringClass();
107
108
        return \sprintf(self::FORMAT_METHOD, $class->getName(), $method->getName());
109
    }
110
111
    /**
112
     * @param \ReflectionFunction $fn
113
     * @return string
114
     */
115
    public function renderFunctionContext(\ReflectionFunction $fn): string
116
    {
117
        if ($fn->isClosure()) {
118
            return \sprintf(self::FORMAT_ANONYMOUS_FUNCTION, $fn->getFileName(), $fn->getStartLine());
119
        }
120
121
        return \sprintf(self::FORMAT_FUNCTION, $fn->getName());
122
    }
123
124
    /**
125
     * @param \ReflectionFunctionAbstract $function
126
     * @return string
127
     */
128
    public function renderCallableContext(\ReflectionFunctionAbstract $function): string
129
    {
130
        if ($function instanceof \ReflectionMethod) {
131
            return $this->renderMethodContext($function);
132
        }
133
134
        if ($function instanceof \ReflectionFunction) {
135
            return $this->renderFunctionContext($function);
136
        }
137
138
        // Compatibility mode
139
        return \sprintf(self::FORMAT_FUNCTION, $function->getName());
140
    }
141
142
    /**
143
     * @param \ReflectionProperty $property
144
     * @return string
145
     */
146
    public function renderPropertyContext(\ReflectionProperty $property): string
147
    {
148
        $class = $property->getDeclaringClass();
149
150
        return \sprintf(self::FORMAT_PROPERTY, $class->getName(), $property->getName());
151
    }
152
153
    /**
154
     * @param \ReflectionClassConstant $const
155
     * @return string
156
     */
157
    public function renderConstantContext(\ReflectionClassConstant $const): string
158
    {
159
        $class = $const->getDeclaringClass();
160
161
        return \sprintf(self::FORMAT_CONSTANT, $class->getName(), $const->getName());
162
    }
163
164
    /**
165
     * @param \ReflectionParameter $param
166
     * @return string
167
     */
168
    public function renderParameterContext(\ReflectionParameter $param): string
169
    {
170
        $context = $this->renderCallableContext($param->getDeclaringFunction());
171
172
        return \sprintf(self::FORMAT_PARAMETER, $param->getName(), $context);
173
    }
174
}
175