ReflectionMethod::setObject()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
eloc 2
c 0
b 0
f 0
dl 0
loc 4
ccs 3
cts 3
cp 1
rs 10
cc 1
nc 1
nop 2
crap 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Ray\Aop;
6
7
use Ray\ServiceLocator\ServiceLocator;
8
9
use function array_key_exists;
10
use function assert;
11
use function class_exists;
12
use function is_object;
13
use function is_string;
14
use function property_exists;
15
use function unserialize;
16
17
final class ReflectionMethod extends \ReflectionMethod implements Reader
18
{
19
    /** @var ?WeavedInterface */
20
    private $object;
21
22
    /** @var string */
23
    private $method = '';
24
25
    /**
26 3
     * Set dependencies
27
     */
28 3
    public function setObject(WeavedInterface $object, \ReflectionMethod $method): void
29 3
    {
30 3
        $this->object = $object;
31
        $this->method = $method->name;
32
    }
33
34
    public function getDeclaringClass(): ReflectionClass
35 2
    {
36
        if (! is_object($this->object)) {
37 2
            assert(class_exists($this->class));
38 2
39
            return new ReflectionClass($this->class);
40
        }
41 2
42 2
        $parencClass = (new \ReflectionClass($this->object))->getParentClass();
43 2
        assert($parencClass instanceof \ReflectionClass);
44
        $originalClass = $parencClass->name;
45 2
        assert(class_exists($originalClass));
46
        $class = new ReflectionClass($originalClass);
47
        $class->setObject($this->object);
48
49
        return $class;
50
    }
51 2
52
    /**
53
     * {@inheritdoc}
54 2
     *
55 2
     * @psalm-suppress NoInterfaceProperties
56 2
     */
57 1
    public function getAnnotations(): array
58
    {
59
        $object = $this->object;
60 1
        if (is_object($object) && property_exists($object, 'methodAnnotations') && is_string($object->methodAnnotations)) {
61
            return $this->getCachedAnnotations($object->methodAnnotations);
62
        }
63
64
        assert(class_exists($this->class));
65
        /** @var list<object> $annotations */
66 2
        $annotations = ServiceLocator::getReader()->getMethodAnnotations(new \ReflectionMethod($this->class, $this->name));
67
68 2
        return $annotations;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $annotations returns the type Ray\Aop\list which is incompatible with the type-hinted return array.
Loading history...
69 2
    }
70 1
71 1
    /**
72
     * @param class-string<T> $annotationName
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string<T> at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string<T>.
Loading history...
73
     *
74
     * @return T|null
75 1
     *
76
     * @template T of object
77
     *
78
     * @psalm-suppress MoreSpecificImplementedParamType
79
     */
80
    public function getAnnotation(string $annotationName)
81
    {
82
        $annotations = $this->getAnnotations();
83
        foreach ($annotations as $annotation) {
84
            if ($annotation instanceof $annotationName) {
85
                return $annotation;
86
            }
87
        }
88
89
        return null;
90
    }
91
92
    /**
93
     * @return list<object>
0 ignored issues
show
Bug introduced by
The type Ray\Aop\list was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
94
     */
95
    private function getCachedAnnotations(string $methodAnnotations): array
96
    {
97
        /** @var array<string, list<object>> $annotations */
98
        $annotations = unserialize($methodAnnotations, ['allowed_classes' => true]);
99
        if (array_key_exists($this->method, $annotations)) {
100
            return $annotations[$this->method];
101
        }
102
103
        return [];
0 ignored issues
show
Bug Best Practice introduced by
The expression return array() returns the type array which is incompatible with the documented return type Ray\Aop\list.
Loading history...
104
    }
105
}
106