Passed
Push — master ( b04af7...44b412 )
by Andrey
02:02
created

ClassNameExtractor::extractClassName()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 5
ccs 3
cts 3
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Borodulin\Container\Autowire;
6
7
use Borodulin\Container\ContainerException;
8
9
class ClassNameExtractor
10
{
11 7
    public function extract($filename): ?string
12
    {
13 7
        $tokens = token_get_all(file_get_contents($filename));
14
15 7
        $namespace = '';
16
17 7
        $token = current($tokens);
18 7
        while (false !== $token) {
19 7
            if ($this->isToken($token, T_NAMESPACE)) {
20 7
                $namespace = $this->extractNamespace($tokens);
21
            }
22
23 7
            if ($this->isToken($token, T_CLASS)) {
24 7
                $className = $this->extractClassName($tokens);
25
26 7
                return $namespace ? "$namespace\\$className" : $className;
27
            }
28 7
            $token = next($tokens);
29
        }
30
31 6
        return null;
32
    }
33
34 7
    private function isToken($token, int $tokenType): bool
35
    {
36 7
        return \is_array($token) && $token[0] === $tokenType;
37
    }
38
39 7
    private function nextToken(array &$tokens, int $tokenType): string
40
    {
41 7
        $token = next($tokens);
42 7
        if (($token[0] ?? null) === $tokenType) {
43 7
            return $token[1];
44
        }
45
        throw new ContainerException('Parse error. Expected '.token_name($tokenType));
46
    }
47
48 7
    private function isNextToken(array &$tokens, int $tokenType): bool
49
    {
50 7
        $token = next($tokens);
51
52 7
        return $this->isToken($token, $tokenType);
53
    }
54
55 7
    private function extractNamespace(array &$tokens): string
56
    {
57 7
        $this->nextToken($tokens, T_WHITESPACE);
58 7
        $namespace = $this->nextToken($tokens, T_STRING);
59 7
        while ($this->isNextToken($tokens, T_NS_SEPARATOR)) {
60 7
            $namespace .= '\\'.$this->nextToken($tokens, T_STRING);
61
        }
62
63 7
        return $namespace;
64
    }
65
66 7
    private function extractClassName(array &$tokens): string
67
    {
68 7
        $this->nextToken($tokens, T_WHITESPACE);
69
70 7
        return $this->nextToken($tokens, T_STRING);
71
    }
72
}
73