Passed
Push — master ( 55f627...47fe5a )
by Dmitriy
02:36 queued 02:02
created

ClosureExporter::export()   D

Complexity

Conditions 22
Paths 24

Size

Total Lines 60
Code Lines 41

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 40
CRAP Score 22.0521

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 22
eloc 41
c 1
b 0
f 0
nc 24
nop 1
dl 0
loc 60
ccs 40
cts 42
cp 0.9524
crap 22.0521
rs 4.1666

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\VarDumper;
6
7
final class ClosureExporter
8
{
9
    private UseStatementParser $useStatementParser;
10
11 39
    public function __construct()
12
    {
13 39
        $this->useStatementParser = new UseStatementParser();
14 39
    }
15
16 39
    public function export(\Closure $closure)
17
    {
18 39
        $reflection = new \ReflectionFunction($closure);
19
20 39
        $fileName = $reflection->getFileName();
21 39
        $start = $reflection->getStartLine();
22 39
        $end = $reflection->getEndLine();
23
24 39
        if ($fileName === false || $start === false || $end === false || ($fileContent = file($fileName)) === false) {
25
            return 'function() {/* Error: unable to determine Closure source */}';
26
        }
27
28 39
        --$start;
29 39
        $uses = $this->useStatementParser->fromFile($fileName);
30
31 39
        $source = implode('', array_slice($fileContent, $start, $end - $start));
32 39
        $tokens = token_get_all('<?php ' . $source);
33 39
        array_shift($tokens);
34
35 39
        $closureTokens = [];
36 39
        $pendingParenthesisCount = 0;
37 39
        $isShortClosure = false;
38 39
        $buffer = '';
39 39
        foreach ($tokens as $token) {
40 39
            if (!isset($token[0])) {
41
                continue;
42
            }
43 39
            if (in_array($token[0], [T_FUNCTION, T_FN, T_STATIC], true)) {
44 39
                $closureTokens[] = $token[1];
45 39
                if (!$isShortClosure && $token[0] === T_FN) {
46 31
                    $isShortClosure = true;
47
                }
48 39
                continue;
49
            }
50 39
            if ($closureTokens !== []) {
51 39
                $readableToken = $token[1] ?? $token;
52 39
                if ($this->isNextTokenIsPartOfNamespace($token)) {
53 20
                    $buffer .= $token[1];
54 20
                    if (!$this->isNextTokenIsPartOfNamespace(next($tokens)) && array_key_exists($buffer, $uses)) {
55 12
                        $readableToken = $uses[$buffer];
56 12
                        $buffer = '';
57
                    }
58
                }
59 39
                if ($token === '{' || $token === '[') {
60 12
                    $pendingParenthesisCount++;
61 39
                } elseif ($token === '}' || $token === ']') {
62 16
                    if ($pendingParenthesisCount === 0) {
63 4
                        break;
64
                    }
65 12
                    $pendingParenthesisCount--;
66 39
                } elseif ($token === ',' || $token === ';') {
67 35
                    if ($pendingParenthesisCount === 0) {
68 35
                        break;
69
                    }
70
                }
71 39
                $closureTokens[] = $readableToken;
72
            }
73
        }
74
75 39
        return implode('', $closureTokens);
76
    }
77
78 39
    private function isNextTokenIsPartOfNamespace($token): bool
79
    {
80 39
        if (!is_array($token)) {
81 39
            return false;
82
        }
83
84 39
        return $token[0] === T_STRING || $token[0] === T_NS_SEPARATOR;
85
    }
86
}
87