Test Failed
Pull Request — master (#63)
by Aleksei
11:21
created

ArgumentException::renderClosureSignature()   B

Complexity

Conditions 9
Paths 20

Size

Total Lines 33
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 20
CRAP Score 9.3752

Importance

Changes 0
Metric Value
eloc 21
c 0
b 0
f 0
dl 0
loc 33
ccs 20
cts 24
cp 0.8333
rs 8.0555
cc 9
nc 20
nop 1
crap 9.3752
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Injector;
6
7
use ReflectionNamedType;
8
use ReflectionUnionType;
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
        /** @psalm-var class-string|null $class */
18 33
        $class = $reflection->class ?? null;
19
20 33
        if ($class === null) {
21 26
            $method = $function;
22 26
            if (substr($method, -9) === '{closure}') {
23 26
                $method = $this->renderClosureSignature($reflection);
24
            }
25
        } else {
26 7
            $method = "{$class}::{$function}";
27
        }
28
29 33
        $fileName = $reflection->getFileName();
30 33
        $line = $reflection->getStartLine();
31
32 33
        $fileAndLine = '';
33 33
        if (!empty($fileName)) {
34 23
            $fileAndLine = " in \"$fileName\" at line $line";
35
        }
36
37 33
        parent::__construct(sprintf((string)static::EXCEPTION_MESSAGE, $parameter, $method, $fileAndLine));
38 33
    }
39
40 14
    private function renderClosureSignature(\ReflectionFunctionAbstract $reflection): string
41
    {
42 14
        $closureParameters = [];
43 14
44 13
        foreach ($reflection->getParameters() as $parameter) {
45 4
            /** @var ReflectionNamedType|ReflectionUnionType|null $type */
46
            $type = $parameter->getType();
47 14
            $parameterString = \sprintf(
48 14
                '%s %s%s$%s',
49 13
                // type
50
                $type,
51 13
                // reference
52 13
                $parameter->isPassedByReference() ? '&' : '',
53 13
                // variadic
54 13
                $parameter->isVariadic() ? '...' : '',
55 4
                $parameter->name,
56
            );
57
            if ($parameter->isDefaultValueAvailable()) {
58
                $default = $parameter->getDefaultValue();
59
                $parameterString .= ' = ';
60
                if (\is_object($default)) {
61
                    $parameterString .= 'new ' . \get_class($default) . '(...)';
62
                } elseif ($parameter->isDefaultValueConstant()) {
63 13
                    $parameterString .= $parameter->getDefaultValueConstantName();
64 13
                } else {
65 13
                    $parameterString .= \var_export($default, true);
66 13
                }
67 3
            }
68
            $closureParameters[] = \ltrim($parameterString);
69 13
        }
70
71 14
        $static = \method_exists($reflection, 'isStatic') && $reflection->isStatic() ? 'static ' : '';
72
        return $static . 'function (' . implode(', ', $closureParameters) . ')';
73
    }
74
}
75