• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

valkyrjaio / valkyrja / 13047041070

30 Jan 2025 06:43AM UTC coverage: 47.621% (+0.2%) from 47.422%
13047041070

push

github

MelechMizrachi
PHPStan level 7 and 8.

168 of 1038 new or added lines in 111 files covered. (16.18%)

444 existing lines in 45 files now uncovered.

5195 of 10909 relevant lines covered (47.62%)

18.83 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

70.97
/src/Valkyrja/Reflection/Reflection.php
1
<?php
2

3
declare(strict_types=1);
4

5
/*
6
 * This file is part of the Valkyrja Framework package.
7
 *
8
 * (c) Melech Mizrachi <melechmizrachi@gmail.com>
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13

14
namespace Valkyrja\Reflection;
15

16
use Closure;
17
use ReflectionClass;
18
use ReflectionClassConstant;
19
use ReflectionFunction;
20
use ReflectionFunctionAbstract;
21
use ReflectionMethod;
22
use ReflectionNamedType;
23
use ReflectionParameter;
24
use ReflectionProperty;
25
use UnitEnum;
26
use Valkyrja\Exception\RuntimeException;
27
use Valkyrja\Reflection\Contract\Reflection as Contract;
28

29
use function class_exists;
30
use function interface_exists;
31
use function is_callable;
32
use function spl_object_id;
33

34
/**
35
 * Class Reflection.
36
 *
37
 * @author Melech Mizrachi
38
 */
39
class Reflection implements Contract
40
{
41
    /**
42
     * Cached reflection classes.
43
     *
44
     * @var array<string, ReflectionClass>
45
     */
46
    protected array $classReflections = [];
47

48
    /**
49
     * Cached reflection classes.
50
     *
51
     * @var array<string, ReflectionClassConstant>
52
     */
53
    protected array $constantReflections = [];
54

55
    /**
56
     * Cached reflection classes.
57
     *
58
     * @var array<string, ReflectionProperty>
59
     */
60
    protected array $propertyReflections = [];
61

62
    /**
63
     * Cached reflection classes.
64
     *
65
     * @var array<string, ReflectionMethod>
66
     */
67
    protected array $methodReflections = [];
68

69
    /**
70
     * Cached reflection classes.
71
     *
72
     * @var array<string, ReflectionFunction>
73
     */
74
    protected array $functionReflections = [];
75

76
    /**
77
     * @inheritDoc
78
     */
79
    public function forClass(string $class): ReflectionClass
80
    {
81
        $index = $class;
22✔
82

83
        return $this->classReflections[$index]
22✔
84
            ??= new ReflectionClass($class);
22✔
85
    }
86

87
    /**
88
     * @inheritDoc
89
     */
90
    public function forClassConstant(string $class, string $const): ReflectionClassConstant
91
    {
92
        $index = $class . $const;
2✔
93

94
        return $this->constantReflections[$index]
2✔
95
            ??= $this->forClass($class)->getReflectionConstant($const)
2✔
NEW
96
            ?: throw new RuntimeException("Failed to retrieve constant $const for $class");
×
97
    }
98

99
    /**
100
     * @inheritDoc
101
     */
102
    public function forClassProperty(string $class, string $property): ReflectionProperty
103
    {
104
        $index = $class . $property;
2✔
105

106
        return $this->propertyReflections[$index]
2✔
107
            ??= $this->forClass($class)->getProperty($property);
2✔
108
    }
109

110
    /**
111
     * @inheritDoc
112
     */
113
    public function forClassMethod(string $class, string $method): ReflectionMethod
114
    {
115
        $index = $class . $method;
6✔
116

117
        return $this->methodReflections[$index]
6✔
118
            ??= $this->forClass($class)->getMethod($method);
6✔
119
    }
120

121
    /**
122
     * @inheritDoc
123
     */
124
    public function forFunction(string $function): ReflectionFunction
125
    {
126
        $index = $function;
2✔
127

128
        return $this->functionReflections[$index]
2✔
129
            ??= new ReflectionFunction($function);
2✔
130
    }
131

132
    /**
133
     * @inheritDoc
134
     */
135
    public function forClosure(Closure $closure): ReflectionFunction
136
    {
137
        /** @phpstan-var string $index */
138
        $index = (string) spl_object_id($closure);
6✔
139

140
        return $this->functionReflections[$index]
6✔
141
            ??= new ReflectionFunction($closure);
6✔
142
    }
143

144
    /**
145
     * @inheritDoc
146
     */
147
    public function getDependencies(ReflectionFunctionAbstract $reflection): array
148
    {
149
        return $this->getDependenciesFromParameters(...$reflection->getParameters());
8✔
150
    }
151

152
    /**
153
     * @inheritDoc
154
     */
155
    public function getDependenciesFromParameters(ReflectionParameter ...$parameters): array
156
    {
157
        // Setup to find any injectable objects through the service container
158
        $dependencies = [];
8✔
159

160
        // Iterate through the method's parameters
161
        foreach ($parameters as $parameter) {
8✔
162
            $type = $parameter->getType();
×
163

164
            if (
165
                // The type is a ReflectionNamedType
166
                $type instanceof ReflectionNamedType
×
167
                // The name is valid
168
                && ($name = $type->getName())
×
169
                // The name is not a callable
170
                && ! is_callable($name)
×
171
                // The class or interface exists
172
                && (class_exists($name) || interface_exists($name))
×
173
                // and it isn't an enum
174
                && ! is_a($name, UnitEnum::class, true)
×
175
                // It's not built in
176
                && ! $type->isBuiltin()
×
177
            ) {
178
                // Set the injectable in the array
179
                $dependencies[] = $name;
×
180
            }
181
        }
182

183
        return $dependencies;
8✔
184
    }
185
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc