Passed
Push — master ( 904fca...2ba06e )
by butschster
07:38
created

InvocationLocator::isTargeted()   A

Complexity

Conditions 6
Paths 6

Size

Total Lines 27
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 7.3329

Importance

Changes 0
Metric Value
eloc 12
c 0
b 0
f 0
dl 0
loc 27
ccs 8
cts 12
cp 0.6667
rs 9.2222
cc 6
nc 6
nop 2
crap 7.3329
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Spiral\Tokenizer;
6
7
use Spiral\Tokenizer\Exception\LocatorException;
8
use Spiral\Tokenizer\Reflection\ReflectionInvocation;
9
use Spiral\Tokenizer\Traits\TargetTrait;
10
11
/**
12
 * Can locate invocations in a specified directory. Can only find simple invocations!
13
 *
14
 * Potentially this class have to be rewritten in order to use new PHP API and AST tree, for now it
15
 * still relies on legacy token based parser.
16
 */
17
final class InvocationLocator extends AbstractLocator implements InvocationsInterface
18
{
19
    public const INJECTOR = InvocationLocatorInjector::class;
20
21 25
    public function getInvocations(\ReflectionFunctionAbstract $function): array
22
    {
23 25
        $result = [];
24 25
        foreach ($this->availableInvocations($function->getName()) as $invocation) {
25 25
            if ($this->isTargeted($invocation, $function)) {
26 25
                $result[] = $invocation;
27
            }
28
        }
29
30 25
        return $result;
31
    }
32
33
    /**
34
     * Invocations available in finder scope.
35
     *
36
     * @param string $signature Method or function signature (name), for pre-filtering.
37
     * @return \Generator<int, ReflectionInvocation>
38
     */
39 25
    protected function availableInvocations(string $signature = ''): \Generator
40
    {
41 25
        $signature = \strtolower(\trim($signature, '\\'));
42 25
        foreach ($this->availableReflections() as $reflection) {
43 25
            foreach ($reflection->getInvocations() as $invocation) {
44
                if (
45 25
                    !empty($signature)
46 25
                    && \strtolower(\trim($invocation->getName(), '\\')) !== $signature
47
                ) {
48 25
                    continue;
49
                }
50
51 25
                yield $invocation;
52
            }
53
        }
54
    }
55
56 25
    protected function isTargeted(ReflectionInvocation $invocation, \ReflectionFunctionAbstract $function): bool
57
    {
58 25
        if ($function instanceof \ReflectionFunction) {
59 13
            return !$invocation->isMethod();
60
        }
61
62
        try {
63 25
            $reflection = $this->classReflection($invocation->getClass());
64
        } catch (LocatorException $e) {
65
            if ($this->debug) {
66
                throw $e;
67
            }
68
69
            return false;
70
        }
71
72
        /**
73
         * @var \ReflectionMethod $function
74
         */
75 25
        $target = $function->getDeclaringClass();
76
77 25
        if ($target->isTrait()) {
78
            //Let's compare traits
79 13
            return \in_array($target->getName(), $this->fetchTraits($invocation->getClass()));
80
        }
81
82 12
        return $reflection->getName() == $target->getName() || $reflection->isSubclassOf($target);
83
    }
84
}
85