SpyCompiler   A
last analyzed

Complexity

Total Complexity 11

Size/Duplication

Total Lines 82
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 11
eloc 22
c 1
b 0
f 0
dl 0
loc 82
rs 10

5 Methods

Rating   Name   Duplication   Size   Complexity  
A newInstance() 0 4 1
A hasBoundMethod() 0 11 3
A getInterceptors() 0 21 3
A hasNoBinding() 0 5 2
A compile() 0 7 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Ray\Di;
6
7
use LogicException;
8
use Ray\Aop\BindInterface;
9
use Ray\Aop\CompilerInterface;
10
11
use function array_keys;
12
use function implode;
13
use function method_exists;
14
use function sprintf;
15
16
/**
17
 * @codeCoverageIgnore
18
 */
19
final class SpyCompiler implements CompilerInterface
20
{
21
    /**
22
     * {@inheritDoc}
23
     *
24
     * @phpstan-return never
25
     *
26
     * @psalm-suppress InvalidReturnType
27
     * @template T of object
28
     */
29
    public function newInstance(string $class, array $args, BindInterface $bind)
30
    {
31
        // never called
32
        throw new LogicException('SpyCompiler::newInstance() should never be called');
33
    }
34
35
    /**
36
     * Return "logging" class name
37
     *
38
     * Dummy classes are used for logging and don't really exist.
39
     * So the code breaks the QA rules as shown below.
40
     * NOTE: psalm-suppress is acceptable here for dummy/logging infrastructure
41
     *
42
     * @psalm-suppress MoreSpecificReturnType
43
     * @psalm-suppress LessSpecificReturnStatement
44
     */
45
    public function compile(string $class, BindInterface $bind): string
46
    {
47
        if ($this->hasNoBinding($class, $bind)) {
48
            return $class;
49
        }
50
51
        return $class . $this->getInterceptors($bind); // @phpstan-ignore-line
52
    }
53
54
    /**
55
     * @param class-string $class
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string.
Loading history...
56
     */
57
    private function hasNoBinding(string $class, BindInterface $bind): bool
58
    {
59
        $hasMethod = $this->hasBoundMethod($class, $bind);
60
61
        return ! $bind->getBindings() && ! $hasMethod;
62
    }
63
64
    /**
65
     * @param class-string $class
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string.
Loading history...
66
     */
67
    private function hasBoundMethod(string $class, BindInterface $bind): bool
68
    {
69
        $bindingMethods = array_keys($bind->getBindings());
0 ignored issues
show
Bug introduced by
$bind->getBindings() of type Ray\Aop\MethodBindings is incompatible with the type array expected by parameter $array of array_keys(). ( Ignorable by Annotation )

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

69
        $bindingMethods = array_keys(/** @scrutinizer ignore-type */ $bind->getBindings());
Loading history...
70
        $hasMethod = false;
71
        foreach ($bindingMethods as $bindingMethod) {
72
            if (method_exists($class, $bindingMethod)) {
73
                $hasMethod = true;
74
            }
75
        }
76
77
        return $hasMethod;
78
    }
79
80
    private function getInterceptors(BindInterface $bind): string
81
    {
82
        $bindings = $bind->getBindings();
83
        if (! $bindings) {
0 ignored issues
show
introduced by
$bindings is of type Ray\Aop\MethodBindings, thus it always evaluated to true.
Loading history...
84
            return ''; // @codeCoverageIgnore
85
        }
86
87
        $log = ' (aop)';
88
        foreach ($bindings as $method => $interceptors) {
89
            /**
90
             * @phpstan-var array<string> $interceptors
91
             * @psalm-ignore-var
92
             */
93
            $log .= sprintf(
94
                ' +%s(%s)',
95
                $method,
96
                implode(', ', $interceptors)
97
            );
98
        }
99
100
        return $log;
101
    }
102
}
103