Test Failed
Pull Request — master (#1111)
by Aleksei
10:51
created

Target::getCallable()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
eloc 1
c 0
b 0
f 0
dl 0
loc 3
ccs 0
cts 0
cp 0
rs 10
cc 1
nc 1
nop 0
crap 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Spiral\Interceptors\Context;
6
7
/**
8
 * @template-covariant TController of object|null
9
 * @implements TargetInterface<TController>
10
 */
11
final class Target implements TargetInterface
12
{
13
    /**
14
     * @param list<string> $path
0 ignored issues
show
Bug introduced by
The type Spiral\Interceptors\Context\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...
15
     * @param \ReflectionFunctionAbstract|null $reflection
16
     * @param TController|null $object
0 ignored issues
show
Bug introduced by
The type Spiral\Interceptors\Context\TController 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...
17
     */
18 239
    private function __construct(
19
        private array $path,
20
        private ?\ReflectionFunctionAbstract $reflection = null,
21
        private readonly ?object $object = null,
22
        private string $delimiter = '.',
23
        private \Closure|array|null $callable = null,
24 239
    ) {
25
    }
26 17
27
    public function __toString(): string
28 17
    {
29
        return \implode($this->delimiter, $this->path);
30
    }
31
32
    /**
33
     * Create a target from a method reflection.
34
     *
35
     * @template T of object
36
     *
37
     * @param \ReflectionMethod $reflection
38
     * @param class-string<T>|T $classOrObject The original class name or object.
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string<T>|T at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string<T>|T.
Loading history...
39
     *        It's required because the reflection may be referring to a parent class method.
40
     *        THe path will contain the original class name and the method name.
41
     *
42
     * @psalmif
43
     *
44
     * @return self<T>
45 158
     */
46
    public static function fromReflectionMethod(
47
        \ReflectionFunctionAbstract $reflection,
48
        string|object $classOrObject,
49
    ): self {
50 158
        $method = $reflection->getName();
51 102
        $isStatic = $reflection->isStatic();
0 ignored issues
show
Bug introduced by
The method isStatic() does not exist on ReflectionFunctionAbstract. It seems like you code against a sub-type of ReflectionFunctionAbstract such as ReflectionMethod. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

51
        /** @scrutinizer ignore-call */ 
52
        $isStatic = $reflection->isStatic();
Loading history...
52 102
53 102
        /** @var self<T> $result */
54 102
        $result = \is_object($classOrObject)
55 102
            ? new self(
56 102
                path: [$classOrObject::class, $method],
57 56
                reflection: $reflection,
58 56
                object: $classOrObject,
59 56
                delimiter: $isStatic ? '::' : '->',
60 56
                callable: [$classOrObject, $method],
61 56
            )
62 158
            : new self(
63
                path: [$classOrObject, $method],
64
                reflection: $reflection,
65
                delimiter: $isStatic ? '::' : '->',
66
                callable: [$classOrObject, $method],
67
            );
68
        return $result;
69
    }
70
71
    /**
72 5
     * Create a target from a function reflection.
73
     *
74
     * @param list<string> $path
75 5
     *
76 5
     * @return self<null>
77
     */
78
    public static function fromReflectionFunction(\ReflectionFunction $reflection, array $path = []): self
79
    {
80
        /** @var self<null> $result */
81
        $result = new self(path: $path, reflection: $reflection, callable: $reflection->getClosure());
82
        return $result;
83
    }
84
85
    /**
86 2
     * Create a target from a closure.
87
     *
88 2
     * @param list<string> $path
89
     *
90
     * @return self<null>
91
     */
92
    public static function fromClosure(\Closure $closure, array $path = []): self
93
    {
94
        /** @var self<null> $result */
95
        $result = new self(path: $path, reflection: new \ReflectionFunction($closure), callable: $closure);
96
        return $result;
97
    }
98 7
99
    /**
100 7
     * Create a target from a path string without reflection.
101
     *
102
     * @param non-empty-string $delimiter
0 ignored issues
show
Documentation Bug introduced by
The doc comment non-empty-string at position 0 could not be parsed: Unknown type name 'non-empty-string' at position 0 in non-empty-string.
Loading history...
103
     *
104
     * @return self<null>
105
     */
106
    public static function fromPathString(string $path, string $delimiter = '.'): self
107
    {
108
        return self::fromPathArray(\explode($delimiter, $path), $delimiter);
109 78
    }
110
111
    /**
112 78
     * Create a target from a path array without reflection.
113 78
     *
114
     * @param list<string> $path
115
     * @return self<null>
116
     */
117
    public static function fromPathArray(array $path, string $delimiter = '.'): self
118
    {
119
        /** @var self<null> $result */
120
        $result = new self(path: $path, delimiter: $delimiter);
121
122
        return $result;
123
    }
124
125
    /**
126
     * Create a target from a controller and action pair.
127 186
     * If the action is a method of the controller, the reflection will be set.
128
     *
129
     * @template T of object
130 186
     *
131
     * @param non-empty-string|class-string<T>|T $controller
0 ignored issues
show
Documentation Bug introduced by
The doc comment non-empty-string|class-string<T>|T at position 0 could not be parsed: Unknown type name 'non-empty-string' at position 0 in non-empty-string|class-string<T>|T.
Loading history...
132 156
     * @param non-empty-string $action
133
     *
134
     * @return ($controller is class-string|T ? self<T> : self<null>)
0 ignored issues
show
Documentation Bug introduced by
The doc comment ($controller at position 1 could not be parsed: Unknown type name '$controller' at position 1 in ($controller.
Loading history...
135 32
     */
136
    public static function fromPair(string|object $controller, string $action): self
137
    {
138 223
        /** @psalm-suppress ArgumentTypeCoercion */
139
        if (\is_object($controller) || \method_exists($controller, $action)) {
140 223
            /** @var T|class-string<T> $controller */
141
            return self::fromReflectionMethod(new \ReflectionMethod($controller, $action), $controller);
142
        }
143 2
144
        return self::fromPathArray([$controller, $action]);
145 2
    }
146 2
147 2
    public function getPath(): array
148 2
    {
149
        return $this->path;
150
    }
151 50
152
    public function withPath(array $path, ?string $delimiter = null): static
153 50
    {
154
        $clone = clone $this;
155
        $clone->path = $path;
0 ignored issues
show
Documentation Bug introduced by
It seems like $path of type array is incompatible with the declared type Spiral\Interceptors\Context\list of property $path.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
156 42
        $clone->delimiter = $delimiter ?? $clone->delimiter;
157
        return $clone;
158 42
    }
159
160
    public function getReflection(): ?\ReflectionFunctionAbstract
161
    {
162
        return $this->reflection;
163
    }
164
165
    public function getObject(): ?object
166
    {
167
        return $this->object;
168
    }
169
170
    public function getCallable(): callable|array|null
171
    {
172
        return $this->callable;
173
    }
174
}
175