Completed
Pull Request — master (#133)
by
unknown
02:52 queued 30s
created

PhpFunctionsScanner::parsePhpComment()   D

Complexity

Conditions 10
Paths 19

Size

Total Lines 28
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 1 Features 0
Metric Value
cc 10
eloc 19
c 3
b 1
f 0
nc 19
nop 1
dl 0
loc 28
rs 4.8196

How to fix   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
namespace Gettext\Utils;
4
5
use Gettext\Extractors\PhpCode;
6
7
class PhpFunctionsScanner extends FunctionsScanner
8
{
9
    /**
10
     * PHP tokens of the code to be parsed.
11
     *
12
     * @var array
13
     */
14
    protected $tokens;
15
16
    /**
17
     * If not false, comments will be extracted.
18
     *
19
     * @var string|false|array
20
     */
21
    protected $extractComments = false;
22
23
    /**
24
     * Enable extracting comments that start with a tag (if $tag is empty all the comments will be extracted).
25
     *
26
     * @param mixed $tag
27
     */
28
    public function enableCommentsExtraction($tag = '')
29
    {
30
        $this->extractComments = $tag;
31
    }
32
33
    /**
34
     * Disable comments extraction.
35
     */
36
    public function disableCommentsExtraction()
37
    {
38
        $this->extractComments = false;
39
    }
40
41
    /**
42
     * Constructor.
43
     *
44
     * @param string $code The php code to scan
45
     */
46
    public function __construct($code)
47
    {
48
        $this->tokens = array_values(
49
            array_filter(
50
                token_get_all($code),
51
                function ($token) {
52
                    return !is_array($token) || $token[0] !== T_WHITESPACE;
53
                }
54
            )
55
        );
56
    }
57
58
    /**
59
     * {@inheritdoc}
60
     */
61
    public function getFunctions(array $constants = [])
62
    {
63
        $count = count($this->tokens);
64
        $bufferFunctions = [];
65
        /* @var ParsedFunction[] $bufferFunctions */
66
        $functions = [];
67
        /* @var ParsedFunction[] $functions */
68
69
        for ($k = 0; $k < $count; ++$k) {
70
            $value = $this->tokens[$k];
71
72
            if (is_string($value)) {
73
                if (isset($bufferFunctions[0])) {
74
                    switch ($value) {
75
                        case ',':
76
                            $bufferFunctions[0]->nextArgument();
77
                            break;
78
                        case ')':
79
                            $functions[] = array_shift($bufferFunctions)->close();
80
                            break;
81
                        case '.':
82
                            break;
83
                        default:
84
                            $bufferFunctions[0]->stopArgument();
85
                            break;
86
                    }
87
                }
88
                continue;
89
            }
90
91
            switch ($value[0]) {
92
                case T_CONSTANT_ENCAPSED_STRING:
93
                    //add an argument to the current function
94
                    if (isset($bufferFunctions[0])) {
95
                        $bufferFunctions[0]->addArgumentChunk(PhpCode::convertString($value[1]));
96
                    }
97
                    break;
98
99
                case T_STRING:
100
                    if (isset($bufferFunctions[0])) {
101
                        if (isset($constants[$value[1]])) {
102
                            $bufferFunctions[0]->addArgumentChunk($constants[$value[1]]);
103
                            break;
104
                        }
105
                        $bufferFunctions[0]->stopArgument();
106
                    }
107
                    //new function found
108
                    for ($j = $k + 1; $j < $count; ++$j) {
109
                        $nextToken = $this->tokens[$j];
110
                        if (is_array($nextToken) && $nextToken[0] === T_COMMENT) {
111
                            continue;
112
                        }
113
                        if ($nextToken === '(') {
114
                            $newFunction = new ParsedFunction($value[1], $value[2]);
115
                            if ($k > 0 && is_array($this->tokens[$k - 1]) && $this->tokens[$k - 1][0] === T_COMMENT) {
116
                                $comment = $this->parsePhpComment($this->tokens[$k - 1][1]);
117
                                if ($comment !== null) {
118
                                    $newFunction->addComment($comment);
119
                                }
120
                            }
121
                            array_unshift($bufferFunctions, $newFunction);
122
                            $k = $j;
123
                        }
124
                        break;
125
                    }
126
                    break;
127
128
                case T_COMMENT:
129
                    if (isset($bufferFunctions[0])) {
130
                        $comment = $this->parsePhpComment($value[1]);
131
                        if ($comment !== null) {
132
                            $bufferFunctions[0]->addComment($comment);
133
                        }
134
                    }
135
                    break;
136
137
                default:
138
                    if (isset($bufferFunctions[0])) {
139
                        $bufferFunctions[0]->stopArgument();
140
                    }
141
                    break;
142
            }
143
        }
144
145
        return $functions;
146
    }
147
148
    protected function parsePhpComment($value)
149
    {
150
        $result = null;
151
        if ($this->extractComments !== false) {
152
            if ($value[0] === '#') {
153
                $value = substr($value, 1);
154
            } elseif ($value[1] === '/') {
155
                $value = substr($value, 2);
156
            } else {
157
                $value = substr($value, 2, -2);
158
            }
159
            $value = trim($value);
160
            if ($value !== '') {
161
                if ($this->extractComments === '' || strpos($value, $this->extractComments) === 0) {
162
                    $result = $value;
163
                }
164
                elseif (is_array($this->extractComments)) {
165
                    foreach ($this->extractComments as $string) {
166
                        if (strpos($value, $string) === 0) {
167
                            $result = $value;
168
                            break;
169
                        }
170
                    }        
171
                }
172
            }
173
        }
174
        return $result;
175
    }
176
}
177