Passed
Push — master ( f88eef...f07f40 )
by Alexander
01:36
created

ArgumentException::getClosureSignature()   B

Complexity

Conditions 6
Paths 7

Size

Total Lines 29
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 20
CRAP Score 6.1666

Importance

Changes 0
Metric Value
cc 6
eloc 22
nc 7
nop 1
dl 0
loc 29
ccs 20
cts 24
cp 0.8333
crap 6.1666
rs 8.9457
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Injector;
6
7
use ReflectionNamedType;
8
use ReflectionUnionType;
0 ignored issues
show
Bug introduced by
The type ReflectionUnionType 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...
9
10
abstract class ArgumentException extends \InvalidArgumentException
11
{
12
    protected const EXCEPTION_MESSAGE = 'Something is wrong with argument "%s" when calling "%s"%s.';
13
14 33
    public function __construct(\ReflectionFunctionAbstract $reflection, string $parameter)
15
    {
16 33
        $function = $reflection->getName();
17 33
        $class = $reflection->class ?? null;
18
19 33
        if ($class === null) {
20 26
            $method = $function;
21 26
            if (substr($method, -9) === '{closure}') {
22 26
                $method = $this->getClosureSignature($reflection);
23
            }
24
        } else {
25 7
            $method = "{$class}::{$function}";
26
        }
27
28 33
        $fileName = $reflection->getFileName();
29 33
        $line = $reflection->getStartLine();
30
31 33
        $fileAndLine = '';
32 33
        if (!empty($fileName)) {
33 23
            $fileAndLine = " in \"$fileName\" at line $line";
34
        }
35
36 33
        parent::__construct(sprintf(static::EXCEPTION_MESSAGE, $parameter, $method, $fileAndLine));
37 33
    }
38
39
    /**
40
     * @phan-suppress PhanUndeclaredClassInstanceof, PhanUndeclaredClassMethod
41
     */
42 14
    private function getClosureSignature(\ReflectionFunctionAbstract $reflection): string
43
    {
44 14
        $closureParameters = [];
45 14
        $append = static function (bool $condition, string $postfix) use (&$parameterString): void {
46 13
            if ($condition) {
47 4
                $parameterString .= $postfix;
48
            }
49 14
        };
50 14
        foreach ($reflection->getParameters() as $parameter) {
51 13
            $parameterString = '';
52 13
            $type = $parameter->getType();
53 13
            if ($type instanceof ReflectionNamedType) {
54 13
                $append($parameter->allowsNull(), '?');
55 13
                $parameterString .= $type->getName() . ' ';
56 4
            } elseif ($type instanceof ReflectionUnionType) {
57
                $parameterString .= implode('|', array_map(
58
                    fn (ReflectionNamedType $r) => $r->getName(),
59
                    $type->getTypes()
0 ignored issues
show
Bug introduced by
The method getTypes() does not exist on ReflectionType. ( Ignorable by Annotation )

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

59
                    $type->/** @scrutinizer ignore-call */ 
60
                           getTypes()

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
60
                )) . ' ';
61
            }
62 13
            $append($parameter->isPassedByReference(), '&');
63 13
            $append($parameter->isVariadic(), '...');
64 13
            $parameterString .= '$' . $parameter->name;
65 13
            if ($parameter->isDefaultValueAvailable()) {
66 3
                $parameterString .= ' = ' . var_export($parameter->getDefaultValue(), true);
67
            }
68 13
            $closureParameters[] = $parameterString;
69
        }
70 14
        return 'function (' . implode(', ', $closureParameters) . ')';
71
    }
72
}
73