Passed
Pull Request — master (#1111)
by Aleksei
10:58
created

Target::fromPathArray()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
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 6
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 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 246
    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
    ) {
25 246
    }
26
27 17
    public function __toString(): string
28
    {
29 17
        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
     */
46 158
    public static function fromReflectionMethod(
47
        \ReflectionFunctionAbstract $reflection,
48
        string|object $classOrObject,
49
    ): self {
50 158
        $method = $reflection->getName();
51 158
        $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
53
        /** @var self<T> $result */
54 158
        $result = \is_object($classOrObject)
55 102
            ? new self(
56 102
                path: [$classOrObject::class, $method],
57 102
                reflection: $reflection,
58 102
                object: $classOrObject,
59 102
                delimiter: $isStatic ? '::' : '->',
60 102
                callable: [$classOrObject, $method],
61 102
            )
62 56
            : new self(
63 56
                path: [$classOrObject, $method],
64 56
                reflection: $reflection,
65 56
                delimiter: $isStatic ? '::' : '->',
66 56
                callable: [$classOrObject, $method],
67 56
            );
68 158
        return $result;
69
    }
70
71
    /**
72
     * Create a target from a function reflection.
73
     *
74
     * @param list<string> $path
75
     *
76
     * @return self<null>
77
     */
78 3
    public static function fromReflectionFunction(\ReflectionFunction $reflection, array $path = []): self
79
    {
80
        /** @var self<null> $result */
81 3
        $result = new self(path: $path, reflection: $reflection, callable: $reflection->getClosure());
82 3
        return $result;
83
    }
84
85
    /**
86
     * Create a target from a closure.
87
     *
88
     * @param list<string> $path
89
     *
90
     * @return self<null>
91
     */
92 2
    public static function fromClosure(\Closure $closure, array $path = []): self
93
    {
94
        /** @var self<null> $result */
95 2
        $result = new self(path: $path, reflection: new \ReflectionFunction($closure), callable: $closure);
96 2
        return $result;
97
    }
98
99
    /**
100
     * 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 7
    public static function fromPathString(string $path, string $delimiter = '.'): self
107
    {
108 7
        return self::fromPathArray(\explode($delimiter, $path), $delimiter);
109
    }
110
111
    /**
112
     * Create a target from a path array without reflection.
113
     *
114
     * @param list<string> $path
115
     * @return self<null>
116
     */
117 85
    public static function fromPathArray(array $path, string $delimiter = '.'): self
118
    {
119
        /** @var self<null> $result */
120 85
        $result = new self(path: $path, delimiter: $delimiter);
121
122 85
        return $result;
123
    }
124
125
    /**
126
     * Create a target from a controller and action pair.
127
     * If the action is a method of the controller, the reflection will be set.
128
     *
129
     * @template T of object
130
     *
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
     * @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
     */
136 186
    public static function fromPair(string|object $controller, string $action): self
137
    {
138
        /** @psalm-suppress ArgumentTypeCoercion */
139 186
        if (\is_object($controller) || \method_exists($controller, $action)) {
140
            /** @var T|class-string<T> $controller */
141 156
            return self::fromReflectionMethod(new \ReflectionMethod($controller, $action), $controller);
142
        }
143
144 32
        return self::fromPathArray([$controller, $action]);
145
    }
146
147 227
    public function getPath(): array
148
    {
149 227
        return $this->path;
150
    }
151
152 2
    public function withPath(array $path, ?string $delimiter = null): static
153
    {
154 2
        $clone = clone $this;
155 2
        $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 2
        $clone->delimiter = $delimiter ?? $clone->delimiter;
157 2
        return $clone;
158
    }
159
160 73
    public function getReflection(): ?\ReflectionFunctionAbstract
161
    {
162 73
        return $this->reflection;
163
    }
164
165 59
    public function getObject(): ?object
166
    {
167 59
        return $this->object;
168
    }
169
170 98
    public function getCallable(): callable|array|null
171
    {
172 98
        return $this->callable;
173
    }
174
}
175