Passed
Pull Request — master (#19)
by Aleksei
15:04
created

ArgumentException::getClosureSignature()   B

Complexity

Conditions 6
Paths 7

Size

Total Lines 29
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 17
CRAP Score 6

Importance

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

53
                    $type->/** @scrutinizer ignore-call */ 
54
                           getTypes() // @phan-suppress-current-line PhanUndeclaredMethod

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...
54 3
                )) . ' ';
55
            }
56 13
            $append($parameter->isPassedByReference(), '&');
57
            $append($parameter->isVariadic(), '...');
58 14
            $parameterString .= '$' . $parameter->name;
59
            if ($parameter->isDefaultValueAvailable()) {
60
                $parameterString .= ' = ' . var_export($parameter->getDefaultValue(), true);
61
            }
62
            $closureParameters[] = $parameterString;
63
        }
64
        return 'function (' . implode(', ', $closureParameters) . ')';
65
    }
66
}
67